]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Don't use bfd_vma in readelf.c
[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
dda8d76d 5691/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5692
015dc7e1 5693static bool
dda8d76d 5694process_file_header (Filedata * filedata)
252b5132 5695{
dda8d76d
NC
5696 Elf_Internal_Ehdr * header = & filedata->file_header;
5697
5698 if ( header->e_ident[EI_MAG0] != ELFMAG0
5699 || header->e_ident[EI_MAG1] != ELFMAG1
5700 || header->e_ident[EI_MAG2] != ELFMAG2
5701 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5702 {
5703 error
5704 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5705 return false;
252b5132
RH
5706 }
5707
ca0e11aa
NC
5708 if (! filedata->is_separate)
5709 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5710
252b5132
RH
5711 if (do_header)
5712 {
32ec8896 5713 unsigned i;
252b5132 5714
ca0e11aa
NC
5715 if (filedata->is_separate)
5716 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5717 else
5718 printf (_("ELF Header:\n"));
252b5132 5719 printf (_(" Magic: "));
b34976b6 5720 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5721 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5722 printf ("\n");
5723 printf (_(" Class: %s\n"),
dda8d76d 5724 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5725 printf (_(" Data: %s\n"),
dda8d76d 5726 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5727 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5728 header->e_ident[EI_VERSION],
5729 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5730 ? _(" (current)")
dda8d76d 5731 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5732 ? _(" <unknown>")
789be9f7 5733 : "")));
252b5132 5734 printf (_(" OS/ABI: %s\n"),
dda8d76d 5735 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5736 printf (_(" ABI Version: %d\n"),
dda8d76d 5737 header->e_ident[EI_ABIVERSION]);
252b5132 5738 printf (_(" Type: %s\n"),
93df3340 5739 get_file_type (filedata));
252b5132 5740 printf (_(" Machine: %s\n"),
dda8d76d 5741 get_machine_name (header->e_machine));
252b5132 5742 printf (_(" Version: 0x%lx\n"),
e8a64888 5743 header->e_version);
76da6bbe 5744
f7a99963 5745 printf (_(" Entry point address: "));
e8a64888 5746 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5747 printf (_("\n Start of program headers: "));
e8a64888 5748 print_vma (header->e_phoff, DEC);
f7a99963 5749 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5750 print_vma (header->e_shoff, DEC);
f7a99963 5751 printf (_(" (bytes into file)\n"));
76da6bbe 5752
252b5132 5753 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5754 header->e_flags,
dda8d76d 5755 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5756 printf (_(" Size of this header: %u (bytes)\n"),
5757 header->e_ehsize);
5758 printf (_(" Size of program headers: %u (bytes)\n"),
5759 header->e_phentsize);
5760 printf (_(" Number of program headers: %u"),
5761 header->e_phnum);
dda8d76d
NC
5762 if (filedata->section_headers != NULL
5763 && header->e_phnum == PN_XNUM
5764 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5765 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5766 putc ('\n', stdout);
e8a64888
AM
5767 printf (_(" Size of section headers: %u (bytes)\n"),
5768 header->e_shentsize);
5769 printf (_(" Number of section headers: %u"),
5770 header->e_shnum);
dda8d76d 5771 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5772 {
5773 header->e_shnum = filedata->section_headers[0].sh_size;
5774 printf (" (%u)", header->e_shnum);
5775 }
560f3c1c 5776 putc ('\n', stdout);
e8a64888
AM
5777 printf (_(" Section header string table index: %u"),
5778 header->e_shstrndx);
dda8d76d
NC
5779 if (filedata->section_headers != NULL
5780 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5781 {
5782 header->e_shstrndx = filedata->section_headers[0].sh_link;
5783 printf (" (%u)", header->e_shstrndx);
5784 }
5785 if (header->e_shstrndx != SHN_UNDEF
5786 && header->e_shstrndx >= header->e_shnum)
5787 {
5788 header->e_shstrndx = SHN_UNDEF;
5789 printf (_(" <corrupt: out of range>"));
5790 }
560f3c1c
AM
5791 putc ('\n', stdout);
5792 }
5793
dda8d76d 5794 if (filedata->section_headers != NULL)
560f3c1c 5795 {
dda8d76d
NC
5796 if (header->e_phnum == PN_XNUM
5797 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5798 {
5799 /* Throw away any cached read of PN_XNUM headers. */
5800 free (filedata->program_headers);
5801 filedata->program_headers = NULL;
5802 header->e_phnum = filedata->section_headers[0].sh_info;
5803 }
dda8d76d
NC
5804 if (header->e_shnum == SHN_UNDEF)
5805 header->e_shnum = filedata->section_headers[0].sh_size;
5806 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5807 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5808 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5809 header->e_shstrndx = SHN_UNDEF;
252b5132 5810 }
103f02d3 5811
015dc7e1 5812 return true;
9ea033b2
NC
5813}
5814
dda8d76d
NC
5815/* Read in the program headers from FILEDATA and store them in PHEADERS.
5816 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5817
015dc7e1 5818static bool
dda8d76d 5819get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5820{
2cf0635d
NC
5821 Elf32_External_Phdr * phdrs;
5822 Elf32_External_Phdr * external;
5823 Elf_Internal_Phdr * internal;
b34976b6 5824 unsigned int i;
dda8d76d
NC
5825 unsigned int size = filedata->file_header.e_phentsize;
5826 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5827
5828 /* PR binutils/17531: Cope with unexpected section header sizes. */
5829 if (size == 0 || num == 0)
015dc7e1 5830 return false;
e0a31db1
NC
5831 if (size < sizeof * phdrs)
5832 {
5833 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5834 return false;
e0a31db1
NC
5835 }
5836 if (size > sizeof * phdrs)
5837 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5838
dda8d76d 5839 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5840 size, num, _("program headers"));
5841 if (phdrs == NULL)
015dc7e1 5842 return false;
9ea033b2 5843
91d6fa6a 5844 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5845 i < filedata->file_header.e_phnum;
b34976b6 5846 i++, internal++, external++)
252b5132 5847 {
9ea033b2
NC
5848 internal->p_type = BYTE_GET (external->p_type);
5849 internal->p_offset = BYTE_GET (external->p_offset);
5850 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5851 internal->p_paddr = BYTE_GET (external->p_paddr);
5852 internal->p_filesz = BYTE_GET (external->p_filesz);
5853 internal->p_memsz = BYTE_GET (external->p_memsz);
5854 internal->p_flags = BYTE_GET (external->p_flags);
5855 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5856 }
5857
9ea033b2 5858 free (phdrs);
015dc7e1 5859 return true;
252b5132
RH
5860}
5861
dda8d76d
NC
5862/* Read in the program headers from FILEDATA and store them in PHEADERS.
5863 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5864
015dc7e1 5865static bool
dda8d76d 5866get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5867{
2cf0635d
NC
5868 Elf64_External_Phdr * phdrs;
5869 Elf64_External_Phdr * external;
5870 Elf_Internal_Phdr * internal;
b34976b6 5871 unsigned int i;
dda8d76d
NC
5872 unsigned int size = filedata->file_header.e_phentsize;
5873 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5874
5875 /* PR binutils/17531: Cope with unexpected section header sizes. */
5876 if (size == 0 || num == 0)
015dc7e1 5877 return false;
e0a31db1
NC
5878 if (size < sizeof * phdrs)
5879 {
5880 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5881 return false;
e0a31db1
NC
5882 }
5883 if (size > sizeof * phdrs)
5884 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5885
dda8d76d 5886 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5887 size, num, _("program headers"));
a6e9f9df 5888 if (!phdrs)
015dc7e1 5889 return false;
9ea033b2 5890
91d6fa6a 5891 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5892 i < filedata->file_header.e_phnum;
b34976b6 5893 i++, internal++, external++)
9ea033b2
NC
5894 {
5895 internal->p_type = BYTE_GET (external->p_type);
5896 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5897 internal->p_offset = BYTE_GET (external->p_offset);
5898 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5899 internal->p_paddr = BYTE_GET (external->p_paddr);
5900 internal->p_filesz = BYTE_GET (external->p_filesz);
5901 internal->p_memsz = BYTE_GET (external->p_memsz);
5902 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5903 }
5904
5905 free (phdrs);
015dc7e1 5906 return true;
9ea033b2 5907}
252b5132 5908
32ec8896 5909/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5910
015dc7e1 5911static bool
dda8d76d 5912get_program_headers (Filedata * filedata)
d93f0186 5913{
2cf0635d 5914 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5915
5916 /* Check cache of prior read. */
dda8d76d 5917 if (filedata->program_headers != NULL)
015dc7e1 5918 return true;
d93f0186 5919
82156ab7
NC
5920 /* Be kind to memory checkers by looking for
5921 e_phnum values which we know must be invalid. */
dda8d76d 5922 if (filedata->file_header.e_phnum
82156ab7 5923 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5924 >= filedata->file_size)
82156ab7
NC
5925 {
5926 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5927 filedata->file_header.e_phnum);
015dc7e1 5928 return false;
82156ab7 5929 }
d93f0186 5930
dda8d76d 5931 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5932 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5933 if (phdrs == NULL)
5934 {
8b73c356 5935 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5936 filedata->file_header.e_phnum);
015dc7e1 5937 return false;
d93f0186
NC
5938 }
5939
5940 if (is_32bit_elf
dda8d76d
NC
5941 ? get_32bit_program_headers (filedata, phdrs)
5942 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5943 {
dda8d76d 5944 filedata->program_headers = phdrs;
015dc7e1 5945 return true;
d93f0186
NC
5946 }
5947
5948 free (phdrs);
015dc7e1 5949 return false;
d93f0186
NC
5950}
5951
93df3340 5952/* Print program header info and locate dynamic section. */
2f62977e 5953
93df3340 5954static void
dda8d76d 5955process_program_headers (Filedata * filedata)
252b5132 5956{
2cf0635d 5957 Elf_Internal_Phdr * segment;
b34976b6 5958 unsigned int i;
1a9ccd70 5959 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5960
dda8d76d 5961 if (filedata->file_header.e_phnum == 0)
252b5132 5962 {
82f2dbf7 5963 /* PR binutils/12467. */
dda8d76d 5964 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5965 warn (_("possibly corrupt ELF header - it has a non-zero program"
5966 " header offset, but no program headers\n"));
82f2dbf7 5967 else if (do_segments)
ca0e11aa
NC
5968 {
5969 if (filedata->is_separate)
5970 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5971 filedata->file_name);
5972 else
5973 printf (_("\nThere are no program headers in this file.\n"));
5974 }
93df3340 5975 goto no_headers;
252b5132
RH
5976 }
5977
5978 if (do_segments && !do_header)
5979 {
ca0e11aa
NC
5980 if (filedata->is_separate)
5981 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5982 filedata->file_name, get_file_type (filedata));
ca0e11aa 5983 else
93df3340 5984 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 5985 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 5986 filedata->file_header.e_entry);
b8281767
AM
5987 printf (ngettext ("There is %d program header,"
5988 " starting at offset %" PRIu64 "\n",
5989 "There are %d program headers,"
5990 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
5991 filedata->file_header.e_phnum),
5992 filedata->file_header.e_phnum,
625d49fc 5993 filedata->file_header.e_phoff);
252b5132
RH
5994 }
5995
dda8d76d 5996 if (! get_program_headers (filedata))
93df3340 5997 goto no_headers;
103f02d3 5998
252b5132
RH
5999 if (do_segments)
6000 {
dda8d76d 6001 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6002 printf (_("\nProgram Headers:\n"));
6003 else
6004 printf (_("\nProgram Headers:\n"));
76da6bbe 6005
f7a99963
NC
6006 if (is_32bit_elf)
6007 printf
6008 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6009 else if (do_wide)
6010 printf
6011 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6012 else
6013 {
6014 printf
6015 (_(" Type Offset VirtAddr PhysAddr\n"));
6016 printf
6017 (_(" FileSiz MemSiz Flags Align\n"));
6018 }
252b5132
RH
6019 }
6020
93df3340 6021 unsigned long dynamic_addr = 0;
be7d229a 6022 uint64_t dynamic_size = 0;
dda8d76d
NC
6023 for (i = 0, segment = filedata->program_headers;
6024 i < filedata->file_header.e_phnum;
b34976b6 6025 i++, segment++)
252b5132
RH
6026 {
6027 if (do_segments)
6028 {
dda8d76d 6029 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6030
6031 if (is_32bit_elf)
6032 {
6033 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6034 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6035 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6036 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6037 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6038 printf ("%c%c%c ",
6039 (segment->p_flags & PF_R ? 'R' : ' '),
6040 (segment->p_flags & PF_W ? 'W' : ' '),
6041 (segment->p_flags & PF_X ? 'E' : ' '));
6042 printf ("%#lx", (unsigned long) segment->p_align);
6043 }
d974e256
JJ
6044 else if (do_wide)
6045 {
6046 if ((unsigned long) segment->p_offset == segment->p_offset)
6047 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6048 else
6049 {
6050 print_vma (segment->p_offset, FULL_HEX);
6051 putchar (' ');
6052 }
6053
6054 print_vma (segment->p_vaddr, FULL_HEX);
6055 putchar (' ');
6056 print_vma (segment->p_paddr, FULL_HEX);
6057 putchar (' ');
6058
6059 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6060 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6061 else
6062 {
6063 print_vma (segment->p_filesz, FULL_HEX);
6064 putchar (' ');
6065 }
6066
6067 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6068 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6069 else
6070 {
f48e6c45 6071 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6072 }
6073
6074 printf (" %c%c%c ",
6075 (segment->p_flags & PF_R ? 'R' : ' '),
6076 (segment->p_flags & PF_W ? 'W' : ' '),
6077 (segment->p_flags & PF_X ? 'E' : ' '));
6078
6079 if ((unsigned long) segment->p_align == segment->p_align)
6080 printf ("%#lx", (unsigned long) segment->p_align);
6081 else
6082 {
6083 print_vma (segment->p_align, PREFIX_HEX);
6084 }
6085 }
f7a99963
NC
6086 else
6087 {
6088 print_vma (segment->p_offset, FULL_HEX);
6089 putchar (' ');
6090 print_vma (segment->p_vaddr, FULL_HEX);
6091 putchar (' ');
6092 print_vma (segment->p_paddr, FULL_HEX);
6093 printf ("\n ");
6094 print_vma (segment->p_filesz, FULL_HEX);
6095 putchar (' ');
6096 print_vma (segment->p_memsz, FULL_HEX);
6097 printf (" %c%c%c ",
6098 (segment->p_flags & PF_R ? 'R' : ' '),
6099 (segment->p_flags & PF_W ? 'W' : ' '),
6100 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6101 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6102 }
252b5132 6103
1a9ccd70
NC
6104 putc ('\n', stdout);
6105 }
f54498b4 6106
252b5132
RH
6107 switch (segment->p_type)
6108 {
1a9ccd70 6109 case PT_LOAD:
502d895c
NC
6110#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6111 required by the ELF standard, several programs, including the Linux
6112 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6113 if (previous_load
6114 && previous_load->p_vaddr > segment->p_vaddr)
6115 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6116#endif
1a9ccd70
NC
6117 if (segment->p_memsz < segment->p_filesz)
6118 error (_("the segment's file size is larger than its memory size\n"));
6119 previous_load = segment;
6120 break;
6121
6122 case PT_PHDR:
6123 /* PR 20815 - Verify that the program header is loaded into memory. */
6124 if (i > 0 && previous_load != NULL)
6125 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6126 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6127 {
6128 unsigned int j;
6129
dda8d76d 6130 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6131 {
6132 Elf_Internal_Phdr *load = filedata->program_headers + j;
6133 if (load->p_type == PT_LOAD
6134 && load->p_offset <= segment->p_offset
6135 && (load->p_offset + load->p_filesz
6136 >= segment->p_offset + segment->p_filesz)
6137 && load->p_vaddr <= segment->p_vaddr
6138 && (load->p_vaddr + load->p_filesz
6139 >= segment->p_vaddr + segment->p_filesz))
6140 break;
6141 }
dda8d76d 6142 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6143 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6144 }
6145 break;
6146
252b5132 6147 case PT_DYNAMIC:
93df3340 6148 if (dynamic_addr)
252b5132
RH
6149 error (_("more than one dynamic segment\n"));
6150
20737c13
AM
6151 /* By default, assume that the .dynamic section is the first
6152 section in the DYNAMIC segment. */
93df3340
AM
6153 dynamic_addr = segment->p_offset;
6154 dynamic_size = segment->p_filesz;
20737c13 6155
b2d38a17
NC
6156 /* Try to locate the .dynamic section. If there is
6157 a section header table, we can easily locate it. */
dda8d76d 6158 if (filedata->section_headers != NULL)
b2d38a17 6159 {
2cf0635d 6160 Elf_Internal_Shdr * sec;
b2d38a17 6161
dda8d76d 6162 sec = find_section (filedata, ".dynamic");
89fac5e3 6163 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6164 {
93df3340
AM
6165 /* A corresponding .dynamic section is expected, but on
6166 IA-64/OpenVMS it is OK for it to be missing. */
6167 if (!is_ia64_vms (filedata))
6168 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6169 break;
6170 }
6171
42bb2e33 6172 if (sec->sh_type == SHT_NOBITS)
20737c13 6173 {
93df3340
AM
6174 dynamic_addr = 0;
6175 dynamic_size = 0;
20737c13
AM
6176 break;
6177 }
42bb2e33 6178
93df3340
AM
6179 dynamic_addr = sec->sh_offset;
6180 dynamic_size = sec->sh_size;
b2d38a17 6181
8ac10c5b
L
6182 /* The PT_DYNAMIC segment, which is used by the run-time
6183 loader, should exactly match the .dynamic section. */
6184 if (do_checks
93df3340
AM
6185 && (dynamic_addr != segment->p_offset
6186 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6187 warn (_("\
6188the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6189 }
39e224f6
MW
6190
6191 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6192 segment. Check this after matching against the section headers
6193 so we don't warn on debuginfo file (which have NOBITS .dynamic
6194 sections). */
93df3340
AM
6195 if (dynamic_addr > filedata->file_size
6196 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6197 {
6198 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6199 dynamic_addr = 0;
6200 dynamic_size = 0;
39e224f6 6201 }
252b5132
RH
6202 break;
6203
6204 case PT_INTERP:
13acb58d
AM
6205 if (segment->p_offset >= filedata->file_size
6206 || segment->p_filesz > filedata->file_size - segment->p_offset
6207 || segment->p_filesz - 1 >= (size_t) -2
6208 || fseek (filedata->handle,
6209 filedata->archive_file_offset + (long) segment->p_offset,
6210 SEEK_SET))
252b5132
RH
6211 error (_("Unable to find program interpreter name\n"));
6212 else
6213 {
13acb58d
AM
6214 size_t len = segment->p_filesz;
6215 free (filedata->program_interpreter);
6216 filedata->program_interpreter = xmalloc (len + 1);
6217 len = fread (filedata->program_interpreter, 1, len,
6218 filedata->handle);
6219 filedata->program_interpreter[len] = 0;
252b5132
RH
6220
6221 if (do_segments)
f54498b4 6222 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6223 filedata->program_interpreter);
252b5132
RH
6224 }
6225 break;
6226 }
252b5132
RH
6227 }
6228
dda8d76d
NC
6229 if (do_segments
6230 && filedata->section_headers != NULL
6231 && filedata->string_table != NULL)
252b5132
RH
6232 {
6233 printf (_("\n Section to Segment mapping:\n"));
6234 printf (_(" Segment Sections...\n"));
6235
dda8d76d 6236 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6237 {
9ad5cbcf 6238 unsigned int j;
2cf0635d 6239 Elf_Internal_Shdr * section;
252b5132 6240
dda8d76d
NC
6241 segment = filedata->program_headers + i;
6242 section = filedata->section_headers + 1;
252b5132
RH
6243
6244 printf (" %2.2d ", i);
6245
dda8d76d 6246 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6247 {
f4638467
AM
6248 if (!ELF_TBSS_SPECIAL (section, segment)
6249 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6250 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6251 }
6252
6253 putc ('\n',stdout);
6254 }
6255 }
6256
93df3340
AM
6257 filedata->dynamic_addr = dynamic_addr;
6258 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6259 return;
6260
6261 no_headers:
6262 filedata->dynamic_addr = 0;
6263 filedata->dynamic_size = 1;
252b5132
RH
6264}
6265
6266
d93f0186
NC
6267/* Find the file offset corresponding to VMA by using the program headers. */
6268
6269static long
625d49fc 6270offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6271{
2cf0635d 6272 Elf_Internal_Phdr * seg;
d93f0186 6273
dda8d76d 6274 if (! get_program_headers (filedata))
d93f0186
NC
6275 {
6276 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6277 return (long) vma;
6278 }
6279
dda8d76d
NC
6280 for (seg = filedata->program_headers;
6281 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6282 ++seg)
6283 {
6284 if (seg->p_type != PT_LOAD)
6285 continue;
6286
6287 if (vma >= (seg->p_vaddr & -seg->p_align)
6288 && vma + size <= seg->p_vaddr + seg->p_filesz)
6289 return vma - seg->p_vaddr + seg->p_offset;
6290 }
6291
6292 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6293 (unsigned long) vma);
d93f0186
NC
6294 return (long) vma;
6295}
6296
6297
dda8d76d
NC
6298/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6299 If PROBE is true, this is just a probe and we do not generate any error
6300 messages if the load fails. */
049b0c3a 6301
015dc7e1
AM
6302static bool
6303get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6304{
2cf0635d
NC
6305 Elf32_External_Shdr * shdrs;
6306 Elf_Internal_Shdr * internal;
dda8d76d
NC
6307 unsigned int i;
6308 unsigned int size = filedata->file_header.e_shentsize;
6309 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6310
6311 /* PR binutils/17531: Cope with unexpected section header sizes. */
6312 if (size == 0 || num == 0)
015dc7e1 6313 return false;
049b0c3a
NC
6314 if (size < sizeof * shdrs)
6315 {
6316 if (! probe)
6317 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6318 return false;
049b0c3a
NC
6319 }
6320 if (!probe && size > sizeof * shdrs)
6321 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6322
dda8d76d 6323 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6324 size, num,
6325 probe ? NULL : _("section headers"));
6326 if (shdrs == NULL)
015dc7e1 6327 return false;
252b5132 6328
dda8d76d
NC
6329 filedata->section_headers = (Elf_Internal_Shdr *)
6330 cmalloc (num, sizeof (Elf_Internal_Shdr));
6331 if (filedata->section_headers == NULL)
252b5132 6332 {
049b0c3a 6333 if (!probe)
8b73c356 6334 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6335 free (shdrs);
015dc7e1 6336 return false;
252b5132
RH
6337 }
6338
dda8d76d 6339 for (i = 0, internal = filedata->section_headers;
560f3c1c 6340 i < num;
b34976b6 6341 i++, internal++)
252b5132
RH
6342 {
6343 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6344 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6345 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6346 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6347 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6348 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6349 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6350 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6351 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6352 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6353 if (!probe && internal->sh_link > num)
6354 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6355 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6356 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6357 }
6358
6359 free (shdrs);
015dc7e1 6360 return true;
252b5132
RH
6361}
6362
dda8d76d
NC
6363/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6364
015dc7e1
AM
6365static bool
6366get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6367{
dda8d76d
NC
6368 Elf64_External_Shdr * shdrs;
6369 Elf_Internal_Shdr * internal;
6370 unsigned int i;
6371 unsigned int size = filedata->file_header.e_shentsize;
6372 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6373
6374 /* PR binutils/17531: Cope with unexpected section header sizes. */
6375 if (size == 0 || num == 0)
015dc7e1 6376 return false;
dda8d76d 6377
049b0c3a
NC
6378 if (size < sizeof * shdrs)
6379 {
6380 if (! probe)
6381 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6382 return false;
049b0c3a 6383 }
dda8d76d 6384
049b0c3a
NC
6385 if (! probe && size > sizeof * shdrs)
6386 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6387
dda8d76d
NC
6388 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6389 filedata->file_header.e_shoff,
049b0c3a
NC
6390 size, num,
6391 probe ? NULL : _("section headers"));
6392 if (shdrs == NULL)
015dc7e1 6393 return false;
9ea033b2 6394
dda8d76d
NC
6395 filedata->section_headers = (Elf_Internal_Shdr *)
6396 cmalloc (num, sizeof (Elf_Internal_Shdr));
6397 if (filedata->section_headers == NULL)
9ea033b2 6398 {
049b0c3a 6399 if (! probe)
8b73c356 6400 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6401 free (shdrs);
015dc7e1 6402 return false;
9ea033b2
NC
6403 }
6404
dda8d76d 6405 for (i = 0, internal = filedata->section_headers;
560f3c1c 6406 i < num;
b34976b6 6407 i++, internal++)
9ea033b2
NC
6408 {
6409 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6410 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6411 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6412 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6413 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6414 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6415 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6416 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6417 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6418 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6419 if (!probe && internal->sh_link > num)
6420 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6421 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6422 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6423 }
6424
6425 free (shdrs);
015dc7e1 6426 return true;
9ea033b2
NC
6427}
6428
4de91c10
AM
6429static bool
6430get_section_headers (Filedata *filedata, bool probe)
6431{
6432 if (filedata->section_headers != NULL)
6433 return true;
6434
4de91c10
AM
6435 if (is_32bit_elf)
6436 return get_32bit_section_headers (filedata, probe);
6437 else
6438 return get_64bit_section_headers (filedata, probe);
6439}
6440
252b5132 6441static Elf_Internal_Sym *
dda8d76d
NC
6442get_32bit_elf_symbols (Filedata * filedata,
6443 Elf_Internal_Shdr * section,
6444 unsigned long * num_syms_return)
252b5132 6445{
ba5cdace 6446 unsigned long number = 0;
dd24e3da 6447 Elf32_External_Sym * esyms = NULL;
ba5cdace 6448 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6449 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6450 Elf_Internal_Sym * psym;
b34976b6 6451 unsigned int j;
e3d39609 6452 elf_section_list * entry;
252b5132 6453
c9c1d674
EG
6454 if (section->sh_size == 0)
6455 {
6456 if (num_syms_return != NULL)
6457 * num_syms_return = 0;
6458 return NULL;
6459 }
6460
dd24e3da 6461 /* Run some sanity checks first. */
c9c1d674 6462 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6463 {
c9c1d674 6464 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6465 printable_section_name (filedata, section),
6466 (unsigned long) section->sh_entsize);
ba5cdace 6467 goto exit_point;
dd24e3da
NC
6468 }
6469
dda8d76d 6470 if (section->sh_size > filedata->file_size)
f54498b4
NC
6471 {
6472 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6473 printable_section_name (filedata, section),
6474 (unsigned long) section->sh_size);
f54498b4
NC
6475 goto exit_point;
6476 }
6477
dd24e3da
NC
6478 number = section->sh_size / section->sh_entsize;
6479
6480 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6481 {
c9c1d674 6482 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6483 (unsigned long) section->sh_size,
dda8d76d 6484 printable_section_name (filedata, section),
8066deb1 6485 (unsigned long) section->sh_entsize);
ba5cdace 6486 goto exit_point;
dd24e3da
NC
6487 }
6488
dda8d76d 6489 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6490 section->sh_size, _("symbols"));
dd24e3da 6491 if (esyms == NULL)
ba5cdace 6492 goto exit_point;
252b5132 6493
e3d39609 6494 shndx = NULL;
978c4450 6495 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6496 {
6497 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6498 continue;
6499
6500 if (shndx != NULL)
6501 {
6502 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6503 free (shndx);
6504 }
6505
6506 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6507 entry->hdr->sh_offset,
6508 1, entry->hdr->sh_size,
6509 _("symbol table section indices"));
6510 if (shndx == NULL)
6511 goto exit_point;
6512
6513 /* PR17531: file: heap-buffer-overflow */
6514 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6515 {
6516 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6517 printable_section_name (filedata, entry->hdr),
6518 (unsigned long) entry->hdr->sh_size,
6519 (unsigned long) section->sh_size);
6520 goto exit_point;
c9c1d674 6521 }
e3d39609 6522 }
9ad5cbcf 6523
3f5e193b 6524 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6525
6526 if (isyms == NULL)
6527 {
8b73c356
NC
6528 error (_("Out of memory reading %lu symbols\n"),
6529 (unsigned long) number);
dd24e3da 6530 goto exit_point;
252b5132
RH
6531 }
6532
dd24e3da 6533 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6534 {
6535 psym->st_name = BYTE_GET (esyms[j].st_name);
6536 psym->st_value = BYTE_GET (esyms[j].st_value);
6537 psym->st_size = BYTE_GET (esyms[j].st_size);
6538 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6539 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6540 psym->st_shndx
6541 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6542 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6543 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6544 psym->st_info = BYTE_GET (esyms[j].st_info);
6545 psym->st_other = BYTE_GET (esyms[j].st_other);
6546 }
6547
dd24e3da 6548 exit_point:
e3d39609
NC
6549 free (shndx);
6550 free (esyms);
252b5132 6551
ba5cdace
NC
6552 if (num_syms_return != NULL)
6553 * num_syms_return = isyms == NULL ? 0 : number;
6554
252b5132
RH
6555 return isyms;
6556}
6557
9ea033b2 6558static Elf_Internal_Sym *
dda8d76d
NC
6559get_64bit_elf_symbols (Filedata * filedata,
6560 Elf_Internal_Shdr * section,
6561 unsigned long * num_syms_return)
9ea033b2 6562{
ba5cdace
NC
6563 unsigned long number = 0;
6564 Elf64_External_Sym * esyms = NULL;
6565 Elf_External_Sym_Shndx * shndx = NULL;
6566 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6567 Elf_Internal_Sym * psym;
b34976b6 6568 unsigned int j;
e3d39609 6569 elf_section_list * entry;
9ea033b2 6570
c9c1d674
EG
6571 if (section->sh_size == 0)
6572 {
6573 if (num_syms_return != NULL)
6574 * num_syms_return = 0;
6575 return NULL;
6576 }
6577
dd24e3da 6578 /* Run some sanity checks first. */
c9c1d674 6579 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6580 {
c9c1d674 6581 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6582 printable_section_name (filedata, section),
8066deb1 6583 (unsigned long) section->sh_entsize);
ba5cdace 6584 goto exit_point;
dd24e3da
NC
6585 }
6586
dda8d76d 6587 if (section->sh_size > filedata->file_size)
f54498b4
NC
6588 {
6589 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6590 printable_section_name (filedata, section),
8066deb1 6591 (unsigned long) section->sh_size);
f54498b4
NC
6592 goto exit_point;
6593 }
6594
dd24e3da
NC
6595 number = section->sh_size / section->sh_entsize;
6596
6597 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6598 {
c9c1d674 6599 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6600 (unsigned long) section->sh_size,
dda8d76d 6601 printable_section_name (filedata, section),
8066deb1 6602 (unsigned long) section->sh_entsize);
ba5cdace 6603 goto exit_point;
dd24e3da
NC
6604 }
6605
dda8d76d 6606 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6607 section->sh_size, _("symbols"));
a6e9f9df 6608 if (!esyms)
ba5cdace 6609 goto exit_point;
9ea033b2 6610
e3d39609 6611 shndx = NULL;
978c4450 6612 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6613 {
6614 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6615 continue;
6616
6617 if (shndx != NULL)
6618 {
6619 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6620 free (shndx);
c9c1d674 6621 }
e3d39609
NC
6622
6623 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6624 entry->hdr->sh_offset,
6625 1, entry->hdr->sh_size,
6626 _("symbol table section indices"));
6627 if (shndx == NULL)
6628 goto exit_point;
6629
6630 /* PR17531: file: heap-buffer-overflow */
6631 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6632 {
6633 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6634 printable_section_name (filedata, entry->hdr),
6635 (unsigned long) entry->hdr->sh_size,
6636 (unsigned long) section->sh_size);
6637 goto exit_point;
6638 }
6639 }
9ad5cbcf 6640
3f5e193b 6641 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6642
6643 if (isyms == NULL)
6644 {
8b73c356
NC
6645 error (_("Out of memory reading %lu symbols\n"),
6646 (unsigned long) number);
ba5cdace 6647 goto exit_point;
9ea033b2
NC
6648 }
6649
ba5cdace 6650 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6651 {
6652 psym->st_name = BYTE_GET (esyms[j].st_name);
6653 psym->st_info = BYTE_GET (esyms[j].st_info);
6654 psym->st_other = BYTE_GET (esyms[j].st_other);
6655 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6656
4fbb74a6 6657 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6658 psym->st_shndx
6659 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6660 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6661 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6662
66543521
AM
6663 psym->st_value = BYTE_GET (esyms[j].st_value);
6664 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6665 }
6666
ba5cdace 6667 exit_point:
e3d39609
NC
6668 free (shndx);
6669 free (esyms);
ba5cdace
NC
6670
6671 if (num_syms_return != NULL)
6672 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6673
6674 return isyms;
6675}
6676
4de91c10
AM
6677static Elf_Internal_Sym *
6678get_elf_symbols (Filedata *filedata,
6679 Elf_Internal_Shdr *section,
6680 unsigned long *num_syms_return)
6681{
6682 if (is_32bit_elf)
6683 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6684 else
6685 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6686}
6687
d1133906 6688static const char *
625d49fc 6689get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 6690{
5477e8a0 6691 static char buff[1024];
2cf0635d 6692 char * p = buff;
32ec8896
NC
6693 unsigned int field_size = is_32bit_elf ? 8 : 16;
6694 signed int sindex;
6695 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
6696 uint64_t os_flags = 0;
6697 uint64_t proc_flags = 0;
6698 uint64_t unknown_flags = 0;
148b93f2 6699 static const struct
5477e8a0 6700 {
2cf0635d 6701 const char * str;
32ec8896 6702 unsigned int len;
5477e8a0
L
6703 }
6704 flags [] =
6705 {
cfcac11d
NC
6706 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6707 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6708 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6709 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6710 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6711 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6712 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6713 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6714 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6715 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6716 /* IA-64 specific. */
6717 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6718 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6719 /* IA-64 OpenVMS specific. */
6720 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6721 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6722 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6723 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6724 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6725 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6726 /* Generic. */
cfcac11d 6727 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6728 /* SPARC specific. */
77115a4a 6729 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6730 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6731 /* ARM specific. */
6732 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6733 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6734 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6735 /* GNU specific. */
6736 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6737 /* VLE specific. */
6738 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6739 /* GNU specific. */
6740 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6741 };
6742
6743 if (do_section_details)
6744 {
8d5ff12c
L
6745 sprintf (buff, "[%*.*lx]: ",
6746 field_size, field_size, (unsigned long) sh_flags);
6747 p += field_size + 4;
5477e8a0 6748 }
76da6bbe 6749
d1133906
NC
6750 while (sh_flags)
6751 {
625d49fc 6752 uint64_t flag;
d1133906
NC
6753
6754 flag = sh_flags & - sh_flags;
6755 sh_flags &= ~ flag;
76da6bbe 6756
5477e8a0 6757 if (do_section_details)
d1133906 6758 {
5477e8a0
L
6759 switch (flag)
6760 {
91d6fa6a
NC
6761 case SHF_WRITE: sindex = 0; break;
6762 case SHF_ALLOC: sindex = 1; break;
6763 case SHF_EXECINSTR: sindex = 2; break;
6764 case SHF_MERGE: sindex = 3; break;
6765 case SHF_STRINGS: sindex = 4; break;
6766 case SHF_INFO_LINK: sindex = 5; break;
6767 case SHF_LINK_ORDER: sindex = 6; break;
6768 case SHF_OS_NONCONFORMING: sindex = 7; break;
6769 case SHF_GROUP: sindex = 8; break;
6770 case SHF_TLS: sindex = 9; break;
18ae9cc1 6771 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6772 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6773
5477e8a0 6774 default:
91d6fa6a 6775 sindex = -1;
dda8d76d 6776 switch (filedata->file_header.e_machine)
148b93f2 6777 {
cfcac11d 6778 case EM_IA_64:
148b93f2 6779 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6780 sindex = 10;
148b93f2 6781 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6782 sindex = 11;
dda8d76d 6783 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6784 switch (flag)
6785 {
91d6fa6a
NC
6786 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6787 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6788 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6789 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6790 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6791 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6792 default: break;
6793 }
cfcac11d
NC
6794 break;
6795
caa83f8b 6796 case EM_386:
22abe556 6797 case EM_IAMCU:
caa83f8b 6798 case EM_X86_64:
7f502d6c 6799 case EM_L1OM:
7a9068fe 6800 case EM_K1OM:
cfcac11d
NC
6801 case EM_OLD_SPARCV9:
6802 case EM_SPARC32PLUS:
6803 case EM_SPARCV9:
6804 case EM_SPARC:
18ae9cc1 6805 if (flag == SHF_ORDERED)
91d6fa6a 6806 sindex = 19;
cfcac11d 6807 break;
ac4c9b04
MG
6808
6809 case EM_ARM:
6810 switch (flag)
6811 {
6812 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6813 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6814 case SHF_COMDEF: sindex = 23; break;
6815 default: break;
6816 }
6817 break;
83eef883
AFB
6818 case EM_PPC:
6819 if (flag == SHF_PPC_VLE)
6820 sindex = 25;
6821 break;
99fabbc9
JL
6822 default:
6823 break;
6824 }
ac4c9b04 6825
99fabbc9
JL
6826 switch (filedata->file_header.e_ident[EI_OSABI])
6827 {
6828 case ELFOSABI_GNU:
6829 case ELFOSABI_FREEBSD:
6830 if (flag == SHF_GNU_RETAIN)
6831 sindex = 26;
6832 /* Fall through */
6833 case ELFOSABI_NONE:
6834 if (flag == SHF_GNU_MBIND)
6835 /* We should not recognize SHF_GNU_MBIND for
6836 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6837 not set the EI_OSABI header byte. */
6838 sindex = 24;
6839 break;
cfcac11d
NC
6840 default:
6841 break;
148b93f2 6842 }
99fabbc9 6843 break;
5477e8a0
L
6844 }
6845
91d6fa6a 6846 if (sindex != -1)
5477e8a0 6847 {
8d5ff12c
L
6848 if (p != buff + field_size + 4)
6849 {
6850 if (size < (10 + 2))
bee0ee85
NC
6851 {
6852 warn (_("Internal error: not enough buffer room for section flag info"));
6853 return _("<unknown>");
6854 }
8d5ff12c
L
6855 size -= 2;
6856 *p++ = ',';
6857 *p++ = ' ';
6858 }
6859
91d6fa6a
NC
6860 size -= flags [sindex].len;
6861 p = stpcpy (p, flags [sindex].str);
5477e8a0 6862 }
3b22753a 6863 else if (flag & SHF_MASKOS)
8d5ff12c 6864 os_flags |= flag;
d1133906 6865 else if (flag & SHF_MASKPROC)
8d5ff12c 6866 proc_flags |= flag;
d1133906 6867 else
8d5ff12c 6868 unknown_flags |= flag;
5477e8a0
L
6869 }
6870 else
6871 {
6872 switch (flag)
6873 {
6874 case SHF_WRITE: *p = 'W'; break;
6875 case SHF_ALLOC: *p = 'A'; break;
6876 case SHF_EXECINSTR: *p = 'X'; break;
6877 case SHF_MERGE: *p = 'M'; break;
6878 case SHF_STRINGS: *p = 'S'; break;
6879 case SHF_INFO_LINK: *p = 'I'; break;
6880 case SHF_LINK_ORDER: *p = 'L'; break;
6881 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6882 case SHF_GROUP: *p = 'G'; break;
6883 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6884 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6885 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6886
6887 default:
dda8d76d
NC
6888 if ((filedata->file_header.e_machine == EM_X86_64
6889 || filedata->file_header.e_machine == EM_L1OM
6890 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6891 && flag == SHF_X86_64_LARGE)
6892 *p = 'l';
dda8d76d 6893 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6894 && flag == SHF_ARM_PURECODE)
99fabbc9 6895 *p = 'y';
dda8d76d 6896 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6897 && flag == SHF_PPC_VLE)
99fabbc9 6898 *p = 'v';
5477e8a0
L
6899 else if (flag & SHF_MASKOS)
6900 {
99fabbc9
JL
6901 switch (filedata->file_header.e_ident[EI_OSABI])
6902 {
6903 case ELFOSABI_GNU:
6904 case ELFOSABI_FREEBSD:
6905 if (flag == SHF_GNU_RETAIN)
6906 {
6907 *p = 'R';
6908 break;
6909 }
6910 /* Fall through */
6911 case ELFOSABI_NONE:
6912 if (flag == SHF_GNU_MBIND)
6913 {
6914 /* We should not recognize SHF_GNU_MBIND for
6915 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6916 not set the EI_OSABI header byte. */
6917 *p = 'D';
6918 break;
6919 }
6920 /* Fall through */
6921 default:
6922 *p = 'o';
6923 sh_flags &= ~SHF_MASKOS;
6924 break;
6925 }
5477e8a0
L
6926 }
6927 else if (flag & SHF_MASKPROC)
6928 {
6929 *p = 'p';
6930 sh_flags &= ~ SHF_MASKPROC;
6931 }
6932 else
6933 *p = 'x';
6934 break;
6935 }
6936 p++;
d1133906
NC
6937 }
6938 }
76da6bbe 6939
8d5ff12c
L
6940 if (do_section_details)
6941 {
6942 if (os_flags)
6943 {
6944 size -= 5 + field_size;
6945 if (p != buff + field_size + 4)
6946 {
6947 if (size < (2 + 1))
bee0ee85
NC
6948 {
6949 warn (_("Internal error: not enough buffer room for section flag info"));
6950 return _("<unknown>");
6951 }
8d5ff12c
L
6952 size -= 2;
6953 *p++ = ',';
6954 *p++ = ' ';
6955 }
6956 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6957 (unsigned long) os_flags);
6958 p += 5 + field_size;
6959 }
6960 if (proc_flags)
6961 {
6962 size -= 7 + field_size;
6963 if (p != buff + field_size + 4)
6964 {
6965 if (size < (2 + 1))
bee0ee85
NC
6966 {
6967 warn (_("Internal error: not enough buffer room for section flag info"));
6968 return _("<unknown>");
6969 }
8d5ff12c
L
6970 size -= 2;
6971 *p++ = ',';
6972 *p++ = ' ';
6973 }
6974 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6975 (unsigned long) proc_flags);
6976 p += 7 + field_size;
6977 }
6978 if (unknown_flags)
6979 {
6980 size -= 10 + field_size;
6981 if (p != buff + field_size + 4)
6982 {
6983 if (size < (2 + 1))
bee0ee85
NC
6984 {
6985 warn (_("Internal error: not enough buffer room for section flag info"));
6986 return _("<unknown>");
6987 }
8d5ff12c
L
6988 size -= 2;
6989 *p++ = ',';
6990 *p++ = ' ';
6991 }
2b692964 6992 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6993 (unsigned long) unknown_flags);
6994 p += 10 + field_size;
6995 }
6996 }
6997
e9e44622 6998 *p = '\0';
d1133906
NC
6999 return buff;
7000}
7001
5844b465 7002static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7003get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7004 uint64_t size)
77115a4a
L
7005{
7006 if (is_32bit_elf)
7007 {
7008 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7009
ebdf1ebf
NC
7010 if (size < sizeof (* echdr))
7011 {
7012 error (_("Compressed section is too small even for a compression header\n"));
7013 return 0;
7014 }
7015
77115a4a
L
7016 chdr->ch_type = BYTE_GET (echdr->ch_type);
7017 chdr->ch_size = BYTE_GET (echdr->ch_size);
7018 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7019 return sizeof (*echdr);
7020 }
7021 else
7022 {
7023 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7024
ebdf1ebf
NC
7025 if (size < sizeof (* echdr))
7026 {
7027 error (_("Compressed section is too small even for a compression header\n"));
7028 return 0;
7029 }
7030
77115a4a
L
7031 chdr->ch_type = BYTE_GET (echdr->ch_type);
7032 chdr->ch_size = BYTE_GET (echdr->ch_size);
7033 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7034 return sizeof (*echdr);
7035 }
7036}
7037
015dc7e1 7038static bool
dda8d76d 7039process_section_headers (Filedata * filedata)
252b5132 7040{
2cf0635d 7041 Elf_Internal_Shdr * section;
b34976b6 7042 unsigned int i;
252b5132 7043
dda8d76d 7044 if (filedata->file_header.e_shnum == 0)
252b5132 7045 {
82f2dbf7 7046 /* PR binutils/12467. */
dda8d76d 7047 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7048 {
7049 warn (_("possibly corrupt ELF file header - it has a non-zero"
7050 " section header offset, but no section headers\n"));
015dc7e1 7051 return false;
32ec8896 7052 }
82f2dbf7 7053 else if (do_sections)
252b5132
RH
7054 printf (_("\nThere are no sections in this file.\n"));
7055
015dc7e1 7056 return true;
252b5132
RH
7057 }
7058
7059 if (do_sections && !do_header)
ca0e11aa
NC
7060 {
7061 if (filedata->is_separate && process_links)
7062 printf (_("In linked file '%s': "), filedata->file_name);
7063 if (! filedata->is_separate || process_links)
7064 printf (ngettext ("There is %d section header, "
7065 "starting at offset 0x%lx:\n",
7066 "There are %d section headers, "
7067 "starting at offset 0x%lx:\n",
7068 filedata->file_header.e_shnum),
7069 filedata->file_header.e_shnum,
7070 (unsigned long) filedata->file_header.e_shoff);
7071 }
252b5132 7072
4de91c10
AM
7073 if (!get_section_headers (filedata, false))
7074 return false;
252b5132
RH
7075
7076 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7077 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7078 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7079 {
dda8d76d 7080 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7081
c256ffe7
JJ
7082 if (section->sh_size != 0)
7083 {
dda8d76d
NC
7084 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7085 1, section->sh_size,
7086 _("string table"));
0de14b54 7087
dda8d76d 7088 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7089 }
252b5132
RH
7090 }
7091
7092 /* Scan the sections for the dynamic symbol table
e3c8793a 7093 and dynamic string table and debug sections. */
89fac5e3 7094 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7095 switch (filedata->file_header.e_machine)
89fac5e3
RS
7096 {
7097 case EM_MIPS:
7098 case EM_MIPS_RS3_LE:
7099 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7100 FDE addresses. However, the ABI also has a semi-official ILP32
7101 variant for which the normal FDE address size rules apply.
7102
7103 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7104 section, where XX is the size of longs in bits. Unfortunately,
7105 earlier compilers provided no way of distinguishing ILP32 objects
7106 from LP64 objects, so if there's any doubt, we should assume that
7107 the official LP64 form is being used. */
dda8d76d
NC
7108 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7109 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7110 eh_addr_size = 8;
7111 break;
0f56a26a
DD
7112
7113 case EM_H8_300:
7114 case EM_H8_300H:
dda8d76d 7115 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7116 {
7117 case E_H8_MACH_H8300:
7118 case E_H8_MACH_H8300HN:
7119 case E_H8_MACH_H8300SN:
7120 case E_H8_MACH_H8300SXN:
7121 eh_addr_size = 2;
7122 break;
7123 case E_H8_MACH_H8300H:
7124 case E_H8_MACH_H8300S:
7125 case E_H8_MACH_H8300SX:
7126 eh_addr_size = 4;
7127 break;
7128 }
f4236fe4
DD
7129 break;
7130
ff7eeb89 7131 case EM_M32C_OLD:
f4236fe4 7132 case EM_M32C:
dda8d76d 7133 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7134 {
7135 case EF_M32C_CPU_M16C:
7136 eh_addr_size = 2;
7137 break;
7138 }
7139 break;
89fac5e3
RS
7140 }
7141
76ca31c0
NC
7142#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7143 do \
7144 { \
be7d229a 7145 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7146 if (section->sh_entsize != expected_entsize) \
9dd3a467 7147 { \
f493c217 7148 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7149 i, section->sh_entsize); \
f493c217 7150 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7151 expected_entsize); \
9dd3a467 7152 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7153 } \
7154 } \
08d8fa11 7155 while (0)
9dd3a467
NC
7156
7157#define CHECK_ENTSIZE(section, i, type) \
1b513401 7158 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7159 sizeof (Elf64_External_##type))
7160
dda8d76d
NC
7161 for (i = 0, section = filedata->section_headers;
7162 i < filedata->file_header.e_shnum;
b34976b6 7163 i++, section++)
252b5132 7164 {
84714f86 7165 const char *name = section_name_print (filedata, section);
252b5132 7166
1b513401
NC
7167 /* Run some sanity checks on the headers and
7168 possibly fill in some file data as well. */
7169 switch (section->sh_type)
252b5132 7170 {
1b513401 7171 case SHT_DYNSYM:
978c4450 7172 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7173 {
7174 error (_("File contains multiple dynamic symbol tables\n"));
7175 continue;
7176 }
7177
08d8fa11 7178 CHECK_ENTSIZE (section, i, Sym);
978c4450 7179 filedata->dynamic_symbols
4de91c10 7180 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7181 filedata->dynamic_symtab_section = section;
1b513401
NC
7182 break;
7183
7184 case SHT_STRTAB:
7185 if (streq (name, ".dynstr"))
252b5132 7186 {
1b513401
NC
7187 if (filedata->dynamic_strings != NULL)
7188 {
7189 error (_("File contains multiple dynamic string tables\n"));
7190 continue;
7191 }
7192
7193 filedata->dynamic_strings
7194 = (char *) get_data (NULL, filedata, section->sh_offset,
7195 1, section->sh_size, _("dynamic strings"));
7196 filedata->dynamic_strings_length
7197 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7198 filedata->dynamic_strtab_section = section;
252b5132 7199 }
1b513401
NC
7200 break;
7201
7202 case SHT_SYMTAB_SHNDX:
7203 {
7204 elf_section_list * entry = xmalloc (sizeof * entry);
7205
7206 entry->hdr = section;
7207 entry->next = filedata->symtab_shndx_list;
7208 filedata->symtab_shndx_list = entry;
7209 }
7210 break;
7211
7212 case SHT_SYMTAB:
7213 CHECK_ENTSIZE (section, i, Sym);
7214 break;
7215
7216 case SHT_GROUP:
7217 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7218 break;
252b5132 7219
1b513401
NC
7220 case SHT_REL:
7221 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7222 if (do_checks && section->sh_size == 0)
1b513401
NC
7223 warn (_("Section '%s': zero-sized relocation section\n"), name);
7224 break;
7225
7226 case SHT_RELA:
7227 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7228 if (do_checks && section->sh_size == 0)
1b513401
NC
7229 warn (_("Section '%s': zero-sized relocation section\n"), name);
7230 break;
7231
682351b9
AM
7232 case SHT_RELR:
7233 CHECK_ENTSIZE (section, i, Relr);
7234 break;
7235
1b513401
NC
7236 case SHT_NOTE:
7237 case SHT_PROGBITS:
546cb2d8
NC
7238 /* Having a zero sized section is not illegal according to the
7239 ELF standard, but it might be an indication that something
7240 is wrong. So issue a warning if we are running in lint mode. */
7241 if (do_checks && section->sh_size == 0)
1b513401
NC
7242 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7243 break;
7244
7245 default:
7246 break;
7247 }
7248
7249 if ((do_debugging || do_debug_info || do_debug_abbrevs
7250 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7251 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7252 || do_debug_str || do_debug_str_offsets || do_debug_loc
7253 || do_debug_ranges
1b513401 7254 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7255 && (startswith (name, ".debug_")
7256 || startswith (name, ".zdebug_")))
252b5132 7257 {
1b315056
CS
7258 if (name[1] == 'z')
7259 name += sizeof (".zdebug_") - 1;
7260 else
7261 name += sizeof (".debug_") - 1;
252b5132
RH
7262
7263 if (do_debugging
24d127aa
ML
7264 || (do_debug_info && startswith (name, "info"))
7265 || (do_debug_info && startswith (name, "types"))
7266 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7267 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7268 || (do_debug_lines && startswith (name, "line."))
7269 || (do_debug_pubnames && startswith (name, "pubnames"))
7270 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7271 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7272 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7273 || (do_debug_aranges && startswith (name, "aranges"))
7274 || (do_debug_ranges && startswith (name, "ranges"))
7275 || (do_debug_ranges && startswith (name, "rnglists"))
7276 || (do_debug_frames && startswith (name, "frame"))
7277 || (do_debug_macinfo && startswith (name, "macinfo"))
7278 || (do_debug_macinfo && startswith (name, "macro"))
7279 || (do_debug_str && startswith (name, "str"))
7280 || (do_debug_links && startswith (name, "sup"))
7281 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7282 || (do_debug_loc && startswith (name, "loc"))
7283 || (do_debug_loc && startswith (name, "loclists"))
7284 || (do_debug_addr && startswith (name, "addr"))
7285 || (do_debug_cu_index && startswith (name, "cu_index"))
7286 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7287 )
6431e409 7288 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7289 }
a262ae96 7290 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7291 else if ((do_debugging || do_debug_info)
24d127aa 7292 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7293 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7294 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7295 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7296 else if (do_gdb_index && (streq (name, ".gdb_index")
7297 || streq (name, ".debug_names")))
6431e409 7298 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7299 /* Trace sections for Itanium VMS. */
7300 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7301 || do_trace_aranges)
24d127aa 7302 && startswith (name, ".trace_"))
6f875884
TG
7303 {
7304 name += sizeof (".trace_") - 1;
7305
7306 if (do_debugging
7307 || (do_trace_info && streq (name, "info"))
7308 || (do_trace_abbrevs && streq (name, "abbrev"))
7309 || (do_trace_aranges && streq (name, "aranges"))
7310 )
6431e409 7311 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7312 }
dda8d76d 7313 else if ((do_debugging || do_debug_links)
24d127aa
ML
7314 && (startswith (name, ".gnu_debuglink")
7315 || startswith (name, ".gnu_debugaltlink")))
6431e409 7316 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7317 }
7318
7319 if (! do_sections)
015dc7e1 7320 return true;
252b5132 7321
ca0e11aa 7322 if (filedata->is_separate && ! process_links)
015dc7e1 7323 return true;
ca0e11aa
NC
7324
7325 if (filedata->is_separate)
7326 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7327 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7328 printf (_("\nSection Headers:\n"));
7329 else
7330 printf (_("\nSection Header:\n"));
76da6bbe 7331
f7a99963 7332 if (is_32bit_elf)
595cf52e 7333 {
5477e8a0 7334 if (do_section_details)
595cf52e
L
7335 {
7336 printf (_(" [Nr] Name\n"));
5477e8a0 7337 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7338 }
7339 else
7340 printf
7341 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7342 }
d974e256 7343 else if (do_wide)
595cf52e 7344 {
5477e8a0 7345 if (do_section_details)
595cf52e
L
7346 {
7347 printf (_(" [Nr] Name\n"));
5477e8a0 7348 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7349 }
7350 else
7351 printf
7352 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7353 }
f7a99963
NC
7354 else
7355 {
5477e8a0 7356 if (do_section_details)
595cf52e
L
7357 {
7358 printf (_(" [Nr] Name\n"));
5477e8a0
L
7359 printf (_(" Type Address Offset Link\n"));
7360 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7361 }
7362 else
7363 {
7364 printf (_(" [Nr] Name Type Address Offset\n"));
7365 printf (_(" Size EntSize Flags Link Info Align\n"));
7366 }
f7a99963 7367 }
252b5132 7368
5477e8a0
L
7369 if (do_section_details)
7370 printf (_(" Flags\n"));
7371
dda8d76d
NC
7372 for (i = 0, section = filedata->section_headers;
7373 i < filedata->file_header.e_shnum;
b34976b6 7374 i++, section++)
252b5132 7375 {
dd905818
NC
7376 /* Run some sanity checks on the section header. */
7377
7378 /* Check the sh_link field. */
7379 switch (section->sh_type)
7380 {
285e3f99
AM
7381 case SHT_REL:
7382 case SHT_RELA:
7383 if (section->sh_link == 0
7384 && (filedata->file_header.e_type == ET_EXEC
7385 || filedata->file_header.e_type == ET_DYN))
7386 /* A dynamic relocation section where all entries use a
7387 zero symbol index need not specify a symtab section. */
7388 break;
7389 /* Fall through. */
dd905818
NC
7390 case SHT_SYMTAB_SHNDX:
7391 case SHT_GROUP:
7392 case SHT_HASH:
7393 case SHT_GNU_HASH:
7394 case SHT_GNU_versym:
285e3f99 7395 if (section->sh_link == 0
dda8d76d
NC
7396 || section->sh_link >= filedata->file_header.e_shnum
7397 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7398 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7399 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7400 i, section->sh_link);
7401 break;
7402
7403 case SHT_DYNAMIC:
7404 case SHT_SYMTAB:
7405 case SHT_DYNSYM:
7406 case SHT_GNU_verneed:
7407 case SHT_GNU_verdef:
7408 case SHT_GNU_LIBLIST:
285e3f99 7409 if (section->sh_link == 0
dda8d76d
NC
7410 || section->sh_link >= filedata->file_header.e_shnum
7411 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7412 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7413 i, section->sh_link);
7414 break;
7415
7416 case SHT_INIT_ARRAY:
7417 case SHT_FINI_ARRAY:
7418 case SHT_PREINIT_ARRAY:
7419 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7420 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7421 i, section->sh_link);
7422 break;
7423
7424 default:
7425 /* FIXME: Add support for target specific section types. */
7426#if 0 /* Currently we do not check other section types as there are too
7427 many special cases. Stab sections for example have a type
7428 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7429 section. */
7430 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7431 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7432 i, section->sh_link);
7433#endif
7434 break;
7435 }
7436
7437 /* Check the sh_info field. */
7438 switch (section->sh_type)
7439 {
7440 case SHT_REL:
7441 case SHT_RELA:
285e3f99
AM
7442 if (section->sh_info == 0
7443 && (filedata->file_header.e_type == ET_EXEC
7444 || filedata->file_header.e_type == ET_DYN))
7445 /* Dynamic relocations apply to segments, so they do not
7446 need to specify the section they relocate. */
7447 break;
7448 if (section->sh_info == 0
dda8d76d
NC
7449 || section->sh_info >= filedata->file_header.e_shnum
7450 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7451 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7452 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7453 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7454 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7455 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7456 /* FIXME: Are other section types valid ? */
dda8d76d 7457 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7458 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7459 i, section->sh_info);
dd905818
NC
7460 break;
7461
7462 case SHT_DYNAMIC:
7463 case SHT_HASH:
7464 case SHT_SYMTAB_SHNDX:
7465 case SHT_INIT_ARRAY:
7466 case SHT_FINI_ARRAY:
7467 case SHT_PREINIT_ARRAY:
7468 if (section->sh_info != 0)
7469 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7470 i, section->sh_info);
7471 break;
7472
7473 case SHT_GROUP:
7474 case SHT_SYMTAB:
7475 case SHT_DYNSYM:
7476 /* A symbol index - we assume that it is valid. */
7477 break;
7478
7479 default:
7480 /* FIXME: Add support for target specific section types. */
7481 if (section->sh_type == SHT_NOBITS)
7482 /* NOBITS section headers with non-zero sh_info fields can be
7483 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7484 information. The stripped sections have their headers
7485 preserved but their types set to SHT_NOBITS. So do not check
7486 this type of section. */
dd905818
NC
7487 ;
7488 else if (section->sh_flags & SHF_INFO_LINK)
7489 {
dda8d76d 7490 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7491 warn (_("[%2u]: Expected link to another section in info field"), i);
7492 }
a91e1603
L
7493 else if (section->sh_type < SHT_LOOS
7494 && (section->sh_flags & SHF_GNU_MBIND) == 0
7495 && section->sh_info != 0)
dd905818
NC
7496 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7497 i, section->sh_info);
7498 break;
7499 }
7500
3e6b6445 7501 /* Check the sh_size field. */
dda8d76d 7502 if (section->sh_size > filedata->file_size
3e6b6445
NC
7503 && section->sh_type != SHT_NOBITS
7504 && section->sh_type != SHT_NULL
7505 && section->sh_type < SHT_LOOS)
7506 warn (_("Size of section %u is larger than the entire file!\n"), i);
7507
7bfd842d 7508 printf (" [%2u] ", i);
5477e8a0 7509 if (do_section_details)
dda8d76d 7510 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7511 else
84714f86 7512 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7513
ea52a088 7514 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7515 get_section_type_name (filedata, section->sh_type));
0b4362b0 7516
f7a99963
NC
7517 if (is_32bit_elf)
7518 {
cfcac11d
NC
7519 const char * link_too_big = NULL;
7520
f7a99963 7521 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7522
f7a99963
NC
7523 printf ( " %6.6lx %6.6lx %2.2lx",
7524 (unsigned long) section->sh_offset,
7525 (unsigned long) section->sh_size,
7526 (unsigned long) section->sh_entsize);
d1133906 7527
5477e8a0
L
7528 if (do_section_details)
7529 fputs (" ", stdout);
7530 else
dda8d76d 7531 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7532
dda8d76d 7533 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7534 {
7535 link_too_big = "";
7536 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7537 an error but it can have special values in Solaris binaries. */
dda8d76d 7538 switch (filedata->file_header.e_machine)
cfcac11d 7539 {
caa83f8b 7540 case EM_386:
22abe556 7541 case EM_IAMCU:
caa83f8b 7542 case EM_X86_64:
7f502d6c 7543 case EM_L1OM:
7a9068fe 7544 case EM_K1OM:
cfcac11d
NC
7545 case EM_OLD_SPARCV9:
7546 case EM_SPARC32PLUS:
7547 case EM_SPARCV9:
7548 case EM_SPARC:
7549 if (section->sh_link == (SHN_BEFORE & 0xffff))
7550 link_too_big = "BEFORE";
7551 else if (section->sh_link == (SHN_AFTER & 0xffff))
7552 link_too_big = "AFTER";
7553 break;
7554 default:
7555 break;
7556 }
7557 }
7558
7559 if (do_section_details)
7560 {
7561 if (link_too_big != NULL && * link_too_big)
7562 printf ("<%s> ", link_too_big);
7563 else
7564 printf ("%2u ", section->sh_link);
7565 printf ("%3u %2lu\n", section->sh_info,
7566 (unsigned long) section->sh_addralign);
7567 }
7568 else
7569 printf ("%2u %3u %2lu\n",
7570 section->sh_link,
7571 section->sh_info,
7572 (unsigned long) section->sh_addralign);
7573
7574 if (link_too_big && ! * link_too_big)
7575 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7576 i, section->sh_link);
f7a99963 7577 }
d974e256
JJ
7578 else if (do_wide)
7579 {
7580 print_vma (section->sh_addr, LONG_HEX);
7581
7582 if ((long) section->sh_offset == section->sh_offset)
7583 printf (" %6.6lx", (unsigned long) section->sh_offset);
7584 else
7585 {
7586 putchar (' ');
7587 print_vma (section->sh_offset, LONG_HEX);
7588 }
7589
7590 if ((unsigned long) section->sh_size == section->sh_size)
7591 printf (" %6.6lx", (unsigned long) section->sh_size);
7592 else
7593 {
7594 putchar (' ');
7595 print_vma (section->sh_size, LONG_HEX);
7596 }
7597
7598 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7599 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7600 else
7601 {
7602 putchar (' ');
7603 print_vma (section->sh_entsize, LONG_HEX);
7604 }
7605
5477e8a0
L
7606 if (do_section_details)
7607 fputs (" ", stdout);
7608 else
dda8d76d 7609 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7610
72de5009 7611 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7612
7613 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7614 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7615 else
7616 {
7617 print_vma (section->sh_addralign, DEC);
7618 putchar ('\n');
7619 }
7620 }
5477e8a0 7621 else if (do_section_details)
595cf52e 7622 {
55cc53e9 7623 putchar (' ');
595cf52e
L
7624 print_vma (section->sh_addr, LONG_HEX);
7625 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7626 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7627 else
7628 {
7629 printf (" ");
7630 print_vma (section->sh_offset, LONG_HEX);
7631 }
72de5009 7632 printf (" %u\n ", section->sh_link);
595cf52e 7633 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7634 putchar (' ');
595cf52e
L
7635 print_vma (section->sh_entsize, LONG_HEX);
7636
72de5009
AM
7637 printf (" %-16u %lu\n",
7638 section->sh_info,
595cf52e
L
7639 (unsigned long) section->sh_addralign);
7640 }
f7a99963
NC
7641 else
7642 {
7643 putchar (' ');
7644 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7645 if ((long) section->sh_offset == section->sh_offset)
7646 printf (" %8.8lx", (unsigned long) section->sh_offset);
7647 else
7648 {
7649 printf (" ");
7650 print_vma (section->sh_offset, LONG_HEX);
7651 }
f7a99963
NC
7652 printf ("\n ");
7653 print_vma (section->sh_size, LONG_HEX);
7654 printf (" ");
7655 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7656
dda8d76d 7657 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7658
72de5009
AM
7659 printf (" %2u %3u %lu\n",
7660 section->sh_link,
7661 section->sh_info,
f7a99963
NC
7662 (unsigned long) section->sh_addralign);
7663 }
5477e8a0
L
7664
7665 if (do_section_details)
77115a4a 7666 {
dda8d76d 7667 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7668 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7669 {
7670 /* Minimum section size is 12 bytes for 32-bit compression
7671 header + 12 bytes for compressed data header. */
7672 unsigned char buf[24];
d8024a91 7673
77115a4a 7674 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7675 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7676 sizeof (buf), _("compression header")))
7677 {
7678 Elf_Internal_Chdr chdr;
d8024a91 7679
5844b465
NC
7680 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7681 printf (_(" [<corrupt>]\n"));
77115a4a 7682 else
5844b465
NC
7683 {
7684 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7685 printf (" ZLIB, ");
1369522f
CC
7686 else if (chdr.ch_type == ELFCOMPRESS_ZSTD)
7687 printf (" ZSTD, ");
5844b465
NC
7688 else
7689 printf (_(" [<unknown>: 0x%x], "),
7690 chdr.ch_type);
7691 print_vma (chdr.ch_size, LONG_HEX);
7692 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7693 }
77115a4a
L
7694 }
7695 }
7696 }
252b5132
RH
7697 }
7698
5477e8a0 7699 if (!do_section_details)
3dbcc61d 7700 {
9fb71ee4
NC
7701 /* The ordering of the letters shown here matches the ordering of the
7702 corresponding SHF_xxx values, and hence the order in which these
7703 letters will be displayed to the user. */
7704 printf (_("Key to Flags:\n\
7705 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7706 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7707 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7708 switch (filedata->file_header.e_ident[EI_OSABI])
7709 {
7710 case ELFOSABI_GNU:
7711 case ELFOSABI_FREEBSD:
7712 printf (_("R (retain), "));
7713 /* Fall through */
7714 case ELFOSABI_NONE:
7715 printf (_("D (mbind), "));
7716 break;
7717 default:
7718 break;
7719 }
dda8d76d
NC
7720 if (filedata->file_header.e_machine == EM_X86_64
7721 || filedata->file_header.e_machine == EM_L1OM
7722 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7723 printf (_("l (large), "));
dda8d76d 7724 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7725 printf (_("y (purecode), "));
dda8d76d 7726 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7727 printf (_("v (VLE), "));
9fb71ee4 7728 printf ("p (processor specific)\n");
0b4362b0 7729 }
d1133906 7730
015dc7e1 7731 return true;
252b5132
RH
7732}
7733
015dc7e1 7734static bool
28d13567
AM
7735get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7736 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7737 char **strtab, unsigned long *strtablen)
7738{
7739 *strtab = NULL;
7740 *strtablen = 0;
4de91c10 7741 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7742
7743 if (*symtab == NULL)
015dc7e1 7744 return false;
28d13567
AM
7745
7746 if (symsec->sh_link != 0)
7747 {
7748 Elf_Internal_Shdr *strsec;
7749
7750 if (symsec->sh_link >= filedata->file_header.e_shnum)
7751 {
7752 error (_("Bad sh_link in symbol table section\n"));
7753 free (*symtab);
7754 *symtab = NULL;
7755 *nsyms = 0;
015dc7e1 7756 return false;
28d13567
AM
7757 }
7758
7759 strsec = filedata->section_headers + symsec->sh_link;
7760
7761 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7762 1, strsec->sh_size, _("string table"));
7763 if (*strtab == NULL)
7764 {
7765 free (*symtab);
7766 *symtab = NULL;
7767 *nsyms = 0;
015dc7e1 7768 return false;
28d13567
AM
7769 }
7770 *strtablen = strsec->sh_size;
7771 }
015dc7e1 7772 return true;
28d13567
AM
7773}
7774
f5842774
L
7775static const char *
7776get_group_flags (unsigned int flags)
7777{
1449284b 7778 static char buff[128];
220453ec 7779
6d913794
NC
7780 if (flags == 0)
7781 return "";
7782 else if (flags == GRP_COMDAT)
7783 return "COMDAT ";
f5842774 7784
89246a0e
AM
7785 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7786 flags,
7787 flags & GRP_MASKOS ? _("<OS specific>") : "",
7788 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7789 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7790 ? _("<unknown>") : ""));
6d913794 7791
f5842774
L
7792 return buff;
7793}
7794
015dc7e1 7795static bool
dda8d76d 7796process_section_groups (Filedata * filedata)
f5842774 7797{
2cf0635d 7798 Elf_Internal_Shdr * section;
f5842774 7799 unsigned int i;
2cf0635d
NC
7800 struct group * group;
7801 Elf_Internal_Shdr * symtab_sec;
7802 Elf_Internal_Shdr * strtab_sec;
7803 Elf_Internal_Sym * symtab;
ba5cdace 7804 unsigned long num_syms;
2cf0635d 7805 char * strtab;
c256ffe7 7806 size_t strtab_size;
d1f5c6e3
L
7807
7808 /* Don't process section groups unless needed. */
7809 if (!do_unwind && !do_section_groups)
015dc7e1 7810 return true;
f5842774 7811
dda8d76d 7812 if (filedata->file_header.e_shnum == 0)
f5842774
L
7813 {
7814 if (do_section_groups)
ca0e11aa
NC
7815 {
7816 if (filedata->is_separate)
7817 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7818 filedata->file_name);
7819 else
7820 printf (_("\nThere are no section groups in this file.\n"));
7821 }
015dc7e1 7822 return true;
f5842774
L
7823 }
7824
dda8d76d 7825 if (filedata->section_headers == NULL)
f5842774
L
7826 {
7827 error (_("Section headers are not available!\n"));
fa1908fd 7828 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7829 return false;
f5842774
L
7830 }
7831
978c4450
AM
7832 filedata->section_headers_groups
7833 = (struct group **) calloc (filedata->file_header.e_shnum,
7834 sizeof (struct group *));
e4b17d5c 7835
978c4450 7836 if (filedata->section_headers_groups == NULL)
e4b17d5c 7837 {
8b73c356 7838 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7839 filedata->file_header.e_shnum);
015dc7e1 7840 return false;
e4b17d5c
L
7841 }
7842
f5842774 7843 /* Scan the sections for the group section. */
978c4450 7844 filedata->group_count = 0;
dda8d76d
NC
7845 for (i = 0, section = filedata->section_headers;
7846 i < filedata->file_header.e_shnum;
f5842774 7847 i++, section++)
e4b17d5c 7848 if (section->sh_type == SHT_GROUP)
978c4450 7849 filedata->group_count++;
e4b17d5c 7850
978c4450 7851 if (filedata->group_count == 0)
d1f5c6e3
L
7852 {
7853 if (do_section_groups)
ca0e11aa
NC
7854 {
7855 if (filedata->is_separate)
7856 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7857 filedata->file_name);
7858 else
7859 printf (_("\nThere are no section groups in this file.\n"));
7860 }
d1f5c6e3 7861
015dc7e1 7862 return true;
d1f5c6e3
L
7863 }
7864
978c4450
AM
7865 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7866 sizeof (struct group));
e4b17d5c 7867
978c4450 7868 if (filedata->section_groups == NULL)
e4b17d5c 7869 {
8b73c356 7870 error (_("Out of memory reading %lu groups\n"),
978c4450 7871 (unsigned long) filedata->group_count);
015dc7e1 7872 return false;
e4b17d5c
L
7873 }
7874
d1f5c6e3
L
7875 symtab_sec = NULL;
7876 strtab_sec = NULL;
7877 symtab = NULL;
ba5cdace 7878 num_syms = 0;
d1f5c6e3 7879 strtab = NULL;
c256ffe7 7880 strtab_size = 0;
ca0e11aa
NC
7881
7882 if (filedata->is_separate)
7883 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7884
978c4450 7885 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7886 i < filedata->file_header.e_shnum;
e4b17d5c 7887 i++, section++)
f5842774
L
7888 {
7889 if (section->sh_type == SHT_GROUP)
7890 {
dda8d76d 7891 const char * name = printable_section_name (filedata, section);
74e1a04b 7892 const char * group_name;
2cf0635d
NC
7893 unsigned char * start;
7894 unsigned char * indices;
f5842774 7895 unsigned int entry, j, size;
2cf0635d
NC
7896 Elf_Internal_Shdr * sec;
7897 Elf_Internal_Sym * sym;
f5842774
L
7898
7899 /* Get the symbol table. */
dda8d76d
NC
7900 if (section->sh_link >= filedata->file_header.e_shnum
7901 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7902 != SHT_SYMTAB))
f5842774
L
7903 {
7904 error (_("Bad sh_link in group section `%s'\n"), name);
7905 continue;
7906 }
d1f5c6e3
L
7907
7908 if (symtab_sec != sec)
7909 {
7910 symtab_sec = sec;
9db70fc3 7911 free (symtab);
4de91c10 7912 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7913 }
f5842774 7914
dd24e3da
NC
7915 if (symtab == NULL)
7916 {
7917 error (_("Corrupt header in group section `%s'\n"), name);
7918 continue;
7919 }
7920
ba5cdace
NC
7921 if (section->sh_info >= num_syms)
7922 {
7923 error (_("Bad sh_info in group section `%s'\n"), name);
7924 continue;
7925 }
7926
f5842774
L
7927 sym = symtab + section->sh_info;
7928
7929 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7930 {
4fbb74a6 7931 if (sym->st_shndx == 0
dda8d76d 7932 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7933 {
7934 error (_("Bad sh_info in group section `%s'\n"), name);
7935 continue;
7936 }
ba2685cc 7937
84714f86
AM
7938 group_name = section_name_print (filedata,
7939 filedata->section_headers
b9e920ec 7940 + sym->st_shndx);
c256ffe7 7941 strtab_sec = NULL;
9db70fc3 7942 free (strtab);
f5842774 7943 strtab = NULL;
c256ffe7 7944 strtab_size = 0;
f5842774
L
7945 }
7946 else
7947 {
7948 /* Get the string table. */
dda8d76d 7949 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7950 {
7951 strtab_sec = NULL;
9db70fc3 7952 free (strtab);
c256ffe7
JJ
7953 strtab = NULL;
7954 strtab_size = 0;
7955 }
7956 else if (strtab_sec
dda8d76d 7957 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7958 {
7959 strtab_sec = sec;
9db70fc3 7960 free (strtab);
071436c6 7961
dda8d76d 7962 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7963 1, strtab_sec->sh_size,
7964 _("string table"));
c256ffe7 7965 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7966 }
c256ffe7 7967 group_name = sym->st_name < strtab_size
2b692964 7968 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7969 }
7970
c9c1d674
EG
7971 /* PR 17531: file: loop. */
7972 if (section->sh_entsize > section->sh_size)
7973 {
7974 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7975 printable_section_name (filedata, section),
8066deb1
AM
7976 (unsigned long) section->sh_entsize,
7977 (unsigned long) section->sh_size);
61dd8e19 7978 continue;
c9c1d674
EG
7979 }
7980
dda8d76d 7981 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7982 1, section->sh_size,
7983 _("section data"));
59245841
NC
7984 if (start == NULL)
7985 continue;
f5842774
L
7986
7987 indices = start;
7988 size = (section->sh_size / section->sh_entsize) - 1;
7989 entry = byte_get (indices, 4);
7990 indices += 4;
e4b17d5c
L
7991
7992 if (do_section_groups)
7993 {
2b692964 7994 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7995 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7996
e4b17d5c
L
7997 printf (_(" [Index] Name\n"));
7998 }
7999
8000 group->group_index = i;
8001
f5842774
L
8002 for (j = 0; j < size; j++)
8003 {
2cf0635d 8004 struct group_list * g;
e4b17d5c 8005
f5842774
L
8006 entry = byte_get (indices, 4);
8007 indices += 4;
8008
dda8d76d 8009 if (entry >= filedata->file_header.e_shnum)
391cb864 8010 {
57028622
NC
8011 static unsigned num_group_errors = 0;
8012
8013 if (num_group_errors ++ < 10)
8014 {
8015 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8016 entry, i, filedata->file_header.e_shnum - 1);
57028622 8017 if (num_group_errors == 10)
67ce483b 8018 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8019 }
391cb864
L
8020 continue;
8021 }
391cb864 8022
978c4450 8023 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8024 {
d1f5c6e3
L
8025 if (entry)
8026 {
57028622
NC
8027 static unsigned num_errs = 0;
8028
8029 if (num_errs ++ < 10)
8030 {
8031 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8032 entry, i,
978c4450 8033 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8034 if (num_errs == 10)
8035 warn (_("Further error messages about already contained group sections suppressed\n"));
8036 }
d1f5c6e3
L
8037 continue;
8038 }
8039 else
8040 {
8041 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8042 section group. We just warn it the first time
d1f5c6e3 8043 and ignore it afterwards. */
015dc7e1 8044 static bool warned = false;
d1f5c6e3
L
8045 if (!warned)
8046 {
8047 error (_("section 0 in group section [%5u]\n"),
978c4450 8048 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8049 warned = true;
d1f5c6e3
L
8050 }
8051 }
e4b17d5c
L
8052 }
8053
978c4450 8054 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8055
8056 if (do_section_groups)
8057 {
dda8d76d
NC
8058 sec = filedata->section_headers + entry;
8059 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8060 }
8061
3f5e193b 8062 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8063 g->section_index = entry;
8064 g->next = group->root;
8065 group->root = g;
f5842774
L
8066 }
8067
9db70fc3 8068 free (start);
e4b17d5c
L
8069
8070 group++;
f5842774
L
8071 }
8072 }
8073
9db70fc3
AM
8074 free (symtab);
8075 free (strtab);
015dc7e1 8076 return true;
f5842774
L
8077}
8078
28f997cf
TG
8079/* Data used to display dynamic fixups. */
8080
8081struct ia64_vms_dynfixup
8082{
625d49fc
AM
8083 uint64_t needed_ident; /* Library ident number. */
8084 uint64_t needed; /* Index in the dstrtab of the library name. */
8085 uint64_t fixup_needed; /* Index of the library. */
8086 uint64_t fixup_rela_cnt; /* Number of fixups. */
8087 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8088};
8089
8090/* Data used to display dynamic relocations. */
8091
8092struct ia64_vms_dynimgrela
8093{
625d49fc
AM
8094 uint64_t img_rela_cnt; /* Number of relocations. */
8095 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8096};
8097
8098/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8099 library). */
8100
015dc7e1 8101static bool
dda8d76d
NC
8102dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8103 struct ia64_vms_dynfixup * fixup,
8104 const char * strtab,
8105 unsigned int strtab_sz)
28f997cf 8106{
32ec8896 8107 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 8108 long i;
32ec8896 8109 const char * lib_name;
28f997cf 8110
978c4450
AM
8111 imfs = get_data (NULL, filedata,
8112 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8113 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8114 _("dynamic section image fixups"));
8115 if (!imfs)
015dc7e1 8116 return false;
28f997cf
TG
8117
8118 if (fixup->needed < strtab_sz)
8119 lib_name = strtab + fixup->needed;
8120 else
8121 {
32ec8896 8122 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8123 (unsigned long) fixup->needed);
28f997cf
TG
8124 lib_name = "???";
8125 }
736990c4 8126
28f997cf
TG
8127 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8128 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8129 printf
8130 (_("Seg Offset Type SymVec DataType\n"));
8131
8132 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8133 {
8134 unsigned int type;
8135 const char *rtype;
8136
8137 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8138 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8139 type = BYTE_GET (imfs [i].type);
8140 rtype = elf_ia64_reloc_type (type);
8141 if (rtype == NULL)
f493c217 8142 printf ("0x%08x ", type);
28f997cf 8143 else
f493c217 8144 printf ("%-32s ", rtype);
28f997cf
TG
8145 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8146 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8147 }
8148
8149 free (imfs);
015dc7e1 8150 return true;
28f997cf
TG
8151}
8152
8153/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8154
015dc7e1 8155static bool
dda8d76d 8156dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8157{
8158 Elf64_External_VMS_IMAGE_RELA *imrs;
8159 long i;
8160
978c4450
AM
8161 imrs = get_data (NULL, filedata,
8162 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8163 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8164 _("dynamic section image relocations"));
28f997cf 8165 if (!imrs)
015dc7e1 8166 return false;
28f997cf
TG
8167
8168 printf (_("\nImage relocs\n"));
8169 printf
8170 (_("Seg Offset Type Addend Seg Sym Off\n"));
8171
8172 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8173 {
8174 unsigned int type;
8175 const char *rtype;
8176
8177 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8178 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8179 type = BYTE_GET (imrs [i].type);
8180 rtype = elf_ia64_reloc_type (type);
8181 if (rtype == NULL)
8182 printf ("0x%08x ", type);
8183 else
8184 printf ("%-31s ", rtype);
8185 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8186 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8187 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8188 }
8189
8190 free (imrs);
015dc7e1 8191 return true;
28f997cf
TG
8192}
8193
8194/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8195
015dc7e1 8196static bool
dda8d76d 8197process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8198{
8199 struct ia64_vms_dynfixup fixup;
8200 struct ia64_vms_dynimgrela imgrela;
8201 Elf_Internal_Dyn *entry;
625d49fc
AM
8202 uint64_t strtab_off = 0;
8203 uint64_t strtab_sz = 0;
28f997cf 8204 char *strtab = NULL;
015dc7e1 8205 bool res = true;
28f997cf
TG
8206
8207 memset (&fixup, 0, sizeof (fixup));
8208 memset (&imgrela, 0, sizeof (imgrela));
8209
8210 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8211 for (entry = filedata->dynamic_section;
8212 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8213 entry++)
8214 {
8215 switch (entry->d_tag)
8216 {
8217 case DT_IA_64_VMS_STRTAB_OFFSET:
8218 strtab_off = entry->d_un.d_val;
8219 break;
8220 case DT_STRSZ:
8221 strtab_sz = entry->d_un.d_val;
8222 if (strtab == NULL)
978c4450
AM
8223 strtab = get_data (NULL, filedata,
8224 filedata->dynamic_addr + strtab_off,
28f997cf 8225 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8226 if (strtab == NULL)
8227 strtab_sz = 0;
28f997cf
TG
8228 break;
8229
8230 case DT_IA_64_VMS_NEEDED_IDENT:
8231 fixup.needed_ident = entry->d_un.d_val;
8232 break;
8233 case DT_NEEDED:
8234 fixup.needed = entry->d_un.d_val;
8235 break;
8236 case DT_IA_64_VMS_FIXUP_NEEDED:
8237 fixup.fixup_needed = entry->d_un.d_val;
8238 break;
8239 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8240 fixup.fixup_rela_cnt = entry->d_un.d_val;
8241 break;
8242 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8243 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8244 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8245 res = false;
28f997cf 8246 break;
28f997cf
TG
8247 case DT_IA_64_VMS_IMG_RELA_CNT:
8248 imgrela.img_rela_cnt = entry->d_un.d_val;
8249 break;
8250 case DT_IA_64_VMS_IMG_RELA_OFF:
8251 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8252 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8253 res = false;
28f997cf
TG
8254 break;
8255
8256 default:
8257 break;
8258 }
8259 }
8260
9db70fc3 8261 free (strtab);
28f997cf
TG
8262
8263 return res;
8264}
8265
85b1c36d 8266static struct
566b0d53 8267{
2cf0635d 8268 const char * name;
566b0d53
L
8269 int reloc;
8270 int size;
a7fd1186 8271 relocation_type rel_type;
32ec8896
NC
8272}
8273 dynamic_relocations [] =
566b0d53 8274{
a7fd1186
FS
8275 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8276 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8277 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8278 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8279};
8280
252b5132 8281/* Process the reloc section. */
18bd398b 8282
015dc7e1 8283static bool
dda8d76d 8284process_relocs (Filedata * filedata)
252b5132 8285{
b34976b6
AM
8286 unsigned long rel_size;
8287 unsigned long rel_offset;
252b5132 8288
252b5132 8289 if (!do_reloc)
015dc7e1 8290 return true;
252b5132
RH
8291
8292 if (do_using_dynamic)
8293 {
a7fd1186 8294 relocation_type rel_type;
2cf0635d 8295 const char * name;
015dc7e1 8296 bool has_dynamic_reloc;
566b0d53 8297 unsigned int i;
0de14b54 8298
015dc7e1 8299 has_dynamic_reloc = false;
252b5132 8300
566b0d53 8301 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8302 {
a7fd1186 8303 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8304 name = dynamic_relocations [i].name;
978c4450
AM
8305 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8306 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8307
32ec8896 8308 if (rel_size)
015dc7e1 8309 has_dynamic_reloc = true;
566b0d53 8310
a7fd1186 8311 if (rel_type == reltype_unknown)
aa903cfb 8312 {
566b0d53 8313 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8314 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8315 {
8316 case DT_REL:
a7fd1186 8317 rel_type = reltype_rel;
566b0d53
L
8318 break;
8319 case DT_RELA:
a7fd1186 8320 rel_type = reltype_rela;
566b0d53
L
8321 break;
8322 }
aa903cfb 8323 }
252b5132 8324
566b0d53
L
8325 if (rel_size)
8326 {
ca0e11aa
NC
8327 if (filedata->is_separate)
8328 printf
8329 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8330 filedata->file_name, name, rel_offset, rel_size);
8331 else
8332 printf
8333 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8334 name, rel_offset, rel_size);
252b5132 8335
dda8d76d
NC
8336 dump_relocations (filedata,
8337 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8338 rel_size,
978c4450
AM
8339 filedata->dynamic_symbols,
8340 filedata->num_dynamic_syms,
8341 filedata->dynamic_strings,
8342 filedata->dynamic_strings_length,
a7fd1186 8343 rel_type, true /* is_dynamic */);
566b0d53 8344 }
252b5132 8345 }
566b0d53 8346
dda8d76d
NC
8347 if (is_ia64_vms (filedata))
8348 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8349 has_dynamic_reloc = true;
28f997cf 8350
566b0d53 8351 if (! has_dynamic_reloc)
ca0e11aa
NC
8352 {
8353 if (filedata->is_separate)
8354 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8355 filedata->file_name);
8356 else
8357 printf (_("\nThere are no dynamic relocations in this file.\n"));
8358 }
252b5132
RH
8359 }
8360 else
8361 {
2cf0635d 8362 Elf_Internal_Shdr * section;
b34976b6 8363 unsigned long i;
015dc7e1 8364 bool found = false;
252b5132 8365
dda8d76d
NC
8366 for (i = 0, section = filedata->section_headers;
8367 i < filedata->file_header.e_shnum;
b34976b6 8368 i++, section++)
252b5132
RH
8369 {
8370 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8371 && section->sh_type != SHT_REL
8372 && section->sh_type != SHT_RELR)
252b5132
RH
8373 continue;
8374
8375 rel_offset = section->sh_offset;
8376 rel_size = section->sh_size;
8377
8378 if (rel_size)
8379 {
a7fd1186 8380 relocation_type rel_type;
d3a49aa8 8381 unsigned long num_rela;
103f02d3 8382
ca0e11aa
NC
8383 if (filedata->is_separate)
8384 printf (_("\nIn linked file '%s' relocation section "),
8385 filedata->file_name);
8386 else
8387 printf (_("\nRelocation section "));
252b5132 8388
dda8d76d 8389 if (filedata->string_table == NULL)
19936277 8390 printf ("%d", section->sh_name);
252b5132 8391 else
dda8d76d 8392 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8393
d3a49aa8
AM
8394 num_rela = rel_size / section->sh_entsize;
8395 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8396 " at offset 0x%lx contains %lu entries:\n",
8397 num_rela),
8398 rel_offset, num_rela);
252b5132 8399
a7fd1186
FS
8400 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8401 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8402
4fbb74a6 8403 if (section->sh_link != 0
dda8d76d 8404 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8405 {
2cf0635d
NC
8406 Elf_Internal_Shdr * symsec;
8407 Elf_Internal_Sym * symtab;
d79b3d50 8408 unsigned long nsyms;
c256ffe7 8409 unsigned long strtablen = 0;
2cf0635d 8410 char * strtab = NULL;
57346661 8411
dda8d76d 8412 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8413 if (symsec->sh_type != SHT_SYMTAB
8414 && symsec->sh_type != SHT_DYNSYM)
8415 continue;
8416
28d13567
AM
8417 if (!get_symtab (filedata, symsec,
8418 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8419 continue;
252b5132 8420
dda8d76d 8421 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8422 symtab, nsyms, strtab, strtablen,
a7fd1186 8423 rel_type,
bb4d2ac2 8424 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8425 free (strtab);
d79b3d50
NC
8426 free (symtab);
8427 }
8428 else
dda8d76d 8429 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8430 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8431
015dc7e1 8432 found = true;
252b5132
RH
8433 }
8434 }
8435
8436 if (! found)
45ac8f4f
NC
8437 {
8438 /* Users sometimes forget the -D option, so try to be helpful. */
8439 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8440 {
978c4450 8441 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8442 {
ca0e11aa
NC
8443 if (filedata->is_separate)
8444 printf (_("\nThere are no static relocations in linked file '%s'."),
8445 filedata->file_name);
8446 else
8447 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8448 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8449
8450 break;
8451 }
8452 }
8453 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8454 {
8455 if (filedata->is_separate)
8456 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8457 filedata->file_name);
8458 else
8459 printf (_("\nThere are no relocations in this file.\n"));
8460 }
45ac8f4f 8461 }
252b5132
RH
8462 }
8463
015dc7e1 8464 return true;
252b5132
RH
8465}
8466
4d6ed7c8
NC
8467/* An absolute address consists of a section and an offset. If the
8468 section is NULL, the offset itself is the address, otherwise, the
8469 address equals to LOAD_ADDRESS(section) + offset. */
8470
8471struct absaddr
948f632f
DA
8472{
8473 unsigned short section;
625d49fc 8474 uint64_t offset;
948f632f 8475};
4d6ed7c8 8476
948f632f
DA
8477/* Find the nearest symbol at or below ADDR. Returns the symbol
8478 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8479
4d6ed7c8 8480static void
dda8d76d
NC
8481find_symbol_for_address (Filedata * filedata,
8482 Elf_Internal_Sym * symtab,
8483 unsigned long nsyms,
8484 const char * strtab,
8485 unsigned long strtab_size,
8486 struct absaddr addr,
8487 const char ** symname,
625d49fc 8488 uint64_t * offset)
4d6ed7c8 8489{
625d49fc 8490 uint64_t dist = 0x100000;
2cf0635d 8491 Elf_Internal_Sym * sym;
948f632f
DA
8492 Elf_Internal_Sym * beg;
8493 Elf_Internal_Sym * end;
2cf0635d 8494 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8495
0b6ae522 8496 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8497 beg = symtab;
8498 end = symtab + nsyms;
0b6ae522 8499
948f632f 8500 while (beg < end)
4d6ed7c8 8501 {
625d49fc 8502 uint64_t value;
948f632f
DA
8503
8504 sym = beg + (end - beg) / 2;
0b6ae522 8505
948f632f 8506 value = sym->st_value;
0b6ae522
DJ
8507 REMOVE_ARCH_BITS (value);
8508
948f632f 8509 if (sym->st_name != 0
4d6ed7c8 8510 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8511 && addr.offset >= value
8512 && addr.offset - value < dist)
4d6ed7c8
NC
8513 {
8514 best = sym;
0b6ae522 8515 dist = addr.offset - value;
4d6ed7c8
NC
8516 if (!dist)
8517 break;
8518 }
948f632f
DA
8519
8520 if (addr.offset < value)
8521 end = sym;
8522 else
8523 beg = sym + 1;
4d6ed7c8 8524 }
1b31d05e 8525
4d6ed7c8
NC
8526 if (best)
8527 {
57346661 8528 *symname = (best->st_name >= strtab_size
2b692964 8529 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8530 *offset = dist;
8531 return;
8532 }
1b31d05e 8533
4d6ed7c8
NC
8534 *symname = NULL;
8535 *offset = addr.offset;
8536}
8537
32ec8896 8538static /* signed */ int
948f632f
DA
8539symcmp (const void *p, const void *q)
8540{
8541 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8542 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8543
8544 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8545}
8546
8547/* Process the unwind section. */
8548
8549#include "unwind-ia64.h"
8550
8551struct ia64_unw_table_entry
8552{
8553 struct absaddr start;
8554 struct absaddr end;
8555 struct absaddr info;
8556};
8557
8558struct ia64_unw_aux_info
8559{
32ec8896
NC
8560 struct ia64_unw_table_entry * table; /* Unwind table. */
8561 unsigned long table_len; /* Length of unwind table. */
8562 unsigned char * info; /* Unwind info. */
8563 unsigned long info_size; /* Size of unwind info. */
625d49fc
AM
8564 uint64_t info_addr; /* Starting address of unwind info. */
8565 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
8566 Elf_Internal_Sym * symtab; /* The symbol table. */
8567 unsigned long nsyms; /* Number of symbols. */
8568 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8569 unsigned long nfuns; /* Number of entries in funtab. */
8570 char * strtab; /* The string table. */
8571 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8572};
8573
015dc7e1 8574static bool
dda8d76d 8575dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8576{
2cf0635d 8577 struct ia64_unw_table_entry * tp;
948f632f 8578 unsigned long j, nfuns;
4d6ed7c8 8579 int in_body;
015dc7e1 8580 bool res = true;
7036c0e1 8581
948f632f
DA
8582 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8583 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8584 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8585 aux->funtab[nfuns++] = aux->symtab[j];
8586 aux->nfuns = nfuns;
8587 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8588
4d6ed7c8
NC
8589 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8590 {
625d49fc
AM
8591 uint64_t stamp;
8592 uint64_t offset;
2cf0635d
NC
8593 const unsigned char * dp;
8594 const unsigned char * head;
53774b7e 8595 const unsigned char * end;
2cf0635d 8596 const char * procname;
4d6ed7c8 8597
dda8d76d 8598 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8599 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8600
8601 fputs ("\n<", stdout);
8602
8603 if (procname)
8604 {
8605 fputs (procname, stdout);
8606
8607 if (offset)
8608 printf ("+%lx", (unsigned long) offset);
8609 }
8610
8611 fputs (">: [", stdout);
8612 print_vma (tp->start.offset, PREFIX_HEX);
8613 fputc ('-', stdout);
8614 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8615 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8616 (unsigned long) (tp->info.offset - aux->seg_base));
8617
53774b7e
NC
8618 /* PR 17531: file: 86232b32. */
8619 if (aux->info == NULL)
8620 continue;
8621
97c0a079
AM
8622 offset = tp->info.offset;
8623 if (tp->info.section)
8624 {
8625 if (tp->info.section >= filedata->file_header.e_shnum)
8626 {
8627 warn (_("Invalid section %u in table entry %ld\n"),
8628 tp->info.section, (long) (tp - aux->table));
015dc7e1 8629 res = false;
97c0a079
AM
8630 continue;
8631 }
8632 offset += filedata->section_headers[tp->info.section].sh_addr;
8633 }
8634 offset -= aux->info_addr;
53774b7e 8635 /* PR 17531: file: 0997b4d1. */
90679903
AM
8636 if (offset >= aux->info_size
8637 || aux->info_size - offset < 8)
53774b7e
NC
8638 {
8639 warn (_("Invalid offset %lx in table entry %ld\n"),
8640 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8641 res = false;
53774b7e
NC
8642 continue;
8643 }
8644
97c0a079 8645 head = aux->info + offset;
a4a00738 8646 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8647
86f55779 8648 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8649 (unsigned) UNW_VER (stamp),
8650 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8651 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8652 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8653 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8654
8655 if (UNW_VER (stamp) != 1)
8656 {
2b692964 8657 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8658 continue;
8659 }
8660
8661 in_body = 0;
53774b7e
NC
8662 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8663 /* PR 17531: file: 16ceda89. */
8664 if (end > aux->info + aux->info_size)
8665 end = aux->info + aux->info_size;
8666 for (dp = head + 8; dp < end;)
b4477bc8 8667 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8668 }
948f632f
DA
8669
8670 free (aux->funtab);
32ec8896
NC
8671
8672 return res;
4d6ed7c8
NC
8673}
8674
015dc7e1 8675static bool
dda8d76d
NC
8676slurp_ia64_unwind_table (Filedata * filedata,
8677 struct ia64_unw_aux_info * aux,
8678 Elf_Internal_Shdr * sec)
4d6ed7c8 8679{
89fac5e3 8680 unsigned long size, nrelas, i;
2cf0635d
NC
8681 Elf_Internal_Phdr * seg;
8682 struct ia64_unw_table_entry * tep;
8683 Elf_Internal_Shdr * relsec;
8684 Elf_Internal_Rela * rela;
8685 Elf_Internal_Rela * rp;
8686 unsigned char * table;
8687 unsigned char * tp;
8688 Elf_Internal_Sym * sym;
8689 const char * relname;
4d6ed7c8 8690
53774b7e
NC
8691 aux->table_len = 0;
8692
4d6ed7c8
NC
8693 /* First, find the starting address of the segment that includes
8694 this section: */
8695
dda8d76d 8696 if (filedata->file_header.e_phnum)
4d6ed7c8 8697 {
dda8d76d 8698 if (! get_program_headers (filedata))
015dc7e1 8699 return false;
4d6ed7c8 8700
dda8d76d
NC
8701 for (seg = filedata->program_headers;
8702 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8703 ++seg)
4d6ed7c8
NC
8704 {
8705 if (seg->p_type != PT_LOAD)
8706 continue;
8707
8708 if (sec->sh_addr >= seg->p_vaddr
8709 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8710 {
8711 aux->seg_base = seg->p_vaddr;
8712 break;
8713 }
8714 }
4d6ed7c8
NC
8715 }
8716
8717 /* Second, build the unwind table from the contents of the unwind section: */
8718 size = sec->sh_size;
dda8d76d 8719 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8720 _("unwind table"));
a6e9f9df 8721 if (!table)
015dc7e1 8722 return false;
4d6ed7c8 8723
53774b7e 8724 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8725 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8726 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8727 tep = aux->table;
53774b7e
NC
8728
8729 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8730 {
8731 tep->start.section = SHN_UNDEF;
8732 tep->end.section = SHN_UNDEF;
8733 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8734 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8735 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8736 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8737 tep->start.offset += aux->seg_base;
8738 tep->end.offset += aux->seg_base;
8739 tep->info.offset += aux->seg_base;
8740 }
8741 free (table);
8742
41e92641 8743 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8744 for (relsec = filedata->section_headers;
8745 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8746 ++relsec)
8747 {
8748 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8749 || relsec->sh_info >= filedata->file_header.e_shnum
8750 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8751 continue;
8752
dda8d76d 8753 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8754 & rela, & nrelas))
53774b7e
NC
8755 {
8756 free (aux->table);
8757 aux->table = NULL;
8758 aux->table_len = 0;
015dc7e1 8759 return false;
53774b7e 8760 }
4d6ed7c8
NC
8761
8762 for (rp = rela; rp < rela + nrelas; ++rp)
8763 {
4770fb94 8764 unsigned int sym_ndx;
726bd37d
AM
8765 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8766 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8767
82b1b41b
NC
8768 /* PR 17531: file: 9fa67536. */
8769 if (relname == NULL)
8770 {
726bd37d 8771 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8772 continue;
8773 }
948f632f 8774
24d127aa 8775 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8776 {
82b1b41b 8777 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8778 continue;
8779 }
8780
89fac5e3 8781 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8782
53774b7e
NC
8783 /* PR 17531: file: 5bc8d9bf. */
8784 if (i >= aux->table_len)
8785 {
8786 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8787 continue;
8788 }
8789
4770fb94
AM
8790 sym_ndx = get_reloc_symindex (rp->r_info);
8791 if (sym_ndx >= aux->nsyms)
8792 {
8793 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8794 sym_ndx);
8795 continue;
8796 }
8797 sym = aux->symtab + sym_ndx;
8798
53774b7e 8799 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8800 {
8801 case 0:
8802 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8803 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8804 break;
8805 case 1:
8806 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8807 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8808 break;
8809 case 2:
8810 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8811 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8812 break;
8813 default:
8814 break;
8815 }
8816 }
8817
8818 free (rela);
8819 }
8820
015dc7e1 8821 return true;
4d6ed7c8
NC
8822}
8823
015dc7e1 8824static bool
dda8d76d 8825ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8826{
2cf0635d
NC
8827 Elf_Internal_Shdr * sec;
8828 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8829 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8830 struct ia64_unw_aux_info aux;
015dc7e1 8831 bool res = true;
f1467e33 8832
4d6ed7c8
NC
8833 memset (& aux, 0, sizeof (aux));
8834
dda8d76d 8835 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8836 {
28d13567 8837 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8838 {
28d13567 8839 if (aux.symtab)
4082ef84 8840 {
28d13567
AM
8841 error (_("Multiple symbol tables encountered\n"));
8842 free (aux.symtab);
8843 aux.symtab = NULL;
4082ef84 8844 free (aux.strtab);
28d13567 8845 aux.strtab = NULL;
4082ef84 8846 }
28d13567
AM
8847 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8848 &aux.strtab, &aux.strtab_size))
015dc7e1 8849 return false;
4d6ed7c8
NC
8850 }
8851 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8852 unwcount++;
8853 }
8854
8855 if (!unwcount)
8856 printf (_("\nThere are no unwind sections in this file.\n"));
8857
8858 while (unwcount-- > 0)
8859 {
84714f86 8860 const char *suffix;
579f31ac
JJ
8861 size_t len, len2;
8862
dda8d76d
NC
8863 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8864 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8865 if (sec->sh_type == SHT_IA_64_UNWIND)
8866 {
8867 unwsec = sec;
8868 break;
8869 }
4082ef84
NC
8870 /* We have already counted the number of SHT_IA64_UNWIND
8871 sections so the loop above should never fail. */
8872 assert (unwsec != NULL);
579f31ac
JJ
8873
8874 unwstart = i + 1;
8875 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8876
e4b17d5c
L
8877 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8878 {
8879 /* We need to find which section group it is in. */
4082ef84 8880 struct group_list * g;
e4b17d5c 8881
978c4450
AM
8882 if (filedata->section_headers_groups == NULL
8883 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8884 i = filedata->file_header.e_shnum;
4082ef84 8885 else
e4b17d5c 8886 {
978c4450 8887 g = filedata->section_headers_groups[i]->root;
18bd398b 8888
4082ef84
NC
8889 for (; g != NULL; g = g->next)
8890 {
dda8d76d 8891 sec = filedata->section_headers + g->section_index;
e4b17d5c 8892
84714f86
AM
8893 if (section_name_valid (filedata, sec)
8894 && streq (section_name (filedata, sec),
8895 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8896 break;
8897 }
8898
8899 if (g == NULL)
dda8d76d 8900 i = filedata->file_header.e_shnum;
4082ef84 8901 }
e4b17d5c 8902 }
84714f86
AM
8903 else if (section_name_valid (filedata, unwsec)
8904 && startswith (section_name (filedata, unwsec),
e9b095a5 8905 ELF_STRING_ia64_unwind_once))
579f31ac 8906 {
18bd398b 8907 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8908 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8909 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8910 for (i = 0, sec = filedata->section_headers;
8911 i < filedata->file_header.e_shnum;
579f31ac 8912 ++i, ++sec)
84714f86
AM
8913 if (section_name_valid (filedata, sec)
8914 && startswith (section_name (filedata, sec),
e9b095a5 8915 ELF_STRING_ia64_unwind_info_once)
84714f86 8916 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8917 break;
8918 }
8919 else
8920 {
8921 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8922 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8923 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8924 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8925 suffix = "";
84714f86
AM
8926 if (section_name_valid (filedata, unwsec)
8927 && startswith (section_name (filedata, unwsec),
8928 ELF_STRING_ia64_unwind))
8929 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8930 for (i = 0, sec = filedata->section_headers;
8931 i < filedata->file_header.e_shnum;
579f31ac 8932 ++i, ++sec)
84714f86
AM
8933 if (section_name_valid (filedata, sec)
8934 && startswith (section_name (filedata, sec),
8935 ELF_STRING_ia64_unwind_info)
8936 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8937 break;
8938 }
8939
dda8d76d 8940 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8941 {
8942 printf (_("\nCould not find unwind info section for "));
8943
dda8d76d 8944 if (filedata->string_table == NULL)
579f31ac
JJ
8945 printf ("%d", unwsec->sh_name);
8946 else
dda8d76d 8947 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8948 }
8949 else
4d6ed7c8 8950 {
4d6ed7c8 8951 aux.info_addr = sec->sh_addr;
dda8d76d 8952 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8953 sec->sh_size,
8954 _("unwind info"));
59245841 8955 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8956
579f31ac 8957 printf (_("\nUnwind section "));
4d6ed7c8 8958
dda8d76d 8959 if (filedata->string_table == NULL)
579f31ac
JJ
8960 printf ("%d", unwsec->sh_name);
8961 else
dda8d76d 8962 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8963
579f31ac 8964 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8965 (unsigned long) unwsec->sh_offset,
89fac5e3 8966 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8967
dda8d76d 8968 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8969 && aux.table_len > 0)
dda8d76d 8970 dump_ia64_unwind (filedata, & aux);
579f31ac 8971
9db70fc3
AM
8972 free ((char *) aux.table);
8973 free ((char *) aux.info);
579f31ac
JJ
8974 aux.table = NULL;
8975 aux.info = NULL;
8976 }
4d6ed7c8 8977 }
4d6ed7c8 8978
9db70fc3
AM
8979 free (aux.symtab);
8980 free ((char *) aux.strtab);
32ec8896
NC
8981
8982 return res;
4d6ed7c8
NC
8983}
8984
3f5e193b 8985struct hppa_unw_table_entry
32ec8896
NC
8986{
8987 struct absaddr start;
8988 struct absaddr end;
8989 unsigned int Cannot_unwind:1; /* 0 */
8990 unsigned int Millicode:1; /* 1 */
8991 unsigned int Millicode_save_sr0:1; /* 2 */
8992 unsigned int Region_description:2; /* 3..4 */
8993 unsigned int reserved1:1; /* 5 */
8994 unsigned int Entry_SR:1; /* 6 */
8995 unsigned int Entry_FR:4; /* Number saved 7..10 */
8996 unsigned int Entry_GR:5; /* Number saved 11..15 */
8997 unsigned int Args_stored:1; /* 16 */
8998 unsigned int Variable_Frame:1; /* 17 */
8999 unsigned int Separate_Package_Body:1; /* 18 */
9000 unsigned int Frame_Extension_Millicode:1; /* 19 */
9001 unsigned int Stack_Overflow_Check:1; /* 20 */
9002 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9003 unsigned int Ada_Region:1; /* 22 */
9004 unsigned int cxx_info:1; /* 23 */
9005 unsigned int cxx_try_catch:1; /* 24 */
9006 unsigned int sched_entry_seq:1; /* 25 */
9007 unsigned int reserved2:1; /* 26 */
9008 unsigned int Save_SP:1; /* 27 */
9009 unsigned int Save_RP:1; /* 28 */
9010 unsigned int Save_MRP_in_frame:1; /* 29 */
9011 unsigned int extn_ptr_defined:1; /* 30 */
9012 unsigned int Cleanup_defined:1; /* 31 */
9013
9014 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9015 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9016 unsigned int Large_frame:1; /* 2 */
9017 unsigned int Pseudo_SP_Set:1; /* 3 */
9018 unsigned int reserved4:1; /* 4 */
9019 unsigned int Total_frame_size:27; /* 5..31 */
9020};
3f5e193b 9021
57346661 9022struct hppa_unw_aux_info
948f632f 9023{
32ec8896
NC
9024 struct hppa_unw_table_entry * table; /* Unwind table. */
9025 unsigned long table_len; /* Length of unwind table. */
625d49fc 9026 uint64_t seg_base; /* Starting address of segment. */
32ec8896
NC
9027 Elf_Internal_Sym * symtab; /* The symbol table. */
9028 unsigned long nsyms; /* Number of symbols. */
9029 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9030 unsigned long nfuns; /* Number of entries in funtab. */
9031 char * strtab; /* The string table. */
9032 unsigned long strtab_size; /* Size of string table. */
948f632f 9033};
57346661 9034
015dc7e1 9035static bool
dda8d76d 9036dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9037{
2cf0635d 9038 struct hppa_unw_table_entry * tp;
948f632f 9039 unsigned long j, nfuns;
015dc7e1 9040 bool res = true;
948f632f
DA
9041
9042 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9043 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9044 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9045 aux->funtab[nfuns++] = aux->symtab[j];
9046 aux->nfuns = nfuns;
9047 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9048
57346661
AM
9049 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9050 {
625d49fc 9051 uint64_t offset;
2cf0635d 9052 const char * procname;
57346661 9053
dda8d76d 9054 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9055 aux->strtab_size, tp->start, &procname,
9056 &offset);
9057
9058 fputs ("\n<", stdout);
9059
9060 if (procname)
9061 {
9062 fputs (procname, stdout);
9063
9064 if (offset)
9065 printf ("+%lx", (unsigned long) offset);
9066 }
9067
9068 fputs (">: [", stdout);
9069 print_vma (tp->start.offset, PREFIX_HEX);
9070 fputc ('-', stdout);
9071 print_vma (tp->end.offset, PREFIX_HEX);
9072 printf ("]\n\t");
9073
18bd398b
NC
9074#define PF(_m) if (tp->_m) printf (#_m " ");
9075#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9076 PF(Cannot_unwind);
9077 PF(Millicode);
9078 PF(Millicode_save_sr0);
18bd398b 9079 /* PV(Region_description); */
57346661
AM
9080 PF(Entry_SR);
9081 PV(Entry_FR);
9082 PV(Entry_GR);
9083 PF(Args_stored);
9084 PF(Variable_Frame);
9085 PF(Separate_Package_Body);
9086 PF(Frame_Extension_Millicode);
9087 PF(Stack_Overflow_Check);
9088 PF(Two_Instruction_SP_Increment);
9089 PF(Ada_Region);
9090 PF(cxx_info);
9091 PF(cxx_try_catch);
9092 PF(sched_entry_seq);
9093 PF(Save_SP);
9094 PF(Save_RP);
9095 PF(Save_MRP_in_frame);
9096 PF(extn_ptr_defined);
9097 PF(Cleanup_defined);
9098 PF(MPE_XL_interrupt_marker);
9099 PF(HP_UX_interrupt_marker);
9100 PF(Large_frame);
9101 PF(Pseudo_SP_Set);
9102 PV(Total_frame_size);
9103#undef PF
9104#undef PV
9105 }
9106
18bd398b 9107 printf ("\n");
948f632f
DA
9108
9109 free (aux->funtab);
32ec8896
NC
9110
9111 return res;
57346661
AM
9112}
9113
015dc7e1 9114static bool
dda8d76d
NC
9115slurp_hppa_unwind_table (Filedata * filedata,
9116 struct hppa_unw_aux_info * aux,
9117 Elf_Internal_Shdr * sec)
57346661 9118{
1c0751b2 9119 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9120 Elf_Internal_Phdr * seg;
9121 struct hppa_unw_table_entry * tep;
9122 Elf_Internal_Shdr * relsec;
9123 Elf_Internal_Rela * rela;
9124 Elf_Internal_Rela * rp;
9125 unsigned char * table;
9126 unsigned char * tp;
9127 Elf_Internal_Sym * sym;
9128 const char * relname;
57346661 9129
57346661
AM
9130 /* First, find the starting address of the segment that includes
9131 this section. */
dda8d76d 9132 if (filedata->file_header.e_phnum)
57346661 9133 {
dda8d76d 9134 if (! get_program_headers (filedata))
015dc7e1 9135 return false;
57346661 9136
dda8d76d
NC
9137 for (seg = filedata->program_headers;
9138 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9139 ++seg)
9140 {
9141 if (seg->p_type != PT_LOAD)
9142 continue;
9143
9144 if (sec->sh_addr >= seg->p_vaddr
9145 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9146 {
9147 aux->seg_base = seg->p_vaddr;
9148 break;
9149 }
9150 }
9151 }
9152
9153 /* Second, build the unwind table from the contents of the unwind
9154 section. */
9155 size = sec->sh_size;
dda8d76d 9156 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9157 _("unwind table"));
57346661 9158 if (!table)
015dc7e1 9159 return false;
57346661 9160
1c0751b2
DA
9161 unw_ent_size = 16;
9162 nentries = size / unw_ent_size;
9163 size = unw_ent_size * nentries;
57346661 9164
e3fdc001 9165 aux->table_len = nentries;
3f5e193b
NC
9166 tep = aux->table = (struct hppa_unw_table_entry *)
9167 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9168
1c0751b2 9169 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9170 {
9171 unsigned int tmp1, tmp2;
9172
9173 tep->start.section = SHN_UNDEF;
9174 tep->end.section = SHN_UNDEF;
9175
1c0751b2
DA
9176 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9177 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9178 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9179 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9180
9181 tep->start.offset += aux->seg_base;
9182 tep->end.offset += aux->seg_base;
57346661
AM
9183
9184 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9185 tep->Millicode = (tmp1 >> 30) & 0x1;
9186 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9187 tep->Region_description = (tmp1 >> 27) & 0x3;
9188 tep->reserved1 = (tmp1 >> 26) & 0x1;
9189 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9190 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9191 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9192 tep->Args_stored = (tmp1 >> 15) & 0x1;
9193 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9194 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9195 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9196 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9197 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9198 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9199 tep->cxx_info = (tmp1 >> 8) & 0x1;
9200 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9201 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9202 tep->reserved2 = (tmp1 >> 5) & 0x1;
9203 tep->Save_SP = (tmp1 >> 4) & 0x1;
9204 tep->Save_RP = (tmp1 >> 3) & 0x1;
9205 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9206 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9207 tep->Cleanup_defined = tmp1 & 0x1;
9208
9209 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9210 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9211 tep->Large_frame = (tmp2 >> 29) & 0x1;
9212 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9213 tep->reserved4 = (tmp2 >> 27) & 0x1;
9214 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9215 }
9216 free (table);
9217
9218 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9219 for (relsec = filedata->section_headers;
9220 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9221 ++relsec)
9222 {
9223 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9224 || relsec->sh_info >= filedata->file_header.e_shnum
9225 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9226 continue;
9227
dda8d76d 9228 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9229 & rela, & nrelas))
015dc7e1 9230 return false;
57346661
AM
9231
9232 for (rp = rela; rp < rela + nrelas; ++rp)
9233 {
4770fb94 9234 unsigned int sym_ndx;
726bd37d
AM
9235 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9236 relname = elf_hppa_reloc_type (r_type);
57346661 9237
726bd37d
AM
9238 if (relname == NULL)
9239 {
9240 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9241 continue;
9242 }
9243
57346661 9244 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9245 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9246 {
726bd37d 9247 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9248 continue;
9249 }
9250
9251 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9252 if (i >= aux->table_len)
9253 {
9254 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9255 continue;
9256 }
57346661 9257
4770fb94
AM
9258 sym_ndx = get_reloc_symindex (rp->r_info);
9259 if (sym_ndx >= aux->nsyms)
9260 {
9261 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9262 sym_ndx);
9263 continue;
9264 }
9265 sym = aux->symtab + sym_ndx;
9266
43f6cd05 9267 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9268 {
9269 case 0:
9270 aux->table[i].start.section = sym->st_shndx;
1e456d54 9271 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9272 break;
9273 case 1:
9274 aux->table[i].end.section = sym->st_shndx;
1e456d54 9275 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9276 break;
9277 default:
9278 break;
9279 }
9280 }
9281
9282 free (rela);
9283 }
9284
015dc7e1 9285 return true;
57346661
AM
9286}
9287
015dc7e1 9288static bool
dda8d76d 9289hppa_process_unwind (Filedata * filedata)
57346661 9290{
57346661 9291 struct hppa_unw_aux_info aux;
2cf0635d 9292 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9293 Elf_Internal_Shdr * sec;
18bd398b 9294 unsigned long i;
015dc7e1 9295 bool res = true;
57346661 9296
dda8d76d 9297 if (filedata->string_table == NULL)
015dc7e1 9298 return false;
1b31d05e
NC
9299
9300 memset (& aux, 0, sizeof (aux));
57346661 9301
dda8d76d 9302 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9303 {
28d13567 9304 if (sec->sh_type == SHT_SYMTAB)
57346661 9305 {
28d13567 9306 if (aux.symtab)
4082ef84 9307 {
28d13567
AM
9308 error (_("Multiple symbol tables encountered\n"));
9309 free (aux.symtab);
9310 aux.symtab = NULL;
4082ef84 9311 free (aux.strtab);
28d13567 9312 aux.strtab = NULL;
4082ef84 9313 }
28d13567
AM
9314 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9315 &aux.strtab, &aux.strtab_size))
015dc7e1 9316 return false;
57346661 9317 }
84714f86
AM
9318 else if (section_name_valid (filedata, sec)
9319 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9320 unwsec = sec;
9321 }
9322
9323 if (!unwsec)
9324 printf (_("\nThere are no unwind sections in this file.\n"));
9325
dda8d76d 9326 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9327 {
84714f86
AM
9328 if (section_name_valid (filedata, sec)
9329 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9330 {
43f6cd05 9331 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9332
d3a49aa8
AM
9333 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9334 "contains %lu entry:\n",
9335 "\nUnwind section '%s' at offset 0x%lx "
9336 "contains %lu entries:\n",
9337 num_unwind),
dda8d76d 9338 printable_section_name (filedata, sec),
57346661 9339 (unsigned long) sec->sh_offset,
d3a49aa8 9340 num_unwind);
57346661 9341
dda8d76d 9342 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9343 res = false;
66b09c7e
S
9344
9345 if (res && aux.table_len > 0)
32ec8896 9346 {
dda8d76d 9347 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9348 res = false;
32ec8896 9349 }
57346661 9350
9db70fc3 9351 free ((char *) aux.table);
57346661
AM
9352 aux.table = NULL;
9353 }
9354 }
9355
9db70fc3
AM
9356 free (aux.symtab);
9357 free ((char *) aux.strtab);
32ec8896
NC
9358
9359 return res;
57346661
AM
9360}
9361
0b6ae522
DJ
9362struct arm_section
9363{
a734115a
NC
9364 unsigned char * data; /* The unwind data. */
9365 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9366 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9367 unsigned long nrelas; /* The number of relocations. */
9368 unsigned int rel_type; /* REL or RELA ? */
9369 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9370};
9371
9372struct arm_unw_aux_info
9373{
dda8d76d 9374 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9375 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9376 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9377 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9378 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9379 char * strtab; /* The file's string table. */
9380 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9381};
9382
9383static const char *
dda8d76d
NC
9384arm_print_vma_and_name (Filedata * filedata,
9385 struct arm_unw_aux_info * aux,
625d49fc 9386 uint64_t fn,
dda8d76d 9387 struct absaddr addr)
0b6ae522
DJ
9388{
9389 const char *procname;
625d49fc 9390 uint64_t sym_offset;
0b6ae522
DJ
9391
9392 if (addr.section == SHN_UNDEF)
9393 addr.offset = fn;
9394
dda8d76d 9395 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9396 aux->strtab_size, addr, &procname,
9397 &sym_offset);
9398
9399 print_vma (fn, PREFIX_HEX);
9400
9401 if (procname)
9402 {
9403 fputs (" <", stdout);
9404 fputs (procname, stdout);
9405
9406 if (sym_offset)
9407 printf ("+0x%lx", (unsigned long) sym_offset);
9408 fputc ('>', stdout);
9409 }
9410
9411 return procname;
9412}
9413
9414static void
9415arm_free_section (struct arm_section *arm_sec)
9416{
9db70fc3
AM
9417 free (arm_sec->data);
9418 free (arm_sec->rela);
0b6ae522
DJ
9419}
9420
a734115a
NC
9421/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9422 cached section and install SEC instead.
9423 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9424 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9425 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9426 relocation's offset in ADDR.
1b31d05e
NC
9427 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9428 into the string table of the symbol associated with the reloc. If no
9429 reloc was applied store -1 there.
9430 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9431
015dc7e1 9432static bool
dda8d76d
NC
9433get_unwind_section_word (Filedata * filedata,
9434 struct arm_unw_aux_info * aux,
1b31d05e
NC
9435 struct arm_section * arm_sec,
9436 Elf_Internal_Shdr * sec,
625d49fc 9437 uint64_t word_offset,
1b31d05e
NC
9438 unsigned int * wordp,
9439 struct absaddr * addr,
625d49fc 9440 uint64_t * sym_name)
0b6ae522
DJ
9441{
9442 Elf_Internal_Rela *rp;
9443 Elf_Internal_Sym *sym;
9444 const char * relname;
9445 unsigned int word;
015dc7e1 9446 bool wrapped;
0b6ae522 9447
e0a31db1 9448 if (sec == NULL || arm_sec == NULL)
015dc7e1 9449 return false;
e0a31db1 9450
0b6ae522
DJ
9451 addr->section = SHN_UNDEF;
9452 addr->offset = 0;
9453
1b31d05e 9454 if (sym_name != NULL)
625d49fc 9455 *sym_name = (uint64_t) -1;
1b31d05e 9456
a734115a 9457 /* If necessary, update the section cache. */
0b6ae522
DJ
9458 if (sec != arm_sec->sec)
9459 {
9460 Elf_Internal_Shdr *relsec;
9461
9462 arm_free_section (arm_sec);
9463
9464 arm_sec->sec = sec;
dda8d76d 9465 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9466 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9467 arm_sec->rela = NULL;
9468 arm_sec->nrelas = 0;
9469
dda8d76d
NC
9470 for (relsec = filedata->section_headers;
9471 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9472 ++relsec)
9473 {
dda8d76d
NC
9474 if (relsec->sh_info >= filedata->file_header.e_shnum
9475 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9476 /* PR 15745: Check the section type as well. */
9477 || (relsec->sh_type != SHT_REL
9478 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9479 continue;
9480
a734115a 9481 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9482 if (relsec->sh_type == SHT_REL)
9483 {
dda8d76d 9484 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9485 relsec->sh_size,
9486 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9487 return false;
0b6ae522 9488 }
1ae40aa4 9489 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9490 {
dda8d76d 9491 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9492 relsec->sh_size,
9493 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9494 return false;
0b6ae522 9495 }
1ae40aa4 9496 break;
0b6ae522
DJ
9497 }
9498
9499 arm_sec->next_rela = arm_sec->rela;
9500 }
9501
a734115a 9502 /* If there is no unwind data we can do nothing. */
0b6ae522 9503 if (arm_sec->data == NULL)
015dc7e1 9504 return false;
0b6ae522 9505
e0a31db1 9506 /* If the offset is invalid then fail. */
f32ba729
NC
9507 if (/* PR 21343 *//* PR 18879 */
9508 sec->sh_size < 4
625d49fc 9509 || word_offset > sec->sh_size - 4)
015dc7e1 9510 return false;
e0a31db1 9511
a734115a 9512 /* Get the word at the required offset. */
0b6ae522
DJ
9513 word = byte_get (arm_sec->data + word_offset, 4);
9514
0eff7165
NC
9515 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9516 if (arm_sec->rela == NULL)
9517 {
9518 * wordp = word;
015dc7e1 9519 return true;
0eff7165
NC
9520 }
9521
a734115a 9522 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9523 wrapped = false;
0b6ae522
DJ
9524 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9525 {
625d49fc 9526 uint64_t prelval, offset;
0b6ae522
DJ
9527
9528 if (rp->r_offset > word_offset && !wrapped)
9529 {
9530 rp = arm_sec->rela;
015dc7e1 9531 wrapped = true;
0b6ae522
DJ
9532 }
9533 if (rp->r_offset > word_offset)
9534 break;
9535
9536 if (rp->r_offset & 3)
9537 {
9538 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9539 (unsigned long) rp->r_offset);
9540 continue;
9541 }
9542
9543 if (rp->r_offset < word_offset)
9544 continue;
9545
74e1a04b
NC
9546 /* PR 17531: file: 027-161405-0.004 */
9547 if (aux->symtab == NULL)
9548 continue;
9549
0b6ae522
DJ
9550 if (arm_sec->rel_type == SHT_REL)
9551 {
9552 offset = word & 0x7fffffff;
9553 if (offset & 0x40000000)
625d49fc 9554 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 9555 }
a734115a 9556 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9557 offset = rp->r_addend;
a734115a 9558 else
74e1a04b
NC
9559 {
9560 error (_("Unknown section relocation type %d encountered\n"),
9561 arm_sec->rel_type);
9562 break;
9563 }
0b6ae522 9564
071436c6
NC
9565 /* PR 17531 file: 027-1241568-0.004. */
9566 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9567 {
9568 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9569 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9570 break;
9571 }
9572
9573 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9574 offset += sym->st_value;
9575 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9576
a734115a 9577 /* Check that we are processing the expected reloc type. */
dda8d76d 9578 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9579 {
9580 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9581 if (relname == NULL)
9582 {
9583 warn (_("Skipping unknown ARM relocation type: %d\n"),
9584 (int) ELF32_R_TYPE (rp->r_info));
9585 continue;
9586 }
a734115a
NC
9587
9588 if (streq (relname, "R_ARM_NONE"))
9589 continue;
0b4362b0 9590
a734115a
NC
9591 if (! streq (relname, "R_ARM_PREL31"))
9592 {
071436c6 9593 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9594 continue;
9595 }
9596 }
dda8d76d 9597 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9598 {
9599 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9600 if (relname == NULL)
9601 {
9602 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9603 (int) ELF32_R_TYPE (rp->r_info));
9604 continue;
9605 }
0b4362b0 9606
a734115a
NC
9607 if (streq (relname, "R_C6000_NONE"))
9608 continue;
9609
9610 if (! streq (relname, "R_C6000_PREL31"))
9611 {
071436c6 9612 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9613 continue;
9614 }
9615
9616 prelval >>= 1;
9617 }
9618 else
74e1a04b
NC
9619 {
9620 /* This function currently only supports ARM and TI unwinders. */
9621 warn (_("Only TI and ARM unwinders are currently supported\n"));
9622 break;
9623 }
fa197c1c 9624
625d49fc 9625 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
9626 addr->section = sym->st_shndx;
9627 addr->offset = offset;
74e1a04b 9628
1b31d05e
NC
9629 if (sym_name)
9630 * sym_name = sym->st_name;
0b6ae522
DJ
9631 break;
9632 }
9633
9634 *wordp = word;
9635 arm_sec->next_rela = rp;
9636
015dc7e1 9637 return true;
0b6ae522
DJ
9638}
9639
a734115a
NC
9640static const char *tic6x_unwind_regnames[16] =
9641{
0b4362b0
RM
9642 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9643 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9644 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9645};
fa197c1c 9646
0b6ae522 9647static void
fa197c1c 9648decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9649{
fa197c1c
PB
9650 int i;
9651
9652 for (i = 12; mask; mask >>= 1, i--)
9653 {
9654 if (mask & 1)
9655 {
9656 fputs (tic6x_unwind_regnames[i], stdout);
9657 if (mask > 1)
9658 fputs (", ", stdout);
9659 }
9660 }
9661}
0b6ae522
DJ
9662
9663#define ADVANCE \
9664 if (remaining == 0 && more_words) \
9665 { \
9666 data_offset += 4; \
dda8d76d 9667 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9668 data_offset, & word, & addr, NULL)) \
015dc7e1 9669 return false; \
0b6ae522
DJ
9670 remaining = 4; \
9671 more_words--; \
9672 } \
9673
9674#define GET_OP(OP) \
9675 ADVANCE; \
9676 if (remaining) \
9677 { \
9678 remaining--; \
9679 (OP) = word >> 24; \
9680 word <<= 8; \
9681 } \
9682 else \
9683 { \
2b692964 9684 printf (_("[Truncated opcode]\n")); \
015dc7e1 9685 return false; \
0b6ae522 9686 } \
cc5914eb 9687 printf ("0x%02x ", OP)
0b6ae522 9688
015dc7e1 9689static bool
dda8d76d
NC
9690decode_arm_unwind_bytecode (Filedata * filedata,
9691 struct arm_unw_aux_info * aux,
948f632f
DA
9692 unsigned int word,
9693 unsigned int remaining,
9694 unsigned int more_words,
625d49fc 9695 uint64_t data_offset,
948f632f
DA
9696 Elf_Internal_Shdr * data_sec,
9697 struct arm_section * data_arm_sec)
fa197c1c
PB
9698{
9699 struct absaddr addr;
015dc7e1 9700 bool res = true;
0b6ae522
DJ
9701
9702 /* Decode the unwinding instructions. */
9703 while (1)
9704 {
9705 unsigned int op, op2;
9706
9707 ADVANCE;
9708 if (remaining == 0)
9709 break;
9710 remaining--;
9711 op = word >> 24;
9712 word <<= 8;
9713
cc5914eb 9714 printf (" 0x%02x ", op);
0b6ae522
DJ
9715
9716 if ((op & 0xc0) == 0x00)
9717 {
9718 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9719
cc5914eb 9720 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9721 }
9722 else if ((op & 0xc0) == 0x40)
9723 {
9724 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9725
cc5914eb 9726 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9727 }
9728 else if ((op & 0xf0) == 0x80)
9729 {
9730 GET_OP (op2);
9731 if (op == 0x80 && op2 == 0)
9732 printf (_("Refuse to unwind"));
9733 else
9734 {
9735 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9736 bool first = true;
0b6ae522 9737 int i;
2b692964 9738
0b6ae522
DJ
9739 printf ("pop {");
9740 for (i = 0; i < 12; i++)
9741 if (mask & (1 << i))
9742 {
9743 if (first)
015dc7e1 9744 first = false;
0b6ae522
DJ
9745 else
9746 printf (", ");
9747 printf ("r%d", 4 + i);
9748 }
9749 printf ("}");
9750 }
9751 }
9752 else if ((op & 0xf0) == 0x90)
9753 {
9754 if (op == 0x9d || op == 0x9f)
9755 printf (_(" [Reserved]"));
9756 else
cc5914eb 9757 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9758 }
9759 else if ((op & 0xf0) == 0xa0)
9760 {
9761 int end = 4 + (op & 0x07);
015dc7e1 9762 bool first = true;
0b6ae522 9763 int i;
61865e30 9764
0b6ae522
DJ
9765 printf (" pop {");
9766 for (i = 4; i <= end; i++)
9767 {
9768 if (first)
015dc7e1 9769 first = false;
0b6ae522
DJ
9770 else
9771 printf (", ");
9772 printf ("r%d", i);
9773 }
9774 if (op & 0x08)
9775 {
1b31d05e 9776 if (!first)
0b6ae522
DJ
9777 printf (", ");
9778 printf ("r14");
9779 }
9780 printf ("}");
9781 }
9782 else if (op == 0xb0)
9783 printf (_(" finish"));
9784 else if (op == 0xb1)
9785 {
9786 GET_OP (op2);
9787 if (op2 == 0 || (op2 & 0xf0) != 0)
9788 printf (_("[Spare]"));
9789 else
9790 {
9791 unsigned int mask = op2 & 0x0f;
015dc7e1 9792 bool first = true;
0b6ae522 9793 int i;
61865e30 9794
0b6ae522
DJ
9795 printf ("pop {");
9796 for (i = 0; i < 12; i++)
9797 if (mask & (1 << i))
9798 {
9799 if (first)
015dc7e1 9800 first = false;
0b6ae522
DJ
9801 else
9802 printf (", ");
9803 printf ("r%d", i);
9804 }
9805 printf ("}");
9806 }
9807 }
9808 else if (op == 0xb2)
9809 {
b115cf96 9810 unsigned char buf[9];
0b6ae522
DJ
9811 unsigned int i, len;
9812 unsigned long offset;
61865e30 9813
b115cf96 9814 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9815 {
9816 GET_OP (buf[i]);
9817 if ((buf[i] & 0x80) == 0)
9818 break;
9819 }
4082ef84 9820 if (i == sizeof (buf))
32ec8896 9821 {
27a45f42 9822 error (_("corrupt change to vsp\n"));
015dc7e1 9823 res = false;
32ec8896 9824 }
4082ef84
NC
9825 else
9826 {
015dc7e1 9827 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9828 assert (len == i + 1);
9829 offset = offset * 4 + 0x204;
9830 printf ("vsp = vsp + %ld", offset);
9831 }
0b6ae522 9832 }
61865e30 9833 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9834 {
61865e30
NC
9835 unsigned int first, last;
9836
9837 GET_OP (op2);
9838 first = op2 >> 4;
9839 last = op2 & 0x0f;
9840 if (op == 0xc8)
9841 first = first + 16;
9842 printf ("pop {D%d", first);
9843 if (last)
9844 printf ("-D%d", first + last);
9845 printf ("}");
9846 }
09854a88
TB
9847 else if (op == 0xb4)
9848 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9849 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9850 {
9851 unsigned int count = op & 0x07;
9852
9853 printf ("pop {D8");
9854 if (count)
9855 printf ("-D%d", 8 + count);
9856 printf ("}");
9857 }
9858 else if (op >= 0xc0 && op <= 0xc5)
9859 {
9860 unsigned int count = op & 0x07;
9861
9862 printf (" pop {wR10");
9863 if (count)
9864 printf ("-wR%d", 10 + count);
9865 printf ("}");
9866 }
9867 else if (op == 0xc6)
9868 {
9869 unsigned int first, last;
9870
9871 GET_OP (op2);
9872 first = op2 >> 4;
9873 last = op2 & 0x0f;
9874 printf ("pop {wR%d", first);
9875 if (last)
9876 printf ("-wR%d", first + last);
9877 printf ("}");
9878 }
9879 else if (op == 0xc7)
9880 {
9881 GET_OP (op2);
9882 if (op2 == 0 || (op2 & 0xf0) != 0)
9883 printf (_("[Spare]"));
0b6ae522
DJ
9884 else
9885 {
61865e30 9886 unsigned int mask = op2 & 0x0f;
015dc7e1 9887 bool first = true;
61865e30
NC
9888 int i;
9889
9890 printf ("pop {");
9891 for (i = 0; i < 4; i++)
9892 if (mask & (1 << i))
9893 {
9894 if (first)
015dc7e1 9895 first = false;
61865e30
NC
9896 else
9897 printf (", ");
9898 printf ("wCGR%d", i);
9899 }
9900 printf ("}");
0b6ae522
DJ
9901 }
9902 }
61865e30 9903 else
32ec8896
NC
9904 {
9905 printf (_(" [unsupported opcode]"));
015dc7e1 9906 res = false;
32ec8896
NC
9907 }
9908
0b6ae522
DJ
9909 printf ("\n");
9910 }
32ec8896
NC
9911
9912 return res;
fa197c1c
PB
9913}
9914
015dc7e1 9915static bool
dda8d76d
NC
9916decode_tic6x_unwind_bytecode (Filedata * filedata,
9917 struct arm_unw_aux_info * aux,
948f632f
DA
9918 unsigned int word,
9919 unsigned int remaining,
9920 unsigned int more_words,
625d49fc 9921 uint64_t data_offset,
948f632f
DA
9922 Elf_Internal_Shdr * data_sec,
9923 struct arm_section * data_arm_sec)
fa197c1c
PB
9924{
9925 struct absaddr addr;
9926
9927 /* Decode the unwinding instructions. */
9928 while (1)
9929 {
9930 unsigned int op, op2;
9931
9932 ADVANCE;
9933 if (remaining == 0)
9934 break;
9935 remaining--;
9936 op = word >> 24;
9937 word <<= 8;
9938
9cf03b7e 9939 printf (" 0x%02x ", op);
fa197c1c
PB
9940
9941 if ((op & 0xc0) == 0x00)
9942 {
9943 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9944 printf (" sp = sp + %d", offset);
fa197c1c
PB
9945 }
9946 else if ((op & 0xc0) == 0x80)
9947 {
9948 GET_OP (op2);
9949 if (op == 0x80 && op2 == 0)
9950 printf (_("Refuse to unwind"));
9951 else
9952 {
9953 unsigned int mask = ((op & 0x1f) << 8) | op2;
9954 if (op & 0x20)
9955 printf ("pop compact {");
9956 else
9957 printf ("pop {");
9958
9959 decode_tic6x_unwind_regmask (mask);
9960 printf("}");
9961 }
9962 }
9963 else if ((op & 0xf0) == 0xc0)
9964 {
9965 unsigned int reg;
9966 unsigned int nregs;
9967 unsigned int i;
9968 const char *name;
a734115a
NC
9969 struct
9970 {
32ec8896
NC
9971 unsigned int offset;
9972 unsigned int reg;
fa197c1c
PB
9973 } regpos[16];
9974
9975 /* Scan entire instruction first so that GET_OP output is not
9976 interleaved with disassembly. */
9977 nregs = 0;
9978 for (i = 0; nregs < (op & 0xf); i++)
9979 {
9980 GET_OP (op2);
9981 reg = op2 >> 4;
9982 if (reg != 0xf)
9983 {
9984 regpos[nregs].offset = i * 2;
9985 regpos[nregs].reg = reg;
9986 nregs++;
9987 }
9988
9989 reg = op2 & 0xf;
9990 if (reg != 0xf)
9991 {
9992 regpos[nregs].offset = i * 2 + 1;
9993 regpos[nregs].reg = reg;
9994 nregs++;
9995 }
9996 }
9997
9998 printf (_("pop frame {"));
18344509 9999 if (nregs == 0)
fa197c1c 10000 {
18344509
NC
10001 printf (_("*corrupt* - no registers specified"));
10002 }
10003 else
10004 {
10005 reg = nregs - 1;
10006 for (i = i * 2; i > 0; i--)
fa197c1c 10007 {
18344509
NC
10008 if (regpos[reg].offset == i - 1)
10009 {
10010 name = tic6x_unwind_regnames[regpos[reg].reg];
10011 if (reg > 0)
10012 reg--;
10013 }
10014 else
10015 name = _("[pad]");
fa197c1c 10016
18344509
NC
10017 fputs (name, stdout);
10018 if (i > 1)
10019 printf (", ");
10020 }
fa197c1c
PB
10021 }
10022
10023 printf ("}");
10024 }
10025 else if (op == 0xd0)
10026 printf (" MOV FP, SP");
10027 else if (op == 0xd1)
10028 printf (" __c6xabi_pop_rts");
10029 else if (op == 0xd2)
10030 {
10031 unsigned char buf[9];
10032 unsigned int i, len;
10033 unsigned long offset;
a734115a 10034
fa197c1c
PB
10035 for (i = 0; i < sizeof (buf); i++)
10036 {
10037 GET_OP (buf[i]);
10038 if ((buf[i] & 0x80) == 0)
10039 break;
10040 }
0eff7165
NC
10041 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10042 if (i == sizeof (buf))
10043 {
0eff7165 10044 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10045 return false;
0eff7165 10046 }
948f632f 10047
015dc7e1 10048 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10049 assert (len == i + 1);
10050 offset = offset * 8 + 0x408;
10051 printf (_("sp = sp + %ld"), offset);
10052 }
10053 else if ((op & 0xf0) == 0xe0)
10054 {
10055 if ((op & 0x0f) == 7)
10056 printf (" RETURN");
10057 else
10058 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10059 }
10060 else
10061 {
10062 printf (_(" [unsupported opcode]"));
10063 }
10064 putchar ('\n');
10065 }
32ec8896 10066
015dc7e1 10067 return true;
fa197c1c
PB
10068}
10069
625d49fc
AM
10070static uint64_t
10071arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10072{
625d49fc 10073 uint64_t offset;
fa197c1c
PB
10074
10075 offset = word & 0x7fffffff;
10076 if (offset & 0x40000000)
625d49fc 10077 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10078
dda8d76d 10079 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10080 offset <<= 1;
10081
10082 return offset + where;
10083}
10084
015dc7e1 10085static bool
dda8d76d
NC
10086decode_arm_unwind (Filedata * filedata,
10087 struct arm_unw_aux_info * aux,
1b31d05e
NC
10088 unsigned int word,
10089 unsigned int remaining,
625d49fc 10090 uint64_t data_offset,
1b31d05e
NC
10091 Elf_Internal_Shdr * data_sec,
10092 struct arm_section * data_arm_sec)
fa197c1c
PB
10093{
10094 int per_index;
10095 unsigned int more_words = 0;
37e14bc3 10096 struct absaddr addr;
625d49fc 10097 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10098 bool res = true;
fa197c1c
PB
10099
10100 if (remaining == 0)
10101 {
1b31d05e
NC
10102 /* Fetch the first word.
10103 Note - when decoding an object file the address extracted
10104 here will always be 0. So we also pass in the sym_name
10105 parameter so that we can find the symbol associated with
10106 the personality routine. */
dda8d76d 10107 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10108 & word, & addr, & sym_name))
015dc7e1 10109 return false;
1b31d05e 10110
fa197c1c
PB
10111 remaining = 4;
10112 }
c93dbb25
CZ
10113 else
10114 {
10115 addr.section = SHN_UNDEF;
10116 addr.offset = 0;
10117 }
fa197c1c
PB
10118
10119 if ((word & 0x80000000) == 0)
10120 {
10121 /* Expand prel31 for personality routine. */
625d49fc 10122 uint64_t fn;
fa197c1c
PB
10123 const char *procname;
10124
dda8d76d 10125 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10126 printf (_(" Personality routine: "));
1b31d05e
NC
10127 if (fn == 0
10128 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10129 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10130 {
10131 procname = aux->strtab + sym_name;
10132 print_vma (fn, PREFIX_HEX);
10133 if (procname)
10134 {
10135 fputs (" <", stdout);
10136 fputs (procname, stdout);
10137 fputc ('>', stdout);
10138 }
10139 }
10140 else
dda8d76d 10141 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10142 fputc ('\n', stdout);
10143
10144 /* The GCC personality routines use the standard compact
10145 encoding, starting with one byte giving the number of
10146 words. */
10147 if (procname != NULL
24d127aa
ML
10148 && (startswith (procname, "__gcc_personality_v0")
10149 || startswith (procname, "__gxx_personality_v0")
10150 || startswith (procname, "__gcj_personality_v0")
10151 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10152 {
10153 remaining = 0;
10154 more_words = 1;
10155 ADVANCE;
10156 if (!remaining)
10157 {
10158 printf (_(" [Truncated data]\n"));
015dc7e1 10159 return false;
fa197c1c
PB
10160 }
10161 more_words = word >> 24;
10162 word <<= 8;
10163 remaining--;
10164 per_index = -1;
10165 }
10166 else
015dc7e1 10167 return true;
fa197c1c
PB
10168 }
10169 else
10170 {
1b31d05e 10171 /* ARM EHABI Section 6.3:
0b4362b0 10172
1b31d05e 10173 An exception-handling table entry for the compact model looks like:
0b4362b0 10174
1b31d05e
NC
10175 31 30-28 27-24 23-0
10176 -- ----- ----- ----
10177 1 0 index Data for personalityRoutine[index] */
10178
dda8d76d 10179 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10180 && (word & 0x70000000))
32ec8896
NC
10181 {
10182 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10183 res = false;
32ec8896 10184 }
1b31d05e 10185
fa197c1c 10186 per_index = (word >> 24) & 0x7f;
1b31d05e 10187 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10188 if (per_index == 0)
10189 {
10190 more_words = 0;
10191 word <<= 8;
10192 remaining--;
10193 }
10194 else if (per_index < 3)
10195 {
10196 more_words = (word >> 16) & 0xff;
10197 word <<= 16;
10198 remaining -= 2;
10199 }
10200 }
10201
dda8d76d 10202 switch (filedata->file_header.e_machine)
fa197c1c
PB
10203 {
10204 case EM_ARM:
10205 if (per_index < 3)
10206 {
dda8d76d 10207 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10208 data_offset, data_sec, data_arm_sec))
015dc7e1 10209 res = false;
fa197c1c
PB
10210 }
10211 else
1b31d05e
NC
10212 {
10213 warn (_("Unknown ARM compact model index encountered\n"));
10214 printf (_(" [reserved]\n"));
015dc7e1 10215 res = false;
1b31d05e 10216 }
fa197c1c
PB
10217 break;
10218
10219 case EM_TI_C6000:
10220 if (per_index < 3)
10221 {
dda8d76d 10222 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10223 data_offset, data_sec, data_arm_sec))
015dc7e1 10224 res = false;
fa197c1c
PB
10225 }
10226 else if (per_index < 5)
10227 {
10228 if (((word >> 17) & 0x7f) == 0x7f)
10229 printf (_(" Restore stack from frame pointer\n"));
10230 else
10231 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10232 printf (_(" Registers restored: "));
10233 if (per_index == 4)
10234 printf (" (compact) ");
10235 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10236 putchar ('\n');
10237 printf (_(" Return register: %s\n"),
10238 tic6x_unwind_regnames[word & 0xf]);
10239 }
10240 else
1b31d05e 10241 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10242 break;
10243
10244 default:
74e1a04b 10245 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10246 filedata->file_header.e_machine);
015dc7e1 10247 res = false;
fa197c1c 10248 }
0b6ae522
DJ
10249
10250 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10251
10252 return res;
0b6ae522
DJ
10253}
10254
015dc7e1 10255static bool
dda8d76d
NC
10256dump_arm_unwind (Filedata * filedata,
10257 struct arm_unw_aux_info * aux,
10258 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10259{
10260 struct arm_section exidx_arm_sec, extab_arm_sec;
10261 unsigned int i, exidx_len;
948f632f 10262 unsigned long j, nfuns;
015dc7e1 10263 bool res = true;
0b6ae522
DJ
10264
10265 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10266 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10267 exidx_len = exidx_sec->sh_size / 8;
10268
948f632f
DA
10269 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10270 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10271 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10272 aux->funtab[nfuns++] = aux->symtab[j];
10273 aux->nfuns = nfuns;
10274 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10275
0b6ae522
DJ
10276 for (i = 0; i < exidx_len; i++)
10277 {
10278 unsigned int exidx_fn, exidx_entry;
10279 struct absaddr fn_addr, entry_addr;
625d49fc 10280 uint64_t fn;
0b6ae522
DJ
10281
10282 fputc ('\n', stdout);
10283
dda8d76d 10284 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10285 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10286 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10287 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10288 {
948f632f 10289 free (aux->funtab);
1b31d05e
NC
10290 arm_free_section (& exidx_arm_sec);
10291 arm_free_section (& extab_arm_sec);
015dc7e1 10292 return false;
0b6ae522
DJ
10293 }
10294
83c257ca
NC
10295 /* ARM EHABI, Section 5:
10296 An index table entry consists of 2 words.
10297 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10298 if (exidx_fn & 0x80000000)
32ec8896
NC
10299 {
10300 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10301 res = false;
32ec8896 10302 }
83c257ca 10303
dda8d76d 10304 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10305
dda8d76d 10306 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10307 fputs (": ", stdout);
10308
10309 if (exidx_entry == 1)
10310 {
10311 print_vma (exidx_entry, PREFIX_HEX);
10312 fputs (" [cantunwind]\n", stdout);
10313 }
10314 else if (exidx_entry & 0x80000000)
10315 {
10316 print_vma (exidx_entry, PREFIX_HEX);
10317 fputc ('\n', stdout);
dda8d76d 10318 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10319 }
10320 else
10321 {
625d49fc 10322 uint64_t table, table_offset = 0;
0b6ae522
DJ
10323 Elf_Internal_Shdr *table_sec;
10324
10325 fputs ("@", stdout);
dda8d76d 10326 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10327 print_vma (table, PREFIX_HEX);
10328 printf ("\n");
10329
10330 /* Locate the matching .ARM.extab. */
10331 if (entry_addr.section != SHN_UNDEF
dda8d76d 10332 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10333 {
dda8d76d 10334 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10335 table_offset = entry_addr.offset;
1a915552 10336 /* PR 18879 */
625d49fc 10337 if (table_offset > table_sec->sh_size)
1a915552
NC
10338 {
10339 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10340 (unsigned long) table_offset,
dda8d76d 10341 printable_section_name (filedata, table_sec));
015dc7e1 10342 res = false;
1a915552
NC
10343 continue;
10344 }
0b6ae522
DJ
10345 }
10346 else
10347 {
dda8d76d 10348 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10349 if (table_sec != NULL)
10350 table_offset = table - table_sec->sh_addr;
10351 }
32ec8896 10352
0b6ae522
DJ
10353 if (table_sec == NULL)
10354 {
10355 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10356 (unsigned long) table);
015dc7e1 10357 res = false;
0b6ae522
DJ
10358 continue;
10359 }
32ec8896 10360
dda8d76d 10361 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10362 &extab_arm_sec))
015dc7e1 10363 res = false;
0b6ae522
DJ
10364 }
10365 }
10366
10367 printf ("\n");
10368
948f632f 10369 free (aux->funtab);
0b6ae522
DJ
10370 arm_free_section (&exidx_arm_sec);
10371 arm_free_section (&extab_arm_sec);
32ec8896
NC
10372
10373 return res;
0b6ae522
DJ
10374}
10375
fa197c1c 10376/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10377
015dc7e1 10378static bool
dda8d76d 10379arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10380{
10381 struct arm_unw_aux_info aux;
10382 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10383 Elf_Internal_Shdr *sec;
10384 unsigned long i;
fa197c1c 10385 unsigned int sec_type;
015dc7e1 10386 bool res = true;
0b6ae522 10387
dda8d76d 10388 switch (filedata->file_header.e_machine)
fa197c1c
PB
10389 {
10390 case EM_ARM:
10391 sec_type = SHT_ARM_EXIDX;
10392 break;
10393
10394 case EM_TI_C6000:
10395 sec_type = SHT_C6000_UNWIND;
10396 break;
10397
0b4362b0 10398 default:
74e1a04b 10399 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10400 filedata->file_header.e_machine);
015dc7e1 10401 return false;
fa197c1c
PB
10402 }
10403
dda8d76d 10404 if (filedata->string_table == NULL)
015dc7e1 10405 return false;
1b31d05e
NC
10406
10407 memset (& aux, 0, sizeof (aux));
dda8d76d 10408 aux.filedata = filedata;
0b6ae522 10409
dda8d76d 10410 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10411 {
28d13567 10412 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10413 {
28d13567 10414 if (aux.symtab)
74e1a04b 10415 {
28d13567
AM
10416 error (_("Multiple symbol tables encountered\n"));
10417 free (aux.symtab);
10418 aux.symtab = NULL;
74e1a04b 10419 free (aux.strtab);
28d13567 10420 aux.strtab = NULL;
74e1a04b 10421 }
28d13567
AM
10422 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10423 &aux.strtab, &aux.strtab_size))
015dc7e1 10424 return false;
0b6ae522 10425 }
fa197c1c 10426 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10427 unwsec = sec;
10428 }
10429
1b31d05e 10430 if (unwsec == NULL)
0b6ae522 10431 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10432 else
dda8d76d 10433 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10434 {
10435 if (sec->sh_type == sec_type)
10436 {
d3a49aa8
AM
10437 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10438 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10439 "contains %lu entry:\n",
10440 "\nUnwind section '%s' at offset 0x%lx "
10441 "contains %lu entries:\n",
10442 num_unwind),
dda8d76d 10443 printable_section_name (filedata, sec),
1b31d05e 10444 (unsigned long) sec->sh_offset,
d3a49aa8 10445 num_unwind);
0b6ae522 10446
dda8d76d 10447 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10448 res = false;
1b31d05e
NC
10449 }
10450 }
0b6ae522 10451
9db70fc3
AM
10452 free (aux.symtab);
10453 free ((char *) aux.strtab);
32ec8896
NC
10454
10455 return res;
0b6ae522
DJ
10456}
10457
3ecc00ec
NC
10458static bool
10459no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10460{
10461 printf (_("No processor specific unwind information to decode\n"));
10462 return true;
10463}
10464
015dc7e1 10465static bool
dda8d76d 10466process_unwind (Filedata * filedata)
57346661 10467{
2cf0635d
NC
10468 struct unwind_handler
10469 {
32ec8896 10470 unsigned int machtype;
015dc7e1 10471 bool (* handler)(Filedata *);
2cf0635d
NC
10472 } handlers[] =
10473 {
0b6ae522 10474 { EM_ARM, arm_process_unwind },
57346661
AM
10475 { EM_IA_64, ia64_process_unwind },
10476 { EM_PARISC, hppa_process_unwind },
fa197c1c 10477 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10478 { EM_386, no_processor_specific_unwind },
10479 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10480 { 0, NULL }
57346661
AM
10481 };
10482 int i;
10483
10484 if (!do_unwind)
015dc7e1 10485 return true;
57346661
AM
10486
10487 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10488 if (filedata->file_header.e_machine == handlers[i].machtype)
10489 return handlers[i].handler (filedata);
57346661 10490
1b31d05e 10491 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10492 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10493 return true;
57346661
AM
10494}
10495
37c18eed
SD
10496static void
10497dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10498{
10499 switch (entry->d_tag)
10500 {
10501 case DT_AARCH64_BTI_PLT:
1dbade74 10502 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10503 break;
10504 default:
10505 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10506 break;
10507 }
10508 putchar ('\n');
10509}
10510
252b5132 10511static void
978c4450 10512dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10513{
10514 switch (entry->d_tag)
10515 {
10516 case DT_MIPS_FLAGS:
10517 if (entry->d_un.d_val == 0)
4b68bca3 10518 printf (_("NONE"));
252b5132
RH
10519 else
10520 {
10521 static const char * opts[] =
10522 {
10523 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10524 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10525 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10526 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10527 "RLD_ORDER_SAFE"
10528 };
10529 unsigned int cnt;
015dc7e1 10530 bool first = true;
2b692964 10531
60bca95a 10532 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10533 if (entry->d_un.d_val & (1 << cnt))
10534 {
10535 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10536 first = false;
252b5132 10537 }
252b5132
RH
10538 }
10539 break;
103f02d3 10540
252b5132 10541 case DT_MIPS_IVERSION:
84714f86 10542 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10543 printf (_("Interface Version: %s"),
84714f86 10544 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10545 else
f493c217 10546 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 10547 entry->d_un.d_ptr);
252b5132 10548 break;
103f02d3 10549
252b5132
RH
10550 case DT_MIPS_TIME_STAMP:
10551 {
d5b07ef4 10552 char timebuf[128];
2cf0635d 10553 struct tm * tmp;
91d6fa6a 10554 time_t atime = entry->d_un.d_val;
82b1b41b 10555
91d6fa6a 10556 tmp = gmtime (&atime);
82b1b41b
NC
10557 /* PR 17531: file: 6accc532. */
10558 if (tmp == NULL)
10559 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10560 else
10561 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10562 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10563 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10564 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10565 }
10566 break;
103f02d3 10567
252b5132
RH
10568 case DT_MIPS_RLD_VERSION:
10569 case DT_MIPS_LOCAL_GOTNO:
10570 case DT_MIPS_CONFLICTNO:
10571 case DT_MIPS_LIBLISTNO:
10572 case DT_MIPS_SYMTABNO:
10573 case DT_MIPS_UNREFEXTNO:
10574 case DT_MIPS_HIPAGENO:
10575 case DT_MIPS_DELTA_CLASS_NO:
10576 case DT_MIPS_DELTA_INSTANCE_NO:
10577 case DT_MIPS_DELTA_RELOC_NO:
10578 case DT_MIPS_DELTA_SYM_NO:
10579 case DT_MIPS_DELTA_CLASSSYM_NO:
10580 case DT_MIPS_COMPACT_SIZE:
c69075ac 10581 print_vma (entry->d_un.d_val, DEC);
252b5132 10582 break;
103f02d3 10583
f16a9783 10584 case DT_MIPS_XHASH:
978c4450
AM
10585 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10586 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10587 /* Falls through. */
10588
103f02d3 10589 default:
4b68bca3 10590 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10591 }
4b68bca3 10592 putchar ('\n');
103f02d3
UD
10593}
10594
103f02d3 10595static void
2cf0635d 10596dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10597{
10598 switch (entry->d_tag)
10599 {
10600 case DT_HP_DLD_FLAGS:
10601 {
10602 static struct
10603 {
10604 long int bit;
2cf0635d 10605 const char * str;
5e220199
NC
10606 }
10607 flags[] =
10608 {
10609 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10610 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10611 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10612 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10613 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10614 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10615 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10616 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10617 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10618 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10619 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10620 { DT_HP_GST, "HP_GST" },
10621 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10622 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10623 { DT_HP_NODELETE, "HP_NODELETE" },
10624 { DT_HP_GROUP, "HP_GROUP" },
10625 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10626 };
015dc7e1 10627 bool first = true;
5e220199 10628 size_t cnt;
625d49fc 10629 uint64_t val = entry->d_un.d_val;
103f02d3 10630
60bca95a 10631 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10632 if (val & flags[cnt].bit)
30800947
NC
10633 {
10634 if (! first)
10635 putchar (' ');
10636 fputs (flags[cnt].str, stdout);
015dc7e1 10637 first = false;
30800947
NC
10638 val ^= flags[cnt].bit;
10639 }
76da6bbe 10640
103f02d3 10641 if (val != 0 || first)
f7a99963
NC
10642 {
10643 if (! first)
10644 putchar (' ');
10645 print_vma (val, HEX);
10646 }
103f02d3
UD
10647 }
10648 break;
76da6bbe 10649
252b5132 10650 default:
f7a99963
NC
10651 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10652 break;
252b5132 10653 }
35b1837e 10654 putchar ('\n');
252b5132
RH
10655}
10656
28f997cf
TG
10657/* VMS vs Unix time offset and factor. */
10658
10659#define VMS_EPOCH_OFFSET 35067168000000000LL
10660#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10661#ifndef INT64_MIN
10662#define INT64_MIN (-9223372036854775807LL - 1)
10663#endif
28f997cf
TG
10664
10665/* Display a VMS time in a human readable format. */
10666
10667static void
0e3c1eeb 10668print_vms_time (int64_t vmstime)
28f997cf 10669{
dccc31de 10670 struct tm *tm = NULL;
28f997cf
TG
10671 time_t unxtime;
10672
dccc31de
AM
10673 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10674 {
10675 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10676 unxtime = vmstime;
10677 if (unxtime == vmstime)
10678 tm = gmtime (&unxtime);
10679 }
10680 if (tm != NULL)
10681 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10682 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10683 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 10684}
28f997cf 10685
ecc51f48 10686static void
2cf0635d 10687dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10688{
10689 switch (entry->d_tag)
10690 {
0de14b54 10691 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10692 /* First 3 slots reserved. */
ecc51f48
NC
10693 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10694 printf (" -- ");
10695 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10696 break;
10697
28f997cf 10698 case DT_IA_64_VMS_LINKTIME:
28f997cf 10699 print_vms_time (entry->d_un.d_val);
28f997cf
TG
10700 break;
10701
10702 case DT_IA_64_VMS_LNKFLAGS:
10703 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10704 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10705 printf (" CALL_DEBUG");
10706 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10707 printf (" NOP0BUFS");
10708 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10709 printf (" P0IMAGE");
10710 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10711 printf (" MKTHREADS");
10712 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10713 printf (" UPCALLS");
10714 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10715 printf (" IMGSTA");
10716 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10717 printf (" INITIALIZE");
10718 if (entry->d_un.d_val & VMS_LF_MAIN)
10719 printf (" MAIN");
10720 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10721 printf (" EXE_INIT");
10722 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10723 printf (" TBK_IN_IMG");
10724 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10725 printf (" DBG_IN_IMG");
10726 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10727 printf (" TBK_IN_DSF");
10728 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10729 printf (" DBG_IN_DSF");
10730 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10731 printf (" SIGNATURES");
10732 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10733 printf (" REL_SEG_OFF");
10734 break;
10735
bdf4d63a
JJ
10736 default:
10737 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10738 break;
ecc51f48 10739 }
bdf4d63a 10740 putchar ('\n');
ecc51f48
NC
10741}
10742
015dc7e1 10743static bool
dda8d76d 10744get_32bit_dynamic_section (Filedata * filedata)
252b5132 10745{
2cf0635d
NC
10746 Elf32_External_Dyn * edyn;
10747 Elf32_External_Dyn * ext;
10748 Elf_Internal_Dyn * entry;
103f02d3 10749
978c4450
AM
10750 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10751 filedata->dynamic_addr, 1,
10752 filedata->dynamic_size,
10753 _("dynamic section"));
a6e9f9df 10754 if (!edyn)
015dc7e1 10755 return false;
103f02d3 10756
071436c6
NC
10757 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10758 might not have the luxury of section headers. Look for the DT_NULL
10759 terminator to determine the number of entries. */
978c4450
AM
10760 for (ext = edyn, filedata->dynamic_nent = 0;
10761 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10762 ext++)
10763 {
978c4450 10764 filedata->dynamic_nent++;
ba2685cc
AM
10765 if (BYTE_GET (ext->d_tag) == DT_NULL)
10766 break;
10767 }
252b5132 10768
978c4450
AM
10769 filedata->dynamic_section
10770 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10771 if (filedata->dynamic_section == NULL)
252b5132 10772 {
8b73c356 10773 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10774 (unsigned long) filedata->dynamic_nent);
9ea033b2 10775 free (edyn);
015dc7e1 10776 return false;
9ea033b2 10777 }
252b5132 10778
978c4450
AM
10779 for (ext = edyn, entry = filedata->dynamic_section;
10780 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10781 ext++, entry++)
9ea033b2 10782 {
fb514b26
AM
10783 entry->d_tag = BYTE_GET (ext->d_tag);
10784 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10785 }
10786
9ea033b2
NC
10787 free (edyn);
10788
015dc7e1 10789 return true;
9ea033b2
NC
10790}
10791
015dc7e1 10792static bool
dda8d76d 10793get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10794{
2cf0635d
NC
10795 Elf64_External_Dyn * edyn;
10796 Elf64_External_Dyn * ext;
10797 Elf_Internal_Dyn * entry;
103f02d3 10798
071436c6 10799 /* Read in the data. */
978c4450
AM
10800 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10801 filedata->dynamic_addr, 1,
10802 filedata->dynamic_size,
10803 _("dynamic section"));
a6e9f9df 10804 if (!edyn)
015dc7e1 10805 return false;
103f02d3 10806
071436c6
NC
10807 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10808 might not have the luxury of section headers. Look for the DT_NULL
10809 terminator to determine the number of entries. */
978c4450 10810 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10811 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10812 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10813 ext++)
10814 {
978c4450 10815 filedata->dynamic_nent++;
66543521 10816 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
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);
252b5132 10826 free (edyn);
015dc7e1 10827 return false;
252b5132
RH
10828 }
10829
071436c6 10830 /* Convert from external to internal formats. */
978c4450
AM
10831 for (ext = edyn, entry = filedata->dynamic_section;
10832 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10833 ext++, entry++)
252b5132 10834 {
66543521
AM
10835 entry->d_tag = BYTE_GET (ext->d_tag);
10836 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10837 }
10838
10839 free (edyn);
10840
015dc7e1 10841 return true;
9ea033b2
NC
10842}
10843
4de91c10
AM
10844static bool
10845get_dynamic_section (Filedata *filedata)
10846{
10847 if (filedata->dynamic_section)
10848 return true;
10849
10850 if (is_32bit_elf)
10851 return get_32bit_dynamic_section (filedata);
10852 else
10853 return get_64bit_dynamic_section (filedata);
10854}
10855
e9e44622 10856static void
625d49fc 10857print_dynamic_flags (uint64_t flags)
d1133906 10858{
015dc7e1 10859 bool first = true;
13ae64f3 10860
d1133906
NC
10861 while (flags)
10862 {
625d49fc 10863 uint64_t flag;
d1133906
NC
10864
10865 flag = flags & - flags;
10866 flags &= ~ flag;
10867
e9e44622 10868 if (first)
015dc7e1 10869 first = false;
e9e44622
JJ
10870 else
10871 putc (' ', stdout);
13ae64f3 10872
d1133906
NC
10873 switch (flag)
10874 {
e9e44622
JJ
10875 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10876 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10877 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10878 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10879 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10880 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10881 }
10882 }
e9e44622 10883 puts ("");
d1133906
NC
10884}
10885
625d49fc 10886static uint64_t *
be7d229a 10887get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
10888{
10889 unsigned char * e_data;
625d49fc 10890 uint64_t * i_data;
10ca4b04 10891
be7d229a
AM
10892 /* If size_t is smaller than uint64_t, eg because you are building
10893 on a 32-bit host, then make sure that when number is cast to
10894 size_t no information is lost. */
10895 if ((size_t) number != number
10896 || ent_size * number / ent_size != number)
10ca4b04 10897 {
be7d229a 10898 error (_("Size overflow prevents reading %" PRIu64
b8281767 10899 " elements of size %u\n"),
be7d229a 10900 number, ent_size);
10ca4b04
L
10901 return NULL;
10902 }
10903
10904 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10905 attempting to allocate memory when the read is bound to fail. */
10906 if (ent_size * number > filedata->file_size)
10907 {
b8281767 10908 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 10909 number);
10ca4b04
L
10910 return NULL;
10911 }
10912
10913 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10914 if (e_data == NULL)
10915 {
b8281767 10916 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 10917 number);
10ca4b04
L
10918 return NULL;
10919 }
10920
10921 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10922 {
b8281767 10923 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 10924 number * ent_size);
10ca4b04
L
10925 free (e_data);
10926 return NULL;
10927 }
10928
625d49fc 10929 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
10930 if (i_data == NULL)
10931 {
b8281767 10932 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 10933 number);
10ca4b04
L
10934 free (e_data);
10935 return NULL;
10936 }
10937
10938 while (number--)
10939 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10940
10941 free (e_data);
10942
10943 return i_data;
10944}
10945
10946static unsigned long
10947get_num_dynamic_syms (Filedata * filedata)
10948{
10949 unsigned long num_of_syms = 0;
10950
10951 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10952 return num_of_syms;
10953
978c4450 10954 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10955 {
10956 unsigned char nb[8];
10957 unsigned char nc[8];
10958 unsigned int hash_ent_size = 4;
10959
10960 if ((filedata->file_header.e_machine == EM_ALPHA
10961 || filedata->file_header.e_machine == EM_S390
10962 || filedata->file_header.e_machine == EM_S390_OLD)
10963 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10964 hash_ent_size = 8;
10965
10966 if (fseek (filedata->handle,
978c4450
AM
10967 (filedata->archive_file_offset
10968 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10969 sizeof nb + sizeof nc)),
10970 SEEK_SET))
10971 {
10972 error (_("Unable to seek to start of dynamic information\n"));
10973 goto no_hash;
10974 }
10975
10976 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10977 {
10978 error (_("Failed to read in number of buckets\n"));
10979 goto no_hash;
10980 }
10981
10982 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10983 {
10984 error (_("Failed to read in number of chains\n"));
10985 goto no_hash;
10986 }
10987
978c4450
AM
10988 filedata->nbuckets = byte_get (nb, hash_ent_size);
10989 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10990
2482f306
AM
10991 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10992 {
10993 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10994 hash_ent_size);
10995 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10996 hash_ent_size);
001890e1 10997
2482f306
AM
10998 if (filedata->buckets != NULL && filedata->chains != NULL)
10999 num_of_syms = filedata->nchains;
11000 }
ceb9bf11 11001 no_hash:
10ca4b04
L
11002 if (num_of_syms == 0)
11003 {
9db70fc3
AM
11004 free (filedata->buckets);
11005 filedata->buckets = NULL;
11006 free (filedata->chains);
11007 filedata->chains = NULL;
978c4450 11008 filedata->nbuckets = 0;
10ca4b04
L
11009 }
11010 }
11011
978c4450 11012 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11013 {
11014 unsigned char nb[16];
625d49fc
AM
11015 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11016 uint64_t buckets_vma;
10ca4b04 11017 unsigned long hn;
10ca4b04
L
11018
11019 if (fseek (filedata->handle,
978c4450
AM
11020 (filedata->archive_file_offset
11021 + offset_from_vma (filedata,
11022 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
11023 sizeof nb)),
11024 SEEK_SET))
11025 {
11026 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11027 goto no_gnu_hash;
11028 }
11029
11030 if (fread (nb, 16, 1, filedata->handle) != 1)
11031 {
11032 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11033 goto no_gnu_hash;
11034 }
11035
978c4450
AM
11036 filedata->ngnubuckets = byte_get (nb, 4);
11037 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11038 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11039 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11040 if (is_32bit_elf)
11041 buckets_vma += bitmaskwords * 4;
11042 else
11043 buckets_vma += bitmaskwords * 8;
11044
11045 if (fseek (filedata->handle,
978c4450 11046 (filedata->archive_file_offset
10ca4b04
L
11047 + offset_from_vma (filedata, buckets_vma, 4)),
11048 SEEK_SET))
11049 {
11050 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11051 goto no_gnu_hash;
11052 }
11053
978c4450
AM
11054 filedata->gnubuckets
11055 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11056
978c4450 11057 if (filedata->gnubuckets == NULL)
90837ea7 11058 goto no_gnu_hash;
10ca4b04 11059
978c4450
AM
11060 for (i = 0; i < filedata->ngnubuckets; i++)
11061 if (filedata->gnubuckets[i] != 0)
10ca4b04 11062 {
978c4450 11063 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11064 goto no_gnu_hash;
10ca4b04 11065
978c4450
AM
11066 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11067 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11068 }
11069
11070 if (maxchain == 0xffffffff)
90837ea7 11071 goto no_gnu_hash;
10ca4b04 11072
978c4450 11073 maxchain -= filedata->gnusymidx;
10ca4b04
L
11074
11075 if (fseek (filedata->handle,
978c4450
AM
11076 (filedata->archive_file_offset
11077 + offset_from_vma (filedata,
11078 buckets_vma + 4 * (filedata->ngnubuckets
11079 + maxchain),
11080 4)),
10ca4b04
L
11081 SEEK_SET))
11082 {
11083 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11084 goto no_gnu_hash;
11085 }
11086
11087 do
11088 {
11089 if (fread (nb, 4, 1, filedata->handle) != 1)
11090 {
11091 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11092 goto no_gnu_hash;
11093 }
11094
11095 if (maxchain + 1 == 0)
90837ea7 11096 goto no_gnu_hash;
10ca4b04
L
11097
11098 ++maxchain;
11099 }
11100 while ((byte_get (nb, 4) & 1) == 0);
11101
11102 if (fseek (filedata->handle,
978c4450
AM
11103 (filedata->archive_file_offset
11104 + offset_from_vma (filedata, (buckets_vma
11105 + 4 * filedata->ngnubuckets),
11106 4)),
10ca4b04
L
11107 SEEK_SET))
11108 {
11109 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11110 goto no_gnu_hash;
11111 }
11112
978c4450
AM
11113 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11114 filedata->ngnuchains = maxchain;
10ca4b04 11115
978c4450 11116 if (filedata->gnuchains == NULL)
90837ea7 11117 goto no_gnu_hash;
10ca4b04 11118
978c4450 11119 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11120 {
11121 if (fseek (filedata->handle,
978c4450 11122 (filedata->archive_file_offset
10ca4b04 11123 + offset_from_vma (filedata, (buckets_vma
978c4450 11124 + 4 * (filedata->ngnubuckets
10ca4b04
L
11125 + maxchain)), 4)),
11126 SEEK_SET))
11127 {
11128 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11129 goto no_gnu_hash;
11130 }
11131
978c4450 11132 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11133 if (filedata->mipsxlat == NULL)
11134 goto no_gnu_hash;
10ca4b04
L
11135 }
11136
978c4450
AM
11137 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11138 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11139 {
625d49fc
AM
11140 uint64_t si = filedata->gnubuckets[hn];
11141 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11142
11143 do
11144 {
978c4450 11145 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11146 {
c31ab5a0
AM
11147 if (off < filedata->ngnuchains
11148 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11149 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11150 }
11151 else
11152 {
11153 if (si >= num_of_syms)
11154 num_of_syms = si + 1;
11155 }
11156 si++;
11157 }
978c4450
AM
11158 while (off < filedata->ngnuchains
11159 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11160 }
11161
90837ea7 11162 if (num_of_syms == 0)
10ca4b04 11163 {
90837ea7 11164 no_gnu_hash:
9db70fc3
AM
11165 free (filedata->mipsxlat);
11166 filedata->mipsxlat = NULL;
11167 free (filedata->gnuchains);
11168 filedata->gnuchains = NULL;
11169 free (filedata->gnubuckets);
11170 filedata->gnubuckets = NULL;
978c4450
AM
11171 filedata->ngnubuckets = 0;
11172 filedata->ngnuchains = 0;
10ca4b04
L
11173 }
11174 }
11175
11176 return num_of_syms;
11177}
11178
b2d38a17
NC
11179/* Parse and display the contents of the dynamic section. */
11180
015dc7e1 11181static bool
dda8d76d 11182process_dynamic_section (Filedata * filedata)
9ea033b2 11183{
2cf0635d 11184 Elf_Internal_Dyn * entry;
9ea033b2 11185
93df3340 11186 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11187 {
11188 if (do_dynamic)
ca0e11aa
NC
11189 {
11190 if (filedata->is_separate)
11191 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11192 filedata->file_name);
11193 else
11194 printf (_("\nThere is no dynamic section in this file.\n"));
11195 }
9ea033b2 11196
015dc7e1 11197 return true;
9ea033b2
NC
11198 }
11199
4de91c10
AM
11200 if (!get_dynamic_section (filedata))
11201 return false;
9ea033b2 11202
252b5132 11203 /* Find the appropriate symbol table. */
978c4450 11204 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11205 {
2482f306
AM
11206 unsigned long num_of_syms;
11207
978c4450
AM
11208 for (entry = filedata->dynamic_section;
11209 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11210 ++entry)
10ca4b04 11211 if (entry->d_tag == DT_SYMTAB)
978c4450 11212 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11213 else if (entry->d_tag == DT_SYMENT)
978c4450 11214 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11215 else if (entry->d_tag == DT_HASH)
978c4450 11216 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11217 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11218 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11219 else if ((filedata->file_header.e_machine == EM_MIPS
11220 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11221 && entry->d_tag == DT_MIPS_XHASH)
11222 {
978c4450
AM
11223 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11224 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11225 }
252b5132 11226
2482f306
AM
11227 num_of_syms = get_num_dynamic_syms (filedata);
11228
11229 if (num_of_syms != 0
11230 && filedata->dynamic_symbols == NULL
11231 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11232 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11233 {
11234 Elf_Internal_Phdr *seg;
625d49fc 11235 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11236
2482f306
AM
11237 if (! get_program_headers (filedata))
11238 {
11239 error (_("Cannot interpret virtual addresses "
11240 "without program headers.\n"));
015dc7e1 11241 return false;
2482f306 11242 }
252b5132 11243
2482f306
AM
11244 for (seg = filedata->program_headers;
11245 seg < filedata->program_headers + filedata->file_header.e_phnum;
11246 ++seg)
11247 {
11248 if (seg->p_type != PT_LOAD)
11249 continue;
252b5132 11250
2482f306
AM
11251 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11252 {
11253 /* See PR 21379 for a reproducer. */
11254 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11255 return false;
2482f306 11256 }
252b5132 11257
2482f306
AM
11258 if (vma >= (seg->p_vaddr & -seg->p_align)
11259 && vma < seg->p_vaddr + seg->p_filesz)
11260 {
11261 /* Since we do not know how big the symbol table is,
11262 we default to reading in up to the end of PT_LOAD
11263 segment and processing that. This is overkill, I
11264 know, but it should work. */
11265 Elf_Internal_Shdr section;
11266 section.sh_offset = (vma - seg->p_vaddr
11267 + seg->p_offset);
11268 section.sh_size = (num_of_syms
11269 * filedata->dynamic_info[DT_SYMENT]);
11270 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11271
11272 if (do_checks
11273 && filedata->dynamic_symtab_section != NULL
11274 && ((filedata->dynamic_symtab_section->sh_offset
11275 != section.sh_offset)
11276 || (filedata->dynamic_symtab_section->sh_size
11277 != section.sh_size)
11278 || (filedata->dynamic_symtab_section->sh_entsize
11279 != section.sh_entsize)))
11280 warn (_("\
11281the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11282
2482f306
AM
11283 section.sh_name = filedata->string_table_length;
11284 filedata->dynamic_symbols
4de91c10 11285 = get_elf_symbols (filedata, &section,
2482f306
AM
11286 &filedata->num_dynamic_syms);
11287 if (filedata->dynamic_symbols == NULL
11288 || filedata->num_dynamic_syms != num_of_syms)
11289 {
11290 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11291 return false;
2482f306
AM
11292 }
11293 break;
11294 }
11295 }
11296 }
11297 }
252b5132
RH
11298
11299 /* Similarly find a string table. */
978c4450
AM
11300 if (filedata->dynamic_strings == NULL)
11301 for (entry = filedata->dynamic_section;
11302 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11303 ++entry)
11304 {
11305 if (entry->d_tag == DT_STRTAB)
978c4450 11306 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11307
10ca4b04 11308 if (entry->d_tag == DT_STRSZ)
978c4450 11309 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11310
978c4450
AM
11311 if (filedata->dynamic_info[DT_STRTAB]
11312 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11313 {
11314 unsigned long offset;
be7d229a 11315 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11316
11317 offset = offset_from_vma (filedata,
978c4450 11318 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11319 str_tab_len);
8ac10c5b
L
11320 if (do_checks
11321 && filedata->dynamic_strtab_section
11322 && ((filedata->dynamic_strtab_section->sh_offset
11323 != (file_ptr) offset)
11324 || (filedata->dynamic_strtab_section->sh_size
11325 != str_tab_len)))
11326 warn (_("\
11327the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11328
978c4450
AM
11329 filedata->dynamic_strings
11330 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11331 _("dynamic string table"));
11332 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11333 {
11334 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11335 break;
11336 }
e3d39609 11337
978c4450 11338 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11339 break;
11340 }
11341 }
252b5132
RH
11342
11343 /* And find the syminfo section if available. */
978c4450 11344 if (filedata->dynamic_syminfo == NULL)
252b5132 11345 {
3e8bba36 11346 unsigned long syminsz = 0;
252b5132 11347
978c4450
AM
11348 for (entry = filedata->dynamic_section;
11349 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11350 ++entry)
252b5132
RH
11351 {
11352 if (entry->d_tag == DT_SYMINENT)
11353 {
11354 /* Note: these braces are necessary to avoid a syntax
11355 error from the SunOS4 C compiler. */
049b0c3a
NC
11356 /* PR binutils/17531: A corrupt file can trigger this test.
11357 So do not use an assert, instead generate an error message. */
11358 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11359 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11360 (int) entry->d_un.d_val);
252b5132
RH
11361 }
11362 else if (entry->d_tag == DT_SYMINSZ)
11363 syminsz = entry->d_un.d_val;
11364 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11365 filedata->dynamic_syminfo_offset
11366 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11367 }
11368
978c4450 11369 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11370 {
2cf0635d
NC
11371 Elf_External_Syminfo * extsyminfo;
11372 Elf_External_Syminfo * extsym;
11373 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11374
11375 /* There is a syminfo section. Read the data. */
3f5e193b 11376 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11377 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11378 1, syminsz, _("symbol information"));
a6e9f9df 11379 if (!extsyminfo)
015dc7e1 11380 return false;
252b5132 11381
978c4450 11382 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11383 {
11384 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11385 free (filedata->dynamic_syminfo);
e3d39609 11386 }
978c4450
AM
11387 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11388 if (filedata->dynamic_syminfo == NULL)
252b5132 11389 {
2482f306
AM
11390 error (_("Out of memory allocating %lu bytes "
11391 "for dynamic symbol info\n"),
8b73c356 11392 (unsigned long) syminsz);
015dc7e1 11393 return false;
252b5132
RH
11394 }
11395
2482f306
AM
11396 filedata->dynamic_syminfo_nent
11397 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11398 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11399 syminfo < (filedata->dynamic_syminfo
11400 + filedata->dynamic_syminfo_nent);
86dba8ee 11401 ++syminfo, ++extsym)
252b5132 11402 {
86dba8ee
AM
11403 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11404 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11405 }
11406
11407 free (extsyminfo);
11408 }
11409 }
11410
978c4450 11411 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11412 {
f253158f
NC
11413 if (filedata->is_separate)
11414 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11415 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11416 (unsigned long) filedata->dynamic_nent),
11417 filedata->file_name,
11418 filedata->dynamic_addr,
11419 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11420 else
11421 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11422 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11423 (unsigned long) filedata->dynamic_nent),
11424 filedata->dynamic_addr,
11425 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11426 }
252b5132
RH
11427 if (do_dynamic)
11428 printf (_(" Tag Type Name/Value\n"));
11429
978c4450
AM
11430 for (entry = filedata->dynamic_section;
11431 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11432 entry++)
252b5132
RH
11433 {
11434 if (do_dynamic)
f7a99963 11435 {
2cf0635d 11436 const char * dtype;
e699b9ff 11437
f7a99963
NC
11438 putchar (' ');
11439 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11440 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11441 printf (" (%s)%*s", dtype,
32ec8896 11442 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11443 }
252b5132
RH
11444
11445 switch (entry->d_tag)
11446 {
d1133906
NC
11447 case DT_FLAGS:
11448 if (do_dynamic)
e9e44622 11449 print_dynamic_flags (entry->d_un.d_val);
d1133906 11450 break;
76da6bbe 11451
252b5132
RH
11452 case DT_AUXILIARY:
11453 case DT_FILTER:
019148e4
L
11454 case DT_CONFIG:
11455 case DT_DEPAUDIT:
11456 case DT_AUDIT:
252b5132
RH
11457 if (do_dynamic)
11458 {
019148e4 11459 switch (entry->d_tag)
b34976b6 11460 {
019148e4
L
11461 case DT_AUXILIARY:
11462 printf (_("Auxiliary library"));
11463 break;
11464
11465 case DT_FILTER:
11466 printf (_("Filter library"));
11467 break;
11468
b34976b6 11469 case DT_CONFIG:
019148e4
L
11470 printf (_("Configuration file"));
11471 break;
11472
11473 case DT_DEPAUDIT:
11474 printf (_("Dependency audit library"));
11475 break;
11476
11477 case DT_AUDIT:
11478 printf (_("Audit library"));
11479 break;
11480 }
252b5132 11481
84714f86 11482 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11483 printf (": [%s]\n",
84714f86 11484 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11485 else
f7a99963
NC
11486 {
11487 printf (": ");
11488 print_vma (entry->d_un.d_val, PREFIX_HEX);
11489 putchar ('\n');
11490 }
252b5132
RH
11491 }
11492 break;
11493
dcefbbbd 11494 case DT_FEATURE:
252b5132
RH
11495 if (do_dynamic)
11496 {
11497 printf (_("Flags:"));
86f55779 11498
252b5132
RH
11499 if (entry->d_un.d_val == 0)
11500 printf (_(" None\n"));
11501 else
11502 {
11503 unsigned long int val = entry->d_un.d_val;
86f55779 11504
252b5132
RH
11505 if (val & DTF_1_PARINIT)
11506 {
11507 printf (" PARINIT");
11508 val ^= DTF_1_PARINIT;
11509 }
dcefbbbd
L
11510 if (val & DTF_1_CONFEXP)
11511 {
11512 printf (" CONFEXP");
11513 val ^= DTF_1_CONFEXP;
11514 }
252b5132
RH
11515 if (val != 0)
11516 printf (" %lx", val);
11517 puts ("");
11518 }
11519 }
11520 break;
11521
11522 case DT_POSFLAG_1:
11523 if (do_dynamic)
11524 {
11525 printf (_("Flags:"));
86f55779 11526
252b5132
RH
11527 if (entry->d_un.d_val == 0)
11528 printf (_(" None\n"));
11529 else
11530 {
11531 unsigned long int val = entry->d_un.d_val;
86f55779 11532
252b5132
RH
11533 if (val & DF_P1_LAZYLOAD)
11534 {
11535 printf (" LAZYLOAD");
11536 val ^= DF_P1_LAZYLOAD;
11537 }
11538 if (val & DF_P1_GROUPPERM)
11539 {
11540 printf (" GROUPPERM");
11541 val ^= DF_P1_GROUPPERM;
11542 }
11543 if (val != 0)
11544 printf (" %lx", val);
11545 puts ("");
11546 }
11547 }
11548 break;
11549
11550 case DT_FLAGS_1:
11551 if (do_dynamic)
11552 {
11553 printf (_("Flags:"));
11554 if (entry->d_un.d_val == 0)
11555 printf (_(" None\n"));
11556 else
11557 {
11558 unsigned long int val = entry->d_un.d_val;
86f55779 11559
252b5132
RH
11560 if (val & DF_1_NOW)
11561 {
11562 printf (" NOW");
11563 val ^= DF_1_NOW;
11564 }
11565 if (val & DF_1_GLOBAL)
11566 {
11567 printf (" GLOBAL");
11568 val ^= DF_1_GLOBAL;
11569 }
11570 if (val & DF_1_GROUP)
11571 {
11572 printf (" GROUP");
11573 val ^= DF_1_GROUP;
11574 }
11575 if (val & DF_1_NODELETE)
11576 {
11577 printf (" NODELETE");
11578 val ^= DF_1_NODELETE;
11579 }
11580 if (val & DF_1_LOADFLTR)
11581 {
11582 printf (" LOADFLTR");
11583 val ^= DF_1_LOADFLTR;
11584 }
11585 if (val & DF_1_INITFIRST)
11586 {
11587 printf (" INITFIRST");
11588 val ^= DF_1_INITFIRST;
11589 }
11590 if (val & DF_1_NOOPEN)
11591 {
11592 printf (" NOOPEN");
11593 val ^= DF_1_NOOPEN;
11594 }
11595 if (val & DF_1_ORIGIN)
11596 {
11597 printf (" ORIGIN");
11598 val ^= DF_1_ORIGIN;
11599 }
11600 if (val & DF_1_DIRECT)
11601 {
11602 printf (" DIRECT");
11603 val ^= DF_1_DIRECT;
11604 }
11605 if (val & DF_1_TRANS)
11606 {
11607 printf (" TRANS");
11608 val ^= DF_1_TRANS;
11609 }
11610 if (val & DF_1_INTERPOSE)
11611 {
11612 printf (" INTERPOSE");
11613 val ^= DF_1_INTERPOSE;
11614 }
f7db6139 11615 if (val & DF_1_NODEFLIB)
dcefbbbd 11616 {
f7db6139
L
11617 printf (" NODEFLIB");
11618 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11619 }
11620 if (val & DF_1_NODUMP)
11621 {
11622 printf (" NODUMP");
11623 val ^= DF_1_NODUMP;
11624 }
34b60028 11625 if (val & DF_1_CONFALT)
dcefbbbd 11626 {
34b60028
L
11627 printf (" CONFALT");
11628 val ^= DF_1_CONFALT;
11629 }
11630 if (val & DF_1_ENDFILTEE)
11631 {
11632 printf (" ENDFILTEE");
11633 val ^= DF_1_ENDFILTEE;
11634 }
11635 if (val & DF_1_DISPRELDNE)
11636 {
11637 printf (" DISPRELDNE");
11638 val ^= DF_1_DISPRELDNE;
11639 }
11640 if (val & DF_1_DISPRELPND)
11641 {
11642 printf (" DISPRELPND");
11643 val ^= DF_1_DISPRELPND;
11644 }
11645 if (val & DF_1_NODIRECT)
11646 {
11647 printf (" NODIRECT");
11648 val ^= DF_1_NODIRECT;
11649 }
11650 if (val & DF_1_IGNMULDEF)
11651 {
11652 printf (" IGNMULDEF");
11653 val ^= DF_1_IGNMULDEF;
11654 }
11655 if (val & DF_1_NOKSYMS)
11656 {
11657 printf (" NOKSYMS");
11658 val ^= DF_1_NOKSYMS;
11659 }
11660 if (val & DF_1_NOHDR)
11661 {
11662 printf (" NOHDR");
11663 val ^= DF_1_NOHDR;
11664 }
11665 if (val & DF_1_EDITED)
11666 {
11667 printf (" EDITED");
11668 val ^= DF_1_EDITED;
11669 }
11670 if (val & DF_1_NORELOC)
11671 {
11672 printf (" NORELOC");
11673 val ^= DF_1_NORELOC;
11674 }
11675 if (val & DF_1_SYMINTPOSE)
11676 {
11677 printf (" SYMINTPOSE");
11678 val ^= DF_1_SYMINTPOSE;
11679 }
11680 if (val & DF_1_GLOBAUDIT)
11681 {
11682 printf (" GLOBAUDIT");
11683 val ^= DF_1_GLOBAUDIT;
11684 }
11685 if (val & DF_1_SINGLETON)
11686 {
11687 printf (" SINGLETON");
11688 val ^= DF_1_SINGLETON;
dcefbbbd 11689 }
5c383f02
RO
11690 if (val & DF_1_STUB)
11691 {
11692 printf (" STUB");
11693 val ^= DF_1_STUB;
11694 }
11695 if (val & DF_1_PIE)
11696 {
11697 printf (" PIE");
11698 val ^= DF_1_PIE;
11699 }
b1202ffa
L
11700 if (val & DF_1_KMOD)
11701 {
11702 printf (" KMOD");
11703 val ^= DF_1_KMOD;
11704 }
11705 if (val & DF_1_WEAKFILTER)
11706 {
11707 printf (" WEAKFILTER");
11708 val ^= DF_1_WEAKFILTER;
11709 }
11710 if (val & DF_1_NOCOMMON)
11711 {
11712 printf (" NOCOMMON");
11713 val ^= DF_1_NOCOMMON;
11714 }
252b5132
RH
11715 if (val != 0)
11716 printf (" %lx", val);
11717 puts ("");
11718 }
11719 }
11720 break;
11721
11722 case DT_PLTREL:
978c4450 11723 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11724 if (do_dynamic)
dda8d76d 11725 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11726 break;
11727
11728 case DT_NULL :
11729 case DT_NEEDED :
11730 case DT_PLTGOT :
11731 case DT_HASH :
11732 case DT_STRTAB :
11733 case DT_SYMTAB :
11734 case DT_RELA :
11735 case DT_INIT :
11736 case DT_FINI :
11737 case DT_SONAME :
11738 case DT_RPATH :
11739 case DT_SYMBOLIC:
11740 case DT_REL :
a7fd1186 11741 case DT_RELR :
252b5132
RH
11742 case DT_DEBUG :
11743 case DT_TEXTREL :
11744 case DT_JMPREL :
019148e4 11745 case DT_RUNPATH :
978c4450 11746 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11747
11748 if (do_dynamic)
11749 {
84714f86 11750 const char *name;
252b5132 11751
84714f86
AM
11752 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11753 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11754 else
d79b3d50 11755 name = NULL;
252b5132
RH
11756
11757 if (name)
11758 {
11759 switch (entry->d_tag)
11760 {
11761 case DT_NEEDED:
11762 printf (_("Shared library: [%s]"), name);
11763
13acb58d
AM
11764 if (filedata->program_interpreter
11765 && streq (name, filedata->program_interpreter))
f7a99963 11766 printf (_(" program interpreter"));
252b5132
RH
11767 break;
11768
11769 case DT_SONAME:
f7a99963 11770 printf (_("Library soname: [%s]"), name);
252b5132
RH
11771 break;
11772
11773 case DT_RPATH:
f7a99963 11774 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11775 break;
11776
019148e4
L
11777 case DT_RUNPATH:
11778 printf (_("Library runpath: [%s]"), name);
11779 break;
11780
252b5132 11781 default:
f7a99963
NC
11782 print_vma (entry->d_un.d_val, PREFIX_HEX);
11783 break;
252b5132
RH
11784 }
11785 }
11786 else
f7a99963
NC
11787 print_vma (entry->d_un.d_val, PREFIX_HEX);
11788
11789 putchar ('\n');
252b5132
RH
11790 }
11791 break;
11792
11793 case DT_PLTRELSZ:
11794 case DT_RELASZ :
11795 case DT_STRSZ :
11796 case DT_RELSZ :
11797 case DT_RELAENT :
a7fd1186
FS
11798 case DT_RELRENT :
11799 case DT_RELRSZ :
252b5132
RH
11800 case DT_SYMENT :
11801 case DT_RELENT :
978c4450 11802 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11803 /* Fall through. */
252b5132
RH
11804 case DT_PLTPADSZ:
11805 case DT_MOVEENT :
11806 case DT_MOVESZ :
04d8355a 11807 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11808 case DT_INIT_ARRAYSZ:
11809 case DT_FINI_ARRAYSZ:
047b2264
JJ
11810 case DT_GNU_CONFLICTSZ:
11811 case DT_GNU_LIBLISTSZ:
252b5132 11812 if (do_dynamic)
f7a99963
NC
11813 {
11814 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11815 printf (_(" (bytes)\n"));
f7a99963 11816 }
252b5132
RH
11817 break;
11818
11819 case DT_VERDEFNUM:
11820 case DT_VERNEEDNUM:
11821 case DT_RELACOUNT:
11822 case DT_RELCOUNT:
11823 if (do_dynamic)
f7a99963
NC
11824 {
11825 print_vma (entry->d_un.d_val, UNSIGNED);
11826 putchar ('\n');
11827 }
252b5132
RH
11828 break;
11829
11830 case DT_SYMINSZ:
11831 case DT_SYMINENT:
11832 case DT_SYMINFO:
11833 case DT_USED:
11834 case DT_INIT_ARRAY:
11835 case DT_FINI_ARRAY:
11836 if (do_dynamic)
11837 {
d79b3d50 11838 if (entry->d_tag == DT_USED
84714f86 11839 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11840 {
84714f86
AM
11841 const char *name
11842 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11843
b34976b6 11844 if (*name)
252b5132
RH
11845 {
11846 printf (_("Not needed object: [%s]\n"), name);
11847 break;
11848 }
11849 }
103f02d3 11850
f7a99963
NC
11851 print_vma (entry->d_un.d_val, PREFIX_HEX);
11852 putchar ('\n');
252b5132
RH
11853 }
11854 break;
11855
11856 case DT_BIND_NOW:
11857 /* The value of this entry is ignored. */
35b1837e
AM
11858 if (do_dynamic)
11859 putchar ('\n');
252b5132 11860 break;
103f02d3 11861
047b2264
JJ
11862 case DT_GNU_PRELINKED:
11863 if (do_dynamic)
11864 {
2cf0635d 11865 struct tm * tmp;
91d6fa6a 11866 time_t atime = entry->d_un.d_val;
047b2264 11867
91d6fa6a 11868 tmp = gmtime (&atime);
071436c6
NC
11869 /* PR 17533 file: 041-1244816-0.004. */
11870 if (tmp == NULL)
5a2cbcf4
L
11871 printf (_("<corrupt time val: %lx"),
11872 (unsigned long) atime);
071436c6
NC
11873 else
11874 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11875 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11876 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11877
11878 }
11879 break;
11880
fdc90cb4 11881 case DT_GNU_HASH:
978c4450 11882 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11883 if (do_dynamic)
11884 {
11885 print_vma (entry->d_un.d_val, PREFIX_HEX);
11886 putchar ('\n');
11887 }
11888 break;
11889
a5da3dee
VDM
11890 case DT_GNU_FLAGS_1:
11891 if (do_dynamic)
11892 {
11893 printf (_("Flags:"));
11894 if (entry->d_un.d_val == 0)
11895 printf (_(" None\n"));
11896 else
11897 {
11898 unsigned long int val = entry->d_un.d_val;
11899
11900 if (val & DF_GNU_1_UNIQUE)
11901 {
11902 printf (" UNIQUE");
11903 val ^= DF_GNU_1_UNIQUE;
11904 }
11905 if (val != 0)
11906 printf (" %lx", val);
11907 puts ("");
11908 }
11909 }
11910 break;
11911
252b5132
RH
11912 default:
11913 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11914 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11915 = entry->d_un.d_val;
252b5132
RH
11916
11917 if (do_dynamic)
11918 {
dda8d76d 11919 switch (filedata->file_header.e_machine)
252b5132 11920 {
37c18eed
SD
11921 case EM_AARCH64:
11922 dynamic_section_aarch64_val (entry);
11923 break;
252b5132 11924 case EM_MIPS:
4fe85591 11925 case EM_MIPS_RS3_LE:
978c4450 11926 dynamic_section_mips_val (filedata, entry);
252b5132 11927 break;
103f02d3 11928 case EM_PARISC:
b2d38a17 11929 dynamic_section_parisc_val (entry);
103f02d3 11930 break;
ecc51f48 11931 case EM_IA_64:
b2d38a17 11932 dynamic_section_ia64_val (entry);
ecc51f48 11933 break;
252b5132 11934 default:
f7a99963
NC
11935 print_vma (entry->d_un.d_val, PREFIX_HEX);
11936 putchar ('\n');
252b5132
RH
11937 }
11938 }
11939 break;
11940 }
11941 }
11942
015dc7e1 11943 return true;
252b5132
RH
11944}
11945
11946static char *
d3ba0551 11947get_ver_flags (unsigned int flags)
252b5132 11948{
6d4f21f6 11949 static char buff[128];
252b5132
RH
11950
11951 buff[0] = 0;
11952
11953 if (flags == 0)
11954 return _("none");
11955
11956 if (flags & VER_FLG_BASE)
7bb1ad17 11957 strcat (buff, "BASE");
252b5132
RH
11958
11959 if (flags & VER_FLG_WEAK)
11960 {
11961 if (flags & VER_FLG_BASE)
7bb1ad17 11962 strcat (buff, " | ");
252b5132 11963
7bb1ad17 11964 strcat (buff, "WEAK");
252b5132
RH
11965 }
11966
44ec90b9
RO
11967 if (flags & VER_FLG_INFO)
11968 {
11969 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11970 strcat (buff, " | ");
44ec90b9 11971
7bb1ad17 11972 strcat (buff, "INFO");
44ec90b9
RO
11973 }
11974
11975 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11976 {
11977 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11978 strcat (buff, " | ");
11979
11980 strcat (buff, _("<unknown>"));
11981 }
252b5132
RH
11982
11983 return buff;
11984}
11985
11986/* Display the contents of the version sections. */
98fb390a 11987
015dc7e1 11988static bool
dda8d76d 11989process_version_sections (Filedata * filedata)
252b5132 11990{
2cf0635d 11991 Elf_Internal_Shdr * section;
b34976b6 11992 unsigned i;
015dc7e1 11993 bool found = false;
252b5132
RH
11994
11995 if (! do_version)
015dc7e1 11996 return true;
252b5132 11997
dda8d76d
NC
11998 for (i = 0, section = filedata->section_headers;
11999 i < filedata->file_header.e_shnum;
b34976b6 12000 i++, section++)
252b5132
RH
12001 {
12002 switch (section->sh_type)
12003 {
12004 case SHT_GNU_verdef:
12005 {
2cf0635d 12006 Elf_External_Verdef * edefs;
452bf675
AM
12007 unsigned long idx;
12008 unsigned long cnt;
2cf0635d 12009 char * endbuf;
252b5132 12010
015dc7e1 12011 found = true;
252b5132 12012
ca0e11aa
NC
12013 if (filedata->is_separate)
12014 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12015 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12016 section->sh_info),
12017 filedata->file_name,
12018 printable_section_name (filedata, section),
12019 section->sh_info);
12020 else
12021 printf (ngettext ("\nVersion definition section '%s' "
12022 "contains %u entry:\n",
12023 "\nVersion definition section '%s' "
12024 "contains %u entries:\n",
12025 section->sh_info),
12026 printable_section_name (filedata, section),
12027 section->sh_info);
047c3dbf 12028
625d49fc 12029 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
233f82cf 12030 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12031 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12032 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12033
3f5e193b 12034 edefs = (Elf_External_Verdef *)
dda8d76d 12035 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12036 _("version definition section"));
a6e9f9df
AM
12037 if (!edefs)
12038 break;
59245841 12039 endbuf = (char *) edefs + section->sh_size;
252b5132 12040
1445030f 12041 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12042 {
2cf0635d
NC
12043 char * vstart;
12044 Elf_External_Verdef * edef;
b34976b6 12045 Elf_Internal_Verdef ent;
2cf0635d 12046 Elf_External_Verdaux * eaux;
b34976b6 12047 Elf_Internal_Verdaux aux;
452bf675 12048 unsigned long isum;
b34976b6 12049 int j;
103f02d3 12050
252b5132 12051 vstart = ((char *) edefs) + idx;
54806181
AM
12052 if (vstart + sizeof (*edef) > endbuf)
12053 break;
252b5132
RH
12054
12055 edef = (Elf_External_Verdef *) vstart;
12056
12057 ent.vd_version = BYTE_GET (edef->vd_version);
12058 ent.vd_flags = BYTE_GET (edef->vd_flags);
12059 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12060 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12061 ent.vd_hash = BYTE_GET (edef->vd_hash);
12062 ent.vd_aux = BYTE_GET (edef->vd_aux);
12063 ent.vd_next = BYTE_GET (edef->vd_next);
12064
452bf675 12065 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
12066 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12067
12068 printf (_(" Index: %d Cnt: %d "),
12069 ent.vd_ndx, ent.vd_cnt);
12070
452bf675 12071 /* Check for overflow. */
1445030f 12072 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12073 break;
12074
252b5132
RH
12075 vstart += ent.vd_aux;
12076
1445030f
AM
12077 if (vstart + sizeof (*eaux) > endbuf)
12078 break;
252b5132
RH
12079 eaux = (Elf_External_Verdaux *) vstart;
12080
12081 aux.vda_name = BYTE_GET (eaux->vda_name);
12082 aux.vda_next = BYTE_GET (eaux->vda_next);
12083
84714f86 12084 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12085 printf (_("Name: %s\n"),
84714f86 12086 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12087 else
12088 printf (_("Name index: %ld\n"), aux.vda_name);
12089
12090 isum = idx + ent.vd_aux;
12091
b34976b6 12092 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12093 {
1445030f
AM
12094 if (aux.vda_next < sizeof (*eaux)
12095 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12096 {
12097 warn (_("Invalid vda_next field of %lx\n"),
12098 aux.vda_next);
12099 j = ent.vd_cnt;
12100 break;
12101 }
dd24e3da 12102 /* Check for overflow. */
7e26601c 12103 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12104 break;
12105
252b5132
RH
12106 isum += aux.vda_next;
12107 vstart += aux.vda_next;
12108
54806181
AM
12109 if (vstart + sizeof (*eaux) > endbuf)
12110 break;
1445030f 12111 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12112
12113 aux.vda_name = BYTE_GET (eaux->vda_name);
12114 aux.vda_next = BYTE_GET (eaux->vda_next);
12115
84714f86 12116 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12117 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12118 isum, j,
84714f86 12119 get_dynamic_name (filedata, aux.vda_name));
252b5132 12120 else
452bf675 12121 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12122 isum, j, aux.vda_name);
12123 }
dd24e3da 12124
54806181
AM
12125 if (j < ent.vd_cnt)
12126 printf (_(" Version def aux past end of section\n"));
252b5132 12127
c9f02c3e
MR
12128 /* PR 17531:
12129 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12130 if (ent.vd_next < sizeof (*edef)
12131 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12132 {
12133 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12134 cnt = section->sh_info;
12135 break;
12136 }
452bf675 12137 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12138 break;
12139
252b5132
RH
12140 idx += ent.vd_next;
12141 }
dd24e3da 12142
54806181
AM
12143 if (cnt < section->sh_info)
12144 printf (_(" Version definition past end of section\n"));
252b5132
RH
12145
12146 free (edefs);
12147 }
12148 break;
103f02d3 12149
252b5132
RH
12150 case SHT_GNU_verneed:
12151 {
2cf0635d 12152 Elf_External_Verneed * eneed;
452bf675
AM
12153 unsigned long idx;
12154 unsigned long cnt;
2cf0635d 12155 char * endbuf;
252b5132 12156
015dc7e1 12157 found = true;
252b5132 12158
ca0e11aa
NC
12159 if (filedata->is_separate)
12160 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12161 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12162 section->sh_info),
12163 filedata->file_name,
12164 printable_section_name (filedata, section),
12165 section->sh_info);
12166 else
12167 printf (ngettext ("\nVersion needs section '%s' "
12168 "contains %u entry:\n",
12169 "\nVersion needs section '%s' "
12170 "contains %u entries:\n",
12171 section->sh_info),
12172 printable_section_name (filedata, section),
12173 section->sh_info);
047c3dbf 12174
625d49fc 12175 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12176 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12177 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12178 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12179
dda8d76d 12180 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12181 section->sh_offset, 1,
12182 section->sh_size,
9cf03b7e 12183 _("Version Needs section"));
a6e9f9df
AM
12184 if (!eneed)
12185 break;
59245841 12186 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12187
12188 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12189 {
2cf0635d 12190 Elf_External_Verneed * entry;
b34976b6 12191 Elf_Internal_Verneed ent;
452bf675 12192 unsigned long isum;
b34976b6 12193 int j;
2cf0635d 12194 char * vstart;
252b5132
RH
12195
12196 vstart = ((char *) eneed) + idx;
54806181
AM
12197 if (vstart + sizeof (*entry) > endbuf)
12198 break;
252b5132
RH
12199
12200 entry = (Elf_External_Verneed *) vstart;
12201
12202 ent.vn_version = BYTE_GET (entry->vn_version);
12203 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12204 ent.vn_file = BYTE_GET (entry->vn_file);
12205 ent.vn_aux = BYTE_GET (entry->vn_aux);
12206 ent.vn_next = BYTE_GET (entry->vn_next);
12207
452bf675 12208 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12209
84714f86 12210 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12211 printf (_(" File: %s"),
84714f86 12212 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12213 else
12214 printf (_(" File: %lx"), ent.vn_file);
12215
12216 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12217
dd24e3da 12218 /* Check for overflow. */
7e26601c 12219 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12220 break;
252b5132
RH
12221 vstart += ent.vn_aux;
12222
12223 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12224 {
2cf0635d 12225 Elf_External_Vernaux * eaux;
b34976b6 12226 Elf_Internal_Vernaux aux;
252b5132 12227
54806181
AM
12228 if (vstart + sizeof (*eaux) > endbuf)
12229 break;
252b5132
RH
12230 eaux = (Elf_External_Vernaux *) vstart;
12231
12232 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12233 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12234 aux.vna_other = BYTE_GET (eaux->vna_other);
12235 aux.vna_name = BYTE_GET (eaux->vna_name);
12236 aux.vna_next = BYTE_GET (eaux->vna_next);
12237
84714f86 12238 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12239 printf (_(" %#06lx: Name: %s"),
84714f86 12240 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12241 else
452bf675 12242 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12243 isum, aux.vna_name);
12244
12245 printf (_(" Flags: %s Version: %d\n"),
12246 get_ver_flags (aux.vna_flags), aux.vna_other);
12247
1445030f
AM
12248 if (aux.vna_next < sizeof (*eaux)
12249 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12250 {
12251 warn (_("Invalid vna_next field of %lx\n"),
12252 aux.vna_next);
12253 j = ent.vn_cnt;
12254 break;
12255 }
1445030f
AM
12256 /* Check for overflow. */
12257 if (aux.vna_next > (size_t) (endbuf - vstart))
12258 break;
252b5132
RH
12259 isum += aux.vna_next;
12260 vstart += aux.vna_next;
12261 }
9cf03b7e 12262
54806181 12263 if (j < ent.vn_cnt)
f9a6a8f0 12264 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12265
1445030f
AM
12266 if (ent.vn_next < sizeof (*entry)
12267 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12268 {
452bf675 12269 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12270 cnt = section->sh_info;
12271 break;
12272 }
1445030f
AM
12273 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12274 break;
252b5132
RH
12275 idx += ent.vn_next;
12276 }
9cf03b7e 12277
54806181 12278 if (cnt < section->sh_info)
9cf03b7e 12279 warn (_("Missing Version Needs information\n"));
103f02d3 12280
252b5132
RH
12281 free (eneed);
12282 }
12283 break;
12284
12285 case SHT_GNU_versym:
12286 {
2cf0635d 12287 Elf_Internal_Shdr * link_section;
8b73c356
NC
12288 size_t total;
12289 unsigned int cnt;
2cf0635d
NC
12290 unsigned char * edata;
12291 unsigned short * data;
12292 char * strtab;
12293 Elf_Internal_Sym * symbols;
12294 Elf_Internal_Shdr * string_sec;
ba5cdace 12295 unsigned long num_syms;
d3ba0551 12296 long off;
252b5132 12297
dda8d76d 12298 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12299 break;
12300
dda8d76d 12301 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12302 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12303
dda8d76d 12304 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12305 break;
12306
015dc7e1 12307 found = true;
252b5132 12308
4de91c10 12309 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12310 if (symbols == NULL)
12311 break;
252b5132 12312
dda8d76d 12313 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12314
dda8d76d 12315 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12316 string_sec->sh_size,
12317 _("version string table"));
a6e9f9df 12318 if (!strtab)
0429c154
MS
12319 {
12320 free (symbols);
12321 break;
12322 }
252b5132 12323
ca0e11aa
NC
12324 if (filedata->is_separate)
12325 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12326 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12327 total),
12328 filedata->file_name,
12329 printable_section_name (filedata, section),
12330 (unsigned long) total);
12331 else
12332 printf (ngettext ("\nVersion symbols section '%s' "
12333 "contains %lu entry:\n",
12334 "\nVersion symbols section '%s' "
12335 "contains %lu entries:\n",
12336 total),
12337 printable_section_name (filedata, section),
12338 (unsigned long) total);
252b5132 12339
625d49fc 12340 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
72de5009 12341 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12342 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12343 printable_section_name (filedata, link_section));
252b5132 12344
dda8d76d 12345 off = offset_from_vma (filedata,
978c4450 12346 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12347 total * sizeof (short));
95099889
AM
12348 edata = (unsigned char *) get_data (NULL, filedata, off,
12349 sizeof (short), total,
12350 _("version symbol data"));
a6e9f9df
AM
12351 if (!edata)
12352 {
12353 free (strtab);
0429c154 12354 free (symbols);
a6e9f9df
AM
12355 break;
12356 }
252b5132 12357
3f5e193b 12358 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12359
12360 for (cnt = total; cnt --;)
b34976b6
AM
12361 data[cnt] = byte_get (edata + cnt * sizeof (short),
12362 sizeof (short));
252b5132
RH
12363
12364 free (edata);
12365
12366 for (cnt = 0; cnt < total; cnt += 4)
12367 {
12368 int j, nn;
ab273396
AM
12369 char *name;
12370 char *invalid = _("*invalid*");
252b5132
RH
12371
12372 printf (" %03x:", cnt);
12373
12374 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12375 switch (data[cnt + j])
252b5132
RH
12376 {
12377 case 0:
12378 fputs (_(" 0 (*local*) "), stdout);
12379 break;
12380
12381 case 1:
12382 fputs (_(" 1 (*global*) "), stdout);
12383 break;
12384
12385 default:
c244d050
NC
12386 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12387 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12388
dd24e3da 12389 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12390 array, break to avoid an out-of-bounds read. */
12391 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12392 {
12393 warn (_("invalid index into symbol array\n"));
12394 break;
12395 }
12396
ab273396 12397 name = NULL;
978c4450 12398 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12399 {
b34976b6
AM
12400 Elf_Internal_Verneed ivn;
12401 unsigned long offset;
252b5132 12402
d93f0186 12403 offset = offset_from_vma
978c4450
AM
12404 (filedata,
12405 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12406 sizeof (Elf_External_Verneed));
252b5132 12407
b34976b6 12408 do
252b5132 12409 {
b34976b6
AM
12410 Elf_Internal_Vernaux ivna;
12411 Elf_External_Verneed evn;
12412 Elf_External_Vernaux evna;
12413 unsigned long a_off;
252b5132 12414
dda8d76d 12415 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12416 _("version need")) == NULL)
12417 break;
0b4362b0 12418
252b5132
RH
12419 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12420 ivn.vn_next = BYTE_GET (evn.vn_next);
12421
12422 a_off = offset + ivn.vn_aux;
12423
12424 do
12425 {
dda8d76d 12426 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12427 1, _("version need aux (2)")) == NULL)
12428 {
12429 ivna.vna_next = 0;
12430 ivna.vna_other = 0;
12431 }
12432 else
12433 {
12434 ivna.vna_next = BYTE_GET (evna.vna_next);
12435 ivna.vna_other = BYTE_GET (evna.vna_other);
12436 }
252b5132
RH
12437
12438 a_off += ivna.vna_next;
12439 }
b34976b6 12440 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12441 && ivna.vna_next != 0);
12442
b34976b6 12443 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12444 {
12445 ivna.vna_name = BYTE_GET (evna.vna_name);
12446
54806181 12447 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12448 name = invalid;
54806181
AM
12449 else
12450 name = strtab + ivna.vna_name;
252b5132
RH
12451 break;
12452 }
12453
12454 offset += ivn.vn_next;
12455 }
12456 while (ivn.vn_next);
12457 }
00d93f34 12458
ab273396 12459 if (data[cnt + j] != 0x8001
978c4450 12460 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12461 {
b34976b6
AM
12462 Elf_Internal_Verdef ivd;
12463 Elf_External_Verdef evd;
12464 unsigned long offset;
252b5132 12465
d93f0186 12466 offset = offset_from_vma
978c4450
AM
12467 (filedata,
12468 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12469 sizeof evd);
252b5132
RH
12470
12471 do
12472 {
dda8d76d 12473 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12474 _("version def")) == NULL)
12475 {
12476 ivd.vd_next = 0;
948f632f 12477 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12478 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12479 break;
59245841
NC
12480 }
12481 else
12482 {
12483 ivd.vd_next = BYTE_GET (evd.vd_next);
12484 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12485 }
252b5132
RH
12486
12487 offset += ivd.vd_next;
12488 }
c244d050 12489 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12490 && ivd.vd_next != 0);
12491
c244d050 12492 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12493 {
b34976b6
AM
12494 Elf_External_Verdaux evda;
12495 Elf_Internal_Verdaux ivda;
252b5132
RH
12496
12497 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12498
dda8d76d 12499 if (get_data (&evda, filedata,
59245841
NC
12500 offset - ivd.vd_next + ivd.vd_aux,
12501 sizeof (evda), 1,
12502 _("version def aux")) == NULL)
12503 break;
252b5132
RH
12504
12505 ivda.vda_name = BYTE_GET (evda.vda_name);
12506
54806181 12507 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12508 name = invalid;
12509 else if (name != NULL && name != invalid)
12510 name = _("*both*");
54806181
AM
12511 else
12512 name = strtab + ivda.vda_name;
252b5132
RH
12513 }
12514 }
ab273396
AM
12515 if (name != NULL)
12516 nn += printf ("(%s%-*s",
12517 name,
12518 12 - (int) strlen (name),
12519 ")");
252b5132
RH
12520
12521 if (nn < 18)
12522 printf ("%*c", 18 - nn, ' ');
12523 }
12524
12525 putchar ('\n');
12526 }
12527
12528 free (data);
12529 free (strtab);
12530 free (symbols);
12531 }
12532 break;
103f02d3 12533
252b5132
RH
12534 default:
12535 break;
12536 }
12537 }
12538
12539 if (! found)
ca0e11aa
NC
12540 {
12541 if (filedata->is_separate)
12542 printf (_("\nNo version information found in linked file '%s'.\n"),
12543 filedata->file_name);
12544 else
12545 printf (_("\nNo version information found in this file.\n"));
12546 }
252b5132 12547
015dc7e1 12548 return true;
252b5132
RH
12549}
12550
d1133906 12551static const char *
dda8d76d 12552get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12553{
89246a0e 12554 static char buff[64];
252b5132
RH
12555
12556 switch (binding)
12557 {
b34976b6
AM
12558 case STB_LOCAL: return "LOCAL";
12559 case STB_GLOBAL: return "GLOBAL";
12560 case STB_WEAK: return "WEAK";
252b5132
RH
12561 default:
12562 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12563 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12564 binding);
252b5132 12565 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12566 {
12567 if (binding == STB_GNU_UNIQUE
df3a023b 12568 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12569 return "UNIQUE";
12570 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12571 }
252b5132 12572 else
e9e44622 12573 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12574 return buff;
12575 }
12576}
12577
d1133906 12578static const char *
dda8d76d 12579get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12580{
89246a0e 12581 static char buff[64];
252b5132
RH
12582
12583 switch (type)
12584 {
b34976b6
AM
12585 case STT_NOTYPE: return "NOTYPE";
12586 case STT_OBJECT: return "OBJECT";
12587 case STT_FUNC: return "FUNC";
12588 case STT_SECTION: return "SECTION";
12589 case STT_FILE: return "FILE";
12590 case STT_COMMON: return "COMMON";
12591 case STT_TLS: return "TLS";
15ab5209
DB
12592 case STT_RELC: return "RELC";
12593 case STT_SRELC: return "SRELC";
252b5132
RH
12594 default:
12595 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12596 {
dda8d76d 12597 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12598 return "THUMB_FUNC";
103f02d3 12599
dda8d76d 12600 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12601 return "REGISTER";
12602
dda8d76d 12603 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12604 return "PARISC_MILLI";
12605
e9e44622 12606 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12607 }
252b5132 12608 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12609 {
dda8d76d 12610 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12611 {
12612 if (type == STT_HP_OPAQUE)
12613 return "HP_OPAQUE";
12614 if (type == STT_HP_STUB)
12615 return "HP_STUB";
12616 }
12617
d8045f23 12618 if (type == STT_GNU_IFUNC
dda8d76d 12619 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12620 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12621 return "IFUNC";
12622
e9e44622 12623 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12624 }
252b5132 12625 else
e9e44622 12626 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12627 return buff;
12628 }
12629}
12630
d1133906 12631static const char *
d3ba0551 12632get_symbol_visibility (unsigned int visibility)
d1133906
NC
12633{
12634 switch (visibility)
12635 {
b34976b6
AM
12636 case STV_DEFAULT: return "DEFAULT";
12637 case STV_INTERNAL: return "INTERNAL";
12638 case STV_HIDDEN: return "HIDDEN";
d1133906 12639 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12640 default:
27a45f42 12641 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12642 return _("<unknown>");
d1133906
NC
12643 }
12644}
12645
2057d69d
CZ
12646static const char *
12647get_alpha_symbol_other (unsigned int other)
9abca702 12648{
2057d69d
CZ
12649 switch (other)
12650 {
12651 case STO_ALPHA_NOPV: return "NOPV";
12652 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12653 default:
27a45f42 12654 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12655 return _("<unknown>");
9abca702 12656 }
2057d69d
CZ
12657}
12658
fd85a6a1
NC
12659static const char *
12660get_solaris_symbol_visibility (unsigned int visibility)
12661{
12662 switch (visibility)
12663 {
12664 case 4: return "EXPORTED";
12665 case 5: return "SINGLETON";
12666 case 6: return "ELIMINATE";
12667 default: return get_symbol_visibility (visibility);
12668 }
12669}
12670
2301ed1c
SN
12671static const char *
12672get_aarch64_symbol_other (unsigned int other)
12673{
12674 static char buf[32];
12675
12676 if (other & STO_AARCH64_VARIANT_PCS)
12677 {
12678 other &= ~STO_AARCH64_VARIANT_PCS;
12679 if (other == 0)
12680 return "VARIANT_PCS";
12681 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12682 return buf;
12683 }
12684 return NULL;
12685}
12686
5e2b0d47
NC
12687static const char *
12688get_mips_symbol_other (unsigned int other)
12689{
12690 switch (other)
12691 {
32ec8896
NC
12692 case STO_OPTIONAL: return "OPTIONAL";
12693 case STO_MIPS_PLT: return "MIPS PLT";
12694 case STO_MIPS_PIC: return "MIPS PIC";
12695 case STO_MICROMIPS: return "MICROMIPS";
12696 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12697 case STO_MIPS16: return "MIPS16";
12698 default: return NULL;
5e2b0d47
NC
12699 }
12700}
12701
28f997cf 12702static const char *
dda8d76d 12703get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12704{
dda8d76d 12705 if (is_ia64_vms (filedata))
28f997cf
TG
12706 {
12707 static char res[32];
12708
12709 res[0] = 0;
12710
12711 /* Function types is for images and .STB files only. */
dda8d76d 12712 switch (filedata->file_header.e_type)
28f997cf
TG
12713 {
12714 case ET_DYN:
12715 case ET_EXEC:
12716 switch (VMS_ST_FUNC_TYPE (other))
12717 {
12718 case VMS_SFT_CODE_ADDR:
12719 strcat (res, " CA");
12720 break;
12721 case VMS_SFT_SYMV_IDX:
12722 strcat (res, " VEC");
12723 break;
12724 case VMS_SFT_FD:
12725 strcat (res, " FD");
12726 break;
12727 case VMS_SFT_RESERVE:
12728 strcat (res, " RSV");
12729 break;
12730 default:
bee0ee85
NC
12731 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12732 VMS_ST_FUNC_TYPE (other));
12733 strcat (res, " <unknown>");
12734 break;
28f997cf
TG
12735 }
12736 break;
12737 default:
12738 break;
12739 }
12740 switch (VMS_ST_LINKAGE (other))
12741 {
12742 case VMS_STL_IGNORE:
12743 strcat (res, " IGN");
12744 break;
12745 case VMS_STL_RESERVE:
12746 strcat (res, " RSV");
12747 break;
12748 case VMS_STL_STD:
12749 strcat (res, " STD");
12750 break;
12751 case VMS_STL_LNK:
12752 strcat (res, " LNK");
12753 break;
12754 default:
bee0ee85
NC
12755 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12756 VMS_ST_LINKAGE (other));
12757 strcat (res, " <unknown>");
12758 break;
28f997cf
TG
12759 }
12760
12761 if (res[0] != 0)
12762 return res + 1;
12763 else
12764 return res;
12765 }
12766 return NULL;
12767}
12768
6911b7dc
AM
12769static const char *
12770get_ppc64_symbol_other (unsigned int other)
12771{
14732552
AM
12772 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12773 return NULL;
12774
12775 other >>= STO_PPC64_LOCAL_BIT;
12776 if (other <= 6)
6911b7dc 12777 {
89246a0e 12778 static char buf[64];
14732552
AM
12779 if (other >= 2)
12780 other = ppc64_decode_local_entry (other);
12781 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12782 return buf;
12783 }
12784 return NULL;
12785}
12786
8155b853
NC
12787static const char *
12788get_riscv_symbol_other (unsigned int other)
12789{
12790 static char buf[32];
12791 buf[0] = 0;
12792
12793 if (other & STO_RISCV_VARIANT_CC)
12794 {
12795 strcat (buf, _(" VARIANT_CC"));
12796 other &= ~STO_RISCV_VARIANT_CC;
12797 }
12798
12799 if (other != 0)
12800 snprintf (buf, sizeof buf, " %x", other);
12801
12802
12803 if (buf[0] != 0)
12804 return buf + 1;
12805 else
12806 return buf;
12807}
12808
5e2b0d47 12809static const char *
dda8d76d 12810get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12811{
12812 const char * result = NULL;
89246a0e 12813 static char buff [64];
5e2b0d47
NC
12814
12815 if (other == 0)
12816 return "";
12817
dda8d76d 12818 switch (filedata->file_header.e_machine)
5e2b0d47 12819 {
2057d69d
CZ
12820 case EM_ALPHA:
12821 result = get_alpha_symbol_other (other);
12822 break;
2301ed1c
SN
12823 case EM_AARCH64:
12824 result = get_aarch64_symbol_other (other);
12825 break;
5e2b0d47
NC
12826 case EM_MIPS:
12827 result = get_mips_symbol_other (other);
28f997cf
TG
12828 break;
12829 case EM_IA_64:
dda8d76d 12830 result = get_ia64_symbol_other (filedata, other);
28f997cf 12831 break;
6911b7dc
AM
12832 case EM_PPC64:
12833 result = get_ppc64_symbol_other (other);
12834 break;
8155b853
NC
12835 case EM_RISCV:
12836 result = get_riscv_symbol_other (other);
12837 break;
5e2b0d47 12838 default:
fd85a6a1 12839 result = NULL;
5e2b0d47
NC
12840 break;
12841 }
12842
12843 if (result)
12844 return result;
12845
12846 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12847 return buff;
12848}
12849
d1133906 12850static const char *
dda8d76d 12851get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12852{
b34976b6 12853 static char buff[32];
5cf1065c 12854
252b5132
RH
12855 switch (type)
12856 {
b34976b6
AM
12857 case SHN_UNDEF: return "UND";
12858 case SHN_ABS: return "ABS";
12859 case SHN_COMMON: return "COM";
252b5132 12860 default:
9ce701e2 12861 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12862 && filedata->file_header.e_machine == EM_IA_64
12863 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12864 return "ANSI_COM";
12865 else if ((filedata->file_header.e_machine == EM_X86_64
12866 || filedata->file_header.e_machine == EM_L1OM
12867 || filedata->file_header.e_machine == EM_K1OM)
12868 && type == SHN_X86_64_LCOMMON)
12869 return "LARGE_COM";
12870 else if ((type == SHN_MIPS_SCOMMON
12871 && filedata->file_header.e_machine == EM_MIPS)
12872 || (type == SHN_TIC6X_SCOMMON
12873 && filedata->file_header.e_machine == EM_TI_C6000))
12874 return "SCOM";
12875 else if (type == SHN_MIPS_SUNDEFINED
12876 && filedata->file_header.e_machine == EM_MIPS)
12877 return "SUND";
12878 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12879 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12880 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12881 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12882 else if (type >= SHN_LORESERVE)
12883 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12884 else if (filedata->file_header.e_shnum != 0
12885 && type >= filedata->file_header.e_shnum)
12886 sprintf (buff, _("bad section index[%3d]"), type);
12887 else
12888 sprintf (buff, "%3d", type);
12889 break;
fd85a6a1
NC
12890 }
12891
10ca4b04 12892 return buff;
6bd1a22c
L
12893}
12894
bb4d2ac2 12895static const char *
dda8d76d 12896get_symbol_version_string (Filedata * filedata,
015dc7e1 12897 bool is_dynsym,
1449284b
NC
12898 const char * strtab,
12899 unsigned long int strtab_size,
12900 unsigned int si,
12901 Elf_Internal_Sym * psym,
12902 enum versioned_symbol_info * sym_info,
12903 unsigned short * vna_other)
bb4d2ac2 12904{
ab273396
AM
12905 unsigned char data[2];
12906 unsigned short vers_data;
12907 unsigned long offset;
7a815dd5 12908 unsigned short max_vd_ndx;
bb4d2ac2 12909
ab273396 12910 if (!is_dynsym
978c4450 12911 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12912 return NULL;
bb4d2ac2 12913
978c4450
AM
12914 offset = offset_from_vma (filedata,
12915 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12916 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12917
dda8d76d 12918 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12919 sizeof (data), 1, _("version data")) == NULL)
12920 return NULL;
12921
12922 vers_data = byte_get (data, 2);
bb4d2ac2 12923
1f6f5dba 12924 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12925 return NULL;
bb4d2ac2 12926
0b8b7609 12927 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12928 max_vd_ndx = 0;
12929
ab273396
AM
12930 /* Usually we'd only see verdef for defined symbols, and verneed for
12931 undefined symbols. However, symbols defined by the linker in
12932 .dynbss for variables copied from a shared library in order to
12933 avoid text relocations are defined yet have verneed. We could
12934 use a heuristic to detect the special case, for example, check
12935 for verneed first on symbols defined in SHT_NOBITS sections, but
12936 it is simpler and more reliable to just look for both verdef and
12937 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12938
ab273396
AM
12939 if (psym->st_shndx != SHN_UNDEF
12940 && vers_data != 0x8001
978c4450 12941 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12942 {
12943 Elf_Internal_Verdef ivd;
12944 Elf_Internal_Verdaux ivda;
12945 Elf_External_Verdaux evda;
12946 unsigned long off;
bb4d2ac2 12947
dda8d76d 12948 off = offset_from_vma (filedata,
978c4450 12949 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12950 sizeof (Elf_External_Verdef));
12951
12952 do
bb4d2ac2 12953 {
ab273396
AM
12954 Elf_External_Verdef evd;
12955
dda8d76d 12956 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12957 _("version def")) == NULL)
12958 {
12959 ivd.vd_ndx = 0;
12960 ivd.vd_aux = 0;
12961 ivd.vd_next = 0;
1f6f5dba 12962 ivd.vd_flags = 0;
ab273396
AM
12963 }
12964 else
bb4d2ac2 12965 {
ab273396
AM
12966 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12967 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12968 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12969 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12970 }
bb4d2ac2 12971
7a815dd5
L
12972 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12973 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12974
ab273396
AM
12975 off += ivd.vd_next;
12976 }
12977 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12978
ab273396
AM
12979 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12980 {
9abca702 12981 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12982 return NULL;
12983
ab273396
AM
12984 off -= ivd.vd_next;
12985 off += ivd.vd_aux;
bb4d2ac2 12986
dda8d76d 12987 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12988 _("version def aux")) != NULL)
12989 {
12990 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12991
ab273396 12992 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12993 return (ivda.vda_name < strtab_size
12994 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12995 }
12996 }
12997 }
bb4d2ac2 12998
978c4450 12999 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13000 {
13001 Elf_External_Verneed evn;
13002 Elf_Internal_Verneed ivn;
13003 Elf_Internal_Vernaux ivna;
bb4d2ac2 13004
dda8d76d 13005 offset = offset_from_vma (filedata,
978c4450 13006 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13007 sizeof evn);
13008 do
13009 {
13010 unsigned long vna_off;
bb4d2ac2 13011
dda8d76d 13012 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13013 _("version need")) == NULL)
13014 {
13015 ivna.vna_next = 0;
13016 ivna.vna_other = 0;
13017 ivna.vna_name = 0;
13018 break;
13019 }
bb4d2ac2 13020
ab273396
AM
13021 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13022 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13023
ab273396 13024 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13025
ab273396
AM
13026 do
13027 {
13028 Elf_External_Vernaux evna;
bb4d2ac2 13029
dda8d76d 13030 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13031 _("version need aux (3)")) == NULL)
bb4d2ac2 13032 {
ab273396
AM
13033 ivna.vna_next = 0;
13034 ivna.vna_other = 0;
13035 ivna.vna_name = 0;
bb4d2ac2 13036 }
bb4d2ac2 13037 else
bb4d2ac2 13038 {
ab273396
AM
13039 ivna.vna_other = BYTE_GET (evna.vna_other);
13040 ivna.vna_next = BYTE_GET (evna.vna_next);
13041 ivna.vna_name = BYTE_GET (evna.vna_name);
13042 }
bb4d2ac2 13043
ab273396
AM
13044 vna_off += ivna.vna_next;
13045 }
13046 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13047
ab273396
AM
13048 if (ivna.vna_other == vers_data)
13049 break;
bb4d2ac2 13050
ab273396
AM
13051 offset += ivn.vn_next;
13052 }
13053 while (ivn.vn_next != 0);
bb4d2ac2 13054
ab273396
AM
13055 if (ivna.vna_other == vers_data)
13056 {
13057 *sym_info = symbol_undefined;
13058 *vna_other = ivna.vna_other;
13059 return (ivna.vna_name < strtab_size
13060 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13061 }
7a815dd5
L
13062 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13063 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13064 return _("<corrupt>");
bb4d2ac2 13065 }
ab273396 13066 return NULL;
bb4d2ac2
L
13067}
13068
047c3dbf
NL
13069/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13070
13071static unsigned int
625d49fc 13072print_dynamic_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13073{
13074 switch (base)
13075 {
13076 case 8:
13077 return print_vma (vma, OCTAL_5);
13078
13079 case 10:
13080 return print_vma (vma, UNSIGNED_5);
13081
13082 case 16:
13083 return print_vma (vma, PREFIX_HEX_5);
13084
13085 case 0:
13086 default:
13087 return print_vma (vma, DEC_5);
13088 }
13089}
13090
10ca4b04
L
13091static void
13092print_dynamic_symbol (Filedata *filedata, unsigned long si,
13093 Elf_Internal_Sym *symtab,
13094 Elf_Internal_Shdr *section,
13095 char *strtab, size_t strtab_size)
252b5132 13096{
10ca4b04
L
13097 const char *version_string;
13098 enum versioned_symbol_info sym_info;
13099 unsigned short vna_other;
23356397
NC
13100 bool is_valid;
13101 const char * sstr;
10ca4b04 13102 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13103
10ca4b04
L
13104 printf ("%6ld: ", si);
13105 print_vma (psym->st_value, LONG_HEX);
13106 putchar (' ');
047c3dbf 13107 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13108 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13109 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13110 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13111 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13112 else
252b5132 13113 {
10ca4b04 13114 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13115
10ca4b04
L
13116 printf (" %-7s", get_symbol_visibility (vis));
13117 /* Check to see if any other bits in the st_other field are set.
13118 Note - displaying this information disrupts the layout of the
13119 table being generated, but for the moment this case is very rare. */
13120 if (psym->st_other ^ vis)
13121 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13122 }
10ca4b04 13123 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13124
23356397
NC
13125 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13126 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13127 && filedata->section_headers != NULL
23356397
NC
13128 && psym->st_name == 0)
13129 {
84714f86
AM
13130 is_valid
13131 = section_name_valid (filedata,
13132 filedata->section_headers + psym->st_shndx);
23356397 13133 sstr = is_valid ?
84714f86
AM
13134 section_name_print (filedata,
13135 filedata->section_headers + psym->st_shndx)
23356397
NC
13136 : _("<corrupt>");
13137 }
13138 else
13139 {
84714f86 13140 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13141 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13142 }
10ca4b04
L
13143
13144 version_string
13145 = get_symbol_version_string (filedata,
13146 (section == NULL
13147 || section->sh_type == SHT_DYNSYM),
13148 strtab, strtab_size, si,
13149 psym, &sym_info, &vna_other);
b9e920ec 13150
0942c7ab
NC
13151 int len_avail = 21;
13152 if (! do_wide && version_string != NULL)
13153 {
ddb43bab 13154 char buffer[16];
0942c7ab 13155
ddb43bab 13156 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13157
13158 if (sym_info == symbol_undefined)
13159 len_avail -= sprintf (buffer," (%d)", vna_other);
13160 else if (sym_info != symbol_hidden)
13161 len_avail -= 1;
13162 }
13163
13164 print_symbol (len_avail, sstr);
b9e920ec 13165
10ca4b04
L
13166 if (version_string)
13167 {
13168 if (sym_info == symbol_undefined)
13169 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13170 else
10ca4b04
L
13171 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13172 version_string);
13173 }
6bd1a22c 13174
10ca4b04 13175 putchar ('\n');
6bd1a22c 13176
10ca4b04
L
13177 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13178 && section != NULL
13179 && si >= section->sh_info
13180 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13181 && filedata->file_header.e_machine != EM_MIPS
13182 /* Solaris binaries have been found to violate this requirement as
13183 well. Not sure if this is a bug or an ABI requirement. */
13184 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13185 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13186 si, printable_section_name (filedata, section), section->sh_info);
13187}
f16a9783 13188
0f03783c
NC
13189static const char *
13190get_lto_kind (unsigned int kind)
13191{
13192 switch (kind)
13193 {
13194 case 0: return "DEF";
13195 case 1: return "WEAKDEF";
13196 case 2: return "UNDEF";
13197 case 3: return "WEAKUNDEF";
13198 case 4: return "COMMON";
13199 default:
13200 break;
13201 }
13202
13203 static char buffer[30];
13204 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13205 sprintf (buffer, "<unknown: %u>", kind);
13206 return buffer;
13207}
13208
13209static const char *
13210get_lto_visibility (unsigned int visibility)
13211{
13212 switch (visibility)
13213 {
13214 case 0: return "DEFAULT";
13215 case 1: return "PROTECTED";
13216 case 2: return "INTERNAL";
13217 case 3: return "HIDDEN";
13218 default:
13219 break;
13220 }
13221
13222 static char buffer[30];
13223 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13224 sprintf (buffer, "<unknown: %u>", visibility);
13225 return buffer;
13226}
13227
13228static const char *
13229get_lto_sym_type (unsigned int sym_type)
13230{
13231 switch (sym_type)
13232 {
13233 case 0: return "UNKNOWN";
13234 case 1: return "FUNCTION";
13235 case 2: return "VARIABLE";
13236 default:
13237 break;
13238 }
13239
13240 static char buffer[30];
13241 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13242 sprintf (buffer, "<unknown: %u>", sym_type);
13243 return buffer;
13244}
13245
13246/* Display an LTO format symbol table.
13247 FIXME: The format of LTO symbol tables is not formalized.
13248 So this code could need changing in the future. */
13249
015dc7e1 13250static bool
0f03783c
NC
13251display_lto_symtab (Filedata * filedata,
13252 Elf_Internal_Shdr * section)
13253{
13254 if (section->sh_size == 0)
13255 {
ca0e11aa
NC
13256 if (filedata->is_separate)
13257 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13258 printable_section_name (filedata, section),
13259 filedata->file_name);
13260 else
13261 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13262 printable_section_name (filedata, section));
047c3dbf 13263
015dc7e1 13264 return true;
0f03783c
NC
13265 }
13266
13267 if (section->sh_size > filedata->file_size)
13268 {
13269 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13270 printable_section_name (filedata, section),
13271 (unsigned long) section->sh_size);
015dc7e1 13272 return false;
0f03783c
NC
13273 }
13274
13275 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13276 section->sh_size, 1, _("LTO symbols"));
13277 if (alloced_data == NULL)
015dc7e1 13278 return false;
0f03783c
NC
13279
13280 /* Look for extended data for the symbol table. */
13281 Elf_Internal_Shdr * ext;
13282 void * ext_data_orig = NULL;
13283 char * ext_data = NULL;
13284 char * ext_data_end = NULL;
13285 char * ext_name = NULL;
13286
13287 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13288 (section_name (filedata, section)
13289 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13290 && ext_name != NULL /* Paranoia. */
13291 && (ext = find_section (filedata, ext_name)) != NULL)
13292 {
13293 if (ext->sh_size < 3)
13294 error (_("LTO Symbol extension table '%s' is empty!\n"),
13295 printable_section_name (filedata, ext));
13296 else
13297 {
13298 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13299 ext->sh_size, 1,
13300 _("LTO ext symbol data"));
13301 if (ext_data != NULL)
13302 {
13303 ext_data_end = ext_data + ext->sh_size;
13304 if (* ext_data++ != 1)
13305 error (_("Unexpected version number in symbol extension table\n"));
13306 }
13307 }
13308 }
b9e920ec 13309
0f03783c
NC
13310 const unsigned char * data = (const unsigned char *) alloced_data;
13311 const unsigned char * end = data + section->sh_size;
13312
ca0e11aa
NC
13313 if (filedata->is_separate)
13314 printf (_("\nIn linked file '%s': "), filedata->file_name);
13315 else
13316 printf ("\n");
13317
0f03783c
NC
13318 if (ext_data_orig != NULL)
13319 {
13320 if (do_wide)
ca0e11aa 13321 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13322 printable_section_name (filedata, section),
13323 printable_section_name (filedata, ext));
13324 else
13325 {
ca0e11aa 13326 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13327 printable_section_name (filedata, section));
13328 printf (_(" and extension table '%s' contain:\n"),
13329 printable_section_name (filedata, ext));
13330 }
13331 }
13332 else
ca0e11aa 13333 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13334 printable_section_name (filedata, section));
b9e920ec 13335
0f03783c 13336 /* FIXME: Add a wide version. */
b9e920ec 13337 if (ext_data_orig != NULL)
0f03783c
NC
13338 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13339 else
13340 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13341
13342 /* FIXME: We do not handle style prefixes. */
13343
13344 while (data < end)
13345 {
13346 const unsigned char * sym_name = data;
13347 data += strnlen ((const char *) sym_name, end - data) + 1;
13348 if (data >= end)
13349 goto fail;
13350
13351 const unsigned char * comdat_key = data;
13352 data += strnlen ((const char *) comdat_key, end - data) + 1;
13353 if (data >= end)
13354 goto fail;
13355
13356 if (data + 2 + 8 + 4 > end)
13357 goto fail;
13358
13359 unsigned int kind = *data++;
13360 unsigned int visibility = *data++;
13361
928c411d 13362 uint64_t size = byte_get (data, 8);
0f03783c
NC
13363 data += 8;
13364
928c411d 13365 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13366 data += 4;
13367
13368 if (ext_data != NULL)
13369 {
13370 if (ext_data < (ext_data_end - 1))
13371 {
13372 unsigned int sym_type = * ext_data ++;
13373 unsigned int sec_kind = * ext_data ++;
13374
13375 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13376 * comdat_key == 0 ? "-" : (char *) comdat_key,
13377 get_lto_kind (kind),
13378 get_lto_visibility (visibility),
13379 (long) size,
13380 (long) slot,
13381 get_lto_sym_type (sym_type),
13382 (long) sec_kind);
13383 print_symbol (6, (const char *) sym_name);
13384 }
13385 else
13386 {
13387 error (_("Ran out of LTO symbol extension data\n"));
13388 ext_data = NULL;
13389 /* FIXME: return FAIL result ? */
13390 }
13391 }
13392 else
13393 {
13394 printf (" %10s %10s %11s %08lx %08lx _",
13395 * comdat_key == 0 ? "-" : (char *) comdat_key,
13396 get_lto_kind (kind),
13397 get_lto_visibility (visibility),
13398 (long) size,
13399 (long) slot);
13400 print_symbol (21, (const char *) sym_name);
13401 }
13402 putchar ('\n');
13403 }
13404
13405 if (ext_data != NULL && ext_data < ext_data_end)
13406 {
13407 error (_("Data remains in the LTO symbol extension table\n"));
13408 goto fail;
13409 }
13410
13411 free (alloced_data);
13412 free (ext_data_orig);
13413 free (ext_name);
015dc7e1 13414 return true;
b9e920ec 13415
0f03783c
NC
13416 fail:
13417 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13418 free (alloced_data);
13419 free (ext_data_orig);
13420 free (ext_name);
015dc7e1 13421 return false;
0f03783c
NC
13422}
13423
13424/* Display LTO symbol tables. */
13425
015dc7e1 13426static bool
0f03783c
NC
13427process_lto_symbol_tables (Filedata * filedata)
13428{
13429 Elf_Internal_Shdr * section;
13430 unsigned int i;
015dc7e1 13431 bool res = true;
0f03783c
NC
13432
13433 if (!do_lto_syms)
015dc7e1 13434 return true;
0f03783c
NC
13435
13436 if (filedata->section_headers == NULL)
015dc7e1 13437 return true;
0f03783c
NC
13438
13439 for (i = 0, section = filedata->section_headers;
13440 i < filedata->file_header.e_shnum;
13441 i++, section++)
84714f86
AM
13442 if (section_name_valid (filedata, section)
13443 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13444 res &= display_lto_symtab (filedata, section);
13445
b9e920ec 13446 return res;
0f03783c
NC
13447}
13448
10ca4b04 13449/* Dump the symbol table. */
0f03783c 13450
015dc7e1 13451static bool
10ca4b04
L
13452process_symbol_table (Filedata * filedata)
13453{
13454 Elf_Internal_Shdr * section;
f16a9783 13455
10ca4b04 13456 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13457 return true;
6bd1a22c 13458
978c4450 13459 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13460 && do_syms
13461 && do_using_dynamic
978c4450
AM
13462 && filedata->dynamic_strings != NULL
13463 && filedata->dynamic_symbols != NULL)
6bd1a22c 13464 {
10ca4b04 13465 unsigned long si;
6bd1a22c 13466
ca0e11aa
NC
13467 if (filedata->is_separate)
13468 {
13469 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13470 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13471 filedata->num_dynamic_syms),
13472 filedata->file_name,
13473 filedata->num_dynamic_syms);
13474 }
13475 else
13476 {
13477 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13478 "\nSymbol table for image contains %lu entries:\n",
13479 filedata->num_dynamic_syms),
13480 filedata->num_dynamic_syms);
13481 }
10ca4b04
L
13482 if (is_32bit_elf)
13483 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13484 else
13485 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13486
978c4450
AM
13487 for (si = 0; si < filedata->num_dynamic_syms; si++)
13488 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13489 filedata->dynamic_strings,
13490 filedata->dynamic_strings_length);
252b5132 13491 }
8b73c356 13492 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13493 && filedata->section_headers != NULL)
252b5132 13494 {
b34976b6 13495 unsigned int i;
252b5132 13496
dda8d76d
NC
13497 for (i = 0, section = filedata->section_headers;
13498 i < filedata->file_header.e_shnum;
252b5132
RH
13499 i++, section++)
13500 {
2cf0635d 13501 char * strtab = NULL;
c256ffe7 13502 unsigned long int strtab_size = 0;
2cf0635d 13503 Elf_Internal_Sym * symtab;
ef3df110 13504 unsigned long si, num_syms;
252b5132 13505
2c610e4b
L
13506 if ((section->sh_type != SHT_SYMTAB
13507 && section->sh_type != SHT_DYNSYM)
13508 || (!do_syms
13509 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13510 continue;
13511
dd24e3da
NC
13512 if (section->sh_entsize == 0)
13513 {
13514 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13515 printable_section_name (filedata, section));
dd24e3da
NC
13516 continue;
13517 }
13518
d3a49aa8 13519 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13520
13521 if (filedata->is_separate)
13522 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13523 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13524 num_syms),
13525 filedata->file_name,
13526 printable_section_name (filedata, section),
13527 num_syms);
13528 else
13529 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13530 "\nSymbol table '%s' contains %lu entries:\n",
13531 num_syms),
13532 printable_section_name (filedata, section),
13533 num_syms);
dd24e3da 13534
f7a99963 13535 if (is_32bit_elf)
ca47b30c 13536 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13537 else
ca47b30c 13538 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13539
4de91c10 13540 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13541 if (symtab == NULL)
13542 continue;
13543
dda8d76d 13544 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13545 {
dda8d76d
NC
13546 strtab = filedata->string_table;
13547 strtab_size = filedata->string_table_length;
c256ffe7 13548 }
dda8d76d 13549 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13550 {
2cf0635d 13551 Elf_Internal_Shdr * string_sec;
252b5132 13552
dda8d76d 13553 string_sec = filedata->section_headers + section->sh_link;
252b5132 13554
dda8d76d 13555 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13556 1, string_sec->sh_size,
13557 _("string table"));
c256ffe7 13558 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13559 }
13560
10ca4b04
L
13561 for (si = 0; si < num_syms; si++)
13562 print_dynamic_symbol (filedata, si, symtab, section,
13563 strtab, strtab_size);
252b5132
RH
13564
13565 free (symtab);
dda8d76d 13566 if (strtab != filedata->string_table)
252b5132
RH
13567 free (strtab);
13568 }
13569 }
13570 else if (do_syms)
13571 printf
13572 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13573
978c4450 13574 if (do_histogram && filedata->buckets != NULL)
252b5132 13575 {
2cf0635d
NC
13576 unsigned long * lengths;
13577 unsigned long * counts;
66543521 13578 unsigned long hn;
625d49fc 13579 uint64_t si;
66543521
AM
13580 unsigned long maxlength = 0;
13581 unsigned long nzero_counts = 0;
13582 unsigned long nsyms = 0;
6bd6a03d 13583 char *visited;
252b5132 13584
d3a49aa8
AM
13585 printf (ngettext ("\nHistogram for bucket list length "
13586 "(total of %lu bucket):\n",
13587 "\nHistogram for bucket list length "
13588 "(total of %lu buckets):\n",
978c4450
AM
13589 (unsigned long) filedata->nbuckets),
13590 (unsigned long) filedata->nbuckets);
252b5132 13591
978c4450
AM
13592 lengths = (unsigned long *) calloc (filedata->nbuckets,
13593 sizeof (*lengths));
252b5132
RH
13594 if (lengths == NULL)
13595 {
8b73c356 13596 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13597 goto err_out;
252b5132 13598 }
978c4450
AM
13599 visited = xcmalloc (filedata->nchains, 1);
13600 memset (visited, 0, filedata->nchains);
8b73c356
NC
13601
13602 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13603 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13604 {
978c4450 13605 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13606 {
b34976b6 13607 ++nsyms;
252b5132 13608 if (maxlength < ++lengths[hn])
b34976b6 13609 ++maxlength;
978c4450 13610 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13611 {
13612 error (_("histogram chain is corrupt\n"));
13613 break;
13614 }
13615 visited[si] = 1;
252b5132
RH
13616 }
13617 }
6bd6a03d 13618 free (visited);
252b5132 13619
3f5e193b 13620 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13621 if (counts == NULL)
13622 {
b2e951ec 13623 free (lengths);
8b73c356 13624 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13625 goto err_out;
252b5132
RH
13626 }
13627
978c4450 13628 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13629 ++counts[lengths[hn]];
252b5132 13630
978c4450 13631 if (filedata->nbuckets > 0)
252b5132 13632 {
66543521
AM
13633 unsigned long i;
13634 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13635 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13636 for (i = 1; i <= maxlength; ++i)
103f02d3 13637 {
66543521
AM
13638 nzero_counts += counts[i] * i;
13639 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13640 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13641 (nzero_counts * 100.0) / nsyms);
13642 }
252b5132
RH
13643 }
13644
13645 free (counts);
13646 free (lengths);
13647 }
13648
978c4450
AM
13649 free (filedata->buckets);
13650 filedata->buckets = NULL;
13651 filedata->nbuckets = 0;
13652 free (filedata->chains);
13653 filedata->chains = NULL;
252b5132 13654
978c4450 13655 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13656 {
2cf0635d
NC
13657 unsigned long * lengths;
13658 unsigned long * counts;
fdc90cb4
JJ
13659 unsigned long hn;
13660 unsigned long maxlength = 0;
13661 unsigned long nzero_counts = 0;
13662 unsigned long nsyms = 0;
fdc90cb4 13663
f16a9783 13664 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13665 "(total of %lu bucket):\n",
f16a9783 13666 "\nHistogram for `%s' bucket list length "
d3a49aa8 13667 "(total of %lu buckets):\n",
978c4450
AM
13668 (unsigned long) filedata->ngnubuckets),
13669 GNU_HASH_SECTION_NAME (filedata),
13670 (unsigned long) filedata->ngnubuckets);
8b73c356 13671
978c4450
AM
13672 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13673 sizeof (*lengths));
fdc90cb4
JJ
13674 if (lengths == NULL)
13675 {
8b73c356 13676 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13677 goto err_out;
fdc90cb4
JJ
13678 }
13679
fdc90cb4
JJ
13680 printf (_(" Length Number %% of total Coverage\n"));
13681
978c4450
AM
13682 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13683 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 13684 {
625d49fc 13685 uint64_t off, length = 1;
fdc90cb4 13686
978c4450 13687 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13688 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13689 off < filedata->ngnuchains
13690 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13691 ++off)
fdc90cb4
JJ
13692 ++length;
13693 lengths[hn] = length;
13694 if (length > maxlength)
13695 maxlength = length;
13696 nsyms += length;
13697 }
13698
3f5e193b 13699 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13700 if (counts == NULL)
13701 {
b2e951ec 13702 free (lengths);
8b73c356 13703 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13704 goto err_out;
fdc90cb4
JJ
13705 }
13706
978c4450 13707 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13708 ++counts[lengths[hn]];
13709
978c4450 13710 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13711 {
13712 unsigned long j;
13713 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13714 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13715 for (j = 1; j <= maxlength; ++j)
13716 {
13717 nzero_counts += counts[j] * j;
13718 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13719 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13720 (nzero_counts * 100.0) / nsyms);
13721 }
13722 }
13723
13724 free (counts);
13725 free (lengths);
fdc90cb4 13726 }
978c4450
AM
13727 free (filedata->gnubuckets);
13728 filedata->gnubuckets = NULL;
13729 filedata->ngnubuckets = 0;
13730 free (filedata->gnuchains);
13731 filedata->gnuchains = NULL;
13732 filedata->ngnuchains = 0;
13733 free (filedata->mipsxlat);
13734 filedata->mipsxlat = NULL;
015dc7e1 13735 return true;
fd486f32
AM
13736
13737 err_out:
978c4450
AM
13738 free (filedata->gnubuckets);
13739 filedata->gnubuckets = NULL;
13740 filedata->ngnubuckets = 0;
13741 free (filedata->gnuchains);
13742 filedata->gnuchains = NULL;
13743 filedata->ngnuchains = 0;
13744 free (filedata->mipsxlat);
13745 filedata->mipsxlat = NULL;
13746 free (filedata->buckets);
13747 filedata->buckets = NULL;
13748 filedata->nbuckets = 0;
13749 free (filedata->chains);
13750 filedata->chains = NULL;
015dc7e1 13751 return false;
252b5132
RH
13752}
13753
015dc7e1 13754static bool
ca0e11aa 13755process_syminfo (Filedata * filedata)
252b5132 13756{
b4c96d0d 13757 unsigned int i;
252b5132 13758
978c4450 13759 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13760 || !do_dynamic)
13761 /* No syminfo, this is ok. */
015dc7e1 13762 return true;
252b5132
RH
13763
13764 /* There better should be a dynamic symbol section. */
978c4450 13765 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13766 return false;
252b5132 13767
ca0e11aa
NC
13768 if (filedata->is_separate)
13769 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13770 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13771 filedata->dynamic_syminfo_nent),
13772 filedata->file_name,
13773 filedata->dynamic_syminfo_offset,
13774 filedata->dynamic_syminfo_nent);
13775 else
d3a49aa8
AM
13776 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13777 "contains %d entry:\n",
13778 "\nDynamic info segment at offset 0x%lx "
13779 "contains %d entries:\n",
978c4450 13780 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13781 filedata->dynamic_syminfo_offset,
13782 filedata->dynamic_syminfo_nent);
252b5132
RH
13783
13784 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13785 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13786 {
978c4450 13787 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13788
31104126 13789 printf ("%4d: ", i);
978c4450 13790 if (i >= filedata->num_dynamic_syms)
4082ef84 13791 printf (_("<corrupt index>"));
84714f86
AM
13792 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13793 print_symbol (30, get_dynamic_name (filedata,
978c4450 13794 filedata->dynamic_symbols[i].st_name));
d79b3d50 13795 else
978c4450 13796 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13797 putchar (' ');
252b5132 13798
978c4450 13799 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13800 {
13801 case SYMINFO_BT_SELF:
13802 fputs ("SELF ", stdout);
13803 break;
13804 case SYMINFO_BT_PARENT:
13805 fputs ("PARENT ", stdout);
13806 break;
13807 default:
978c4450
AM
13808 if (filedata->dynamic_syminfo[i].si_boundto > 0
13809 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13810 && valid_dynamic_name (filedata,
978c4450 13811 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13812 {
84714f86 13813 print_symbol (10, get_dynamic_name (filedata,
978c4450 13814 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13815 putchar (' ' );
13816 }
252b5132 13817 else
978c4450 13818 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13819 break;
13820 }
13821
13822 if (flags & SYMINFO_FLG_DIRECT)
13823 printf (" DIRECT");
13824 if (flags & SYMINFO_FLG_PASSTHRU)
13825 printf (" PASSTHRU");
13826 if (flags & SYMINFO_FLG_COPY)
13827 printf (" COPY");
13828 if (flags & SYMINFO_FLG_LAZYLOAD)
13829 printf (" LAZYLOAD");
13830
13831 puts ("");
13832 }
13833
015dc7e1 13834 return true;
252b5132
RH
13835}
13836
75802ccb
CE
13837/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13838 is contained by the region START .. END. The types of ADDR, START
13839 and END should all be the same. Note both ADDR + NELEM and END
13840 point to just beyond the end of the regions that are being tested. */
13841#define IN_RANGE(START,END,ADDR,NELEM) \
13842 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13843
cf13d699
NC
13844/* Check to see if the given reloc needs to be handled in a target specific
13845 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13846 FALSE.
13847
13848 If called with reloc == NULL, then this is a signal that reloc processing
13849 for the current section has finished, and any saved state should be
13850 discarded. */
09c11c86 13851
015dc7e1 13852static bool
dda8d76d
NC
13853target_specific_reloc_handling (Filedata * filedata,
13854 Elf_Internal_Rela * reloc,
13855 unsigned char * start,
13856 unsigned char * end,
13857 Elf_Internal_Sym * symtab,
13858 unsigned long num_syms)
252b5132 13859{
f84ce13b
NC
13860 unsigned int reloc_type = 0;
13861 unsigned long sym_index = 0;
13862
13863 if (reloc)
13864 {
dda8d76d 13865 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13866 sym_index = get_reloc_symindex (reloc->r_info);
13867 }
252b5132 13868
dda8d76d 13869 switch (filedata->file_header.e_machine)
252b5132 13870 {
13761a11
NC
13871 case EM_MSP430:
13872 case EM_MSP430_OLD:
13873 {
13874 static Elf_Internal_Sym * saved_sym = NULL;
13875
f84ce13b
NC
13876 if (reloc == NULL)
13877 {
13878 saved_sym = NULL;
015dc7e1 13879 return true;
f84ce13b
NC
13880 }
13881
13761a11
NC
13882 switch (reloc_type)
13883 {
13884 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13885 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13886 if (uses_msp430x_relocs (filedata))
13761a11 13887 break;
1a0670f3 13888 /* Fall through. */
13761a11 13889 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13890 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13891 /* PR 21139. */
13892 if (sym_index >= num_syms)
13893 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13894 sym_index);
13895 else
13896 saved_sym = symtab + sym_index;
015dc7e1 13897 return true;
13761a11
NC
13898
13899 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13900 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13901 goto handle_sym_diff;
0b4362b0 13902
13761a11
NC
13903 case 5: /* R_MSP430_16_BYTE */
13904 case 9: /* R_MSP430_8 */
7d81bc93 13905 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13906 if (uses_msp430x_relocs (filedata))
13761a11
NC
13907 break;
13908 goto handle_sym_diff;
13909
13910 case 2: /* R_MSP430_ABS16 */
13911 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13912 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13913 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13914 break;
13915 goto handle_sym_diff;
0b4362b0 13916
13761a11
NC
13917 handle_sym_diff:
13918 if (saved_sym != NULL)
13919 {
625d49fc 13920 uint64_t value;
5a805384 13921 unsigned int reloc_size = 0;
7d81bc93
JL
13922 int leb_ret = 0;
13923 switch (reloc_type)
13924 {
13925 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13926 reloc_size = 4;
13927 break;
13928 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13929 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13930 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13931 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13932 &reloc_size, &leb_ret);
7d81bc93
JL
13933 break;
13934 default:
13935 reloc_size = 2;
13936 break;
13937 }
13761a11 13938
5a805384 13939 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13940 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13941 "ULEB128 value\n"),
13942 (long) reloc->r_offset);
13943 else if (sym_index >= num_syms)
f84ce13b
NC
13944 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13945 sym_index);
03f7786e 13946 else
f84ce13b
NC
13947 {
13948 value = reloc->r_addend + (symtab[sym_index].st_value
13949 - saved_sym->st_value);
13950
b32e566b 13951 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13952 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13953 else
13954 /* PR 21137 */
13955 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13956 (long) reloc->r_offset);
f84ce13b 13957 }
13761a11
NC
13958
13959 saved_sym = NULL;
015dc7e1 13960 return true;
13761a11
NC
13961 }
13962 break;
13963
13964 default:
13965 if (saved_sym != NULL)
071436c6 13966 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13967 break;
13968 }
13969 break;
13970 }
13971
cf13d699
NC
13972 case EM_MN10300:
13973 case EM_CYGNUS_MN10300:
13974 {
13975 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13976
f84ce13b
NC
13977 if (reloc == NULL)
13978 {
13979 saved_sym = NULL;
015dc7e1 13980 return true;
f84ce13b
NC
13981 }
13982
cf13d699
NC
13983 switch (reloc_type)
13984 {
13985 case 34: /* R_MN10300_ALIGN */
015dc7e1 13986 return true;
cf13d699 13987 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13988 if (sym_index >= num_syms)
13989 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13990 sym_index);
13991 else
13992 saved_sym = symtab + sym_index;
015dc7e1 13993 return true;
f84ce13b 13994
cf13d699
NC
13995 case 1: /* R_MN10300_32 */
13996 case 2: /* R_MN10300_16 */
13997 if (saved_sym != NULL)
13998 {
03f7786e 13999 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14000 uint64_t value;
252b5132 14001
f84ce13b
NC
14002 if (sym_index >= num_syms)
14003 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
14004 sym_index);
03f7786e 14005 else
f84ce13b
NC
14006 {
14007 value = reloc->r_addend + (symtab[sym_index].st_value
14008 - saved_sym->st_value);
14009
b32e566b 14010 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14011 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14012 else
14013 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
14014 (long) reloc->r_offset);
f84ce13b 14015 }
252b5132 14016
cf13d699 14017 saved_sym = NULL;
015dc7e1 14018 return true;
cf13d699
NC
14019 }
14020 break;
14021 default:
14022 if (saved_sym != NULL)
071436c6 14023 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14024 break;
14025 }
14026 break;
14027 }
6ff71e76
NC
14028
14029 case EM_RL78:
14030 {
625d49fc
AM
14031 static uint64_t saved_sym1 = 0;
14032 static uint64_t saved_sym2 = 0;
14033 static uint64_t value;
6ff71e76 14034
f84ce13b
NC
14035 if (reloc == NULL)
14036 {
14037 saved_sym1 = saved_sym2 = 0;
015dc7e1 14038 return true;
f84ce13b
NC
14039 }
14040
6ff71e76
NC
14041 switch (reloc_type)
14042 {
14043 case 0x80: /* R_RL78_SYM. */
14044 saved_sym1 = saved_sym2;
f84ce13b
NC
14045 if (sym_index >= num_syms)
14046 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
14047 sym_index);
14048 else
14049 {
14050 saved_sym2 = symtab[sym_index].st_value;
14051 saved_sym2 += reloc->r_addend;
14052 }
015dc7e1 14053 return true;
6ff71e76
NC
14054
14055 case 0x83: /* R_RL78_OPsub. */
14056 value = saved_sym1 - saved_sym2;
14057 saved_sym2 = saved_sym1 = 0;
015dc7e1 14058 return true;
6ff71e76
NC
14059 break;
14060
14061 case 0x41: /* R_RL78_ABS32. */
b32e566b 14062 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14063 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
14064 else
14065 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14066 (long) reloc->r_offset);
6ff71e76 14067 value = 0;
015dc7e1 14068 return true;
6ff71e76
NC
14069
14070 case 0x43: /* R_RL78_ABS16. */
b32e566b 14071 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14072 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
14073 else
14074 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
14075 (long) reloc->r_offset);
6ff71e76 14076 value = 0;
015dc7e1 14077 return true;
6ff71e76
NC
14078
14079 default:
14080 break;
14081 }
14082 break;
14083 }
252b5132
RH
14084 }
14085
015dc7e1 14086 return false;
252b5132
RH
14087}
14088
aca88567
NC
14089/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14090 DWARF debug sections. This is a target specific test. Note - we do not
14091 go through the whole including-target-headers-multiple-times route, (as
14092 we have already done with <elf/h8.h>) because this would become very
14093 messy and even then this function would have to contain target specific
14094 information (the names of the relocs instead of their numeric values).
14095 FIXME: This is not the correct way to solve this problem. The proper way
14096 is to have target specific reloc sizing and typing functions created by
14097 the reloc-macros.h header, in the same way that it already creates the
14098 reloc naming functions. */
14099
015dc7e1 14100static bool
dda8d76d 14101is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14102{
d347c9df 14103 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14104 switch (filedata->file_header.e_machine)
aca88567 14105 {
41e92641 14106 case EM_386:
22abe556 14107 case EM_IAMCU:
41e92641 14108 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14109 case EM_68K:
14110 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14111 case EM_860:
14112 return reloc_type == 1; /* R_860_32. */
14113 case EM_960:
14114 return reloc_type == 2; /* R_960_32. */
a06ea964 14115 case EM_AARCH64:
9282b95a
JW
14116 return (reloc_type == 258
14117 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14118 case EM_BPF:
14119 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14120 case EM_ADAPTEVA_EPIPHANY:
14121 return reloc_type == 3;
aca88567 14122 case EM_ALPHA:
137b6b5f 14123 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14124 case EM_ARC:
14125 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14126 case EM_ARC_COMPACT:
14127 case EM_ARC_COMPACT2:
14128 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14129 case EM_ARM:
14130 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14131 case EM_AVR_OLD:
aca88567
NC
14132 case EM_AVR:
14133 return reloc_type == 1;
14134 case EM_BLACKFIN:
14135 return reloc_type == 0x12; /* R_byte4_data. */
14136 case EM_CRIS:
14137 return reloc_type == 3; /* R_CRIS_32. */
14138 case EM_CR16:
14139 return reloc_type == 3; /* R_CR16_NUM32. */
14140 case EM_CRX:
14141 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14142 case EM_CSKY:
14143 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14144 case EM_CYGNUS_FRV:
14145 return reloc_type == 1;
41e92641
NC
14146 case EM_CYGNUS_D10V:
14147 case EM_D10V:
14148 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14149 case EM_CYGNUS_D30V:
14150 case EM_D30V:
14151 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14152 case EM_DLX:
14153 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14154 case EM_CYGNUS_FR30:
14155 case EM_FR30:
14156 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14157 case EM_FT32:
14158 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14159 case EM_H8S:
14160 case EM_H8_300:
14161 case EM_H8_300H:
14162 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14163 case EM_IA_64:
262cdac7
AM
14164 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14165 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14166 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14167 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14168 case EM_IP2K_OLD:
14169 case EM_IP2K:
14170 return reloc_type == 2; /* R_IP2K_32. */
14171 case EM_IQ2000:
14172 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14173 case EM_LATTICEMICO32:
14174 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14175 case EM_LOONGARCH:
14176 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14177 case EM_M32C_OLD:
aca88567
NC
14178 case EM_M32C:
14179 return reloc_type == 3; /* R_M32C_32. */
14180 case EM_M32R:
14181 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14182 case EM_68HC11:
14183 case EM_68HC12:
14184 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14185 case EM_S12Z:
2849d19f
JD
14186 return reloc_type == 7 || /* R_S12Z_EXT32 */
14187 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14188 case EM_MCORE:
14189 return reloc_type == 1; /* R_MCORE_ADDR32. */
14190 case EM_CYGNUS_MEP:
14191 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14192 case EM_METAG:
14193 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14194 case EM_MICROBLAZE:
14195 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14196 case EM_MIPS:
14197 return reloc_type == 2; /* R_MIPS_32. */
14198 case EM_MMIX:
14199 return reloc_type == 4; /* R_MMIX_32. */
14200 case EM_CYGNUS_MN10200:
14201 case EM_MN10200:
14202 return reloc_type == 1; /* R_MN10200_32. */
14203 case EM_CYGNUS_MN10300:
14204 case EM_MN10300:
14205 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14206 case EM_MOXIE:
14207 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14208 case EM_MSP430_OLD:
14209 case EM_MSP430:
13761a11 14210 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14211 case EM_MT:
14212 return reloc_type == 2; /* R_MT_32. */
35c08157 14213 case EM_NDS32:
81c5e376 14214 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14215 case EM_ALTERA_NIOS2:
36591ba1 14216 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14217 case EM_NIOS32:
14218 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14219 case EM_OR1K:
14220 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14221 case EM_PARISC:
9abca702 14222 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14223 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14224 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14225 case EM_PJ:
14226 case EM_PJ_OLD:
14227 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14228 case EM_PPC64:
14229 return reloc_type == 1; /* R_PPC64_ADDR32. */
14230 case EM_PPC:
14231 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14232 case EM_TI_PRU:
14233 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14234 case EM_RISCV:
14235 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14236 case EM_RL78:
14237 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14238 case EM_RX:
14239 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14240 case EM_S370:
14241 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14242 case EM_S390_OLD:
14243 case EM_S390:
14244 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14245 case EM_SCORE:
14246 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14247 case EM_SH:
14248 return reloc_type == 1; /* R_SH_DIR32. */
14249 case EM_SPARC32PLUS:
14250 case EM_SPARCV9:
14251 case EM_SPARC:
14252 return reloc_type == 3 /* R_SPARC_32. */
14253 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14254 case EM_SPU:
14255 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14256 case EM_TI_C6000:
14257 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14258 case EM_TILEGX:
14259 return reloc_type == 2; /* R_TILEGX_32. */
14260 case EM_TILEPRO:
14261 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14262 case EM_CYGNUS_V850:
14263 case EM_V850:
14264 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14265 case EM_V800:
14266 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14267 case EM_VAX:
14268 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14269 case EM_VISIUM:
14270 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14271 case EM_WEBASSEMBLY:
14272 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14273 case EM_X86_64:
8a9036a4 14274 case EM_L1OM:
7a9068fe 14275 case EM_K1OM:
aca88567 14276 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14277 case EM_XGATE:
14278 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14279 case EM_XSTORMY16:
14280 return reloc_type == 1; /* R_XSTROMY16_32. */
14281 case EM_XTENSA_OLD:
14282 case EM_XTENSA:
14283 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14284 case EM_Z80:
14285 return reloc_type == 6; /* R_Z80_32. */
aca88567 14286 default:
bee0ee85
NC
14287 {
14288 static unsigned int prev_warn = 0;
14289
14290 /* Avoid repeating the same warning multiple times. */
dda8d76d 14291 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14292 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14293 filedata->file_header.e_machine);
14294 prev_warn = filedata->file_header.e_machine;
015dc7e1 14295 return false;
bee0ee85 14296 }
aca88567
NC
14297 }
14298}
14299
14300/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14301 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14302
015dc7e1 14303static bool
dda8d76d 14304is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14305{
dda8d76d 14306 switch (filedata->file_header.e_machine)
d347c9df 14307 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14308 {
41e92641 14309 case EM_386:
22abe556 14310 case EM_IAMCU:
3e0873ac 14311 return reloc_type == 2; /* R_386_PC32. */
aca88567 14312 case EM_68K:
3e0873ac 14313 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14314 case EM_AARCH64:
14315 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14316 case EM_ADAPTEVA_EPIPHANY:
14317 return reloc_type == 6;
aca88567
NC
14318 case EM_ALPHA:
14319 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14320 case EM_ARC_COMPACT:
14321 case EM_ARC_COMPACT2:
14322 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14323 case EM_ARM:
3e0873ac 14324 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14325 case EM_AVR_OLD:
14326 case EM_AVR:
14327 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 14328 case EM_LOONGARCH:
14329 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
14330 case EM_MICROBLAZE:
14331 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14332 case EM_OR1K:
14333 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14334 case EM_PARISC:
85acf597 14335 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14336 case EM_PPC:
14337 return reloc_type == 26; /* R_PPC_REL32. */
14338 case EM_PPC64:
3e0873ac 14339 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14340 case EM_RISCV:
14341 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14342 case EM_S390_OLD:
14343 case EM_S390:
3e0873ac 14344 return reloc_type == 5; /* R_390_PC32. */
aca88567 14345 case EM_SH:
3e0873ac 14346 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14347 case EM_SPARC32PLUS:
14348 case EM_SPARCV9:
14349 case EM_SPARC:
3e0873ac 14350 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14351 case EM_SPU:
14352 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14353 case EM_TILEGX:
14354 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14355 case EM_TILEPRO:
14356 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14357 case EM_VISIUM:
14358 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14359 case EM_X86_64:
8a9036a4 14360 case EM_L1OM:
7a9068fe 14361 case EM_K1OM:
3e0873ac 14362 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14363 case EM_VAX:
14364 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14365 case EM_XTENSA_OLD:
14366 case EM_XTENSA:
14367 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14368 default:
14369 /* Do not abort or issue an error message here. Not all targets use
14370 pc-relative 32-bit relocs in their DWARF debug information and we
14371 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14372 more helpful warning message will be generated by apply_relocations
14373 anyway, so just return. */
015dc7e1 14374 return false;
aca88567
NC
14375 }
14376}
14377
14378/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14379 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14380
015dc7e1 14381static bool
dda8d76d 14382is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14383{
dda8d76d 14384 switch (filedata->file_header.e_machine)
aca88567 14385 {
a06ea964
NC
14386 case EM_AARCH64:
14387 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14388 case EM_ALPHA:
14389 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14390 case EM_IA_64:
262cdac7
AM
14391 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14392 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14393 case EM_LOONGARCH:
14394 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14395 case EM_PARISC:
14396 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14397 case EM_PPC64:
14398 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14399 case EM_RISCV:
14400 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14401 case EM_SPARC32PLUS:
14402 case EM_SPARCV9:
14403 case EM_SPARC:
714da62f
NC
14404 return reloc_type == 32 /* R_SPARC_64. */
14405 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14406 case EM_X86_64:
8a9036a4 14407 case EM_L1OM:
7a9068fe 14408 case EM_K1OM:
aca88567 14409 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14410 case EM_S390_OLD:
14411 case EM_S390:
aa137e4d
NC
14412 return reloc_type == 22; /* R_S390_64. */
14413 case EM_TILEGX:
14414 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14415 case EM_MIPS:
aa137e4d 14416 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14417 default:
015dc7e1 14418 return false;
aca88567
NC
14419 }
14420}
14421
85acf597
RH
14422/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14423 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14424
015dc7e1 14425static bool
dda8d76d 14426is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14427{
dda8d76d 14428 switch (filedata->file_header.e_machine)
85acf597 14429 {
a06ea964
NC
14430 case EM_AARCH64:
14431 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14432 case EM_ALPHA:
aa137e4d 14433 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14434 case EM_IA_64:
262cdac7
AM
14435 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14436 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14437 case EM_PARISC:
aa137e4d 14438 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14439 case EM_PPC64:
aa137e4d 14440 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14441 case EM_SPARC32PLUS:
14442 case EM_SPARCV9:
14443 case EM_SPARC:
aa137e4d 14444 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14445 case EM_X86_64:
8a9036a4 14446 case EM_L1OM:
7a9068fe 14447 case EM_K1OM:
aa137e4d 14448 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14449 case EM_S390_OLD:
14450 case EM_S390:
aa137e4d
NC
14451 return reloc_type == 23; /* R_S390_PC64. */
14452 case EM_TILEGX:
14453 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14454 default:
015dc7e1 14455 return false;
85acf597
RH
14456 }
14457}
14458
4dc3c23d
AM
14459/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14460 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14461
015dc7e1 14462static bool
dda8d76d 14463is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14464{
dda8d76d 14465 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14466 {
14467 case EM_CYGNUS_MN10200:
14468 case EM_MN10200:
14469 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14470 case EM_FT32:
14471 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14472 case EM_Z80:
14473 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14474 default:
015dc7e1 14475 return false;
4dc3c23d
AM
14476 }
14477}
14478
aca88567
NC
14479/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14480 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14481
015dc7e1 14482static bool
dda8d76d 14483is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14484{
d347c9df 14485 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14486 switch (filedata->file_header.e_machine)
4b78141a 14487 {
886a2506
NC
14488 case EM_ARC:
14489 case EM_ARC_COMPACT:
14490 case EM_ARC_COMPACT2:
14491 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14492 case EM_ADAPTEVA_EPIPHANY:
14493 return reloc_type == 5;
aca88567
NC
14494 case EM_AVR_OLD:
14495 case EM_AVR:
14496 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14497 case EM_CYGNUS_D10V:
14498 case EM_D10V:
14499 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14500 case EM_FT32:
14501 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14502 case EM_H8S:
14503 case EM_H8_300:
14504 case EM_H8_300H:
aca88567
NC
14505 return reloc_type == R_H8_DIR16;
14506 case EM_IP2K_OLD:
14507 case EM_IP2K:
14508 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14509 case EM_M32C_OLD:
f4236fe4
DD
14510 case EM_M32C:
14511 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14512 case EM_CYGNUS_MN10200:
14513 case EM_MN10200:
14514 return reloc_type == 2; /* R_MN10200_16. */
14515 case EM_CYGNUS_MN10300:
14516 case EM_MN10300:
14517 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14518 case EM_MSP430:
dda8d76d 14519 if (uses_msp430x_relocs (filedata))
13761a11 14520 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14521 /* Fall through. */
78c8d46c 14522 case EM_MSP430_OLD:
aca88567 14523 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 14524 case EM_NDS32:
81c5e376 14525 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 14526 case EM_ALTERA_NIOS2:
36591ba1 14527 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14528 case EM_NIOS32:
14529 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14530 case EM_OR1K:
14531 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14532 case EM_RISCV:
14533 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14534 case EM_TI_PRU:
14535 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14536 case EM_TI_C6000:
14537 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14538 case EM_VISIUM:
14539 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
14540 case EM_XGATE:
14541 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14542 case EM_Z80:
14543 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14544 default:
015dc7e1 14545 return false;
4b78141a
NC
14546 }
14547}
14548
39e07931
AS
14549/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14550 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14551
015dc7e1 14552static bool
39e07931
AS
14553is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14554{
14555 switch (filedata->file_header.e_machine)
14556 {
14557 case EM_RISCV:
14558 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14559 case EM_Z80:
14560 return reloc_type == 1; /* R_Z80_8. */
39e07931 14561 default:
015dc7e1 14562 return false;
39e07931
AS
14563 }
14564}
14565
14566/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14567 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14568
015dc7e1 14569static bool
39e07931
AS
14570is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14571{
14572 switch (filedata->file_header.e_machine)
14573 {
14574 case EM_RISCV:
14575 return reloc_type == 53; /* R_RISCV_SET6. */
14576 default:
015dc7e1 14577 return false;
39e07931
AS
14578 }
14579}
14580
03336641
JW
14581/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14582 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14583
015dc7e1 14584static bool
03336641
JW
14585is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14586{
14587 /* Please keep this table alpha-sorted for ease of visual lookup. */
14588 switch (filedata->file_header.e_machine)
14589 {
14590 case EM_RISCV:
14591 return reloc_type == 35; /* R_RISCV_ADD32. */
14592 default:
015dc7e1 14593 return false;
03336641
JW
14594 }
14595}
14596
14597/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14598 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14599
015dc7e1 14600static bool
03336641
JW
14601is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14602{
14603 /* Please keep this table alpha-sorted for ease of visual lookup. */
14604 switch (filedata->file_header.e_machine)
14605 {
14606 case EM_RISCV:
14607 return reloc_type == 39; /* R_RISCV_SUB32. */
14608 default:
015dc7e1 14609 return false;
03336641
JW
14610 }
14611}
14612
14613/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14614 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14615
015dc7e1 14616static bool
03336641
JW
14617is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14618{
14619 /* Please keep this table alpha-sorted for ease of visual lookup. */
14620 switch (filedata->file_header.e_machine)
14621 {
14622 case EM_RISCV:
14623 return reloc_type == 36; /* R_RISCV_ADD64. */
14624 default:
015dc7e1 14625 return false;
03336641
JW
14626 }
14627}
14628
14629/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14630 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14631
015dc7e1 14632static bool
03336641
JW
14633is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14634{
14635 /* Please keep this table alpha-sorted for ease of visual lookup. */
14636 switch (filedata->file_header.e_machine)
14637 {
14638 case EM_RISCV:
14639 return reloc_type == 40; /* R_RISCV_SUB64. */
14640 default:
015dc7e1 14641 return false;
03336641
JW
14642 }
14643}
14644
14645/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14646 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14647
015dc7e1 14648static bool
03336641
JW
14649is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14650{
14651 /* Please keep this table alpha-sorted for ease of visual lookup. */
14652 switch (filedata->file_header.e_machine)
14653 {
14654 case EM_RISCV:
14655 return reloc_type == 34; /* R_RISCV_ADD16. */
14656 default:
015dc7e1 14657 return false;
03336641
JW
14658 }
14659}
14660
14661/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14662 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14663
015dc7e1 14664static bool
03336641
JW
14665is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14666{
14667 /* Please keep this table alpha-sorted for ease of visual lookup. */
14668 switch (filedata->file_header.e_machine)
14669 {
14670 case EM_RISCV:
14671 return reloc_type == 38; /* R_RISCV_SUB16. */
14672 default:
015dc7e1 14673 return false;
03336641
JW
14674 }
14675}
14676
14677/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14678 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14679
015dc7e1 14680static bool
03336641
JW
14681is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14682{
14683 /* Please keep this table alpha-sorted for ease of visual lookup. */
14684 switch (filedata->file_header.e_machine)
14685 {
14686 case EM_RISCV:
14687 return reloc_type == 33; /* R_RISCV_ADD8. */
14688 default:
015dc7e1 14689 return false;
03336641
JW
14690 }
14691}
14692
14693/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14694 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14695
015dc7e1 14696static bool
03336641
JW
14697is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14698{
14699 /* Please keep this table alpha-sorted for ease of visual lookup. */
14700 switch (filedata->file_header.e_machine)
14701 {
14702 case EM_RISCV:
14703 return reloc_type == 37; /* R_RISCV_SUB8. */
14704 default:
015dc7e1 14705 return false;
03336641
JW
14706 }
14707}
14708
39e07931
AS
14709/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14710 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14711
015dc7e1 14712static bool
39e07931
AS
14713is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14714{
14715 switch (filedata->file_header.e_machine)
14716 {
14717 case EM_RISCV:
14718 return reloc_type == 52; /* R_RISCV_SUB6. */
14719 default:
015dc7e1 14720 return false;
39e07931
AS
14721 }
14722}
14723
2a7b2e88
JK
14724/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14725 relocation entries (possibly formerly used for SHT_GROUP sections). */
14726
015dc7e1 14727static bool
dda8d76d 14728is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14729{
dda8d76d 14730 switch (filedata->file_header.e_machine)
2a7b2e88 14731 {
cb8f3167 14732 case EM_386: /* R_386_NONE. */
d347c9df 14733 case EM_68K: /* R_68K_NONE. */
cfb8c092 14734 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14735 case EM_ALPHA: /* R_ALPHA_NONE. */
14736 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14737 case EM_ARC: /* R_ARC_NONE. */
886a2506 14738 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14739 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14740 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 14741 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14742 case EM_FT32: /* R_FT32_NONE. */
14743 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14744 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14745 case EM_L1OM: /* R_X86_64_NONE. */
14746 case EM_M32R: /* R_M32R_NONE. */
14747 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14748 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14749 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14750 case EM_NIOS32: /* R_NIOS_NONE. */
14751 case EM_OR1K: /* R_OR1K_NONE. */
14752 case EM_PARISC: /* R_PARISC_NONE. */
14753 case EM_PPC64: /* R_PPC64_NONE. */
14754 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14755 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14756 case EM_S390: /* R_390_NONE. */
14757 case EM_S390_OLD:
14758 case EM_SH: /* R_SH_NONE. */
14759 case EM_SPARC32PLUS:
14760 case EM_SPARC: /* R_SPARC_NONE. */
14761 case EM_SPARCV9:
aa137e4d
NC
14762 case EM_TILEGX: /* R_TILEGX_NONE. */
14763 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14764 case EM_TI_C6000:/* R_C6000_NONE. */
14765 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 14766 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14767 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14768 return reloc_type == 0;
d347c9df 14769
a06ea964
NC
14770 case EM_AARCH64:
14771 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14772 case EM_AVR_OLD:
14773 case EM_AVR:
14774 return (reloc_type == 0 /* R_AVR_NONE. */
14775 || reloc_type == 30 /* R_AVR_DIFF8. */
14776 || reloc_type == 31 /* R_AVR_DIFF16. */
14777 || reloc_type == 32 /* R_AVR_DIFF32. */);
14778 case EM_METAG:
14779 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 14780 case EM_NDS32:
81c5e376
AM
14781 return (reloc_type == 0 /* R_NDS32_NONE. */
14782 || reloc_type == 205 /* R_NDS32_DIFF8. */
14783 || reloc_type == 206 /* R_NDS32_DIFF16. */
14784 || reloc_type == 207 /* R_NDS32_DIFF32. */
14785 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
14786 case EM_TI_PRU:
14787 return (reloc_type == 0 /* R_PRU_NONE. */
14788 || reloc_type == 65 /* R_PRU_DIFF8. */
14789 || reloc_type == 66 /* R_PRU_DIFF16. */
14790 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14791 case EM_XTENSA_OLD:
14792 case EM_XTENSA:
4dc3c23d
AM
14793 return (reloc_type == 0 /* R_XTENSA_NONE. */
14794 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14795 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14796 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14797 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14798 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14799 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14800 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14801 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14802 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14803 }
015dc7e1 14804 return false;
2a7b2e88
JK
14805}
14806
d1c4b12b
NC
14807/* Returns TRUE if there is a relocation against
14808 section NAME at OFFSET bytes. */
14809
015dc7e1 14810bool
d1c4b12b
NC
14811reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14812{
14813 Elf_Internal_Rela * relocs;
14814 Elf_Internal_Rela * rp;
14815
14816 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14817 return false;
d1c4b12b
NC
14818
14819 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14820
14821 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14822 if (rp->r_offset == offset)
015dc7e1 14823 return true;
d1c4b12b 14824
015dc7e1 14825 return false;
d1c4b12b
NC
14826}
14827
cf13d699 14828/* Apply relocations to a section.
32ec8896
NC
14829 Returns TRUE upon success, FALSE otherwise.
14830 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14831 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14832 will be set to the number of relocs loaded.
14833
cf13d699 14834 Note: So far support has been added only for those relocations
32ec8896
NC
14835 which can be found in debug sections. FIXME: Add support for
14836 more relocations ? */
1b315056 14837
015dc7e1 14838static bool
be7d229a
AM
14839apply_relocations (Filedata *filedata,
14840 const Elf_Internal_Shdr *section,
14841 unsigned char *start,
14842 size_t size,
14843 void **relocs_return,
14844 unsigned long *num_relocs_return)
1b315056 14845{
cf13d699 14846 Elf_Internal_Shdr * relsec;
0d2a7a93 14847 unsigned char * end = start + size;
cb8f3167 14848
d1c4b12b
NC
14849 if (relocs_return != NULL)
14850 {
14851 * (Elf_Internal_Rela **) relocs_return = NULL;
14852 * num_relocs_return = 0;
14853 }
14854
dda8d76d 14855 if (filedata->file_header.e_type != ET_REL)
32ec8896 14856 /* No relocs to apply. */
015dc7e1 14857 return true;
1b315056 14858
cf13d699 14859 /* Find the reloc section associated with the section. */
dda8d76d
NC
14860 for (relsec = filedata->section_headers;
14861 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14862 ++relsec)
252b5132 14863 {
015dc7e1 14864 bool is_rela;
41e92641 14865 unsigned long num_relocs;
2cf0635d
NC
14866 Elf_Internal_Rela * relocs;
14867 Elf_Internal_Rela * rp;
14868 Elf_Internal_Shdr * symsec;
14869 Elf_Internal_Sym * symtab;
ba5cdace 14870 unsigned long num_syms;
2cf0635d 14871 Elf_Internal_Sym * sym;
252b5132 14872
41e92641 14873 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14874 || relsec->sh_info >= filedata->file_header.e_shnum
14875 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14876 || relsec->sh_size == 0
dda8d76d 14877 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14878 continue;
428409d5 14879
a788aedd
AM
14880 symsec = filedata->section_headers + relsec->sh_link;
14881 if (symsec->sh_type != SHT_SYMTAB
14882 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14883 return false;
a788aedd 14884
41e92641
NC
14885 is_rela = relsec->sh_type == SHT_RELA;
14886
14887 if (is_rela)
14888 {
dda8d76d 14889 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14890 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14891 return false;
41e92641
NC
14892 }
14893 else
14894 {
dda8d76d 14895 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14896 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14897 return false;
41e92641
NC
14898 }
14899
14900 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14901 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14902 is_rela = false;
428409d5 14903
4de91c10 14904 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14905
41e92641 14906 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14907 {
625d49fc 14908 uint64_t addend;
015dc7e1
AM
14909 unsigned int reloc_type;
14910 unsigned int reloc_size;
14911 bool reloc_inplace = false;
14912 bool reloc_subtract = false;
14913 unsigned char *rloc;
14914 unsigned long sym_index;
4b78141a 14915
dda8d76d 14916 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14917
dda8d76d 14918 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14919 continue;
dda8d76d 14920 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14921 continue;
dda8d76d
NC
14922 else if (is_32bit_abs_reloc (filedata, reloc_type)
14923 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14924 reloc_size = 4;
dda8d76d
NC
14925 else if (is_64bit_abs_reloc (filedata, reloc_type)
14926 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14927 reloc_size = 8;
dda8d76d 14928 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14929 reloc_size = 3;
dda8d76d 14930 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14931 reloc_size = 2;
39e07931
AS
14932 else if (is_8bit_abs_reloc (filedata, reloc_type)
14933 || is_6bit_abs_reloc (filedata, reloc_type))
14934 reloc_size = 1;
03336641
JW
14935 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14936 reloc_type))
14937 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14938 {
14939 reloc_size = 4;
015dc7e1 14940 reloc_inplace = true;
03336641
JW
14941 }
14942 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14943 reloc_type))
14944 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14945 {
14946 reloc_size = 8;
015dc7e1 14947 reloc_inplace = true;
03336641
JW
14948 }
14949 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14950 reloc_type))
14951 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14952 {
14953 reloc_size = 2;
015dc7e1 14954 reloc_inplace = true;
03336641
JW
14955 }
14956 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14957 reloc_type))
14958 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14959 {
14960 reloc_size = 1;
015dc7e1 14961 reloc_inplace = true;
03336641 14962 }
39e07931
AS
14963 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14964 reloc_type)))
14965 {
14966 reloc_size = 1;
015dc7e1 14967 reloc_inplace = true;
39e07931 14968 }
aca88567 14969 else
4b78141a 14970 {
bee0ee85 14971 static unsigned int prev_reloc = 0;
dda8d76d 14972
bee0ee85
NC
14973 if (reloc_type != prev_reloc)
14974 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14975 reloc_type, printable_section_name (filedata, section));
bee0ee85 14976 prev_reloc = reloc_type;
4b78141a
NC
14977 continue;
14978 }
103f02d3 14979
91d6fa6a 14980 rloc = start + rp->r_offset;
75802ccb 14981 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14982 {
14983 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14984 (unsigned long) rp->r_offset,
dda8d76d 14985 printable_section_name (filedata, section));
700dd8b7
L
14986 continue;
14987 }
103f02d3 14988
ba5cdace
NC
14989 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14990 if (sym_index >= num_syms)
14991 {
14992 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14993 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14994 continue;
14995 }
14996 sym = symtab + sym_index;
41e92641
NC
14997
14998 /* If the reloc has a symbol associated with it,
55f25fc3
L
14999 make sure that it is of an appropriate type.
15000
15001 Relocations against symbols without type can happen.
15002 Gcc -feliminate-dwarf2-dups may generate symbols
15003 without type for debug info.
15004
15005 Icc generates relocations against function symbols
15006 instead of local labels.
15007
15008 Relocations against object symbols can happen, eg when
15009 referencing a global array. For an example of this see
15010 the _clz.o binary in libgcc.a. */
aca88567 15011 if (sym != symtab
b8871f35 15012 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15013 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15014 {
d3a49aa8 15015 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
15016 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15017 printable_section_name (filedata, relsec),
d3a49aa8 15018 (long int)(rp - relocs));
aca88567 15019 continue;
5b18a4bc 15020 }
252b5132 15021
4dc3c23d
AM
15022 addend = 0;
15023 if (is_rela)
15024 addend += rp->r_addend;
c47320c3
AM
15025 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15026 partial_inplace. */
4dc3c23d 15027 if (!is_rela
dda8d76d 15028 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15029 && reloc_type == 1)
dda8d76d
NC
15030 || ((filedata->file_header.e_machine == EM_PJ
15031 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15032 && reloc_type == 1)
dda8d76d
NC
15033 || ((filedata->file_header.e_machine == EM_D30V
15034 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15035 && reloc_type == 12)
15036 || reloc_inplace)
39e07931
AS
15037 {
15038 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15039 addend += byte_get (rloc, reloc_size) & 0x3f;
15040 else
15041 addend += byte_get (rloc, reloc_size);
15042 }
cb8f3167 15043
dda8d76d
NC
15044 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15045 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15046 {
15047 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15048 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15049 addend -= 8;
91d6fa6a 15050 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15051 reloc_size);
15052 }
39e07931
AS
15053 else if (is_6bit_abs_reloc (filedata, reloc_type)
15054 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
15055 {
15056 if (reloc_subtract)
15057 addend -= sym->st_value;
15058 else
15059 addend += sym->st_value;
15060 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15061 byte_put (rloc, addend, reloc_size);
15062 }
03336641
JW
15063 else if (reloc_subtract)
15064 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15065 else
91d6fa6a 15066 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15067 }
252b5132 15068
5b18a4bc 15069 free (symtab);
f84ce13b
NC
15070 /* Let the target specific reloc processing code know that
15071 we have finished with these relocs. */
dda8d76d 15072 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15073
15074 if (relocs_return)
15075 {
15076 * (Elf_Internal_Rela **) relocs_return = relocs;
15077 * num_relocs_return = num_relocs;
15078 }
15079 else
15080 free (relocs);
15081
5b18a4bc
NC
15082 break;
15083 }
32ec8896 15084
015dc7e1 15085 return true;
5b18a4bc 15086}
103f02d3 15087
cf13d699 15088#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15089static bool
dda8d76d 15090disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15091{
dda8d76d 15092 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15093
74e1a04b 15094 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15095
015dc7e1 15096 return true;
cf13d699
NC
15097}
15098#endif
15099
15100/* Reads in the contents of SECTION from FILE, returning a pointer
15101 to a malloc'ed buffer or NULL if something went wrong. */
15102
15103static char *
dda8d76d 15104get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15105{
be7d229a 15106 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15107
15108 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15109 {
c6b78c96 15110 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15111 printable_section_name (filedata, section));
cf13d699
NC
15112 return NULL;
15113 }
15114
dda8d76d 15115 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15116 _("section contents"));
cf13d699
NC
15117}
15118
0e602686
NC
15119/* Uncompresses a section that was compressed using zlib, in place. */
15120
015dc7e1 15121static bool
dda8d76d
NC
15122uncompress_section_contents (unsigned char ** buffer,
15123 dwarf_size_type uncompressed_size,
15124 dwarf_size_type * size)
0e602686
NC
15125{
15126 dwarf_size_type compressed_size = *size;
15127 unsigned char * compressed_buffer = *buffer;
15128 unsigned char * uncompressed_buffer;
15129 z_stream strm;
15130 int rc;
15131
15132 /* It is possible the section consists of several compressed
15133 buffers concatenated together, so we uncompress in a loop. */
15134 /* PR 18313: The state field in the z_stream structure is supposed
15135 to be invisible to the user (ie us), but some compilers will
15136 still complain about it being used without initialisation. So
15137 we first zero the entire z_stream structure and then set the fields
15138 that we need. */
15139 memset (& strm, 0, sizeof strm);
15140 strm.avail_in = compressed_size;
15141 strm.next_in = (Bytef *) compressed_buffer;
15142 strm.avail_out = uncompressed_size;
15143 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15144
15145 rc = inflateInit (& strm);
15146 while (strm.avail_in > 0)
15147 {
15148 if (rc != Z_OK)
3624a6c1 15149 break;
0e602686
NC
15150 strm.next_out = ((Bytef *) uncompressed_buffer
15151 + (uncompressed_size - strm.avail_out));
15152 rc = inflate (&strm, Z_FINISH);
15153 if (rc != Z_STREAM_END)
3624a6c1 15154 break;
0e602686
NC
15155 rc = inflateReset (& strm);
15156 }
ad92f33d
AM
15157 if (inflateEnd (& strm) != Z_OK
15158 || rc != Z_OK
0e602686
NC
15159 || strm.avail_out != 0)
15160 goto fail;
15161
15162 *buffer = uncompressed_buffer;
15163 *size = uncompressed_size;
015dc7e1 15164 return true;
0e602686
NC
15165
15166 fail:
15167 free (uncompressed_buffer);
15168 /* Indicate decompression failure. */
15169 *buffer = NULL;
015dc7e1 15170 return false;
0e602686 15171}
dd24e3da 15172
015dc7e1 15173static bool
dda8d76d 15174dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15175{
015dc7e1 15176 Elf_Internal_Shdr *relsec;
be7d229a 15177 uint64_t num_bytes;
015dc7e1
AM
15178 unsigned char *data;
15179 unsigned char *end;
15180 unsigned char *real_start;
15181 unsigned char *start;
15182 bool some_strings_shown;
cf13d699 15183
dda8d76d 15184 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15185 if (start == NULL)
c6b78c96 15186 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15187 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15188
0e602686 15189 num_bytes = section->sh_size;
cf13d699 15190
835f2fae
NC
15191 if (filedata->is_separate)
15192 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15193 printable_section_name (filedata, section),
15194 filedata->file_name);
15195 else
15196 printf (_("\nString dump of section '%s':\n"),
15197 printable_section_name (filedata, section));
cf13d699 15198
0e602686
NC
15199 if (decompress_dumps)
15200 {
15201 dwarf_size_type new_size = num_bytes;
15202 dwarf_size_type uncompressed_size = 0;
15203
15204 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15205 {
15206 Elf_Internal_Chdr chdr;
15207 unsigned int compression_header_size
ebdf1ebf
NC
15208 = get_compression_header (& chdr, (unsigned char *) start,
15209 num_bytes);
5844b465
NC
15210 if (compression_header_size == 0)
15211 /* An error message will have already been generated
15212 by get_compression_header. */
15213 goto error_out;
0e602686 15214
813dabb9 15215 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15216 {
813dabb9 15217 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15218 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15219 goto error_out;
813dabb9 15220 }
813dabb9
L
15221 uncompressed_size = chdr.ch_size;
15222 start += compression_header_size;
15223 new_size -= compression_header_size;
0e602686
NC
15224 }
15225 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15226 {
15227 /* Read the zlib header. In this case, it should be "ZLIB"
15228 followed by the uncompressed section size, 8 bytes in
15229 big-endian order. */
15230 uncompressed_size = start[4]; uncompressed_size <<= 8;
15231 uncompressed_size += start[5]; uncompressed_size <<= 8;
15232 uncompressed_size += start[6]; uncompressed_size <<= 8;
15233 uncompressed_size += start[7]; uncompressed_size <<= 8;
15234 uncompressed_size += start[8]; uncompressed_size <<= 8;
15235 uncompressed_size += start[9]; uncompressed_size <<= 8;
15236 uncompressed_size += start[10]; uncompressed_size <<= 8;
15237 uncompressed_size += start[11];
15238 start += 12;
15239 new_size -= 12;
15240 }
15241
1835f746
NC
15242 if (uncompressed_size)
15243 {
15244 if (uncompress_section_contents (& start,
15245 uncompressed_size, & new_size))
15246 num_bytes = new_size;
15247 else
15248 {
15249 error (_("Unable to decompress section %s\n"),
dda8d76d 15250 printable_section_name (filedata, section));
f761cb13 15251 goto error_out;
1835f746
NC
15252 }
15253 }
bc303e5d
NC
15254 else
15255 start = real_start;
0e602686 15256 }
fd8008d8 15257
cf13d699
NC
15258 /* If the section being dumped has relocations against it the user might
15259 be expecting these relocations to have been applied. Check for this
15260 case and issue a warning message in order to avoid confusion.
15261 FIXME: Maybe we ought to have an option that dumps a section with
15262 relocs applied ? */
dda8d76d
NC
15263 for (relsec = filedata->section_headers;
15264 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15265 ++relsec)
15266 {
15267 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15268 || relsec->sh_info >= filedata->file_header.e_shnum
15269 || filedata->section_headers + relsec->sh_info != section
cf13d699 15270 || relsec->sh_size == 0
dda8d76d 15271 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15272 continue;
15273
15274 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15275 break;
15276 }
15277
cf13d699
NC
15278 data = start;
15279 end = start + num_bytes;
015dc7e1 15280 some_strings_shown = false;
cf13d699 15281
ba3265d0
NC
15282#ifdef HAVE_MBSTATE_T
15283 mbstate_t state;
15284 /* Initialise the multibyte conversion state. */
15285 memset (& state, 0, sizeof (state));
15286#endif
15287
015dc7e1 15288 bool continuing = false;
ba3265d0 15289
cf13d699
NC
15290 while (data < end)
15291 {
15292 while (!ISPRINT (* data))
15293 if (++ data >= end)
15294 break;
15295
15296 if (data < end)
15297 {
071436c6
NC
15298 size_t maxlen = end - data;
15299
ba3265d0
NC
15300 if (continuing)
15301 {
15302 printf (" ");
015dc7e1 15303 continuing = false;
ba3265d0
NC
15304 }
15305 else
15306 {
d1ce973e 15307 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15308 }
15309
4082ef84
NC
15310 if (maxlen > 0)
15311 {
f3da8a96 15312 char c = 0;
ba3265d0
NC
15313
15314 while (maxlen)
15315 {
15316 c = *data++;
15317
15318 if (c == 0)
15319 break;
15320
15321 /* PR 25543: Treat new-lines as string-ending characters. */
15322 if (c == '\n')
15323 {
15324 printf ("\\n\n");
15325 if (*data != 0)
015dc7e1 15326 continuing = true;
ba3265d0
NC
15327 break;
15328 }
15329
15330 /* Do not print control characters directly as they can affect terminal
15331 settings. Such characters usually appear in the names generated
15332 by the assembler for local labels. */
15333 if (ISCNTRL (c))
15334 {
15335 printf ("^%c", c + 0x40);
15336 }
15337 else if (ISPRINT (c))
15338 {
15339 putchar (c);
15340 }
15341 else
15342 {
15343 size_t n;
15344#ifdef HAVE_MBSTATE_T
15345 wchar_t w;
15346#endif
15347 /* Let printf do the hard work of displaying multibyte characters. */
15348 printf ("%.1s", data - 1);
15349#ifdef HAVE_MBSTATE_T
15350 /* Try to find out how many bytes made up the character that was
15351 just printed. Advance the symbol pointer past the bytes that
15352 were displayed. */
15353 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15354#else
15355 n = 1;
15356#endif
15357 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15358 data += (n - 1);
15359 }
15360 }
15361
15362 if (c != '\n')
15363 putchar ('\n');
4082ef84
NC
15364 }
15365 else
15366 {
15367 printf (_("<corrupt>\n"));
15368 data = end;
15369 }
015dc7e1 15370 some_strings_shown = true;
cf13d699
NC
15371 }
15372 }
15373
15374 if (! some_strings_shown)
15375 printf (_(" No strings found in this section."));
15376
0e602686 15377 free (real_start);
cf13d699
NC
15378
15379 putchar ('\n');
015dc7e1 15380 return true;
f761cb13
AM
15381
15382error_out:
15383 free (real_start);
015dc7e1 15384 return false;
cf13d699
NC
15385}
15386
015dc7e1
AM
15387static bool
15388dump_section_as_bytes (Elf_Internal_Shdr *section,
15389 Filedata *filedata,
15390 bool relocate)
cf13d699 15391{
be7d229a
AM
15392 Elf_Internal_Shdr *relsec;
15393 size_t bytes;
15394 uint64_t section_size;
625d49fc 15395 uint64_t addr;
be7d229a
AM
15396 unsigned char *data;
15397 unsigned char *real_start;
15398 unsigned char *start;
0e602686 15399
dda8d76d 15400 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15401 if (start == NULL)
c6b78c96 15402 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15403 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15404
0e602686 15405 section_size = section->sh_size;
cf13d699 15406
835f2fae
NC
15407 if (filedata->is_separate)
15408 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15409 printable_section_name (filedata, section),
15410 filedata->file_name);
15411 else
15412 printf (_("\nHex dump of section '%s':\n"),
15413 printable_section_name (filedata, section));
cf13d699 15414
0e602686
NC
15415 if (decompress_dumps)
15416 {
15417 dwarf_size_type new_size = section_size;
15418 dwarf_size_type uncompressed_size = 0;
15419
15420 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15421 {
15422 Elf_Internal_Chdr chdr;
15423 unsigned int compression_header_size
ebdf1ebf 15424 = get_compression_header (& chdr, start, section_size);
0e602686 15425
5844b465
NC
15426 if (compression_header_size == 0)
15427 /* An error message will have already been generated
15428 by get_compression_header. */
15429 goto error_out;
15430
813dabb9 15431 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15432 {
813dabb9 15433 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15434 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15435 goto error_out;
0e602686 15436 }
813dabb9
L
15437 uncompressed_size = chdr.ch_size;
15438 start += compression_header_size;
15439 new_size -= compression_header_size;
0e602686
NC
15440 }
15441 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15442 {
15443 /* Read the zlib header. In this case, it should be "ZLIB"
15444 followed by the uncompressed section size, 8 bytes in
15445 big-endian order. */
15446 uncompressed_size = start[4]; uncompressed_size <<= 8;
15447 uncompressed_size += start[5]; uncompressed_size <<= 8;
15448 uncompressed_size += start[6]; uncompressed_size <<= 8;
15449 uncompressed_size += start[7]; uncompressed_size <<= 8;
15450 uncompressed_size += start[8]; uncompressed_size <<= 8;
15451 uncompressed_size += start[9]; uncompressed_size <<= 8;
15452 uncompressed_size += start[10]; uncompressed_size <<= 8;
15453 uncompressed_size += start[11];
15454 start += 12;
15455 new_size -= 12;
15456 }
15457
f055032e
NC
15458 if (uncompressed_size)
15459 {
15460 if (uncompress_section_contents (& start, uncompressed_size,
15461 & new_size))
bc303e5d
NC
15462 {
15463 section_size = new_size;
15464 }
f055032e
NC
15465 else
15466 {
15467 error (_("Unable to decompress section %s\n"),
dda8d76d 15468 printable_section_name (filedata, section));
bc303e5d 15469 /* FIXME: Print the section anyway ? */
f761cb13 15470 goto error_out;
f055032e
NC
15471 }
15472 }
bc303e5d
NC
15473 else
15474 start = real_start;
0e602686 15475 }
14ae95f2 15476
cf13d699
NC
15477 if (relocate)
15478 {
dda8d76d 15479 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15480 goto error_out;
cf13d699
NC
15481 }
15482 else
15483 {
15484 /* If the section being dumped has relocations against it the user might
15485 be expecting these relocations to have been applied. Check for this
15486 case and issue a warning message in order to avoid confusion.
15487 FIXME: Maybe we ought to have an option that dumps a section with
15488 relocs applied ? */
dda8d76d
NC
15489 for (relsec = filedata->section_headers;
15490 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15491 ++relsec)
15492 {
15493 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15494 || relsec->sh_info >= filedata->file_header.e_shnum
15495 || filedata->section_headers + relsec->sh_info != section
cf13d699 15496 || relsec->sh_size == 0
dda8d76d 15497 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15498 continue;
15499
15500 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15501 break;
15502 }
15503 }
15504
15505 addr = section->sh_addr;
0e602686 15506 bytes = section_size;
cf13d699
NC
15507 data = start;
15508
15509 while (bytes)
15510 {
15511 int j;
15512 int k;
15513 int lbytes;
15514
15515 lbytes = (bytes > 16 ? 16 : bytes);
15516
15517 printf (" 0x%8.8lx ", (unsigned long) addr);
15518
15519 for (j = 0; j < 16; j++)
15520 {
15521 if (j < lbytes)
15522 printf ("%2.2x", data[j]);
15523 else
15524 printf (" ");
15525
15526 if ((j & 3) == 3)
15527 printf (" ");
15528 }
15529
15530 for (j = 0; j < lbytes; j++)
15531 {
15532 k = data[j];
15533 if (k >= ' ' && k < 0x7f)
15534 printf ("%c", k);
15535 else
15536 printf (".");
15537 }
15538
15539 putchar ('\n');
15540
15541 data += lbytes;
15542 addr += lbytes;
15543 bytes -= lbytes;
15544 }
15545
0e602686 15546 free (real_start);
cf13d699
NC
15547
15548 putchar ('\n');
015dc7e1 15549 return true;
f761cb13
AM
15550
15551 error_out:
15552 free (real_start);
015dc7e1 15553 return false;
cf13d699
NC
15554}
15555
094e34f2 15556#ifdef ENABLE_LIBCTF
7d9813f1
NA
15557static ctf_sect_t *
15558shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15559{
84714f86 15560 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15561 buf->cts_size = shdr->sh_size;
15562 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15563
15564 return buf;
15565}
15566
15567/* Formatting callback function passed to ctf_dump. Returns either the pointer
15568 it is passed, or a pointer to newly-allocated storage, in which case
15569 dump_ctf() will free it when it no longer needs it. */
15570
2f6ecaed
NA
15571static char *
15572dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15573 char *s, void *arg)
7d9813f1 15574{
3e50a591 15575 const char *blanks = arg;
7d9813f1
NA
15576 char *new_s;
15577
3e50a591 15578 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15579 return s;
15580 return new_s;
15581}
15582
926c9e76
NA
15583/* Dump CTF errors/warnings. */
15584static void
139633c3 15585dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15586{
15587 ctf_next_t *it = NULL;
15588 char *errtext;
15589 int is_warning;
15590 int err;
15591
15592 /* Dump accumulated errors and warnings. */
15593 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15594 {
5e9b84f7 15595 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15596 errtext);
15597 free (errtext);
15598 }
15599 if (err != ECTF_NEXT_END)
15600 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15601}
15602
2f6ecaed
NA
15603/* Dump one CTF archive member. */
15604
80b56fad
NA
15605static void
15606dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15607 size_t member)
2f6ecaed 15608{
2f6ecaed
NA
15609 const char *things[] = {"Header", "Labels", "Data objects",
15610 "Function objects", "Variables", "Types", "Strings",
15611 ""};
15612 const char **thing;
15613 size_t i;
15614
80b56fad
NA
15615 /* Don't print out the name of the default-named archive member if it appears
15616 first in the list. The name .ctf appears everywhere, even for things that
15617 aren't really archives, so printing it out is liable to be confusing; also,
15618 the common case by far is for only one archive member to exist, and hiding
15619 it in that case seems worthwhile. */
2f6ecaed 15620
80b56fad
NA
15621 if (strcmp (name, ".ctf") != 0 || member != 0)
15622 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15623
80b56fad
NA
15624 if (ctf_parent_name (ctf) != NULL)
15625 ctf_import (ctf, parent);
2f6ecaed
NA
15626
15627 for (i = 0, thing = things; *thing[0]; thing++, i++)
15628 {
15629 ctf_dump_state_t *s = NULL;
15630 char *item;
15631
15632 printf ("\n %s:\n", *thing);
15633 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15634 (void *) " ")) != NULL)
15635 {
15636 printf ("%s\n", item);
15637 free (item);
15638 }
15639
15640 if (ctf_errno (ctf))
15641 {
15642 error (_("Iteration failed: %s, %s\n"), *thing,
15643 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15644 break;
2f6ecaed
NA
15645 }
15646 }
8b37e7b6 15647
926c9e76 15648 dump_ctf_errs (ctf);
2f6ecaed
NA
15649}
15650
015dc7e1 15651static bool
7d9813f1
NA
15652dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15653{
7d9813f1
NA
15654 Elf_Internal_Shdr * symtab_sec = NULL;
15655 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15656 void * data = NULL;
15657 void * symdata = NULL;
15658 void * strdata = NULL;
80b56fad 15659 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15660 ctf_sect_t * symsectp = NULL;
15661 ctf_sect_t * strsectp = NULL;
2f6ecaed 15662 ctf_archive_t * ctfa = NULL;
139633c3 15663 ctf_dict_t * parent = NULL;
80b56fad 15664 ctf_dict_t * fp;
7d9813f1 15665
80b56fad
NA
15666 ctf_next_t *i = NULL;
15667 const char *name;
15668 size_t member = 0;
7d9813f1 15669 int err;
015dc7e1 15670 bool ret = false;
7d9813f1
NA
15671
15672 shdr_to_ctf_sect (&ctfsect, section, filedata);
15673 data = get_section_contents (section, filedata);
15674 ctfsect.cts_data = data;
15675
616febde 15676 if (!dump_ctf_symtab_name)
3d16b64e 15677 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15678
15679 if (!dump_ctf_strtab_name)
3d16b64e 15680 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15681
15682 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15683 {
15684 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15685 {
15686 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15687 goto fail;
15688 }
15689 if ((symdata = (void *) get_data (NULL, filedata,
15690 symtab_sec->sh_offset, 1,
15691 symtab_sec->sh_size,
15692 _("symbols"))) == NULL)
15693 goto fail;
15694 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15695 symsect.cts_data = symdata;
15696 }
835f2fae 15697
df16e041 15698 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15699 {
15700 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15701 {
15702 error (_("No string table section named %s\n"),
15703 dump_ctf_strtab_name);
15704 goto fail;
15705 }
15706 if ((strdata = (void *) get_data (NULL, filedata,
15707 strtab_sec->sh_offset, 1,
15708 strtab_sec->sh_size,
15709 _("strings"))) == NULL)
15710 goto fail;
15711 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15712 strsect.cts_data = strdata;
15713 }
835f2fae 15714
2f6ecaed
NA
15715 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15716 libctf papers over the difference, so we can pretend it is always an
80b56fad 15717 archive. */
7d9813f1 15718
2f6ecaed 15719 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15720 {
926c9e76 15721 dump_ctf_errs (NULL);
7d9813f1
NA
15722 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15723 goto fail;
15724 }
15725
96c61be5
NA
15726 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15727 != ELFDATA2MSB);
15728
80b56fad
NA
15729 /* Preload the parent dict, since it will need to be imported into every
15730 child in turn. */
15731 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15732 {
926c9e76 15733 dump_ctf_errs (NULL);
2f6ecaed
NA
15734 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15735 goto fail;
7d9813f1
NA
15736 }
15737
015dc7e1 15738 ret = true;
7d9813f1 15739
835f2fae
NC
15740 if (filedata->is_separate)
15741 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15742 printable_section_name (filedata, section),
15743 filedata->file_name);
15744 else
15745 printf (_("\nDump of CTF section '%s':\n"),
15746 printable_section_name (filedata, section));
7d9813f1 15747
80b56fad
NA
15748 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15749 dump_ctf_archive_member (fp, name, parent, member++);
15750 if (err != ECTF_NEXT_END)
15751 {
15752 dump_ctf_errs (NULL);
15753 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15754 ret = false;
15755 }
7d9813f1
NA
15756
15757 fail:
139633c3 15758 ctf_dict_close (parent);
2f6ecaed 15759 ctf_close (ctfa);
7d9813f1
NA
15760 free (data);
15761 free (symdata);
15762 free (strdata);
15763 return ret;
15764}
094e34f2 15765#endif
7d9813f1 15766
015dc7e1 15767static bool
dda8d76d
NC
15768load_specific_debug_section (enum dwarf_section_display_enum debug,
15769 const Elf_Internal_Shdr * sec,
15770 void * data)
1007acb3 15771{
2cf0635d 15772 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15773 char buf [64];
dda8d76d 15774 Filedata * filedata = (Filedata *) data;
9abca702 15775
19e6b90e 15776 if (section->start != NULL)
dda8d76d
NC
15777 {
15778 /* If it is already loaded, do nothing. */
15779 if (streq (section->filename, filedata->file_name))
015dc7e1 15780 return true;
dda8d76d
NC
15781 free (section->start);
15782 }
1007acb3 15783
19e6b90e
L
15784 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15785 section->address = sec->sh_addr;
dda8d76d
NC
15786 section->filename = filedata->file_name;
15787 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15788 sec->sh_offset, 1,
15789 sec->sh_size, buf);
59245841
NC
15790 if (section->start == NULL)
15791 section->size = 0;
15792 else
15793 {
77115a4a
L
15794 unsigned char *start = section->start;
15795 dwarf_size_type size = sec->sh_size;
dab394de 15796 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15797
15798 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15799 {
15800 Elf_Internal_Chdr chdr;
d8024a91
NC
15801 unsigned int compression_header_size;
15802
f53be977
L
15803 if (size < (is_32bit_elf
15804 ? sizeof (Elf32_External_Chdr)
15805 : sizeof (Elf64_External_Chdr)))
d8024a91 15806 {
55be8fd0 15807 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15808 section->name);
015dc7e1 15809 return false;
d8024a91
NC
15810 }
15811
ebdf1ebf 15812 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15813 if (compression_header_size == 0)
15814 /* An error message will have already been generated
15815 by get_compression_header. */
015dc7e1 15816 return false;
d8024a91 15817
813dabb9
L
15818 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15819 {
15820 warn (_("section '%s' has unsupported compress type: %d\n"),
15821 section->name, chdr.ch_type);
015dc7e1 15822 return false;
813dabb9 15823 }
dab394de 15824 uncompressed_size = chdr.ch_size;
77115a4a
L
15825 start += compression_header_size;
15826 size -= compression_header_size;
15827 }
dab394de
L
15828 else if (size > 12 && streq ((char *) start, "ZLIB"))
15829 {
15830 /* Read the zlib header. In this case, it should be "ZLIB"
15831 followed by the uncompressed section size, 8 bytes in
15832 big-endian order. */
15833 uncompressed_size = start[4]; uncompressed_size <<= 8;
15834 uncompressed_size += start[5]; uncompressed_size <<= 8;
15835 uncompressed_size += start[6]; uncompressed_size <<= 8;
15836 uncompressed_size += start[7]; uncompressed_size <<= 8;
15837 uncompressed_size += start[8]; uncompressed_size <<= 8;
15838 uncompressed_size += start[9]; uncompressed_size <<= 8;
15839 uncompressed_size += start[10]; uncompressed_size <<= 8;
15840 uncompressed_size += start[11];
15841 start += 12;
15842 size -= 12;
15843 }
15844
1835f746 15845 if (uncompressed_size)
77115a4a 15846 {
1835f746
NC
15847 if (uncompress_section_contents (&start, uncompressed_size,
15848 &size))
15849 {
15850 /* Free the compressed buffer, update the section buffer
15851 and the section size if uncompress is successful. */
15852 free (section->start);
15853 section->start = start;
15854 }
15855 else
15856 {
15857 error (_("Unable to decompress section %s\n"),
dda8d76d 15858 printable_section_name (filedata, sec));
015dc7e1 15859 return false;
1835f746 15860 }
77115a4a 15861 }
bc303e5d 15862
77115a4a 15863 section->size = size;
59245841 15864 }
4a114e3e 15865
1b315056 15866 if (section->start == NULL)
015dc7e1 15867 return false;
1b315056 15868
19e6b90e 15869 if (debug_displays [debug].relocate)
32ec8896 15870 {
dda8d76d 15871 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15872 & section->reloc_info, & section->num_relocs))
015dc7e1 15873 return false;
32ec8896 15874 }
d1c4b12b
NC
15875 else
15876 {
15877 section->reloc_info = NULL;
15878 section->num_relocs = 0;
15879 }
1007acb3 15880
015dc7e1 15881 return true;
1007acb3
L
15882}
15883
301a9420
AM
15884#if HAVE_LIBDEBUGINFOD
15885/* Return a hex string representation of the build-id. */
15886unsigned char *
15887get_build_id (void * data)
15888{
ca0e11aa 15889 Filedata * filedata = (Filedata *) data;
301a9420
AM
15890 Elf_Internal_Shdr * shdr;
15891 unsigned long i;
15892
55be8fd0
NC
15893 /* Iterate through notes to find note.gnu.build-id.
15894 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15895 for (i = 0, shdr = filedata->section_headers;
15896 i < filedata->file_header.e_shnum && shdr != NULL;
15897 i++, shdr++)
15898 {
15899 if (shdr->sh_type != SHT_NOTE)
15900 continue;
15901
15902 char * next;
15903 char * end;
15904 size_t data_remaining;
15905 size_t min_notesz;
15906 Elf_External_Note * enote;
15907 Elf_Internal_Note inote;
15908
625d49fc
AM
15909 uint64_t offset = shdr->sh_offset;
15910 uint64_t align = shdr->sh_addralign;
15911 uint64_t length = shdr->sh_size;
301a9420
AM
15912
15913 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15914 if (enote == NULL)
15915 continue;
15916
15917 if (align < 4)
15918 align = 4;
15919 else if (align != 4 && align != 8)
f761cb13
AM
15920 {
15921 free (enote);
15922 continue;
15923 }
301a9420
AM
15924
15925 end = (char *) enote + length;
15926 data_remaining = end - (char *) enote;
15927
15928 if (!is_ia64_vms (filedata))
15929 {
15930 min_notesz = offsetof (Elf_External_Note, name);
15931 if (data_remaining < min_notesz)
15932 {
55be8fd0
NC
15933 warn (_("\
15934malformed note encountered in section %s whilst scanning for build-id note\n"),
15935 printable_section_name (filedata, shdr));
f761cb13 15936 free (enote);
55be8fd0 15937 continue;
301a9420
AM
15938 }
15939 data_remaining -= min_notesz;
15940
15941 inote.type = BYTE_GET (enote->type);
15942 inote.namesz = BYTE_GET (enote->namesz);
15943 inote.namedata = enote->name;
15944 inote.descsz = BYTE_GET (enote->descsz);
15945 inote.descdata = ((char *) enote
15946 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15947 inote.descpos = offset + (inote.descdata - (char *) enote);
15948 next = ((char *) enote
15949 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15950 }
15951 else
15952 {
15953 Elf64_External_VMS_Note *vms_enote;
15954
15955 /* PR binutils/15191
15956 Make sure that there is enough data to read. */
15957 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15958 if (data_remaining < min_notesz)
15959 {
55be8fd0
NC
15960 warn (_("\
15961malformed note encountered in section %s whilst scanning for build-id note\n"),
15962 printable_section_name (filedata, shdr));
f761cb13 15963 free (enote);
55be8fd0 15964 continue;
301a9420
AM
15965 }
15966 data_remaining -= min_notesz;
15967
15968 vms_enote = (Elf64_External_VMS_Note *) enote;
15969 inote.type = BYTE_GET (vms_enote->type);
15970 inote.namesz = BYTE_GET (vms_enote->namesz);
15971 inote.namedata = vms_enote->name;
15972 inote.descsz = BYTE_GET (vms_enote->descsz);
15973 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15974 inote.descpos = offset + (inote.descdata - (char *) enote);
15975 next = inote.descdata + align_power (inote.descsz, 3);
15976 }
15977
15978 /* Skip malformed notes. */
15979 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15980 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15981 || (size_t) (next - inote.descdata) < inote.descsz
15982 || ((size_t) (next - inote.descdata)
15983 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15984 {
55be8fd0
NC
15985 warn (_("\
15986malformed note encountered in section %s whilst scanning for build-id note\n"),
15987 printable_section_name (filedata, shdr));
f761cb13 15988 free (enote);
301a9420
AM
15989 continue;
15990 }
15991
15992 /* Check if this is the build-id note. If so then convert the build-id
15993 bytes to a hex string. */
15994 if (inote.namesz > 0
24d127aa 15995 && startswith (inote.namedata, "GNU")
301a9420
AM
15996 && inote.type == NT_GNU_BUILD_ID)
15997 {
15998 unsigned long j;
15999 char * build_id;
16000
16001 build_id = malloc (inote.descsz * 2 + 1);
16002 if (build_id == NULL)
f761cb13
AM
16003 {
16004 free (enote);
16005 return NULL;
16006 }
301a9420
AM
16007
16008 for (j = 0; j < inote.descsz; ++j)
16009 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16010 build_id[inote.descsz * 2] = '\0';
f761cb13 16011 free (enote);
301a9420 16012
55be8fd0 16013 return (unsigned char *) build_id;
301a9420 16014 }
f761cb13 16015 free (enote);
301a9420
AM
16016 }
16017
16018 return NULL;
16019}
16020#endif /* HAVE_LIBDEBUGINFOD */
16021
657d0d47
CC
16022/* If this is not NULL, load_debug_section will only look for sections
16023 within the list of sections given here. */
32ec8896 16024static unsigned int * section_subset = NULL;
657d0d47 16025
015dc7e1 16026bool
dda8d76d 16027load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16028{
2cf0635d
NC
16029 struct dwarf_section * section = &debug_displays [debug].section;
16030 Elf_Internal_Shdr * sec;
dda8d76d
NC
16031 Filedata * filedata = (Filedata *) data;
16032
e1dbfc17
L
16033 if (!dump_any_debugging)
16034 return false;
16035
f425ec66
NC
16036 /* Without section headers we cannot find any sections. */
16037 if (filedata->section_headers == NULL)
015dc7e1 16038 return false;
f425ec66 16039
9c1ce108
AM
16040 if (filedata->string_table == NULL
16041 && filedata->file_header.e_shstrndx != SHN_UNDEF
16042 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16043 {
16044 Elf_Internal_Shdr * strs;
16045
16046 /* Read in the string table, so that we have section names to scan. */
16047 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16048
4dff97b2 16049 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16050 {
9c1ce108
AM
16051 filedata->string_table
16052 = (char *) get_data (NULL, filedata, strs->sh_offset,
16053 1, strs->sh_size, _("string table"));
dda8d76d 16054
9c1ce108
AM
16055 filedata->string_table_length
16056 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16057 }
16058 }
d966045b
DJ
16059
16060 /* Locate the debug section. */
dda8d76d 16061 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16062 if (sec != NULL)
16063 section->name = section->uncompressed_name;
16064 else
16065 {
dda8d76d 16066 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16067 if (sec != NULL)
16068 section->name = section->compressed_name;
16069 }
16070 if (sec == NULL)
015dc7e1 16071 return false;
d966045b 16072
657d0d47
CC
16073 /* If we're loading from a subset of sections, and we've loaded
16074 a section matching this name before, it's likely that it's a
16075 different one. */
16076 if (section_subset != NULL)
16077 free_debug_section (debug);
16078
dda8d76d 16079 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16080}
16081
19e6b90e
L
16082void
16083free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16084{
2cf0635d 16085 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16086
19e6b90e
L
16087 if (section->start == NULL)
16088 return;
1007acb3 16089
19e6b90e
L
16090 free ((char *) section->start);
16091 section->start = NULL;
16092 section->address = 0;
16093 section->size = 0;
a788aedd 16094
9db70fc3
AM
16095 free (section->reloc_info);
16096 section->reloc_info = NULL;
16097 section->num_relocs = 0;
1007acb3
L
16098}
16099
015dc7e1 16100static bool
dda8d76d 16101display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16102{
84714f86
AM
16103 const char *name = (section_name_valid (filedata, section)
16104 ? section_name (filedata, section) : "");
16105 const char *print_name = printable_section_name (filedata, section);
be7d229a 16106 uint64_t length;
015dc7e1 16107 bool result = true;
3f5e193b 16108 int i;
1007acb3 16109
19e6b90e
L
16110 length = section->sh_size;
16111 if (length == 0)
1007acb3 16112 {
74e1a04b 16113 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16114 return true;
1007acb3 16115 }
5dff79d8
NC
16116 if (section->sh_type == SHT_NOBITS)
16117 {
16118 /* There is no point in dumping the contents of a debugging section
16119 which has the NOBITS type - the bits in the file will be random.
16120 This can happen when a file containing a .eh_frame section is
16121 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16122 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16123 print_name);
015dc7e1 16124 return false;
5dff79d8 16125 }
1007acb3 16126
24d127aa 16127 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16128 name = ".debug_info";
1007acb3 16129
19e6b90e
L
16130 /* See if we know how to display the contents of this section. */
16131 for (i = 0; i < max; i++)
d85bf2ba
NC
16132 {
16133 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16134 struct dwarf_section_display * display = debug_displays + i;
16135 struct dwarf_section * sec = & display->section;
d966045b 16136
d85bf2ba 16137 if (streq (sec->uncompressed_name, name)
24d127aa 16138 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16139 || streq (sec->compressed_name, name))
16140 {
015dc7e1 16141 bool secondary = (section != find_section (filedata, name));
1007acb3 16142
d85bf2ba
NC
16143 if (secondary)
16144 free_debug_section (id);
dda8d76d 16145
24d127aa 16146 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16147 sec->name = name;
16148 else if (streq (sec->uncompressed_name, name))
16149 sec->name = sec->uncompressed_name;
16150 else
16151 sec->name = sec->compressed_name;
657d0d47 16152
d85bf2ba
NC
16153 if (load_specific_debug_section (id, section, filedata))
16154 {
16155 /* If this debug section is part of a CU/TU set in a .dwp file,
16156 restrict load_debug_section to the sections in that set. */
16157 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16158
d85bf2ba 16159 result &= display->display (sec, filedata);
657d0d47 16160
d85bf2ba 16161 section_subset = NULL;
1007acb3 16162
44266f36 16163 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16164 free_debug_section (id);
16165 }
16166 break;
16167 }
16168 }
1007acb3 16169
19e6b90e 16170 if (i == max)
1007acb3 16171 {
74e1a04b 16172 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16173 result = false;
1007acb3
L
16174 }
16175
19e6b90e 16176 return result;
5b18a4bc 16177}
103f02d3 16178
aef1f6d0
DJ
16179/* Set DUMP_SECTS for all sections where dumps were requested
16180 based on section name. */
16181
16182static void
dda8d76d 16183initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16184{
2cf0635d 16185 struct dump_list_entry * cur;
aef1f6d0
DJ
16186
16187 for (cur = dump_sects_byname; cur; cur = cur->next)
16188 {
16189 unsigned int i;
015dc7e1 16190 bool any = false;
aef1f6d0 16191
dda8d76d 16192 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16193 if (section_name_valid (filedata, filedata->section_headers + i)
16194 && streq (section_name (filedata, filedata->section_headers + i),
16195 cur->name))
aef1f6d0 16196 {
6431e409 16197 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16198 any = true;
aef1f6d0
DJ
16199 }
16200
835f2fae
NC
16201 if (!any && !filedata->is_separate)
16202 warn (_("Section '%s' was not dumped because it does not exist\n"),
16203 cur->name);
aef1f6d0
DJ
16204 }
16205}
16206
015dc7e1 16207static bool
dda8d76d 16208process_section_contents (Filedata * filedata)
5b18a4bc 16209{
2cf0635d 16210 Elf_Internal_Shdr * section;
19e6b90e 16211 unsigned int i;
015dc7e1 16212 bool res = true;
103f02d3 16213
19e6b90e 16214 if (! do_dump)
015dc7e1 16215 return true;
103f02d3 16216
dda8d76d 16217 initialise_dumps_byname (filedata);
aef1f6d0 16218
dda8d76d 16219 for (i = 0, section = filedata->section_headers;
6431e409 16220 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16221 i++, section++)
16222 {
6431e409 16223 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16224
d6bfbc39
NC
16225 if (filedata->is_separate && ! process_links)
16226 dump &= DEBUG_DUMP;
047c3dbf 16227
19e6b90e 16228#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16229 if (dump & DISASS_DUMP)
16230 {
16231 if (! disassemble_section (section, filedata))
015dc7e1 16232 res = false;
dda8d76d 16233 }
19e6b90e 16234#endif
dda8d76d 16235 if (dump & HEX_DUMP)
32ec8896 16236 {
015dc7e1
AM
16237 if (! dump_section_as_bytes (section, filedata, false))
16238 res = false;
32ec8896 16239 }
103f02d3 16240
dda8d76d 16241 if (dump & RELOC_DUMP)
32ec8896 16242 {
015dc7e1
AM
16243 if (! dump_section_as_bytes (section, filedata, true))
16244 res = false;
32ec8896 16245 }
09c11c86 16246
dda8d76d 16247 if (dump & STRING_DUMP)
32ec8896 16248 {
dda8d76d 16249 if (! dump_section_as_strings (section, filedata))
015dc7e1 16250 res = false;
32ec8896 16251 }
cf13d699 16252
dda8d76d 16253 if (dump & DEBUG_DUMP)
32ec8896 16254 {
dda8d76d 16255 if (! display_debug_section (i, section, filedata))
015dc7e1 16256 res = false;
32ec8896 16257 }
7d9813f1 16258
094e34f2 16259#ifdef ENABLE_LIBCTF
7d9813f1
NA
16260 if (dump & CTF_DUMP)
16261 {
16262 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16263 res = false;
7d9813f1 16264 }
094e34f2 16265#endif
5b18a4bc 16266 }
103f02d3 16267
835f2fae 16268 if (! filedata->is_separate)
0ee3043f 16269 {
835f2fae
NC
16270 /* Check to see if the user requested a
16271 dump of a section that does not exist. */
16272 for (; i < filedata->dump.num_dump_sects; i++)
16273 if (filedata->dump.dump_sects[i])
16274 {
ca0e11aa 16275 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16276 res = false;
835f2fae 16277 }
0ee3043f 16278 }
32ec8896
NC
16279
16280 return res;
5b18a4bc 16281}
103f02d3 16282
5b18a4bc 16283static void
19e6b90e 16284process_mips_fpe_exception (int mask)
5b18a4bc 16285{
19e6b90e
L
16286 if (mask)
16287 {
015dc7e1 16288 bool first = true;
32ec8896 16289
19e6b90e 16290 if (mask & OEX_FPU_INEX)
015dc7e1 16291 fputs ("INEX", stdout), first = false;
19e6b90e 16292 if (mask & OEX_FPU_UFLO)
015dc7e1 16293 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16294 if (mask & OEX_FPU_OFLO)
015dc7e1 16295 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16296 if (mask & OEX_FPU_DIV0)
015dc7e1 16297 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16298 if (mask & OEX_FPU_INVAL)
16299 printf ("%sINVAL", first ? "" : "|");
16300 }
5b18a4bc 16301 else
19e6b90e 16302 fputs ("0", stdout);
5b18a4bc 16303}
103f02d3 16304
f6f0e17b
NC
16305/* Display's the value of TAG at location P. If TAG is
16306 greater than 0 it is assumed to be an unknown tag, and
16307 a message is printed to this effect. Otherwise it is
16308 assumed that a message has already been printed.
16309
16310 If the bottom bit of TAG is set it assumed to have a
16311 string value, otherwise it is assumed to have an integer
16312 value.
16313
16314 Returns an updated P pointing to the first unread byte
16315 beyond the end of TAG's value.
16316
16317 Reads at or beyond END will not be made. */
16318
16319static unsigned char *
60abdbed 16320display_tag_value (signed int tag,
f6f0e17b
NC
16321 unsigned char * p,
16322 const unsigned char * const end)
16323{
16324 unsigned long val;
16325
16326 if (tag > 0)
16327 printf (" Tag_unknown_%d: ", tag);
16328
16329 if (p >= end)
16330 {
4082ef84 16331 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16332 }
16333 else if (tag & 1)
16334 {
071436c6
NC
16335 /* PR 17531 file: 027-19978-0.004. */
16336 size_t maxlen = (end - p) - 1;
16337
16338 putchar ('"');
4082ef84
NC
16339 if (maxlen > 0)
16340 {
16341 print_symbol ((int) maxlen, (const char *) p);
16342 p += strnlen ((char *) p, maxlen) + 1;
16343 }
16344 else
16345 {
16346 printf (_("<corrupt string tag>"));
16347 p = (unsigned char *) end;
16348 }
071436c6 16349 printf ("\"\n");
f6f0e17b
NC
16350 }
16351 else
16352 {
cd30bcef 16353 READ_ULEB (val, p, end);
f6f0e17b
NC
16354 printf ("%ld (0x%lx)\n", val, val);
16355 }
16356
4082ef84 16357 assert (p <= end);
f6f0e17b
NC
16358 return p;
16359}
16360
53a346d8
CZ
16361/* ARC ABI attributes section. */
16362
16363static unsigned char *
16364display_arc_attribute (unsigned char * p,
16365 const unsigned char * const end)
16366{
16367 unsigned int tag;
53a346d8
CZ
16368 unsigned int val;
16369
cd30bcef 16370 READ_ULEB (tag, p, end);
53a346d8
CZ
16371
16372 switch (tag)
16373 {
16374 case Tag_ARC_PCS_config:
cd30bcef 16375 READ_ULEB (val, p, end);
53a346d8
CZ
16376 printf (" Tag_ARC_PCS_config: ");
16377 switch (val)
16378 {
16379 case 0:
16380 printf (_("Absent/Non standard\n"));
16381 break;
16382 case 1:
16383 printf (_("Bare metal/mwdt\n"));
16384 break;
16385 case 2:
16386 printf (_("Bare metal/newlib\n"));
16387 break;
16388 case 3:
16389 printf (_("Linux/uclibc\n"));
16390 break;
16391 case 4:
16392 printf (_("Linux/glibc\n"));
16393 break;
16394 default:
16395 printf (_("Unknown\n"));
16396 break;
16397 }
16398 break;
16399
16400 case Tag_ARC_CPU_base:
cd30bcef 16401 READ_ULEB (val, p, end);
53a346d8
CZ
16402 printf (" Tag_ARC_CPU_base: ");
16403 switch (val)
16404 {
16405 default:
16406 case TAG_CPU_NONE:
16407 printf (_("Absent\n"));
16408 break;
16409 case TAG_CPU_ARC6xx:
16410 printf ("ARC6xx\n");
16411 break;
16412 case TAG_CPU_ARC7xx:
16413 printf ("ARC7xx\n");
16414 break;
16415 case TAG_CPU_ARCEM:
16416 printf ("ARCEM\n");
16417 break;
16418 case TAG_CPU_ARCHS:
16419 printf ("ARCHS\n");
16420 break;
16421 }
16422 break;
16423
16424 case Tag_ARC_CPU_variation:
cd30bcef 16425 READ_ULEB (val, p, end);
53a346d8
CZ
16426 printf (" Tag_ARC_CPU_variation: ");
16427 switch (val)
16428 {
16429 default:
16430 if (val > 0 && val < 16)
53a346d8 16431 printf ("Core%d\n", val);
d8cbc93b
JL
16432 else
16433 printf ("Unknown\n");
16434 break;
16435
53a346d8
CZ
16436 case 0:
16437 printf (_("Absent\n"));
16438 break;
16439 }
16440 break;
16441
16442 case Tag_ARC_CPU_name:
16443 printf (" Tag_ARC_CPU_name: ");
16444 p = display_tag_value (-1, p, end);
16445 break;
16446
16447 case Tag_ARC_ABI_rf16:
cd30bcef 16448 READ_ULEB (val, p, end);
53a346d8
CZ
16449 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16450 break;
16451
16452 case Tag_ARC_ABI_osver:
cd30bcef 16453 READ_ULEB (val, p, end);
53a346d8
CZ
16454 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16455 break;
16456
16457 case Tag_ARC_ABI_pic:
16458 case Tag_ARC_ABI_sda:
cd30bcef 16459 READ_ULEB (val, p, end);
53a346d8
CZ
16460 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16461 : " Tag_ARC_ABI_pic: ");
16462 switch (val)
16463 {
16464 case 0:
16465 printf (_("Absent\n"));
16466 break;
16467 case 1:
16468 printf ("MWDT\n");
16469 break;
16470 case 2:
16471 printf ("GNU\n");
16472 break;
16473 default:
16474 printf (_("Unknown\n"));
16475 break;
16476 }
16477 break;
16478
16479 case Tag_ARC_ABI_tls:
cd30bcef 16480 READ_ULEB (val, p, end);
53a346d8
CZ
16481 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16482 break;
16483
16484 case Tag_ARC_ABI_enumsize:
cd30bcef 16485 READ_ULEB (val, p, end);
53a346d8
CZ
16486 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16487 _("smallest"));
16488 break;
16489
16490 case Tag_ARC_ABI_exceptions:
cd30bcef 16491 READ_ULEB (val, p, end);
53a346d8
CZ
16492 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16493 : _("default"));
16494 break;
16495
16496 case Tag_ARC_ABI_double_size:
cd30bcef 16497 READ_ULEB (val, p, end);
53a346d8
CZ
16498 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16499 break;
16500
16501 case Tag_ARC_ISA_config:
16502 printf (" Tag_ARC_ISA_config: ");
16503 p = display_tag_value (-1, p, end);
16504 break;
16505
16506 case Tag_ARC_ISA_apex:
16507 printf (" Tag_ARC_ISA_apex: ");
16508 p = display_tag_value (-1, p, end);
16509 break;
16510
16511 case Tag_ARC_ISA_mpy_option:
cd30bcef 16512 READ_ULEB (val, p, end);
53a346d8
CZ
16513 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16514 break;
16515
db1e1b45 16516 case Tag_ARC_ATR_version:
cd30bcef 16517 READ_ULEB (val, p, end);
db1e1b45 16518 printf (" Tag_ARC_ATR_version: %d\n", val);
16519 break;
16520
53a346d8
CZ
16521 default:
16522 return display_tag_value (tag & 1, p, end);
16523 }
16524
16525 return p;
16526}
16527
11c1ff18
PB
16528/* ARM EABI attributes section. */
16529typedef struct
16530{
70e99720 16531 unsigned int tag;
2cf0635d 16532 const char * name;
11c1ff18 16533 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16534 unsigned int type;
288f0ba2 16535 const char *const *table;
11c1ff18
PB
16536} arm_attr_public_tag;
16537
288f0ba2 16538static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16539 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16540 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16541 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16542 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16543static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16544static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16545 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16546static const char *const arm_attr_tag_FP_arch[] =
bca38921 16547 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16548 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16549static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16550static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16551 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16552 "NEON for ARMv8.1"};
288f0ba2 16553static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16554 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16555 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16556static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16557 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16558static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16559 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16560static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16561 {"Absolute", "PC-relative", "None"};
288f0ba2 16562static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16563 {"None", "direct", "GOT-indirect"};
288f0ba2 16564static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16565 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16566static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16567static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16568 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16569static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16570static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16571static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16572 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16573static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16574 {"Unused", "small", "int", "forced to int"};
288f0ba2 16575static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16576 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16577static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16578 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16579static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16580 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16581static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16582 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16583 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16584static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16585 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16586 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16587static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16588static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16589 {"Not Allowed", "Allowed"};
288f0ba2 16590static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16591 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16592static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16593 {"Follow architecture", "Allowed"};
288f0ba2 16594static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16595 {"Not Allowed", "Allowed"};
288f0ba2 16596static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16597 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16598 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16599static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16600static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16601 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16602 "TrustZone and Virtualization Extensions"};
288f0ba2 16603static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16604 {"Not Allowed", "Allowed"};
11c1ff18 16605
288f0ba2 16606static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16607 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16608
99db83d0
AC
16609static const char * arm_attr_tag_PAC_extension[] =
16610 {"No PAC/AUT instructions",
16611 "PAC/AUT instructions permitted in the NOP space",
16612 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16613
4b535030
AC
16614static const char * arm_attr_tag_BTI_extension[] =
16615 {"BTI instructions not permitted",
16616 "BTI instructions permitted in the NOP space",
16617 "BTI instructions permitted in the NOP and in the non-NOP space"};
16618
b81ee92f
AC
16619static const char * arm_attr_tag_BTI_use[] =
16620 {"Compiled without branch target enforcement",
16621 "Compiled with branch target enforcement"};
16622
c9fed665
AC
16623static const char * arm_attr_tag_PACRET_use[] =
16624 {"Compiled without return address signing and authentication",
16625 "Compiled with return address signing and authentication"};
16626
11c1ff18
PB
16627#define LOOKUP(id, name) \
16628 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16629static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16630{
16631 {4, "CPU_raw_name", 1, NULL},
16632 {5, "CPU_name", 1, NULL},
16633 LOOKUP(6, CPU_arch),
16634 {7, "CPU_arch_profile", 0, NULL},
16635 LOOKUP(8, ARM_ISA_use),
16636 LOOKUP(9, THUMB_ISA_use),
75375b3e 16637 LOOKUP(10, FP_arch),
11c1ff18 16638 LOOKUP(11, WMMX_arch),
f5f53991
AS
16639 LOOKUP(12, Advanced_SIMD_arch),
16640 LOOKUP(13, PCS_config),
11c1ff18
PB
16641 LOOKUP(14, ABI_PCS_R9_use),
16642 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16643 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16644 LOOKUP(17, ABI_PCS_GOT_use),
16645 LOOKUP(18, ABI_PCS_wchar_t),
16646 LOOKUP(19, ABI_FP_rounding),
16647 LOOKUP(20, ABI_FP_denormal),
16648 LOOKUP(21, ABI_FP_exceptions),
16649 LOOKUP(22, ABI_FP_user_exceptions),
16650 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16651 {24, "ABI_align_needed", 0, NULL},
16652 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16653 LOOKUP(26, ABI_enum_size),
16654 LOOKUP(27, ABI_HardFP_use),
16655 LOOKUP(28, ABI_VFP_args),
16656 LOOKUP(29, ABI_WMMX_args),
16657 LOOKUP(30, ABI_optimization_goals),
16658 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16659 {32, "compatibility", 0, NULL},
f5f53991 16660 LOOKUP(34, CPU_unaligned_access),
75375b3e 16661 LOOKUP(36, FP_HP_extension),
8e79c3df 16662 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16663 LOOKUP(42, MPextension_use),
16664 LOOKUP(44, DIV_use),
15afaa63 16665 LOOKUP(46, DSP_extension),
a7ad558c 16666 LOOKUP(48, MVE_arch),
99db83d0 16667 LOOKUP(50, PAC_extension),
4b535030 16668 LOOKUP(52, BTI_extension),
b81ee92f 16669 LOOKUP(74, BTI_use),
c9fed665 16670 LOOKUP(76, PACRET_use),
f5f53991
AS
16671 {64, "nodefaults", 0, NULL},
16672 {65, "also_compatible_with", 0, NULL},
16673 LOOKUP(66, T2EE_use),
16674 {67, "conformance", 1, NULL},
16675 LOOKUP(68, Virtualization_use),
cd21e546 16676 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16677};
16678#undef LOOKUP
16679
11c1ff18 16680static unsigned char *
f6f0e17b
NC
16681display_arm_attribute (unsigned char * p,
16682 const unsigned char * const end)
11c1ff18 16683{
70e99720 16684 unsigned int tag;
70e99720 16685 unsigned int val;
2cf0635d 16686 arm_attr_public_tag * attr;
11c1ff18 16687 unsigned i;
70e99720 16688 unsigned int type;
11c1ff18 16689
cd30bcef 16690 READ_ULEB (tag, p, end);
11c1ff18 16691 attr = NULL;
2cf0635d 16692 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16693 {
16694 if (arm_attr_public_tags[i].tag == tag)
16695 {
16696 attr = &arm_attr_public_tags[i];
16697 break;
16698 }
16699 }
16700
16701 if (attr)
16702 {
16703 printf (" Tag_%s: ", attr->name);
16704 switch (attr->type)
16705 {
16706 case 0:
16707 switch (tag)
16708 {
16709 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16710 READ_ULEB (val, p, end);
11c1ff18
PB
16711 switch (val)
16712 {
2b692964
NC
16713 case 0: printf (_("None\n")); break;
16714 case 'A': printf (_("Application\n")); break;
16715 case 'R': printf (_("Realtime\n")); break;
16716 case 'M': printf (_("Microcontroller\n")); break;
16717 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16718 default: printf ("??? (%d)\n", val); break;
16719 }
16720 break;
16721
75375b3e 16722 case 24: /* Tag_align_needed. */
cd30bcef 16723 READ_ULEB (val, p, end);
75375b3e
MGD
16724 switch (val)
16725 {
2b692964
NC
16726 case 0: printf (_("None\n")); break;
16727 case 1: printf (_("8-byte\n")); break;
16728 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16729 case 3: printf ("??? 3\n"); break;
16730 default:
16731 if (val <= 12)
dd24e3da 16732 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16733 1 << val);
16734 else
16735 printf ("??? (%d)\n", val);
16736 break;
16737 }
16738 break;
16739
16740 case 25: /* Tag_align_preserved. */
cd30bcef 16741 READ_ULEB (val, p, end);
75375b3e
MGD
16742 switch (val)
16743 {
2b692964
NC
16744 case 0: printf (_("None\n")); break;
16745 case 1: printf (_("8-byte, except leaf SP\n")); break;
16746 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16747 case 3: printf ("??? 3\n"); break;
16748 default:
16749 if (val <= 12)
dd24e3da 16750 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16751 1 << val);
16752 else
16753 printf ("??? (%d)\n", val);
16754 break;
16755 }
16756 break;
16757
11c1ff18 16758 case 32: /* Tag_compatibility. */
071436c6 16759 {
cd30bcef 16760 READ_ULEB (val, p, end);
071436c6 16761 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16762 if (p < end - 1)
16763 {
16764 size_t maxlen = (end - p) - 1;
16765
16766 print_symbol ((int) maxlen, (const char *) p);
16767 p += strnlen ((char *) p, maxlen) + 1;
16768 }
16769 else
16770 {
16771 printf (_("<corrupt>"));
16772 p = (unsigned char *) end;
16773 }
071436c6 16774 putchar ('\n');
071436c6 16775 }
11c1ff18
PB
16776 break;
16777
f5f53991 16778 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16779 /* PR 17531: file: 001-505008-0.01. */
16780 if (p < end)
16781 p++;
2b692964 16782 printf (_("True\n"));
f5f53991
AS
16783 break;
16784
16785 case 65: /* Tag_also_compatible_with. */
cd30bcef 16786 READ_ULEB (val, p, end);
f5f53991
AS
16787 if (val == 6 /* Tag_CPU_arch. */)
16788 {
cd30bcef 16789 READ_ULEB (val, p, end);
071436c6 16790 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16791 printf ("??? (%d)\n", val);
16792 else
16793 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16794 }
16795 else
16796 printf ("???\n");
071436c6
NC
16797 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16798 ;
f5f53991
AS
16799 break;
16800
11c1ff18 16801 default:
bee0ee85
NC
16802 printf (_("<unknown: %d>\n"), tag);
16803 break;
11c1ff18
PB
16804 }
16805 return p;
16806
16807 case 1:
f6f0e17b 16808 return display_tag_value (-1, p, end);
11c1ff18 16809 case 2:
f6f0e17b 16810 return display_tag_value (0, p, end);
11c1ff18
PB
16811
16812 default:
16813 assert (attr->type & 0x80);
cd30bcef 16814 READ_ULEB (val, p, end);
11c1ff18
PB
16815 type = attr->type & 0x7f;
16816 if (val >= type)
16817 printf ("??? (%d)\n", val);
16818 else
16819 printf ("%s\n", attr->table[val]);
16820 return p;
16821 }
16822 }
11c1ff18 16823
f6f0e17b 16824 return display_tag_value (tag, p, end);
11c1ff18
PB
16825}
16826
104d59d1 16827static unsigned char *
60bca95a 16828display_gnu_attribute (unsigned char * p,
60abdbed 16829 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16830 const unsigned char * const end)
104d59d1 16831{
cd30bcef 16832 unsigned int tag;
60abdbed 16833 unsigned int val;
104d59d1 16834
cd30bcef 16835 READ_ULEB (tag, p, end);
104d59d1
JM
16836
16837 /* Tag_compatibility is the only generic GNU attribute defined at
16838 present. */
16839 if (tag == 32)
16840 {
cd30bcef 16841 READ_ULEB (val, p, end);
071436c6
NC
16842
16843 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16844 if (p == end)
16845 {
071436c6 16846 printf (_("<corrupt>\n"));
f6f0e17b
NC
16847 warn (_("corrupt vendor attribute\n"));
16848 }
16849 else
16850 {
4082ef84
NC
16851 if (p < end - 1)
16852 {
16853 size_t maxlen = (end - p) - 1;
071436c6 16854
4082ef84
NC
16855 print_symbol ((int) maxlen, (const char *) p);
16856 p += strnlen ((char *) p, maxlen) + 1;
16857 }
16858 else
16859 {
16860 printf (_("<corrupt>"));
16861 p = (unsigned char *) end;
16862 }
071436c6 16863 putchar ('\n');
f6f0e17b 16864 }
104d59d1
JM
16865 return p;
16866 }
16867
16868 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16869 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16870
f6f0e17b 16871 return display_tag_value (tag, p, end);
104d59d1
JM
16872}
16873
85f7484a
PB
16874static unsigned char *
16875display_m68k_gnu_attribute (unsigned char * p,
16876 unsigned int tag,
16877 const unsigned char * const end)
16878{
16879 unsigned int val;
16880
16881 if (tag == Tag_GNU_M68K_ABI_FP)
16882 {
16883 printf (" Tag_GNU_M68K_ABI_FP: ");
16884 if (p == end)
16885 {
16886 printf (_("<corrupt>\n"));
16887 return p;
16888 }
16889 READ_ULEB (val, p, end);
16890
16891 if (val > 3)
16892 printf ("(%#x), ", val);
16893
16894 switch (val & 3)
16895 {
16896 case 0:
16897 printf (_("unspecified hard/soft float\n"));
16898 break;
16899 case 1:
16900 printf (_("hard float\n"));
16901 break;
16902 case 2:
16903 printf (_("soft float\n"));
16904 break;
16905 }
16906 return p;
16907 }
16908
16909 return display_tag_value (tag & 1, p, end);
16910}
16911
34c8bcba 16912static unsigned char *
f6f0e17b 16913display_power_gnu_attribute (unsigned char * p,
60abdbed 16914 unsigned int tag,
f6f0e17b 16915 const unsigned char * const end)
34c8bcba 16916{
005d79fd 16917 unsigned int val;
34c8bcba
JM
16918
16919 if (tag == Tag_GNU_Power_ABI_FP)
16920 {
34c8bcba 16921 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16922 if (p == end)
005d79fd
AM
16923 {
16924 printf (_("<corrupt>\n"));
16925 return p;
16926 }
cd30bcef 16927 READ_ULEB (val, p, end);
60bca95a 16928
005d79fd
AM
16929 if (val > 15)
16930 printf ("(%#x), ", val);
16931
16932 switch (val & 3)
34c8bcba
JM
16933 {
16934 case 0:
005d79fd 16935 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16936 break;
16937 case 1:
005d79fd 16938 printf (_("hard float, "));
34c8bcba
JM
16939 break;
16940 case 2:
005d79fd 16941 printf (_("soft float, "));
34c8bcba 16942 break;
3c7b9897 16943 case 3:
005d79fd 16944 printf (_("single-precision hard float, "));
3c7b9897 16945 break;
005d79fd
AM
16946 }
16947
16948 switch (val & 0xC)
16949 {
16950 case 0:
16951 printf (_("unspecified long double\n"));
16952 break;
16953 case 4:
16954 printf (_("128-bit IBM long double\n"));
16955 break;
16956 case 8:
16957 printf (_("64-bit long double\n"));
16958 break;
16959 case 12:
16960 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16961 break;
16962 }
16963 return p;
005d79fd 16964 }
34c8bcba 16965
c6e65352
DJ
16966 if (tag == Tag_GNU_Power_ABI_Vector)
16967 {
c6e65352 16968 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16969 if (p == end)
005d79fd
AM
16970 {
16971 printf (_("<corrupt>\n"));
16972 return p;
16973 }
cd30bcef 16974 READ_ULEB (val, p, end);
005d79fd
AM
16975
16976 if (val > 3)
16977 printf ("(%#x), ", val);
16978
16979 switch (val & 3)
c6e65352
DJ
16980 {
16981 case 0:
005d79fd 16982 printf (_("unspecified\n"));
c6e65352
DJ
16983 break;
16984 case 1:
005d79fd 16985 printf (_("generic\n"));
c6e65352
DJ
16986 break;
16987 case 2:
16988 printf ("AltiVec\n");
16989 break;
16990 case 3:
16991 printf ("SPE\n");
16992 break;
c6e65352
DJ
16993 }
16994 return p;
005d79fd 16995 }
c6e65352 16996
f82e0623
NF
16997 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16998 {
005d79fd 16999 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17000 if (p == end)
f6f0e17b 17001 {
005d79fd 17002 printf (_("<corrupt>\n"));
f6f0e17b
NC
17003 return p;
17004 }
cd30bcef 17005 READ_ULEB (val, p, end);
0b4362b0 17006
005d79fd
AM
17007 if (val > 2)
17008 printf ("(%#x), ", val);
17009
17010 switch (val & 3)
17011 {
17012 case 0:
17013 printf (_("unspecified\n"));
17014 break;
17015 case 1:
17016 printf ("r3/r4\n");
17017 break;
17018 case 2:
17019 printf (_("memory\n"));
17020 break;
17021 case 3:
17022 printf ("???\n");
17023 break;
17024 }
f82e0623
NF
17025 return p;
17026 }
17027
f6f0e17b 17028 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17029}
17030
643f7afb
AK
17031static unsigned char *
17032display_s390_gnu_attribute (unsigned char * p,
60abdbed 17033 unsigned int tag,
643f7afb
AK
17034 const unsigned char * const end)
17035{
cd30bcef 17036 unsigned int val;
643f7afb
AK
17037
17038 if (tag == Tag_GNU_S390_ABI_Vector)
17039 {
643f7afb 17040 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17041 READ_ULEB (val, p, end);
643f7afb
AK
17042
17043 switch (val)
17044 {
17045 case 0:
17046 printf (_("any\n"));
17047 break;
17048 case 1:
17049 printf (_("software\n"));
17050 break;
17051 case 2:
17052 printf (_("hardware\n"));
17053 break;
17054 default:
17055 printf ("??? (%d)\n", val);
17056 break;
17057 }
17058 return p;
17059 }
17060
17061 return display_tag_value (tag & 1, p, end);
17062}
17063
9e8c70f9 17064static void
60abdbed 17065display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17066{
17067 if (mask)
17068 {
015dc7e1 17069 bool first = true;
071436c6 17070
9e8c70f9 17071 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17072 fputs ("mul32", stdout), first = false;
9e8c70f9 17073 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17074 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17075 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17076 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17077 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17078 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17079 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17080 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17081 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17082 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17083 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17084 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17085 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17086 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17087 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17088 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17089 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17090 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17091 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17092 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17093 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17094 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17095 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17096 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17097 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17098 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17099 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17100 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17101 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17102 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17103 }
17104 else
071436c6
NC
17105 fputc ('0', stdout);
17106 fputc ('\n', stdout);
9e8c70f9
DM
17107}
17108
3d68f91c 17109static void
60abdbed 17110display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17111{
17112 if (mask)
17113 {
015dc7e1 17114 bool first = true;
071436c6 17115
3d68f91c 17116 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17117 fputs ("fjathplus", stdout), first = false;
3d68f91c 17118 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17119 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17120 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17121 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17122 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17123 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17124 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17125 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17126 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17127 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17128 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17129 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17130 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17131 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17132 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17133 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17134 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17135 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17136 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17137 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17138 }
17139 else
071436c6
NC
17140 fputc ('0', stdout);
17141 fputc ('\n', stdout);
3d68f91c
JM
17142}
17143
9e8c70f9 17144static unsigned char *
f6f0e17b 17145display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17146 unsigned int tag,
f6f0e17b 17147 const unsigned char * const end)
9e8c70f9 17148{
cd30bcef 17149 unsigned int val;
3d68f91c 17150
9e8c70f9
DM
17151 if (tag == Tag_GNU_Sparc_HWCAPS)
17152 {
cd30bcef 17153 READ_ULEB (val, p, end);
9e8c70f9 17154 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17155 display_sparc_hwcaps (val);
17156 return p;
3d68f91c
JM
17157 }
17158 if (tag == Tag_GNU_Sparc_HWCAPS2)
17159 {
cd30bcef 17160 READ_ULEB (val, p, end);
3d68f91c
JM
17161 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17162 display_sparc_hwcaps2 (val);
17163 return p;
17164 }
9e8c70f9 17165
f6f0e17b 17166 return display_tag_value (tag, p, end);
9e8c70f9
DM
17167}
17168
351cdf24 17169static void
32ec8896 17170print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17171{
17172 switch (val)
17173 {
17174 case Val_GNU_MIPS_ABI_FP_ANY:
17175 printf (_("Hard or soft float\n"));
17176 break;
17177 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17178 printf (_("Hard float (double precision)\n"));
17179 break;
17180 case Val_GNU_MIPS_ABI_FP_SINGLE:
17181 printf (_("Hard float (single precision)\n"));
17182 break;
17183 case Val_GNU_MIPS_ABI_FP_SOFT:
17184 printf (_("Soft float\n"));
17185 break;
17186 case Val_GNU_MIPS_ABI_FP_OLD_64:
17187 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17188 break;
17189 case Val_GNU_MIPS_ABI_FP_XX:
17190 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17191 break;
17192 case Val_GNU_MIPS_ABI_FP_64:
17193 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17194 break;
17195 case Val_GNU_MIPS_ABI_FP_64A:
17196 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17197 break;
3350cc01
CM
17198 case Val_GNU_MIPS_ABI_FP_NAN2008:
17199 printf (_("NaN 2008 compatibility\n"));
17200 break;
351cdf24
MF
17201 default:
17202 printf ("??? (%d)\n", val);
17203 break;
17204 }
17205}
17206
2cf19d5c 17207static unsigned char *
f6f0e17b 17208display_mips_gnu_attribute (unsigned char * p,
60abdbed 17209 unsigned int tag,
f6f0e17b 17210 const unsigned char * const end)
2cf19d5c 17211{
2cf19d5c
JM
17212 if (tag == Tag_GNU_MIPS_ABI_FP)
17213 {
32ec8896 17214 unsigned int val;
f6f0e17b 17215
2cf19d5c 17216 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17217 READ_ULEB (val, p, end);
351cdf24 17218 print_mips_fp_abi_value (val);
2cf19d5c
JM
17219 return p;
17220 }
17221
a9f58168
CF
17222 if (tag == Tag_GNU_MIPS_ABI_MSA)
17223 {
32ec8896 17224 unsigned int val;
a9f58168 17225
a9f58168 17226 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17227 READ_ULEB (val, p, end);
a9f58168
CF
17228
17229 switch (val)
17230 {
17231 case Val_GNU_MIPS_ABI_MSA_ANY:
17232 printf (_("Any MSA or not\n"));
17233 break;
17234 case Val_GNU_MIPS_ABI_MSA_128:
17235 printf (_("128-bit MSA\n"));
17236 break;
17237 default:
17238 printf ("??? (%d)\n", val);
17239 break;
17240 }
17241 return p;
17242 }
17243
f6f0e17b 17244 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17245}
17246
59e6276b 17247static unsigned char *
f6f0e17b
NC
17248display_tic6x_attribute (unsigned char * p,
17249 const unsigned char * const end)
59e6276b 17250{
60abdbed 17251 unsigned int tag;
cd30bcef 17252 unsigned int val;
59e6276b 17253
cd30bcef 17254 READ_ULEB (tag, p, end);
59e6276b
JM
17255
17256 switch (tag)
17257 {
75fa6dc1 17258 case Tag_ISA:
75fa6dc1 17259 printf (" Tag_ISA: ");
cd30bcef 17260 READ_ULEB (val, p, end);
59e6276b
JM
17261
17262 switch (val)
17263 {
75fa6dc1 17264 case C6XABI_Tag_ISA_none:
59e6276b
JM
17265 printf (_("None\n"));
17266 break;
75fa6dc1 17267 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17268 printf ("C62x\n");
17269 break;
75fa6dc1 17270 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17271 printf ("C67x\n");
17272 break;
75fa6dc1 17273 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17274 printf ("C67x+\n");
17275 break;
75fa6dc1 17276 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17277 printf ("C64x\n");
17278 break;
75fa6dc1 17279 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17280 printf ("C64x+\n");
17281 break;
75fa6dc1 17282 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17283 printf ("C674x\n");
17284 break;
17285 default:
17286 printf ("??? (%d)\n", val);
17287 break;
17288 }
17289 return p;
17290
87779176 17291 case Tag_ABI_wchar_t:
87779176 17292 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17293 READ_ULEB (val, p, end);
87779176
JM
17294 switch (val)
17295 {
17296 case 0:
17297 printf (_("Not used\n"));
17298 break;
17299 case 1:
17300 printf (_("2 bytes\n"));
17301 break;
17302 case 2:
17303 printf (_("4 bytes\n"));
17304 break;
17305 default:
17306 printf ("??? (%d)\n", val);
17307 break;
17308 }
17309 return p;
17310
17311 case Tag_ABI_stack_align_needed:
87779176 17312 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17313 READ_ULEB (val, p, end);
87779176
JM
17314 switch (val)
17315 {
17316 case 0:
17317 printf (_("8-byte\n"));
17318 break;
17319 case 1:
17320 printf (_("16-byte\n"));
17321 break;
17322 default:
17323 printf ("??? (%d)\n", val);
17324 break;
17325 }
17326 return p;
17327
17328 case Tag_ABI_stack_align_preserved:
cd30bcef 17329 READ_ULEB (val, p, end);
87779176
JM
17330 printf (" Tag_ABI_stack_align_preserved: ");
17331 switch (val)
17332 {
17333 case 0:
17334 printf (_("8-byte\n"));
17335 break;
17336 case 1:
17337 printf (_("16-byte\n"));
17338 break;
17339 default:
17340 printf ("??? (%d)\n", val);
17341 break;
17342 }
17343 return p;
17344
b5593623 17345 case Tag_ABI_DSBT:
cd30bcef 17346 READ_ULEB (val, p, end);
b5593623
JM
17347 printf (" Tag_ABI_DSBT: ");
17348 switch (val)
17349 {
17350 case 0:
17351 printf (_("DSBT addressing not used\n"));
17352 break;
17353 case 1:
17354 printf (_("DSBT addressing used\n"));
17355 break;
17356 default:
17357 printf ("??? (%d)\n", val);
17358 break;
17359 }
17360 return p;
17361
87779176 17362 case Tag_ABI_PID:
cd30bcef 17363 READ_ULEB (val, p, end);
87779176
JM
17364 printf (" Tag_ABI_PID: ");
17365 switch (val)
17366 {
17367 case 0:
17368 printf (_("Data addressing position-dependent\n"));
17369 break;
17370 case 1:
17371 printf (_("Data addressing position-independent, GOT near DP\n"));
17372 break;
17373 case 2:
17374 printf (_("Data addressing position-independent, GOT far from DP\n"));
17375 break;
17376 default:
17377 printf ("??? (%d)\n", val);
17378 break;
17379 }
17380 return p;
17381
17382 case Tag_ABI_PIC:
cd30bcef 17383 READ_ULEB (val, p, end);
87779176
JM
17384 printf (" Tag_ABI_PIC: ");
17385 switch (val)
17386 {
17387 case 0:
17388 printf (_("Code addressing position-dependent\n"));
17389 break;
17390 case 1:
17391 printf (_("Code addressing position-independent\n"));
17392 break;
17393 default:
17394 printf ("??? (%d)\n", val);
17395 break;
17396 }
17397 return p;
17398
17399 case Tag_ABI_array_object_alignment:
cd30bcef 17400 READ_ULEB (val, p, end);
87779176
JM
17401 printf (" Tag_ABI_array_object_alignment: ");
17402 switch (val)
17403 {
17404 case 0:
17405 printf (_("8-byte\n"));
17406 break;
17407 case 1:
17408 printf (_("4-byte\n"));
17409 break;
17410 case 2:
17411 printf (_("16-byte\n"));
17412 break;
17413 default:
17414 printf ("??? (%d)\n", val);
17415 break;
17416 }
17417 return p;
17418
17419 case Tag_ABI_array_object_align_expected:
cd30bcef 17420 READ_ULEB (val, p, end);
87779176
JM
17421 printf (" Tag_ABI_array_object_align_expected: ");
17422 switch (val)
17423 {
17424 case 0:
17425 printf (_("8-byte\n"));
17426 break;
17427 case 1:
17428 printf (_("4-byte\n"));
17429 break;
17430 case 2:
17431 printf (_("16-byte\n"));
17432 break;
17433 default:
17434 printf ("??? (%d)\n", val);
17435 break;
17436 }
17437 return p;
17438
3cbd1c06 17439 case Tag_ABI_compatibility:
071436c6 17440 {
cd30bcef 17441 READ_ULEB (val, p, end);
071436c6 17442 printf (" Tag_ABI_compatibility: ");
071436c6 17443 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17444 if (p < end - 1)
17445 {
17446 size_t maxlen = (end - p) - 1;
17447
17448 print_symbol ((int) maxlen, (const char *) p);
17449 p += strnlen ((char *) p, maxlen) + 1;
17450 }
17451 else
17452 {
17453 printf (_("<corrupt>"));
17454 p = (unsigned char *) end;
17455 }
071436c6 17456 putchar ('\n');
071436c6
NC
17457 return p;
17458 }
87779176
JM
17459
17460 case Tag_ABI_conformance:
071436c6 17461 {
4082ef84
NC
17462 printf (" Tag_ABI_conformance: \"");
17463 if (p < end - 1)
17464 {
17465 size_t maxlen = (end - p) - 1;
071436c6 17466
4082ef84
NC
17467 print_symbol ((int) maxlen, (const char *) p);
17468 p += strnlen ((char *) p, maxlen) + 1;
17469 }
17470 else
17471 {
17472 printf (_("<corrupt>"));
17473 p = (unsigned char *) end;
17474 }
071436c6 17475 printf ("\"\n");
071436c6
NC
17476 return p;
17477 }
59e6276b
JM
17478 }
17479
f6f0e17b
NC
17480 return display_tag_value (tag, p, end);
17481}
59e6276b 17482
f6f0e17b 17483static void
60abdbed 17484display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17485{
17486 unsigned long addr = 0;
17487 size_t bytes = end - p;
17488
feceaa59 17489 assert (end >= p);
f6f0e17b 17490 while (bytes)
87779176 17491 {
f6f0e17b
NC
17492 int j;
17493 int k;
17494 int lbytes = (bytes > 16 ? 16 : bytes);
17495
17496 printf (" 0x%8.8lx ", addr);
17497
17498 for (j = 0; j < 16; j++)
17499 {
17500 if (j < lbytes)
17501 printf ("%2.2x", p[j]);
17502 else
17503 printf (" ");
17504
17505 if ((j & 3) == 3)
17506 printf (" ");
17507 }
17508
17509 for (j = 0; j < lbytes; j++)
17510 {
17511 k = p[j];
17512 if (k >= ' ' && k < 0x7f)
17513 printf ("%c", k);
17514 else
17515 printf (".");
17516 }
17517
17518 putchar ('\n');
17519
17520 p += lbytes;
17521 bytes -= lbytes;
17522 addr += lbytes;
87779176 17523 }
59e6276b 17524
f6f0e17b 17525 putchar ('\n');
59e6276b
JM
17526}
17527
13761a11 17528static unsigned char *
b0191216 17529display_msp430_attribute (unsigned char * p,
13761a11
NC
17530 const unsigned char * const end)
17531{
60abdbed
NC
17532 unsigned int val;
17533 unsigned int tag;
13761a11 17534
cd30bcef 17535 READ_ULEB (tag, p, end);
0b4362b0 17536
13761a11
NC
17537 switch (tag)
17538 {
17539 case OFBA_MSPABI_Tag_ISA:
13761a11 17540 printf (" Tag_ISA: ");
cd30bcef 17541 READ_ULEB (val, p, end);
13761a11
NC
17542 switch (val)
17543 {
17544 case 0: printf (_("None\n")); break;
17545 case 1: printf (_("MSP430\n")); break;
17546 case 2: printf (_("MSP430X\n")); break;
17547 default: printf ("??? (%d)\n", val); break;
17548 }
17549 break;
17550
17551 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17552 printf (" Tag_Code_Model: ");
cd30bcef 17553 READ_ULEB (val, p, end);
13761a11
NC
17554 switch (val)
17555 {
17556 case 0: printf (_("None\n")); break;
17557 case 1: printf (_("Small\n")); break;
17558 case 2: printf (_("Large\n")); break;
17559 default: printf ("??? (%d)\n", val); break;
17560 }
17561 break;
17562
17563 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17564 printf (" Tag_Data_Model: ");
cd30bcef 17565 READ_ULEB (val, p, end);
13761a11
NC
17566 switch (val)
17567 {
17568 case 0: printf (_("None\n")); break;
17569 case 1: printf (_("Small\n")); break;
17570 case 2: printf (_("Large\n")); break;
17571 case 3: printf (_("Restricted Large\n")); break;
17572 default: printf ("??? (%d)\n", val); break;
17573 }
17574 break;
17575
17576 default:
17577 printf (_(" <unknown tag %d>: "), tag);
17578
17579 if (tag & 1)
17580 {
071436c6 17581 putchar ('"');
4082ef84
NC
17582 if (p < end - 1)
17583 {
17584 size_t maxlen = (end - p) - 1;
17585
17586 print_symbol ((int) maxlen, (const char *) p);
17587 p += strnlen ((char *) p, maxlen) + 1;
17588 }
17589 else
17590 {
17591 printf (_("<corrupt>"));
17592 p = (unsigned char *) end;
17593 }
071436c6 17594 printf ("\"\n");
13761a11
NC
17595 }
17596 else
17597 {
cd30bcef 17598 READ_ULEB (val, p, end);
13761a11
NC
17599 printf ("%d (0x%x)\n", val, val);
17600 }
17601 break;
17602 }
17603
4082ef84 17604 assert (p <= end);
13761a11
NC
17605 return p;
17606}
17607
c0ea7c52
JL
17608static unsigned char *
17609display_msp430_gnu_attribute (unsigned char * p,
17610 unsigned int tag,
17611 const unsigned char * const end)
17612{
17613 if (tag == Tag_GNU_MSP430_Data_Region)
17614 {
cd30bcef 17615 unsigned int val;
c0ea7c52 17616
c0ea7c52 17617 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17618 READ_ULEB (val, p, end);
c0ea7c52
JL
17619
17620 switch (val)
17621 {
17622 case Val_GNU_MSP430_Data_Region_Any:
17623 printf (_("Any Region\n"));
17624 break;
17625 case Val_GNU_MSP430_Data_Region_Lower:
17626 printf (_("Lower Region Only\n"));
17627 break;
17628 default:
cd30bcef 17629 printf ("??? (%u)\n", val);
c0ea7c52
JL
17630 }
17631 return p;
17632 }
17633 return display_tag_value (tag & 1, p, end);
17634}
17635
2dc8dd17
JW
17636struct riscv_attr_tag_t {
17637 const char *name;
cd30bcef 17638 unsigned int tag;
2dc8dd17
JW
17639};
17640
17641static struct riscv_attr_tag_t riscv_attr_tag[] =
17642{
17643#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17644 T(arch),
17645 T(priv_spec),
17646 T(priv_spec_minor),
17647 T(priv_spec_revision),
17648 T(unaligned_access),
17649 T(stack_align),
17650#undef T
17651};
17652
17653static unsigned char *
17654display_riscv_attribute (unsigned char *p,
17655 const unsigned char * const end)
17656{
cd30bcef
AM
17657 unsigned int val;
17658 unsigned int tag;
2dc8dd17
JW
17659 struct riscv_attr_tag_t *attr = NULL;
17660 unsigned i;
17661
cd30bcef 17662 READ_ULEB (tag, p, end);
2dc8dd17
JW
17663
17664 /* Find the name of attribute. */
17665 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17666 {
17667 if (riscv_attr_tag[i].tag == tag)
17668 {
17669 attr = &riscv_attr_tag[i];
17670 break;
17671 }
17672 }
17673
17674 if (attr)
17675 printf (" %s: ", attr->name);
17676 else
17677 return display_tag_value (tag, p, end);
17678
17679 switch (tag)
17680 {
17681 case Tag_RISCV_priv_spec:
17682 case Tag_RISCV_priv_spec_minor:
17683 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17684 READ_ULEB (val, p, end);
17685 printf (_("%u\n"), val);
2dc8dd17
JW
17686 break;
17687 case Tag_RISCV_unaligned_access:
cd30bcef 17688 READ_ULEB (val, p, end);
2dc8dd17
JW
17689 switch (val)
17690 {
17691 case 0:
17692 printf (_("No unaligned access\n"));
17693 break;
17694 case 1:
17695 printf (_("Unaligned access\n"));
17696 break;
17697 }
17698 break;
17699 case Tag_RISCV_stack_align:
cd30bcef
AM
17700 READ_ULEB (val, p, end);
17701 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17702 break;
17703 case Tag_RISCV_arch:
17704 p = display_tag_value (-1, p, end);
17705 break;
17706 default:
17707 return display_tag_value (tag, p, end);
17708 }
17709
17710 return p;
17711}
17712
0861f561
CQ
17713static unsigned char *
17714display_csky_attribute (unsigned char * p,
17715 const unsigned char * const end)
17716{
17717 unsigned int tag;
17718 unsigned int val;
17719 READ_ULEB (tag, p, end);
17720
17721 if (tag >= Tag_CSKY_MAX)
17722 {
17723 return display_tag_value (-1, p, end);
17724 }
17725
17726 switch (tag)
17727 {
17728 case Tag_CSKY_ARCH_NAME:
17729 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17730 return display_tag_value (-1, p, end);
17731 case Tag_CSKY_CPU_NAME:
17732 printf (" Tag_CSKY_CPU_NAME:\t\t");
17733 return display_tag_value (-1, p, end);
17734
17735 case Tag_CSKY_ISA_FLAGS:
17736 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17737 return display_tag_value (0, p, end);
17738 case Tag_CSKY_ISA_EXT_FLAGS:
17739 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17740 return display_tag_value (0, p, end);
17741
17742 case Tag_CSKY_DSP_VERSION:
17743 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17744 READ_ULEB (val, p, end);
17745 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17746 printf ("DSP Extension\n");
17747 else if (val == VAL_CSKY_DSP_VERSION_2)
17748 printf ("DSP 2.0\n");
17749 break;
17750
17751 case Tag_CSKY_VDSP_VERSION:
17752 printf (" Tag_CSKY_VDSP_VERSION:\t");
17753 READ_ULEB (val, p, end);
17754 printf ("VDSP Version %d\n", val);
17755 break;
17756
17757 case Tag_CSKY_FPU_VERSION:
17758 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17759 READ_ULEB (val, p, end);
17760 if (val == VAL_CSKY_FPU_VERSION_1)
17761 printf ("ABIV1 FPU Version 1\n");
17762 else if (val == VAL_CSKY_FPU_VERSION_2)
17763 printf ("FPU Version 2\n");
17764 break;
17765
17766 case Tag_CSKY_FPU_ABI:
17767 printf (" Tag_CSKY_FPU_ABI:\t\t");
17768 READ_ULEB (val, p, end);
17769 if (val == VAL_CSKY_FPU_ABI_HARD)
17770 printf ("Hard\n");
17771 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17772 printf ("SoftFP\n");
17773 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17774 printf ("Soft\n");
17775 break;
17776 case Tag_CSKY_FPU_ROUNDING:
17777 READ_ULEB (val, p, end);
f253158f
NC
17778 if (val == 1)
17779 {
17780 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17781 printf ("Needed\n");
17782 }
0861f561
CQ
17783 break;
17784 case Tag_CSKY_FPU_DENORMAL:
17785 READ_ULEB (val, p, end);
f253158f
NC
17786 if (val == 1)
17787 {
17788 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17789 printf ("Needed\n");
17790 }
0861f561
CQ
17791 break;
17792 case Tag_CSKY_FPU_Exception:
17793 READ_ULEB (val, p, end);
f253158f
NC
17794 if (val == 1)
17795 {
17796 printf (" Tag_CSKY_FPU_Exception:\t");
17797 printf ("Needed\n");
17798 }
0861f561
CQ
17799 break;
17800 case Tag_CSKY_FPU_NUMBER_MODULE:
17801 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17802 return display_tag_value (-1, p, end);
17803 case Tag_CSKY_FPU_HARDFP:
17804 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17805 READ_ULEB (val, p, end);
17806 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17807 printf (" Half");
17808 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17809 printf (" Single");
17810 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17811 printf (" Double");
17812 printf ("\n");
17813 break;
17814 default:
17815 return display_tag_value (tag, p, end);
17816 }
17817 return p;
17818}
17819
015dc7e1 17820static bool
dda8d76d 17821process_attributes (Filedata * filedata,
60bca95a 17822 const char * public_name,
104d59d1 17823 unsigned int proc_type,
f6f0e17b 17824 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17825 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17826{
2cf0635d 17827 Elf_Internal_Shdr * sect;
11c1ff18 17828 unsigned i;
015dc7e1 17829 bool res = true;
11c1ff18
PB
17830
17831 /* Find the section header so that we get the size. */
dda8d76d
NC
17832 for (i = 0, sect = filedata->section_headers;
17833 i < filedata->file_header.e_shnum;
11c1ff18
PB
17834 i++, sect++)
17835 {
071436c6
NC
17836 unsigned char * contents;
17837 unsigned char * p;
17838
104d59d1 17839 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17840 continue;
17841
dda8d76d 17842 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17843 sect->sh_size, _("attributes"));
60bca95a 17844 if (contents == NULL)
32ec8896 17845 {
015dc7e1 17846 res = false;
32ec8896
NC
17847 continue;
17848 }
60bca95a 17849
11c1ff18 17850 p = contents;
60abdbed
NC
17851 /* The first character is the version of the attributes.
17852 Currently only version 1, (aka 'A') is recognised here. */
17853 if (*p != 'A')
32ec8896
NC
17854 {
17855 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17856 res = false;
32ec8896 17857 }
60abdbed 17858 else
11c1ff18 17859 {
625d49fc 17860 uint64_t section_len;
071436c6
NC
17861
17862 section_len = sect->sh_size - 1;
11c1ff18 17863 p++;
60bca95a 17864
071436c6 17865 while (section_len > 0)
11c1ff18 17866 {
625d49fc 17867 uint64_t attr_len;
e9847026 17868 unsigned int namelen;
015dc7e1
AM
17869 bool public_section;
17870 bool gnu_section;
11c1ff18 17871
071436c6 17872 if (section_len <= 4)
e0a31db1
NC
17873 {
17874 error (_("Tag section ends prematurely\n"));
015dc7e1 17875 res = false;
e0a31db1
NC
17876 break;
17877 }
071436c6 17878 attr_len = byte_get (p, 4);
11c1ff18 17879 p += 4;
60bca95a 17880
071436c6 17881 if (attr_len > section_len)
11c1ff18 17882 {
071436c6
NC
17883 error (_("Bad attribute length (%u > %u)\n"),
17884 (unsigned) attr_len, (unsigned) section_len);
17885 attr_len = section_len;
015dc7e1 17886 res = false;
11c1ff18 17887 }
74e1a04b 17888 /* PR 17531: file: 001-101425-0.004 */
071436c6 17889 else if (attr_len < 5)
74e1a04b 17890 {
071436c6 17891 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17892 res = false;
74e1a04b
NC
17893 break;
17894 }
e9847026 17895
071436c6
NC
17896 section_len -= attr_len;
17897 attr_len -= 4;
17898
17899 namelen = strnlen ((char *) p, attr_len) + 1;
17900 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17901 {
17902 error (_("Corrupt attribute section name\n"));
015dc7e1 17903 res = false;
e9847026
NC
17904 break;
17905 }
17906
071436c6
NC
17907 printf (_("Attribute Section: "));
17908 print_symbol (INT_MAX, (const char *) p);
17909 putchar ('\n');
60bca95a
NC
17910
17911 if (public_name && streq ((char *) p, public_name))
015dc7e1 17912 public_section = true;
11c1ff18 17913 else
015dc7e1 17914 public_section = false;
60bca95a
NC
17915
17916 if (streq ((char *) p, "gnu"))
015dc7e1 17917 gnu_section = true;
104d59d1 17918 else
015dc7e1 17919 gnu_section = false;
60bca95a 17920
11c1ff18 17921 p += namelen;
071436c6 17922 attr_len -= namelen;
e0a31db1 17923
071436c6 17924 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17925 {
e0a31db1 17926 int tag;
cd30bcef 17927 unsigned int val;
625d49fc 17928 uint64_t size;
071436c6 17929 unsigned char * end;
60bca95a 17930
e0a31db1 17931 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17932 if (attr_len < 6)
e0a31db1
NC
17933 {
17934 error (_("Unused bytes at end of section\n"));
015dc7e1 17935 res = false;
e0a31db1
NC
17936 section_len = 0;
17937 break;
17938 }
17939
17940 tag = *(p++);
11c1ff18 17941 size = byte_get (p, 4);
071436c6 17942 if (size > attr_len)
11c1ff18 17943 {
e9847026 17944 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17945 (unsigned) size, (unsigned) attr_len);
015dc7e1 17946 res = false;
071436c6 17947 size = attr_len;
11c1ff18 17948 }
e0a31db1
NC
17949 /* PR binutils/17531: Safe handling of corrupt files. */
17950 if (size < 6)
17951 {
17952 error (_("Bad subsection length (%u < 6)\n"),
17953 (unsigned) size);
015dc7e1 17954 res = false;
e0a31db1
NC
17955 section_len = 0;
17956 break;
17957 }
60bca95a 17958
071436c6 17959 attr_len -= size;
11c1ff18 17960 end = p + size - 1;
071436c6 17961 assert (end <= contents + sect->sh_size);
11c1ff18 17962 p += 4;
60bca95a 17963
11c1ff18
PB
17964 switch (tag)
17965 {
17966 case 1:
2b692964 17967 printf (_("File Attributes\n"));
11c1ff18
PB
17968 break;
17969 case 2:
2b692964 17970 printf (_("Section Attributes:"));
11c1ff18
PB
17971 goto do_numlist;
17972 case 3:
2b692964 17973 printf (_("Symbol Attributes:"));
1a0670f3 17974 /* Fall through. */
11c1ff18
PB
17975 do_numlist:
17976 for (;;)
17977 {
cd30bcef 17978 READ_ULEB (val, p, end);
11c1ff18
PB
17979 if (val == 0)
17980 break;
17981 printf (" %d", val);
17982 }
17983 printf ("\n");
17984 break;
17985 default:
2b692964 17986 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17987 public_section = false;
11c1ff18
PB
17988 break;
17989 }
60bca95a 17990
071436c6 17991 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17992 {
17993 while (p < end)
f6f0e17b 17994 p = display_pub_attribute (p, end);
60abdbed 17995 assert (p == end);
104d59d1 17996 }
071436c6 17997 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17998 {
17999 while (p < end)
18000 p = display_gnu_attribute (p,
f6f0e17b
NC
18001 display_proc_gnu_attribute,
18002 end);
60abdbed 18003 assert (p == end);
11c1ff18 18004 }
071436c6 18005 else if (p < end)
11c1ff18 18006 {
071436c6 18007 printf (_(" Unknown attribute:\n"));
f6f0e17b 18008 display_raw_attribute (p, end);
11c1ff18
PB
18009 p = end;
18010 }
071436c6
NC
18011 else
18012 attr_len = 0;
11c1ff18
PB
18013 }
18014 }
18015 }
d70c5fc7 18016
60bca95a 18017 free (contents);
11c1ff18 18018 }
32ec8896
NC
18019
18020 return res;
11c1ff18
PB
18021}
18022
ccb4c951
RS
18023/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18024 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18025 and return the VMA of the next entry, or -1 if there was a problem.
18026 Does not read from DATA_END or beyond. */
ccb4c951 18027
625d49fc
AM
18028static uint64_t
18029print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18030 unsigned char * data_end)
ccb4c951
RS
18031{
18032 printf (" ");
18033 print_vma (addr, LONG_HEX);
18034 printf (" ");
18035 if (addr < pltgot + 0xfff0)
18036 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18037 else
18038 printf ("%10s", "");
18039 printf (" ");
18040 if (data == NULL)
2b692964 18041 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18042 else
18043 {
625d49fc 18044 uint64_t entry;
82b1b41b 18045 unsigned char * from = data + addr - pltgot;
ccb4c951 18046
82b1b41b
NC
18047 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18048 {
18049 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18050 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18051 return (uint64_t) -1;
82b1b41b
NC
18052 }
18053 else
18054 {
18055 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18056 print_vma (entry, LONG_HEX);
18057 }
ccb4c951
RS
18058 }
18059 return addr + (is_32bit_elf ? 4 : 8);
18060}
18061
861fb55a
DJ
18062/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18063 PLTGOT. Print the Address and Initial fields of an entry at VMA
18064 ADDR and return the VMA of the next entry. */
18065
625d49fc
AM
18066static uint64_t
18067print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18068{
18069 printf (" ");
18070 print_vma (addr, LONG_HEX);
18071 printf (" ");
18072 if (data == NULL)
2b692964 18073 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18074 else
18075 {
625d49fc 18076 uint64_t entry;
861fb55a
DJ
18077
18078 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18079 print_vma (entry, LONG_HEX);
18080 }
18081 return addr + (is_32bit_elf ? 4 : 8);
18082}
18083
351cdf24
MF
18084static void
18085print_mips_ases (unsigned int mask)
18086{
18087 if (mask & AFL_ASE_DSP)
18088 fputs ("\n\tDSP ASE", stdout);
18089 if (mask & AFL_ASE_DSPR2)
18090 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18091 if (mask & AFL_ASE_DSPR3)
18092 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18093 if (mask & AFL_ASE_EVA)
18094 fputs ("\n\tEnhanced VA Scheme", stdout);
18095 if (mask & AFL_ASE_MCU)
18096 fputs ("\n\tMCU (MicroController) ASE", stdout);
18097 if (mask & AFL_ASE_MDMX)
18098 fputs ("\n\tMDMX ASE", stdout);
18099 if (mask & AFL_ASE_MIPS3D)
18100 fputs ("\n\tMIPS-3D ASE", stdout);
18101 if (mask & AFL_ASE_MT)
18102 fputs ("\n\tMT ASE", stdout);
18103 if (mask & AFL_ASE_SMARTMIPS)
18104 fputs ("\n\tSmartMIPS ASE", stdout);
18105 if (mask & AFL_ASE_VIRT)
18106 fputs ("\n\tVZ ASE", stdout);
18107 if (mask & AFL_ASE_MSA)
18108 fputs ("\n\tMSA ASE", stdout);
18109 if (mask & AFL_ASE_MIPS16)
18110 fputs ("\n\tMIPS16 ASE", stdout);
18111 if (mask & AFL_ASE_MICROMIPS)
18112 fputs ("\n\tMICROMIPS ASE", stdout);
18113 if (mask & AFL_ASE_XPA)
18114 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18115 if (mask & AFL_ASE_MIPS16E2)
18116 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18117 if (mask & AFL_ASE_CRC)
18118 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18119 if (mask & AFL_ASE_GINV)
18120 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18121 if (mask & AFL_ASE_LOONGSON_MMI)
18122 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18123 if (mask & AFL_ASE_LOONGSON_CAM)
18124 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18125 if (mask & AFL_ASE_LOONGSON_EXT)
18126 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18127 if (mask & AFL_ASE_LOONGSON_EXT2)
18128 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18129 if (mask == 0)
18130 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18131 else if ((mask & ~AFL_ASE_MASK) != 0)
18132 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18133}
18134
18135static void
18136print_mips_isa_ext (unsigned int isa_ext)
18137{
18138 switch (isa_ext)
18139 {
18140 case 0:
18141 fputs (_("None"), stdout);
18142 break;
18143 case AFL_EXT_XLR:
18144 fputs ("RMI XLR", stdout);
18145 break;
2c629856
N
18146 case AFL_EXT_OCTEON3:
18147 fputs ("Cavium Networks Octeon3", stdout);
18148 break;
351cdf24
MF
18149 case AFL_EXT_OCTEON2:
18150 fputs ("Cavium Networks Octeon2", stdout);
18151 break;
18152 case AFL_EXT_OCTEONP:
18153 fputs ("Cavium Networks OcteonP", stdout);
18154 break;
351cdf24
MF
18155 case AFL_EXT_OCTEON:
18156 fputs ("Cavium Networks Octeon", stdout);
18157 break;
18158 case AFL_EXT_5900:
18159 fputs ("Toshiba R5900", stdout);
18160 break;
18161 case AFL_EXT_4650:
18162 fputs ("MIPS R4650", stdout);
18163 break;
18164 case AFL_EXT_4010:
18165 fputs ("LSI R4010", stdout);
18166 break;
18167 case AFL_EXT_4100:
18168 fputs ("NEC VR4100", stdout);
18169 break;
18170 case AFL_EXT_3900:
18171 fputs ("Toshiba R3900", stdout);
18172 break;
18173 case AFL_EXT_10000:
18174 fputs ("MIPS R10000", stdout);
18175 break;
18176 case AFL_EXT_SB1:
18177 fputs ("Broadcom SB-1", stdout);
18178 break;
18179 case AFL_EXT_4111:
18180 fputs ("NEC VR4111/VR4181", stdout);
18181 break;
18182 case AFL_EXT_4120:
18183 fputs ("NEC VR4120", stdout);
18184 break;
18185 case AFL_EXT_5400:
18186 fputs ("NEC VR5400", stdout);
18187 break;
18188 case AFL_EXT_5500:
18189 fputs ("NEC VR5500", stdout);
18190 break;
18191 case AFL_EXT_LOONGSON_2E:
18192 fputs ("ST Microelectronics Loongson 2E", stdout);
18193 break;
18194 case AFL_EXT_LOONGSON_2F:
18195 fputs ("ST Microelectronics Loongson 2F", stdout);
18196 break;
38bf472a
MR
18197 case AFL_EXT_INTERAPTIV_MR2:
18198 fputs ("Imagination interAptiv MR2", stdout);
18199 break;
351cdf24 18200 default:
00ac7aa0 18201 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18202 }
18203}
18204
32ec8896 18205static signed int
351cdf24
MF
18206get_mips_reg_size (int reg_size)
18207{
18208 return (reg_size == AFL_REG_NONE) ? 0
18209 : (reg_size == AFL_REG_32) ? 32
18210 : (reg_size == AFL_REG_64) ? 64
18211 : (reg_size == AFL_REG_128) ? 128
18212 : -1;
18213}
18214
015dc7e1 18215static bool
dda8d76d 18216process_mips_specific (Filedata * filedata)
5b18a4bc 18217{
2cf0635d 18218 Elf_Internal_Dyn * entry;
351cdf24 18219 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18220 size_t liblist_offset = 0;
18221 size_t liblistno = 0;
18222 size_t conflictsno = 0;
18223 size_t options_offset = 0;
18224 size_t conflicts_offset = 0;
861fb55a
DJ
18225 size_t pltrelsz = 0;
18226 size_t pltrel = 0;
625d49fc
AM
18227 uint64_t pltgot = 0;
18228 uint64_t mips_pltgot = 0;
18229 uint64_t jmprel = 0;
18230 uint64_t local_gotno = 0;
18231 uint64_t gotsym = 0;
18232 uint64_t symtabno = 0;
015dc7e1 18233 bool res = true;
103f02d3 18234
dda8d76d 18235 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18236 display_mips_gnu_attribute))
015dc7e1 18237 res = false;
2cf19d5c 18238
dda8d76d 18239 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18240
18241 if (sect != NULL)
18242 {
18243 Elf_External_ABIFlags_v0 *abiflags_ext;
18244 Elf_Internal_ABIFlags_v0 abiflags_in;
18245
18246 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18247 {
18248 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18249 res = false;
32ec8896 18250 }
351cdf24
MF
18251 else
18252 {
dda8d76d 18253 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18254 sect->sh_size, _("MIPS ABI Flags section"));
18255 if (abiflags_ext)
18256 {
18257 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18258 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18259 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18260 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18261 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18262 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18263 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18264 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18265 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18266 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18267 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18268
18269 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18270 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18271 if (abiflags_in.isa_rev > 1)
18272 printf ("r%d", abiflags_in.isa_rev);
18273 printf ("\nGPR size: %d",
18274 get_mips_reg_size (abiflags_in.gpr_size));
18275 printf ("\nCPR1 size: %d",
18276 get_mips_reg_size (abiflags_in.cpr1_size));
18277 printf ("\nCPR2 size: %d",
18278 get_mips_reg_size (abiflags_in.cpr2_size));
18279 fputs ("\nFP ABI: ", stdout);
18280 print_mips_fp_abi_value (abiflags_in.fp_abi);
18281 fputs ("ISA Extension: ", stdout);
18282 print_mips_isa_ext (abiflags_in.isa_ext);
18283 fputs ("\nASEs:", stdout);
18284 print_mips_ases (abiflags_in.ases);
18285 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18286 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18287 fputc ('\n', stdout);
18288 free (abiflags_ext);
18289 }
18290 }
18291 }
18292
19e6b90e 18293 /* We have a lot of special sections. Thanks SGI! */
978c4450 18294 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18295 {
18296 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18297 sect = find_section (filedata, ".got");
bbdd9a68
MR
18298 if (sect != NULL)
18299 {
18300 unsigned char *data_end;
18301 unsigned char *data;
625d49fc 18302 uint64_t ent, end;
bbdd9a68
MR
18303 int addr_size;
18304
18305 pltgot = sect->sh_addr;
18306
18307 ent = pltgot;
18308 addr_size = (is_32bit_elf ? 4 : 8);
18309 end = pltgot + sect->sh_size;
18310
dda8d76d 18311 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18312 end - pltgot, 1,
18313 _("Global Offset Table data"));
18314 /* PR 12855: Null data is handled gracefully throughout. */
18315 data_end = data + (end - pltgot);
18316
18317 printf (_("\nStatic GOT:\n"));
18318 printf (_(" Canonical gp value: "));
18319 print_vma (ent + 0x7ff0, LONG_HEX);
18320 printf ("\n\n");
18321
18322 /* In a dynamic binary GOT[0] is reserved for the dynamic
18323 loader to store the lazy resolver pointer, however in
18324 a static binary it may well have been omitted and GOT
18325 reduced to a table of addresses.
18326 PR 21344: Check for the entry being fully available
18327 before fetching it. */
18328 if (data
18329 && data + ent - pltgot + addr_size <= data_end
18330 && byte_get (data + ent - pltgot, addr_size) == 0)
18331 {
18332 printf (_(" Reserved entries:\n"));
18333 printf (_(" %*s %10s %*s\n"),
18334 addr_size * 2, _("Address"), _("Access"),
18335 addr_size * 2, _("Value"));
18336 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18337 printf ("\n");
625d49fc 18338 if (ent == (uint64_t) -1)
bbdd9a68
MR
18339 goto sgot_print_fail;
18340
18341 /* Check for the MSB of GOT[1] being set, identifying a
18342 GNU object. This entry will be used by some runtime
18343 loaders, to store the module pointer. Otherwise this
18344 is an ordinary local entry.
18345 PR 21344: Check for the entry being fully available
18346 before fetching it. */
18347 if (data
18348 && data + ent - pltgot + addr_size <= data_end
18349 && (byte_get (data + ent - pltgot, addr_size)
18350 >> (addr_size * 8 - 1)) != 0)
18351 {
18352 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18353 printf ("\n");
625d49fc 18354 if (ent == (uint64_t) -1)
bbdd9a68
MR
18355 goto sgot_print_fail;
18356 }
18357 printf ("\n");
18358 }
18359
f17e9d8a 18360 if (data != NULL && ent < end)
bbdd9a68
MR
18361 {
18362 printf (_(" Local entries:\n"));
18363 printf (" %*s %10s %*s\n",
18364 addr_size * 2, _("Address"), _("Access"),
18365 addr_size * 2, _("Value"));
18366 while (ent < end)
18367 {
18368 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18369 printf ("\n");
625d49fc 18370 if (ent == (uint64_t) -1)
bbdd9a68
MR
18371 goto sgot_print_fail;
18372 }
18373 printf ("\n");
18374 }
18375
18376 sgot_print_fail:
9db70fc3 18377 free (data);
bbdd9a68
MR
18378 }
18379 return res;
18380 }
252b5132 18381
978c4450 18382 for (entry = filedata->dynamic_section;
071436c6 18383 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18384 (entry < filedata->dynamic_section + filedata->dynamic_nent
18385 && entry->d_tag != DT_NULL);
071436c6 18386 ++entry)
252b5132
RH
18387 switch (entry->d_tag)
18388 {
18389 case DT_MIPS_LIBLIST:
d93f0186 18390 liblist_offset
dda8d76d 18391 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18392 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18393 break;
18394 case DT_MIPS_LIBLISTNO:
18395 liblistno = entry->d_un.d_val;
18396 break;
18397 case DT_MIPS_OPTIONS:
dda8d76d 18398 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18399 break;
18400 case DT_MIPS_CONFLICT:
d93f0186 18401 conflicts_offset
dda8d76d 18402 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18403 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18404 break;
18405 case DT_MIPS_CONFLICTNO:
18406 conflictsno = entry->d_un.d_val;
18407 break;
ccb4c951 18408 case DT_PLTGOT:
861fb55a
DJ
18409 pltgot = entry->d_un.d_ptr;
18410 break;
ccb4c951
RS
18411 case DT_MIPS_LOCAL_GOTNO:
18412 local_gotno = entry->d_un.d_val;
18413 break;
18414 case DT_MIPS_GOTSYM:
18415 gotsym = entry->d_un.d_val;
18416 break;
18417 case DT_MIPS_SYMTABNO:
18418 symtabno = entry->d_un.d_val;
18419 break;
861fb55a
DJ
18420 case DT_MIPS_PLTGOT:
18421 mips_pltgot = entry->d_un.d_ptr;
18422 break;
18423 case DT_PLTREL:
18424 pltrel = entry->d_un.d_val;
18425 break;
18426 case DT_PLTRELSZ:
18427 pltrelsz = entry->d_un.d_val;
18428 break;
18429 case DT_JMPREL:
18430 jmprel = entry->d_un.d_ptr;
18431 break;
252b5132
RH
18432 default:
18433 break;
18434 }
18435
18436 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18437 {
2cf0635d 18438 Elf32_External_Lib * elib;
252b5132
RH
18439 size_t cnt;
18440
dda8d76d 18441 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18442 sizeof (Elf32_External_Lib),
18443 liblistno,
18444 _("liblist section data"));
a6e9f9df 18445 if (elib)
252b5132 18446 {
d3a49aa8
AM
18447 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18448 "\nSection '.liblist' contains %lu entries:\n",
18449 (unsigned long) liblistno),
a6e9f9df 18450 (unsigned long) liblistno);
2b692964 18451 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18452 stdout);
18453
18454 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18455 {
a6e9f9df 18456 Elf32_Lib liblist;
91d6fa6a 18457 time_t atime;
d5b07ef4 18458 char timebuf[128];
2cf0635d 18459 struct tm * tmp;
a6e9f9df
AM
18460
18461 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18462 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18463 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18464 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18465 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18466
91d6fa6a 18467 tmp = gmtime (&atime);
e9e44622
JJ
18468 snprintf (timebuf, sizeof (timebuf),
18469 "%04u-%02u-%02uT%02u:%02u:%02u",
18470 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18471 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18472
31104126 18473 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18474 if (valid_dynamic_name (filedata, liblist.l_name))
18475 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18476 else
2b692964 18477 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18478 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18479 liblist.l_version);
a6e9f9df
AM
18480
18481 if (liblist.l_flags == 0)
2b692964 18482 puts (_(" NONE"));
a6e9f9df
AM
18483 else
18484 {
18485 static const struct
252b5132 18486 {
2cf0635d 18487 const char * name;
a6e9f9df 18488 int bit;
252b5132 18489 }
a6e9f9df
AM
18490 l_flags_vals[] =
18491 {
18492 { " EXACT_MATCH", LL_EXACT_MATCH },
18493 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18494 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18495 { " EXPORTS", LL_EXPORTS },
18496 { " DELAY_LOAD", LL_DELAY_LOAD },
18497 { " DELTA", LL_DELTA }
18498 };
18499 int flags = liblist.l_flags;
18500 size_t fcnt;
18501
60bca95a 18502 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18503 if ((flags & l_flags_vals[fcnt].bit) != 0)
18504 {
18505 fputs (l_flags_vals[fcnt].name, stdout);
18506 flags ^= l_flags_vals[fcnt].bit;
18507 }
18508 if (flags != 0)
18509 printf (" %#x", (unsigned int) flags);
252b5132 18510
a6e9f9df
AM
18511 puts ("");
18512 }
252b5132 18513 }
252b5132 18514
a6e9f9df
AM
18515 free (elib);
18516 }
32ec8896 18517 else
015dc7e1 18518 res = false;
252b5132
RH
18519 }
18520
18521 if (options_offset != 0)
18522 {
2cf0635d 18523 Elf_External_Options * eopt;
252b5132
RH
18524 size_t offset;
18525 int cnt;
18526
18527 /* Find the section header so that we get the size. */
dda8d76d 18528 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18529 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18530 if (sect == NULL)
18531 {
18532 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18533 return false;
071436c6 18534 }
7fc0c668
NC
18535 /* PR 24243 */
18536 if (sect->sh_size < sizeof (* eopt))
18537 {
18538 error (_("The MIPS options section is too small.\n"));
015dc7e1 18539 return false;
7fc0c668 18540 }
252b5132 18541
dda8d76d 18542 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18543 sect->sh_size, _("options"));
a6e9f9df 18544 if (eopt)
252b5132 18545 {
fd17d1e6 18546 Elf_Internal_Options option;
76da6bbe 18547
a6e9f9df 18548 offset = cnt = 0;
82b1b41b 18549 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18550 {
2cf0635d 18551 Elf_External_Options * eoption;
fd17d1e6 18552 unsigned int optsize;
252b5132 18553
a6e9f9df 18554 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18555
fd17d1e6 18556 optsize = BYTE_GET (eoption->size);
76da6bbe 18557
82b1b41b 18558 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18559 if (optsize < sizeof (* eopt)
18560 || optsize > sect->sh_size - offset)
82b1b41b 18561 {
645f43a8 18562 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18563 optsize);
645f43a8 18564 free (eopt);
015dc7e1 18565 return false;
82b1b41b 18566 }
fd17d1e6 18567 offset += optsize;
a6e9f9df
AM
18568 ++cnt;
18569 }
252b5132 18570
d3a49aa8
AM
18571 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18572 "\nSection '%s' contains %d entries:\n",
18573 cnt),
dda8d76d 18574 printable_section_name (filedata, sect), cnt);
76da6bbe 18575
82b1b41b 18576 offset = 0;
a6e9f9df 18577 while (cnt-- > 0)
252b5132 18578 {
a6e9f9df 18579 size_t len;
fd17d1e6
AM
18580 Elf_External_Options * eoption;
18581
18582 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18583
18584 option.kind = BYTE_GET (eoption->kind);
18585 option.size = BYTE_GET (eoption->size);
18586 option.section = BYTE_GET (eoption->section);
18587 option.info = BYTE_GET (eoption->info);
a6e9f9df 18588
fd17d1e6 18589 switch (option.kind)
252b5132 18590 {
a6e9f9df
AM
18591 case ODK_NULL:
18592 /* This shouldn't happen. */
d0c4e780 18593 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18594 option.section, option.info);
a6e9f9df 18595 break;
2e6be59c 18596
a6e9f9df
AM
18597 case ODK_REGINFO:
18598 printf (" REGINFO ");
dda8d76d 18599 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18600 {
2cf0635d 18601 Elf32_External_RegInfo * ereg;
b34976b6 18602 Elf32_RegInfo reginfo;
a6e9f9df 18603
2e6be59c 18604 /* 32bit form. */
fd17d1e6
AM
18605 if (option.size < (sizeof (Elf_External_Options)
18606 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18607 {
18608 printf (_("<corrupt>\n"));
18609 error (_("Truncated MIPS REGINFO option\n"));
18610 cnt = 0;
18611 break;
18612 }
18613
fd17d1e6 18614 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18615
a6e9f9df
AM
18616 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18617 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18618 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18619 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18620 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18621 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18622
d0c4e780
AM
18623 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18624 reginfo.ri_gprmask, reginfo.ri_gp_value);
18625 printf (" "
18626 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18627 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18628 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18629 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18630 }
18631 else
18632 {
18633 /* 64 bit form. */
2cf0635d 18634 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18635 Elf64_Internal_RegInfo reginfo;
18636
fd17d1e6
AM
18637 if (option.size < (sizeof (Elf_External_Options)
18638 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18639 {
18640 printf (_("<corrupt>\n"));
18641 error (_("Truncated MIPS REGINFO option\n"));
18642 cnt = 0;
18643 break;
18644 }
18645
fd17d1e6 18646 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18647 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18648 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18649 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18650 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18651 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18652 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18653
d0c4e780
AM
18654 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18655 reginfo.ri_gprmask, reginfo.ri_gp_value);
18656 printf (" "
18657 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18658 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18659 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18660 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18661 }
fd17d1e6 18662 offset += option.size;
a6e9f9df 18663 continue;
2e6be59c 18664
a6e9f9df
AM
18665 case ODK_EXCEPTIONS:
18666 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18667 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18668 fputs (") fpe_max(", stdout);
fd17d1e6 18669 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18670 fputs (")", stdout);
18671
fd17d1e6 18672 if (option.info & OEX_PAGE0)
a6e9f9df 18673 fputs (" PAGE0", stdout);
fd17d1e6 18674 if (option.info & OEX_SMM)
a6e9f9df 18675 fputs (" SMM", stdout);
fd17d1e6 18676 if (option.info & OEX_FPDBUG)
a6e9f9df 18677 fputs (" FPDBUG", stdout);
fd17d1e6 18678 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18679 fputs (" DISMISS", stdout);
18680 break;
2e6be59c 18681
a6e9f9df
AM
18682 case ODK_PAD:
18683 fputs (" PAD ", stdout);
fd17d1e6 18684 if (option.info & OPAD_PREFIX)
a6e9f9df 18685 fputs (" PREFIX", stdout);
fd17d1e6 18686 if (option.info & OPAD_POSTFIX)
a6e9f9df 18687 fputs (" POSTFIX", stdout);
fd17d1e6 18688 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18689 fputs (" SYMBOL", stdout);
18690 break;
2e6be59c 18691
a6e9f9df
AM
18692 case ODK_HWPATCH:
18693 fputs (" HWPATCH ", stdout);
fd17d1e6 18694 if (option.info & OHW_R4KEOP)
a6e9f9df 18695 fputs (" R4KEOP", stdout);
fd17d1e6 18696 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18697 fputs (" R8KPFETCH", stdout);
fd17d1e6 18698 if (option.info & OHW_R5KEOP)
a6e9f9df 18699 fputs (" R5KEOP", stdout);
fd17d1e6 18700 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18701 fputs (" R5KCVTL", stdout);
18702 break;
2e6be59c 18703
a6e9f9df
AM
18704 case ODK_FILL:
18705 fputs (" FILL ", stdout);
18706 /* XXX Print content of info word? */
18707 break;
2e6be59c 18708
a6e9f9df
AM
18709 case ODK_TAGS:
18710 fputs (" TAGS ", stdout);
18711 /* XXX Print content of info word? */
18712 break;
2e6be59c 18713
a6e9f9df
AM
18714 case ODK_HWAND:
18715 fputs (" HWAND ", stdout);
fd17d1e6 18716 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18717 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18718 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18719 fputs (" R4KEOP_CLEAN", stdout);
18720 break;
2e6be59c 18721
a6e9f9df
AM
18722 case ODK_HWOR:
18723 fputs (" HWOR ", stdout);
fd17d1e6 18724 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18725 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18726 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18727 fputs (" R4KEOP_CLEAN", stdout);
18728 break;
2e6be59c 18729
a6e9f9df 18730 case ODK_GP_GROUP:
d0c4e780 18731 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18732 option.info & OGP_GROUP,
18733 (option.info & OGP_SELF) >> 16);
a6e9f9df 18734 break;
2e6be59c 18735
a6e9f9df 18736 case ODK_IDENT:
d0c4e780 18737 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18738 option.info & OGP_GROUP,
18739 (option.info & OGP_SELF) >> 16);
a6e9f9df 18740 break;
2e6be59c 18741
a6e9f9df
AM
18742 default:
18743 /* This shouldn't happen. */
d0c4e780 18744 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18745 option.kind, option.section, option.info);
a6e9f9df 18746 break;
252b5132 18747 }
a6e9f9df 18748
2cf0635d 18749 len = sizeof (* eopt);
fd17d1e6 18750 while (len < option.size)
82b1b41b 18751 {
fd17d1e6 18752 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18753
82b1b41b
NC
18754 if (ISPRINT (datum))
18755 printf ("%c", datum);
18756 else
18757 printf ("\\%03o", datum);
18758 len ++;
18759 }
a6e9f9df 18760 fputs ("\n", stdout);
82b1b41b 18761
fd17d1e6 18762 offset += option.size;
252b5132 18763 }
a6e9f9df 18764 free (eopt);
252b5132 18765 }
32ec8896 18766 else
015dc7e1 18767 res = false;
252b5132
RH
18768 }
18769
18770 if (conflicts_offset != 0 && conflictsno != 0)
18771 {
2cf0635d 18772 Elf32_Conflict * iconf;
252b5132
RH
18773 size_t cnt;
18774
978c4450 18775 if (filedata->dynamic_symbols == NULL)
252b5132 18776 {
591a748a 18777 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18778 return false;
252b5132
RH
18779 }
18780
7296a62a
NC
18781 /* PR 21345 - print a slightly more helpful error message
18782 if we are sure that the cmalloc will fail. */
645f43a8 18783 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18784 {
18785 error (_("Overlarge number of conflicts detected: %lx\n"),
18786 (long) conflictsno);
015dc7e1 18787 return false;
7296a62a
NC
18788 }
18789
3f5e193b 18790 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18791 if (iconf == NULL)
18792 {
8b73c356 18793 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18794 return false;
252b5132
RH
18795 }
18796
9ea033b2 18797 if (is_32bit_elf)
252b5132 18798 {
2cf0635d 18799 Elf32_External_Conflict * econf32;
a6e9f9df 18800
3f5e193b 18801 econf32 = (Elf32_External_Conflict *)
95099889
AM
18802 get_data (NULL, filedata, conflicts_offset,
18803 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18804 if (!econf32)
5a814d6d
AM
18805 {
18806 free (iconf);
015dc7e1 18807 return false;
5a814d6d 18808 }
252b5132
RH
18809
18810 for (cnt = 0; cnt < conflictsno; ++cnt)
18811 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18812
18813 free (econf32);
252b5132
RH
18814 }
18815 else
18816 {
2cf0635d 18817 Elf64_External_Conflict * econf64;
a6e9f9df 18818
3f5e193b 18819 econf64 = (Elf64_External_Conflict *)
95099889
AM
18820 get_data (NULL, filedata, conflicts_offset,
18821 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18822 if (!econf64)
5a814d6d
AM
18823 {
18824 free (iconf);
015dc7e1 18825 return false;
5a814d6d 18826 }
252b5132
RH
18827
18828 for (cnt = 0; cnt < conflictsno; ++cnt)
18829 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18830
18831 free (econf64);
252b5132
RH
18832 }
18833
d3a49aa8
AM
18834 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18835 "\nSection '.conflict' contains %lu entries:\n",
18836 (unsigned long) conflictsno),
c7e7ca54 18837 (unsigned long) conflictsno);
252b5132
RH
18838 puts (_(" Num: Index Value Name"));
18839
18840 for (cnt = 0; cnt < conflictsno; ++cnt)
18841 {
b34976b6 18842 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18843
978c4450 18844 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18845 printf (_("<corrupt symbol index>"));
d79b3d50 18846 else
e0a31db1
NC
18847 {
18848 Elf_Internal_Sym * psym;
18849
978c4450 18850 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18851 print_vma (psym->st_value, FULL_HEX);
18852 putchar (' ');
84714f86
AM
18853 if (valid_dynamic_name (filedata, psym->st_name))
18854 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18855 else
18856 printf (_("<corrupt: %14ld>"), psym->st_name);
18857 }
31104126 18858 putchar ('\n');
252b5132
RH
18859 }
18860
252b5132
RH
18861 free (iconf);
18862 }
18863
ccb4c951
RS
18864 if (pltgot != 0 && local_gotno != 0)
18865 {
625d49fc 18866 uint64_t ent, local_end, global_end;
bbeee7ea 18867 size_t i, offset;
2cf0635d 18868 unsigned char * data;
82b1b41b 18869 unsigned char * data_end;
bbeee7ea 18870 int addr_size;
ccb4c951 18871
91d6fa6a 18872 ent = pltgot;
ccb4c951
RS
18873 addr_size = (is_32bit_elf ? 4 : 8);
18874 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18875
74e1a04b
NC
18876 /* PR binutils/17533 file: 012-111227-0.004 */
18877 if (symtabno < gotsym)
18878 {
18879 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18880 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18881 return false;
74e1a04b 18882 }
82b1b41b 18883
74e1a04b 18884 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18885 /* PR 17531: file: 54c91a34. */
18886 if (global_end < local_end)
18887 {
18888 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18889 return false;
82b1b41b 18890 }
948f632f 18891
dda8d76d
NC
18892 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18893 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18894 global_end - pltgot, 1,
18895 _("Global Offset Table data"));
919383ac 18896 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18897 data_end = data + (global_end - pltgot);
59245841 18898
ccb4c951
RS
18899 printf (_("\nPrimary GOT:\n"));
18900 printf (_(" Canonical gp value: "));
18901 print_vma (pltgot + 0x7ff0, LONG_HEX);
18902 printf ("\n\n");
18903
18904 printf (_(" Reserved entries:\n"));
18905 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18906 addr_size * 2, _("Address"), _("Access"),
18907 addr_size * 2, _("Initial"));
82b1b41b 18908 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18909 printf (_(" Lazy resolver\n"));
625d49fc 18910 if (ent == (uint64_t) -1)
82b1b41b 18911 goto got_print_fail;
75ec1fdb 18912
c4ab9505
MR
18913 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18914 This entry will be used by some runtime loaders, to store the
18915 module pointer. Otherwise this is an ordinary local entry.
18916 PR 21344: Check for the entry being fully available before
18917 fetching it. */
18918 if (data
18919 && data + ent - pltgot + addr_size <= data_end
18920 && (byte_get (data + ent - pltgot, addr_size)
18921 >> (addr_size * 8 - 1)) != 0)
18922 {
18923 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18924 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 18925 if (ent == (uint64_t) -1)
c4ab9505 18926 goto got_print_fail;
ccb4c951
RS
18927 }
18928 printf ("\n");
18929
f17e9d8a 18930 if (data != NULL && ent < local_end)
ccb4c951
RS
18931 {
18932 printf (_(" Local entries:\n"));
cc5914eb 18933 printf (" %*s %10s %*s\n",
2b692964
NC
18934 addr_size * 2, _("Address"), _("Access"),
18935 addr_size * 2, _("Initial"));
91d6fa6a 18936 while (ent < local_end)
ccb4c951 18937 {
82b1b41b 18938 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18939 printf ("\n");
625d49fc 18940 if (ent == (uint64_t) -1)
82b1b41b 18941 goto got_print_fail;
ccb4c951
RS
18942 }
18943 printf ("\n");
18944 }
18945
f17e9d8a 18946 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18947 {
18948 int sym_width;
18949
18950 printf (_(" Global entries:\n"));
cc5914eb 18951 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18952 addr_size * 2, _("Address"),
18953 _("Access"),
2b692964 18954 addr_size * 2, _("Initial"),
9cf03b7e
NC
18955 addr_size * 2, _("Sym.Val."),
18956 _("Type"),
18957 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18958 _("Ndx"), _("Name"));
0b4362b0 18959
ccb4c951 18960 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18961
ccb4c951
RS
18962 for (i = gotsym; i < symtabno; i++)
18963 {
82b1b41b 18964 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18965 printf (" ");
e0a31db1 18966
978c4450 18967 if (filedata->dynamic_symbols == NULL)
e0a31db1 18968 printf (_("<no dynamic symbols>"));
978c4450 18969 else if (i < filedata->num_dynamic_syms)
e0a31db1 18970 {
978c4450 18971 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18972
18973 print_vma (psym->st_value, LONG_HEX);
18974 printf (" %-7s %3s ",
dda8d76d
NC
18975 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18976 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18977
84714f86 18978 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18979 print_symbol (sym_width,
84714f86 18980 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18981 else
18982 printf (_("<corrupt: %14ld>"), psym->st_name);
18983 }
ccb4c951 18984 else
7fc5ac57
JBG
18985 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18986 (unsigned long) i);
e0a31db1 18987
ccb4c951 18988 printf ("\n");
625d49fc 18989 if (ent == (uint64_t) -1)
82b1b41b 18990 break;
ccb4c951
RS
18991 }
18992 printf ("\n");
18993 }
18994
82b1b41b 18995 got_print_fail:
9db70fc3 18996 free (data);
ccb4c951
RS
18997 }
18998
861fb55a
DJ
18999 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19000 {
625d49fc 19001 uint64_t ent, end;
861fb55a
DJ
19002 size_t offset, rel_offset;
19003 unsigned long count, i;
2cf0635d 19004 unsigned char * data;
861fb55a 19005 int addr_size, sym_width;
2cf0635d 19006 Elf_Internal_Rela * rels;
861fb55a 19007
dda8d76d 19008 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19009 if (pltrel == DT_RELA)
19010 {
dda8d76d 19011 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19012 return false;
861fb55a
DJ
19013 }
19014 else
19015 {
dda8d76d 19016 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19017 return false;
861fb55a
DJ
19018 }
19019
91d6fa6a 19020 ent = mips_pltgot;
861fb55a
DJ
19021 addr_size = (is_32bit_elf ? 4 : 8);
19022 end = mips_pltgot + (2 + count) * addr_size;
19023
dda8d76d
NC
19024 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19025 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19026 1, _("Procedure Linkage Table data"));
59245841 19027 if (data == NULL)
288f0ba2
AM
19028 {
19029 free (rels);
015dc7e1 19030 return false;
288f0ba2 19031 }
59245841 19032
9cf03b7e 19033 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19034 printf (_(" Reserved entries:\n"));
19035 printf (_(" %*s %*s Purpose\n"),
2b692964 19036 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19037 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19038 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19039 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19040 printf (_(" Module pointer\n"));
861fb55a
DJ
19041 printf ("\n");
19042
19043 printf (_(" Entries:\n"));
cc5914eb 19044 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19045 addr_size * 2, _("Address"),
19046 addr_size * 2, _("Initial"),
19047 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19048 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19049 for (i = 0; i < count; i++)
19050 {
df97ab2a 19051 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19052
91d6fa6a 19053 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19054 printf (" ");
e0a31db1 19055
978c4450 19056 if (idx >= filedata->num_dynamic_syms)
df97ab2a 19057 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 19058 else
e0a31db1 19059 {
978c4450 19060 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19061
19062 print_vma (psym->st_value, LONG_HEX);
19063 printf (" %-7s %3s ",
dda8d76d
NC
19064 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
19065 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 19066 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 19067 print_symbol (sym_width,
84714f86 19068 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19069 else
19070 printf (_("<corrupt: %14ld>"), psym->st_name);
19071 }
861fb55a
DJ
19072 printf ("\n");
19073 }
19074 printf ("\n");
19075
9db70fc3 19076 free (data);
861fb55a
DJ
19077 free (rels);
19078 }
19079
32ec8896 19080 return res;
252b5132
RH
19081}
19082
015dc7e1 19083static bool
dda8d76d 19084process_nds32_specific (Filedata * filedata)
35c08157
KLC
19085{
19086 Elf_Internal_Shdr *sect = NULL;
19087
dda8d76d 19088 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19089 if (sect != NULL && sect->sh_size >= 4)
35c08157 19090 {
9c7b8e9b
AM
19091 unsigned char *buf;
19092 unsigned int flag;
35c08157
KLC
19093
19094 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19095 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19096 _("NDS32 elf flags section"));
35c08157 19097
9c7b8e9b 19098 if (buf == NULL)
015dc7e1 19099 return false;
32ec8896 19100
9c7b8e9b
AM
19101 flag = byte_get (buf, 4);
19102 free (buf);
19103 switch (flag & 0x3)
35c08157
KLC
19104 {
19105 case 0:
19106 printf ("(VEC_SIZE):\tNo entry.\n");
19107 break;
19108 case 1:
19109 printf ("(VEC_SIZE):\t4 bytes\n");
19110 break;
19111 case 2:
19112 printf ("(VEC_SIZE):\t16 bytes\n");
19113 break;
19114 case 3:
19115 printf ("(VEC_SIZE):\treserved\n");
19116 break;
19117 }
19118 }
19119
015dc7e1 19120 return true;
35c08157
KLC
19121}
19122
015dc7e1 19123static bool
dda8d76d 19124process_gnu_liblist (Filedata * filedata)
047b2264 19125{
2cf0635d
NC
19126 Elf_Internal_Shdr * section;
19127 Elf_Internal_Shdr * string_sec;
19128 Elf32_External_Lib * elib;
19129 char * strtab;
c256ffe7 19130 size_t strtab_size;
047b2264 19131 size_t cnt;
d3a49aa8 19132 unsigned long num_liblist;
047b2264 19133 unsigned i;
015dc7e1 19134 bool res = true;
047b2264
JJ
19135
19136 if (! do_arch)
015dc7e1 19137 return true;
047b2264 19138
dda8d76d
NC
19139 for (i = 0, section = filedata->section_headers;
19140 i < filedata->file_header.e_shnum;
b34976b6 19141 i++, section++)
047b2264
JJ
19142 {
19143 switch (section->sh_type)
19144 {
19145 case SHT_GNU_LIBLIST:
dda8d76d 19146 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19147 break;
19148
3f5e193b 19149 elib = (Elf32_External_Lib *)
dda8d76d 19150 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19151 _("liblist section data"));
047b2264
JJ
19152
19153 if (elib == NULL)
32ec8896 19154 {
015dc7e1 19155 res = false;
32ec8896
NC
19156 break;
19157 }
047b2264 19158
dda8d76d
NC
19159 string_sec = filedata->section_headers + section->sh_link;
19160 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19161 string_sec->sh_size,
19162 _("liblist string table"));
047b2264
JJ
19163 if (strtab == NULL
19164 || section->sh_entsize != sizeof (Elf32_External_Lib))
19165 {
19166 free (elib);
2842702f 19167 free (strtab);
015dc7e1 19168 res = false;
047b2264
JJ
19169 break;
19170 }
59245841 19171 strtab_size = string_sec->sh_size;
047b2264 19172
d3a49aa8
AM
19173 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19174 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19175 "\nLibrary list section '%s' contains %lu entries:\n",
19176 num_liblist),
dda8d76d 19177 printable_section_name (filedata, section),
d3a49aa8 19178 num_liblist);
047b2264 19179
2b692964 19180 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19181
19182 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19183 ++cnt)
19184 {
19185 Elf32_Lib liblist;
91d6fa6a 19186 time_t atime;
d5b07ef4 19187 char timebuf[128];
2cf0635d 19188 struct tm * tmp;
047b2264
JJ
19189
19190 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19191 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19192 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19193 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19194 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19195
91d6fa6a 19196 tmp = gmtime (&atime);
e9e44622
JJ
19197 snprintf (timebuf, sizeof (timebuf),
19198 "%04u-%02u-%02uT%02u:%02u:%02u",
19199 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19200 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19201
19202 printf ("%3lu: ", (unsigned long) cnt);
19203 if (do_wide)
c256ffe7 19204 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19205 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19206 else
c256ffe7 19207 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19208 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19209 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19210 liblist.l_version, liblist.l_flags);
19211 }
19212
19213 free (elib);
2842702f 19214 free (strtab);
047b2264
JJ
19215 }
19216 }
19217
32ec8896 19218 return res;
047b2264
JJ
19219}
19220
9437c45b 19221static const char *
dda8d76d 19222get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19223{
19224 static char buff[64];
103f02d3 19225
dda8d76d 19226 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19227 switch (e_type)
19228 {
57346661 19229 case NT_AUXV:
1ec5cd37 19230 return _("NT_AUXV (auxiliary vector)");
57346661 19231 case NT_PRSTATUS:
1ec5cd37 19232 return _("NT_PRSTATUS (prstatus structure)");
57346661 19233 case NT_FPREGSET:
1ec5cd37 19234 return _("NT_FPREGSET (floating point registers)");
57346661 19235 case NT_PRPSINFO:
1ec5cd37 19236 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19237 case NT_TASKSTRUCT:
1ec5cd37 19238 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19239 case NT_GDB_TDESC:
19240 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19241 case NT_PRXFPREG:
1ec5cd37 19242 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19243 case NT_PPC_VMX:
19244 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19245 case NT_PPC_VSX:
19246 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19247 case NT_PPC_TAR:
19248 return _("NT_PPC_TAR (ppc TAR register)");
19249 case NT_PPC_PPR:
19250 return _("NT_PPC_PPR (ppc PPR register)");
19251 case NT_PPC_DSCR:
19252 return _("NT_PPC_DSCR (ppc DSCR register)");
19253 case NT_PPC_EBB:
19254 return _("NT_PPC_EBB (ppc EBB registers)");
19255 case NT_PPC_PMU:
19256 return _("NT_PPC_PMU (ppc PMU registers)");
19257 case NT_PPC_TM_CGPR:
19258 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19259 case NT_PPC_TM_CFPR:
19260 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19261 case NT_PPC_TM_CVMX:
19262 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19263 case NT_PPC_TM_CVSX:
3fd21718 19264 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19265 case NT_PPC_TM_SPR:
19266 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19267 case NT_PPC_TM_CTAR:
19268 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19269 case NT_PPC_TM_CPPR:
19270 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19271 case NT_PPC_TM_CDSCR:
19272 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19273 case NT_386_TLS:
19274 return _("NT_386_TLS (x86 TLS information)");
19275 case NT_386_IOPERM:
19276 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19277 case NT_X86_XSTATE:
19278 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19279 case NT_X86_CET:
19280 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19281 case NT_S390_HIGH_GPRS:
19282 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19283 case NT_S390_TIMER:
19284 return _("NT_S390_TIMER (s390 timer register)");
19285 case NT_S390_TODCMP:
19286 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19287 case NT_S390_TODPREG:
19288 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19289 case NT_S390_CTRS:
19290 return _("NT_S390_CTRS (s390 control registers)");
19291 case NT_S390_PREFIX:
19292 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19293 case NT_S390_LAST_BREAK:
19294 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19295 case NT_S390_SYSTEM_CALL:
19296 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19297 case NT_S390_TDB:
19298 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19299 case NT_S390_VXRS_LOW:
19300 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19301 case NT_S390_VXRS_HIGH:
19302 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19303 case NT_S390_GS_CB:
19304 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19305 case NT_S390_GS_BC:
19306 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19307 case NT_ARM_VFP:
19308 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19309 case NT_ARM_TLS:
19310 return _("NT_ARM_TLS (AArch TLS registers)");
19311 case NT_ARM_HW_BREAK:
19312 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19313 case NT_ARM_HW_WATCH:
19314 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
19315 case NT_ARM_SYSTEM_CALL:
19316 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
19317 case NT_ARM_SVE:
19318 return _("NT_ARM_SVE (AArch SVE registers)");
19319 case NT_ARM_PAC_MASK:
19320 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19321 case NT_ARM_PACA_KEYS:
19322 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19323 case NT_ARM_PACG_KEYS:
19324 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19325 case NT_ARM_TAGGED_ADDR_CTRL:
19326 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19327 case NT_ARM_PAC_ENABLED_KEYS:
19328 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19329 case NT_ARC_V2:
19330 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19331 case NT_RISCV_CSR:
19332 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19333 case NT_PSTATUS:
1ec5cd37 19334 return _("NT_PSTATUS (pstatus structure)");
57346661 19335 case NT_FPREGS:
1ec5cd37 19336 return _("NT_FPREGS (floating point registers)");
57346661 19337 case NT_PSINFO:
1ec5cd37 19338 return _("NT_PSINFO (psinfo structure)");
57346661 19339 case NT_LWPSTATUS:
1ec5cd37 19340 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19341 case NT_LWPSINFO:
1ec5cd37 19342 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19343 case NT_WIN32PSTATUS:
1ec5cd37 19344 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19345 case NT_SIGINFO:
19346 return _("NT_SIGINFO (siginfo_t data)");
19347 case NT_FILE:
19348 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19349 default:
19350 break;
19351 }
19352 else
19353 switch (e_type)
19354 {
19355 case NT_VERSION:
19356 return _("NT_VERSION (version)");
19357 case NT_ARCH:
19358 return _("NT_ARCH (architecture)");
9ef920e9 19359 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19360 return _("OPEN");
9ef920e9 19361 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19362 return _("func");
c8795e1f
NC
19363 case NT_GO_BUILDID:
19364 return _("GO BUILDID");
3ac925fc
LB
19365 case FDO_PACKAGING_METADATA:
19366 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19367 default:
19368 break;
19369 }
19370
e9e44622 19371 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19372 return buff;
779fe533
NC
19373}
19374
015dc7e1 19375static bool
9ece1fa9
TT
19376print_core_note (Elf_Internal_Note *pnote)
19377{
19378 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 19379 uint64_t count, page_size;
9ece1fa9
TT
19380 unsigned char *descdata, *filenames, *descend;
19381
19382 if (pnote->type != NT_FILE)
04ac15ab
AS
19383 {
19384 if (do_wide)
19385 printf ("\n");
015dc7e1 19386 return true;
04ac15ab 19387 }
9ece1fa9 19388
9ece1fa9
TT
19389 if (!is_32bit_elf)
19390 {
19391 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19392 /* Still "successful". */
015dc7e1 19393 return true;
9ece1fa9 19394 }
9ece1fa9
TT
19395
19396 if (pnote->descsz < 2 * addr_size)
19397 {
32ec8896 19398 error (_(" Malformed note - too short for header\n"));
015dc7e1 19399 return false;
9ece1fa9
TT
19400 }
19401
19402 descdata = (unsigned char *) pnote->descdata;
19403 descend = descdata + pnote->descsz;
19404
19405 if (descdata[pnote->descsz - 1] != '\0')
19406 {
32ec8896 19407 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19408 return false;
9ece1fa9
TT
19409 }
19410
19411 count = byte_get (descdata, addr_size);
19412 descdata += addr_size;
19413
19414 page_size = byte_get (descdata, addr_size);
19415 descdata += addr_size;
19416
625d49fc 19417 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 19418 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19419 {
32ec8896 19420 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19421 return false;
9ece1fa9
TT
19422 }
19423
19424 printf (_(" Page size: "));
19425 print_vma (page_size, DEC);
19426 printf ("\n");
19427
19428 printf (_(" %*s%*s%*s\n"),
19429 (int) (2 + 2 * addr_size), _("Start"),
19430 (int) (4 + 2 * addr_size), _("End"),
19431 (int) (4 + 2 * addr_size), _("Page Offset"));
19432 filenames = descdata + count * 3 * addr_size;
595712bb 19433 while (count-- > 0)
9ece1fa9 19434 {
625d49fc 19435 uint64_t start, end, file_ofs;
9ece1fa9
TT
19436
19437 if (filenames == descend)
19438 {
32ec8896 19439 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19440 return false;
9ece1fa9
TT
19441 }
19442
19443 start = byte_get (descdata, addr_size);
19444 descdata += addr_size;
19445 end = byte_get (descdata, addr_size);
19446 descdata += addr_size;
19447 file_ofs = byte_get (descdata, addr_size);
19448 descdata += addr_size;
19449
19450 printf (" ");
19451 print_vma (start, FULL_HEX);
19452 printf (" ");
19453 print_vma (end, FULL_HEX);
19454 printf (" ");
19455 print_vma (file_ofs, FULL_HEX);
19456 printf ("\n %s\n", filenames);
19457
19458 filenames += 1 + strlen ((char *) filenames);
19459 }
19460
015dc7e1 19461 return true;
9ece1fa9
TT
19462}
19463
1118d252
RM
19464static const char *
19465get_gnu_elf_note_type (unsigned e_type)
19466{
1449284b 19467 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19468 switch (e_type)
19469 {
19470 case NT_GNU_ABI_TAG:
19471 return _("NT_GNU_ABI_TAG (ABI version tag)");
19472 case NT_GNU_HWCAP:
19473 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19474 case NT_GNU_BUILD_ID:
19475 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19476 case NT_GNU_GOLD_VERSION:
19477 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19478 case NT_GNU_PROPERTY_TYPE_0:
19479 return _("NT_GNU_PROPERTY_TYPE_0");
19480 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19481 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19482 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19483 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19484 default:
1449284b
NC
19485 {
19486 static char buff[64];
1118d252 19487
1449284b
NC
19488 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19489 return buff;
19490 }
19491 }
1118d252
RM
19492}
19493
a9eafb08
L
19494static void
19495decode_x86_compat_isa (unsigned int bitmask)
19496{
19497 while (bitmask)
19498 {
19499 unsigned int bit = bitmask & (- bitmask);
19500
19501 bitmask &= ~ bit;
19502 switch (bit)
19503 {
19504 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19505 printf ("i486");
19506 break;
19507 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19508 printf ("586");
19509 break;
19510 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19511 printf ("686");
19512 break;
19513 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19514 printf ("SSE");
19515 break;
19516 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19517 printf ("SSE2");
19518 break;
19519 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19520 printf ("SSE3");
19521 break;
19522 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19523 printf ("SSSE3");
19524 break;
19525 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19526 printf ("SSE4_1");
19527 break;
19528 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19529 printf ("SSE4_2");
19530 break;
19531 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19532 printf ("AVX");
19533 break;
19534 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19535 printf ("AVX2");
19536 break;
19537 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19538 printf ("AVX512F");
19539 break;
19540 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19541 printf ("AVX512CD");
19542 break;
19543 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19544 printf ("AVX512ER");
19545 break;
19546 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19547 printf ("AVX512PF");
19548 break;
19549 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19550 printf ("AVX512VL");
19551 break;
19552 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19553 printf ("AVX512DQ");
19554 break;
19555 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19556 printf ("AVX512BW");
19557 break;
65b3d26e
L
19558 default:
19559 printf (_("<unknown: %x>"), bit);
19560 break;
a9eafb08
L
19561 }
19562 if (bitmask)
19563 printf (", ");
19564 }
19565}
19566
9ef920e9 19567static void
32930e4e 19568decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19569{
0a59decb 19570 if (!bitmask)
90c745dc
L
19571 {
19572 printf (_("<None>"));
19573 return;
19574 }
90c745dc 19575
9ef920e9
NC
19576 while (bitmask)
19577 {
1fc87489 19578 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19579
19580 bitmask &= ~ bit;
19581 switch (bit)
19582 {
32930e4e 19583 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19584 printf ("CMOV");
19585 break;
32930e4e 19586 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19587 printf ("SSE");
19588 break;
32930e4e 19589 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19590 printf ("SSE2");
19591 break;
32930e4e 19592 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19593 printf ("SSE3");
19594 break;
32930e4e 19595 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19596 printf ("SSSE3");
19597 break;
32930e4e 19598 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19599 printf ("SSE4_1");
19600 break;
32930e4e 19601 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19602 printf ("SSE4_2");
19603 break;
32930e4e 19604 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19605 printf ("AVX");
19606 break;
32930e4e 19607 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19608 printf ("AVX2");
19609 break;
32930e4e 19610 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19611 printf ("FMA");
19612 break;
32930e4e 19613 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19614 printf ("AVX512F");
19615 break;
32930e4e 19616 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19617 printf ("AVX512CD");
19618 break;
32930e4e 19619 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19620 printf ("AVX512ER");
19621 break;
32930e4e 19622 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19623 printf ("AVX512PF");
19624 break;
32930e4e 19625 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19626 printf ("AVX512VL");
19627 break;
32930e4e 19628 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19629 printf ("AVX512DQ");
19630 break;
32930e4e 19631 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19632 printf ("AVX512BW");
19633 break;
32930e4e 19634 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19635 printf ("AVX512_4FMAPS");
19636 break;
32930e4e 19637 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19638 printf ("AVX512_4VNNIW");
19639 break;
32930e4e 19640 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19641 printf ("AVX512_BITALG");
19642 break;
32930e4e 19643 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19644 printf ("AVX512_IFMA");
19645 break;
32930e4e 19646 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19647 printf ("AVX512_VBMI");
19648 break;
32930e4e 19649 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19650 printf ("AVX512_VBMI2");
19651 break;
32930e4e 19652 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19653 printf ("AVX512_VNNI");
19654 break;
32930e4e 19655 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19656 printf ("AVX512_BF16");
19657 break;
65b3d26e
L
19658 default:
19659 printf (_("<unknown: %x>"), bit);
19660 break;
9ef920e9
NC
19661 }
19662 if (bitmask)
19663 printf (", ");
19664 }
19665}
19666
28cdbb18
SM
19667static const char *
19668get_amdgpu_elf_note_type (unsigned int e_type)
19669{
19670 switch (e_type)
19671 {
19672 case NT_AMDGPU_METADATA:
19673 return _("NT_AMDGPU_METADATA (code object metadata)");
19674 default:
19675 {
19676 static char buf[64];
19677 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
19678 return buf;
19679 }
19680 }
19681}
19682
32930e4e
L
19683static void
19684decode_x86_isa (unsigned int bitmask)
19685{
32930e4e
L
19686 while (bitmask)
19687 {
19688 unsigned int bit = bitmask & (- bitmask);
19689
19690 bitmask &= ~ bit;
19691 switch (bit)
19692 {
b0ab0693
L
19693 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19694 printf ("x86-64-baseline");
19695 break;
32930e4e
L
19696 case GNU_PROPERTY_X86_ISA_1_V2:
19697 printf ("x86-64-v2");
19698 break;
19699 case GNU_PROPERTY_X86_ISA_1_V3:
19700 printf ("x86-64-v3");
19701 break;
19702 case GNU_PROPERTY_X86_ISA_1_V4:
19703 printf ("x86-64-v4");
19704 break;
19705 default:
19706 printf (_("<unknown: %x>"), bit);
19707 break;
19708 }
19709 if (bitmask)
19710 printf (", ");
19711 }
19712}
19713
ee2fdd6f 19714static void
a9eafb08 19715decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19716{
0a59decb 19717 if (!bitmask)
90c745dc
L
19718 {
19719 printf (_("<None>"));
19720 return;
19721 }
90c745dc 19722
ee2fdd6f
L
19723 while (bitmask)
19724 {
19725 unsigned int bit = bitmask & (- bitmask);
19726
19727 bitmask &= ~ bit;
19728 switch (bit)
19729 {
19730 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19731 printf ("IBT");
ee2fdd6f 19732 break;
48580982 19733 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19734 printf ("SHSTK");
48580982 19735 break;
279d901e
L
19736 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19737 printf ("LAM_U48");
19738 break;
19739 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19740 printf ("LAM_U57");
19741 break;
ee2fdd6f
L
19742 default:
19743 printf (_("<unknown: %x>"), bit);
19744 break;
19745 }
19746 if (bitmask)
19747 printf (", ");
19748 }
19749}
19750
a9eafb08
L
19751static void
19752decode_x86_feature_2 (unsigned int bitmask)
19753{
0a59decb 19754 if (!bitmask)
90c745dc
L
19755 {
19756 printf (_("<None>"));
19757 return;
19758 }
90c745dc 19759
a9eafb08
L
19760 while (bitmask)
19761 {
19762 unsigned int bit = bitmask & (- bitmask);
19763
19764 bitmask &= ~ bit;
19765 switch (bit)
19766 {
19767 case GNU_PROPERTY_X86_FEATURE_2_X86:
19768 printf ("x86");
19769 break;
19770 case GNU_PROPERTY_X86_FEATURE_2_X87:
19771 printf ("x87");
19772 break;
19773 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19774 printf ("MMX");
19775 break;
19776 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19777 printf ("XMM");
19778 break;
19779 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19780 printf ("YMM");
19781 break;
19782 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19783 printf ("ZMM");
19784 break;
a308b89d
L
19785 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19786 printf ("TMM");
19787 break;
32930e4e
L
19788 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19789 printf ("MASK");
19790 break;
a9eafb08
L
19791 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19792 printf ("FXSR");
19793 break;
19794 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19795 printf ("XSAVE");
19796 break;
19797 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19798 printf ("XSAVEOPT");
19799 break;
19800 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19801 printf ("XSAVEC");
19802 break;
65b3d26e
L
19803 default:
19804 printf (_("<unknown: %x>"), bit);
19805 break;
a9eafb08
L
19806 }
19807 if (bitmask)
19808 printf (", ");
19809 }
19810}
19811
cd702818
SD
19812static void
19813decode_aarch64_feature_1_and (unsigned int bitmask)
19814{
19815 while (bitmask)
19816 {
19817 unsigned int bit = bitmask & (- bitmask);
19818
19819 bitmask &= ~ bit;
19820 switch (bit)
19821 {
19822 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19823 printf ("BTI");
19824 break;
19825
19826 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19827 printf ("PAC");
19828 break;
19829
19830 default:
19831 printf (_("<unknown: %x>"), bit);
19832 break;
19833 }
19834 if (bitmask)
19835 printf (", ");
19836 }
19837}
19838
6320fd00
L
19839static void
19840decode_1_needed (unsigned int bitmask)
19841{
19842 while (bitmask)
19843 {
19844 unsigned int bit = bitmask & (- bitmask);
19845
19846 bitmask &= ~ bit;
19847 switch (bit)
19848 {
19849 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19850 printf ("indirect external access");
19851 break;
19852 default:
19853 printf (_("<unknown: %x>"), bit);
19854 break;
19855 }
19856 if (bitmask)
19857 printf (", ");
19858 }
19859}
19860
9ef920e9 19861static void
dda8d76d 19862print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19863{
19864 unsigned char * ptr = (unsigned char *) pnote->descdata;
19865 unsigned char * ptr_end = ptr + pnote->descsz;
19866 unsigned int size = is_32bit_elf ? 4 : 8;
19867
19868 printf (_(" Properties: "));
19869
1fc87489 19870 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19871 {
19872 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19873 return;
19874 }
19875
6ab2c4ed 19876 while (ptr < ptr_end)
9ef920e9 19877 {
1fc87489 19878 unsigned int j;
6ab2c4ed
MC
19879 unsigned int type;
19880 unsigned int datasz;
19881
19882 if ((size_t) (ptr_end - ptr) < 8)
19883 {
19884 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19885 break;
19886 }
19887
19888 type = byte_get (ptr, 4);
19889 datasz = byte_get (ptr + 4, 4);
9ef920e9 19890
1fc87489 19891 ptr += 8;
9ef920e9 19892
6ab2c4ed 19893 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19894 {
1fc87489
L
19895 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19896 type, datasz);
9ef920e9 19897 break;
1fc87489 19898 }
9ef920e9 19899
1fc87489
L
19900 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19901 {
dda8d76d
NC
19902 if (filedata->file_header.e_machine == EM_X86_64
19903 || filedata->file_header.e_machine == EM_IAMCU
19904 || filedata->file_header.e_machine == EM_386)
1fc87489 19905 {
aa7bca9b
L
19906 unsigned int bitmask;
19907
19908 if (datasz == 4)
0a59decb 19909 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19910 else
19911 bitmask = 0;
19912
1fc87489
L
19913 switch (type)
19914 {
19915 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19916 if (datasz != 4)
aa7bca9b
L
19917 printf (_("x86 ISA used: <corrupt length: %#x> "),
19918 datasz);
1fc87489 19919 else
aa7bca9b
L
19920 {
19921 printf ("x86 ISA used: ");
19922 decode_x86_isa (bitmask);
19923 }
1fc87489 19924 goto next;
9ef920e9 19925
1fc87489 19926 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19927 if (datasz != 4)
aa7bca9b
L
19928 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19929 datasz);
1fc87489 19930 else
aa7bca9b
L
19931 {
19932 printf ("x86 ISA needed: ");
19933 decode_x86_isa (bitmask);
19934 }
1fc87489 19935 goto next;
9ef920e9 19936
ee2fdd6f 19937 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19938 if (datasz != 4)
aa7bca9b
L
19939 printf (_("x86 feature: <corrupt length: %#x> "),
19940 datasz);
ee2fdd6f 19941 else
aa7bca9b
L
19942 {
19943 printf ("x86 feature: ");
a9eafb08
L
19944 decode_x86_feature_1 (bitmask);
19945 }
19946 goto next;
19947
19948 case GNU_PROPERTY_X86_FEATURE_2_USED:
19949 if (datasz != 4)
19950 printf (_("x86 feature used: <corrupt length: %#x> "),
19951 datasz);
19952 else
19953 {
19954 printf ("x86 feature used: ");
19955 decode_x86_feature_2 (bitmask);
19956 }
19957 goto next;
19958
19959 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19960 if (datasz != 4)
19961 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19962 else
19963 {
19964 printf ("x86 feature needed: ");
19965 decode_x86_feature_2 (bitmask);
19966 }
19967 goto next;
19968
19969 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19970 if (datasz != 4)
19971 printf (_("x86 ISA used: <corrupt length: %#x> "),
19972 datasz);
19973 else
19974 {
19975 printf ("x86 ISA used: ");
19976 decode_x86_compat_isa (bitmask);
19977 }
19978 goto next;
19979
19980 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19981 if (datasz != 4)
19982 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19983 datasz);
19984 else
19985 {
19986 printf ("x86 ISA needed: ");
19987 decode_x86_compat_isa (bitmask);
aa7bca9b 19988 }
ee2fdd6f
L
19989 goto next;
19990
32930e4e
L
19991 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19992 if (datasz != 4)
19993 printf (_("x86 ISA used: <corrupt length: %#x> "),
19994 datasz);
19995 else
19996 {
19997 printf ("x86 ISA used: ");
19998 decode_x86_compat_2_isa (bitmask);
19999 }
20000 goto next;
20001
20002 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20003 if (datasz != 4)
20004 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20005 datasz);
20006 else
20007 {
20008 printf ("x86 ISA needed: ");
20009 decode_x86_compat_2_isa (bitmask);
20010 }
20011 goto next;
20012
1fc87489
L
20013 default:
20014 break;
20015 }
20016 }
cd702818
SD
20017 else if (filedata->file_header.e_machine == EM_AARCH64)
20018 {
20019 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20020 {
20021 printf ("AArch64 feature: ");
20022 if (datasz != 4)
20023 printf (_("<corrupt length: %#x> "), datasz);
20024 else
20025 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20026 goto next;
20027 }
20028 }
1fc87489
L
20029 }
20030 else
20031 {
20032 switch (type)
9ef920e9 20033 {
1fc87489
L
20034 case GNU_PROPERTY_STACK_SIZE:
20035 printf (_("stack size: "));
20036 if (datasz != size)
20037 printf (_("<corrupt length: %#x> "), datasz);
20038 else
20039 printf ("%#lx", (unsigned long) byte_get (ptr, size));
20040 goto next;
20041
20042 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20043 printf ("no copy on protected ");
20044 if (datasz)
20045 printf (_("<corrupt length: %#x> "), datasz);
20046 goto next;
20047
20048 default:
5a767724
L
20049 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20050 && type <= GNU_PROPERTY_UINT32_AND_HI)
20051 || (type >= GNU_PROPERTY_UINT32_OR_LO
20052 && type <= GNU_PROPERTY_UINT32_OR_HI))
20053 {
6320fd00
L
20054 switch (type)
20055 {
20056 case GNU_PROPERTY_1_NEEDED:
20057 if (datasz != 4)
20058 printf (_("1_needed: <corrupt length: %#x> "),
20059 datasz);
20060 else
20061 {
20062 unsigned int bitmask = byte_get (ptr, 4);
20063 printf ("1_needed: ");
20064 decode_1_needed (bitmask);
20065 }
20066 goto next;
20067
20068 default:
20069 break;
20070 }
5a767724
L
20071 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20072 printf (_("UINT32_AND (%#x): "), type);
20073 else
20074 printf (_("UINT32_OR (%#x): "), type);
20075 if (datasz != 4)
20076 printf (_("<corrupt length: %#x> "), datasz);
20077 else
20078 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20079 goto next;
20080 }
9ef920e9
NC
20081 break;
20082 }
9ef920e9
NC
20083 }
20084
1fc87489
L
20085 if (type < GNU_PROPERTY_LOPROC)
20086 printf (_("<unknown type %#x data: "), type);
20087 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20088 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20089 else
20090 printf (_("<application-specific type %#x data: "), type);
20091 for (j = 0; j < datasz; ++j)
20092 printf ("%02x ", ptr[j] & 0xff);
20093 printf (">");
20094
dc1e8a47 20095 next:
9ef920e9 20096 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20097 if (ptr == ptr_end)
20098 break;
1fc87489 20099
6ab2c4ed
MC
20100 if (do_wide)
20101 printf (", ");
20102 else
20103 printf ("\n\t");
9ef920e9
NC
20104 }
20105
20106 printf ("\n");
20107}
20108
015dc7e1 20109static bool
dda8d76d 20110print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20111{
1449284b 20112 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20113 switch (pnote->type)
20114 {
20115 case NT_GNU_BUILD_ID:
20116 {
20117 unsigned long i;
20118
20119 printf (_(" Build ID: "));
20120 for (i = 0; i < pnote->descsz; ++i)
20121 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20122 printf ("\n");
664f90a3
TT
20123 }
20124 break;
20125
20126 case NT_GNU_ABI_TAG:
20127 {
20128 unsigned long os, major, minor, subminor;
20129 const char *osname;
20130
3102e897
NC
20131 /* PR 17531: file: 030-599401-0.004. */
20132 if (pnote->descsz < 16)
20133 {
20134 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20135 break;
20136 }
20137
664f90a3
TT
20138 os = byte_get ((unsigned char *) pnote->descdata, 4);
20139 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20140 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20141 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20142
20143 switch (os)
20144 {
20145 case GNU_ABI_TAG_LINUX:
20146 osname = "Linux";
20147 break;
20148 case GNU_ABI_TAG_HURD:
20149 osname = "Hurd";
20150 break;
20151 case GNU_ABI_TAG_SOLARIS:
20152 osname = "Solaris";
20153 break;
20154 case GNU_ABI_TAG_FREEBSD:
20155 osname = "FreeBSD";
20156 break;
20157 case GNU_ABI_TAG_NETBSD:
20158 osname = "NetBSD";
20159 break;
14ae95f2
RM
20160 case GNU_ABI_TAG_SYLLABLE:
20161 osname = "Syllable";
20162 break;
20163 case GNU_ABI_TAG_NACL:
20164 osname = "NaCl";
20165 break;
664f90a3
TT
20166 default:
20167 osname = "Unknown";
20168 break;
20169 }
20170
20171 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20172 major, minor, subminor);
20173 }
20174 break;
926c5385
CC
20175
20176 case NT_GNU_GOLD_VERSION:
20177 {
20178 unsigned long i;
20179
20180 printf (_(" Version: "));
20181 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20182 printf ("%c", pnote->descdata[i]);
20183 printf ("\n");
20184 }
20185 break;
1449284b
NC
20186
20187 case NT_GNU_HWCAP:
20188 {
20189 unsigned long num_entries, mask;
20190
20191 /* Hardware capabilities information. Word 0 is the number of entries.
20192 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20193 is a series of entries, where each entry is a single byte followed
20194 by a nul terminated string. The byte gives the bit number to test
20195 if enabled in the bitmask. */
20196 printf (_(" Hardware Capabilities: "));
20197 if (pnote->descsz < 8)
20198 {
32ec8896 20199 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20200 return false;
1449284b
NC
20201 }
20202 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20203 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20204 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20205 /* FIXME: Add code to display the entries... */
20206 }
20207 break;
20208
9ef920e9 20209 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20210 print_gnu_property_note (filedata, pnote);
9ef920e9 20211 break;
9abca702 20212
1449284b
NC
20213 default:
20214 /* Handle unrecognised types. An error message should have already been
20215 created by get_gnu_elf_note_type(), so all that we need to do is to
20216 display the data. */
20217 {
20218 unsigned long i;
20219
20220 printf (_(" Description data: "));
20221 for (i = 0; i < pnote->descsz; ++i)
20222 printf ("%02x ", pnote->descdata[i] & 0xff);
20223 printf ("\n");
20224 }
20225 break;
664f90a3
TT
20226 }
20227
015dc7e1 20228 return true;
664f90a3
TT
20229}
20230
685080f2
NC
20231static const char *
20232get_v850_elf_note_type (enum v850_notes n_type)
20233{
20234 static char buff[64];
20235
20236 switch (n_type)
20237 {
20238 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20239 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20240 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20241 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20242 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20243 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20244 default:
20245 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20246 return buff;
20247 }
20248}
20249
015dc7e1 20250static bool
685080f2
NC
20251print_v850_note (Elf_Internal_Note * pnote)
20252{
20253 unsigned int val;
20254
20255 if (pnote->descsz != 4)
015dc7e1 20256 return false;
32ec8896 20257
685080f2
NC
20258 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20259
20260 if (val == 0)
20261 {
20262 printf (_("not set\n"));
015dc7e1 20263 return true;
685080f2
NC
20264 }
20265
20266 switch (pnote->type)
20267 {
20268 case V850_NOTE_ALIGNMENT:
20269 switch (val)
20270 {
015dc7e1
AM
20271 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20272 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20273 }
20274 break;
14ae95f2 20275
685080f2
NC
20276 case V850_NOTE_DATA_SIZE:
20277 switch (val)
20278 {
015dc7e1
AM
20279 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20280 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20281 }
20282 break;
14ae95f2 20283
685080f2
NC
20284 case V850_NOTE_FPU_INFO:
20285 switch (val)
20286 {
015dc7e1
AM
20287 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20288 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20289 }
20290 break;
14ae95f2 20291
685080f2
NC
20292 case V850_NOTE_MMU_INFO:
20293 case V850_NOTE_CACHE_INFO:
20294 case V850_NOTE_SIMD_INFO:
20295 if (val == EF_RH850_SIMD)
20296 {
20297 printf (_("yes\n"));
015dc7e1 20298 return true;
685080f2
NC
20299 }
20300 break;
20301
20302 default:
20303 /* An 'unknown note type' message will already have been displayed. */
20304 break;
20305 }
20306
20307 printf (_("unknown value: %x\n"), val);
015dc7e1 20308 return false;
685080f2
NC
20309}
20310
015dc7e1 20311static bool
c6056a74
SF
20312process_netbsd_elf_note (Elf_Internal_Note * pnote)
20313{
20314 unsigned int version;
20315
20316 switch (pnote->type)
20317 {
20318 case NT_NETBSD_IDENT:
b966f55f
AM
20319 if (pnote->descsz < 1)
20320 break;
c6056a74
SF
20321 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20322 if ((version / 10000) % 100)
b966f55f 20323 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20324 version, version / 100000000, (version / 1000000) % 100,
20325 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20326 'A' + (version / 10000) % 26);
c6056a74
SF
20327 else
20328 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20329 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20330 (version / 100) % 100);
015dc7e1 20331 return true;
c6056a74
SF
20332
20333 case NT_NETBSD_MARCH:
9abca702 20334 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20335 pnote->descdata);
015dc7e1 20336 return true;
c6056a74 20337
9abca702 20338 case NT_NETBSD_PAX:
b966f55f
AM
20339 if (pnote->descsz < 1)
20340 break;
9abca702
CZ
20341 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20342 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20343 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20344 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20345 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20346 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20347 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20348 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20349 return true;
c6056a74 20350 }
b966f55f
AM
20351
20352 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20353 pnote->descsz, pnote->type);
015dc7e1 20354 return false;
c6056a74
SF
20355}
20356
f4ddf30f 20357static const char *
dda8d76d 20358get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20359{
f4ddf30f
JB
20360 switch (e_type)
20361 {
20362 case NT_FREEBSD_THRMISC:
20363 return _("NT_THRMISC (thrmisc structure)");
20364 case NT_FREEBSD_PROCSTAT_PROC:
20365 return _("NT_PROCSTAT_PROC (proc data)");
20366 case NT_FREEBSD_PROCSTAT_FILES:
20367 return _("NT_PROCSTAT_FILES (files data)");
20368 case NT_FREEBSD_PROCSTAT_VMMAP:
20369 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20370 case NT_FREEBSD_PROCSTAT_GROUPS:
20371 return _("NT_PROCSTAT_GROUPS (groups data)");
20372 case NT_FREEBSD_PROCSTAT_UMASK:
20373 return _("NT_PROCSTAT_UMASK (umask data)");
20374 case NT_FREEBSD_PROCSTAT_RLIMIT:
20375 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20376 case NT_FREEBSD_PROCSTAT_OSREL:
20377 return _("NT_PROCSTAT_OSREL (osreldate data)");
20378 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20379 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20380 case NT_FREEBSD_PROCSTAT_AUXV:
20381 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20382 case NT_FREEBSD_PTLWPINFO:
20383 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
20384 case NT_FREEBSD_X86_SEGBASES:
20385 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 20386 }
dda8d76d 20387 return get_note_type (filedata, e_type);
f4ddf30f
JB
20388}
20389
9437c45b 20390static const char *
dda8d76d 20391get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20392{
20393 static char buff[64];
20394
540e6170
CZ
20395 switch (e_type)
20396 {
20397 case NT_NETBSDCORE_PROCINFO:
20398 /* NetBSD core "procinfo" structure. */
20399 return _("NetBSD procinfo structure");
9437c45b 20400
540e6170
CZ
20401 case NT_NETBSDCORE_AUXV:
20402 return _("NetBSD ELF auxiliary vector data");
9437c45b 20403
06d949ec
KR
20404 case NT_NETBSDCORE_LWPSTATUS:
20405 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20406
540e6170 20407 default:
06d949ec 20408 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20409 defined for NetBSD core files. If the note type is less
20410 than the start of the machine-dependent note types, we don't
20411 understand it. */
20412
20413 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20414 {
20415 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20416 return buff;
20417 }
20418 break;
9437c45b
JT
20419 }
20420
dda8d76d 20421 switch (filedata->file_header.e_machine)
9437c45b
JT
20422 {
20423 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20424 and PT_GETFPREGS == mach+2. */
20425
20426 case EM_OLD_ALPHA:
20427 case EM_ALPHA:
20428 case EM_SPARC:
20429 case EM_SPARC32PLUS:
20430 case EM_SPARCV9:
20431 switch (e_type)
20432 {
2b692964 20433 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20434 return _("PT_GETREGS (reg structure)");
2b692964 20435 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20436 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20437 default:
20438 break;
20439 }
20440 break;
20441
c0d38b0e
CZ
20442 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20443 There's also old PT___GETREGS40 == mach + 1 for old reg
20444 structure which lacks GBR. */
20445 case EM_SH:
20446 switch (e_type)
20447 {
20448 case NT_NETBSDCORE_FIRSTMACH + 1:
20449 return _("PT___GETREGS40 (old reg structure)");
20450 case NT_NETBSDCORE_FIRSTMACH + 3:
20451 return _("PT_GETREGS (reg structure)");
20452 case NT_NETBSDCORE_FIRSTMACH + 5:
20453 return _("PT_GETFPREGS (fpreg structure)");
20454 default:
20455 break;
20456 }
20457 break;
20458
9437c45b
JT
20459 /* On all other arch's, PT_GETREGS == mach+1 and
20460 PT_GETFPREGS == mach+3. */
20461 default:
20462 switch (e_type)
20463 {
2b692964 20464 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20465 return _("PT_GETREGS (reg structure)");
2b692964 20466 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20467 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20468 default:
20469 break;
20470 }
20471 }
20472
9cf03b7e 20473 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20474 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20475 return buff;
20476}
20477
98ca73af
FC
20478static const char *
20479get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20480{
20481 switch (e_type)
20482 {
20483 case NT_OPENBSD_PROCINFO:
20484 return _("OpenBSD procinfo structure");
20485 case NT_OPENBSD_AUXV:
20486 return _("OpenBSD ELF auxiliary vector data");
20487 case NT_OPENBSD_REGS:
20488 return _("OpenBSD regular registers");
20489 case NT_OPENBSD_FPREGS:
20490 return _("OpenBSD floating point registers");
20491 case NT_OPENBSD_WCOOKIE:
20492 return _("OpenBSD window cookie");
20493 }
20494
20495 return get_note_type (filedata, e_type);
20496}
20497
70616151
TT
20498static const char *
20499get_stapsdt_note_type (unsigned e_type)
20500{
20501 static char buff[64];
20502
20503 switch (e_type)
20504 {
20505 case NT_STAPSDT:
20506 return _("NT_STAPSDT (SystemTap probe descriptors)");
20507
20508 default:
20509 break;
20510 }
20511
20512 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20513 return buff;
20514}
20515
015dc7e1 20516static bool
c6a9fc58
TT
20517print_stapsdt_note (Elf_Internal_Note *pnote)
20518{
3ca60c57
NC
20519 size_t len, maxlen;
20520 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20521 char *data = pnote->descdata;
20522 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 20523 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
20524 char *provider, *probe, *arg_fmt;
20525
3ca60c57
NC
20526 if (pnote->descsz < (addr_size * 3))
20527 goto stapdt_note_too_small;
20528
c6a9fc58
TT
20529 pc = byte_get ((unsigned char *) data, addr_size);
20530 data += addr_size;
3ca60c57 20531
c6a9fc58
TT
20532 base_addr = byte_get ((unsigned char *) data, addr_size);
20533 data += addr_size;
3ca60c57 20534
c6a9fc58
TT
20535 semaphore = byte_get ((unsigned char *) data, addr_size);
20536 data += addr_size;
20537
3ca60c57
NC
20538 if (data >= data_end)
20539 goto stapdt_note_too_small;
20540 maxlen = data_end - data;
20541 len = strnlen (data, maxlen);
20542 if (len < maxlen)
20543 {
20544 provider = data;
20545 data += len + 1;
20546 }
20547 else
20548 goto stapdt_note_too_small;
20549
20550 if (data >= data_end)
20551 goto stapdt_note_too_small;
20552 maxlen = data_end - data;
20553 len = strnlen (data, maxlen);
20554 if (len < maxlen)
20555 {
20556 probe = data;
20557 data += len + 1;
20558 }
20559 else
20560 goto stapdt_note_too_small;
9abca702 20561
3ca60c57
NC
20562 if (data >= data_end)
20563 goto stapdt_note_too_small;
20564 maxlen = data_end - data;
20565 len = strnlen (data, maxlen);
20566 if (len < maxlen)
20567 {
20568 arg_fmt = data;
20569 data += len + 1;
20570 }
20571 else
20572 goto stapdt_note_too_small;
c6a9fc58
TT
20573
20574 printf (_(" Provider: %s\n"), provider);
20575 printf (_(" Name: %s\n"), probe);
20576 printf (_(" Location: "));
20577 print_vma (pc, FULL_HEX);
20578 printf (_(", Base: "));
20579 print_vma (base_addr, FULL_HEX);
20580 printf (_(", Semaphore: "));
20581 print_vma (semaphore, FULL_HEX);
9cf03b7e 20582 printf ("\n");
c6a9fc58
TT
20583 printf (_(" Arguments: %s\n"), arg_fmt);
20584
20585 return data == data_end;
3ca60c57
NC
20586
20587 stapdt_note_too_small:
20588 printf (_(" <corrupt - note is too small>\n"));
20589 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20590 return false;
c6a9fc58
TT
20591}
20592
e5382207
LB
20593static bool
20594print_fdo_note (Elf_Internal_Note * pnote)
20595{
20596 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20597 {
20598 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20599 return true;
20600 }
20601 return false;
20602}
20603
00e98fc7
TG
20604static const char *
20605get_ia64_vms_note_type (unsigned e_type)
20606{
20607 static char buff[64];
20608
20609 switch (e_type)
20610 {
20611 case NT_VMS_MHD:
20612 return _("NT_VMS_MHD (module header)");
20613 case NT_VMS_LNM:
20614 return _("NT_VMS_LNM (language name)");
20615 case NT_VMS_SRC:
20616 return _("NT_VMS_SRC (source files)");
20617 case NT_VMS_TITLE:
9cf03b7e 20618 return "NT_VMS_TITLE";
00e98fc7
TG
20619 case NT_VMS_EIDC:
20620 return _("NT_VMS_EIDC (consistency check)");
20621 case NT_VMS_FPMODE:
20622 return _("NT_VMS_FPMODE (FP mode)");
20623 case NT_VMS_LINKTIME:
9cf03b7e 20624 return "NT_VMS_LINKTIME";
00e98fc7
TG
20625 case NT_VMS_IMGNAM:
20626 return _("NT_VMS_IMGNAM (image name)");
20627 case NT_VMS_IMGID:
20628 return _("NT_VMS_IMGID (image id)");
20629 case NT_VMS_LINKID:
20630 return _("NT_VMS_LINKID (link id)");
20631 case NT_VMS_IMGBID:
20632 return _("NT_VMS_IMGBID (build id)");
20633 case NT_VMS_GSTNAM:
20634 return _("NT_VMS_GSTNAM (sym table name)");
20635 case NT_VMS_ORIG_DYN:
9cf03b7e 20636 return "NT_VMS_ORIG_DYN";
00e98fc7 20637 case NT_VMS_PATCHTIME:
9cf03b7e 20638 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20639 default:
20640 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20641 return buff;
20642 }
20643}
20644
015dc7e1 20645static bool
00e98fc7
TG
20646print_ia64_vms_note (Elf_Internal_Note * pnote)
20647{
8d18bf79
NC
20648 int maxlen = pnote->descsz;
20649
20650 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20651 goto desc_size_fail;
20652
00e98fc7
TG
20653 switch (pnote->type)
20654 {
20655 case NT_VMS_MHD:
8d18bf79
NC
20656 if (maxlen <= 36)
20657 goto desc_size_fail;
20658
20659 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20660
20661 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20662 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20663 if (l + 34 < maxlen)
20664 {
20665 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20666 if (l + 35 < maxlen)
20667 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20668 else
20669 printf (_(" Module version : <missing>\n"));
20670 }
00e98fc7 20671 else
8d18bf79
NC
20672 {
20673 printf (_(" Module name : <missing>\n"));
20674 printf (_(" Module version : <missing>\n"));
20675 }
00e98fc7 20676 break;
8d18bf79 20677
00e98fc7 20678 case NT_VMS_LNM:
8d18bf79 20679 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20680 break;
8d18bf79 20681
00e98fc7 20682 case NT_VMS_FPMODE:
9cf03b7e 20683 printf (_(" Floating Point mode: "));
8d18bf79
NC
20684 if (maxlen < 8)
20685 goto desc_size_fail;
20686 /* FIXME: Generate an error if descsz > 8 ? */
20687
b8281767 20688 printf ("0x%016" PRIx64 "\n",
625d49fc 20689 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 20690 break;
8d18bf79 20691
00e98fc7
TG
20692 case NT_VMS_LINKTIME:
20693 printf (_(" Link time: "));
8d18bf79
NC
20694 if (maxlen < 8)
20695 goto desc_size_fail;
20696 /* FIXME: Generate an error if descsz > 8 ? */
20697
0e3c1eeb 20698 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20699 printf ("\n");
20700 break;
8d18bf79 20701
00e98fc7
TG
20702 case NT_VMS_PATCHTIME:
20703 printf (_(" Patch time: "));
8d18bf79
NC
20704 if (maxlen < 8)
20705 goto desc_size_fail;
20706 /* FIXME: Generate an error if descsz > 8 ? */
20707
0e3c1eeb 20708 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
20709 printf ("\n");
20710 break;
8d18bf79 20711
00e98fc7 20712 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20713 if (maxlen < 34)
20714 goto desc_size_fail;
20715
00e98fc7 20716 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
20717 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
20718 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 20719 printf (_(" Last modified : "));
0e3c1eeb 20720 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 20721 printf (_("\n Link flags : "));
b8281767 20722 printf ("0x%016" PRIx64 "\n",
625d49fc 20723 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 20724 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 20725 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 20726 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 20727 break;
8d18bf79 20728
00e98fc7 20729 case NT_VMS_IMGNAM:
8d18bf79 20730 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20731 break;
8d18bf79 20732
00e98fc7 20733 case NT_VMS_GSTNAM:
8d18bf79 20734 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20735 break;
8d18bf79 20736
00e98fc7 20737 case NT_VMS_IMGID:
8d18bf79 20738 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20739 break;
8d18bf79 20740
00e98fc7 20741 case NT_VMS_LINKID:
8d18bf79 20742 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20743 break;
8d18bf79 20744
00e98fc7 20745 default:
015dc7e1 20746 return false;
00e98fc7 20747 }
8d18bf79 20748
015dc7e1 20749 return true;
8d18bf79
NC
20750
20751 desc_size_fail:
20752 printf (_(" <corrupt - data size is too small>\n"));
20753 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20754 return false;
00e98fc7
TG
20755}
20756
fd486f32
AM
20757struct build_attr_cache {
20758 Filedata *filedata;
20759 char *strtab;
20760 unsigned long strtablen;
20761 Elf_Internal_Sym *symtab;
20762 unsigned long nsyms;
20763} ba_cache;
20764
6f156d7a
NC
20765/* Find the symbol associated with a build attribute that is attached
20766 to address OFFSET. If PNAME is non-NULL then store the name of
20767 the symbol (if found) in the provided pointer, Returns NULL if a
20768 symbol could not be found. */
c799a79d 20769
6f156d7a 20770static Elf_Internal_Sym *
015dc7e1
AM
20771get_symbol_for_build_attribute (Filedata *filedata,
20772 unsigned long offset,
20773 bool is_open_attr,
20774 const char **pname)
9ef920e9 20775{
fd486f32
AM
20776 Elf_Internal_Sym *saved_sym = NULL;
20777 Elf_Internal_Sym *sym;
9ef920e9 20778
dda8d76d 20779 if (filedata->section_headers != NULL
fd486f32 20780 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20781 {
c799a79d 20782 Elf_Internal_Shdr * symsec;
9ef920e9 20783
fd486f32
AM
20784 free (ba_cache.strtab);
20785 ba_cache.strtab = NULL;
20786 free (ba_cache.symtab);
20787 ba_cache.symtab = NULL;
20788
c799a79d 20789 /* Load the symbol and string sections. */
dda8d76d
NC
20790 for (symsec = filedata->section_headers;
20791 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20792 symsec ++)
9ef920e9 20793 {
28d13567
AM
20794 if (symsec->sh_type == SHT_SYMTAB
20795 && get_symtab (filedata, symsec,
20796 &ba_cache.symtab, &ba_cache.nsyms,
20797 &ba_cache.strtab, &ba_cache.strtablen))
20798 break;
9ef920e9 20799 }
fd486f32 20800 ba_cache.filedata = filedata;
9ef920e9
NC
20801 }
20802
fd486f32 20803 if (ba_cache.symtab == NULL)
6f156d7a 20804 return NULL;
9ef920e9 20805
c799a79d 20806 /* Find a symbol whose value matches offset. */
fd486f32 20807 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20808 if (sym->st_value == offset)
20809 {
fd486f32 20810 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20811 /* Huh ? This should not happen. */
20812 continue;
9ef920e9 20813
fd486f32 20814 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20815 continue;
9ef920e9 20816
9b9b1092 20817 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20818 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20819 if (ba_cache.strtab[sym->st_name] == '$'
20820 && ba_cache.strtab[sym->st_name + 1] != 0
20821 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20822 continue;
20823
c799a79d
NC
20824 if (is_open_attr)
20825 {
20826 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20827 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20828 FUNC symbols entirely. */
20829 switch (ELF_ST_TYPE (sym->st_info))
20830 {
c799a79d 20831 case STT_OBJECT:
6f156d7a 20832 case STT_FILE:
c799a79d 20833 saved_sym = sym;
6f156d7a
NC
20834 if (sym->st_size)
20835 {
20836 /* If the symbol has a size associated
20837 with it then we can stop searching. */
fd486f32 20838 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20839 }
c799a79d 20840 continue;
9ef920e9 20841
c799a79d
NC
20842 case STT_FUNC:
20843 /* Ignore function symbols. */
20844 continue;
20845
20846 default:
20847 break;
20848 }
20849
20850 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20851 {
c799a79d
NC
20852 case STB_GLOBAL:
20853 if (saved_sym == NULL
20854 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20855 saved_sym = sym;
20856 break;
c871dade 20857
c799a79d
NC
20858 case STB_LOCAL:
20859 if (saved_sym == NULL)
20860 saved_sym = sym;
20861 break;
20862
20863 default:
9ef920e9
NC
20864 break;
20865 }
20866 }
c799a79d
NC
20867 else
20868 {
20869 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20870 continue;
20871
20872 saved_sym = sym;
20873 break;
20874 }
20875 }
20876
6f156d7a 20877 if (saved_sym && pname)
fd486f32 20878 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20879
20880 return saved_sym;
c799a79d
NC
20881}
20882
d20e98ab
NC
20883/* Returns true iff addr1 and addr2 are in the same section. */
20884
015dc7e1 20885static bool
d20e98ab
NC
20886same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20887{
20888 Elf_Internal_Shdr * a1;
20889 Elf_Internal_Shdr * a2;
20890
20891 a1 = find_section_by_address (filedata, addr1);
20892 a2 = find_section_by_address (filedata, addr2);
9abca702 20893
d20e98ab
NC
20894 return a1 == a2 && a1 != NULL;
20895}
20896
015dc7e1 20897static bool
dda8d76d
NC
20898print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20899 Filedata * filedata)
c799a79d 20900{
015dc7e1
AM
20901 static unsigned long global_offset = 0;
20902 static unsigned long global_end = 0;
20903 static unsigned long func_offset = 0;
20904 static unsigned long func_end = 0;
c871dade 20905
015dc7e1
AM
20906 Elf_Internal_Sym *sym;
20907 const char *name;
20908 unsigned long start;
20909 unsigned long end;
20910 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20911
20912 switch (pnote->descsz)
c799a79d 20913 {
6f156d7a
NC
20914 case 0:
20915 /* A zero-length description means that the range of
20916 the previous note of the same type should be used. */
c799a79d 20917 if (is_open_attr)
c871dade 20918 {
6f156d7a
NC
20919 if (global_end > global_offset)
20920 printf (_(" Applies to region from %#lx to %#lx\n"),
20921 global_offset, global_end);
20922 else
20923 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20924 }
20925 else
20926 {
6f156d7a
NC
20927 if (func_end > func_offset)
20928 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20929 else
20930 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20931 }
015dc7e1 20932 return true;
9ef920e9 20933
6f156d7a
NC
20934 case 4:
20935 start = byte_get ((unsigned char *) pnote->descdata, 4);
20936 end = 0;
20937 break;
20938
20939 case 8:
c74147bb
NC
20940 start = byte_get ((unsigned char *) pnote->descdata, 4);
20941 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20942 break;
20943
20944 case 16:
20945 start = byte_get ((unsigned char *) pnote->descdata, 8);
20946 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20947 break;
9abca702 20948
6f156d7a 20949 default:
c799a79d
NC
20950 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20951 printf (_(" <invalid descsz>"));
015dc7e1 20952 return false;
c799a79d
NC
20953 }
20954
6f156d7a
NC
20955 name = NULL;
20956 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20957 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20958 in order to avoid them being confused with the start address of the
20959 first function in the file... */
20960 if (sym == NULL && is_open_attr)
20961 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20962 & name);
6f156d7a
NC
20963
20964 if (end == 0 && sym != NULL && sym->st_size > 0)
20965 end = start + sym->st_size;
c799a79d
NC
20966
20967 if (is_open_attr)
20968 {
d20e98ab
NC
20969 /* FIXME: Need to properly allow for section alignment.
20970 16 is just the alignment used on x86_64. */
20971 if (global_end > 0
20972 && start > BFD_ALIGN (global_end, 16)
20973 /* Build notes are not guaranteed to be organised in order of
20974 increasing address, but we should find the all of the notes
20975 for one section in the same place. */
20976 && same_section (filedata, start, global_end))
6f156d7a
NC
20977 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20978 global_end + 1, start - 1);
20979
20980 printf (_(" Applies to region from %#lx"), start);
20981 global_offset = start;
20982
20983 if (end)
20984 {
20985 printf (_(" to %#lx"), end);
20986 global_end = end;
20987 }
c799a79d
NC
20988 }
20989 else
20990 {
6f156d7a
NC
20991 printf (_(" Applies to region from %#lx"), start);
20992 func_offset = start;
20993
20994 if (end)
20995 {
20996 printf (_(" to %#lx"), end);
20997 func_end = end;
20998 }
c799a79d
NC
20999 }
21000
6f156d7a
NC
21001 if (sym && name)
21002 printf (_(" (%s)"), name);
21003
21004 printf ("\n");
015dc7e1 21005 return true;
9ef920e9
NC
21006}
21007
015dc7e1 21008static bool
9ef920e9
NC
21009print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21010{
1d15e434
NC
21011 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21012 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21013 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21014 char name_type;
21015 char name_attribute;
1d15e434 21016 const char * expected_types;
9ef920e9
NC
21017 const char * name = pnote->namedata;
21018 const char * text;
88305e1b 21019 signed int left;
9ef920e9
NC
21020
21021 if (name == NULL || pnote->namesz < 2)
21022 {
21023 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 21024 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21025 return false;
9ef920e9
NC
21026 }
21027
6f156d7a
NC
21028 if (do_wide)
21029 left = 28;
21030 else
21031 left = 20;
88305e1b
NC
21032
21033 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21034 if (name[0] == 'G' && name[1] == 'A')
21035 {
6f156d7a
NC
21036 if (pnote->namesz < 4)
21037 {
21038 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
21039 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 21040 return false;
6f156d7a
NC
21041 }
21042
88305e1b
NC
21043 printf ("GA");
21044 name += 2;
21045 left -= 2;
21046 }
21047
9ef920e9
NC
21048 switch ((name_type = * name))
21049 {
21050 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21051 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21052 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21053 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21054 printf ("%c", * name);
88305e1b 21055 left --;
9ef920e9
NC
21056 break;
21057 default:
21058 error (_("unrecognised attribute type in name field: %d\n"), name_type);
21059 print_symbol (-20, _("<unknown name type>"));
015dc7e1 21060 return false;
9ef920e9
NC
21061 }
21062
9ef920e9
NC
21063 ++ name;
21064 text = NULL;
21065
21066 switch ((name_attribute = * name))
21067 {
21068 case GNU_BUILD_ATTRIBUTE_VERSION:
21069 text = _("<version>");
1d15e434 21070 expected_types = string_expected;
9ef920e9
NC
21071 ++ name;
21072 break;
21073 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21074 text = _("<stack prot>");
75d7d298 21075 expected_types = "!+*";
9ef920e9
NC
21076 ++ name;
21077 break;
21078 case GNU_BUILD_ATTRIBUTE_RELRO:
21079 text = _("<relro>");
1d15e434 21080 expected_types = bool_expected;
9ef920e9
NC
21081 ++ name;
21082 break;
21083 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21084 text = _("<stack size>");
1d15e434 21085 expected_types = number_expected;
9ef920e9
NC
21086 ++ name;
21087 break;
21088 case GNU_BUILD_ATTRIBUTE_TOOL:
21089 text = _("<tool>");
1d15e434 21090 expected_types = string_expected;
9ef920e9
NC
21091 ++ name;
21092 break;
21093 case GNU_BUILD_ATTRIBUTE_ABI:
21094 text = _("<ABI>");
21095 expected_types = "$*";
21096 ++ name;
21097 break;
21098 case GNU_BUILD_ATTRIBUTE_PIC:
21099 text = _("<PIC>");
1d15e434 21100 expected_types = number_expected;
9ef920e9
NC
21101 ++ name;
21102 break;
a8be5506
NC
21103 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21104 text = _("<short enum>");
1d15e434 21105 expected_types = bool_expected;
a8be5506
NC
21106 ++ name;
21107 break;
9ef920e9
NC
21108 default:
21109 if (ISPRINT (* name))
21110 {
21111 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21112
21113 if (len > left && ! do_wide)
21114 len = left;
75d7d298 21115 printf ("%.*s:", len, name);
9ef920e9 21116 left -= len;
0dd6ae21 21117 name += len;
9ef920e9
NC
21118 }
21119 else
21120 {
3e6b6445 21121 static char tmpbuf [128];
88305e1b 21122
3e6b6445
NC
21123 error (_("unrecognised byte in name field: %d\n"), * name);
21124 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21125 text = tmpbuf;
21126 name ++;
9ef920e9
NC
21127 }
21128 expected_types = "*$!+";
21129 break;
21130 }
21131
21132 if (text)
88305e1b 21133 left -= printf ("%s", text);
9ef920e9
NC
21134
21135 if (strchr (expected_types, name_type) == NULL)
75d7d298 21136 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21137
21138 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21139 {
21140 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21141 (unsigned long) pnote->namesz,
21142 (long) (name - pnote->namedata));
015dc7e1 21143 return false;
9ef920e9
NC
21144 }
21145
21146 if (left < 1 && ! do_wide)
015dc7e1 21147 return true;
9ef920e9
NC
21148
21149 switch (name_type)
21150 {
21151 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21152 {
b06b2c92 21153 unsigned int bytes;
ddef72cd
NC
21154 unsigned long long val = 0;
21155 unsigned int shift = 0;
21156 char * decoded = NULL;
21157
b06b2c92
NC
21158 bytes = pnote->namesz - (name - pnote->namedata);
21159 if (bytes > 0)
21160 /* The -1 is because the name field is always 0 terminated, and we
21161 want to be able to ensure that the shift in the while loop below
21162 will not overflow. */
21163 -- bytes;
21164
ddef72cd
NC
21165 if (bytes > sizeof (val))
21166 {
3e6b6445
NC
21167 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21168 bytes);
21169 bytes = sizeof (val);
ddef72cd 21170 }
3e6b6445
NC
21171 /* We do not bother to warn if bytes == 0 as this can
21172 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21173
21174 while (bytes --)
21175 {
54b8331d 21176 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21177
21178 val |= byte << shift;
9ef920e9
NC
21179 shift += 8;
21180 }
21181
75d7d298 21182 switch (name_attribute)
9ef920e9 21183 {
75d7d298 21184 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21185 switch (val)
21186 {
75d7d298
NC
21187 case 0: decoded = "static"; break;
21188 case 1: decoded = "pic"; break;
21189 case 2: decoded = "PIC"; break;
21190 case 3: decoded = "pie"; break;
21191 case 4: decoded = "PIE"; break;
21192 default: break;
9ef920e9 21193 }
75d7d298
NC
21194 break;
21195 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21196 switch (val)
9ef920e9 21197 {
75d7d298
NC
21198 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21199 case 0: decoded = "off"; break;
21200 case 1: decoded = "on"; break;
21201 case 2: decoded = "all"; break;
21202 case 3: decoded = "strong"; break;
21203 case 4: decoded = "explicit"; break;
21204 default: break;
9ef920e9 21205 }
75d7d298
NC
21206 break;
21207 default:
21208 break;
9ef920e9
NC
21209 }
21210
75d7d298 21211 if (decoded != NULL)
3e6b6445
NC
21212 {
21213 print_symbol (-left, decoded);
21214 left = 0;
21215 }
21216 else if (val == 0)
21217 {
21218 printf ("0x0");
21219 left -= 3;
21220 }
9ef920e9 21221 else
75d7d298
NC
21222 {
21223 if (do_wide)
ddef72cd 21224 left -= printf ("0x%llx", val);
75d7d298 21225 else
ddef72cd 21226 left -= printf ("0x%-.*llx", left, val);
75d7d298 21227 }
9ef920e9
NC
21228 }
21229 break;
21230 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21231 left -= print_symbol (- left, name);
21232 break;
21233 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21234 left -= print_symbol (- left, "true");
21235 break;
21236 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21237 left -= print_symbol (- left, "false");
21238 break;
21239 }
21240
21241 if (do_wide && left > 0)
21242 printf ("%-*s", left, " ");
9abca702 21243
015dc7e1 21244 return true;
9ef920e9
NC
21245}
21246
2952f10c
SM
21247/* Print the contents of PNOTE as hex. */
21248
21249static void
21250print_note_contents_hex (Elf_Internal_Note *pnote)
21251{
21252 if (pnote->descsz)
21253 {
21254 unsigned long i;
21255
21256 printf (_(" description data: "));
21257 for (i = 0; i < pnote->descsz; i++)
21258 printf ("%02x ", pnote->descdata[i] & 0xff);
21259 if (!do_wide)
21260 printf ("\n");
21261 }
21262
21263 if (do_wide)
21264 printf ("\n");
21265}
21266
21267#if defined HAVE_MSGPACK
21268
21269static void
21270print_indents (int n)
21271{
21272 printf (" ");
21273
21274 for (int i = 0; i < n; i++)
21275 printf (" ");
21276}
21277
21278/* Print OBJ in human-readable form. */
21279
21280static void
21281dump_msgpack_obj (const msgpack_object *obj, int indent)
21282{
21283 switch (obj->type)
21284 {
21285 case MSGPACK_OBJECT_NIL:
21286 printf ("(nil)");
21287 break;
21288
21289 case MSGPACK_OBJECT_BOOLEAN:
21290 printf ("%s", obj->via.boolean ? "true" : "false");
21291 break;
21292
21293 case MSGPACK_OBJECT_POSITIVE_INTEGER:
21294 printf ("%" PRIu64, obj->via.u64);
21295 break;
21296
21297 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
21298 printf ("%" PRIi64, obj->via.i64);
21299 break;
21300
21301 case MSGPACK_OBJECT_FLOAT32:
21302 case MSGPACK_OBJECT_FLOAT64:
21303 printf ("%f", obj->via.f64);
21304 break;
21305
21306 case MSGPACK_OBJECT_STR:
21307 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
21308 break;
21309
21310 case MSGPACK_OBJECT_ARRAY:
21311 {
21312 const msgpack_object_array *array = &obj->via.array;
21313
21314 printf ("[\n");
21315 ++indent;
21316
21317 for (uint32_t i = 0; i < array->size; ++i)
21318 {
21319 const msgpack_object *item = &array->ptr[i];
21320
21321 print_indents (indent);
21322 dump_msgpack_obj (item, indent);
21323 printf (",\n");
21324 }
21325
21326 --indent;
21327 print_indents (indent);
21328 printf ("]");
21329 break;
21330 }
21331 break;
21332
21333 case MSGPACK_OBJECT_MAP:
21334 {
21335 const msgpack_object_map *map = &obj->via.map;
21336
21337 printf ("{\n");
21338 ++indent;
21339
21340 for (uint32_t i = 0; i < map->size; ++i)
21341 {
21342 const msgpack_object_kv *kv = &map->ptr[i];
21343 const msgpack_object *key = &kv->key;
21344 const msgpack_object *val = &kv->val;
21345
21346 print_indents (indent);
21347 dump_msgpack_obj (key, indent);
21348 printf (": ");
21349 dump_msgpack_obj (val, indent);
21350
21351 printf (",\n");
21352 }
21353
21354 --indent;
21355 print_indents (indent);
21356 printf ("}");
21357
21358 break;
21359 }
21360
21361 case MSGPACK_OBJECT_BIN:
21362 printf ("(bin)");
21363 break;
21364
21365 case MSGPACK_OBJECT_EXT:
21366 printf ("(ext)");
21367 break;
21368 }
21369}
21370
21371static void
21372dump_msgpack (const msgpack_unpacked *msg)
21373{
21374 print_indents (0);
21375 dump_msgpack_obj (&msg->data, 0);
21376 printf ("\n");
21377}
21378
21379#endif /* defined HAVE_MSGPACK */
21380
21381static bool
21382print_amdgpu_note (Elf_Internal_Note *pnote)
21383{
21384#if defined HAVE_MSGPACK
21385 /* If msgpack is available, decode and dump the note's content. */
21386 bool ret;
21387 msgpack_unpacked msg;
21388 msgpack_unpack_return msgpack_ret;
21389
21390 assert (pnote->type == NT_AMDGPU_METADATA);
21391
21392 msgpack_unpacked_init (&msg);
21393 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
21394 NULL);
21395
21396 switch (msgpack_ret)
21397 {
21398 case MSGPACK_UNPACK_SUCCESS:
21399 dump_msgpack (&msg);
21400 ret = true;
21401 break;
21402
21403 default:
21404 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
21405 ret = false;
21406 break;
21407 }
21408
21409 msgpack_unpacked_destroy (&msg);
21410 return ret;
21411#else
21412 /* msgpack is not available, dump contents as hex. */
21413 print_note_contents_hex (pnote);
21414 return true;
21415#endif
21416}
21417
6d118b09
NC
21418/* Note that by the ELF standard, the name field is already null byte
21419 terminated, and namesz includes the terminating null byte.
21420 I.E. the value of namesz for the name "FSF" is 4.
21421
e3c8793a 21422 If the value of namesz is zero, there is no name present. */
9ef920e9 21423
015dc7e1 21424static bool
9ef920e9 21425process_note (Elf_Internal_Note * pnote,
dda8d76d 21426 Filedata * filedata)
779fe533 21427{
2cf0635d
NC
21428 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21429 const char * nt;
9437c45b
JT
21430
21431 if (pnote->namesz == 0)
1ec5cd37
NC
21432 /* If there is no note name, then use the default set of
21433 note type strings. */
dda8d76d 21434 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21435
24d127aa 21436 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21437 /* GNU-specific object file notes. */
21438 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21439
28cdbb18
SM
21440 else if (startswith (pnote->namedata, "AMDGPU"))
21441 /* AMDGPU-specific object file notes. */
21442 nt = get_amdgpu_elf_note_type (pnote->type);
21443
24d127aa 21444 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21445 /* FreeBSD-specific core file notes. */
dda8d76d 21446 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21447
24d127aa 21448 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21449 /* NetBSD-specific core file notes. */
dda8d76d 21450 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21451
24d127aa 21452 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21453 /* NetBSD-specific core file notes. */
21454 return process_netbsd_elf_note (pnote);
21455
24d127aa 21456 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21457 /* NetBSD-specific core file notes. */
21458 return process_netbsd_elf_note (pnote);
21459
98ca73af
FC
21460 else if (startswith (pnote->namedata, "OpenBSD"))
21461 /* OpenBSD-specific core file notes. */
21462 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21463
e9b095a5 21464 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21465 {
21466 /* SPU-specific core file notes. */
21467 nt = pnote->namedata + 4;
21468 name = "SPU";
21469 }
21470
24d127aa 21471 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21472 /* VMS/ia64-specific file notes. */
21473 nt = get_ia64_vms_note_type (pnote->type);
21474
24d127aa 21475 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21476 nt = get_stapsdt_note_type (pnote->type);
21477
9437c45b 21478 else
1ec5cd37
NC
21479 /* Don't recognize this note name; just use the default set of
21480 note type strings. */
dda8d76d 21481 nt = get_note_type (filedata, pnote->type);
9437c45b 21482
1449284b 21483 printf (" ");
9ef920e9 21484
24d127aa 21485 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21486 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21487 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21488 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21489 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21490 print_gnu_build_attribute_name (pnote);
21491 else
21492 print_symbol (-20, name);
21493
21494 if (do_wide)
21495 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21496 else
21497 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21498
24d127aa 21499 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21500 return print_ia64_vms_note (pnote);
24d127aa 21501 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21502 return print_gnu_note (filedata, pnote);
24d127aa 21503 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21504 return print_stapsdt_note (pnote);
24d127aa 21505 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21506 return print_core_note (pnote);
e5382207
LB
21507 else if (startswith (pnote->namedata, "FDO"))
21508 return print_fdo_note (pnote);
24d127aa 21509 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21510 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21511 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21512 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21513 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21514 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
21515 else if (startswith (pnote->namedata, "AMDGPU")
21516 && pnote->type == NT_AMDGPU_METADATA)
21517 return print_amdgpu_note (pnote);
779fe533 21518
2952f10c 21519 print_note_contents_hex (pnote);
015dc7e1 21520 return true;
1449284b 21521}
6d118b09 21522
015dc7e1 21523static bool
dda8d76d
NC
21524process_notes_at (Filedata * filedata,
21525 Elf_Internal_Shdr * section,
625d49fc
AM
21526 uint64_t offset,
21527 uint64_t length,
21528 uint64_t align)
779fe533 21529{
015dc7e1
AM
21530 Elf_External_Note *pnotes;
21531 Elf_External_Note *external;
21532 char *end;
21533 bool res = true;
103f02d3 21534
779fe533 21535 if (length <= 0)
015dc7e1 21536 return false;
103f02d3 21537
1449284b
NC
21538 if (section)
21539 {
dda8d76d 21540 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21541 if (pnotes)
32ec8896 21542 {
dda8d76d 21543 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21544 {
21545 free (pnotes);
015dc7e1 21546 return false;
f761cb13 21547 }
32ec8896 21548 }
1449284b
NC
21549 }
21550 else
82ed9683 21551 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21552 _("notes"));
4dff97b2 21553
dd24e3da 21554 if (pnotes == NULL)
015dc7e1 21555 return false;
779fe533 21556
103f02d3 21557 external = pnotes;
103f02d3 21558
ca0e11aa
NC
21559 if (filedata->is_separate)
21560 printf (_("In linked file '%s': "), filedata->file_name);
21561 else
21562 printf ("\n");
1449284b 21563 if (section)
ca0e11aa 21564 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21565 else
ca0e11aa 21566 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21567 (unsigned long) offset, (unsigned long) length);
21568
82ed9683
L
21569 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21570 specifies that notes should be aligned to 4 bytes in 32-bit
21571 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21572 we also support 4 byte alignment in 64-bit objects. If section
21573 alignment is less than 4, we treate alignment as 4 bytes. */
21574 if (align < 4)
21575 align = 4;
21576 else if (align != 4 && align != 8)
21577 {
21578 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21579 (long) align);
a788aedd 21580 free (pnotes);
015dc7e1 21581 return false;
82ed9683
L
21582 }
21583
dbe15e4e 21584 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21585
c8071705
NC
21586 end = (char *) pnotes + length;
21587 while ((char *) external < end)
779fe533 21588 {
b34976b6 21589 Elf_Internal_Note inote;
15b42fb0 21590 size_t min_notesz;
4dff97b2 21591 char * next;
2cf0635d 21592 char * temp = NULL;
c8071705 21593 size_t data_remaining = end - (char *) external;
6d118b09 21594
dda8d76d 21595 if (!is_ia64_vms (filedata))
15b42fb0 21596 {
9dd3a467
NC
21597 /* PR binutils/15191
21598 Make sure that there is enough data to read. */
15b42fb0
AM
21599 min_notesz = offsetof (Elf_External_Note, name);
21600 if (data_remaining < min_notesz)
9dd3a467 21601 {
d3a49aa8
AM
21602 warn (ngettext ("Corrupt note: only %ld byte remains, "
21603 "not enough for a full note\n",
21604 "Corrupt note: only %ld bytes remain, "
21605 "not enough for a full note\n",
21606 data_remaining),
21607 (long) data_remaining);
9dd3a467
NC
21608 break;
21609 }
5396a86e
AM
21610 data_remaining -= min_notesz;
21611
15b42fb0
AM
21612 inote.type = BYTE_GET (external->type);
21613 inote.namesz = BYTE_GET (external->namesz);
21614 inote.namedata = external->name;
21615 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21616 inote.descdata = ((char *) external
4dff97b2 21617 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21618 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21619 next = ((char *) external
4dff97b2 21620 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21621 }
00e98fc7 21622 else
15b42fb0
AM
21623 {
21624 Elf64_External_VMS_Note *vms_external;
00e98fc7 21625
9dd3a467
NC
21626 /* PR binutils/15191
21627 Make sure that there is enough data to read. */
15b42fb0
AM
21628 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21629 if (data_remaining < min_notesz)
9dd3a467 21630 {
d3a49aa8
AM
21631 warn (ngettext ("Corrupt note: only %ld byte remains, "
21632 "not enough for a full note\n",
21633 "Corrupt note: only %ld bytes remain, "
21634 "not enough for a full note\n",
21635 data_remaining),
21636 (long) data_remaining);
9dd3a467
NC
21637 break;
21638 }
5396a86e 21639 data_remaining -= min_notesz;
3e55a963 21640
15b42fb0
AM
21641 vms_external = (Elf64_External_VMS_Note *) external;
21642 inote.type = BYTE_GET (vms_external->type);
21643 inote.namesz = BYTE_GET (vms_external->namesz);
21644 inote.namedata = vms_external->name;
21645 inote.descsz = BYTE_GET (vms_external->descsz);
21646 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21647 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21648 next = inote.descdata + align_power (inote.descsz, 3);
21649 }
21650
5396a86e
AM
21651 /* PR 17531: file: 3443835e. */
21652 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21653 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21654 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21655 || (size_t) (next - inote.descdata) < inote.descsz
21656 || ((size_t) (next - inote.descdata)
21657 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21658 {
15b42fb0 21659 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21660 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21661 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21662 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21663 break;
21664 }
21665
15b42fb0 21666 external = (Elf_External_Note *) next;
dd24e3da 21667
6d118b09
NC
21668 /* Verify that name is null terminated. It appears that at least
21669 one version of Linux (RedHat 6.0) generates corefiles that don't
21670 comply with the ELF spec by failing to include the null byte in
21671 namesz. */
18344509 21672 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21673 {
5396a86e 21674 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21675 {
5396a86e
AM
21676 temp = (char *) malloc (inote.namesz + 1);
21677 if (temp == NULL)
21678 {
21679 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21680 res = false;
5396a86e
AM
21681 break;
21682 }
76da6bbe 21683
5396a86e
AM
21684 memcpy (temp, inote.namedata, inote.namesz);
21685 inote.namedata = temp;
21686 }
21687 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21688 }
21689
dda8d76d 21690 if (! process_note (& inote, filedata))
015dc7e1 21691 res = false;
103f02d3 21692
9db70fc3
AM
21693 free (temp);
21694 temp = NULL;
779fe533
NC
21695 }
21696
21697 free (pnotes);
103f02d3 21698
779fe533
NC
21699 return res;
21700}
21701
015dc7e1 21702static bool
dda8d76d 21703process_corefile_note_segments (Filedata * filedata)
779fe533 21704{
015dc7e1 21705 Elf_Internal_Phdr *segment;
b34976b6 21706 unsigned int i;
015dc7e1 21707 bool res = true;
103f02d3 21708
dda8d76d 21709 if (! get_program_headers (filedata))
015dc7e1 21710 return true;
103f02d3 21711
dda8d76d
NC
21712 for (i = 0, segment = filedata->program_headers;
21713 i < filedata->file_header.e_phnum;
b34976b6 21714 i++, segment++)
779fe533
NC
21715 {
21716 if (segment->p_type == PT_NOTE)
625d49fc
AM
21717 if (! process_notes_at (filedata, NULL, segment->p_offset,
21718 segment->p_filesz, segment->p_align))
015dc7e1 21719 res = false;
779fe533 21720 }
103f02d3 21721
779fe533
NC
21722 return res;
21723}
21724
015dc7e1 21725static bool
625d49fc 21726process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
21727{
21728 Elf_External_Note * pnotes;
21729 Elf_External_Note * external;
c8071705 21730 char * end;
015dc7e1 21731 bool res = true;
685080f2
NC
21732
21733 if (length <= 0)
015dc7e1 21734 return false;
685080f2 21735
dda8d76d 21736 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21737 _("v850 notes"));
21738 if (pnotes == NULL)
015dc7e1 21739 return false;
685080f2
NC
21740
21741 external = pnotes;
c8071705 21742 end = (char*) pnotes + length;
685080f2
NC
21743
21744 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21745 (unsigned long) offset, (unsigned long) length);
21746
c8071705 21747 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21748 {
21749 Elf_External_Note * next;
21750 Elf_Internal_Note inote;
21751
21752 inote.type = BYTE_GET (external->type);
21753 inote.namesz = BYTE_GET (external->namesz);
21754 inote.namedata = external->name;
21755 inote.descsz = BYTE_GET (external->descsz);
21756 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21757 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21758
c8071705
NC
21759 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21760 {
21761 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21762 inote.descdata = inote.namedata;
21763 inote.namesz = 0;
21764 }
21765
685080f2
NC
21766 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21767
c8071705 21768 if ( ((char *) next > end)
685080f2
NC
21769 || ((char *) next < (char *) pnotes))
21770 {
21771 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21772 (unsigned long) ((char *) external - (char *) pnotes));
21773 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21774 inote.type, inote.namesz, inote.descsz);
21775 break;
21776 }
21777
21778 external = next;
21779
21780 /* Prevent out-of-bounds indexing. */
c8071705 21781 if ( inote.namedata + inote.namesz > end
685080f2
NC
21782 || inote.namedata + inote.namesz < inote.namedata)
21783 {
21784 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21785 (unsigned long) ((char *) external - (char *) pnotes));
21786 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21787 inote.type, inote.namesz, inote.descsz);
21788 break;
21789 }
21790
21791 printf (" %s: ", get_v850_elf_note_type (inote.type));
21792
21793 if (! print_v850_note (& inote))
21794 {
015dc7e1 21795 res = false;
685080f2
NC
21796 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21797 inote.namesz, inote.descsz);
21798 }
21799 }
21800
21801 free (pnotes);
21802
21803 return res;
21804}
21805
015dc7e1 21806static bool
dda8d76d 21807process_note_sections (Filedata * filedata)
1ec5cd37 21808{
015dc7e1 21809 Elf_Internal_Shdr *section;
1ec5cd37 21810 unsigned long i;
32ec8896 21811 unsigned int n = 0;
015dc7e1 21812 bool res = true;
1ec5cd37 21813
dda8d76d
NC
21814 for (i = 0, section = filedata->section_headers;
21815 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21816 i++, section++)
685080f2
NC
21817 {
21818 if (section->sh_type == SHT_NOTE)
21819 {
625d49fc
AM
21820 if (! process_notes_at (filedata, section, section->sh_offset,
21821 section->sh_size, section->sh_addralign))
015dc7e1 21822 res = false;
685080f2
NC
21823 n++;
21824 }
21825
dda8d76d
NC
21826 if (( filedata->file_header.e_machine == EM_V800
21827 || filedata->file_header.e_machine == EM_V850
21828 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21829 && section->sh_type == SHT_RENESAS_INFO)
21830 {
625d49fc
AM
21831 if (! process_v850_notes (filedata, section->sh_offset,
21832 section->sh_size))
015dc7e1 21833 res = false;
685080f2
NC
21834 n++;
21835 }
21836 }
df565f32
NC
21837
21838 if (n == 0)
21839 /* Try processing NOTE segments instead. */
dda8d76d 21840 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21841
21842 return res;
21843}
21844
015dc7e1 21845static bool
dda8d76d 21846process_notes (Filedata * filedata)
779fe533
NC
21847{
21848 /* If we have not been asked to display the notes then do nothing. */
21849 if (! do_notes)
015dc7e1 21850 return true;
103f02d3 21851
dda8d76d
NC
21852 if (filedata->file_header.e_type != ET_CORE)
21853 return process_note_sections (filedata);
103f02d3 21854
779fe533 21855 /* No program headers means no NOTE segment. */
dda8d76d
NC
21856 if (filedata->file_header.e_phnum > 0)
21857 return process_corefile_note_segments (filedata);
779fe533 21858
ca0e11aa
NC
21859 if (filedata->is_separate)
21860 printf (_("No notes found in linked file '%s'.\n"),
21861 filedata->file_name);
21862 else
21863 printf (_("No notes found file.\n"));
21864
015dc7e1 21865 return true;
779fe533
NC
21866}
21867
60abdbed
NC
21868static unsigned char *
21869display_public_gnu_attributes (unsigned char * start,
21870 const unsigned char * const end)
21871{
21872 printf (_(" Unknown GNU attribute: %s\n"), start);
21873
21874 start += strnlen ((char *) start, end - start);
21875 display_raw_attribute (start, end);
21876
21877 return (unsigned char *) end;
21878}
21879
21880static unsigned char *
21881display_generic_attribute (unsigned char * start,
21882 unsigned int tag,
21883 const unsigned char * const end)
21884{
21885 if (tag == 0)
21886 return (unsigned char *) end;
21887
21888 return display_tag_value (tag, start, end);
21889}
21890
015dc7e1 21891static bool
dda8d76d 21892process_arch_specific (Filedata * filedata)
252b5132 21893{
a952a375 21894 if (! do_arch)
015dc7e1 21895 return true;
a952a375 21896
dda8d76d 21897 switch (filedata->file_header.e_machine)
252b5132 21898 {
53a346d8
CZ
21899 case EM_ARC:
21900 case EM_ARC_COMPACT:
21901 case EM_ARC_COMPACT2:
dda8d76d 21902 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21903 display_arc_attribute,
21904 display_generic_attribute);
11c1ff18 21905 case EM_ARM:
dda8d76d 21906 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21907 display_arm_attribute,
21908 display_generic_attribute);
21909
252b5132 21910 case EM_MIPS:
4fe85591 21911 case EM_MIPS_RS3_LE:
dda8d76d 21912 return process_mips_specific (filedata);
60abdbed
NC
21913
21914 case EM_MSP430:
dda8d76d 21915 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21916 display_msp430_attribute,
c0ea7c52 21917 display_msp430_gnu_attribute);
60abdbed 21918
2dc8dd17
JW
21919 case EM_RISCV:
21920 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21921 display_riscv_attribute,
21922 display_generic_attribute);
21923
35c08157 21924 case EM_NDS32:
dda8d76d 21925 return process_nds32_specific (filedata);
60abdbed 21926
85f7484a
PB
21927 case EM_68K:
21928 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21929 display_m68k_gnu_attribute);
21930
34c8bcba 21931 case EM_PPC:
b82317dd 21932 case EM_PPC64:
dda8d76d 21933 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21934 display_power_gnu_attribute);
21935
643f7afb
AK
21936 case EM_S390:
21937 case EM_S390_OLD:
dda8d76d 21938 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21939 display_s390_gnu_attribute);
21940
9e8c70f9
DM
21941 case EM_SPARC:
21942 case EM_SPARC32PLUS:
21943 case EM_SPARCV9:
dda8d76d 21944 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21945 display_sparc_gnu_attribute);
21946
59e6276b 21947 case EM_TI_C6000:
dda8d76d 21948 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21949 display_tic6x_attribute,
21950 display_generic_attribute);
21951
0861f561
CQ
21952 case EM_CSKY:
21953 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21954 display_csky_attribute, NULL);
21955
252b5132 21956 default:
dda8d76d 21957 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21958 display_public_gnu_attributes,
21959 display_generic_attribute);
252b5132 21960 }
252b5132
RH
21961}
21962
015dc7e1 21963static bool
dda8d76d 21964get_file_header (Filedata * filedata)
252b5132 21965{
9ea033b2 21966 /* Read in the identity array. */
dda8d76d 21967 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21968 return false;
252b5132 21969
9ea033b2 21970 /* Determine how to read the rest of the header. */
dda8d76d 21971 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21972 {
1a0670f3
AM
21973 default:
21974 case ELFDATANONE:
adab8cdc
AO
21975 case ELFDATA2LSB:
21976 byte_get = byte_get_little_endian;
21977 byte_put = byte_put_little_endian;
21978 break;
21979 case ELFDATA2MSB:
21980 byte_get = byte_get_big_endian;
21981 byte_put = byte_put_big_endian;
21982 break;
9ea033b2
NC
21983 }
21984
21985 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21986 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21987
21988 /* Read in the rest of the header. */
21989 if (is_32bit_elf)
21990 {
21991 Elf32_External_Ehdr ehdr32;
252b5132 21992
dda8d76d 21993 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21994 return false;
103f02d3 21995
dda8d76d
NC
21996 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21997 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21998 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21999 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22000 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22001 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22002 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22003 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22004 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22005 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22006 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22007 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22008 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22009 }
252b5132 22010 else
9ea033b2
NC
22011 {
22012 Elf64_External_Ehdr ehdr64;
a952a375 22013
dda8d76d 22014 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22015 return false;
103f02d3 22016
dda8d76d
NC
22017 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22018 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22019 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22020 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22021 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22022 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22023 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22024 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22025 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22026 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22027 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22028 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22029 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22030 }
252b5132 22031
015dc7e1 22032 return true;
252b5132
RH
22033}
22034
13acb58d
AM
22035static void
22036free_filedata (Filedata *filedata)
22037{
22038 free (filedata->program_interpreter);
13acb58d 22039 free (filedata->program_headers);
13acb58d 22040 free (filedata->section_headers);
13acb58d 22041 free (filedata->string_table);
13acb58d 22042 free (filedata->dump.dump_sects);
13acb58d 22043 free (filedata->dynamic_strings);
13acb58d 22044 free (filedata->dynamic_symbols);
13acb58d 22045 free (filedata->dynamic_syminfo);
13acb58d 22046 free (filedata->dynamic_section);
13acb58d
AM
22047
22048 while (filedata->symtab_shndx_list != NULL)
22049 {
22050 elf_section_list *next = filedata->symtab_shndx_list->next;
22051 free (filedata->symtab_shndx_list);
22052 filedata->symtab_shndx_list = next;
22053 }
22054
22055 free (filedata->section_headers_groups);
13acb58d
AM
22056
22057 if (filedata->section_groups)
22058 {
22059 size_t i;
22060 struct group_list * g;
22061 struct group_list * next;
22062
22063 for (i = 0; i < filedata->group_count; i++)
22064 {
22065 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22066 {
22067 next = g->next;
22068 free (g);
22069 }
22070 }
22071
22072 free (filedata->section_groups);
13acb58d 22073 }
066f8fbe
AM
22074 memset (&filedata->section_headers, 0,
22075 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22076}
22077
dda8d76d
NC
22078static void
22079close_file (Filedata * filedata)
22080{
22081 if (filedata)
22082 {
22083 if (filedata->handle)
22084 fclose (filedata->handle);
22085 free (filedata);
22086 }
22087}
22088
22089void
22090close_debug_file (void * data)
22091{
13acb58d 22092 free_filedata ((Filedata *) data);
dda8d76d
NC
22093 close_file ((Filedata *) data);
22094}
22095
22096static Filedata *
015dc7e1 22097open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22098{
22099 struct stat statbuf;
22100 Filedata * filedata = NULL;
22101
22102 if (stat (pathname, & statbuf) < 0
22103 || ! S_ISREG (statbuf.st_mode))
22104 goto fail;
22105
22106 filedata = calloc (1, sizeof * filedata);
22107 if (filedata == NULL)
22108 goto fail;
22109
22110 filedata->handle = fopen (pathname, "rb");
22111 if (filedata->handle == NULL)
22112 goto fail;
22113
be7d229a 22114 filedata->file_size = statbuf.st_size;
dda8d76d 22115 filedata->file_name = pathname;
ca0e11aa 22116 filedata->is_separate = is_separate;
dda8d76d
NC
22117
22118 if (! get_file_header (filedata))
22119 goto fail;
22120
4de91c10
AM
22121 if (!get_section_headers (filedata, false))
22122 goto fail;
dda8d76d
NC
22123
22124 return filedata;
22125
22126 fail:
22127 if (filedata)
22128 {
22129 if (filedata->handle)
22130 fclose (filedata->handle);
22131 free (filedata);
22132 }
22133 return NULL;
22134}
22135
22136void *
22137open_debug_file (const char * pathname)
22138{
015dc7e1 22139 return open_file (pathname, true);
dda8d76d
NC
22140}
22141
835f2fae
NC
22142static void
22143initialise_dump_sects (Filedata * filedata)
22144{
22145 /* Initialise the dump_sects array from the cmdline_dump_sects array.
22146 Note we do this even if cmdline_dump_sects is empty because we
22147 must make sure that the dump_sets array is zeroed out before each
22148 object file is processed. */
22149 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
22150 memset (filedata->dump.dump_sects, 0,
22151 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22152
22153 if (cmdline.num_dump_sects > 0)
22154 {
22155 if (filedata->dump.num_dump_sects == 0)
22156 /* A sneaky way of allocating the dump_sects array. */
22157 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
22158
22159 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
22160 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
22161 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
22162 }
22163}
22164
94585d6d
NC
22165static bool
22166might_need_separate_debug_info (Filedata * filedata)
22167{
22168 /* Debuginfo files do not need further separate file loading. */
22169 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
22170 return false;
22171
22172 /* Since do_follow_links might be enabled by default, only treat it as an
22173 indication that separate files should be loaded if setting it was a
22174 deliberate user action. */
22175 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
22176 return true;
22177
22178 if (process_links || do_syms || do_unwind
22179 || dump_any_debugging || do_dump || do_debugging)
22180 return true;
22181
22182 return false;
22183}
22184
fb52b2f4
NC
22185/* Process one ELF object file according to the command line options.
22186 This file may actually be stored in an archive. The file is
32ec8896
NC
22187 positioned at the start of the ELF object. Returns TRUE if no
22188 problems were encountered, FALSE otherwise. */
fb52b2f4 22189
015dc7e1 22190static bool
dda8d76d 22191process_object (Filedata * filedata)
252b5132 22192{
015dc7e1 22193 bool have_separate_files;
252b5132 22194 unsigned int i;
015dc7e1 22195 bool res;
252b5132 22196
dda8d76d 22197 if (! get_file_header (filedata))
252b5132 22198 {
dda8d76d 22199 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 22200 return false;
252b5132
RH
22201 }
22202
22203 /* Initialise per file variables. */
978c4450
AM
22204 for (i = ARRAY_SIZE (filedata->version_info); i--;)
22205 filedata->version_info[i] = 0;
252b5132 22206
978c4450
AM
22207 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
22208 filedata->dynamic_info[i] = 0;
22209 filedata->dynamic_info_DT_GNU_HASH = 0;
22210 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
22211
22212 /* Process the file. */
22213 if (show_name)
dda8d76d 22214 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 22215
835f2fae 22216 initialise_dump_sects (filedata);
d70c5fc7 22217
4de91c10
AM
22218 /* There may be some extensions in the first section header. Don't
22219 bomb if we can't read it. */
22220 get_section_headers (filedata, true);
22221
dda8d76d 22222 if (! process_file_header (filedata))
4de91c10
AM
22223 {
22224 res = false;
22225 goto out;
22226 }
252b5132 22227
e331b18d
AM
22228 /* Throw away the single section header read above, so that we
22229 re-read the entire set. */
22230 free (filedata->section_headers);
22231 filedata->section_headers = NULL;
22232
dda8d76d 22233 if (! process_section_headers (filedata))
2f62977e 22234 {
32ec8896 22235 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 22236 do_unwind = do_version = do_dump = do_arch = false;
252b5132 22237
2f62977e 22238 if (! do_using_dynamic)
015dc7e1 22239 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 22240 }
252b5132 22241
dda8d76d 22242 if (! process_section_groups (filedata))
32ec8896 22243 /* Without loaded section groups we cannot process unwind. */
015dc7e1 22244 do_unwind = false;
d1f5c6e3 22245
93df3340
AM
22246 process_program_headers (filedata);
22247
22248 res = process_dynamic_section (filedata);
252b5132 22249
dda8d76d 22250 if (! process_relocs (filedata))
015dc7e1 22251 res = false;
252b5132 22252
dda8d76d 22253 if (! process_unwind (filedata))
015dc7e1 22254 res = false;
4d6ed7c8 22255
dda8d76d 22256 if (! process_symbol_table (filedata))
015dc7e1 22257 res = false;
252b5132 22258
0f03783c 22259 if (! process_lto_symbol_tables (filedata))
015dc7e1 22260 res = false;
b9e920ec 22261
dda8d76d 22262 if (! process_syminfo (filedata))
015dc7e1 22263 res = false;
252b5132 22264
dda8d76d 22265 if (! process_version_sections (filedata))
015dc7e1 22266 res = false;
252b5132 22267
94585d6d 22268 if (might_need_separate_debug_info (filedata))
24841daa 22269 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 22270 else
015dc7e1 22271 have_separate_files = false;
dda8d76d
NC
22272
22273 if (! process_section_contents (filedata))
015dc7e1 22274 res = false;
f5842774 22275
24841daa 22276 if (have_separate_files)
dda8d76d 22277 {
24841daa
NC
22278 separate_info * d;
22279
22280 for (d = first_separate_info; d != NULL; d = d->next)
22281 {
835f2fae
NC
22282 initialise_dump_sects (d->handle);
22283
ca0e11aa 22284 if (process_links && ! process_file_header (d->handle))
015dc7e1 22285 res = false;
ca0e11aa 22286 else if (! process_section_headers (d->handle))
015dc7e1 22287 res = false;
d6bfbc39 22288 else if (! process_section_contents (d->handle))
015dc7e1 22289 res = false;
ca0e11aa
NC
22290 else if (process_links)
22291 {
ca0e11aa 22292 if (! process_section_groups (d->handle))
015dc7e1 22293 res = false;
93df3340 22294 process_program_headers (d->handle);
ca0e11aa 22295 if (! process_dynamic_section (d->handle))
015dc7e1 22296 res = false;
ca0e11aa 22297 if (! process_relocs (d->handle))
015dc7e1 22298 res = false;
ca0e11aa 22299 if (! process_unwind (d->handle))
015dc7e1 22300 res = false;
ca0e11aa 22301 if (! process_symbol_table (d->handle))
015dc7e1 22302 res = false;
ca0e11aa 22303 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22304 res = false;
ca0e11aa 22305 if (! process_syminfo (d->handle))
015dc7e1 22306 res = false;
ca0e11aa 22307 if (! process_version_sections (d->handle))
015dc7e1 22308 res = false;
ca0e11aa 22309 if (! process_notes (d->handle))
015dc7e1 22310 res = false;
ca0e11aa 22311 }
24841daa
NC
22312 }
22313
22314 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22315 }
22316
22317 if (! process_notes (filedata))
015dc7e1 22318 res = false;
103f02d3 22319
dda8d76d 22320 if (! process_gnu_liblist (filedata))
015dc7e1 22321 res = false;
047b2264 22322
dda8d76d 22323 if (! process_arch_specific (filedata))
015dc7e1 22324 res = false;
252b5132 22325
4de91c10 22326 out:
13acb58d 22327 free_filedata (filedata);
e4b17d5c 22328
19e6b90e 22329 free_debug_memory ();
18bd398b 22330
32ec8896 22331 return res;
252b5132
RH
22332}
22333
2cf0635d 22334/* Process an ELF archive.
32ec8896
NC
22335 On entry the file is positioned just after the ARMAG string.
22336 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22337
015dc7e1
AM
22338static bool
22339process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22340{
22341 struct archive_info arch;
22342 struct archive_info nested_arch;
22343 size_t got;
015dc7e1 22344 bool ret = true;
2cf0635d 22345
015dc7e1 22346 show_name = true;
2cf0635d
NC
22347
22348 /* The ARCH structure is used to hold information about this archive. */
22349 arch.file_name = NULL;
22350 arch.file = NULL;
22351 arch.index_array = NULL;
22352 arch.sym_table = NULL;
22353 arch.longnames = NULL;
22354
22355 /* The NESTED_ARCH structure is used as a single-item cache of information
22356 about a nested archive (when members of a thin archive reside within
22357 another regular archive file). */
22358 nested_arch.file_name = NULL;
22359 nested_arch.file = NULL;
22360 nested_arch.index_array = NULL;
22361 nested_arch.sym_table = NULL;
22362 nested_arch.longnames = NULL;
22363
dda8d76d 22364 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22365 filedata->file_size, is_thin_archive,
22366 do_archive_index) != 0)
2cf0635d 22367 {
015dc7e1 22368 ret = false;
2cf0635d 22369 goto out;
4145f1d5 22370 }
fb52b2f4 22371
4145f1d5
NC
22372 if (do_archive_index)
22373 {
2cf0635d 22374 if (arch.sym_table == NULL)
1cb7d8b1
AM
22375 error (_("%s: unable to dump the index as none was found\n"),
22376 filedata->file_name);
4145f1d5
NC
22377 else
22378 {
591f7597 22379 unsigned long i, l;
4145f1d5
NC
22380 unsigned long current_pos;
22381
1cb7d8b1
AM
22382 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22383 "in the symbol table)\n"),
22384 filedata->file_name, (unsigned long) arch.index_num,
22385 arch.sym_size);
dda8d76d
NC
22386
22387 current_pos = ftell (filedata->handle);
4145f1d5 22388
2cf0635d 22389 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22390 {
1cb7d8b1
AM
22391 if (i == 0
22392 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22393 {
22394 char * member_name
22395 = get_archive_member_name_at (&arch, arch.index_array[i],
22396 &nested_arch);
2cf0635d 22397
1cb7d8b1
AM
22398 if (member_name != NULL)
22399 {
22400 char * qualified_name
22401 = make_qualified_name (&arch, &nested_arch,
22402 member_name);
2cf0635d 22403
1cb7d8b1
AM
22404 if (qualified_name != NULL)
22405 {
22406 printf (_("Contents of binary %s at offset "),
22407 qualified_name);
c2a7d3f5
NC
22408 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22409 putchar ('\n');
1cb7d8b1
AM
22410 free (qualified_name);
22411 }
fd486f32 22412 free (member_name);
4145f1d5
NC
22413 }
22414 }
2cf0635d
NC
22415
22416 if (l >= arch.sym_size)
4145f1d5 22417 {
1cb7d8b1
AM
22418 error (_("%s: end of the symbol table reached "
22419 "before the end of the index\n"),
dda8d76d 22420 filedata->file_name);
015dc7e1 22421 ret = false;
cb8f3167 22422 break;
4145f1d5 22423 }
591f7597 22424 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22425 printf ("\t%.*s\n",
22426 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22427 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22428 }
22429
67ce483b 22430 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22431 l = (l + 7) & ~ 7;
22432 else
22433 l += l & 1;
22434
2cf0635d 22435 if (l < arch.sym_size)
32ec8896 22436 {
d3a49aa8
AM
22437 error (ngettext ("%s: %ld byte remains in the symbol table, "
22438 "but without corresponding entries in "
22439 "the index table\n",
22440 "%s: %ld bytes remain in the symbol table, "
22441 "but without corresponding entries in "
22442 "the index table\n",
22443 arch.sym_size - l),
dda8d76d 22444 filedata->file_name, arch.sym_size - l);
015dc7e1 22445 ret = false;
32ec8896 22446 }
4145f1d5 22447
dda8d76d 22448 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22449 {
1cb7d8b1
AM
22450 error (_("%s: failed to seek back to start of object files "
22451 "in the archive\n"),
dda8d76d 22452 filedata->file_name);
015dc7e1 22453 ret = false;
2cf0635d 22454 goto out;
4145f1d5 22455 }
fb52b2f4 22456 }
4145f1d5
NC
22457
22458 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22459 && !do_segments && !do_header && !do_dump && !do_version
22460 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22461 && !do_section_groups && !do_dyn_syms)
2cf0635d 22462 {
015dc7e1 22463 ret = true; /* Archive index only. */
2cf0635d
NC
22464 goto out;
22465 }
fb52b2f4
NC
22466 }
22467
fb52b2f4
NC
22468 while (1)
22469 {
2cf0635d
NC
22470 char * name;
22471 size_t namelen;
22472 char * qualified_name;
22473
22474 /* Read the next archive header. */
dda8d76d 22475 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22476 {
22477 error (_("%s: failed to seek to next archive header\n"),
22478 arch.file_name);
015dc7e1 22479 ret = false;
1cb7d8b1
AM
22480 break;
22481 }
dda8d76d 22482 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22483 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22484 {
22485 if (got == 0)
2cf0635d 22486 break;
28e817cc
NC
22487 /* PR 24049 - we cannot use filedata->file_name as this will
22488 have already been freed. */
22489 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22490
015dc7e1 22491 ret = false;
1cb7d8b1
AM
22492 break;
22493 }
2cf0635d 22494 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22495 {
22496 error (_("%s: did not find a valid archive header\n"),
22497 arch.file_name);
015dc7e1 22498 ret = false;
1cb7d8b1
AM
22499 break;
22500 }
2cf0635d
NC
22501
22502 arch.next_arhdr_offset += sizeof arch.arhdr;
22503
978c4450 22504 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22505
22506 name = get_archive_member_name (&arch, &nested_arch);
22507 if (name == NULL)
fb52b2f4 22508 {
28e817cc 22509 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22510 ret = false;
d989285c 22511 break;
fb52b2f4 22512 }
2cf0635d 22513 namelen = strlen (name);
fb52b2f4 22514
2cf0635d
NC
22515 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22516 if (qualified_name == NULL)
fb52b2f4 22517 {
28e817cc 22518 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22519 free (name);
015dc7e1 22520 ret = false;
d989285c 22521 break;
fb52b2f4
NC
22522 }
22523
2cf0635d 22524 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22525 {
22526 /* This is a proxy for an external member of a thin archive. */
22527 Filedata * member_filedata;
22528 char * member_file_name = adjust_relative_path
dda8d76d 22529 (filedata->file_name, name, namelen);
32ec8896 22530
fd486f32 22531 free (name);
1cb7d8b1
AM
22532 if (member_file_name == NULL)
22533 {
fd486f32 22534 free (qualified_name);
015dc7e1 22535 ret = false;
1cb7d8b1
AM
22536 break;
22537 }
2cf0635d 22538
015dc7e1 22539 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22540 if (member_filedata == NULL)
22541 {
22542 error (_("Input file '%s' is not readable.\n"), member_file_name);
22543 free (member_file_name);
fd486f32 22544 free (qualified_name);
015dc7e1 22545 ret = false;
1cb7d8b1
AM
22546 break;
22547 }
2cf0635d 22548
978c4450 22549 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22550 member_filedata->file_name = qualified_name;
2cf0635d 22551
75a2da57
AH
22552 /* The call to process_object() expects the file to be at the beginning. */
22553 rewind (member_filedata->handle);
22554
1cb7d8b1 22555 if (! process_object (member_filedata))
015dc7e1 22556 ret = false;
2cf0635d 22557
1cb7d8b1
AM
22558 close_file (member_filedata);
22559 free (member_file_name);
1cb7d8b1 22560 }
2cf0635d 22561 else if (is_thin_archive)
1cb7d8b1
AM
22562 {
22563 Filedata thin_filedata;
eb02c04d 22564
1cb7d8b1 22565 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22566
a043396b
NC
22567 /* PR 15140: Allow for corrupt thin archives. */
22568 if (nested_arch.file == NULL)
22569 {
22570 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22571 qualified_name, name);
fd486f32
AM
22572 free (qualified_name);
22573 free (name);
015dc7e1 22574 ret = false;
a043396b
NC
22575 break;
22576 }
fd486f32 22577 free (name);
a043396b 22578
1cb7d8b1 22579 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22580 filedata->archive_file_offset
22581 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22582
1cb7d8b1
AM
22583 /* The nested archive file will have been opened and setup by
22584 get_archive_member_name. */
978c4450
AM
22585 if (fseek (nested_arch.file, filedata->archive_file_offset,
22586 SEEK_SET) != 0)
1cb7d8b1
AM
22587 {
22588 error (_("%s: failed to seek to archive member.\n"),
22589 nested_arch.file_name);
fd486f32 22590 free (qualified_name);
015dc7e1 22591 ret = false;
1cb7d8b1
AM
22592 break;
22593 }
2cf0635d 22594
dda8d76d
NC
22595 thin_filedata.handle = nested_arch.file;
22596 thin_filedata.file_name = qualified_name;
9abca702 22597
1cb7d8b1 22598 if (! process_object (& thin_filedata))
015dc7e1 22599 ret = false;
1cb7d8b1 22600 }
2cf0635d 22601 else
1cb7d8b1 22602 {
fd486f32 22603 free (name);
978c4450 22604 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22605 filedata->file_name = qualified_name;
1cb7d8b1 22606 if (! process_object (filedata))
015dc7e1 22607 ret = false;
237877b8 22608 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22609 /* Stop looping with "negative" archive_file_size. */
978c4450 22610 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22611 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22612 }
fb52b2f4 22613
2cf0635d 22614 free (qualified_name);
fb52b2f4
NC
22615 }
22616
4145f1d5 22617 out:
2cf0635d
NC
22618 if (nested_arch.file != NULL)
22619 fclose (nested_arch.file);
22620 release_archive (&nested_arch);
22621 release_archive (&arch);
fb52b2f4 22622
d989285c 22623 return ret;
fb52b2f4
NC
22624}
22625
015dc7e1 22626static bool
2cf0635d 22627process_file (char * file_name)
fb52b2f4 22628{
dda8d76d 22629 Filedata * filedata = NULL;
fb52b2f4
NC
22630 struct stat statbuf;
22631 char armag[SARMAG];
015dc7e1 22632 bool ret = true;
fb52b2f4
NC
22633
22634 if (stat (file_name, &statbuf) < 0)
22635 {
f24ddbdd
NC
22636 if (errno == ENOENT)
22637 error (_("'%s': No such file\n"), file_name);
22638 else
22639 error (_("Could not locate '%s'. System error message: %s\n"),
22640 file_name, strerror (errno));
015dc7e1 22641 return false;
f24ddbdd
NC
22642 }
22643
22644 if (! S_ISREG (statbuf.st_mode))
22645 {
22646 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22647 return false;
fb52b2f4
NC
22648 }
22649
dda8d76d
NC
22650 filedata = calloc (1, sizeof * filedata);
22651 if (filedata == NULL)
22652 {
22653 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22654 return false;
dda8d76d
NC
22655 }
22656
22657 filedata->file_name = file_name;
22658 filedata->handle = fopen (file_name, "rb");
22659 if (filedata->handle == NULL)
fb52b2f4 22660 {
f24ddbdd 22661 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22662 free (filedata);
015dc7e1 22663 return false;
fb52b2f4
NC
22664 }
22665
dda8d76d 22666 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22667 {
4145f1d5 22668 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22669 fclose (filedata->handle);
22670 free (filedata);
015dc7e1 22671 return false;
fb52b2f4
NC
22672 }
22673
be7d229a 22674 filedata->file_size = statbuf.st_size;
015dc7e1 22675 filedata->is_separate = false;
f54498b4 22676
fb52b2f4 22677 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22678 {
015dc7e1
AM
22679 if (! process_archive (filedata, false))
22680 ret = false;
32ec8896 22681 }
2cf0635d 22682 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22683 {
015dc7e1
AM
22684 if ( ! process_archive (filedata, true))
22685 ret = false;
32ec8896 22686 }
fb52b2f4
NC
22687 else
22688 {
1b513401 22689 if (do_archive_index && !check_all)
4145f1d5
NC
22690 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22691 file_name);
22692
dda8d76d 22693 rewind (filedata->handle);
978c4450 22694 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22695
dda8d76d 22696 if (! process_object (filedata))
015dc7e1 22697 ret = false;
fb52b2f4
NC
22698 }
22699
dda8d76d 22700 fclose (filedata->handle);
8fb879cd
AM
22701 free (filedata->section_headers);
22702 free (filedata->program_headers);
22703 free (filedata->string_table);
6431e409 22704 free (filedata->dump.dump_sects);
dda8d76d 22705 free (filedata);
32ec8896 22706
fd486f32 22707 free (ba_cache.strtab);
1bd6175a 22708 ba_cache.strtab = NULL;
fd486f32 22709 free (ba_cache.symtab);
1bd6175a 22710 ba_cache.symtab = NULL;
fd486f32
AM
22711 ba_cache.filedata = NULL;
22712
fb52b2f4
NC
22713 return ret;
22714}
22715
252b5132
RH
22716#ifdef SUPPORT_DISASSEMBLY
22717/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22718 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22719 symbols. */
252b5132
RH
22720
22721void
2cf0635d 22722print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22723{
22724 fprintf (outfile,"0x%8.8x", addr);
22725}
22726
e3c8793a 22727/* Needed by the i386 disassembler. */
dda8d76d 22728
252b5132
RH
22729void
22730db_task_printsym (unsigned int addr)
22731{
22732 print_address (addr, stderr);
22733}
22734#endif
22735
22736int
2cf0635d 22737main (int argc, char ** argv)
252b5132 22738{
ff78d6d6
L
22739 int err;
22740
87b9f255 22741#ifdef HAVE_LC_MESSAGES
252b5132 22742 setlocale (LC_MESSAGES, "");
3882b010 22743#endif
3882b010 22744 setlocale (LC_CTYPE, "");
252b5132
RH
22745 bindtextdomain (PACKAGE, LOCALEDIR);
22746 textdomain (PACKAGE);
22747
869b9d07
MM
22748 expandargv (&argc, &argv);
22749
dda8d76d 22750 parse_args (& cmdline, argc, argv);
59f14fc0 22751
18bd398b 22752 if (optind < (argc - 1))
1b513401
NC
22753 /* When displaying information for more than one file,
22754 prefix the information with the file name. */
015dc7e1 22755 show_name = true;
5656ba2c
L
22756 else if (optind >= argc)
22757 {
1b513401 22758 /* Ensure that the warning is always displayed. */
015dc7e1 22759 do_checks = true;
1b513401 22760
5656ba2c
L
22761 warn (_("Nothing to do.\n"));
22762 usage (stderr);
22763 }
18bd398b 22764
015dc7e1 22765 err = false;
252b5132 22766 while (optind < argc)
32ec8896 22767 if (! process_file (argv[optind++]))
015dc7e1 22768 err = true;
252b5132 22769
9db70fc3 22770 free (cmdline.dump_sects);
252b5132 22771
7d9813f1
NA
22772 free (dump_ctf_symtab_name);
22773 free (dump_ctf_strtab_name);
22774 free (dump_ctf_parent_name);
22775
32ec8896 22776 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22777}