]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Remove redunant test of ELF size in core note decoder.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
fd67aa11 2 Copyright (C) 1998-2024 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>
1f5a3546
FS
47#ifdef HAVE_ZSTD
48#include <zstd.h>
49#endif
7bfd842d 50#include <wchar.h>
252b5132 51
2952f10c
SM
52#if defined HAVE_MSGPACK
53#include <msgpack.h>
54#endif
55
19936277 56/* Define BFD64 here, even if our default architecture is 32 bit ELF
625d49fc 57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
19936277 58#define BFD64
a952a375 59
3db64b00
AM
60#include "bfd.h"
61#include "bucomm.h"
3284fe0c 62#include "elfcomm.h"
0d646226 63#include "demanguse.h"
19e6b90e 64#include "dwarf.h"
7d9813f1 65#include "ctf-api.h"
42b6953b 66#include "sframe-api.h"
79bc120c 67#include "demangle.h"
252b5132
RH
68
69#include "elf/common.h"
70#include "elf/external.h"
71#include "elf/internal.h"
252b5132 72
4b78141a
NC
73
74/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
78
79#include "elf/h8.h"
80#undef _ELF_H8_H
81
82/* Undo the effects of #including reloc-macros.h. */
83
84#undef START_RELOC_NUMBERS
85#undef RELOC_NUMBER
86#undef FAKE_RELOC
87#undef EMPTY_RELOC
88#undef END_RELOC_NUMBERS
89#undef _RELOC_MACROS_H
90
252b5132
RH
91/* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
94
95#define RELOC_MACROS_GEN_FUNC
96
a06ea964 97#include "elf/aarch64.h"
252b5132 98#include "elf/alpha.h"
c077c580 99#include "elf/amdgpu.h"
3b16e843 100#include "elf/arc.h"
252b5132 101#include "elf/arm.h"
3b16e843 102#include "elf/avr.h"
1d65ded4 103#include "elf/bfin.h"
60bca95a 104#include "elf/cr16.h"
3b16e843 105#include "elf/cris.h"
1c0d3aa6 106#include "elf/crx.h"
b8891f8d 107#include "elf/csky.h"
252b5132
RH
108#include "elf/d10v.h"
109#include "elf/d30v.h"
d172d4ba 110#include "elf/dlx.h"
aca4efc7 111#include "elf/bpf.h"
cfb8c092 112#include "elf/epiphany.h"
252b5132 113#include "elf/fr30.h"
5c70f934 114#include "elf/frv.h"
3f8107ab 115#include "elf/ft32.h"
3b16e843
NC
116#include "elf/h8.h"
117#include "elf/hppa.h"
118#include "elf/i386.h"
f954747f
AM
119#include "elf/i370.h"
120#include "elf/i860.h"
121#include "elf/i960.h"
3b16e843 122#include "elf/ia64.h"
1e4cf259 123#include "elf/ip2k.h"
6e712424 124#include "elf/kvx.h"
84e94c90 125#include "elf/lm32.h"
1c0d3aa6 126#include "elf/iq2000.h"
49f58d10 127#include "elf/m32c.h"
3b16e843
NC
128#include "elf/m32r.h"
129#include "elf/m68k.h"
75751cd9 130#include "elf/m68hc11.h"
7b4ae824 131#include "elf/s12z.h"
252b5132 132#include "elf/mcore.h"
15ab5209 133#include "elf/mep.h"
a3c62988 134#include "elf/metag.h"
7ba29e2a 135#include "elf/microblaze.h"
3b16e843 136#include "elf/mips.h"
3c3bdf30 137#include "elf/mmix.h"
3b16e843
NC
138#include "elf/mn10200.h"
139#include "elf/mn10300.h"
5506d11a 140#include "elf/moxie.h"
4970f871 141#include "elf/mt.h"
2469cfa2 142#include "elf/msp430.h"
35c08157 143#include "elf/nds32.h"
fe944acf 144#include "elf/nfp.h"
13761a11 145#include "elf/nios2.h"
73589c9d 146#include "elf/or1k.h"
7d466069 147#include "elf/pj.h"
3b16e843 148#include "elf/ppc.h"
c833c019 149#include "elf/ppc64.h"
2b100bb5 150#include "elf/pru.h"
03336641 151#include "elf/riscv.h"
99c513f6 152#include "elf/rl78.h"
c7927a3c 153#include "elf/rx.h"
a85d7ed0 154#include "elf/s390.h"
1c0d3aa6 155#include "elf/score.h"
3b16e843
NC
156#include "elf/sh.h"
157#include "elf/sparc.h"
e9f53129 158#include "elf/spu.h"
40b36596 159#include "elf/tic6x.h"
aa137e4d
NC
160#include "elf/tilegx.h"
161#include "elf/tilepro.h"
3b16e843 162#include "elf/v850.h"
179d3252 163#include "elf/vax.h"
619ed720 164#include "elf/visium.h"
f96bd6c2 165#include "elf/wasm32.h"
3b16e843 166#include "elf/x86-64.h"
f6c1a2d5 167#include "elf/xgate.h"
93fbbb04 168#include "elf/xstormy16.h"
88da6820 169#include "elf/xtensa.h"
6655dba2 170#include "elf/z80.h"
e9a0721f 171#include "elf/loongarch.h"
b5c37946 172#include "elf/bpf.h"
252b5132 173
252b5132 174#include "getopt.h"
566b0d53 175#include "libiberty.h"
09c11c86 176#include "safe-ctype.h"
2cf0635d 177#include "filenames.h"
252b5132 178
15b42fb0
AM
179#ifndef offsetof
180#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
181#endif
182
6a40cf0c
NC
183typedef struct elf_section_list
184{
dda8d76d
NC
185 Elf_Internal_Shdr * hdr;
186 struct elf_section_list * next;
6a40cf0c
NC
187} elf_section_list;
188
dda8d76d
NC
189/* Flag bits indicating particular types of dump. */
190#define HEX_DUMP (1 << 0) /* The -x command line switch. */
191#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
192#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
193#define STRING_DUMP (1 << 3) /* The -p command line switch. */
194#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 195#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 196#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
dda8d76d
NC
197
198typedef unsigned char dump_type;
199
200/* A linked list of the section names for which dumps were requested. */
201struct dump_list_entry
202{
203 char * name;
204 dump_type type;
205 struct dump_list_entry * next;
206};
207
6431e409
AM
208/* A dynamic array of flags indicating for which sections a dump
209 has been requested via command line switches. */
1b513401
NC
210struct dump_data
211{
6431e409
AM
212 dump_type * dump_sects;
213 unsigned int num_dump_sects;
214};
215
216static struct dump_data cmdline;
217
218static struct dump_list_entry * dump_sects_byname;
219
2cf0635d 220char * program_name = "readelf";
dda8d76d 221
015dc7e1
AM
222static bool show_name = false;
223static bool do_dynamic = false;
224static bool do_syms = false;
225static bool do_dyn_syms = false;
226static bool do_lto_syms = false;
227static bool do_reloc = false;
228static bool do_sections = false;
229static bool do_section_groups = false;
230static bool do_section_details = false;
231static bool do_segments = false;
232static bool do_unwind = false;
233static bool do_using_dynamic = false;
234static bool do_header = false;
235static bool do_dump = false;
236static bool do_version = false;
237static bool do_histogram = false;
238static bool do_debugging = false;
239static bool do_ctf = false;
42b6953b 240static bool do_sframe = false;
015dc7e1
AM
241static bool do_arch = false;
242static bool do_notes = false;
243static bool do_archive_index = false;
244static bool check_all = false;
245static bool is_32bit_elf = false;
246static bool decompress_dumps = false;
247static bool do_not_show_symbol_truncation = false;
248static bool do_demangle = false; /* Pretty print C++ symbol names. */
249static bool process_links = false;
e1dbfc17 250static bool dump_any_debugging = false;
b6ac461a 251static bool extra_sym_info = false;
79bc120c 252static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 253static int sym_base = 0;
252b5132 254
7d9813f1
NA
255static char *dump_ctf_parent_name;
256static char *dump_ctf_symtab_name;
257static char *dump_ctf_strtab_name;
258
e4b17d5c
L
259struct group_list
260{
dda8d76d
NC
261 struct group_list * next;
262 unsigned int section_index;
e4b17d5c
L
263};
264
265struct group
266{
dda8d76d
NC
267 struct group_list * root;
268 unsigned int group_index;
e4b17d5c
L
269};
270
978c4450
AM
271typedef struct filedata
272{
273 const char * file_name;
015dc7e1 274 bool is_separate;
978c4450 275 FILE * handle;
be7d229a 276 uint64_t file_size;
978c4450 277 Elf_Internal_Ehdr file_header;
26c527e6
AM
278 uint64_t archive_file_offset;
279 uint64_t archive_file_size;
066f8fbe 280 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
281 Elf_Internal_Shdr * section_headers;
282 Elf_Internal_Phdr * program_headers;
283 char * string_table;
26c527e6
AM
284 uint64_t string_table_length;
285 uint64_t dynamic_addr;
be7d229a 286 uint64_t dynamic_size;
26c527e6 287 uint64_t dynamic_nent;
978c4450 288 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 289 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 290 char * dynamic_strings;
26c527e6 291 uint64_t dynamic_strings_length;
8ac10c5b 292 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 293 uint64_t num_dynamic_syms;
978c4450 294 Elf_Internal_Sym * dynamic_symbols;
26c527e6 295 uint64_t version_info[16];
978c4450
AM
296 unsigned int dynamic_syminfo_nent;
297 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 298 uint64_t dynamic_syminfo_offset;
be7d229a
AM
299 uint64_t nbuckets;
300 uint64_t nchains;
625d49fc
AM
301 uint64_t * buckets;
302 uint64_t * chains;
be7d229a
AM
303 uint64_t ngnubuckets;
304 uint64_t ngnuchains;
625d49fc
AM
305 uint64_t * gnubuckets;
306 uint64_t * gnuchains;
307 uint64_t * mipsxlat;
308 uint64_t gnusymidx;
13acb58d 309 char * program_interpreter;
bc227f4c 310 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
311 uint64_t dynamic_info_DT_GNU_HASH;
312 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
313 elf_section_list * symtab_shndx_list;
314 size_t group_count;
315 struct group * section_groups;
316 struct group ** section_headers_groups;
317 /* A dynamic array of flags indicating for which sections a dump of
318 some kind has been requested. It is reset on a per-object file
319 basis and then initialised from the cmdline_dump_sects array,
320 the results of interpreting the -w switch, and the
321 dump_sects_byname list. */
322 struct dump_data dump;
323} Filedata;
aef1f6d0 324
c256ffe7 325/* How to print a vma value. */
843dd992
NC
326typedef enum print_mode
327{
328 HEX,
047c3dbf 329 HEX_5,
843dd992
NC
330 DEC,
331 DEC_5,
332 UNSIGNED,
047c3dbf 333 UNSIGNED_5,
843dd992 334 PREFIX_HEX,
047c3dbf 335 PREFIX_HEX_5,
843dd992 336 FULL_HEX,
047c3dbf
NL
337 LONG_HEX,
338 OCTAL,
339 OCTAL_5
843dd992
NC
340}
341print_mode;
342
b3aa80b4
NC
343typedef enum unicode_display_type
344{
345 unicode_default = 0,
346 unicode_locale,
347 unicode_escape,
348 unicode_hex,
349 unicode_highlight,
350 unicode_invalid
351} unicode_display_type;
352
353static unicode_display_type unicode_display = unicode_default;
354
a7fd1186
FS
355typedef enum
356{
357 reltype_unknown,
358 reltype_rel,
359 reltype_rela,
360 reltype_relr
361} relocation_type;
362
bb4d2ac2
L
363/* Versioned symbol info. */
364enum versioned_symbol_info
365{
366 symbol_undefined,
367 symbol_hidden,
368 symbol_public
369};
370
63cf857e
AM
371static int
372fseek64 (FILE *stream, int64_t offset, int whence)
373{
374#if defined (HAVE_FSEEKO64)
375 off64_t o = offset;
376 if (o != offset)
377 {
378 errno = EINVAL;
379 return -1;
380 }
381 return fseeko64 (stream, o, whence);
382#elif defined (HAVE_FSEEKO)
383 off_t o = offset;
384 if (o != offset)
385 {
386 errno = EINVAL;
387 return -1;
388 }
389 return fseeko (stream, o, whence);
390#else
391 long o = offset;
392 if (o != offset)
393 {
394 errno = EINVAL;
395 return -1;
396 }
397 return fseek (stream, o, whence);
398#endif
399}
400
32ec8896 401static const char * get_symbol_version_string
26c527e6 402 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 403 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 404
9c19a809
NC
405#define UNKNOWN -1
406
84714f86
AM
407static inline const char *
408section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
409{
410 return filedata->string_table + hdr->sh_name;
411}
b9e920ec 412
84714f86
AM
413static inline bool
414section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
415{
b6ac461a
NC
416 return (filedata != NULL
417 && hdr != NULL
84714f86
AM
418 && filedata->string_table != NULL
419 && hdr->sh_name < filedata->string_table_length);
420}
b9e920ec 421
b6ac461a
NC
422/* Returns true if the given index is real/valid. Note: "real" here
423 means "references a real section in the section header" and not
424 "is a valid section index as per the ELF standard". */
425
426static inline bool
427section_index_real (const Filedata *filedata, unsigned int ndx)
84714f86 428{
b6ac461a
NC
429 return (filedata != NULL
430 && filedata->section_headers != NULL
431 && ndx < filedata->file_header.e_shnum
432 && ndx > 0);
84714f86 433}
b6ac461a 434
ee42cf8c 435#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 436
84714f86
AM
437static inline bool
438valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
439{
440 return strtab != NULL && offset < strtab_size;
441}
442
443static inline bool
444valid_dynamic_name (const Filedata *filedata, uint64_t offset)
445{
446 return valid_symbol_name (filedata->dynamic_strings,
447 filedata->dynamic_strings_length, offset);
448}
449
d79b3d50
NC
450/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
451 already been called and verified that the string exists. */
84714f86
AM
452static inline const char *
453get_dynamic_name (const Filedata *filedata, size_t offset)
454{
455 return filedata->dynamic_strings + offset;
456}
18bd398b 457
61865e30
NC
458#define REMOVE_ARCH_BITS(ADDR) \
459 do \
460 { \
dda8d76d 461 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
462 (ADDR) &= ~1; \
463 } \
464 while (0)
f16a9783
MS
465
466/* Get the correct GNU hash section name. */
978c4450
AM
467#define GNU_HASH_SECTION_NAME(filedata) \
468 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 469\f
dda8d76d
NC
470/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
471 OFFSET + the offset of the current archive member, if we are examining an
472 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
473 allocate a buffer using malloc and fill that. In either case return the
474 pointer to the start of the retrieved data or NULL if something went wrong.
475 If something does go wrong and REASON is not NULL then emit an error
476 message using REASON as part of the context. */
59245841 477
c256ffe7 478static void *
be7d229a
AM
479get_data (void *var,
480 Filedata *filedata,
26c527e6 481 uint64_t offset,
be7d229a
AM
482 uint64_t size,
483 uint64_t nmemb,
484 const char *reason)
a6e9f9df 485{
2cf0635d 486 void * mvar;
be7d229a 487 uint64_t amt = size * nmemb;
a6e9f9df 488
c256ffe7 489 if (size == 0 || nmemb == 0)
a6e9f9df
AM
490 return NULL;
491
be7d229a
AM
492 /* If size_t is smaller than uint64_t, eg because you are building
493 on a 32-bit host, then make sure that when the sizes are cast to
494 size_t no information is lost. */
7c1c1904
AM
495 if ((size_t) size != size
496 || (size_t) nmemb != nmemb
be7d229a
AM
497 || (size_t) amt != amt
498 || amt / size != nmemb
499 || (size_t) amt + 1 == 0)
57028622
NC
500 {
501 if (reason)
b8281767
AM
502 error (_("Size overflow prevents reading %" PRIu64
503 " elements of size %" PRIu64 " for %s\n"),
be7d229a 504 nmemb, size, reason);
57028622
NC
505 return NULL;
506 }
507
c22b42ce 508 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 509 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
510 if (filedata->archive_file_offset > filedata->file_size
511 || offset > filedata->file_size - filedata->archive_file_offset
512 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 513 {
049b0c3a 514 if (reason)
b8281767 515 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 516 amt, reason);
a6e9f9df
AM
517 return NULL;
518 }
519
63cf857e
AM
520 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
521 SEEK_SET))
071436c6
NC
522 {
523 if (reason)
26c527e6 524 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 525 filedata->archive_file_offset + offset, reason);
071436c6
NC
526 return NULL;
527 }
528
a6e9f9df
AM
529 mvar = var;
530 if (mvar == NULL)
531 {
7c1c1904
AM
532 /* + 1 so that we can '\0' terminate invalid string table sections. */
533 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
534
535 if (mvar == NULL)
536 {
049b0c3a 537 if (reason)
b8281767 538 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 539 amt, reason);
a6e9f9df
AM
540 return NULL;
541 }
c256ffe7 542
c9c1d674 543 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
544 }
545
dda8d76d 546 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 547 {
049b0c3a 548 if (reason)
b8281767 549 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 550 amt, reason);
a6e9f9df
AM
551 if (mvar != var)
552 free (mvar);
553 return NULL;
554 }
555
556 return mvar;
557}
558
32ec8896
NC
559/* Print a VMA value in the MODE specified.
560 Returns the number of characters displayed. */
cb8f3167 561
32ec8896 562static unsigned int
625d49fc 563print_vma (uint64_t vma, print_mode mode)
66543521 564{
32ec8896 565 unsigned int nc = 0;
66543521 566
14a91970 567 switch (mode)
66543521 568 {
14a91970
AM
569 case FULL_HEX:
570 nc = printf ("0x");
1a0670f3 571 /* Fall through. */
14a91970 572 case LONG_HEX:
f493c217 573 if (!is_32bit_elf)
625d49fc
AM
574 return nc + printf ("%16.16" PRIx64, vma);
575 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 576
14a91970
AM
577 case DEC_5:
578 if (vma <= 99999)
625d49fc 579 return printf ("%5" PRId64, vma);
1a0670f3 580 /* Fall through. */
14a91970
AM
581 case PREFIX_HEX:
582 nc = printf ("0x");
1a0670f3 583 /* Fall through. */
14a91970 584 case HEX:
625d49fc 585 return nc + printf ("%" PRIx64, vma);
b19aac67 586
047c3dbf
NL
587 case PREFIX_HEX_5:
588 nc = printf ("0x");
589 /* Fall through. */
590 case HEX_5:
625d49fc 591 return nc + printf ("%05" PRIx64, vma);
047c3dbf 592
14a91970 593 case DEC:
625d49fc 594 return printf ("%" PRId64, vma);
b19aac67 595
14a91970 596 case UNSIGNED:
625d49fc 597 return printf ("%" PRIu64, vma);
32ec8896 598
047c3dbf 599 case UNSIGNED_5:
625d49fc 600 return printf ("%5" PRIu64, vma);
047c3dbf
NL
601
602 case OCTAL:
625d49fc 603 return printf ("%" PRIo64, vma);
047c3dbf
NL
604
605 case OCTAL_5:
625d49fc 606 return printf ("%5" PRIo64, vma);
047c3dbf 607
32ec8896
NC
608 default:
609 /* FIXME: Report unrecognised mode ? */
610 return 0;
f7a99963 611 }
f7a99963
NC
612}
613
047c3dbf 614
7bfd842d 615/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 616 multibye characters (assuming the host environment supports them).
31104126 617
b6ac461a
NC
618 Display at most abs(WIDTH) characters, truncating as necessary,
619 unless do_wide or extra_sym_info is true.
7bfd842d 620
0942c7ab
NC
621 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
622 abs(WIDTH) - 5 characters followed by "[...]".
623
7bfd842d
NC
624 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
625 padding as necessary.
171191ba
NC
626
627 Returns the number of emitted characters. */
628
629static unsigned int
b6ac461a 630print_symbol_name (signed int width, const char * symbol)
31104126 631{
015dc7e1
AM
632 bool extra_padding = false;
633 bool do_dots = false;
32ec8896 634 signed int num_printed = 0;
3bfcb652 635#ifdef HAVE_MBSTATE_T
7bfd842d 636 mbstate_t state;
3bfcb652 637#endif
32ec8896 638 unsigned int width_remaining;
79bc120c 639 const void * alloced_symbol = NULL;
961c521f 640
7bfd842d 641 if (width < 0)
961c521f 642 {
88305e1b 643 /* Keep the width positive. This helps the code below. */
961c521f 644 width = - width;
015dc7e1 645 extra_padding = true;
0b4362b0 646 }
56d8f8a9
NC
647 else if (width == 0)
648 return 0;
961c521f 649
b6ac461a 650 if (do_wide || extra_sym_info)
7bfd842d
NC
651 /* Set the remaining width to a very large value.
652 This simplifies the code below. */
653 width_remaining = INT_MAX;
654 else
0942c7ab
NC
655 {
656 width_remaining = width;
b6ac461a 657
0942c7ab
NC
658 if (! do_not_show_symbol_truncation
659 && (int) strlen (symbol) > width)
660 {
661 width_remaining -= 5;
662 if ((int) width_remaining < 0)
663 width_remaining = 0;
015dc7e1 664 do_dots = true;
0942c7ab
NC
665 }
666 }
cb8f3167 667
3bfcb652 668#ifdef HAVE_MBSTATE_T
7bfd842d
NC
669 /* Initialise the multibyte conversion state. */
670 memset (& state, 0, sizeof (state));
3bfcb652 671#endif
961c521f 672
79bc120c
NC
673 if (do_demangle && *symbol)
674 {
675 const char * res = cplus_demangle (symbol, demangle_flags);
676
677 if (res != NULL)
678 alloced_symbol = symbol = res;
679 }
680
7bfd842d
NC
681 while (width_remaining)
682 {
683 size_t n;
7bfd842d 684 const char c = *symbol++;
961c521f 685
7bfd842d 686 if (c == 0)
961c521f
NC
687 break;
688
b3aa80b4
NC
689 if (ISPRINT (c))
690 {
691 putchar (c);
692 width_remaining --;
693 num_printed ++;
694 }
695 else if (ISCNTRL (c))
961c521f 696 {
b3aa80b4
NC
697 /* Do not print control characters directly as they can affect terminal
698 settings. Such characters usually appear in the names generated
699 by the assembler for local labels. */
700
7bfd842d 701 if (width_remaining < 2)
961c521f
NC
702 break;
703
7bfd842d
NC
704 printf ("^%c", c + 0x40);
705 width_remaining -= 2;
171191ba 706 num_printed += 2;
961c521f 707 }
b3aa80b4 708 else if (c == 0x7f)
7bfd842d 709 {
b3aa80b4
NC
710 if (width_remaining < 5)
711 break;
712 printf ("<DEL>");
713 width_remaining -= 5;
714 num_printed += 5;
715 }
716 else if (unicode_display != unicode_locale
717 && unicode_display != unicode_default)
718 {
719 /* Display unicode characters as something else. */
720 unsigned char bytes[4];
721 bool is_utf8;
795588ae 722 unsigned int nbytes;
b3aa80b4
NC
723
724 bytes[0] = c;
725
726 if (bytes[0] < 0xc0)
727 {
728 nbytes = 1;
729 is_utf8 = false;
730 }
731 else
732 {
733 bytes[1] = *symbol++;
734
735 if ((bytes[1] & 0xc0) != 0x80)
736 {
737 is_utf8 = false;
738 /* Do not consume this character. It may only
739 be the first byte in the sequence that was
740 corrupt. */
741 --symbol;
742 nbytes = 1;
743 }
744 else if ((bytes[0] & 0x20) == 0)
745 {
746 is_utf8 = true;
747 nbytes = 2;
748 }
749 else
750 {
751 bytes[2] = *symbol++;
752
753 if ((bytes[2] & 0xc0) != 0x80)
754 {
755 is_utf8 = false;
756 symbol -= 2;
757 nbytes = 1;
758 }
759 else if ((bytes[0] & 0x10) == 0)
760 {
761 is_utf8 = true;
762 nbytes = 3;
763 }
764 else
765 {
766 bytes[3] = *symbol++;
767
768 nbytes = 4;
769
770 if ((bytes[3] & 0xc0) != 0x80)
771 {
772 is_utf8 = false;
773 symbol -= 3;
774 nbytes = 1;
775 }
776 else
777 is_utf8 = true;
778 }
779 }
780 }
781
782 if (unicode_display == unicode_invalid)
783 is_utf8 = false;
784
785 if (unicode_display == unicode_hex || ! is_utf8)
786 {
795588ae 787 unsigned int i;
b3aa80b4
NC
788
789 if (width_remaining < (nbytes * 2) + 2)
790 break;
791
792 putchar (is_utf8 ? '<' : '{');
793 printf ("0x");
794 for (i = 0; i < nbytes; i++)
795 printf ("%02x", bytes[i]);
796 putchar (is_utf8 ? '>' : '}');
797 }
798 else
799 {
800 if (unicode_display == unicode_highlight && isatty (1))
801 printf ("\x1B[31;47m"); /* Red. */
802
803 switch (nbytes)
804 {
805 case 2:
806 if (width_remaining < 6)
807 break;
808 printf ("\\u%02x%02x",
809 (bytes[0] & 0x1c) >> 2,
810 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
811 break;
812 case 3:
813 if (width_remaining < 6)
814 break;
815 printf ("\\u%02x%02x",
816 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
817 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
818 break;
819 case 4:
820 if (width_remaining < 8)
821 break;
822 printf ("\\u%02x%02x%02x",
823 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
824 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
825 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
826
827 break;
828 default:
829 /* URG. */
830 break;
831 }
832
833 if (unicode_display == unicode_highlight && isatty (1))
834 printf ("\033[0m"); /* Default colour. */
835 }
836
837 if (bytes[nbytes - 1] == 0)
838 break;
7bfd842d 839 }
961c521f
NC
840 else
841 {
3bfcb652
NC
842#ifdef HAVE_MBSTATE_T
843 wchar_t w;
844#endif
7bfd842d
NC
845 /* Let printf do the hard work of displaying multibyte characters. */
846 printf ("%.1s", symbol - 1);
847 width_remaining --;
848 num_printed ++;
849
3bfcb652 850#ifdef HAVE_MBSTATE_T
7bfd842d
NC
851 /* Try to find out how many bytes made up the character that was
852 just printed. Advance the symbol pointer past the bytes that
853 were displayed. */
854 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
855#else
856 n = 1;
857#endif
7bfd842d
NC
858 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
859 symbol += (n - 1);
961c521f 860 }
961c521f 861 }
171191ba 862
0942c7ab
NC
863 if (do_dots)
864 num_printed += printf ("[...]");
865
7bfd842d 866 if (extra_padding && num_printed < width)
171191ba
NC
867 {
868 /* Fill in the remaining spaces. */
7bfd842d
NC
869 printf ("%-*s", width - num_printed, " ");
870 num_printed = width;
171191ba
NC
871 }
872
79bc120c 873 free ((void *) alloced_symbol);
171191ba 874 return num_printed;
31104126
NC
875}
876
1449284b 877/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
878 the given section's name. Like print_symbol, except that it does not try
879 to print multibyte characters, it just interprets them as hex values. */
880
881static const char *
dda8d76d 882printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 883{
b6ac461a
NC
884#define NUM_SEC_NAME_BUFS 5
885#define MAX_PRINT_SEC_NAME_LEN 256
886
887 static int sec_name_buf_index = 0;
888 /* We use a rotating array of static buffers, so that multiple successive calls
889 to printable_section_name() will still work. eg when used in a printf. */
890 static char sec_name_buf [NUM_SEC_NAME_BUFS][MAX_PRINT_SEC_NAME_LEN + 1];
891
892 const char * name;
893 char * buf;
894 char * buf_start;
74e1a04b
NC
895 char c;
896 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
897
b6ac461a
NC
898 /* Validate the input parameters. */
899 if (filedata == NULL)
900 return _("<internal error>");
901 if (sec == NULL)
902 return _("<none>");
903 if (filedata->string_table == NULL)
904 return _("<no-strings>");
905 if (sec->sh_name >= filedata->string_table_length)
906 return _("<corrupt>");
907
908 /* Select a buffer to use. */
909 buf_start = buf = sec_name_buf[sec_name_buf_index];
910 if (++sec_name_buf_index >= NUM_SEC_NAME_BUFS)
911 sec_name_buf_index = 0;
912
913 name = section_name (filedata, sec);
914
74e1a04b
NC
915 while ((c = * name ++) != 0)
916 {
917 if (ISCNTRL (c))
918 {
919 if (remaining < 2)
920 break;
948f632f 921
74e1a04b
NC
922 * buf ++ = '^';
923 * buf ++ = c + 0x40;
924 remaining -= 2;
925 }
926 else if (ISPRINT (c))
927 {
928 * buf ++ = c;
929 remaining -= 1;
930 }
931 else
932 {
933 static char hex[17] = "0123456789ABCDEF";
934
935 if (remaining < 4)
936 break;
937 * buf ++ = '<';
938 * buf ++ = hex[(c & 0xf0) >> 4];
939 * buf ++ = hex[c & 0x0f];
940 * buf ++ = '>';
941 remaining -= 4;
942 }
943
944 if (remaining == 0)
945 break;
946 }
947
948 * buf = 0;
b6ac461a
NC
949 return buf_start;
950}
951
952/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
953 This OS has so many departures from the ELF standard that we test it at
954 many places. */
955
956static inline bool
957is_ia64_vms (Filedata * filedata)
958{
959 return filedata->file_header.e_machine == EM_IA_64
960 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
74e1a04b
NC
961}
962
963static const char *
b6ac461a
NC
964printable_section_name_from_index (Filedata * filedata,
965 size_t ndx,
966 bool * is_special)
74e1a04b 967{
b6ac461a
NC
968 if (is_special != NULL)
969 * is_special = true;
970
971 switch (ndx)
972 {
973 case SHN_UNDEF: return "UND";
974 case SHN_ABS: return "ABS";
975 case SHN_COMMON: return "COM";
976 break;
977 }
978
979 if (filedata != NULL)
980 {
981 switch (filedata->file_header.e_machine)
982 {
983 case EM_MIPS:
984 if (ndx == SHN_MIPS_SCOMMON)
985 return "SCOMMON";
986 if (ndx == SHN_MIPS_SUNDEFINED)
987 return "SUNDEF";
988 break;
989
990 case EM_TI_C6000:
991 if (ndx == SHN_TIC6X_SCOMMON)
992 return "SCOM";
993 break;
994
995 case EM_X86_64:
996 case EM_L1OM:
997 case EM_K1OM:
998 if (ndx == SHN_X86_64_LCOMMON)
999 return "LARGE_COM";
1000 break;
1001
1002 case EM_IA_64:
1003 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1004 && ndx == SHN_IA_64_ANSI_COMMON)
1005 return "ANSI_COM";
1006
1007 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1008 return "VMS_SYMVEC";
1009 break;
1010
1011 default:
1012 break;
1013 }
74e1a04b 1014
b6ac461a
NC
1015 if (filedata->section_headers != NULL
1016 && ndx < filedata->file_header.e_shnum)
1017 {
1018 const char * res;
1019
1020 res = printable_section_name (filedata, filedata->section_headers + ndx);
1021 if (is_special != NULL)
1022 * is_special = (res[0] == '<');
1023
1024 return res;
1025 }
1026 }
1027
1028 static char name_buf[40];
1029 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1030
1031 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1032 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1033 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1034 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1035 else if (ndx >= SHN_LORESERVE)
1036 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1037 else if (filedata->file_header.e_shnum != 0
1038 && ndx >= filedata->file_header.e_shnum)
1039 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1040 else
1041 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1042
1043 return name_buf;
74e1a04b
NC
1044}
1045
89fac5e3
RS
1046/* Return a pointer to section NAME, or NULL if no such section exists. */
1047
1048static Elf_Internal_Shdr *
dda8d76d 1049find_section (Filedata * filedata, const char * name)
89fac5e3
RS
1050{
1051 unsigned int i;
1052
68807c3c
NC
1053 if (filedata->section_headers == NULL)
1054 return NULL;
dda8d76d
NC
1055
1056 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
1057 if (section_name_valid (filedata, filedata->section_headers + i)
1058 && streq (section_name (filedata, filedata->section_headers + i),
1059 name))
dda8d76d 1060 return filedata->section_headers + i;
89fac5e3
RS
1061
1062 return NULL;
1063}
1064
0b6ae522
DJ
1065/* Return a pointer to a section containing ADDR, or NULL if no such
1066 section exists. */
1067
1068static Elf_Internal_Shdr *
625d49fc 1069find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
1070{
1071 unsigned int i;
1072
68807c3c
NC
1073 if (filedata->section_headers == NULL)
1074 return NULL;
1075
dda8d76d 1076 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 1077 {
dda8d76d
NC
1078 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1079
0b6ae522
DJ
1080 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1081 return sec;
1082 }
1083
1084 return NULL;
1085}
1086
071436c6 1087static Elf_Internal_Shdr *
dda8d76d 1088find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
1089{
1090 unsigned int i;
1091
68807c3c
NC
1092 if (filedata->section_headers == NULL)
1093 return NULL;
1094
dda8d76d 1095 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 1096 {
dda8d76d
NC
1097 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1098
071436c6
NC
1099 if (sec->sh_type == type)
1100 return sec;
1101 }
1102
1103 return NULL;
1104}
1105
657d0d47
CC
1106/* Return a pointer to section NAME, or NULL if no such section exists,
1107 restricted to the list of sections given in SET. */
1108
1109static Elf_Internal_Shdr *
dda8d76d 1110find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
1111{
1112 unsigned int i;
1113
68807c3c
NC
1114 if (filedata->section_headers == NULL)
1115 return NULL;
1116
657d0d47
CC
1117 if (set != NULL)
1118 {
1119 while ((i = *set++) > 0)
b814a36d
NC
1120 {
1121 /* See PR 21156 for a reproducer. */
dda8d76d 1122 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1123 continue; /* FIXME: Should we issue an error message ? */
1124
84714f86
AM
1125 if (section_name_valid (filedata, filedata->section_headers + i)
1126 && streq (section_name (filedata, filedata->section_headers + i),
1127 name))
dda8d76d 1128 return filedata->section_headers + i;
b814a36d 1129 }
657d0d47
CC
1130 }
1131
dda8d76d 1132 return find_section (filedata, name);
657d0d47
CC
1133}
1134
bcedfee6 1135/* Guess the relocation size commonly used by the specific machines. */
252b5132 1136
015dc7e1 1137static bool
2dc4cec1 1138guess_is_rela (unsigned int e_machine)
252b5132 1139{
9c19a809 1140 switch (e_machine)
252b5132
RH
1141 {
1142 /* Targets that use REL relocations. */
252b5132 1143 case EM_386:
22abe556 1144 case EM_IAMCU:
f954747f 1145 case EM_960:
e9f53129 1146 case EM_ARM:
2b0337b0 1147 case EM_D10V:
252b5132 1148 case EM_CYGNUS_D10V:
e9f53129 1149 case EM_DLX:
252b5132 1150 case EM_MIPS:
4fe85591 1151 case EM_MIPS_RS3_LE:
e9f53129 1152 case EM_CYGNUS_M32R:
1c0d3aa6 1153 case EM_SCORE:
f6c1a2d5 1154 case EM_XGATE:
fe944acf 1155 case EM_NFP:
aca4efc7 1156 case EM_BPF:
015dc7e1 1157 return false;
103f02d3 1158
252b5132
RH
1159 /* Targets that use RELA relocations. */
1160 case EM_68K:
f954747f 1161 case EM_860:
a06ea964 1162 case EM_AARCH64:
cfb8c092 1163 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1164 case EM_ALPHA:
1165 case EM_ALTERA_NIOS2:
886a2506
NC
1166 case EM_ARC:
1167 case EM_ARC_COMPACT:
1168 case EM_ARC_COMPACT2:
b5c37946
SJ
1169 case EM_ARC_COMPACT3:
1170 case EM_ARC_COMPACT3_64:
e9f53129
AM
1171 case EM_AVR:
1172 case EM_AVR_OLD:
1173 case EM_BLACKFIN:
60bca95a 1174 case EM_CR16:
e9f53129
AM
1175 case EM_CRIS:
1176 case EM_CRX:
b8891f8d 1177 case EM_CSKY:
2b0337b0 1178 case EM_D30V:
252b5132 1179 case EM_CYGNUS_D30V:
2b0337b0 1180 case EM_FR30:
3f8107ab 1181 case EM_FT32:
252b5132 1182 case EM_CYGNUS_FR30:
5c70f934 1183 case EM_CYGNUS_FRV:
e9f53129
AM
1184 case EM_H8S:
1185 case EM_H8_300:
1186 case EM_H8_300H:
800eeca4 1187 case EM_IA_64:
1e4cf259
NC
1188 case EM_IP2K:
1189 case EM_IP2K_OLD:
3b36097d 1190 case EM_IQ2000:
6e712424 1191 case EM_KVX:
84e94c90 1192 case EM_LATTICEMICO32:
ff7eeb89 1193 case EM_M32C_OLD:
49f58d10 1194 case EM_M32C:
e9f53129
AM
1195 case EM_M32R:
1196 case EM_MCORE:
15ab5209 1197 case EM_CYGNUS_MEP:
a3c62988 1198 case EM_METAG:
e9f53129
AM
1199 case EM_MMIX:
1200 case EM_MN10200:
1201 case EM_CYGNUS_MN10200:
1202 case EM_MN10300:
1203 case EM_CYGNUS_MN10300:
5506d11a 1204 case EM_MOXIE:
e9f53129
AM
1205 case EM_MSP430:
1206 case EM_MSP430_OLD:
d031aafb 1207 case EM_MT:
35c08157 1208 case EM_NDS32:
64fd6348 1209 case EM_NIOS32:
73589c9d 1210 case EM_OR1K:
e9f53129
AM
1211 case EM_PPC64:
1212 case EM_PPC:
2b100bb5 1213 case EM_TI_PRU:
e23eba97 1214 case EM_RISCV:
99c513f6 1215 case EM_RL78:
c7927a3c 1216 case EM_RX:
e9f53129
AM
1217 case EM_S390:
1218 case EM_S390_OLD:
1219 case EM_SH:
1220 case EM_SPARC:
1221 case EM_SPARC32PLUS:
1222 case EM_SPARCV9:
1223 case EM_SPU:
40b36596 1224 case EM_TI_C6000:
aa137e4d
NC
1225 case EM_TILEGX:
1226 case EM_TILEPRO:
708e2187 1227 case EM_V800:
e9f53129
AM
1228 case EM_V850:
1229 case EM_CYGNUS_V850:
1230 case EM_VAX:
619ed720 1231 case EM_VISIUM:
e9f53129 1232 case EM_X86_64:
8a9036a4 1233 case EM_L1OM:
7a9068fe 1234 case EM_K1OM:
e9f53129
AM
1235 case EM_XSTORMY16:
1236 case EM_XTENSA:
1237 case EM_XTENSA_OLD:
7ba29e2a
NC
1238 case EM_MICROBLAZE:
1239 case EM_MICROBLAZE_OLD:
f96bd6c2 1240 case EM_WEBASSEMBLY:
015dc7e1 1241 return true;
103f02d3 1242
e9f53129
AM
1243 case EM_68HC05:
1244 case EM_68HC08:
1245 case EM_68HC11:
1246 case EM_68HC16:
1247 case EM_FX66:
1248 case EM_ME16:
d1133906 1249 case EM_MMA:
d1133906
NC
1250 case EM_NCPU:
1251 case EM_NDR1:
e9f53129 1252 case EM_PCP:
d1133906 1253 case EM_ST100:
e9f53129 1254 case EM_ST19:
d1133906 1255 case EM_ST7:
e9f53129
AM
1256 case EM_ST9PLUS:
1257 case EM_STARCORE:
d1133906 1258 case EM_SVX:
e9f53129 1259 case EM_TINYJ:
9c19a809
NC
1260 default:
1261 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1262 return false;
9c19a809
NC
1263 }
1264}
252b5132 1265
dda8d76d 1266/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1267 Returns TRUE upon success, FALSE otherwise. If successful then a
1268 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1269 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1270 responsibility to free the allocated buffer. */
1271
015dc7e1 1272static bool
26c527e6
AM
1273slurp_rela_relocs (Filedata *filedata,
1274 uint64_t rel_offset,
1275 uint64_t rel_size,
1276 Elf_Internal_Rela **relasp,
1277 uint64_t *nrelasp)
9c19a809 1278{
2cf0635d 1279 Elf_Internal_Rela * relas;
26c527e6 1280 uint64_t nrelas;
4d6ed7c8 1281 unsigned int i;
252b5132 1282
4d6ed7c8
NC
1283 if (is_32bit_elf)
1284 {
2cf0635d 1285 Elf32_External_Rela * erelas;
103f02d3 1286
dda8d76d 1287 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1288 rel_size, _("32-bit relocation data"));
a6e9f9df 1289 if (!erelas)
015dc7e1 1290 return false;
252b5132 1291
4d6ed7c8 1292 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1293
3f5e193b
NC
1294 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1295 sizeof (Elf_Internal_Rela));
103f02d3 1296
4d6ed7c8
NC
1297 if (relas == NULL)
1298 {
c256ffe7 1299 free (erelas);
591a748a 1300 error (_("out of memory parsing relocs\n"));
015dc7e1 1301 return false;
4d6ed7c8 1302 }
103f02d3 1303
4d6ed7c8
NC
1304 for (i = 0; i < nrelas; i++)
1305 {
1306 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1307 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1308 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1309 }
103f02d3 1310
4d6ed7c8
NC
1311 free (erelas);
1312 }
1313 else
1314 {
2cf0635d 1315 Elf64_External_Rela * erelas;
103f02d3 1316
dda8d76d 1317 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1318 rel_size, _("64-bit relocation data"));
a6e9f9df 1319 if (!erelas)
015dc7e1 1320 return false;
4d6ed7c8
NC
1321
1322 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1323
3f5e193b
NC
1324 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1325 sizeof (Elf_Internal_Rela));
103f02d3 1326
4d6ed7c8
NC
1327 if (relas == NULL)
1328 {
c256ffe7 1329 free (erelas);
591a748a 1330 error (_("out of memory parsing relocs\n"));
015dc7e1 1331 return false;
9c19a809 1332 }
4d6ed7c8
NC
1333
1334 for (i = 0; i < nrelas; i++)
9c19a809 1335 {
66543521
AM
1336 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1337 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1338 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1339
dda8d76d
NC
1340 if (filedata->file_header.e_machine == EM_MIPS
1341 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1342 {
1343 /* In little-endian objects, r_info isn't really a
1344 64-bit little-endian value: it has a 32-bit
1345 little-endian symbol index followed by four
1346 individual byte fields. Reorder INFO
1347 accordingly. */
625d49fc 1348 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1349 inf = (((inf & 0xffffffff) << 32)
1350 | ((inf >> 56) & 0xff)
1351 | ((inf >> 40) & 0xff00)
1352 | ((inf >> 24) & 0xff0000)
1353 | ((inf >> 8) & 0xff000000));
1354 relas[i].r_info = inf;
861fb55a 1355 }
4d6ed7c8 1356 }
103f02d3 1357
4d6ed7c8
NC
1358 free (erelas);
1359 }
32ec8896 1360
4d6ed7c8
NC
1361 *relasp = relas;
1362 *nrelasp = nrelas;
015dc7e1 1363 return true;
4d6ed7c8 1364}
103f02d3 1365
dda8d76d 1366/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1367 Returns TRUE upon success, FALSE otherwise. If successful then a
1368 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1369 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1370 responsibility to free the allocated buffer. */
1371
015dc7e1 1372static bool
26c527e6
AM
1373slurp_rel_relocs (Filedata *filedata,
1374 uint64_t rel_offset,
1375 uint64_t rel_size,
1376 Elf_Internal_Rela **relsp,
1377 uint64_t *nrelsp)
4d6ed7c8 1378{
2cf0635d 1379 Elf_Internal_Rela * rels;
26c527e6 1380 uint64_t nrels;
4d6ed7c8 1381 unsigned int i;
103f02d3 1382
4d6ed7c8
NC
1383 if (is_32bit_elf)
1384 {
2cf0635d 1385 Elf32_External_Rel * erels;
103f02d3 1386
dda8d76d 1387 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1388 rel_size, _("32-bit relocation data"));
a6e9f9df 1389 if (!erels)
015dc7e1 1390 return false;
103f02d3 1391
4d6ed7c8 1392 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1393
3f5e193b 1394 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1395
4d6ed7c8
NC
1396 if (rels == NULL)
1397 {
c256ffe7 1398 free (erels);
591a748a 1399 error (_("out of memory parsing relocs\n"));
015dc7e1 1400 return false;
4d6ed7c8
NC
1401 }
1402
1403 for (i = 0; i < nrels; i++)
1404 {
1405 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1406 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1407 rels[i].r_addend = 0;
9ea033b2 1408 }
4d6ed7c8
NC
1409
1410 free (erels);
9c19a809
NC
1411 }
1412 else
1413 {
2cf0635d 1414 Elf64_External_Rel * erels;
9ea033b2 1415
dda8d76d 1416 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1417 rel_size, _("64-bit relocation data"));
a6e9f9df 1418 if (!erels)
015dc7e1 1419 return false;
103f02d3 1420
4d6ed7c8 1421 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1422
3f5e193b 1423 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1424
4d6ed7c8 1425 if (rels == NULL)
9c19a809 1426 {
c256ffe7 1427 free (erels);
591a748a 1428 error (_("out of memory parsing relocs\n"));
015dc7e1 1429 return false;
4d6ed7c8 1430 }
103f02d3 1431
4d6ed7c8
NC
1432 for (i = 0; i < nrels; i++)
1433 {
66543521
AM
1434 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1435 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1436 rels[i].r_addend = 0;
861fb55a 1437
dda8d76d
NC
1438 if (filedata->file_header.e_machine == EM_MIPS
1439 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1440 {
1441 /* In little-endian objects, r_info isn't really a
1442 64-bit little-endian value: it has a 32-bit
1443 little-endian symbol index followed by four
1444 individual byte fields. Reorder INFO
1445 accordingly. */
625d49fc 1446 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1447 inf = (((inf & 0xffffffff) << 32)
1448 | ((inf >> 56) & 0xff)
1449 | ((inf >> 40) & 0xff00)
1450 | ((inf >> 24) & 0xff0000)
1451 | ((inf >> 8) & 0xff000000));
1452 rels[i].r_info = inf;
861fb55a 1453 }
4d6ed7c8 1454 }
103f02d3 1455
4d6ed7c8
NC
1456 free (erels);
1457 }
32ec8896 1458
4d6ed7c8
NC
1459 *relsp = rels;
1460 *nrelsp = nrels;
015dc7e1 1461 return true;
4d6ed7c8 1462}
103f02d3 1463
a7fd1186 1464static bool
26c527e6
AM
1465slurp_relr_relocs (Filedata *filedata,
1466 uint64_t relr_offset,
1467 uint64_t relr_size,
1468 uint64_t **relrsp,
1469 uint64_t *nrelrsp)
a7fd1186
FS
1470{
1471 void *relrs;
1472 size_t size = 0, nentries, i;
625d49fc 1473 uint64_t base = 0, addr, entry;
a7fd1186
FS
1474
1475 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1476 _("RELR relocation data"));
1477 if (!relrs)
1478 return false;
1479
1480 if (is_32bit_elf)
1481 nentries = relr_size / sizeof (Elf32_External_Relr);
1482 else
1483 nentries = relr_size / sizeof (Elf64_External_Relr);
1484 for (i = 0; i < nentries; i++)
1485 {
1486 if (is_32bit_elf)
1487 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1488 else
1489 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1490 if ((entry & 1) == 0)
1491 size++;
1492 else
1493 while ((entry >>= 1) != 0)
1494 if ((entry & 1) == 1)
1495 size++;
1496 }
1497
625d49fc 1498 *relrsp = malloc (size * sizeof (**relrsp));
a7fd1186
FS
1499 if (*relrsp == NULL)
1500 {
1501 free (relrs);
1502 error (_("out of memory parsing relocs\n"));
1503 return false;
1504 }
1505
1506 size = 0;
1507 for (i = 0; i < nentries; i++)
1508 {
625d49fc 1509 const uint64_t entry_bytes = is_32bit_elf ? 4 : 8;
a7fd1186
FS
1510
1511 if (is_32bit_elf)
1512 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1513 else
1514 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1515 if ((entry & 1) == 0)
1516 {
1517 (*relrsp)[size++] = entry;
1518 base = entry + entry_bytes;
1519 }
1520 else
1521 {
1522 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1523 if ((entry & 1) != 0)
1524 (*relrsp)[size++] = addr;
1525 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1526 }
1527 }
1528
1529 *nrelrsp = size;
1530 free (relrs);
1531 return true;
1532}
1533
aca88567
NC
1534/* Returns the reloc type extracted from the reloc info field. */
1535
1536static unsigned int
625d49fc 1537get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1538{
1539 if (is_32bit_elf)
1540 return ELF32_R_TYPE (reloc_info);
1541
dda8d76d 1542 switch (filedata->file_header.e_machine)
aca88567
NC
1543 {
1544 case EM_MIPS:
1545 /* Note: We assume that reloc_info has already been adjusted for us. */
1546 return ELF64_MIPS_R_TYPE (reloc_info);
1547
1548 case EM_SPARCV9:
1549 return ELF64_R_TYPE_ID (reloc_info);
1550
1551 default:
1552 return ELF64_R_TYPE (reloc_info);
1553 }
1554}
1555
1556/* Return the symbol index extracted from the reloc info field. */
1557
625d49fc
AM
1558static uint64_t
1559get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1560{
1561 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1562}
1563
015dc7e1 1564static inline bool
dda8d76d 1565uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1566{
1567 return
dda8d76d 1568 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1569 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1570 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1571 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1572 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1573}
1574
d3ba0551
AM
1575/* Display the contents of the relocation data found at the specified
1576 offset. */
ee42cf8c 1577
015dc7e1 1578static bool
26c527e6
AM
1579dump_relocations (Filedata *filedata,
1580 uint64_t rel_offset,
1581 uint64_t rel_size,
1582 Elf_Internal_Sym *symtab,
1583 uint64_t nsyms,
1584 char *strtab,
1585 uint64_t strtablen,
1586 relocation_type rel_type,
1587 bool is_dynsym)
1588{
1589 size_t i;
2cf0635d 1590 Elf_Internal_Rela * rels;
015dc7e1 1591 bool res = true;
103f02d3 1592
a7fd1186
FS
1593 if (rel_type == reltype_unknown)
1594 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1595
a7fd1186 1596 if (rel_type == reltype_rela)
4d6ed7c8 1597 {
dda8d76d 1598 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1599 return false;
4d6ed7c8 1600 }
a7fd1186 1601 else if (rel_type == reltype_rel)
4d6ed7c8 1602 {
dda8d76d 1603 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1604 return false;
252b5132 1605 }
a7fd1186
FS
1606 else if (rel_type == reltype_relr)
1607 {
625d49fc 1608 uint64_t * relrs;
a7fd1186 1609 const char *format
b8281767 1610 = is_32bit_elf ? "%08" PRIx64 "\n" : "%016" PRIx64 "\n";
a7fd1186
FS
1611
1612 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1613 &rel_size))
1614 return false;
1615
26c527e6
AM
1616 printf (ngettext (" %" PRIu64 " offset\n",
1617 " %" PRIu64 " offsets\n", rel_size),
b8281767 1618 rel_size);
a7fd1186 1619 for (i = 0; i < rel_size; i++)
625d49fc 1620 printf (format, relrs[i]);
a7fd1186
FS
1621 free (relrs);
1622 return true;
1623 }
252b5132 1624
410f7a12
L
1625 if (is_32bit_elf)
1626 {
a7fd1186 1627 if (rel_type == reltype_rela)
2c71103e
NC
1628 {
1629 if (do_wide)
1630 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1631 else
1632 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1633 }
410f7a12 1634 else
2c71103e
NC
1635 {
1636 if (do_wide)
1637 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1638 else
1639 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1640 }
410f7a12 1641 }
252b5132 1642 else
410f7a12 1643 {
a7fd1186 1644 if (rel_type == reltype_rela)
2c71103e
NC
1645 {
1646 if (do_wide)
8beeaeb7 1647 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1648 else
1649 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1650 }
410f7a12 1651 else
2c71103e
NC
1652 {
1653 if (do_wide)
8beeaeb7 1654 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1655 else
1656 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1657 }
410f7a12 1658 }
252b5132
RH
1659
1660 for (i = 0; i < rel_size; i++)
1661 {
2cf0635d 1662 const char * rtype;
625d49fc
AM
1663 uint64_t offset;
1664 uint64_t inf;
1665 uint64_t symtab_index;
1666 uint64_t type;
103f02d3 1667
b34976b6 1668 offset = rels[i].r_offset;
91d6fa6a 1669 inf = rels[i].r_info;
103f02d3 1670
dda8d76d 1671 type = get_reloc_type (filedata, inf);
91d6fa6a 1672 symtab_index = get_reloc_symindex (inf);
252b5132 1673
410f7a12
L
1674 if (is_32bit_elf)
1675 {
39dbeff8
AM
1676 printf ("%8.8lx %8.8lx ",
1677 (unsigned long) offset & 0xffffffff,
91d6fa6a 1678 (unsigned long) inf & 0xffffffff);
410f7a12
L
1679 }
1680 else
1681 {
39dbeff8 1682 printf (do_wide
b8281767
AM
1683 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1684 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1685 offset, inf);
410f7a12 1686 }
103f02d3 1687
dda8d76d 1688 switch (filedata->file_header.e_machine)
252b5132
RH
1689 {
1690 default:
1691 rtype = NULL;
1692 break;
1693
a06ea964
NC
1694 case EM_AARCH64:
1695 rtype = elf_aarch64_reloc_type (type);
1696 break;
1697
2b0337b0 1698 case EM_M32R:
252b5132 1699 case EM_CYGNUS_M32R:
9ea033b2 1700 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1701 break;
1702
1703 case EM_386:
22abe556 1704 case EM_IAMCU:
9ea033b2 1705 rtype = elf_i386_reloc_type (type);
252b5132
RH
1706 break;
1707
ba2685cc
AM
1708 case EM_68HC11:
1709 case EM_68HC12:
1710 rtype = elf_m68hc11_reloc_type (type);
1711 break;
75751cd9 1712
7b4ae824
JD
1713 case EM_S12Z:
1714 rtype = elf_s12z_reloc_type (type);
1715 break;
1716
252b5132 1717 case EM_68K:
9ea033b2 1718 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1719 break;
1720
f954747f
AM
1721 case EM_960:
1722 rtype = elf_i960_reloc_type (type);
1723 break;
1724
adde6300 1725 case EM_AVR:
2b0337b0 1726 case EM_AVR_OLD:
adde6300
AM
1727 rtype = elf_avr_reloc_type (type);
1728 break;
1729
9ea033b2
NC
1730 case EM_OLD_SPARCV9:
1731 case EM_SPARC32PLUS:
1732 case EM_SPARCV9:
252b5132 1733 case EM_SPARC:
9ea033b2 1734 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1735 break;
1736
e9f53129
AM
1737 case EM_SPU:
1738 rtype = elf_spu_reloc_type (type);
1739 break;
1740
708e2187
NC
1741 case EM_V800:
1742 rtype = v800_reloc_type (type);
1743 break;
2b0337b0 1744 case EM_V850:
252b5132 1745 case EM_CYGNUS_V850:
9ea033b2 1746 rtype = v850_reloc_type (type);
252b5132
RH
1747 break;
1748
2b0337b0 1749 case EM_D10V:
252b5132 1750 case EM_CYGNUS_D10V:
9ea033b2 1751 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1752 break;
1753
2b0337b0 1754 case EM_D30V:
252b5132 1755 case EM_CYGNUS_D30V:
9ea033b2 1756 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1757 break;
1758
d172d4ba
NC
1759 case EM_DLX:
1760 rtype = elf_dlx_reloc_type (type);
1761 break;
1762
252b5132 1763 case EM_SH:
9ea033b2 1764 rtype = elf_sh_reloc_type (type);
252b5132
RH
1765 break;
1766
2b0337b0 1767 case EM_MN10300:
252b5132 1768 case EM_CYGNUS_MN10300:
9ea033b2 1769 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1770 break;
1771
2b0337b0 1772 case EM_MN10200:
252b5132 1773 case EM_CYGNUS_MN10200:
9ea033b2 1774 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1775 break;
1776
2b0337b0 1777 case EM_FR30:
252b5132 1778 case EM_CYGNUS_FR30:
9ea033b2 1779 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1780 break;
1781
ba2685cc
AM
1782 case EM_CYGNUS_FRV:
1783 rtype = elf_frv_reloc_type (type);
1784 break;
5c70f934 1785
b8891f8d
AJ
1786 case EM_CSKY:
1787 rtype = elf_csky_reloc_type (type);
1788 break;
1789
3f8107ab
AM
1790 case EM_FT32:
1791 rtype = elf_ft32_reloc_type (type);
1792 break;
1793
252b5132 1794 case EM_MCORE:
9ea033b2 1795 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1796 break;
1797
3c3bdf30
NC
1798 case EM_MMIX:
1799 rtype = elf_mmix_reloc_type (type);
1800 break;
1801
5506d11a
AM
1802 case EM_MOXIE:
1803 rtype = elf_moxie_reloc_type (type);
1804 break;
1805
2469cfa2 1806 case EM_MSP430:
dda8d76d 1807 if (uses_msp430x_relocs (filedata))
13761a11
NC
1808 {
1809 rtype = elf_msp430x_reloc_type (type);
1810 break;
1811 }
1a0670f3 1812 /* Fall through. */
2469cfa2
NC
1813 case EM_MSP430_OLD:
1814 rtype = elf_msp430_reloc_type (type);
1815 break;
1816
35c08157
KLC
1817 case EM_NDS32:
1818 rtype = elf_nds32_reloc_type (type);
1819 break;
1820
252b5132 1821 case EM_PPC:
9ea033b2 1822 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1823 break;
1824
c833c019
AM
1825 case EM_PPC64:
1826 rtype = elf_ppc64_reloc_type (type);
1827 break;
1828
252b5132 1829 case EM_MIPS:
4fe85591 1830 case EM_MIPS_RS3_LE:
9ea033b2 1831 rtype = elf_mips_reloc_type (type);
252b5132
RH
1832 break;
1833
e23eba97
NC
1834 case EM_RISCV:
1835 rtype = elf_riscv_reloc_type (type);
1836 break;
1837
252b5132 1838 case EM_ALPHA:
9ea033b2 1839 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1840 break;
1841
1842 case EM_ARM:
9ea033b2 1843 rtype = elf_arm_reloc_type (type);
252b5132
RH
1844 break;
1845
584da044 1846 case EM_ARC:
886a2506
NC
1847 case EM_ARC_COMPACT:
1848 case EM_ARC_COMPACT2:
b5c37946
SJ
1849 case EM_ARC_COMPACT3:
1850 case EM_ARC_COMPACT3_64:
9ea033b2 1851 rtype = elf_arc_reloc_type (type);
252b5132
RH
1852 break;
1853
1854 case EM_PARISC:
69e617ca 1855 rtype = elf_hppa_reloc_type (type);
252b5132 1856 break;
7d466069 1857
b8720f9d
JL
1858 case EM_H8_300:
1859 case EM_H8_300H:
1860 case EM_H8S:
1861 rtype = elf_h8_reloc_type (type);
1862 break;
1863
73589c9d
CS
1864 case EM_OR1K:
1865 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1866 break;
1867
7d466069 1868 case EM_PJ:
2b0337b0 1869 case EM_PJ_OLD:
7d466069
ILT
1870 rtype = elf_pj_reloc_type (type);
1871 break;
800eeca4
JW
1872 case EM_IA_64:
1873 rtype = elf_ia64_reloc_type (type);
1874 break;
1b61cf92 1875
6e712424
PI
1876 case EM_KVX:
1877 rtype = elf_kvx_reloc_type (type);
1878 break;
1879
1b61cf92
HPN
1880 case EM_CRIS:
1881 rtype = elf_cris_reloc_type (type);
1882 break;
535c37ff 1883
f954747f
AM
1884 case EM_860:
1885 rtype = elf_i860_reloc_type (type);
1886 break;
1887
bcedfee6 1888 case EM_X86_64:
8a9036a4 1889 case EM_L1OM:
7a9068fe 1890 case EM_K1OM:
bcedfee6
NC
1891 rtype = elf_x86_64_reloc_type (type);
1892 break;
a85d7ed0 1893
f954747f
AM
1894 case EM_S370:
1895 rtype = i370_reloc_type (type);
1896 break;
1897
53c7db4b
KH
1898 case EM_S390_OLD:
1899 case EM_S390:
1900 rtype = elf_s390_reloc_type (type);
1901 break;
93fbbb04 1902
1c0d3aa6
NC
1903 case EM_SCORE:
1904 rtype = elf_score_reloc_type (type);
1905 break;
1906
93fbbb04
GK
1907 case EM_XSTORMY16:
1908 rtype = elf_xstormy16_reloc_type (type);
1909 break;
179d3252 1910
1fe1f39c
NC
1911 case EM_CRX:
1912 rtype = elf_crx_reloc_type (type);
1913 break;
1914
179d3252
JT
1915 case EM_VAX:
1916 rtype = elf_vax_reloc_type (type);
1917 break;
1e4cf259 1918
619ed720
EB
1919 case EM_VISIUM:
1920 rtype = elf_visium_reloc_type (type);
1921 break;
1922
aca4efc7
JM
1923 case EM_BPF:
1924 rtype = elf_bpf_reloc_type (type);
1925 break;
1926
cfb8c092
NC
1927 case EM_ADAPTEVA_EPIPHANY:
1928 rtype = elf_epiphany_reloc_type (type);
1929 break;
1930
1e4cf259
NC
1931 case EM_IP2K:
1932 case EM_IP2K_OLD:
1933 rtype = elf_ip2k_reloc_type (type);
1934 break;
3b36097d
SC
1935
1936 case EM_IQ2000:
1937 rtype = elf_iq2000_reloc_type (type);
1938 break;
88da6820
NC
1939
1940 case EM_XTENSA_OLD:
1941 case EM_XTENSA:
1942 rtype = elf_xtensa_reloc_type (type);
1943 break;
a34e3ecb 1944
84e94c90
NC
1945 case EM_LATTICEMICO32:
1946 rtype = elf_lm32_reloc_type (type);
1947 break;
1948
ff7eeb89 1949 case EM_M32C_OLD:
49f58d10
JB
1950 case EM_M32C:
1951 rtype = elf_m32c_reloc_type (type);
1952 break;
1953
d031aafb
NS
1954 case EM_MT:
1955 rtype = elf_mt_reloc_type (type);
a34e3ecb 1956 break;
1d65ded4
CM
1957
1958 case EM_BLACKFIN:
1959 rtype = elf_bfin_reloc_type (type);
1960 break;
15ab5209
DB
1961
1962 case EM_CYGNUS_MEP:
1963 rtype = elf_mep_reloc_type (type);
1964 break;
60bca95a
NC
1965
1966 case EM_CR16:
1967 rtype = elf_cr16_reloc_type (type);
1968 break;
dd24e3da 1969
7ba29e2a
NC
1970 case EM_MICROBLAZE:
1971 case EM_MICROBLAZE_OLD:
1972 rtype = elf_microblaze_reloc_type (type);
1973 break;
c7927a3c 1974
99c513f6
DD
1975 case EM_RL78:
1976 rtype = elf_rl78_reloc_type (type);
1977 break;
1978
c7927a3c
NC
1979 case EM_RX:
1980 rtype = elf_rx_reloc_type (type);
1981 break;
c29aca4a 1982
a3c62988
NC
1983 case EM_METAG:
1984 rtype = elf_metag_reloc_type (type);
1985 break;
1986
40b36596
JM
1987 case EM_TI_C6000:
1988 rtype = elf_tic6x_reloc_type (type);
1989 break;
aa137e4d
NC
1990
1991 case EM_TILEGX:
1992 rtype = elf_tilegx_reloc_type (type);
1993 break;
1994
1995 case EM_TILEPRO:
1996 rtype = elf_tilepro_reloc_type (type);
1997 break;
f6c1a2d5 1998
f96bd6c2
PC
1999 case EM_WEBASSEMBLY:
2000 rtype = elf_wasm32_reloc_type (type);
2001 break;
2002
f6c1a2d5
NC
2003 case EM_XGATE:
2004 rtype = elf_xgate_reloc_type (type);
2005 break;
36591ba1
SL
2006
2007 case EM_ALTERA_NIOS2:
2008 rtype = elf_nios2_reloc_type (type);
2009 break;
2b100bb5
DD
2010
2011 case EM_TI_PRU:
2012 rtype = elf_pru_reloc_type (type);
2013 break;
fe944acf
FT
2014
2015 case EM_NFP:
2016 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2017 rtype = elf_nfp3200_reloc_type (type);
2018 else
2019 rtype = elf_nfp_reloc_type (type);
2020 break;
6655dba2
SB
2021
2022 case EM_Z80:
2023 rtype = elf_z80_reloc_type (type);
2024 break;
e9a0721f 2025
2026 case EM_LOONGARCH:
2027 rtype = elf_loongarch_reloc_type (type);
2028 break;
2029
0c857ef4
SM
2030 case EM_AMDGPU:
2031 rtype = elf_amdgpu_reloc_type (type);
2032 break;
252b5132
RH
2033 }
2034
2035 if (rtype == NULL)
39dbeff8 2036 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 2037 else
5c144731 2038 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 2039
dda8d76d 2040 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 2041 && rtype != NULL
7ace3541 2042 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 2043 && rel_type == reltype_rela)
7ace3541
RH
2044 {
2045 switch (rels[i].r_addend)
2046 {
2047 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2048 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2049 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2050 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2051 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2052 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2053 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2054 default: rtype = NULL;
2055 }
32ec8896 2056
7ace3541
RH
2057 if (rtype)
2058 printf (" (%s)", rtype);
2059 else
2060 {
2061 putchar (' ');
26c527e6
AM
2062 printf (_("<unknown addend: %" PRIx64 ">"),
2063 rels[i].r_addend);
015dc7e1 2064 res = false;
7ace3541
RH
2065 }
2066 }
2067 else if (symtab_index)
252b5132 2068 {
af3fc3bc 2069 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 2070 {
27a45f42
AS
2071 error (_(" bad symbol index: %08lx in reloc\n"),
2072 (unsigned long) symtab_index);
015dc7e1 2073 res = false;
32ec8896 2074 }
af3fc3bc 2075 else
19936277 2076 {
2cf0635d 2077 Elf_Internal_Sym * psym;
bb4d2ac2
L
2078 const char * version_string;
2079 enum versioned_symbol_info sym_info;
2080 unsigned short vna_other;
19936277 2081
af3fc3bc 2082 psym = symtab + symtab_index;
103f02d3 2083
bb4d2ac2 2084 version_string
dda8d76d 2085 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
2086 strtab, strtablen,
2087 symtab_index,
2088 psym,
2089 &sym_info,
2090 &vna_other);
2091
af3fc3bc 2092 printf (" ");
171191ba 2093
d8045f23
NC
2094 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2095 {
2096 const char * name;
2097 unsigned int len;
2098 unsigned int width = is_32bit_elf ? 8 : 14;
2099
2100 /* Relocations against GNU_IFUNC symbols do not use the value
2101 of the symbol as the address to relocate against. Instead
2102 they invoke the function named by the symbol and use its
2103 result as the address for relocation.
2104
2105 To indicate this to the user, do not display the value of
2106 the symbol in the "Symbols's Value" field. Instead show
2107 its name followed by () as a hint that the symbol is
2108 invoked. */
2109
2110 if (strtab == NULL
2111 || psym->st_name == 0
2112 || psym->st_name >= strtablen)
2113 name = "??";
2114 else
2115 name = strtab + psym->st_name;
2116
b6ac461a 2117 len = print_symbol_name (width, name);
bb4d2ac2
L
2118 if (version_string)
2119 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2120 version_string);
d8045f23
NC
2121 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2122 }
2123 else
2124 {
2125 print_vma (psym->st_value, LONG_HEX);
171191ba 2126
d8045f23
NC
2127 printf (is_32bit_elf ? " " : " ");
2128 }
103f02d3 2129
af3fc3bc 2130 if (psym->st_name == 0)
f1ef08cb 2131 {
2cf0635d 2132 const char * sec_name = "<null>";
f1ef08cb
AM
2133
2134 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
b6ac461a
NC
2135 sec_name = printable_section_name_from_index
2136 (filedata, psym->st_shndx, NULL);
2137
2138 print_symbol_name (22, sec_name);
f1ef08cb 2139 }
af3fc3bc 2140 else if (strtab == NULL)
d79b3d50 2141 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2142 else if (psym->st_name >= strtablen)
32ec8896 2143 {
27a45f42
AS
2144 error (_("<corrupt string table index: %3ld>\n"),
2145 psym->st_name);
015dc7e1 2146 res = false;
32ec8896 2147 }
af3fc3bc 2148 else
bb4d2ac2 2149 {
b6ac461a 2150 print_symbol_name (22, strtab + psym->st_name);
bb4d2ac2
L
2151 if (version_string)
2152 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2153 version_string);
2154 }
103f02d3 2155
a7fd1186 2156 if (rel_type == reltype_rela)
171191ba 2157 {
625d49fc 2158 uint64_t off = rels[i].r_addend;
171191ba 2159
625d49fc
AM
2160 if ((int64_t) off < 0)
2161 printf (" - %" PRIx64, -off);
171191ba 2162 else
625d49fc 2163 printf (" + %" PRIx64, off);
171191ba 2164 }
19936277 2165 }
252b5132 2166 }
a7fd1186 2167 else if (rel_type == reltype_rela)
f7a99963 2168 {
625d49fc 2169 uint64_t off = rels[i].r_addend;
e04d7088
L
2170
2171 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2172 if ((int64_t) off < 0)
2173 printf ("-%" PRIx64, -off);
e04d7088 2174 else
625d49fc 2175 printf ("%" PRIx64, off);
f7a99963 2176 }
252b5132 2177
dda8d76d 2178 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2179 && rtype != NULL
2180 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2181 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2182
252b5132 2183 putchar ('\n');
2c71103e 2184
dda8d76d 2185 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2186 {
625d49fc
AM
2187 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2188 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2189 const char * rtype2 = elf_mips_reloc_type (type2);
2190 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2191
2c71103e
NC
2192 printf (" Type2: ");
2193
2194 if (rtype2 == NULL)
39dbeff8
AM
2195 printf (_("unrecognized: %-7lx"),
2196 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2197 else
2198 printf ("%-17.17s", rtype2);
2199
18bd398b 2200 printf ("\n Type3: ");
2c71103e
NC
2201
2202 if (rtype3 == NULL)
39dbeff8
AM
2203 printf (_("unrecognized: %-7lx"),
2204 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2205 else
2206 printf ("%-17.17s", rtype3);
2207
53c7db4b 2208 putchar ('\n');
2c71103e 2209 }
252b5132
RH
2210 }
2211
c8286bd1 2212 free (rels);
32ec8896
NC
2213
2214 return res;
252b5132
RH
2215}
2216
37c18eed
SD
2217static const char *
2218get_aarch64_dynamic_type (unsigned long type)
2219{
2220 switch (type)
2221 {
2222 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2223 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2224 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2225 default:
2226 return NULL;
2227 }
2228}
2229
252b5132 2230static const char *
d3ba0551 2231get_mips_dynamic_type (unsigned long type)
252b5132
RH
2232{
2233 switch (type)
2234 {
2235 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2236 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2237 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2238 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2239 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2240 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2241 case DT_MIPS_MSYM: return "MIPS_MSYM";
2242 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2243 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2244 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2245 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2246 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2247 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2248 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2249 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2250 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2251 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2252 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2253 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2254 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2255 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2256 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2257 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2258 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2259 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2260 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2261 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2262 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2263 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2264 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2265 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2266 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2267 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2268 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2269 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2270 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2271 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2272 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2273 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2274 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2275 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2276 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2277 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2278 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2279 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2280 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2281 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2282 default:
2283 return NULL;
2284 }
2285}
2286
9a097730 2287static const char *
d3ba0551 2288get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2289{
2290 switch (type)
2291 {
2292 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2293 default:
2294 return NULL;
2295 }
103f02d3
UD
2296}
2297
7490d522
AM
2298static const char *
2299get_ppc_dynamic_type (unsigned long type)
2300{
2301 switch (type)
2302 {
a7f2871e 2303 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2304 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2305 default:
2306 return NULL;
2307 }
2308}
2309
f1cb7e17 2310static const char *
d3ba0551 2311get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2312{
2313 switch (type)
2314 {
a7f2871e
AM
2315 case DT_PPC64_GLINK: return "PPC64_GLINK";
2316 case DT_PPC64_OPD: return "PPC64_OPD";
2317 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2318 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2319 default:
2320 return NULL;
2321 }
2322}
2323
103f02d3 2324static const char *
d3ba0551 2325get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2326{
2327 switch (type)
2328 {
2329 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2330 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2331 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2332 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2333 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2334 case DT_HP_PREINIT: return "HP_PREINIT";
2335 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2336 case DT_HP_NEEDED: return "HP_NEEDED";
2337 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2338 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2339 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2340 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2341 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2342 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2343 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2344 case DT_HP_FILTERED: return "HP_FILTERED";
2345 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2346 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2347 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2348 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2349 case DT_PLT: return "PLT";
2350 case DT_PLT_SIZE: return "PLT_SIZE";
2351 case DT_DLT: return "DLT";
2352 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2353 default:
2354 return NULL;
2355 }
2356}
9a097730 2357
ecc51f48 2358static const char *
d3ba0551 2359get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2360{
2361 switch (type)
2362 {
148b93f2
NC
2363 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2364 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2365 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2366 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2367 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2368 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2369 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2370 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2371 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2372 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2373 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2374 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2375 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2376 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2377 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2378 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2379 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2380 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2381 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2382 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2383 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2384 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2385 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2386 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2387 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2388 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2389 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2390 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2391 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2392 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2393 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2394 default:
2395 return NULL;
2396 }
2397}
2398
fd85a6a1
NC
2399static const char *
2400get_solaris_section_type (unsigned long type)
2401{
2402 switch (type)
2403 {
2404 case 0x6fffffee: return "SUNW_ancillary";
2405 case 0x6fffffef: return "SUNW_capchain";
2406 case 0x6ffffff0: return "SUNW_capinfo";
2407 case 0x6ffffff1: return "SUNW_symsort";
2408 case 0x6ffffff2: return "SUNW_tlssort";
2409 case 0x6ffffff3: return "SUNW_LDYNSYM";
2410 case 0x6ffffff4: return "SUNW_dof";
2411 case 0x6ffffff5: return "SUNW_cap";
2412 case 0x6ffffff6: return "SUNW_SIGNATURE";
2413 case 0x6ffffff7: return "SUNW_ANNOTATE";
2414 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2415 case 0x6ffffff9: return "SUNW_DEBUG";
2416 case 0x6ffffffa: return "SUNW_move";
2417 case 0x6ffffffb: return "SUNW_COMDAT";
2418 case 0x6ffffffc: return "SUNW_syminfo";
2419 case 0x6ffffffd: return "SUNW_verdef";
2420 case 0x6ffffffe: return "SUNW_verneed";
2421 case 0x6fffffff: return "SUNW_versym";
2422 case 0x70000000: return "SPARC_GOTDATA";
2423 default: return NULL;
2424 }
2425}
2426
fabcb361
RH
2427static const char *
2428get_alpha_dynamic_type (unsigned long type)
2429{
2430 switch (type)
2431 {
2432 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2433 default: return NULL;
fabcb361
RH
2434 }
2435}
2436
1c0d3aa6
NC
2437static const char *
2438get_score_dynamic_type (unsigned long type)
2439{
2440 switch (type)
2441 {
2442 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2443 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2444 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2445 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2446 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2447 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2448 default: return NULL;
1c0d3aa6
NC
2449 }
2450}
2451
40b36596
JM
2452static const char *
2453get_tic6x_dynamic_type (unsigned long type)
2454{
2455 switch (type)
2456 {
2457 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2458 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2459 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2460 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2461 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2462 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2463 default: return NULL;
40b36596
JM
2464 }
2465}
1c0d3aa6 2466
36591ba1
SL
2467static const char *
2468get_nios2_dynamic_type (unsigned long type)
2469{
2470 switch (type)
2471 {
2472 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2473 default: return NULL;
36591ba1
SL
2474 }
2475}
2476
fd85a6a1
NC
2477static const char *
2478get_solaris_dynamic_type (unsigned long type)
2479{
2480 switch (type)
2481 {
2482 case 0x6000000d: return "SUNW_AUXILIARY";
2483 case 0x6000000e: return "SUNW_RTLDINF";
2484 case 0x6000000f: return "SUNW_FILTER";
2485 case 0x60000010: return "SUNW_CAP";
2486 case 0x60000011: return "SUNW_SYMTAB";
2487 case 0x60000012: return "SUNW_SYMSZ";
2488 case 0x60000013: return "SUNW_SORTENT";
2489 case 0x60000014: return "SUNW_SYMSORT";
2490 case 0x60000015: return "SUNW_SYMSORTSZ";
2491 case 0x60000016: return "SUNW_TLSSORT";
2492 case 0x60000017: return "SUNW_TLSSORTSZ";
2493 case 0x60000018: return "SUNW_CAPINFO";
2494 case 0x60000019: return "SUNW_STRPAD";
2495 case 0x6000001a: return "SUNW_CAPCHAIN";
2496 case 0x6000001b: return "SUNW_LDMACH";
2497 case 0x6000001d: return "SUNW_CAPCHAINENT";
2498 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2499 case 0x60000021: return "SUNW_PARENT";
2500 case 0x60000023: return "SUNW_ASLR";
2501 case 0x60000025: return "SUNW_RELAX";
2502 case 0x60000029: return "SUNW_NXHEAP";
2503 case 0x6000002b: return "SUNW_NXSTACK";
2504
2505 case 0x70000001: return "SPARC_REGISTER";
2506 case 0x7ffffffd: return "AUXILIARY";
2507 case 0x7ffffffe: return "USED";
2508 case 0x7fffffff: return "FILTER";
2509
15f205b1 2510 default: return NULL;
fd85a6a1
NC
2511 }
2512}
2513
8155b853
NC
2514static const char *
2515get_riscv_dynamic_type (unsigned long type)
2516{
2517 switch (type)
2518 {
2519 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2520 default:
2521 return NULL;
2522 }
2523}
2524
832ca732
L
2525static const char *
2526get_x86_64_dynamic_type (unsigned long type)
2527{
2528 switch (type)
2529 {
2530 case DT_X86_64_PLT:
2531 return "DT_X86_64_PLT";
2532 case DT_X86_64_PLTSZ:
2533 return "DT_X86_64_PLTSZ";
2534 case DT_X86_64_PLTENT:
2535 return "DT_X86_64_PLTENT";
2536 default:
2537 return NULL;
2538 }
2539}
2540
252b5132 2541static const char *
dda8d76d 2542get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2543{
e9e44622 2544 static char buff[64];
252b5132
RH
2545
2546 switch (type)
2547 {
2548 case DT_NULL: return "NULL";
2549 case DT_NEEDED: return "NEEDED";
2550 case DT_PLTRELSZ: return "PLTRELSZ";
2551 case DT_PLTGOT: return "PLTGOT";
2552 case DT_HASH: return "HASH";
2553 case DT_STRTAB: return "STRTAB";
2554 case DT_SYMTAB: return "SYMTAB";
2555 case DT_RELA: return "RELA";
2556 case DT_RELASZ: return "RELASZ";
2557 case DT_RELAENT: return "RELAENT";
2558 case DT_STRSZ: return "STRSZ";
2559 case DT_SYMENT: return "SYMENT";
2560 case DT_INIT: return "INIT";
2561 case DT_FINI: return "FINI";
2562 case DT_SONAME: return "SONAME";
2563 case DT_RPATH: return "RPATH";
2564 case DT_SYMBOLIC: return "SYMBOLIC";
2565 case DT_REL: return "REL";
2566 case DT_RELSZ: return "RELSZ";
2567 case DT_RELENT: return "RELENT";
dd207c13
FS
2568 case DT_RELR: return "RELR";
2569 case DT_RELRSZ: return "RELRSZ";
2570 case DT_RELRENT: return "RELRENT";
252b5132
RH
2571 case DT_PLTREL: return "PLTREL";
2572 case DT_DEBUG: return "DEBUG";
2573 case DT_TEXTREL: return "TEXTREL";
2574 case DT_JMPREL: return "JMPREL";
2575 case DT_BIND_NOW: return "BIND_NOW";
2576 case DT_INIT_ARRAY: return "INIT_ARRAY";
2577 case DT_FINI_ARRAY: return "FINI_ARRAY";
2578 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2579 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2580 case DT_RUNPATH: return "RUNPATH";
2581 case DT_FLAGS: return "FLAGS";
2d0e6f43 2582
d1133906
NC
2583 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2584 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2585 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2586
05107a46 2587 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2588 case DT_PLTPADSZ: return "PLTPADSZ";
2589 case DT_MOVEENT: return "MOVEENT";
2590 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2591 case DT_FEATURE: return "FEATURE";
252b5132
RH
2592 case DT_POSFLAG_1: return "POSFLAG_1";
2593 case DT_SYMINSZ: return "SYMINSZ";
2594 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2595
252b5132 2596 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2597 case DT_CONFIG: return "CONFIG";
2598 case DT_DEPAUDIT: return "DEPAUDIT";
2599 case DT_AUDIT: return "AUDIT";
2600 case DT_PLTPAD: return "PLTPAD";
2601 case DT_MOVETAB: return "MOVETAB";
252b5132 2602 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2603
252b5132 2604 case DT_VERSYM: return "VERSYM";
103f02d3 2605
67a4f2b7
AO
2606 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2607 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2608 case DT_RELACOUNT: return "RELACOUNT";
2609 case DT_RELCOUNT: return "RELCOUNT";
2610 case DT_FLAGS_1: return "FLAGS_1";
2611 case DT_VERDEF: return "VERDEF";
2612 case DT_VERDEFNUM: return "VERDEFNUM";
2613 case DT_VERNEED: return "VERNEED";
2614 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2615
019148e4 2616 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2617 case DT_USED: return "USED";
2618 case DT_FILTER: return "FILTER";
103f02d3 2619
047b2264
JJ
2620 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2621 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2622 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2623 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2624 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2625 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2626 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2627
252b5132
RH
2628 default:
2629 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2630 {
2cf0635d 2631 const char * result;
103f02d3 2632
dda8d76d 2633 switch (filedata->file_header.e_machine)
252b5132 2634 {
37c18eed
SD
2635 case EM_AARCH64:
2636 result = get_aarch64_dynamic_type (type);
2637 break;
252b5132 2638 case EM_MIPS:
4fe85591 2639 case EM_MIPS_RS3_LE:
252b5132
RH
2640 result = get_mips_dynamic_type (type);
2641 break;
9a097730
RH
2642 case EM_SPARCV9:
2643 result = get_sparc64_dynamic_type (type);
2644 break;
7490d522
AM
2645 case EM_PPC:
2646 result = get_ppc_dynamic_type (type);
2647 break;
f1cb7e17
AM
2648 case EM_PPC64:
2649 result = get_ppc64_dynamic_type (type);
2650 break;
ecc51f48
NC
2651 case EM_IA_64:
2652 result = get_ia64_dynamic_type (type);
2653 break;
fabcb361
RH
2654 case EM_ALPHA:
2655 result = get_alpha_dynamic_type (type);
2656 break;
1c0d3aa6
NC
2657 case EM_SCORE:
2658 result = get_score_dynamic_type (type);
2659 break;
40b36596
JM
2660 case EM_TI_C6000:
2661 result = get_tic6x_dynamic_type (type);
2662 break;
36591ba1
SL
2663 case EM_ALTERA_NIOS2:
2664 result = get_nios2_dynamic_type (type);
2665 break;
8155b853
NC
2666 case EM_RISCV:
2667 result = get_riscv_dynamic_type (type);
2668 break;
832ca732
L
2669 case EM_X86_64:
2670 result = get_x86_64_dynamic_type (type);
2671 break;
252b5132 2672 default:
dda8d76d 2673 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2674 result = get_solaris_dynamic_type (type);
2675 else
2676 result = NULL;
252b5132
RH
2677 break;
2678 }
2679
2680 if (result != NULL)
2681 return result;
2682
e9e44622 2683 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2684 }
eec8f817 2685 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2686 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2687 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2688 {
2cf0635d 2689 const char * result;
103f02d3 2690
dda8d76d 2691 switch (filedata->file_header.e_machine)
103f02d3
UD
2692 {
2693 case EM_PARISC:
2694 result = get_parisc_dynamic_type (type);
2695 break;
148b93f2
NC
2696 case EM_IA_64:
2697 result = get_ia64_dynamic_type (type);
2698 break;
103f02d3 2699 default:
dda8d76d 2700 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2701 result = get_solaris_dynamic_type (type);
2702 else
2703 result = NULL;
103f02d3
UD
2704 break;
2705 }
2706
2707 if (result != NULL)
2708 return result;
2709
e9e44622
JJ
2710 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2711 type);
103f02d3 2712 }
252b5132 2713 else
e9e44622 2714 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2715
252b5132
RH
2716 return buff;
2717 }
2718}
2719
93df3340
AM
2720static bool get_program_headers (Filedata *);
2721static bool get_dynamic_section (Filedata *);
2722
2723static void
2724locate_dynamic_section (Filedata *filedata)
2725{
26c527e6 2726 uint64_t dynamic_addr = 0;
be7d229a 2727 uint64_t dynamic_size = 0;
93df3340
AM
2728
2729 if (filedata->file_header.e_phnum != 0
2730 && get_program_headers (filedata))
2731 {
2732 Elf_Internal_Phdr *segment;
2733 unsigned int i;
2734
2735 for (i = 0, segment = filedata->program_headers;
2736 i < filedata->file_header.e_phnum;
2737 i++, segment++)
2738 {
2739 if (segment->p_type == PT_DYNAMIC)
2740 {
2741 dynamic_addr = segment->p_offset;
2742 dynamic_size = segment->p_filesz;
2743
2744 if (filedata->section_headers != NULL)
2745 {
2746 Elf_Internal_Shdr *sec;
2747
2748 sec = find_section (filedata, ".dynamic");
2749 if (sec != NULL)
2750 {
2751 if (sec->sh_size == 0
2752 || sec->sh_type == SHT_NOBITS)
2753 {
2754 dynamic_addr = 0;
2755 dynamic_size = 0;
2756 }
2757 else
2758 {
2759 dynamic_addr = sec->sh_offset;
2760 dynamic_size = sec->sh_size;
2761 }
2762 }
2763 }
2764
2765 if (dynamic_addr > filedata->file_size
2766 || (dynamic_size > filedata->file_size - dynamic_addr))
2767 {
2768 dynamic_addr = 0;
2769 dynamic_size = 0;
2770 }
2771 break;
2772 }
2773 }
2774 }
2775 filedata->dynamic_addr = dynamic_addr;
2776 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2777}
2778
2779static bool
2780is_pie (Filedata *filedata)
2781{
2782 Elf_Internal_Dyn *entry;
2783
2784 if (filedata->dynamic_size == 0)
2785 locate_dynamic_section (filedata);
2786 if (filedata->dynamic_size <= 1)
2787 return false;
2788
2789 if (!get_dynamic_section (filedata))
2790 return false;
2791
2792 for (entry = filedata->dynamic_section;
2793 entry < filedata->dynamic_section + filedata->dynamic_nent;
2794 entry++)
2795 {
2796 if (entry->d_tag == DT_FLAGS_1)
2797 {
2798 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2799 return true;
2800 break;
2801 }
2802 }
2803 return false;
2804}
2805
252b5132 2806static char *
93df3340 2807get_file_type (Filedata *filedata)
252b5132 2808{
93df3340 2809 unsigned e_type = filedata->file_header.e_type;
89246a0e 2810 static char buff[64];
252b5132
RH
2811
2812 switch (e_type)
2813 {
32ec8896
NC
2814 case ET_NONE: return _("NONE (None)");
2815 case ET_REL: return _("REL (Relocatable file)");
2816 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2817 case ET_DYN:
2818 if (is_pie (filedata))
2819 return _("DYN (Position-Independent Executable file)");
2820 else
2821 return _("DYN (Shared object file)");
32ec8896 2822 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2823
2824 default:
2825 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2826 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2827 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2828 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2829 else
e9e44622 2830 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2831 return buff;
2832 }
2833}
2834
2835static char *
d3ba0551 2836get_machine_name (unsigned e_machine)
252b5132 2837{
b34976b6 2838 static char buff[64]; /* XXX */
252b5132
RH
2839
2840 switch (e_machine)
2841 {
55e22ca8
NC
2842 /* Please keep this switch table sorted by increasing EM_ value. */
2843 /* 0 */
c45021f2
NC
2844 case EM_NONE: return _("None");
2845 case EM_M32: return "WE32100";
2846 case EM_SPARC: return "Sparc";
2847 case EM_386: return "Intel 80386";
2848 case EM_68K: return "MC68000";
2849 case EM_88K: return "MC88000";
22abe556 2850 case EM_IAMCU: return "Intel MCU";
fb70ec17 2851 case EM_860: return "Intel 80860";
c45021f2
NC
2852 case EM_MIPS: return "MIPS R3000";
2853 case EM_S370: return "IBM System/370";
55e22ca8 2854 /* 10 */
7036c0e1 2855 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2856 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2857 case EM_PARISC: return "HPPA";
55e22ca8 2858 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2859 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2860 case EM_960: return "Intel 80960";
c45021f2 2861 case EM_PPC: return "PowerPC";
55e22ca8 2862 /* 20 */
285d1771 2863 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2864 case EM_S390_OLD:
2865 case EM_S390: return "IBM S/390";
2866 case EM_SPU: return "SPU";
2867 /* 30 */
2868 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2869 case EM_FR20: return "Fujitsu FR20";
2870 case EM_RH32: return "TRW RH32";
b34976b6 2871 case EM_MCORE: return "MCORE";
55e22ca8 2872 /* 40 */
7036c0e1
AJ
2873 case EM_ARM: return "ARM";
2874 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2875 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2876 case EM_SPARCV9: return "Sparc v9";
2877 case EM_TRICORE: return "Siemens Tricore";
584da044 2878 case EM_ARC: return "ARC";
c2dcd04e
NC
2879 case EM_H8_300: return "Renesas H8/300";
2880 case EM_H8_300H: return "Renesas H8/300H";
2881 case EM_H8S: return "Renesas H8S";
2882 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2883 /* 50 */
30800947 2884 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2885 case EM_MIPS_X: return "Stanford MIPS-X";
2886 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2887 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2888 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2889 case EM_PCP: return "Siemens PCP";
2890 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 2891 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
2892 case EM_STARCORE: return "Motorola Star*Core processor";
2893 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2894 /* 60 */
7036c0e1
AJ
2895 case EM_ST100: return "STMicroelectronics ST100 processor";
2896 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2897 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2898 case EM_PDSP: return "Sony DSP processor";
2899 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2900 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2901 case EM_FX66: return "Siemens FX66 microcontroller";
2902 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2903 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2904 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2905 /* 70 */
7036c0e1
AJ
2906 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2907 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2908 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2909 case EM_SVX: return "Silicon Graphics SVx";
2910 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2911 case EM_VAX: return "Digital VAX";
1b61cf92 2912 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2913 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2914 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2915 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2916 /* 80 */
b34976b6 2917 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2918 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2919 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2920 case EM_AVR_OLD:
2921 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2922 case EM_CYGNUS_FR30:
2923 case EM_FR30: return "Fujitsu FR30";
2924 case EM_CYGNUS_D10V:
2925 case EM_D10V: return "d10v";
2926 case EM_CYGNUS_D30V:
2927 case EM_D30V: return "d30v";
2928 case EM_CYGNUS_V850:
2929 case EM_V850: return "Renesas V850";
2930 case EM_CYGNUS_M32R:
2931 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2932 case EM_CYGNUS_MN10300:
2933 case EM_MN10300: return "mn10300";
2934 /* 90 */
2935 case EM_CYGNUS_MN10200:
2936 case EM_MN10200: return "mn10200";
2937 case EM_PJ: return "picoJava";
73589c9d 2938 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2939 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2940 case EM_XTENSA_OLD:
2941 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2942 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2943 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2944 case EM_NS32K: return "National Semiconductor 32000 series";
2945 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2946 case EM_SNP1K: return "Trebia SNP 1000 processor";
2947 /* 100 */
9abca702 2948 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2949 case EM_IP2K_OLD:
2950 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2951 case EM_MAX: return "MAX Processor";
2952 case EM_CR: return "National Semiconductor CompactRISC";
2953 case EM_F2MC16: return "Fujitsu F2MC16";
2954 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2955 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2956 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2957 case EM_SEP: return "Sharp embedded microprocessor";
2958 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2959 /* 110 */
11636f9e
JM
2960 case EM_UNICORE: return "Unicore";
2961 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2962 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2963 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2964 case EM_CRX: return "National Semiconductor CRX microprocessor";
2965 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2966 case EM_C166:
d70c5fc7 2967 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2968 case EM_M16C: return "Renesas M16C series microprocessors";
2969 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2970 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2971 /* 120 */
2972 case EM_M32C: return "Renesas M32c";
2973 /* 130 */
11636f9e
JM
2974 case EM_TSK3000: return "Altium TSK3000 core";
2975 case EM_RS08: return "Freescale RS08 embedded processor";
2976 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2977 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2978 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2979 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2980 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2981 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2982 /* 140 */
11636f9e
JM
2983 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2984 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2985 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2986 case EM_TI_PRU: return "TI PRU I/O processor";
2987 /* 160 */
11636f9e
JM
2988 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2989 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2990 case EM_R32C: return "Renesas R32C series microprocessors";
2991 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2992 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2993 case EM_8051: return "Intel 8051 and variants";
2994 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2995 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2996 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2997 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2998 /* 170 */
11636f9e
JM
2999 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3000 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3001 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 3002 case EM_RX: return "Renesas RX";
a3c62988 3003 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
3004 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3005 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
3006 case EM_CR16:
3007 case EM_MICROBLAZE:
3008 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
3009 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3010 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
3011 /* 180 */
3012 case EM_L1OM: return "Intel L1OM";
3013 case EM_K1OM: return "Intel K1OM";
3014 case EM_INTEL182: return "Intel (reserved)";
3015 case EM_AARCH64: return "AArch64";
3016 case EM_ARM184: return "ARM (reserved)";
3017 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
3018 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3019 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3020 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3021 /* 190 */
11636f9e 3022 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3023 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3024 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3025 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3026 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3027 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3028 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3029 case EM_RL78: return "Renesas RL78";
6d913794 3030 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3031 case EM_78K0R: return "Renesas 78K0R";
3032 /* 200 */
6d913794 3033 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3034 case EM_BA1: return "Beyond BA1 CPU architecture";
3035 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3036 case EM_XCORE: return "XMOS xCORE processor family";
3037 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3038 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3039 /* 210 */
6d913794
NC
3040 case EM_KM32: return "KM211 KM32 32-bit processor";
3041 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3042 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3043 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3044 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3045 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3046 case EM_COGE: return "Cognitive Smart Memory Processor";
3047 case EM_COOL: return "Bluechip Systems CoolEngine";
3048 case EM_NORC: return "Nanoradio Optimized RISC";
3049 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3050 /* 220 */
15f205b1 3051 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3052 case EM_VISIUM: return "CDS VISIUMcore processor";
3053 case EM_FT32: return "FTDI Chip FT32";
3054 case EM_MOXIE: return "Moxie";
3055 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3056 /* 230 (all reserved) */
3057 /* 240 */
55e22ca8
NC
3058 case EM_RISCV: return "RISC-V";
3059 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3060 case EM_CEVA: return "CEVA Processor Architecture Family";
3061 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3062 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3063 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3064 case EM_IMG1: return "Imagination Technologies";
3065 /* 250 */
fe944acf 3066 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3067 case EM_VE: return "NEC Vector Engine";
3068 case EM_CSKY: return "C-SKY";
b5c37946 3069 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3070 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3071 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3072 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3073 case EM_65816: return "WDC 65816/65C816";
01a8c731 3074 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3075 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3076
3077 /* Large numbers... */
3078 case EM_MT: return "Morpho Techologies MT processor";
3079 case EM_ALPHA: return "Alpha";
3080 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3081 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3082 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3083 case EM_IQ2000: return "Vitesse IQ2000";
3084 case EM_M32C_OLD:
3085 case EM_NIOS32: return "Altera Nios";
3086 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3087 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3088 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3089 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3090
252b5132 3091 default:
35d9dd2f 3092 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3093 return buff;
3094 }
3095}
3096
f8c4789c
AM
3097static char *
3098decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3099{
3100 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3101 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3102 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3103 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3104 architectures.
3105
3106 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3107 but also sets a specific architecture type in the e_flags field.
3108
3109 However, when decoding the flags we don't worry if we see an
3110 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3111 ARCEM architecture type. */
3112
3113 switch (e_flags & EF_ARC_MACH_MSK)
3114 {
3115 /* We only expect these to occur for EM_ARC_COMPACT2. */
3116 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3117 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3118 break;
3119 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3120 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3121 break;
3122
3123 /* We only expect these to occur for EM_ARC_COMPACT. */
3124 case E_ARC_MACH_ARC600:
f8c4789c 3125 out = stpcpy (out, ", ARC600");
a9522a21
AB
3126 break;
3127 case E_ARC_MACH_ARC601:
f8c4789c 3128 out = stpcpy (out, ", ARC601");
a9522a21
AB
3129 break;
3130 case E_ARC_MACH_ARC700:
f8c4789c 3131 out = stpcpy (out, ", ARC700");
a9522a21
AB
3132 break;
3133
3134 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3135 new ELF with new architecture being read by an old version of
3136 readelf, or (c) An ELF built with non-GNU compiler that does not
3137 set the architecture in the e_flags. */
3138 default:
3139 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3140 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3141 else
f8c4789c 3142 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3143 break;
3144 }
3145
3146 switch (e_flags & EF_ARC_OSABI_MSK)
3147 {
3148 case E_ARC_OSABI_ORIG:
f8c4789c 3149 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3150 break;
3151 case E_ARC_OSABI_V2:
f8c4789c 3152 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3153 break;
3154 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3155 case E_ARC_OSABI_V3:
f8c4789c 3156 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3157 break;
53a346d8 3158 case E_ARC_OSABI_V4:
f8c4789c 3159 out = stpcpy (out, ", v4 ABI");
53a346d8 3160 break;
a9522a21 3161 default:
f8c4789c 3162 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3163 break;
3164 }
f8c4789c 3165 return out;
a9522a21
AB
3166}
3167
f8c4789c
AM
3168static char *
3169decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3170{
3171 unsigned eabi;
015dc7e1 3172 bool unknown = false;
f3485b74
NC
3173
3174 eabi = EF_ARM_EABI_VERSION (e_flags);
3175 e_flags &= ~ EF_ARM_EABIMASK;
3176
3177 /* Handle "generic" ARM flags. */
3178 if (e_flags & EF_ARM_RELEXEC)
3179 {
f8c4789c 3180 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3181 e_flags &= ~ EF_ARM_RELEXEC;
3182 }
76da6bbe 3183
18a20338
CL
3184 if (e_flags & EF_ARM_PIC)
3185 {
f8c4789c 3186 out = stpcpy (out, ", position independent");
18a20338
CL
3187 e_flags &= ~ EF_ARM_PIC;
3188 }
3189
f3485b74
NC
3190 /* Now handle EABI specific flags. */
3191 switch (eabi)
3192 {
3193 default:
f8c4789c 3194 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3195 if (e_flags)
015dc7e1 3196 unknown = true;
f3485b74
NC
3197 break;
3198
3199 case EF_ARM_EABI_VER1:
f8c4789c 3200 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3201 while (e_flags)
3202 {
3203 unsigned flag;
76da6bbe 3204
f3485b74
NC
3205 /* Process flags one bit at a time. */
3206 flag = e_flags & - e_flags;
3207 e_flags &= ~ flag;
76da6bbe 3208
f3485b74
NC
3209 switch (flag)
3210 {
a5bcd848 3211 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3212 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3213 break;
76da6bbe 3214
f3485b74 3215 default:
015dc7e1 3216 unknown = true;
f3485b74
NC
3217 break;
3218 }
3219 }
3220 break;
76da6bbe 3221
a5bcd848 3222 case EF_ARM_EABI_VER2:
f8c4789c 3223 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3224 while (e_flags)
3225 {
3226 unsigned flag;
3227
3228 /* Process flags one bit at a time. */
3229 flag = e_flags & - e_flags;
3230 e_flags &= ~ flag;
3231
3232 switch (flag)
3233 {
3234 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3235 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3236 break;
3237
3238 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3239 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3240 break;
3241
3242 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3243 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3244 break;
3245
3246 default:
015dc7e1 3247 unknown = true;
a5bcd848
PB
3248 break;
3249 }
3250 }
3251 break;
3252
d507cf36 3253 case EF_ARM_EABI_VER3:
f8c4789c 3254 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3255 break;
3256
3257 case EF_ARM_EABI_VER4:
f8c4789c 3258 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3259 while (e_flags)
3260 {
3261 unsigned flag;
3262
3263 /* Process flags one bit at a time. */
3264 flag = e_flags & - e_flags;
3265 e_flags &= ~ flag;
3266
3267 switch (flag)
3268 {
3269 case EF_ARM_BE8:
f8c4789c 3270 out = stpcpy (out, ", BE8");
3bfcb652
NC
3271 break;
3272
3273 case EF_ARM_LE8:
f8c4789c 3274 out = stpcpy (out, ", LE8");
3bfcb652
NC
3275 break;
3276
3277 default:
015dc7e1 3278 unknown = true;
3bfcb652
NC
3279 break;
3280 }
3bfcb652
NC
3281 }
3282 break;
3a4a14e9
PB
3283
3284 case EF_ARM_EABI_VER5:
f8c4789c 3285 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3286 while (e_flags)
3287 {
3288 unsigned flag;
3289
3290 /* Process flags one bit at a time. */
3291 flag = e_flags & - e_flags;
3292 e_flags &= ~ flag;
3293
3294 switch (flag)
3295 {
3296 case EF_ARM_BE8:
f8c4789c 3297 out = stpcpy (out, ", BE8");
d507cf36
PB
3298 break;
3299
3300 case EF_ARM_LE8:
f8c4789c 3301 out = stpcpy (out, ", LE8");
d507cf36
PB
3302 break;
3303
3bfcb652 3304 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3305 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3306 break;
3307
3308 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3309 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3310 break;
3311
d507cf36 3312 default:
015dc7e1 3313 unknown = true;
d507cf36
PB
3314 break;
3315 }
3316 }
3317 break;
3318
f3485b74 3319 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3320 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3321 while (e_flags)
3322 {
3323 unsigned flag;
76da6bbe 3324
f3485b74
NC
3325 /* Process flags one bit at a time. */
3326 flag = e_flags & - e_flags;
3327 e_flags &= ~ flag;
76da6bbe 3328
f3485b74
NC
3329 switch (flag)
3330 {
a5bcd848 3331 case EF_ARM_INTERWORK:
f8c4789c 3332 out = stpcpy (out, ", interworking enabled");
f3485b74 3333 break;
76da6bbe 3334
a5bcd848 3335 case EF_ARM_APCS_26:
f8c4789c 3336 out = stpcpy (out, ", uses APCS/26");
f3485b74 3337 break;
76da6bbe 3338
a5bcd848 3339 case EF_ARM_APCS_FLOAT:
f8c4789c 3340 out = stpcpy (out, ", uses APCS/float");
f3485b74 3341 break;
76da6bbe 3342
a5bcd848 3343 case EF_ARM_PIC:
f8c4789c 3344 out = stpcpy (out, ", position independent");
f3485b74 3345 break;
76da6bbe 3346
a5bcd848 3347 case EF_ARM_ALIGN8:
f8c4789c 3348 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3349 break;
76da6bbe 3350
a5bcd848 3351 case EF_ARM_NEW_ABI:
f8c4789c 3352 out = stpcpy (out, ", uses new ABI");
f3485b74 3353 break;
76da6bbe 3354
a5bcd848 3355 case EF_ARM_OLD_ABI:
f8c4789c 3356 out = stpcpy (out, ", uses old ABI");
f3485b74 3357 break;
76da6bbe 3358
a5bcd848 3359 case EF_ARM_SOFT_FLOAT:
f8c4789c 3360 out = stpcpy (out, ", software FP");
f3485b74 3361 break;
76da6bbe 3362
90e01f86 3363 case EF_ARM_VFP_FLOAT:
f8c4789c 3364 out = stpcpy (out, ", VFP");
90e01f86
ILT
3365 break;
3366
fde78edd 3367 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3368 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3369 break;
3370
f3485b74 3371 default:
015dc7e1 3372 unknown = true;
f3485b74
NC
3373 break;
3374 }
3375 }
3376 }
f3485b74
NC
3377
3378 if (unknown)
f8c4789c
AM
3379 out = stpcpy (out,_(", <unknown>"));
3380 return out;
f3485b74
NC
3381}
3382
f8c4789c
AM
3383static char *
3384decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3385{
343433df
AB
3386 switch (e_flags & EF_AVR_MACH)
3387 {
3388 case E_AVR_MACH_AVR1:
f8c4789c 3389 out = stpcpy (out, ", avr:1");
343433df
AB
3390 break;
3391 case E_AVR_MACH_AVR2:
f8c4789c 3392 out = stpcpy (out, ", avr:2");
343433df
AB
3393 break;
3394 case E_AVR_MACH_AVR25:
f8c4789c 3395 out = stpcpy (out, ", avr:25");
343433df
AB
3396 break;
3397 case E_AVR_MACH_AVR3:
f8c4789c 3398 out = stpcpy (out, ", avr:3");
343433df
AB
3399 break;
3400 case E_AVR_MACH_AVR31:
f8c4789c 3401 out = stpcpy (out, ", avr:31");
343433df
AB
3402 break;
3403 case E_AVR_MACH_AVR35:
f8c4789c 3404 out = stpcpy (out, ", avr:35");
343433df
AB
3405 break;
3406 case E_AVR_MACH_AVR4:
f8c4789c 3407 out = stpcpy (out, ", avr:4");
343433df
AB
3408 break;
3409 case E_AVR_MACH_AVR5:
f8c4789c 3410 out = stpcpy (out, ", avr:5");
343433df
AB
3411 break;
3412 case E_AVR_MACH_AVR51:
f8c4789c 3413 out = stpcpy (out, ", avr:51");
343433df
AB
3414 break;
3415 case E_AVR_MACH_AVR6:
f8c4789c 3416 out = stpcpy (out, ", avr:6");
343433df
AB
3417 break;
3418 case E_AVR_MACH_AVRTINY:
f8c4789c 3419 out = stpcpy (out, ", avr:100");
343433df
AB
3420 break;
3421 case E_AVR_MACH_XMEGA1:
f8c4789c 3422 out = stpcpy (out, ", avr:101");
343433df
AB
3423 break;
3424 case E_AVR_MACH_XMEGA2:
f8c4789c 3425 out = stpcpy (out, ", avr:102");
343433df
AB
3426 break;
3427 case E_AVR_MACH_XMEGA3:
f8c4789c 3428 out = stpcpy (out, ", avr:103");
343433df
AB
3429 break;
3430 case E_AVR_MACH_XMEGA4:
f8c4789c 3431 out = stpcpy (out, ", avr:104");
343433df
AB
3432 break;
3433 case E_AVR_MACH_XMEGA5:
f8c4789c 3434 out = stpcpy (out, ", avr:105");
343433df
AB
3435 break;
3436 case E_AVR_MACH_XMEGA6:
f8c4789c 3437 out = stpcpy (out, ", avr:106");
343433df
AB
3438 break;
3439 case E_AVR_MACH_XMEGA7:
f8c4789c 3440 out = stpcpy (out, ", avr:107");
343433df
AB
3441 break;
3442 default:
f8c4789c 3443 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3444 break;
3445 }
3446
343433df 3447 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3448 out = stpcpy (out, ", link-relax");
3449 return out;
343433df
AB
3450}
3451
f8c4789c
AM
3452static char *
3453decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3454{
3455 if (e_flags & EF_BFIN_PIC)
3456 out = stpcpy (out, ", PIC");
3457
3458 if (e_flags & EF_BFIN_FDPIC)
3459 out = stpcpy (out, ", FDPIC");
3460
3461 if (e_flags & EF_BFIN_CODE_IN_L1)
3462 out = stpcpy (out, ", code in L1");
3463
3464 if (e_flags & EF_BFIN_DATA_IN_L1)
3465 out = stpcpy (out, ", data in L1");
3466 return out;
3467}
3468
3469static char *
3470decode_FRV_machine_flags (char *out, unsigned e_flags)
3471{
3472 switch (e_flags & EF_FRV_CPU_MASK)
3473 {
3474 case EF_FRV_CPU_GENERIC:
3475 break;
3476
3477 default:
3478 out = stpcpy (out, ", fr???");
3479 break;
3480
3481 case EF_FRV_CPU_FR300:
3482 out = stpcpy (out, ", fr300");
3483 break;
3484
3485 case EF_FRV_CPU_FR400:
3486 out = stpcpy (out, ", fr400");
3487 break;
3488 case EF_FRV_CPU_FR405:
3489 out = stpcpy (out, ", fr405");
3490 break;
3491
3492 case EF_FRV_CPU_FR450:
3493 out = stpcpy (out, ", fr450");
3494 break;
3495
3496 case EF_FRV_CPU_FR500:
3497 out = stpcpy (out, ", fr500");
3498 break;
3499 case EF_FRV_CPU_FR550:
3500 out = stpcpy (out, ", fr550");
3501 break;
3502
3503 case EF_FRV_CPU_SIMPLE:
3504 out = stpcpy (out, ", simple");
3505 break;
3506 case EF_FRV_CPU_TOMCAT:
3507 out = stpcpy (out, ", tomcat");
3508 break;
3509 }
3510 return out;
3511}
3512
3513static char *
3514decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3515{
3516 if ((e_flags & EF_IA_64_ABI64))
3517 out = stpcpy (out, ", 64-bit");
3518 else
3519 out = stpcpy (out, ", 32-bit");
3520 if ((e_flags & EF_IA_64_REDUCEDFP))
3521 out = stpcpy (out, ", reduced fp model");
3522 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3523 out = stpcpy (out, ", no function descriptors, constant gp");
3524 else if ((e_flags & EF_IA_64_CONS_GP))
3525 out = stpcpy (out, ", constant gp");
3526 if ((e_flags & EF_IA_64_ABSOLUTE))
3527 out = stpcpy (out, ", absolute");
3528 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3529 {
3530 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3531 out = stpcpy (out, ", vms_linkages");
3532 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3533 {
3534 case EF_IA_64_VMS_COMCOD_SUCCESS:
3535 break;
3536 case EF_IA_64_VMS_COMCOD_WARNING:
3537 out = stpcpy (out, ", warning");
3538 break;
3539 case EF_IA_64_VMS_COMCOD_ERROR:
3540 out = stpcpy (out, ", error");
3541 break;
3542 case EF_IA_64_VMS_COMCOD_ABORT:
3543 out = stpcpy (out, ", abort");
3544 break;
3545 default:
3546 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3547 e_flags & EF_IA_64_VMS_COMCOD);
3548 out = stpcpy (out, ", <unknown>");
3549 }
3550 }
3551 return out;
3552}
3553
3554static char *
3555decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3556{
3557 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3558 out = stpcpy (out, ", SOFT-FLOAT");
3559 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3560 out = stpcpy (out, ", SINGLE-FLOAT");
3561 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3562 out = stpcpy (out, ", DOUBLE-FLOAT");
3563
3564 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3565 out = stpcpy (out, ", OBJ-v0");
3566 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3567 out = stpcpy (out, ", OBJ-v1");
3568 return out;
3569}
3570
3571static char *
3572decode_M68K_machine_flags (char *out, unsigned int e_flags)
3573{
3574 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3575 out = stpcpy (out, ", m68000");
3576 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3577 out = stpcpy (out, ", cpu32");
3578 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3579 out = stpcpy (out, ", fido_a");
3580 else
3581 {
3582 char const *isa = _("unknown");
3583 char const *mac = _("unknown mac");
3584 char const *additional = NULL;
3585
3586 switch (e_flags & EF_M68K_CF_ISA_MASK)
3587 {
3588 case EF_M68K_CF_ISA_A_NODIV:
3589 isa = "A";
3590 additional = ", nodiv";
3591 break;
3592 case EF_M68K_CF_ISA_A:
3593 isa = "A";
3594 break;
3595 case EF_M68K_CF_ISA_A_PLUS:
3596 isa = "A+";
3597 break;
3598 case EF_M68K_CF_ISA_B_NOUSP:
3599 isa = "B";
3600 additional = ", nousp";
3601 break;
3602 case EF_M68K_CF_ISA_B:
3603 isa = "B";
3604 break;
3605 case EF_M68K_CF_ISA_C:
3606 isa = "C";
3607 break;
3608 case EF_M68K_CF_ISA_C_NODIV:
3609 isa = "C";
3610 additional = ", nodiv";
3611 break;
3612 }
3613 out = stpcpy (out, ", cf, isa ");
3614 out = stpcpy (out, isa);
3615 if (additional)
3616 out = stpcpy (out, additional);
3617 if (e_flags & EF_M68K_CF_FLOAT)
3618 out = stpcpy (out, ", float");
3619 switch (e_flags & EF_M68K_CF_MAC_MASK)
3620 {
3621 case 0:
3622 mac = NULL;
3623 break;
3624 case EF_M68K_CF_MAC:
3625 mac = "mac";
3626 break;
3627 case EF_M68K_CF_EMAC:
3628 mac = "emac";
3629 break;
3630 case EF_M68K_CF_EMAC_B:
3631 mac = "emac_b";
3632 break;
3633 }
3634 if (mac)
3635 {
3636 out = stpcpy (out, ", ");
3637 out = stpcpy (out, mac);
3638 }
3639 }
3640 return out;
3641}
3642
3643static char *
3644decode_MeP_machine_flags (char *out, unsigned int e_flags)
3645{
3646 switch (e_flags & EF_MEP_CPU_MASK)
3647 {
3648 case EF_MEP_CPU_MEP:
3649 out = stpcpy (out, ", generic MeP");
3650 break;
3651 case EF_MEP_CPU_C2:
3652 out = stpcpy (out, ", MeP C2");
3653 break;
3654 case EF_MEP_CPU_C3:
3655 out = stpcpy (out, ", MeP C3");
3656 break;
3657 case EF_MEP_CPU_C4:
3658 out = stpcpy (out, ", MeP C4");
3659 break;
3660 case EF_MEP_CPU_C5:
3661 out = stpcpy (out, ", MeP C5");
3662 break;
3663 case EF_MEP_CPU_H1:
3664 out = stpcpy (out, ", MeP H1");
3665 break;
3666 default:
3667 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3668 break;
3669 }
3670
3671 switch (e_flags & EF_MEP_COP_MASK)
3672 {
3673 case EF_MEP_COP_NONE:
3674 break;
3675 case EF_MEP_COP_AVC:
3676 out = stpcpy (out, ", AVC coprocessor");
3677 break;
3678 case EF_MEP_COP_AVC2:
3679 out = stpcpy (out, ", AVC2 coprocessor");
3680 break;
3681 case EF_MEP_COP_FMAX:
3682 out = stpcpy (out, ", FMAX coprocessor");
3683 break;
3684 case EF_MEP_COP_IVC2:
3685 out = stpcpy (out, ", IVC2 coprocessor");
3686 break;
3687 default:
3688 out = stpcpy (out, _("<unknown MeP copro type>"));
3689 break;
3690 }
3691
3692 if (e_flags & EF_MEP_LIBRARY)
3693 out = stpcpy (out, ", Built for Library");
3694
3695 if (e_flags & EF_MEP_INDEX_MASK)
3696 out += sprintf (out, ", Configuration Index: %#x",
3697 e_flags & EF_MEP_INDEX_MASK);
3698
3699 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3700 out += sprintf (out, _(", unknown flags bits: %#x"),
3701 e_flags & ~ EF_MEP_ALL_FLAGS);
3702 return out;
3703}
3704
3705static char *
3706decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3707{
3708 if (e_flags & EF_MIPS_NOREORDER)
3709 out = stpcpy (out, ", noreorder");
3710
3711 if (e_flags & EF_MIPS_PIC)
3712 out = stpcpy (out, ", pic");
3713
3714 if (e_flags & EF_MIPS_CPIC)
3715 out = stpcpy (out, ", cpic");
3716
3717 if (e_flags & EF_MIPS_UCODE)
3718 out = stpcpy (out, ", ugen_reserved");
3719
3720 if (e_flags & EF_MIPS_ABI2)
3721 out = stpcpy (out, ", abi2");
3722
3723 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3724 out = stpcpy (out, ", odk first");
3725
3726 if (e_flags & EF_MIPS_32BITMODE)
3727 out = stpcpy (out, ", 32bitmode");
3728
3729 if (e_flags & EF_MIPS_NAN2008)
3730 out = stpcpy (out, ", nan2008");
3731
3732 if (e_flags & EF_MIPS_FP64)
3733 out = stpcpy (out, ", fp64");
3734
3735 switch ((e_flags & EF_MIPS_MACH))
3736 {
d173146d 3737 case EF_MIPS_MACH_3900:
f8c4789c
AM
3738 out = stpcpy (out, ", 3900");
3739 break;
d173146d 3740 case EF_MIPS_MACH_4010:
f8c4789c
AM
3741 out = stpcpy (out, ", 4010");
3742 break;
d173146d 3743 case EF_MIPS_MACH_4100:
f8c4789c
AM
3744 out = stpcpy (out, ", 4100");
3745 break;
d173146d 3746 case EF_MIPS_MACH_4111:
f8c4789c
AM
3747 out = stpcpy (out, ", 4111");
3748 break;
d173146d 3749 case EF_MIPS_MACH_4120:
f8c4789c
AM
3750 out = stpcpy (out, ", 4120");
3751 break;
d173146d 3752 case EF_MIPS_MACH_4650:
f8c4789c
AM
3753 out = stpcpy (out, ", 4650");
3754 break;
d173146d 3755 case EF_MIPS_MACH_5400:
f8c4789c
AM
3756 out = stpcpy (out, ", 5400");
3757 break;
d173146d 3758 case EF_MIPS_MACH_5500:
f8c4789c
AM
3759 out = stpcpy (out, ", 5500");
3760 break;
d173146d 3761 case EF_MIPS_MACH_5900:
f8c4789c
AM
3762 out = stpcpy (out, ", 5900");
3763 break;
d173146d 3764 case EF_MIPS_MACH_SB1:
f8c4789c
AM
3765 out = stpcpy (out, ", sb1");
3766 break;
d173146d 3767 case EF_MIPS_MACH_9000:
f8c4789c
AM
3768 out = stpcpy (out, ", 9000");
3769 break;
d173146d 3770 case EF_MIPS_MACH_LS2E:
f8c4789c
AM
3771 out = stpcpy (out, ", loongson-2e");
3772 break;
d173146d 3773 case EF_MIPS_MACH_LS2F:
f8c4789c
AM
3774 out = stpcpy (out, ", loongson-2f");
3775 break;
d173146d 3776 case EF_MIPS_MACH_GS464:
f8c4789c
AM
3777 out = stpcpy (out, ", gs464");
3778 break;
d173146d 3779 case EF_MIPS_MACH_GS464E:
f8c4789c
AM
3780 out = stpcpy (out, ", gs464e");
3781 break;
d173146d 3782 case EF_MIPS_MACH_GS264E:
f8c4789c
AM
3783 out = stpcpy (out, ", gs264e");
3784 break;
d173146d 3785 case EF_MIPS_MACH_OCTEON:
f8c4789c
AM
3786 out = stpcpy (out, ", octeon");
3787 break;
d173146d 3788 case EF_MIPS_MACH_OCTEON2:
f8c4789c
AM
3789 out = stpcpy (out, ", octeon2");
3790 break;
d173146d 3791 case EF_MIPS_MACH_OCTEON3:
f8c4789c
AM
3792 out = stpcpy (out, ", octeon3");
3793 break;
d173146d 3794 case EF_MIPS_MACH_XLR:
f8c4789c
AM
3795 out = stpcpy (out, ", xlr");
3796 break;
d173146d 3797 case EF_MIPS_MACH_IAMR2:
f8c4789c
AM
3798 out = stpcpy (out, ", interaptiv-mr2");
3799 break;
d173146d 3800 case EF_MIPS_MACH_ALLEGREX:
f8c4789c
AM
3801 out = stpcpy (out, ", allegrex");
3802 break;
3803 case 0:
3804 /* We simply ignore the field in this case to avoid confusion:
3805 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3806 extension. */
3807 break;
3808 default:
3809 out = stpcpy (out, _(", unknown CPU"));
3810 break;
3811 }
3812
3813 switch ((e_flags & EF_MIPS_ABI))
3814 {
d173146d 3815 case EF_MIPS_ABI_O32:
f8c4789c
AM
3816 out = stpcpy (out, ", o32");
3817 break;
d173146d 3818 case EF_MIPS_ABI_O64:
f8c4789c
AM
3819 out = stpcpy (out, ", o64");
3820 break;
d173146d 3821 case EF_MIPS_ABI_EABI32:
f8c4789c
AM
3822 out = stpcpy (out, ", eabi32");
3823 break;
d173146d 3824 case EF_MIPS_ABI_EABI64:
f8c4789c
AM
3825 out = stpcpy (out, ", eabi64");
3826 break;
3827 case 0:
3828 /* We simply ignore the field in this case to avoid confusion:
3829 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3830 This means it is likely to be an o32 file, but not for
3831 sure. */
3832 break;
3833 default:
3834 out = stpcpy (out, _(", unknown ABI"));
3835 break;
3836 }
3837
3838 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3839 out = stpcpy (out, ", mdmx");
3840
3841 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3842 out = stpcpy (out, ", mips16");
3843
3844 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3845 out = stpcpy (out, ", micromips");
3846
3847 switch ((e_flags & EF_MIPS_ARCH))
3848 {
d173146d 3849 case EF_MIPS_ARCH_1:
f8c4789c
AM
3850 out = stpcpy (out, ", mips1");
3851 break;
d173146d 3852 case EF_MIPS_ARCH_2:
f8c4789c
AM
3853 out = stpcpy (out, ", mips2");
3854 break;
d173146d 3855 case EF_MIPS_ARCH_3:
f8c4789c
AM
3856 out = stpcpy (out, ", mips3");
3857 break;
d173146d 3858 case EF_MIPS_ARCH_4:
f8c4789c
AM
3859 out = stpcpy (out, ", mips4");
3860 break;
d173146d 3861 case EF_MIPS_ARCH_5:
f8c4789c
AM
3862 out = stpcpy (out, ", mips5");
3863 break;
d173146d 3864 case EF_MIPS_ARCH_32:
f8c4789c
AM
3865 out = stpcpy (out, ", mips32");
3866 break;
d173146d 3867 case EF_MIPS_ARCH_32R2:
f8c4789c
AM
3868 out = stpcpy (out, ", mips32r2");
3869 break;
d173146d 3870 case EF_MIPS_ARCH_32R6:
f8c4789c
AM
3871 out = stpcpy (out, ", mips32r6");
3872 break;
d173146d 3873 case EF_MIPS_ARCH_64:
f8c4789c
AM
3874 out = stpcpy (out, ", mips64");
3875 break;
d173146d 3876 case EF_MIPS_ARCH_64R2:
f8c4789c
AM
3877 out = stpcpy (out, ", mips64r2");
3878 break;
d173146d 3879 case EF_MIPS_ARCH_64R6:
f8c4789c
AM
3880 out = stpcpy (out, ", mips64r6");
3881 break;
3882 default:
3883 out = stpcpy (out, _(", unknown ISA"));
3884 break;
3885 }
3886 return out;
3887}
3888
3889static char *
3890decode_MSP430_machine_flags (char *out, unsigned e_flags)
3891{
3892 out = stpcpy (out, _(": architecture variant: "));
3893 switch (e_flags & EF_MSP430_MACH)
3894 {
3895 case E_MSP430_MACH_MSP430x11:
3896 out = stpcpy (out, "MSP430x11");
3897 break;
3898 case E_MSP430_MACH_MSP430x11x1:
3899 out = stpcpy (out, "MSP430x11x1 ");
3900 break;
3901 case E_MSP430_MACH_MSP430x12:
3902 out = stpcpy (out, "MSP430x12");
3903 break;
3904 case E_MSP430_MACH_MSP430x13:
3905 out = stpcpy (out, "MSP430x13");
3906 break;
3907 case E_MSP430_MACH_MSP430x14:
3908 out = stpcpy (out, "MSP430x14");
3909 break;
3910 case E_MSP430_MACH_MSP430x15:
3911 out = stpcpy (out, "MSP430x15");
3912 break;
3913 case E_MSP430_MACH_MSP430x16:
3914 out = stpcpy (out, "MSP430x16");
3915 break;
3916 case E_MSP430_MACH_MSP430x31:
3917 out = stpcpy (out, "MSP430x31");
3918 break;
3919 case E_MSP430_MACH_MSP430x32:
3920 out = stpcpy (out, "MSP430x32");
3921 break;
3922 case E_MSP430_MACH_MSP430x33:
3923 out = stpcpy (out, "MSP430x33");
3924 break;
3925 case E_MSP430_MACH_MSP430x41:
3926 out = stpcpy (out, "MSP430x41");
3927 break;
3928 case E_MSP430_MACH_MSP430x42:
3929 out = stpcpy (out, "MSP430x42");
3930 break;
3931 case E_MSP430_MACH_MSP430x43:
3932 out = stpcpy (out, "MSP430x43");
3933 break;
3934 case E_MSP430_MACH_MSP430x44:
3935 out = stpcpy (out, "MSP430x44");
3936 break;
3937 case E_MSP430_MACH_MSP430X :
3938 out = stpcpy (out, "MSP430X");
3939 break;
3940 default:
3941 out = stpcpy (out, _(": unknown"));
3942 break;
3943 }
3944
3945 if (e_flags & ~ EF_MSP430_MACH)
3946 out = stpcpy (out, _(": unknown extra flag bits also present"));
3947 return out;
3948}
3949
3950static char *
3951decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
3952{
3953 unsigned abi;
3954 unsigned arch;
3955 unsigned config;
3956 unsigned version;
015dc7e1 3957 bool has_fpu = false;
35c08157
KLC
3958
3959 static const char *ABI_STRINGS[] =
3960 {
3961 "ABI v0", /* use r5 as return register; only used in N1213HC */
3962 "ABI v1", /* use r0 as return register */
3963 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3964 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3965 "AABI",
3966 "ABI2 FP+"
35c08157
KLC
3967 };
3968 static const char *VER_STRINGS[] =
3969 {
3970 "Andes ELF V1.3 or older",
3971 "Andes ELF V1.3.1",
3972 "Andes ELF V1.4"
3973 };
3974 static const char *ARCH_STRINGS[] =
3975 {
3976 "",
3977 "Andes Star v1.0",
3978 "Andes Star v2.0",
3979 "Andes Star v3.0",
3980 "Andes Star v3.0m"
3981 };
3982
3983 abi = EF_NDS_ABI & e_flags;
3984 arch = EF_NDS_ARCH & e_flags;
3985 config = EF_NDS_INST & e_flags;
3986 version = EF_NDS32_ELF_VERSION & e_flags;
3987
35c08157
KLC
3988 switch (abi)
3989 {
3990 case E_NDS_ABI_V0:
3991 case E_NDS_ABI_V1:
3992 case E_NDS_ABI_V2:
3993 case E_NDS_ABI_V2FP:
3994 case E_NDS_ABI_AABI:
40c7a7cb 3995 case E_NDS_ABI_V2FP_PLUS:
35c08157 3996 /* In case there are holes in the array. */
f8c4789c 3997 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
3998 break;
3999
4000 default:
f8c4789c 4001 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
4002 break;
4003 }
4004
4005 switch (version)
4006 {
4007 case E_NDS32_ELF_VER_1_2:
4008 case E_NDS32_ELF_VER_1_3:
4009 case E_NDS32_ELF_VER_1_4:
f8c4789c 4010 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
4011 break;
4012
4013 default:
f8c4789c 4014 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
4015 break;
4016 }
4017
4018 if (E_NDS_ABI_V0 == abi)
4019 {
4020 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4021 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4022 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4023 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4024 return out;
35c08157
KLC
4025 }
4026
4027 switch (arch)
4028 {
4029 case E_NDS_ARCH_STAR_V1_0:
4030 case E_NDS_ARCH_STAR_V2_0:
4031 case E_NDS_ARCH_STAR_V3_0:
4032 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4033 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4034 break;
4035
4036 default:
f8c4789c 4037 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4038 /* ARCH version determines how the e_flags are interpreted.
4039 If it is unknown, we cannot proceed. */
f8c4789c 4040 return out;
35c08157
KLC
4041 }
4042
4043 /* Newer ABI; Now handle architecture specific flags. */
4044 if (arch == E_NDS_ARCH_STAR_V1_0)
4045 {
4046 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4047 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4048
4049 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4050 out = stpcpy (out, ", MAC");
35c08157
KLC
4051
4052 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4053 out = stpcpy (out, ", DIV");
35c08157
KLC
4054
4055 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4056 out = stpcpy (out, ", 16b");
35c08157
KLC
4057 }
4058 else
4059 {
4060 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4061 {
4062 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4063 out = stpcpy (out, ", [B8]");
35c08157 4064 else
f8c4789c 4065 out = stpcpy (out, ", EX9");
35c08157
KLC
4066 }
4067
4068 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4069 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4070
4071 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4072 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4073
4074 if (config & E_NDS32_HAS_16BIT_INST)
4075 {
4076 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4077 out = stpcpy (out, ", 16b");
35c08157 4078 else
f8c4789c 4079 out = stpcpy (out, ", IFC");
35c08157
KLC
4080 }
4081 }
4082
4083 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4084 out = stpcpy (out, ", PERF1");
35c08157
KLC
4085
4086 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4087 out = stpcpy (out, ", PERF2");
35c08157
KLC
4088
4089 if (config & E_NDS32_HAS_FPU_INST)
4090 {
015dc7e1 4091 has_fpu = true;
f8c4789c 4092 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4093 }
4094
4095 if (config & E_NDS32_HAS_FPU_DP_INST)
4096 {
015dc7e1 4097 has_fpu = true;
f8c4789c 4098 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4099 }
4100
4101 if (config & E_NDS32_HAS_FPU_MAC_INST)
4102 {
015dc7e1 4103 has_fpu = true;
f8c4789c 4104 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4105 }
4106
4107 if (has_fpu)
4108 {
4109 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4110 {
4111 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4112 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4113 break;
4114 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4115 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4116 break;
4117 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4118 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4119 break;
4120 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4121 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4122 break;
4123 }
4124 }
4125
4126 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4127 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4128
4129 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4130 out = stpcpy (out, ", STR");
35c08157
KLC
4131
4132 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4133 out = stpcpy (out, ", 16REG");
35c08157
KLC
4134
4135 if (config & E_NDS32_HAS_VIDEO_INST)
4136 {
4137 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4138 out = stpcpy (out, ", VIDEO");
35c08157 4139 else
f8c4789c 4140 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4141 }
4142
4143 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4144 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4145
4146 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4147 out = stpcpy (out, ", L2C");
4148
4149 return out;
35c08157
KLC
4150}
4151
f8c4789c
AM
4152static char *
4153decode_PARISC_machine_flags (char *out, unsigned e_flags)
4154{
4155 switch (e_flags & EF_PARISC_ARCH)
4156 {
4157 case EFA_PARISC_1_0:
4158 out = stpcpy (out, ", PA-RISC 1.0");
4159 break;
4160 case EFA_PARISC_1_1:
4161 out = stpcpy (out, ", PA-RISC 1.1");
4162 break;
4163 case EFA_PARISC_2_0:
4164 out = stpcpy (out, ", PA-RISC 2.0");
4165 break;
4166 default:
4167 break;
4168 }
4169 if (e_flags & EF_PARISC_TRAPNIL)
4170 out = stpcpy (out, ", trapnil");
4171 if (e_flags & EF_PARISC_EXT)
4172 out = stpcpy (out, ", ext");
4173 if (e_flags & EF_PARISC_LSB)
4174 out = stpcpy (out, ", lsb");
4175 if (e_flags & EF_PARISC_WIDE)
4176 out = stpcpy (out, ", wide");
4177 if (e_flags & EF_PARISC_NO_KABP)
4178 out = stpcpy (out, ", no kabp");
4179 if (e_flags & EF_PARISC_LAZYSWAP)
4180 out = stpcpy (out, ", lazyswap");
4181 return out;
4182}
4183
4184static char *
4185decode_RISCV_machine_flags (char *out, unsigned e_flags)
4186{
4187 if (e_flags & EF_RISCV_RVC)
4188 out = stpcpy (out, ", RVC");
4189
4190 if (e_flags & EF_RISCV_RVE)
4191 out = stpcpy (out, ", RVE");
4192
4193 if (e_flags & EF_RISCV_TSO)
4194 out = stpcpy (out, ", TSO");
4195
4196 switch (e_flags & EF_RISCV_FLOAT_ABI)
4197 {
4198 case EF_RISCV_FLOAT_ABI_SOFT:
4199 out = stpcpy (out, ", soft-float ABI");
4200 break;
4201
4202 case EF_RISCV_FLOAT_ABI_SINGLE:
4203 out = stpcpy (out, ", single-float ABI");
4204 break;
4205
4206 case EF_RISCV_FLOAT_ABI_DOUBLE:
4207 out = stpcpy (out, ", double-float ABI");
4208 break;
4209
4210 case EF_RISCV_FLOAT_ABI_QUAD:
4211 out = stpcpy (out, ", quad-float ABI");
4212 break;
4213 }
4214 return out;
4215}
4216
4217static char *
4218decode_RL78_machine_flags (char *out, unsigned e_flags)
4219{
4220 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4221 {
4222 case E_FLAG_RL78_ANY_CPU:
4223 break;
4224 case E_FLAG_RL78_G10:
4225 out = stpcpy (out, ", G10");
4226 break;
4227 case E_FLAG_RL78_G13:
4228 out = stpcpy (out, ", G13");
4229 break;
4230 case E_FLAG_RL78_G14:
4231 out = stpcpy (out, ", G14");
4232 break;
4233 }
4234 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4235 out = stpcpy (out, ", 64-bit doubles");
4236 return out;
4237}
4238
4239static char *
4240decode_RX_machine_flags (char *out, unsigned e_flags)
4241{
4242 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4243 out = stpcpy (out, ", 64-bit doubles");
4244 if (e_flags & E_FLAG_RX_DSP)
4245 out = stpcpy (out, ", dsp");
4246 if (e_flags & E_FLAG_RX_PID)
4247 out = stpcpy (out, ", pid");
4248 if (e_flags & E_FLAG_RX_ABI)
4249 out = stpcpy (out, ", RX ABI");
4250 if (e_flags & E_FLAG_RX_SINSNS_SET)
4251 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4252 ? ", uses String instructions"
4253 : ", bans String instructions"));
4254 if (e_flags & E_FLAG_RX_V2)
4255 out = stpcpy (out, ", V2");
4256 if (e_flags & E_FLAG_RX_V3)
4257 out = stpcpy (out, ", V3");
4258 return out;
4259}
4260
4261static char *
4262decode_SH_machine_flags (char *out, unsigned e_flags)
4263{
4264 switch ((e_flags & EF_SH_MACH_MASK))
4265 {
4266 case EF_SH1:
4267 out = stpcpy (out, ", sh1");
4268 break;
4269 case EF_SH2:
4270 out = stpcpy (out, ", sh2");
4271 break;
4272 case EF_SH3:
4273 out = stpcpy (out, ", sh3");
4274 break;
4275 case EF_SH_DSP:
4276 out = stpcpy (out, ", sh-dsp");
4277 break;
4278 case EF_SH3_DSP:
4279 out = stpcpy (out, ", sh3-dsp");
4280 break;
4281 case EF_SH4AL_DSP:
4282 out = stpcpy (out, ", sh4al-dsp");
4283 break;
4284 case EF_SH3E:
4285 out = stpcpy (out, ", sh3e");
4286 break;
4287 case EF_SH4:
4288 out = stpcpy (out, ", sh4");
4289 break;
4290 case EF_SH5:
4291 out = stpcpy (out, ", sh5");
4292 break;
4293 case EF_SH2E:
4294 out = stpcpy (out, ", sh2e");
4295 break;
4296 case EF_SH4A:
4297 out = stpcpy (out, ", sh4a");
4298 break;
4299 case EF_SH2A:
4300 out = stpcpy (out, ", sh2a");
4301 break;
4302 case EF_SH4_NOFPU:
4303 out = stpcpy (out, ", sh4-nofpu");
4304 break;
4305 case EF_SH4A_NOFPU:
4306 out = stpcpy (out, ", sh4a-nofpu");
4307 break;
4308 case EF_SH2A_NOFPU:
4309 out = stpcpy (out, ", sh2a-nofpu");
4310 break;
4311 case EF_SH3_NOMMU:
4312 out = stpcpy (out, ", sh3-nommu");
4313 break;
4314 case EF_SH4_NOMMU_NOFPU:
4315 out = stpcpy (out, ", sh4-nommu-nofpu");
4316 break;
4317 case EF_SH2A_SH4_NOFPU:
4318 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4319 break;
4320 case EF_SH2A_SH3_NOFPU:
4321 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4322 break;
4323 case EF_SH2A_SH4:
4324 out = stpcpy (out, ", sh2a-or-sh4");
4325 break;
4326 case EF_SH2A_SH3E:
4327 out = stpcpy (out, ", sh2a-or-sh3e");
4328 break;
4329 default:
4330 out = stpcpy (out, _(", unknown ISA"));
4331 break;
4332 }
4333
4334 if (e_flags & EF_SH_PIC)
4335 out = stpcpy (out, ", pic");
4336
4337 if (e_flags & EF_SH_FDPIC)
4338 out = stpcpy (out, ", fdpic");
4339 return out;
4340}
4341
4342static char *
4343decode_SPARC_machine_flags (char *out, unsigned e_flags)
4344{
4345 if (e_flags & EF_SPARC_32PLUS)
4346 out = stpcpy (out, ", v8+");
4347
4348 if (e_flags & EF_SPARC_SUN_US1)
4349 out = stpcpy (out, ", ultrasparcI");
4350
4351 if (e_flags & EF_SPARC_SUN_US3)
4352 out = stpcpy (out, ", ultrasparcIII");
4353
4354 if (e_flags & EF_SPARC_HAL_R1)
4355 out = stpcpy (out, ", halr1");
4356
4357 if (e_flags & EF_SPARC_LEDATA)
4358 out = stpcpy (out, ", ledata");
4359
4360 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4361 out = stpcpy (out, ", tso");
4362
4363 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4364 out = stpcpy (out, ", pso");
4365
4366 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4367 out = stpcpy (out, ", rmo");
4368 return out;
4369}
4370
4371static char *
4372decode_V800_machine_flags (char *out, unsigned int e_flags)
4373{
4374 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4375 out = stpcpy (out, ", RH850 ABI");
4376
4377 if (e_flags & EF_V800_850E3)
4378 out = stpcpy (out, ", V3 architecture");
4379
4380 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4381 out = stpcpy (out, ", FPU not used");
4382
4383 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4384 out = stpcpy (out, ", regmode: COMMON");
4385
4386 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4387 out = stpcpy (out, ", r4 not used");
4388
4389 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4390 out = stpcpy (out, ", r30 not used");
4391
4392 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4393 out = stpcpy (out, ", r5 not used");
4394
4395 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4396 out = stpcpy (out, ", r2 not used");
4397
4398 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4399 {
4400 switch (e_flags & - e_flags)
4401 {
4402 case EF_RH850_FPU_DOUBLE:
4403 out = stpcpy (out, ", double precision FPU");
4404 break;
4405 case EF_RH850_FPU_SINGLE:
4406 out = stpcpy (out, ", single precision FPU");
4407 break;
4408 case EF_RH850_REGMODE22:
4409 out = stpcpy (out, ", regmode:22");
4410 break;
4411 case EF_RH850_REGMODE32:
4412 out = stpcpy (out, ", regmode:23");
4413 break;
4414 case EF_RH850_GP_FIX:
4415 out = stpcpy (out, ", r4 fixed");
4416 break;
4417 case EF_RH850_GP_NOFIX:
4418 out = stpcpy (out, ", r4 free");
4419 break;
4420 case EF_RH850_EP_FIX:
4421 out = stpcpy (out, ", r30 fixed");
4422 break;
4423 case EF_RH850_EP_NOFIX:
4424 out = stpcpy (out, ", r30 free");
4425 break;
4426 case EF_RH850_TP_FIX:
4427 out = stpcpy (out, ", r5 fixed");
4428 break;
4429 case EF_RH850_TP_NOFIX:
4430 out = stpcpy (out, ", r5 free");
4431 break;
4432 case EF_RH850_REG2_RESERVE:
4433 out = stpcpy (out, ", r2 fixed");
4434 break;
4435 case EF_RH850_REG2_NORESERVE:
4436 out = stpcpy (out, ", r2 free");
4437 break;
4438 default:
4439 break;
4440 }
4441 }
4442 return out;
4443}
4444
4445static char *
4446decode_V850_machine_flags (char *out, unsigned int e_flags)
4447{
4448 switch (e_flags & EF_V850_ARCH)
4449 {
4450 case E_V850E3V5_ARCH:
4451 out = stpcpy (out, ", v850e3v5");
4452 break;
4453 case E_V850E2V3_ARCH:
4454 out = stpcpy (out, ", v850e2v3");
4455 break;
4456 case E_V850E2_ARCH:
4457 out = stpcpy (out, ", v850e2");
4458 break;
4459 case E_V850E1_ARCH:
4460 out = stpcpy (out, ", v850e1");
4461 break;
4462 case E_V850E_ARCH:
4463 out = stpcpy (out, ", v850e");
4464 break;
4465 case E_V850_ARCH:
4466 out = stpcpy (out, ", v850");
4467 break;
4468 default:
4469 out = stpcpy (out, _(", unknown v850 architecture variant"));
4470 break;
4471 }
4472 return out;
4473}
4474
4475static char *
4476decode_Z80_machine_flags (char *out, unsigned int e_flags)
4477{
4478 switch (e_flags & EF_Z80_MACH_MSK)
4479 {
4480 case EF_Z80_MACH_Z80:
4481 out = stpcpy (out, ", Z80");
4482 break;
4483 case EF_Z80_MACH_Z180:
4484 out = stpcpy (out, ", Z180");
4485 break;
4486 case EF_Z80_MACH_R800:
4487 out = stpcpy (out, ", R800");
4488 break;
4489 case EF_Z80_MACH_EZ80_Z80:
4490 out = stpcpy (out, ", EZ80");
4491 break;
4492 case EF_Z80_MACH_EZ80_ADL:
4493 out = stpcpy (out, ", EZ80, ADL");
4494 break;
4495 case EF_Z80_MACH_GBZ80:
4496 out = stpcpy (out, ", GBZ80");
4497 break;
4498 case EF_Z80_MACH_Z80N:
4499 out = stpcpy (out, ", Z80N");
4500 break;
4501 default:
4502 out = stpcpy (out, _(", unknown"));
4503 break;
4504 }
4505 return out;
4506}
4507
4508static char *
4509decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4510{
4511 unsigned char *e_ident = filedata->file_header.e_ident;
4512 unsigned char osabi = e_ident[EI_OSABI];
4513 unsigned char abiversion = e_ident[EI_ABIVERSION];
4514 unsigned int mach;
4515
4516 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4517 it has been deprecated for a while.
4518
4519 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4520 of writing, they use the same flags as HSA v3, so the code below uses that
4521 assumption. */
4522 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4523 return out;
c077c580
SM
4524
4525 mach = e_flags & EF_AMDGPU_MACH;
4526 switch (mach)
4527 {
4528#define AMDGPU_CASE(code, string) \
f8c4789c 4529 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4530 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4531 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4532 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4533 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4534 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4535 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4536 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4537 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4538 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4539 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4540 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4541 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4542 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4543 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4544 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4545 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4546 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4547 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4548 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4549 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4550 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4551 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4552 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4553 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4554 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
a7a0cb6c
SM
4555 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4556 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4557 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
c077c580
SM
4558 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4559 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4560 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4564 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4565 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4566 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4567 default:
f8c4789c 4568 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4569 break;
4570#undef AMDGPU_CASE
4571 }
4572
c077c580
SM
4573 e_flags &= ~EF_AMDGPU_MACH;
4574
4575 if ((osabi == ELFOSABI_AMDGPU_HSA
4576 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4577 || osabi != ELFOSABI_AMDGPU_HSA)
4578 {
4579 /* For HSA v3 and other OS ABIs. */
4580 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4581 {
f8c4789c 4582 out = stpcpy (out, ", xnack on");
c077c580
SM
4583 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4584 }
4585
4586 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4587 {
f8c4789c 4588 out = stpcpy (out, ", sramecc on");
c077c580
SM
4589 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4590 }
4591 }
4592 else
4593 {
4594 /* For HSA v4+. */
4595 int xnack, sramecc;
4596
4597 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4598 switch (xnack)
4599 {
4600 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4601 break;
4602
4603 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4604 out = stpcpy (out, ", xnack any");
c077c580
SM
4605 break;
4606
4607 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4608 out = stpcpy (out, ", xnack off");
c077c580
SM
4609 break;
4610
4611 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4612 out = stpcpy (out, ", xnack on");
c077c580
SM
4613 break;
4614
4615 default:
f8c4789c 4616 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4617 break;
4618 }
4619
c077c580
SM
4620 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4621
4622 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4623 switch (sramecc)
4624 {
4625 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4626 break;
4627
4628 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4629 out = stpcpy (out, ", sramecc any");
c077c580
SM
4630 break;
4631
4632 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4633 out = stpcpy (out, ", sramecc off");
c077c580
SM
4634 break;
4635
4636 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4637 out = stpcpy (out, ", sramecc on");
c077c580
SM
4638 break;
4639
4640 default:
f8c4789c 4641 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4642 break;
4643 }
4644
c077c580
SM
4645 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4646 }
4647
4648 if (e_flags != 0)
f8c4789c
AM
4649 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4650 return out;
c077c580
SM
4651}
4652
252b5132 4653static char *
dda8d76d 4654get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4655{
b34976b6 4656 static char buf[1024];
f8c4789c 4657 char *out = buf;
252b5132
RH
4658
4659 buf[0] = '\0';
76da6bbe 4660
252b5132
RH
4661 if (e_flags)
4662 {
4663 switch (e_machine)
4664 {
4665 default:
4666 break;
4667
b5c37946 4668 case EM_ARC_COMPACT3:
f8c4789c 4669 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4670 break;
4671
4672 case EM_ARC_COMPACT3_64:
f8c4789c 4673 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4674 break;
4675
886a2506 4676 case EM_ARC_COMPACT2:
886a2506 4677 case EM_ARC_COMPACT:
f8c4789c
AM
4678 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4679 break;
886a2506 4680
f3485b74 4681 case EM_ARM:
f8c4789c 4682 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4683 break;
76da6bbe 4684
f8c4789c
AM
4685 case EM_AVR:
4686 out = decode_AVR_machine_flags (out, e_flags);
4687 break;
343433df 4688
781303ce 4689 case EM_BLACKFIN:
f8c4789c 4690 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4691 break;
4692
ec2dfb42 4693 case EM_CYGNUS_FRV:
f8c4789c 4694 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4695 break;
ec2dfb42 4696
53c7db4b 4697 case EM_68K:
f8c4789c 4698 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4699 break;
33c63f9d 4700
c077c580 4701 case EM_AMDGPU:
f8c4789c 4702 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4703 break;
4704
153a2776 4705 case EM_CYGNUS_MEP:
f8c4789c 4706 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4707 break;
4708
252b5132
RH
4709 case EM_PPC:
4710 if (e_flags & EF_PPC_EMB)
f8c4789c 4711 out = stpcpy (out, ", emb");
252b5132
RH
4712
4713 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4714 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4715
4716 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4717 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4718 break;
4719
ee67d69a
AM
4720 case EM_PPC64:
4721 if (e_flags & EF_PPC64_ABI)
f8c4789c 4722 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4723 break;
4724
708e2187 4725 case EM_V800:
f8c4789c 4726 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4727 break;
4728
2b0337b0 4729 case EM_V850:
252b5132 4730 case EM_CYGNUS_V850:
f8c4789c 4731 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4732 break;
4733
2b0337b0 4734 case EM_M32R:
252b5132
RH
4735 case EM_CYGNUS_M32R:
4736 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4737 out = stpcpy (out, ", m32r");
252b5132
RH
4738 break;
4739
4740 case EM_MIPS:
4fe85591 4741 case EM_MIPS_RS3_LE:
f8c4789c 4742 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4743 break;
351b4b40 4744
35c08157 4745 case EM_NDS32:
f8c4789c 4746 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4747 break;
4748
fe944acf
FT
4749 case EM_NFP:
4750 switch (EF_NFP_MACH (e_flags))
4751 {
4752 case E_NFP_MACH_3200:
f8c4789c 4753 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4754 break;
4755 case E_NFP_MACH_6000:
f8c4789c 4756 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4757 break;
4758 }
4759 break;
4760
e23eba97 4761 case EM_RISCV:
f8c4789c 4762 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4763 break;
4764
ccde1100 4765 case EM_SH:
f8c4789c 4766 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4767 break;
948f632f 4768
f8c4789c
AM
4769 case EM_OR1K:
4770 if (e_flags & EF_OR1K_NODELAY)
4771 out = stpcpy (out, ", no delay");
4772 break;
57346661 4773
f8c4789c
AM
4774 case EM_BPF:
4775 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4776 break;
b5c37946 4777
351b4b40 4778 case EM_SPARCV9:
f8c4789c 4779 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4780 break;
7d466069 4781
103f02d3 4782 case EM_PARISC:
f8c4789c 4783 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4784 break;
76da6bbe 4785
7d466069 4786 case EM_PJ:
2b0337b0 4787 case EM_PJ_OLD:
7d466069 4788 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4789 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4790
4791 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4792 out = stpcpy (out, ", gnu calling convention");
7d466069 4793 break;
4d6ed7c8
NC
4794
4795 case EM_IA_64:
f8c4789c 4796 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4797 break;
179d3252
JT
4798
4799 case EM_VAX:
4800 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4801 out = stpcpy (out, ", non-PIC");
179d3252 4802 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4803 out = stpcpy (out, ", D-Float");
179d3252 4804 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4805 out = stpcpy (out, ", G-Float");
179d3252 4806 break;
c7927a3c 4807
f8c4789c 4808 case EM_VISIUM:
619ed720 4809 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4810 out = stpcpy (out, ", mcm");
619ed720 4811 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4812 out = stpcpy (out, ", mcm24");
619ed720 4813 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4814 out = stpcpy (out, ", gr6");
619ed720
EB
4815 break;
4816
4046d87a 4817 case EM_RL78:
f8c4789c 4818 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4819 break;
0b4362b0 4820
c7927a3c 4821 case EM_RX:
f8c4789c 4822 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4823 break;
55786da2
AK
4824
4825 case EM_S390:
4826 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4827 out = stpcpy (out, ", highgprs");
d4cb0ea0 4828 break;
40b36596
JM
4829
4830 case EM_TI_C6000:
4831 if ((e_flags & EF_C6000_REL))
f8c4789c 4832 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4833 break;
13761a11 4834
6e712424
PI
4835 case EM_KVX:
4836 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4837 strcat (buf, ", Kalray VLIW kv3-1");
4838 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4839 strcat (buf, ", Kalray VLIW kv3-2");
4840 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4841 strcat (buf, ", Kalray VLIW kv4-1");
4842 else
4843 strcat (buf, ", unknown KVX MPPA");
4844 break;
4845
13761a11 4846 case EM_MSP430:
f8c4789c 4847 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4848 break;
4849
4850 case EM_Z80:
f8c4789c 4851 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4852 break;
c4a7e6b5 4853
f8c4789c
AM
4854 case EM_LOONGARCH:
4855 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4856 break;
252b5132
RH
4857 }
4858 }
4859
4860 return buf;
4861}
4862
252b5132 4863static const char *
dda8d76d 4864get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4865{
4866 static char buff[32];
4867
4868 switch (osabi)
4869 {
4870 case ELFOSABI_NONE: return "UNIX - System V";
4871 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4872 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4873 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4874 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4875 case ELFOSABI_AIX: return "UNIX - AIX";
4876 case ELFOSABI_IRIX: return "UNIX - IRIX";
4877 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4878 case ELFOSABI_TRU64: return "UNIX - TRU64";
4879 case ELFOSABI_MODESTO: return "Novell - Modesto";
4880 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4881 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4882 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4883 case ELFOSABI_AROS: return "AROS";
11636f9e 4884 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4885 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4886 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4887 default:
40b36596 4888 if (osabi >= 64)
dda8d76d 4889 switch (filedata->file_header.e_machine)
40b36596 4890 {
37870be8
SM
4891 case EM_AMDGPU:
4892 switch (osabi)
4893 {
4894 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4895 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4896 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4897 default:
4898 break;
4899 }
4900 break;
4901
40b36596
JM
4902 case EM_ARM:
4903 switch (osabi)
4904 {
4905 case ELFOSABI_ARM: return "ARM";
18a20338 4906 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4907 default:
4908 break;
4909 }
4910 break;
4911
4912 case EM_MSP430:
4913 case EM_MSP430_OLD:
619ed720 4914 case EM_VISIUM:
40b36596
JM
4915 switch (osabi)
4916 {
4917 case ELFOSABI_STANDALONE: return _("Standalone App");
4918 default:
4919 break;
4920 }
4921 break;
4922
4923 case EM_TI_C6000:
4924 switch (osabi)
4925 {
4926 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4927 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4928 default:
4929 break;
4930 }
4931 break;
4932
4933 default:
4934 break;
4935 }
e9e44622 4936 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4937 return buff;
4938 }
4939}
4940
a06ea964
NC
4941static const char *
4942get_aarch64_segment_type (unsigned long type)
4943{
4944 switch (type)
4945 {
32ec8896 4946 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4947 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4948 default: return NULL;
a06ea964 4949 }
a06ea964
NC
4950}
4951
b294bdf8
MM
4952static const char *
4953get_arm_segment_type (unsigned long type)
4954{
4955 switch (type)
4956 {
32ec8896
NC
4957 case PT_ARM_EXIDX: return "EXIDX";
4958 default: return NULL;
b294bdf8 4959 }
b294bdf8
MM
4960}
4961
b4cbbe8f
AK
4962static const char *
4963get_s390_segment_type (unsigned long type)
4964{
4965 switch (type)
4966 {
4967 case PT_S390_PGSTE: return "S390_PGSTE";
4968 default: return NULL;
4969 }
4970}
4971
d3ba0551
AM
4972static const char *
4973get_mips_segment_type (unsigned long type)
252b5132
RH
4974{
4975 switch (type)
4976 {
32ec8896
NC
4977 case PT_MIPS_REGINFO: return "REGINFO";
4978 case PT_MIPS_RTPROC: return "RTPROC";
4979 case PT_MIPS_OPTIONS: return "OPTIONS";
4980 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4981 default: return NULL;
252b5132 4982 }
252b5132
RH
4983}
4984
103f02d3 4985static const char *
d3ba0551 4986get_parisc_segment_type (unsigned long type)
103f02d3
UD
4987{
4988 switch (type)
4989 {
103f02d3
UD
4990 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4991 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4992 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4993 default: return NULL;
103f02d3 4994 }
103f02d3
UD
4995}
4996
4d6ed7c8 4997static const char *
d3ba0551 4998get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4999{
5000 switch (type)
5001 {
5002 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5003 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5004 default: return NULL;
4d6ed7c8 5005 }
4d6ed7c8
NC
5006}
5007
40b36596
JM
5008static const char *
5009get_tic6x_segment_type (unsigned long type)
5010{
5011 switch (type)
5012 {
32ec8896
NC
5013 case PT_C6000_PHATTR: return "C6000_PHATTR";
5014 default: return NULL;
40b36596 5015 }
40b36596
JM
5016}
5017
fbc95f1e
KC
5018static const char *
5019get_riscv_segment_type (unsigned long type)
5020{
5021 switch (type)
5022 {
5023 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5024 default: return NULL;
5025 }
5026}
5027
df3a023b
AM
5028static const char *
5029get_hpux_segment_type (unsigned long type, unsigned e_machine)
5030{
5031 if (e_machine == EM_PARISC)
5032 switch (type)
5033 {
5034 case PT_HP_TLS: return "HP_TLS";
5035 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5036 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5037 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5038 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5039 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5040 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5041 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5042 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5043 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5044 case PT_HP_PARALLEL: return "HP_PARALLEL";
5045 case PT_HP_FASTBIND: return "HP_FASTBIND";
5046 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5047 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5048 case PT_HP_STACK: return "HP_STACK";
5049 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5050 default: return NULL;
5051 }
5052
5053 if (e_machine == EM_IA_64)
5054 switch (type)
5055 {
5056 case PT_HP_TLS: return "HP_TLS";
5057 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5058 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5059 case PT_IA_64_HP_STACK: return "HP_STACK";
5060 default: return NULL;
5061 }
5062
5063 return NULL;
5064}
5065
5522f910
NC
5066static const char *
5067get_solaris_segment_type (unsigned long type)
5068{
5069 switch (type)
5070 {
5071 case 0x6464e550: return "PT_SUNW_UNWIND";
5072 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5073 case 0x6ffffff7: return "PT_LOSUNW";
5074 case 0x6ffffffa: return "PT_SUNWBSS";
5075 case 0x6ffffffb: return "PT_SUNWSTACK";
5076 case 0x6ffffffc: return "PT_SUNWDTRACE";
5077 case 0x6ffffffd: return "PT_SUNWCAP";
5078 case 0x6fffffff: return "PT_HISUNW";
32ec8896 5079 default: return NULL;
5522f910
NC
5080 }
5081}
5082
252b5132 5083static const char *
dda8d76d 5084get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5085{
b34976b6 5086 static char buff[32];
252b5132
RH
5087
5088 switch (p_type)
5089 {
b34976b6
AM
5090 case PT_NULL: return "NULL";
5091 case PT_LOAD: return "LOAD";
252b5132 5092 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5093 case PT_INTERP: return "INTERP";
5094 case PT_NOTE: return "NOTE";
5095 case PT_SHLIB: return "SHLIB";
5096 case PT_PHDR: return "PHDR";
13ae64f3 5097 case PT_TLS: return "TLS";
32ec8896 5098 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5099 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5100 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5101 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5102 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5103
80251d41 5104 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5105 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5106 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
73b22419 5107 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
d86205c3 5108 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
3eba3ef3 5109 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5110
252b5132 5111 default:
df3a023b 5112 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5113 {
2cf0635d 5114 const char * result;
103f02d3 5115
dda8d76d 5116 switch (filedata->file_header.e_machine)
252b5132 5117 {
a06ea964
NC
5118 case EM_AARCH64:
5119 result = get_aarch64_segment_type (p_type);
5120 break;
b294bdf8
MM
5121 case EM_ARM:
5122 result = get_arm_segment_type (p_type);
5123 break;
252b5132 5124 case EM_MIPS:
4fe85591 5125 case EM_MIPS_RS3_LE:
252b5132
RH
5126 result = get_mips_segment_type (p_type);
5127 break;
103f02d3
UD
5128 case EM_PARISC:
5129 result = get_parisc_segment_type (p_type);
5130 break;
4d6ed7c8
NC
5131 case EM_IA_64:
5132 result = get_ia64_segment_type (p_type);
5133 break;
40b36596
JM
5134 case EM_TI_C6000:
5135 result = get_tic6x_segment_type (p_type);
5136 break;
b4cbbe8f
AK
5137 case EM_S390:
5138 case EM_S390_OLD:
5139 result = get_s390_segment_type (p_type);
5140 break;
fbc95f1e
KC
5141 case EM_RISCV:
5142 result = get_riscv_segment_type (p_type);
5143 break;
252b5132
RH
5144 default:
5145 result = NULL;
5146 break;
5147 }
103f02d3 5148
252b5132
RH
5149 if (result != NULL)
5150 return result;
103f02d3 5151
1a9ccd70 5152 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5153 }
5154 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5155 {
df3a023b 5156 const char * result = NULL;
103f02d3 5157
df3a023b 5158 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5159 {
df3a023b
AM
5160 case ELFOSABI_GNU:
5161 case ELFOSABI_FREEBSD:
5162 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5163 {
5164 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5165 result = buff;
5166 }
103f02d3 5167 break;
df3a023b
AM
5168 case ELFOSABI_HPUX:
5169 result = get_hpux_segment_type (p_type,
5170 filedata->file_header.e_machine);
5171 break;
5172 case ELFOSABI_SOLARIS:
5173 result = get_solaris_segment_type (p_type);
00428cca 5174 break;
103f02d3 5175 default:
103f02d3
UD
5176 break;
5177 }
103f02d3
UD
5178 if (result != NULL)
5179 return result;
5180
1a9ccd70 5181 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5182 }
252b5132 5183 else
e9e44622 5184 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5185
5186 return buff;
5187 }
5188}
5189
53a346d8
CZ
5190static const char *
5191get_arc_section_type_name (unsigned int sh_type)
5192{
5193 switch (sh_type)
5194 {
5195 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5196 default:
5197 break;
5198 }
5199 return NULL;
5200}
5201
252b5132 5202static const char *
d3ba0551 5203get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5204{
5205 switch (sh_type)
5206 {
b34976b6
AM
5207 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5208 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5209 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5210 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5211 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5212 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5213 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5214 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5215 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5216 case SHT_MIPS_RELD: return "MIPS_RELD";
5217 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5218 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5219 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5220 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5221 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5222 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5223 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5224 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5225 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5226 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5227 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5228 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5229 case SHT_MIPS_LINE: return "MIPS_LINE";
5230 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5231 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5232 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5233 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5234 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5235 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5236 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5237 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5238 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5239 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5240 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5241 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5242 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5243 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5244 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5245 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5246 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5247 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5248 default:
5249 break;
5250 }
5251 return NULL;
5252}
5253
103f02d3 5254static const char *
d3ba0551 5255get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5256{
5257 switch (sh_type)
5258 {
5259 case SHT_PARISC_EXT: return "PARISC_EXT";
5260 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5261 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5262 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5263 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5264 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5265 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5266 default: return NULL;
103f02d3 5267 }
103f02d3
UD
5268}
5269
4d6ed7c8 5270static const char *
dda8d76d 5271get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5272{
18bd398b 5273 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5274 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5275 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5276
4d6ed7c8
NC
5277 switch (sh_type)
5278 {
148b93f2
NC
5279 case SHT_IA_64_EXT: return "IA_64_EXT";
5280 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5281 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5282 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5283 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5284 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5285 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5286 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5287 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5288 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5289 default:
5290 break;
5291 }
5292 return NULL;
5293}
5294
d2b2c203
DJ
5295static const char *
5296get_x86_64_section_type_name (unsigned int sh_type)
5297{
5298 switch (sh_type)
5299 {
5300 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5301 default: return NULL;
d2b2c203 5302 }
d2b2c203
DJ
5303}
5304
a06ea964
NC
5305static const char *
5306get_aarch64_section_type_name (unsigned int sh_type)
5307{
5308 switch (sh_type)
5309 {
32ec8896
NC
5310 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5311 default: return NULL;
a06ea964 5312 }
a06ea964
NC
5313}
5314
40a18ebd
NC
5315static const char *
5316get_arm_section_type_name (unsigned int sh_type)
5317{
5318 switch (sh_type)
5319 {
7f6fed87
NC
5320 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5321 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5322 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5323 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5324 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5325 default: return NULL;
40a18ebd 5326 }
40a18ebd
NC
5327}
5328
40b36596
JM
5329static const char *
5330get_tic6x_section_type_name (unsigned int sh_type)
5331{
5332 switch (sh_type)
5333 {
32ec8896
NC
5334 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5335 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5336 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5337 case SHT_TI_ICODE: return "TI_ICODE";
5338 case SHT_TI_XREF: return "TI_XREF";
5339 case SHT_TI_HANDLER: return "TI_HANDLER";
5340 case SHT_TI_INITINFO: return "TI_INITINFO";
5341 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5342 default: return NULL;
40b36596 5343 }
40b36596
JM
5344}
5345
13761a11 5346static const char *
b0191216 5347get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5348{
5349 switch (sh_type)
5350 {
32ec8896
NC
5351 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5352 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5353 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5354 default: return NULL;
13761a11
NC
5355 }
5356}
5357
fe944acf
FT
5358static const char *
5359get_nfp_section_type_name (unsigned int sh_type)
5360{
5361 switch (sh_type)
5362 {
5363 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5364 case SHT_NFP_INITREG: return "NFP_INITREG";
5365 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5366 default: return NULL;
5367 }
5368}
5369
685080f2
NC
5370static const char *
5371get_v850_section_type_name (unsigned int sh_type)
5372{
5373 switch (sh_type)
5374 {
32ec8896
NC
5375 case SHT_V850_SCOMMON: return "V850 Small Common";
5376 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5377 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5378 case SHT_RENESAS_IOP: return "RENESAS IOP";
5379 case SHT_RENESAS_INFO: return "RENESAS INFO";
5380 default: return NULL;
685080f2
NC
5381 }
5382}
5383
2dc8dd17
JW
5384static const char *
5385get_riscv_section_type_name (unsigned int sh_type)
5386{
5387 switch (sh_type)
5388 {
5389 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5390 default: return NULL;
5391 }
5392}
5393
0861f561
CQ
5394static const char *
5395get_csky_section_type_name (unsigned int sh_type)
5396{
5397 switch (sh_type)
5398 {
5399 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5400 default: return NULL;
5401 }
5402}
5403
252b5132 5404static const char *
dda8d76d 5405get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5406{
b34976b6 5407 static char buff[32];
9fb71ee4 5408 const char * result;
252b5132
RH
5409
5410 switch (sh_type)
5411 {
5412 case SHT_NULL: return "NULL";
5413 case SHT_PROGBITS: return "PROGBITS";
5414 case SHT_SYMTAB: return "SYMTAB";
5415 case SHT_STRTAB: return "STRTAB";
5416 case SHT_RELA: return "RELA";
dd207c13 5417 case SHT_RELR: return "RELR";
252b5132
RH
5418 case SHT_HASH: return "HASH";
5419 case SHT_DYNAMIC: return "DYNAMIC";
5420 case SHT_NOTE: return "NOTE";
5421 case SHT_NOBITS: return "NOBITS";
5422 case SHT_REL: return "REL";
5423 case SHT_SHLIB: return "SHLIB";
5424 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
5425 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5426 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5427 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 5428 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 5429 case SHT_GROUP: return "GROUP";
67ce483b 5430 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
5431 case SHT_GNU_verdef: return "VERDEF";
5432 case SHT_GNU_verneed: return "VERNEED";
5433 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
5434 case 0x6ffffff0: return "VERSYM";
5435 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5436 case 0x7ffffffd: return "AUXILIARY";
5437 case 0x7fffffff: return "FILTER";
047b2264 5438 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
5439
5440 default:
5441 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5442 {
dda8d76d 5443 switch (filedata->file_header.e_machine)
252b5132 5444 {
53a346d8
CZ
5445 case EM_ARC:
5446 case EM_ARC_COMPACT:
5447 case EM_ARC_COMPACT2:
b5c37946
SJ
5448 case EM_ARC_COMPACT3:
5449 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5450 result = get_arc_section_type_name (sh_type);
5451 break;
252b5132 5452 case EM_MIPS:
4fe85591 5453 case EM_MIPS_RS3_LE:
252b5132
RH
5454 result = get_mips_section_type_name (sh_type);
5455 break;
103f02d3
UD
5456 case EM_PARISC:
5457 result = get_parisc_section_type_name (sh_type);
5458 break;
4d6ed7c8 5459 case EM_IA_64:
dda8d76d 5460 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5461 break;
d2b2c203 5462 case EM_X86_64:
8a9036a4 5463 case EM_L1OM:
7a9068fe 5464 case EM_K1OM:
d2b2c203
DJ
5465 result = get_x86_64_section_type_name (sh_type);
5466 break;
a06ea964
NC
5467 case EM_AARCH64:
5468 result = get_aarch64_section_type_name (sh_type);
5469 break;
40a18ebd
NC
5470 case EM_ARM:
5471 result = get_arm_section_type_name (sh_type);
5472 break;
40b36596
JM
5473 case EM_TI_C6000:
5474 result = get_tic6x_section_type_name (sh_type);
5475 break;
13761a11 5476 case EM_MSP430:
b0191216 5477 result = get_msp430_section_type_name (sh_type);
13761a11 5478 break;
fe944acf
FT
5479 case EM_NFP:
5480 result = get_nfp_section_type_name (sh_type);
5481 break;
685080f2
NC
5482 case EM_V800:
5483 case EM_V850:
5484 case EM_CYGNUS_V850:
5485 result = get_v850_section_type_name (sh_type);
5486 break;
2dc8dd17
JW
5487 case EM_RISCV:
5488 result = get_riscv_section_type_name (sh_type);
5489 break;
0861f561
CQ
5490 case EM_CSKY:
5491 result = get_csky_section_type_name (sh_type);
5492 break;
252b5132
RH
5493 default:
5494 result = NULL;
5495 break;
5496 }
5497
5498 if (result != NULL)
5499 return result;
5500
9fb71ee4 5501 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5502 }
5503 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5504 {
dda8d76d 5505 switch (filedata->file_header.e_machine)
148b93f2
NC
5506 {
5507 case EM_IA_64:
dda8d76d 5508 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5509 break;
5510 default:
dda8d76d 5511 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5512 result = get_solaris_section_type (sh_type);
5513 else
1b4b80bf
NC
5514 {
5515 switch (sh_type)
5516 {
5517 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5518 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5519 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5520 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5521 default:
5522 result = NULL;
5523 break;
5524 }
5525 }
148b93f2
NC
5526 break;
5527 }
5528
5529 if (result != NULL)
5530 return result;
5531
9fb71ee4 5532 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5533 }
252b5132 5534 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5535 {
dda8d76d 5536 switch (filedata->file_header.e_machine)
685080f2
NC
5537 {
5538 case EM_V800:
5539 case EM_V850:
5540 case EM_CYGNUS_V850:
9fb71ee4 5541 result = get_v850_section_type_name (sh_type);
a9fb83be 5542 break;
685080f2 5543 default:
9fb71ee4 5544 result = NULL;
685080f2
NC
5545 break;
5546 }
5547
9fb71ee4
NC
5548 if (result != NULL)
5549 return result;
5550
5551 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5552 }
252b5132 5553 else
a7dbfd1c
NC
5554 /* This message is probably going to be displayed in a 15
5555 character wide field, so put the hex value first. */
5556 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5557
252b5132
RH
5558 return buff;
5559 }
5560}
5561
79bc120c
NC
5562enum long_option_values
5563{
5564 OPTION_DEBUG_DUMP = 512,
5565 OPTION_DYN_SYMS,
0f03783c 5566 OPTION_LTO_SYMS,
79bc120c
NC
5567 OPTION_DWARF_DEPTH,
5568 OPTION_DWARF_START,
5569 OPTION_DWARF_CHECK,
5570 OPTION_CTF_DUMP,
5571 OPTION_CTF_PARENT,
5572 OPTION_CTF_SYMBOLS,
5573 OPTION_CTF_STRINGS,
42b6953b 5574 OPTION_SFRAME_DUMP,
79bc120c
NC
5575 OPTION_WITH_SYMBOL_VERSIONS,
5576 OPTION_RECURSE_LIMIT,
5577 OPTION_NO_RECURSE_LIMIT,
047c3dbf 5578 OPTION_NO_DEMANGLING,
b6ac461a 5579 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 5580 OPTION_SYM_BASE
79bc120c 5581};
2979dc34 5582
85b1c36d 5583static struct option options[] =
252b5132 5584{
79bc120c
NC
5585 /* Note - This table is alpha-sorted on the 'val'
5586 field in order to make adding new options easier. */
5587 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5588 {"all", no_argument, 0, 'a'},
79bc120c
NC
5589 {"demangle", optional_argument, 0, 'C'},
5590 {"archive-index", no_argument, 0, 'c'},
5591 {"use-dynamic", no_argument, 0, 'D'},
5592 {"dynamic", no_argument, 0, 'd'},
b34976b6 5593 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5594 {"section-groups", no_argument, 0, 'g'},
5595 {"help", no_argument, 0, 'H'},
5596 {"file-header", no_argument, 0, 'h'},
b34976b6 5597 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5598 {"lint", no_argument, 0, 'L'},
5599 {"enable-checks", no_argument, 0, 'L'},
5600 {"program-headers", no_argument, 0, 'l'},
b34976b6 5601 {"segments", no_argument, 0, 'l'},
595cf52e 5602 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5603 {"notes", no_argument, 0, 'n'},
ca0e11aa 5604 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5605 {"string-dump", required_argument, 0, 'p'},
5606 {"relocated-dump", required_argument, 0, 'R'},
5607 {"relocs", no_argument, 0, 'r'},
5608 {"section-headers", no_argument, 0, 'S'},
5609 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5610 {"symbols", no_argument, 0, 's'},
5611 {"syms", no_argument, 0, 's'},
79bc120c
NC
5612 {"silent-truncation",no_argument, 0, 'T'},
5613 {"section-details", no_argument, 0, 't'},
b3aa80b4 5614 {"unicode", required_argument, NULL, 'U'},
09c11c86 5615 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5616 {"version-info", no_argument, 0, 'V'},
5617 {"version", no_argument, 0, 'v'},
5618 {"wide", no_argument, 0, 'W'},
b6ac461a 5619 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 5620 {"hex-dump", required_argument, 0, 'x'},
0e602686 5621 {"decompress", no_argument, 0, 'z'},
252b5132 5622
79bc120c 5623 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 5624 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
5625 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5626 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5627 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5628 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5629 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5630 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5631 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5632 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5633 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5634#ifdef ENABLE_LIBCTF
d344b407 5635 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5636 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5637 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5638 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5639#endif
42b6953b 5640 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5641 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5642
b34976b6 5643 {0, no_argument, 0, 0}
252b5132
RH
5644};
5645
5646static void
2cf0635d 5647usage (FILE * stream)
252b5132 5648{
92f01d61
JM
5649 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5650 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5651 fprintf (stream, _(" Options are:\n"));
5652 fprintf (stream, _("\
5653 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5654 fprintf (stream, _("\
5655 -h --file-header Display the ELF file header\n"));
5656 fprintf (stream, _("\
5657 -l --program-headers Display the program headers\n"));
5658 fprintf (stream, _("\
5659 --segments An alias for --program-headers\n"));
5660 fprintf (stream, _("\
5661 -S --section-headers Display the sections' header\n"));
5662 fprintf (stream, _("\
5663 --sections An alias for --section-headers\n"));
5664 fprintf (stream, _("\
5665 -g --section-groups Display the section groups\n"));
5666 fprintf (stream, _("\
5667 -t --section-details Display the section details\n"));
5668 fprintf (stream, _("\
5669 -e --headers Equivalent to: -h -l -S\n"));
5670 fprintf (stream, _("\
5671 -s --syms Display the symbol table\n"));
5672 fprintf (stream, _("\
5673 --symbols An alias for --syms\n"));
5674 fprintf (stream, _("\
5675 --dyn-syms Display the dynamic symbol table\n"));
5676 fprintf (stream, _("\
5677 --lto-syms Display LTO symbol tables\n"));
5678 fprintf (stream, _("\
047c3dbf
NL
5679 --sym-base=[0|8|10|16] \n\
5680 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5681 mixed (the default), octal, decimal, hexadecimal.\n"));
5682 fprintf (stream, _("\
0d646226
AM
5683 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5684 display_demangler_styles (stream, _("\
5685 STYLE can be "));
d6249f5f
AM
5686 fprintf (stream, _("\
5687 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5688 fprintf (stream, _("\
5689 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5690 fprintf (stream, _("\
5691 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5692 fprintf (stream, _("\
5693 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5694 Display unicode characters as determined by the current locale\n\
5695 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5696 escape sequences, or treat them as invalid and display as\n\
5697 \"{hex sequences}\"\n"));
d6249f5f 5698 fprintf (stream, _("\
b6ac461a
NC
5699 -X --extra-sym-info Display extra information when showing symbols\n"));
5700 fprintf (stream, _("\
5701 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5702 fprintf (stream, _("\
5703 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
5704 fprintf (stream, _("\
5705 -r --relocs Display the relocations (if present)\n"));
5706 fprintf (stream, _("\
5707 -u --unwind Display the unwind info (if present)\n"));
5708 fprintf (stream, _("\
5709 -d --dynamic Display the dynamic section (if present)\n"));
5710 fprintf (stream, _("\
5711 -V --version-info Display the version sections (if present)\n"));
5712 fprintf (stream, _("\
5713 -A --arch-specific Display architecture specific information (if any)\n"));
5714 fprintf (stream, _("\
5715 -c --archive-index Display the symbol/file index in an archive\n"));
5716 fprintf (stream, _("\
5717 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5718 fprintf (stream, _("\
5719 -L --lint|--enable-checks\n\
5720 Display warning messages for possible problems\n"));
5721 fprintf (stream, _("\
09c11c86 5722 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5723 Dump the contents of section <number|name> as bytes\n"));
5724 fprintf (stream, _("\
09c11c86 5725 -p --string-dump=<number|name>\n\
d6249f5f
AM
5726 Dump the contents of section <number|name> as strings\n"));
5727 fprintf (stream, _("\
cf13d699 5728 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5729 Dump the relocated contents of section <number|name>\n"));
5730 fprintf (stream, _("\
5731 -z --decompress Decompress section before dumping it\n"));
5732 fprintf (stream, _("\
5733 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5734 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5735 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5736 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5737 U/=trace_info]\n\
5738 Display the contents of DWARF debug sections\n"));
5739 fprintf (stream, _("\
5740 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5741 debuginfo files\n"));
5742 fprintf (stream, _("\
5743 -P --process-links Display the contents of non-debug sections in separate\n\
5744 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5745#if DEFAULT_FOR_FOLLOW_LINKS
5746 fprintf (stream, _("\
d6249f5f
AM
5747 -wK --debug-dump=follow-links\n\
5748 Follow links to separate debug info files (default)\n"));
5749 fprintf (stream, _("\
5750 -wN --debug-dump=no-follow-links\n\
5751 Do not follow links to separate debug info files\n"));
c46b7066
NC
5752#else
5753 fprintf (stream, _("\
d6249f5f
AM
5754 -wK --debug-dump=follow-links\n\
5755 Follow links to separate debug info files\n"));
5756 fprintf (stream, _("\
5757 -wN --debug-dump=no-follow-links\n\
5758 Do not follow links to separate debug info files\n\
5759 (default)\n"));
bed566bb
NC
5760#endif
5761#if HAVE_LIBDEBUGINFOD
5762 fprintf (stream, _("\
5763 -wD --debug-dump=use-debuginfod\n\
5764 When following links, also query debuginfod servers (default)\n"));
5765 fprintf (stream, _("\
5766 -wE --debug-dump=do-not-use-debuginfod\n\
5767 When following links, do not query debuginfod servers\n"));
c46b7066 5768#endif
fd2f0033 5769 fprintf (stream, _("\
d6249f5f
AM
5770 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5771 fprintf (stream, _("\
5772 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5773#ifdef ENABLE_LIBCTF
7d9813f1 5774 fprintf (stream, _("\
d6249f5f
AM
5775 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5776 fprintf (stream, _("\
80b56fad 5777 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5778 fprintf (stream, _("\
7d9813f1 5779 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5780 Use section <number|name> as the CTF external symtab\n"));
5781 fprintf (stream, _("\
7d9813f1 5782 --ctf-strings=<number|name>\n\
d6249f5f 5783 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5784#endif
42b6953b
IB
5785 fprintf (stream, _("\
5786 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5787
252b5132 5788#ifdef SUPPORT_DISASSEMBLY
92f01d61 5789 fprintf (stream, _("\
09c11c86
NC
5790 -i --instruction-dump=<number|name>\n\
5791 Disassemble the contents of section <number|name>\n"));
252b5132 5792#endif
92f01d61 5793 fprintf (stream, _("\
d6249f5f
AM
5794 -I --histogram Display histogram of bucket list lengths\n"));
5795 fprintf (stream, _("\
5796 -W --wide Allow output width to exceed 80 characters\n"));
5797 fprintf (stream, _("\
5798 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5799 fprintf (stream, _("\
5800 @<file> Read options from <file>\n"));
5801 fprintf (stream, _("\
5802 -H --help Display this information\n"));
5803 fprintf (stream, _("\
8b53311e 5804 -v --version Display the version number of readelf\n"));
1118d252 5805
92f01d61
JM
5806 if (REPORT_BUGS_TO[0] && stream == stdout)
5807 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5808
92f01d61 5809 exit (stream == stdout ? 0 : 1);
252b5132
RH
5810}
5811
18bd398b
NC
5812/* Record the fact that the user wants the contents of section number
5813 SECTION to be displayed using the method(s) encoded as flags bits
5814 in TYPE. Note, TYPE can be zero if we are creating the array for
5815 the first time. */
5816
252b5132 5817static void
6431e409
AM
5818request_dump_bynumber (struct dump_data *dumpdata,
5819 unsigned int section, dump_type type)
252b5132 5820{
6431e409 5821 if (section >= dumpdata->num_dump_sects)
252b5132 5822 {
2cf0635d 5823 dump_type * new_dump_sects;
252b5132 5824
3f5e193b 5825 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5826 sizeof (* new_dump_sects));
252b5132
RH
5827
5828 if (new_dump_sects == NULL)
591a748a 5829 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5830 else
5831 {
6431e409 5832 if (dumpdata->dump_sects)
21b65bac
NC
5833 {
5834 /* Copy current flag settings. */
6431e409
AM
5835 memcpy (new_dump_sects, dumpdata->dump_sects,
5836 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5837
6431e409 5838 free (dumpdata->dump_sects);
21b65bac 5839 }
252b5132 5840
6431e409
AM
5841 dumpdata->dump_sects = new_dump_sects;
5842 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5843 }
5844 }
5845
6431e409
AM
5846 if (dumpdata->dump_sects)
5847 dumpdata->dump_sects[section] |= type;
252b5132
RH
5848}
5849
aef1f6d0
DJ
5850/* Request a dump by section name. */
5851
5852static void
2cf0635d 5853request_dump_byname (const char * section, dump_type type)
aef1f6d0 5854{
2cf0635d 5855 struct dump_list_entry * new_request;
aef1f6d0 5856
3f5e193b
NC
5857 new_request = (struct dump_list_entry *)
5858 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5859 if (!new_request)
591a748a 5860 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5861
5862 new_request->name = strdup (section);
5863 if (!new_request->name)
591a748a 5864 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5865
5866 new_request->type = type;
5867
5868 new_request->next = dump_sects_byname;
5869 dump_sects_byname = new_request;
5870}
5871
cf13d699 5872static inline void
6431e409 5873request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5874{
5875 int section;
5876 char * cp;
5877
015dc7e1 5878 do_dump = true;
cf13d699
NC
5879 section = strtoul (optarg, & cp, 0);
5880
5881 if (! *cp && section >= 0)
6431e409 5882 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5883 else
5884 request_dump_byname (optarg, type);
5885}
5886
252b5132 5887static void
6431e409 5888parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5889{
5890 int c;
5891
5892 if (argc < 2)
92f01d61 5893 usage (stderr);
252b5132
RH
5894
5895 while ((c = getopt_long
b6ac461a 5896 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5897 {
252b5132
RH
5898 switch (c)
5899 {
5900 case 0:
5901 /* Long options. */
5902 break;
5903 case 'H':
92f01d61 5904 usage (stdout);
252b5132
RH
5905 break;
5906
5907 case 'a':
015dc7e1
AM
5908 do_syms = true;
5909 do_reloc = true;
5910 do_unwind = true;
5911 do_dynamic = true;
5912 do_header = true;
5913 do_sections = true;
5914 do_section_groups = true;
5915 do_segments = true;
5916 do_version = true;
5917 do_histogram = true;
5918 do_arch = true;
5919 do_notes = true;
252b5132 5920 break;
79bc120c 5921
f5842774 5922 case 'g':
015dc7e1 5923 do_section_groups = true;
f5842774 5924 break;
5477e8a0 5925 case 't':
595cf52e 5926 case 'N':
015dc7e1
AM
5927 do_sections = true;
5928 do_section_details = true;
595cf52e 5929 break;
252b5132 5930 case 'e':
015dc7e1
AM
5931 do_header = true;
5932 do_sections = true;
5933 do_segments = true;
252b5132 5934 break;
a952a375 5935 case 'A':
015dc7e1 5936 do_arch = true;
a952a375 5937 break;
252b5132 5938 case 'D':
015dc7e1 5939 do_using_dynamic = true;
252b5132
RH
5940 break;
5941 case 'r':
015dc7e1 5942 do_reloc = true;
252b5132 5943 break;
4d6ed7c8 5944 case 'u':
015dc7e1 5945 do_unwind = true;
4d6ed7c8 5946 break;
252b5132 5947 case 'h':
015dc7e1 5948 do_header = true;
252b5132
RH
5949 break;
5950 case 'l':
015dc7e1 5951 do_segments = true;
252b5132
RH
5952 break;
5953 case 's':
015dc7e1 5954 do_syms = true;
252b5132
RH
5955 break;
5956 case 'S':
015dc7e1 5957 do_sections = true;
252b5132
RH
5958 break;
5959 case 'd':
015dc7e1 5960 do_dynamic = true;
252b5132 5961 break;
a952a375 5962 case 'I':
015dc7e1 5963 do_histogram = true;
a952a375 5964 break;
779fe533 5965 case 'n':
015dc7e1 5966 do_notes = true;
779fe533 5967 break;
4145f1d5 5968 case 'c':
015dc7e1 5969 do_archive_index = true;
4145f1d5 5970 break;
1b513401 5971 case 'L':
015dc7e1 5972 do_checks = true;
1b513401 5973 break;
ca0e11aa 5974 case 'P':
015dc7e1
AM
5975 process_links = true;
5976 do_follow_links = true;
e1dbfc17 5977 dump_any_debugging = true;
ca0e11aa 5978 break;
252b5132 5979 case 'x':
6431e409 5980 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5981 break;
09c11c86 5982 case 'p':
6431e409 5983 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5984 break;
5985 case 'R':
6431e409 5986 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5987 break;
0e602686 5988 case 'z':
015dc7e1 5989 decompress_dumps = true;
0e602686 5990 break;
252b5132 5991 case 'w':
0f03783c 5992 if (optarg == NULL)
613ff48b 5993 {
015dc7e1 5994 do_debugging = true;
94585d6d
NC
5995 do_dump = true;
5996 dump_any_debugging = true;
613ff48b
CC
5997 dwarf_select_sections_all ();
5998 }
252b5132
RH
5999 else
6000 {
015dc7e1 6001 do_debugging = false;
94585d6d
NC
6002 if (dwarf_select_sections_by_letters (optarg))
6003 {
6004 do_dump = true;
6005 dump_any_debugging = true;
6006 }
252b5132
RH
6007 }
6008 break;
2979dc34 6009 case OPTION_DEBUG_DUMP:
0f03783c 6010 if (optarg == NULL)
d6249f5f 6011 {
94585d6d 6012 do_dump = true;
d6249f5f 6013 do_debugging = true;
94585d6d 6014 dump_any_debugging = true;
d6249f5f
AM
6015 dwarf_select_sections_all ();
6016 }
2979dc34
JJ
6017 else
6018 {
015dc7e1 6019 do_debugging = false;
94585d6d
NC
6020 if (dwarf_select_sections_by_names (optarg))
6021 {
6022 do_dump = true;
6023 dump_any_debugging = true;
6024 }
2979dc34
JJ
6025 }
6026 break;
fd2f0033
TT
6027 case OPTION_DWARF_DEPTH:
6028 {
6029 char *cp;
6030
6031 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6032 }
6033 break;
6034 case OPTION_DWARF_START:
6035 {
6036 char *cp;
6037
6038 dwarf_start_die = strtoul (optarg, & cp, 0);
6039 }
6040 break;
4723351a 6041 case OPTION_DWARF_CHECK:
015dc7e1 6042 dwarf_check = true;
4723351a 6043 break;
7d9813f1 6044 case OPTION_CTF_DUMP:
015dc7e1 6045 do_ctf = true;
6431e409 6046 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6047 break;
6048 case OPTION_CTF_SYMBOLS:
df16e041 6049 free (dump_ctf_symtab_name);
7d9813f1
NA
6050 dump_ctf_symtab_name = strdup (optarg);
6051 break;
6052 case OPTION_CTF_STRINGS:
df16e041 6053 free (dump_ctf_strtab_name);
7d9813f1
NA
6054 dump_ctf_strtab_name = strdup (optarg);
6055 break;
6056 case OPTION_CTF_PARENT:
df16e041 6057 free (dump_ctf_parent_name);
7d9813f1
NA
6058 dump_ctf_parent_name = strdup (optarg);
6059 break;
42b6953b
IB
6060 case OPTION_SFRAME_DUMP:
6061 do_sframe = true;
6062 /* Providing section name is optional. request_dump (), however,
6063 thrives on non NULL optarg. Handle it explicitly here. */
6064 if (optarg != NULL)
6065 request_dump (dumpdata, SFRAME_DUMP);
6066 else
6067 {
6068 do_dump = true;
6069 const char *sframe_sec_name = strdup (".sframe");
6070 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6071 }
6072 break;
2c610e4b 6073 case OPTION_DYN_SYMS:
015dc7e1 6074 do_dyn_syms = true;
2c610e4b 6075 break;
0f03783c 6076 case OPTION_LTO_SYMS:
015dc7e1 6077 do_lto_syms = true;
0f03783c 6078 break;
b6ac461a
NC
6079 case 'X':
6080 extra_sym_info = true;
6081 break;
6082 case OPTION_NO_EXTRA_SYM_INFO:
6083 extra_sym_info = false;
6084 break;
6085
252b5132
RH
6086#ifdef SUPPORT_DISASSEMBLY
6087 case 'i':
6431e409 6088 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6089 break;
252b5132
RH
6090#endif
6091 case 'v':
6092 print_version (program_name);
6093 break;
6094 case 'V':
015dc7e1 6095 do_version = true;
252b5132 6096 break;
d974e256 6097 case 'W':
015dc7e1 6098 do_wide = true;
d974e256 6099 break;
0942c7ab 6100 case 'T':
015dc7e1 6101 do_not_show_symbol_truncation = true;
0942c7ab 6102 break;
79bc120c 6103 case 'C':
015dc7e1 6104 do_demangle = true;
79bc120c
NC
6105 if (optarg != NULL)
6106 {
6107 enum demangling_styles style;
6108
6109 style = cplus_demangle_name_to_style (optarg);
6110 if (style == unknown_demangling)
6111 error (_("unknown demangling style `%s'"), optarg);
6112
6113 cplus_demangle_set_style (style);
6114 }
6115 break;
6116 case OPTION_NO_DEMANGLING:
015dc7e1 6117 do_demangle = false;
79bc120c
NC
6118 break;
6119 case OPTION_RECURSE_LIMIT:
6120 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6121 break;
6122 case OPTION_NO_RECURSE_LIMIT:
6123 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6124 break;
6125 case OPTION_WITH_SYMBOL_VERSIONS:
6126 /* Ignored for backward compatibility. */
6127 break;
b9e920ec 6128
b3aa80b4
NC
6129 case 'U':
6130 if (optarg == NULL)
6131 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6132 else if (streq (optarg, "default") || streq (optarg, "d"))
6133 unicode_display = unicode_default;
6134 else if (streq (optarg, "locale") || streq (optarg, "l"))
6135 unicode_display = unicode_locale;
6136 else if (streq (optarg, "escape") || streq (optarg, "e"))
6137 unicode_display = unicode_escape;
6138 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6139 unicode_display = unicode_invalid;
6140 else if (streq (optarg, "hex") || streq (optarg, "x"))
6141 unicode_display = unicode_hex;
6142 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6143 unicode_display = unicode_highlight;
6144 else
6145 error (_("invalid argument to -U/--unicode: %s"), optarg);
6146 break;
6147
047c3dbf
NL
6148 case OPTION_SYM_BASE:
6149 sym_base = 0;
6150 if (optarg != NULL)
6151 {
6152 sym_base = strtoul (optarg, NULL, 0);
6153 switch (sym_base)
6154 {
6155 case 0:
6156 case 8:
6157 case 10:
6158 case 16:
6159 break;
6160
6161 default:
6162 sym_base = 0;
6163 break;
6164 }
6165 }
6166 break;
6167
252b5132 6168 default:
252b5132
RH
6169 /* xgettext:c-format */
6170 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6171 /* Fall through. */
252b5132 6172 case '?':
92f01d61 6173 usage (stderr);
252b5132
RH
6174 }
6175 }
6176
4d6ed7c8 6177 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6178 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6179 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6180 && !do_section_groups && !do_archive_index
0f03783c 6181 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6182 {
6183 if (do_checks)
6184 {
015dc7e1
AM
6185 check_all = true;
6186 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6187 do_segments = do_header = do_dump = do_version = true;
6188 do_histogram = do_debugging = do_arch = do_notes = true;
6189 do_section_groups = do_archive_index = do_dyn_syms = true;
6190 do_lto_syms = true;
1b513401
NC
6191 }
6192 else
6193 usage (stderr);
6194 }
252b5132
RH
6195}
6196
6197static const char *
d3ba0551 6198get_elf_class (unsigned int elf_class)
252b5132 6199{
b34976b6 6200 static char buff[32];
103f02d3 6201
252b5132
RH
6202 switch (elf_class)
6203 {
6204 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6205 case ELFCLASS32: return "ELF32";
6206 case ELFCLASS64: return "ELF64";
ab5e7794 6207 default:
e9e44622 6208 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6209 return buff;
252b5132
RH
6210 }
6211}
6212
6213static const char *
d3ba0551 6214get_data_encoding (unsigned int encoding)
252b5132 6215{
b34976b6 6216 static char buff[32];
103f02d3 6217
252b5132
RH
6218 switch (encoding)
6219 {
6220 case ELFDATANONE: return _("none");
33c63f9d
CM
6221 case ELFDATA2LSB: return _("2's complement, little endian");
6222 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6223 default:
e9e44622 6224 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6225 return buff;
252b5132
RH
6226 }
6227}
6228
521f7268
NC
6229static bool
6230check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6231{
6232 if (header->e_ident[EI_MAG0] == ELFMAG0
6233 && header->e_ident[EI_MAG1] == ELFMAG1
6234 && header->e_ident[EI_MAG2] == ELFMAG2
6235 && header->e_ident[EI_MAG3] == ELFMAG3)
6236 return true;
6237
6238 /* Some compilers produce object files that are not in the ELF file format.
6239 As an aid to users of readelf, try to identify these cases and suggest
6240 alternative tools.
6241
6242 FIXME: It is not clear if all four bytes are used as constant magic
6243 valus by all compilers. It may be necessary to recode this function if
6244 different tools use different length sequences. */
6245
6246 static struct
6247 {
6248 unsigned char magic[4];
6249 const char * obj_message;
6250 const char * ar_message;
6251 }
6252 known_magic[] =
6253 {
6254 { { 'B', 'C', 0xc0, 0xde },
6255 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6256 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6257 },
6258 { { 'g', 'o', ' ', 'o' },
6259 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6260 NULL
6261 }
6262 };
6263 int i;
6264
6265 for (i = ARRAY_SIZE (known_magic); i--;)
6266 {
6267 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6268 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6269 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6270 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6271 {
6272 /* Some compiler's analyzer tools do not handle archives,
6273 so we provide two different kinds of error message. */
6274 if (filedata->archive_file_size > 0
6275 && known_magic[i].ar_message != NULL)
b3ea2010 6276 error ("%s", known_magic[i].ar_message);
521f7268 6277 else
b3ea2010 6278 error ("%s", known_magic[i].obj_message);
521f7268
NC
6279 return false;
6280 }
6281 }
6282
6283 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6284 return false;
6285}
6286
dda8d76d 6287/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6288
015dc7e1 6289static bool
dda8d76d 6290process_file_header (Filedata * filedata)
252b5132 6291{
dda8d76d
NC
6292 Elf_Internal_Ehdr * header = & filedata->file_header;
6293
521f7268
NC
6294 if (! check_magic_number (filedata, header))
6295 return false;
252b5132 6296
ca0e11aa
NC
6297 if (! filedata->is_separate)
6298 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6299
252b5132
RH
6300 if (do_header)
6301 {
32ec8896 6302 unsigned i;
252b5132 6303
ca0e11aa
NC
6304 if (filedata->is_separate)
6305 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6306 else
6307 printf (_("ELF Header:\n"));
252b5132 6308 printf (_(" Magic: "));
b34976b6 6309 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6310 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6311 printf ("\n");
6312 printf (_(" Class: %s\n"),
dda8d76d 6313 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6314 printf (_(" Data: %s\n"),
dda8d76d 6315 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6316 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6317 header->e_ident[EI_VERSION],
6318 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6319 ? _(" (current)")
dda8d76d 6320 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6321 ? _(" <unknown>")
789be9f7 6322 : "")));
252b5132 6323 printf (_(" OS/ABI: %s\n"),
dda8d76d 6324 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6325 printf (_(" ABI Version: %d\n"),
dda8d76d 6326 header->e_ident[EI_ABIVERSION]);
252b5132 6327 printf (_(" Type: %s\n"),
93df3340 6328 get_file_type (filedata));
252b5132 6329 printf (_(" Machine: %s\n"),
dda8d76d 6330 get_machine_name (header->e_machine));
252b5132 6331 printf (_(" Version: 0x%lx\n"),
e8a64888 6332 header->e_version);
76da6bbe 6333
f7a99963 6334 printf (_(" Entry point address: "));
e8a64888 6335 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6336 printf (_("\n Start of program headers: "));
e8a64888 6337 print_vma (header->e_phoff, DEC);
f7a99963 6338 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6339 print_vma (header->e_shoff, DEC);
f7a99963 6340 printf (_(" (bytes into file)\n"));
76da6bbe 6341
252b5132 6342 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6343 header->e_flags,
dda8d76d 6344 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6345 printf (_(" Size of this header: %u (bytes)\n"),
6346 header->e_ehsize);
6347 printf (_(" Size of program headers: %u (bytes)\n"),
6348 header->e_phentsize);
6349 printf (_(" Number of program headers: %u"),
6350 header->e_phnum);
dda8d76d
NC
6351 if (filedata->section_headers != NULL
6352 && header->e_phnum == PN_XNUM
6353 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6354 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6355 putc ('\n', stdout);
e8a64888
AM
6356 printf (_(" Size of section headers: %u (bytes)\n"),
6357 header->e_shentsize);
6358 printf (_(" Number of section headers: %u"),
6359 header->e_shnum);
dda8d76d 6360 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6361 {
6362 header->e_shnum = filedata->section_headers[0].sh_size;
6363 printf (" (%u)", header->e_shnum);
6364 }
560f3c1c 6365 putc ('\n', stdout);
e8a64888
AM
6366 printf (_(" Section header string table index: %u"),
6367 header->e_shstrndx);
dda8d76d
NC
6368 if (filedata->section_headers != NULL
6369 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6370 {
6371 header->e_shstrndx = filedata->section_headers[0].sh_link;
6372 printf (" (%u)", header->e_shstrndx);
6373 }
6374 if (header->e_shstrndx != SHN_UNDEF
6375 && header->e_shstrndx >= header->e_shnum)
6376 {
6377 header->e_shstrndx = SHN_UNDEF;
6378 printf (_(" <corrupt: out of range>"));
6379 }
560f3c1c
AM
6380 putc ('\n', stdout);
6381 }
6382
dda8d76d 6383 if (filedata->section_headers != NULL)
560f3c1c 6384 {
dda8d76d
NC
6385 if (header->e_phnum == PN_XNUM
6386 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6387 {
6388 /* Throw away any cached read of PN_XNUM headers. */
6389 free (filedata->program_headers);
6390 filedata->program_headers = NULL;
6391 header->e_phnum = filedata->section_headers[0].sh_info;
6392 }
dda8d76d
NC
6393 if (header->e_shnum == SHN_UNDEF)
6394 header->e_shnum = filedata->section_headers[0].sh_size;
6395 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6396 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6397 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6398 header->e_shstrndx = SHN_UNDEF;
252b5132 6399 }
103f02d3 6400
015dc7e1 6401 return true;
9ea033b2
NC
6402}
6403
dda8d76d
NC
6404/* Read in the program headers from FILEDATA and store them in PHEADERS.
6405 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6406
015dc7e1 6407static bool
dda8d76d 6408get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6409{
2cf0635d
NC
6410 Elf32_External_Phdr * phdrs;
6411 Elf32_External_Phdr * external;
6412 Elf_Internal_Phdr * internal;
b34976b6 6413 unsigned int i;
dda8d76d
NC
6414 unsigned int size = filedata->file_header.e_phentsize;
6415 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6416
6417 /* PR binutils/17531: Cope with unexpected section header sizes. */
6418 if (size == 0 || num == 0)
015dc7e1 6419 return false;
e0a31db1
NC
6420 if (size < sizeof * phdrs)
6421 {
6422 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6423 return false;
e0a31db1
NC
6424 }
6425 if (size > sizeof * phdrs)
6426 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6427
dda8d76d 6428 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6429 size, num, _("program headers"));
6430 if (phdrs == NULL)
015dc7e1 6431 return false;
9ea033b2 6432
91d6fa6a 6433 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6434 i < filedata->file_header.e_phnum;
b34976b6 6435 i++, internal++, external++)
252b5132 6436 {
9ea033b2
NC
6437 internal->p_type = BYTE_GET (external->p_type);
6438 internal->p_offset = BYTE_GET (external->p_offset);
6439 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6440 internal->p_paddr = BYTE_GET (external->p_paddr);
6441 internal->p_filesz = BYTE_GET (external->p_filesz);
6442 internal->p_memsz = BYTE_GET (external->p_memsz);
6443 internal->p_flags = BYTE_GET (external->p_flags);
6444 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6445 }
6446
9ea033b2 6447 free (phdrs);
015dc7e1 6448 return true;
252b5132
RH
6449}
6450
dda8d76d
NC
6451/* Read in the program headers from FILEDATA and store them in PHEADERS.
6452 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6453
015dc7e1 6454static bool
dda8d76d 6455get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6456{
2cf0635d
NC
6457 Elf64_External_Phdr * phdrs;
6458 Elf64_External_Phdr * external;
6459 Elf_Internal_Phdr * internal;
b34976b6 6460 unsigned int i;
dda8d76d
NC
6461 unsigned int size = filedata->file_header.e_phentsize;
6462 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6463
6464 /* PR binutils/17531: Cope with unexpected section header sizes. */
6465 if (size == 0 || num == 0)
015dc7e1 6466 return false;
e0a31db1
NC
6467 if (size < sizeof * phdrs)
6468 {
6469 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6470 return false;
e0a31db1
NC
6471 }
6472 if (size > sizeof * phdrs)
6473 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6474
dda8d76d 6475 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6476 size, num, _("program headers"));
a6e9f9df 6477 if (!phdrs)
015dc7e1 6478 return false;
9ea033b2 6479
91d6fa6a 6480 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6481 i < filedata->file_header.e_phnum;
b34976b6 6482 i++, internal++, external++)
9ea033b2
NC
6483 {
6484 internal->p_type = BYTE_GET (external->p_type);
6485 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6486 internal->p_offset = BYTE_GET (external->p_offset);
6487 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6488 internal->p_paddr = BYTE_GET (external->p_paddr);
6489 internal->p_filesz = BYTE_GET (external->p_filesz);
6490 internal->p_memsz = BYTE_GET (external->p_memsz);
6491 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6492 }
6493
6494 free (phdrs);
015dc7e1 6495 return true;
9ea033b2 6496}
252b5132 6497
32ec8896 6498/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6499
015dc7e1 6500static bool
dda8d76d 6501get_program_headers (Filedata * filedata)
d93f0186 6502{
2cf0635d 6503 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6504
6505 /* Check cache of prior read. */
dda8d76d 6506 if (filedata->program_headers != NULL)
015dc7e1 6507 return true;
d93f0186 6508
82156ab7
NC
6509 /* Be kind to memory checkers by looking for
6510 e_phnum values which we know must be invalid. */
dda8d76d 6511 if (filedata->file_header.e_phnum
82156ab7 6512 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6513 >= filedata->file_size)
82156ab7
NC
6514 {
6515 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6516 filedata->file_header.e_phnum);
015dc7e1 6517 return false;
82156ab7 6518 }
d93f0186 6519
dda8d76d 6520 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6521 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6522 if (phdrs == NULL)
6523 {
8b73c356 6524 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6525 filedata->file_header.e_phnum);
015dc7e1 6526 return false;
d93f0186
NC
6527 }
6528
6529 if (is_32bit_elf
dda8d76d
NC
6530 ? get_32bit_program_headers (filedata, phdrs)
6531 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6532 {
dda8d76d 6533 filedata->program_headers = phdrs;
015dc7e1 6534 return true;
d93f0186
NC
6535 }
6536
6537 free (phdrs);
015dc7e1 6538 return false;
d93f0186
NC
6539}
6540
93df3340 6541/* Print program header info and locate dynamic section. */
2f62977e 6542
93df3340 6543static void
dda8d76d 6544process_program_headers (Filedata * filedata)
252b5132 6545{
2cf0635d 6546 Elf_Internal_Phdr * segment;
b34976b6 6547 unsigned int i;
1a9ccd70 6548 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6549
dda8d76d 6550 if (filedata->file_header.e_phnum == 0)
252b5132 6551 {
82f2dbf7 6552 /* PR binutils/12467. */
dda8d76d 6553 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6554 warn (_("possibly corrupt ELF header - it has a non-zero program"
6555 " header offset, but no program headers\n"));
82f2dbf7 6556 else if (do_segments)
ca0e11aa
NC
6557 {
6558 if (filedata->is_separate)
6559 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6560 filedata->file_name);
6561 else
6562 printf (_("\nThere are no program headers in this file.\n"));
6563 }
93df3340 6564 goto no_headers;
252b5132
RH
6565 }
6566
6567 if (do_segments && !do_header)
6568 {
ca0e11aa
NC
6569 if (filedata->is_separate)
6570 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6571 filedata->file_name, get_file_type (filedata));
ca0e11aa 6572 else
93df3340 6573 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6574 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6575 filedata->file_header.e_entry);
b8281767
AM
6576 printf (ngettext ("There is %d program header,"
6577 " starting at offset %" PRIu64 "\n",
6578 "There are %d program headers,"
6579 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6580 filedata->file_header.e_phnum),
6581 filedata->file_header.e_phnum,
625d49fc 6582 filedata->file_header.e_phoff);
252b5132
RH
6583 }
6584
dda8d76d 6585 if (! get_program_headers (filedata))
93df3340 6586 goto no_headers;
103f02d3 6587
252b5132
RH
6588 if (do_segments)
6589 {
dda8d76d 6590 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6591 printf (_("\nProgram Headers:\n"));
6592 else
6593 printf (_("\nProgram Headers:\n"));
76da6bbe 6594
f7a99963
NC
6595 if (is_32bit_elf)
6596 printf
6597 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6598 else if (do_wide)
6599 printf
6600 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6601 else
6602 {
6603 printf
6604 (_(" Type Offset VirtAddr PhysAddr\n"));
6605 printf
6606 (_(" FileSiz MemSiz Flags Align\n"));
6607 }
252b5132
RH
6608 }
6609
26c527e6 6610 uint64_t dynamic_addr = 0;
be7d229a 6611 uint64_t dynamic_size = 0;
dda8d76d
NC
6612 for (i = 0, segment = filedata->program_headers;
6613 i < filedata->file_header.e_phnum;
b34976b6 6614 i++, segment++)
252b5132
RH
6615 {
6616 if (do_segments)
6617 {
dda8d76d 6618 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6619
6620 if (is_32bit_elf)
6621 {
6622 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6623 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6624 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6625 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6626 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6627 printf ("%c%c%c ",
6628 (segment->p_flags & PF_R ? 'R' : ' '),
6629 (segment->p_flags & PF_W ? 'W' : ' '),
6630 (segment->p_flags & PF_X ? 'E' : ' '));
6631 printf ("%#lx", (unsigned long) segment->p_align);
6632 }
d974e256
JJ
6633 else if (do_wide)
6634 {
6635 if ((unsigned long) segment->p_offset == segment->p_offset)
6636 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6637 else
6638 {
6639 print_vma (segment->p_offset, FULL_HEX);
6640 putchar (' ');
6641 }
6642
6643 print_vma (segment->p_vaddr, FULL_HEX);
6644 putchar (' ');
6645 print_vma (segment->p_paddr, FULL_HEX);
6646 putchar (' ');
6647
6648 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6649 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6650 else
6651 {
6652 print_vma (segment->p_filesz, FULL_HEX);
6653 putchar (' ');
6654 }
6655
6656 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6657 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6658 else
6659 {
f48e6c45 6660 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6661 }
6662
6663 printf (" %c%c%c ",
6664 (segment->p_flags & PF_R ? 'R' : ' '),
6665 (segment->p_flags & PF_W ? 'W' : ' '),
6666 (segment->p_flags & PF_X ? 'E' : ' '));
6667
6668 if ((unsigned long) segment->p_align == segment->p_align)
6669 printf ("%#lx", (unsigned long) segment->p_align);
6670 else
6671 {
6672 print_vma (segment->p_align, PREFIX_HEX);
6673 }
6674 }
f7a99963
NC
6675 else
6676 {
6677 print_vma (segment->p_offset, FULL_HEX);
6678 putchar (' ');
6679 print_vma (segment->p_vaddr, FULL_HEX);
6680 putchar (' ');
6681 print_vma (segment->p_paddr, FULL_HEX);
6682 printf ("\n ");
6683 print_vma (segment->p_filesz, FULL_HEX);
6684 putchar (' ');
6685 print_vma (segment->p_memsz, FULL_HEX);
6686 printf (" %c%c%c ",
6687 (segment->p_flags & PF_R ? 'R' : ' '),
6688 (segment->p_flags & PF_W ? 'W' : ' '),
6689 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6690 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6691 }
252b5132 6692
1a9ccd70
NC
6693 putc ('\n', stdout);
6694 }
f54498b4 6695
252b5132
RH
6696 switch (segment->p_type)
6697 {
1a9ccd70 6698 case PT_LOAD:
502d895c
NC
6699#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6700 required by the ELF standard, several programs, including the Linux
6701 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6702 if (previous_load
6703 && previous_load->p_vaddr > segment->p_vaddr)
6704 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6705#endif
1a9ccd70
NC
6706 if (segment->p_memsz < segment->p_filesz)
6707 error (_("the segment's file size is larger than its memory size\n"));
6708 previous_load = segment;
6709 break;
6710
6711 case PT_PHDR:
6712 /* PR 20815 - Verify that the program header is loaded into memory. */
6713 if (i > 0 && previous_load != NULL)
6714 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6715 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6716 {
6717 unsigned int j;
6718
dda8d76d 6719 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6720 {
6721 Elf_Internal_Phdr *load = filedata->program_headers + j;
6722 if (load->p_type == PT_LOAD
6723 && load->p_offset <= segment->p_offset
6724 && (load->p_offset + load->p_filesz
6725 >= segment->p_offset + segment->p_filesz)
6726 && load->p_vaddr <= segment->p_vaddr
6727 && (load->p_vaddr + load->p_filesz
6728 >= segment->p_vaddr + segment->p_filesz))
6729 break;
6730 }
dda8d76d 6731 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6732 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6733 }
6734 break;
6735
252b5132 6736 case PT_DYNAMIC:
93df3340 6737 if (dynamic_addr)
252b5132
RH
6738 error (_("more than one dynamic segment\n"));
6739
20737c13
AM
6740 /* By default, assume that the .dynamic section is the first
6741 section in the DYNAMIC segment. */
93df3340
AM
6742 dynamic_addr = segment->p_offset;
6743 dynamic_size = segment->p_filesz;
20737c13 6744
b2d38a17
NC
6745 /* Try to locate the .dynamic section. If there is
6746 a section header table, we can easily locate it. */
dda8d76d 6747 if (filedata->section_headers != NULL)
b2d38a17 6748 {
2cf0635d 6749 Elf_Internal_Shdr * sec;
b2d38a17 6750
dda8d76d 6751 sec = find_section (filedata, ".dynamic");
89fac5e3 6752 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6753 {
93df3340
AM
6754 /* A corresponding .dynamic section is expected, but on
6755 IA-64/OpenVMS it is OK for it to be missing. */
6756 if (!is_ia64_vms (filedata))
6757 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6758 break;
6759 }
6760
42bb2e33 6761 if (sec->sh_type == SHT_NOBITS)
20737c13 6762 {
93df3340
AM
6763 dynamic_addr = 0;
6764 dynamic_size = 0;
20737c13
AM
6765 break;
6766 }
42bb2e33 6767
93df3340
AM
6768 dynamic_addr = sec->sh_offset;
6769 dynamic_size = sec->sh_size;
b2d38a17 6770
8ac10c5b
L
6771 /* The PT_DYNAMIC segment, which is used by the run-time
6772 loader, should exactly match the .dynamic section. */
6773 if (do_checks
93df3340
AM
6774 && (dynamic_addr != segment->p_offset
6775 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6776 warn (_("\
6777the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6778 }
39e224f6
MW
6779
6780 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6781 segment. Check this after matching against the section headers
6782 so we don't warn on debuginfo file (which have NOBITS .dynamic
6783 sections). */
93df3340
AM
6784 if (dynamic_addr > filedata->file_size
6785 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6786 {
6787 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6788 dynamic_addr = 0;
6789 dynamic_size = 0;
39e224f6 6790 }
252b5132
RH
6791 break;
6792
6793 case PT_INTERP:
13acb58d
AM
6794 if (segment->p_offset >= filedata->file_size
6795 || segment->p_filesz > filedata->file_size - segment->p_offset
6796 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6797 || fseek64 (filedata->handle,
6798 filedata->archive_file_offset + segment->p_offset,
6799 SEEK_SET))
252b5132
RH
6800 error (_("Unable to find program interpreter name\n"));
6801 else
6802 {
13acb58d
AM
6803 size_t len = segment->p_filesz;
6804 free (filedata->program_interpreter);
6805 filedata->program_interpreter = xmalloc (len + 1);
6806 len = fread (filedata->program_interpreter, 1, len,
6807 filedata->handle);
6808 filedata->program_interpreter[len] = 0;
252b5132
RH
6809
6810 if (do_segments)
f54498b4 6811 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6812 filedata->program_interpreter);
252b5132
RH
6813 }
6814 break;
6815 }
252b5132
RH
6816 }
6817
dda8d76d
NC
6818 if (do_segments
6819 && filedata->section_headers != NULL
6820 && filedata->string_table != NULL)
252b5132
RH
6821 {
6822 printf (_("\n Section to Segment mapping:\n"));
6823 printf (_(" Segment Sections...\n"));
6824
dda8d76d 6825 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6826 {
9ad5cbcf 6827 unsigned int j;
2cf0635d 6828 Elf_Internal_Shdr * section;
252b5132 6829
dda8d76d
NC
6830 segment = filedata->program_headers + i;
6831 section = filedata->section_headers + 1;
252b5132
RH
6832
6833 printf (" %2.2d ", i);
6834
dda8d76d 6835 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6836 {
f4638467
AM
6837 if (!ELF_TBSS_SPECIAL (section, segment)
6838 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6839 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6840 }
6841
6842 putc ('\n',stdout);
6843 }
6844 }
6845
93df3340
AM
6846 filedata->dynamic_addr = dynamic_addr;
6847 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6848 return;
6849
6850 no_headers:
6851 filedata->dynamic_addr = 0;
6852 filedata->dynamic_size = 1;
252b5132
RH
6853}
6854
6855
d93f0186
NC
6856/* Find the file offset corresponding to VMA by using the program headers. */
6857
26c527e6 6858static int64_t
625d49fc 6859offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6860{
2cf0635d 6861 Elf_Internal_Phdr * seg;
d93f0186 6862
dda8d76d 6863 if (! get_program_headers (filedata))
d93f0186
NC
6864 {
6865 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6866 return (long) vma;
6867 }
6868
dda8d76d
NC
6869 for (seg = filedata->program_headers;
6870 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6871 ++seg)
6872 {
6873 if (seg->p_type != PT_LOAD)
6874 continue;
6875
6876 if (vma >= (seg->p_vaddr & -seg->p_align)
6877 && vma + size <= seg->p_vaddr + seg->p_filesz)
6878 return vma - seg->p_vaddr + seg->p_offset;
6879 }
6880
26c527e6
AM
6881 warn (_("Virtual address %#" PRIx64
6882 " not located in any PT_LOAD segment.\n"), vma);
6883 return vma;
d93f0186
NC
6884}
6885
6886
dda8d76d
NC
6887/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6888 If PROBE is true, this is just a probe and we do not generate any error
6889 messages if the load fails. */
049b0c3a 6890
015dc7e1
AM
6891static bool
6892get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6893{
2cf0635d
NC
6894 Elf32_External_Shdr * shdrs;
6895 Elf_Internal_Shdr * internal;
dda8d76d
NC
6896 unsigned int i;
6897 unsigned int size = filedata->file_header.e_shentsize;
6898 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6899
6900 /* PR binutils/17531: Cope with unexpected section header sizes. */
6901 if (size == 0 || num == 0)
015dc7e1 6902 return false;
907b52f4
NC
6903
6904 /* The section header cannot be at the start of the file - that is
6905 where the ELF file header is located. A file with absolutely no
6906 sections in it will use a shoff of 0. */
6907 if (filedata->file_header.e_shoff == 0)
6908 return false;
6909
049b0c3a
NC
6910 if (size < sizeof * shdrs)
6911 {
6912 if (! probe)
6913 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6914 return false;
049b0c3a
NC
6915 }
6916 if (!probe && size > sizeof * shdrs)
6917 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6918
dda8d76d 6919 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6920 size, num,
6921 probe ? NULL : _("section headers"));
6922 if (shdrs == NULL)
015dc7e1 6923 return false;
252b5132 6924
dda8d76d
NC
6925 filedata->section_headers = (Elf_Internal_Shdr *)
6926 cmalloc (num, sizeof (Elf_Internal_Shdr));
6927 if (filedata->section_headers == NULL)
252b5132 6928 {
049b0c3a 6929 if (!probe)
8b73c356 6930 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6931 free (shdrs);
015dc7e1 6932 return false;
252b5132
RH
6933 }
6934
dda8d76d 6935 for (i = 0, internal = filedata->section_headers;
560f3c1c 6936 i < num;
b34976b6 6937 i++, internal++)
252b5132
RH
6938 {
6939 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6940 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6941 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6942 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6943 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6944 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6945 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6946 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6947 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6948 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6949 if (!probe && internal->sh_link > num)
6950 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6951 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6952 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6953 }
6954
6955 free (shdrs);
015dc7e1 6956 return true;
252b5132
RH
6957}
6958
dda8d76d
NC
6959/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6960
015dc7e1
AM
6961static bool
6962get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6963{
dda8d76d
NC
6964 Elf64_External_Shdr * shdrs;
6965 Elf_Internal_Shdr * internal;
6966 unsigned int i;
6967 unsigned int size = filedata->file_header.e_shentsize;
6968 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6969
6970 /* PR binutils/17531: Cope with unexpected section header sizes. */
6971 if (size == 0 || num == 0)
015dc7e1 6972 return false;
dda8d76d 6973
907b52f4
NC
6974 /* The section header cannot be at the start of the file - that is
6975 where the ELF file header is located. A file with absolutely no
6976 sections in it will use a shoff of 0. */
6977 if (filedata->file_header.e_shoff == 0)
6978 return false;
6979
049b0c3a
NC
6980 if (size < sizeof * shdrs)
6981 {
6982 if (! probe)
6983 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6984 return false;
049b0c3a 6985 }
dda8d76d 6986
049b0c3a
NC
6987 if (! probe && size > sizeof * shdrs)
6988 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6989
dda8d76d
NC
6990 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6991 filedata->file_header.e_shoff,
049b0c3a
NC
6992 size, num,
6993 probe ? NULL : _("section headers"));
6994 if (shdrs == NULL)
015dc7e1 6995 return false;
9ea033b2 6996
dda8d76d
NC
6997 filedata->section_headers = (Elf_Internal_Shdr *)
6998 cmalloc (num, sizeof (Elf_Internal_Shdr));
6999 if (filedata->section_headers == NULL)
9ea033b2 7000 {
049b0c3a 7001 if (! probe)
8b73c356 7002 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7003 free (shdrs);
015dc7e1 7004 return false;
9ea033b2
NC
7005 }
7006
dda8d76d 7007 for (i = 0, internal = filedata->section_headers;
560f3c1c 7008 i < num;
b34976b6 7009 i++, internal++)
9ea033b2
NC
7010 {
7011 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7012 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7013 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7014 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7015 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7016 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7017 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7018 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7019 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7020 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7021 if (!probe && internal->sh_link > num)
7022 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7023 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7024 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7025 }
7026
7027 free (shdrs);
015dc7e1 7028 return true;
9ea033b2
NC
7029}
7030
4de91c10
AM
7031static bool
7032get_section_headers (Filedata *filedata, bool probe)
7033{
7034 if (filedata->section_headers != NULL)
7035 return true;
7036
4de91c10
AM
7037 if (is_32bit_elf)
7038 return get_32bit_section_headers (filedata, probe);
7039 else
7040 return get_64bit_section_headers (filedata, probe);
7041}
7042
252b5132 7043static Elf_Internal_Sym *
26c527e6
AM
7044get_32bit_elf_symbols (Filedata *filedata,
7045 Elf_Internal_Shdr *section,
7046 uint64_t *num_syms_return)
252b5132 7047{
26c527e6 7048 uint64_t number = 0;
dd24e3da 7049 Elf32_External_Sym * esyms = NULL;
ba5cdace 7050 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7051 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7052 Elf_Internal_Sym * psym;
b34976b6 7053 unsigned int j;
e3d39609 7054 elf_section_list * entry;
252b5132 7055
c9c1d674
EG
7056 if (section->sh_size == 0)
7057 {
7058 if (num_syms_return != NULL)
7059 * num_syms_return = 0;
7060 return NULL;
7061 }
7062
dd24e3da 7063 /* Run some sanity checks first. */
c9c1d674 7064 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7065 {
26c527e6 7066 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7067 printable_section_name (filedata, section),
26c527e6 7068 section->sh_entsize);
ba5cdace 7069 goto exit_point;
dd24e3da
NC
7070 }
7071
dda8d76d 7072 if (section->sh_size > filedata->file_size)
f54498b4 7073 {
26c527e6 7074 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7075 printable_section_name (filedata, section),
26c527e6 7076 section->sh_size);
f54498b4
NC
7077 goto exit_point;
7078 }
7079
dd24e3da
NC
7080 number = section->sh_size / section->sh_entsize;
7081
7082 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7083 {
26c527e6
AM
7084 error (_("Size (%#" PRIx64 ") of section %s "
7085 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7086 section->sh_size,
dda8d76d 7087 printable_section_name (filedata, section),
26c527e6 7088 section->sh_entsize);
ba5cdace 7089 goto exit_point;
dd24e3da
NC
7090 }
7091
dda8d76d 7092 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7093 section->sh_size, _("symbols"));
dd24e3da 7094 if (esyms == NULL)
ba5cdace 7095 goto exit_point;
252b5132 7096
e3d39609 7097 shndx = NULL;
978c4450 7098 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7099 {
26c527e6 7100 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7101 continue;
7102
7103 if (shndx != NULL)
7104 {
7105 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7106 free (shndx);
7107 }
7108
7109 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7110 entry->hdr->sh_offset,
7111 1, entry->hdr->sh_size,
7112 _("symbol table section indices"));
7113 if (shndx == NULL)
7114 goto exit_point;
7115
7116 /* PR17531: file: heap-buffer-overflow */
7117 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7118 {
26c527e6 7119 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7120 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7121 entry->hdr->sh_size,
7122 section->sh_size);
e3d39609 7123 goto exit_point;
c9c1d674 7124 }
e3d39609 7125 }
9ad5cbcf 7126
3f5e193b 7127 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7128
7129 if (isyms == NULL)
7130 {
26c527e6 7131 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7132 goto exit_point;
252b5132
RH
7133 }
7134
dd24e3da 7135 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7136 {
7137 psym->st_name = BYTE_GET (esyms[j].st_name);
7138 psym->st_value = BYTE_GET (esyms[j].st_value);
7139 psym->st_size = BYTE_GET (esyms[j].st_size);
7140 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7141 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7142 psym->st_shndx
7143 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7144 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7145 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7146 psym->st_info = BYTE_GET (esyms[j].st_info);
7147 psym->st_other = BYTE_GET (esyms[j].st_other);
7148 }
7149
dd24e3da 7150 exit_point:
e3d39609
NC
7151 free (shndx);
7152 free (esyms);
252b5132 7153
ba5cdace
NC
7154 if (num_syms_return != NULL)
7155 * num_syms_return = isyms == NULL ? 0 : number;
7156
252b5132
RH
7157 return isyms;
7158}
7159
9ea033b2 7160static Elf_Internal_Sym *
26c527e6
AM
7161get_64bit_elf_symbols (Filedata *filedata,
7162 Elf_Internal_Shdr *section,
7163 uint64_t *num_syms_return)
9ea033b2 7164{
26c527e6 7165 uint64_t number = 0;
ba5cdace
NC
7166 Elf64_External_Sym * esyms = NULL;
7167 Elf_External_Sym_Shndx * shndx = NULL;
7168 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7169 Elf_Internal_Sym * psym;
b34976b6 7170 unsigned int j;
e3d39609 7171 elf_section_list * entry;
9ea033b2 7172
c9c1d674
EG
7173 if (section->sh_size == 0)
7174 {
7175 if (num_syms_return != NULL)
7176 * num_syms_return = 0;
7177 return NULL;
7178 }
7179
dd24e3da 7180 /* Run some sanity checks first. */
c9c1d674 7181 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7182 {
26c527e6 7183 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7184 printable_section_name (filedata, section),
26c527e6 7185 section->sh_entsize);
ba5cdace 7186 goto exit_point;
dd24e3da
NC
7187 }
7188
dda8d76d 7189 if (section->sh_size > filedata->file_size)
f54498b4 7190 {
26c527e6 7191 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7192 printable_section_name (filedata, section),
26c527e6 7193 section->sh_size);
f54498b4
NC
7194 goto exit_point;
7195 }
7196
dd24e3da
NC
7197 number = section->sh_size / section->sh_entsize;
7198
7199 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7200 {
26c527e6
AM
7201 error (_("Size (%#" PRIx64 ") of section %s "
7202 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7203 section->sh_size,
dda8d76d 7204 printable_section_name (filedata, section),
26c527e6 7205 section->sh_entsize);
ba5cdace 7206 goto exit_point;
dd24e3da
NC
7207 }
7208
dda8d76d 7209 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7210 section->sh_size, _("symbols"));
a6e9f9df 7211 if (!esyms)
ba5cdace 7212 goto exit_point;
9ea033b2 7213
e3d39609 7214 shndx = NULL;
978c4450 7215 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7216 {
26c527e6 7217 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7218 continue;
7219
7220 if (shndx != NULL)
7221 {
7222 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7223 free (shndx);
c9c1d674 7224 }
e3d39609
NC
7225
7226 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7227 entry->hdr->sh_offset,
7228 1, entry->hdr->sh_size,
7229 _("symbol table section indices"));
7230 if (shndx == NULL)
7231 goto exit_point;
7232
7233 /* PR17531: file: heap-buffer-overflow */
7234 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7235 {
26c527e6 7236 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7237 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7238 entry->hdr->sh_size,
7239 section->sh_size);
e3d39609
NC
7240 goto exit_point;
7241 }
7242 }
9ad5cbcf 7243
3f5e193b 7244 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7245
7246 if (isyms == NULL)
7247 {
26c527e6 7248 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7249 goto exit_point;
9ea033b2
NC
7250 }
7251
ba5cdace 7252 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7253 {
7254 psym->st_name = BYTE_GET (esyms[j].st_name);
7255 psym->st_info = BYTE_GET (esyms[j].st_info);
7256 psym->st_other = BYTE_GET (esyms[j].st_other);
7257 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7258
4fbb74a6 7259 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7260 psym->st_shndx
7261 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7262 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7263 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7264
66543521
AM
7265 psym->st_value = BYTE_GET (esyms[j].st_value);
7266 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7267 }
7268
ba5cdace 7269 exit_point:
e3d39609
NC
7270 free (shndx);
7271 free (esyms);
ba5cdace
NC
7272
7273 if (num_syms_return != NULL)
7274 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7275
7276 return isyms;
7277}
7278
4de91c10
AM
7279static Elf_Internal_Sym *
7280get_elf_symbols (Filedata *filedata,
7281 Elf_Internal_Shdr *section,
26c527e6 7282 uint64_t *num_syms_return)
4de91c10
AM
7283{
7284 if (is_32bit_elf)
7285 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7286 else
7287 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7288}
7289
d1133906 7290static const char *
625d49fc 7291get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7292{
5477e8a0 7293 static char buff[1024];
2cf0635d 7294 char * p = buff;
32ec8896
NC
7295 unsigned int field_size = is_32bit_elf ? 8 : 16;
7296 signed int sindex;
7297 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7298 uint64_t os_flags = 0;
7299 uint64_t proc_flags = 0;
7300 uint64_t unknown_flags = 0;
148b93f2 7301 static const struct
5477e8a0 7302 {
2cf0635d 7303 const char * str;
32ec8896 7304 unsigned int len;
5477e8a0
L
7305 }
7306 flags [] =
7307 {
cfcac11d
NC
7308 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7309 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7310 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7311 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7312 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7313 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7314 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7315 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7316 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7317 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7318 /* IA-64 specific. */
7319 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7320 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7321 /* IA-64 OpenVMS specific. */
7322 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7323 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7324 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7325 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7326 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7327 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7328 /* Generic. */
cfcac11d 7329 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7330 /* SPARC specific. */
77115a4a 7331 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7332 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7333 /* ARM specific. */
7334 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7335 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7336 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7337 /* GNU specific. */
7338 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7339 /* VLE specific. */
7340 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7341 /* GNU specific. */
7342 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7343 };
7344
7345 if (do_section_details)
f8c4789c
AM
7346 p += sprintf (p, "[%*.*lx]: ",
7347 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7348
d1133906
NC
7349 while (sh_flags)
7350 {
625d49fc 7351 uint64_t flag;
d1133906
NC
7352
7353 flag = sh_flags & - sh_flags;
7354 sh_flags &= ~ flag;
76da6bbe 7355
5477e8a0 7356 if (do_section_details)
d1133906 7357 {
5477e8a0
L
7358 switch (flag)
7359 {
91d6fa6a
NC
7360 case SHF_WRITE: sindex = 0; break;
7361 case SHF_ALLOC: sindex = 1; break;
7362 case SHF_EXECINSTR: sindex = 2; break;
7363 case SHF_MERGE: sindex = 3; break;
7364 case SHF_STRINGS: sindex = 4; break;
7365 case SHF_INFO_LINK: sindex = 5; break;
7366 case SHF_LINK_ORDER: sindex = 6; break;
7367 case SHF_OS_NONCONFORMING: sindex = 7; break;
7368 case SHF_GROUP: sindex = 8; break;
7369 case SHF_TLS: sindex = 9; break;
18ae9cc1 7370 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7371 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7372
5477e8a0 7373 default:
91d6fa6a 7374 sindex = -1;
dda8d76d 7375 switch (filedata->file_header.e_machine)
148b93f2 7376 {
cfcac11d 7377 case EM_IA_64:
148b93f2 7378 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7379 sindex = 10;
148b93f2 7380 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7381 sindex = 11;
dda8d76d 7382 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7383 switch (flag)
7384 {
91d6fa6a
NC
7385 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7386 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7387 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7388 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7389 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7390 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7391 default: break;
7392 }
cfcac11d
NC
7393 break;
7394
caa83f8b 7395 case EM_386:
22abe556 7396 case EM_IAMCU:
caa83f8b 7397 case EM_X86_64:
7f502d6c 7398 case EM_L1OM:
7a9068fe 7399 case EM_K1OM:
cfcac11d
NC
7400 case EM_OLD_SPARCV9:
7401 case EM_SPARC32PLUS:
7402 case EM_SPARCV9:
7403 case EM_SPARC:
18ae9cc1 7404 if (flag == SHF_ORDERED)
91d6fa6a 7405 sindex = 19;
cfcac11d 7406 break;
ac4c9b04
MG
7407
7408 case EM_ARM:
7409 switch (flag)
7410 {
7411 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7412 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7413 case SHF_COMDEF: sindex = 23; break;
7414 default: break;
7415 }
7416 break;
83eef883
AFB
7417 case EM_PPC:
7418 if (flag == SHF_PPC_VLE)
7419 sindex = 25;
7420 break;
99fabbc9
JL
7421 default:
7422 break;
7423 }
ac4c9b04 7424
99fabbc9
JL
7425 switch (filedata->file_header.e_ident[EI_OSABI])
7426 {
7427 case ELFOSABI_GNU:
7428 case ELFOSABI_FREEBSD:
7429 if (flag == SHF_GNU_RETAIN)
7430 sindex = 26;
7431 /* Fall through */
7432 case ELFOSABI_NONE:
7433 if (flag == SHF_GNU_MBIND)
7434 /* We should not recognize SHF_GNU_MBIND for
7435 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7436 not set the EI_OSABI header byte. */
7437 sindex = 24;
7438 break;
cfcac11d
NC
7439 default:
7440 break;
148b93f2 7441 }
99fabbc9 7442 break;
5477e8a0
L
7443 }
7444
91d6fa6a 7445 if (sindex != -1)
5477e8a0 7446 {
8d5ff12c
L
7447 if (p != buff + field_size + 4)
7448 {
7449 if (size < (10 + 2))
bee0ee85
NC
7450 {
7451 warn (_("Internal error: not enough buffer room for section flag info"));
7452 return _("<unknown>");
7453 }
8d5ff12c
L
7454 size -= 2;
7455 *p++ = ',';
7456 *p++ = ' ';
7457 }
7458
91d6fa6a
NC
7459 size -= flags [sindex].len;
7460 p = stpcpy (p, flags [sindex].str);
5477e8a0 7461 }
3b22753a 7462 else if (flag & SHF_MASKOS)
8d5ff12c 7463 os_flags |= flag;
d1133906 7464 else if (flag & SHF_MASKPROC)
8d5ff12c 7465 proc_flags |= flag;
d1133906 7466 else
8d5ff12c 7467 unknown_flags |= flag;
5477e8a0
L
7468 }
7469 else
7470 {
7471 switch (flag)
7472 {
7473 case SHF_WRITE: *p = 'W'; break;
7474 case SHF_ALLOC: *p = 'A'; break;
7475 case SHF_EXECINSTR: *p = 'X'; break;
7476 case SHF_MERGE: *p = 'M'; break;
7477 case SHF_STRINGS: *p = 'S'; break;
7478 case SHF_INFO_LINK: *p = 'I'; break;
7479 case SHF_LINK_ORDER: *p = 'L'; break;
7480 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7481 case SHF_GROUP: *p = 'G'; break;
7482 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7483 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7484 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7485
7486 default:
dda8d76d
NC
7487 if ((filedata->file_header.e_machine == EM_X86_64
7488 || filedata->file_header.e_machine == EM_L1OM
7489 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7490 && flag == SHF_X86_64_LARGE)
7491 *p = 'l';
dda8d76d 7492 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7493 && flag == SHF_ARM_PURECODE)
99fabbc9 7494 *p = 'y';
dda8d76d 7495 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7496 && flag == SHF_PPC_VLE)
99fabbc9 7497 *p = 'v';
5477e8a0
L
7498 else if (flag & SHF_MASKOS)
7499 {
99fabbc9
JL
7500 switch (filedata->file_header.e_ident[EI_OSABI])
7501 {
7502 case ELFOSABI_GNU:
7503 case ELFOSABI_FREEBSD:
7504 if (flag == SHF_GNU_RETAIN)
7505 {
7506 *p = 'R';
7507 break;
7508 }
7509 /* Fall through */
7510 case ELFOSABI_NONE:
7511 if (flag == SHF_GNU_MBIND)
7512 {
7513 /* We should not recognize SHF_GNU_MBIND for
7514 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7515 not set the EI_OSABI header byte. */
7516 *p = 'D';
7517 break;
7518 }
7519 /* Fall through */
7520 default:
7521 *p = 'o';
7522 sh_flags &= ~SHF_MASKOS;
7523 break;
7524 }
5477e8a0
L
7525 }
7526 else if (flag & SHF_MASKPROC)
7527 {
7528 *p = 'p';
7529 sh_flags &= ~ SHF_MASKPROC;
7530 }
7531 else
7532 *p = 'x';
7533 break;
7534 }
7535 p++;
d1133906
NC
7536 }
7537 }
76da6bbe 7538
8d5ff12c
L
7539 if (do_section_details)
7540 {
7541 if (os_flags)
7542 {
8d5ff12c
L
7543 if (p != buff + field_size + 4)
7544 {
f8c4789c 7545 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7546 {
7547 warn (_("Internal error: not enough buffer room for section flag info"));
7548 return _("<unknown>");
7549 }
8d5ff12c
L
7550 size -= 2;
7551 *p++ = ',';
7552 *p++ = ' ';
7553 }
f8c4789c
AM
7554 size -= 5 + field_size;
7555 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7556 (unsigned long) os_flags);
8d5ff12c
L
7557 }
7558 if (proc_flags)
7559 {
8d5ff12c
L
7560 if (p != buff + field_size + 4)
7561 {
f8c4789c 7562 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7563 {
7564 warn (_("Internal error: not enough buffer room for section flag info"));
7565 return _("<unknown>");
7566 }
8d5ff12c
L
7567 size -= 2;
7568 *p++ = ',';
7569 *p++ = ' ';
7570 }
f8c4789c
AM
7571 size -= 7 + field_size;
7572 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7573 (unsigned long) proc_flags);
8d5ff12c
L
7574 }
7575 if (unknown_flags)
7576 {
8d5ff12c
L
7577 if (p != buff + field_size + 4)
7578 {
f8c4789c 7579 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7580 {
7581 warn (_("Internal error: not enough buffer room for section flag info"));
7582 return _("<unknown>");
7583 }
8d5ff12c
L
7584 size -= 2;
7585 *p++ = ',';
7586 *p++ = ' ';
7587 }
f8c4789c
AM
7588 size -= 10 + field_size;
7589 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7590 (unsigned long) unknown_flags);
8d5ff12c
L
7591 }
7592 }
7593
e9e44622 7594 *p = '\0';
d1133906
NC
7595 return buff;
7596}
7597
5844b465 7598static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7599get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7600 uint64_t size)
77115a4a
L
7601{
7602 if (is_32bit_elf)
7603 {
7604 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7605
ebdf1ebf
NC
7606 if (size < sizeof (* echdr))
7607 {
7608 error (_("Compressed section is too small even for a compression header\n"));
7609 return 0;
7610 }
7611
77115a4a
L
7612 chdr->ch_type = BYTE_GET (echdr->ch_type);
7613 chdr->ch_size = BYTE_GET (echdr->ch_size);
7614 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7615 return sizeof (*echdr);
7616 }
7617 else
7618 {
7619 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7620
ebdf1ebf
NC
7621 if (size < sizeof (* echdr))
7622 {
7623 error (_("Compressed section is too small even for a compression header\n"));
7624 return 0;
7625 }
7626
77115a4a
L
7627 chdr->ch_type = BYTE_GET (echdr->ch_type);
7628 chdr->ch_size = BYTE_GET (echdr->ch_size);
7629 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7630 return sizeof (*echdr);
7631 }
7632}
7633
015dc7e1 7634static bool
dda8d76d 7635process_section_headers (Filedata * filedata)
252b5132 7636{
2cf0635d 7637 Elf_Internal_Shdr * section;
b34976b6 7638 unsigned int i;
252b5132 7639
dda8d76d 7640 if (filedata->file_header.e_shnum == 0)
252b5132 7641 {
82f2dbf7 7642 /* PR binutils/12467. */
dda8d76d 7643 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7644 {
7645 warn (_("possibly corrupt ELF file header - it has a non-zero"
7646 " section header offset, but no section headers\n"));
015dc7e1 7647 return false;
32ec8896 7648 }
82f2dbf7 7649 else if (do_sections)
252b5132
RH
7650 printf (_("\nThere are no sections in this file.\n"));
7651
015dc7e1 7652 return true;
252b5132
RH
7653 }
7654
7655 if (do_sections && !do_header)
ca0e11aa
NC
7656 {
7657 if (filedata->is_separate && process_links)
7658 printf (_("In linked file '%s': "), filedata->file_name);
7659 if (! filedata->is_separate || process_links)
7660 printf (ngettext ("There is %d section header, "
26c527e6 7661 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7662 "There are %d section headers, "
26c527e6 7663 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7664 filedata->file_header.e_shnum),
7665 filedata->file_header.e_shnum,
26c527e6 7666 filedata->file_header.e_shoff);
ca0e11aa 7667 }
252b5132 7668
4de91c10
AM
7669 if (!get_section_headers (filedata, false))
7670 return false;
252b5132
RH
7671
7672 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7673 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7674 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7675 {
dda8d76d 7676 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7677
c256ffe7
JJ
7678 if (section->sh_size != 0)
7679 {
dda8d76d
NC
7680 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7681 1, section->sh_size,
7682 _("string table"));
0de14b54 7683
dda8d76d 7684 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7685 }
252b5132
RH
7686 }
7687
7688 /* Scan the sections for the dynamic symbol table
e3c8793a 7689 and dynamic string table and debug sections. */
89fac5e3 7690 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7691 switch (filedata->file_header.e_machine)
89fac5e3
RS
7692 {
7693 case EM_MIPS:
7694 case EM_MIPS_RS3_LE:
7695 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7696 FDE addresses. However, the ABI also has a semi-official ILP32
7697 variant for which the normal FDE address size rules apply.
7698
7699 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7700 section, where XX is the size of longs in bits. Unfortunately,
7701 earlier compilers provided no way of distinguishing ILP32 objects
7702 from LP64 objects, so if there's any doubt, we should assume that
7703 the official LP64 form is being used. */
d173146d 7704 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 7705 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7706 eh_addr_size = 8;
7707 break;
0f56a26a
DD
7708
7709 case EM_H8_300:
7710 case EM_H8_300H:
dda8d76d 7711 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7712 {
7713 case E_H8_MACH_H8300:
7714 case E_H8_MACH_H8300HN:
7715 case E_H8_MACH_H8300SN:
7716 case E_H8_MACH_H8300SXN:
7717 eh_addr_size = 2;
7718 break;
7719 case E_H8_MACH_H8300H:
7720 case E_H8_MACH_H8300S:
7721 case E_H8_MACH_H8300SX:
7722 eh_addr_size = 4;
7723 break;
7724 }
f4236fe4
DD
7725 break;
7726
ff7eeb89 7727 case EM_M32C_OLD:
f4236fe4 7728 case EM_M32C:
dda8d76d 7729 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7730 {
7731 case EF_M32C_CPU_M16C:
7732 eh_addr_size = 2;
7733 break;
7734 }
7735 break;
89fac5e3
RS
7736 }
7737
76ca31c0
NC
7738#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7739 do \
7740 { \
be7d229a 7741 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7742 if (section->sh_entsize != expected_entsize) \
9dd3a467 7743 { \
f493c217 7744 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7745 i, section->sh_entsize); \
f493c217 7746 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7747 expected_entsize); \
9dd3a467 7748 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7749 } \
7750 } \
08d8fa11 7751 while (0)
9dd3a467
NC
7752
7753#define CHECK_ENTSIZE(section, i, type) \
1b513401 7754 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7755 sizeof (Elf64_External_##type))
7756
dda8d76d
NC
7757 for (i = 0, section = filedata->section_headers;
7758 i < filedata->file_header.e_shnum;
b34976b6 7759 i++, section++)
252b5132 7760 {
b6ac461a 7761 const char *name = printable_section_name (filedata, section);
252b5132 7762
1b513401
NC
7763 /* Run some sanity checks on the headers and
7764 possibly fill in some file data as well. */
7765 switch (section->sh_type)
252b5132 7766 {
1b513401 7767 case SHT_DYNSYM:
978c4450 7768 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7769 {
7770 error (_("File contains multiple dynamic symbol tables\n"));
7771 continue;
7772 }
7773
08d8fa11 7774 CHECK_ENTSIZE (section, i, Sym);
978c4450 7775 filedata->dynamic_symbols
4de91c10 7776 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7777 filedata->dynamic_symtab_section = section;
1b513401
NC
7778 break;
7779
7780 case SHT_STRTAB:
7781 if (streq (name, ".dynstr"))
252b5132 7782 {
1b513401
NC
7783 if (filedata->dynamic_strings != NULL)
7784 {
7785 error (_("File contains multiple dynamic string tables\n"));
7786 continue;
7787 }
7788
7789 filedata->dynamic_strings
7790 = (char *) get_data (NULL, filedata, section->sh_offset,
7791 1, section->sh_size, _("dynamic strings"));
7792 filedata->dynamic_strings_length
7793 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7794 filedata->dynamic_strtab_section = section;
252b5132 7795 }
1b513401
NC
7796 break;
7797
7798 case SHT_SYMTAB_SHNDX:
7799 {
7800 elf_section_list * entry = xmalloc (sizeof * entry);
7801
7802 entry->hdr = section;
7803 entry->next = filedata->symtab_shndx_list;
7804 filedata->symtab_shndx_list = entry;
7805 }
7806 break;
7807
7808 case SHT_SYMTAB:
7809 CHECK_ENTSIZE (section, i, Sym);
7810 break;
7811
7812 case SHT_GROUP:
7813 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7814 break;
252b5132 7815
1b513401
NC
7816 case SHT_REL:
7817 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7818 if (do_checks && section->sh_size == 0)
1b513401
NC
7819 warn (_("Section '%s': zero-sized relocation section\n"), name);
7820 break;
7821
7822 case SHT_RELA:
7823 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7824 if (do_checks && section->sh_size == 0)
1b513401
NC
7825 warn (_("Section '%s': zero-sized relocation section\n"), name);
7826 break;
7827
682351b9
AM
7828 case SHT_RELR:
7829 CHECK_ENTSIZE (section, i, Relr);
7830 break;
7831
1b513401
NC
7832 case SHT_NOTE:
7833 case SHT_PROGBITS:
546cb2d8
NC
7834 /* Having a zero sized section is not illegal according to the
7835 ELF standard, but it might be an indication that something
7836 is wrong. So issue a warning if we are running in lint mode. */
7837 if (do_checks && section->sh_size == 0)
1b513401
NC
7838 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7839 break;
7840
7841 default:
7842 break;
7843 }
7844
7845 if ((do_debugging || do_debug_info || do_debug_abbrevs
7846 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7847 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7848 || do_debug_str || do_debug_str_offsets || do_debug_loc
7849 || do_debug_ranges
1b513401 7850 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7851 && (startswith (name, ".debug_")
7852 || startswith (name, ".zdebug_")))
252b5132 7853 {
1b315056
CS
7854 if (name[1] == 'z')
7855 name += sizeof (".zdebug_") - 1;
7856 else
7857 name += sizeof (".debug_") - 1;
252b5132
RH
7858
7859 if (do_debugging
24d127aa
ML
7860 || (do_debug_info && startswith (name, "info"))
7861 || (do_debug_info && startswith (name, "types"))
7862 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7863 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7864 || (do_debug_lines && startswith (name, "line."))
7865 || (do_debug_pubnames && startswith (name, "pubnames"))
7866 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7867 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7868 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7869 || (do_debug_aranges && startswith (name, "aranges"))
7870 || (do_debug_ranges && startswith (name, "ranges"))
7871 || (do_debug_ranges && startswith (name, "rnglists"))
7872 || (do_debug_frames && startswith (name, "frame"))
7873 || (do_debug_macinfo && startswith (name, "macinfo"))
7874 || (do_debug_macinfo && startswith (name, "macro"))
7875 || (do_debug_str && startswith (name, "str"))
7876 || (do_debug_links && startswith (name, "sup"))
7877 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7878 || (do_debug_loc && startswith (name, "loc"))
7879 || (do_debug_loc && startswith (name, "loclists"))
7880 || (do_debug_addr && startswith (name, "addr"))
7881 || (do_debug_cu_index && startswith (name, "cu_index"))
7882 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7883 )
6431e409 7884 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7885 }
a262ae96 7886 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7887 else if ((do_debugging || do_debug_info)
24d127aa 7888 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7889 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7890 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7891 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
1878f44b
NC
7892 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
7893 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7894 else if (do_gdb_index && (streq (name, ".gdb_index")
7895 || streq (name, ".debug_names")))
6431e409 7896 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7897 /* Trace sections for Itanium VMS. */
7898 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7899 || do_trace_aranges)
24d127aa 7900 && startswith (name, ".trace_"))
6f875884
TG
7901 {
7902 name += sizeof (".trace_") - 1;
7903
7904 if (do_debugging
7905 || (do_trace_info && streq (name, "info"))
7906 || (do_trace_abbrevs && streq (name, "abbrev"))
7907 || (do_trace_aranges && streq (name, "aranges"))
7908 )
6431e409 7909 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7910 }
dda8d76d 7911 else if ((do_debugging || do_debug_links)
24d127aa
ML
7912 && (startswith (name, ".gnu_debuglink")
7913 || startswith (name, ".gnu_debugaltlink")))
6431e409 7914 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7915 }
7916
7917 if (! do_sections)
015dc7e1 7918 return true;
252b5132 7919
ca0e11aa 7920 if (filedata->is_separate && ! process_links)
015dc7e1 7921 return true;
ca0e11aa
NC
7922
7923 if (filedata->is_separate)
7924 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7925 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7926 printf (_("\nSection Headers:\n"));
7927 else
7928 printf (_("\nSection Header:\n"));
76da6bbe 7929
f7a99963 7930 if (is_32bit_elf)
595cf52e 7931 {
5477e8a0 7932 if (do_section_details)
595cf52e
L
7933 {
7934 printf (_(" [Nr] Name\n"));
5477e8a0 7935 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7936 }
7937 else
7938 printf
7939 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7940 }
d974e256 7941 else if (do_wide)
595cf52e 7942 {
5477e8a0 7943 if (do_section_details)
595cf52e
L
7944 {
7945 printf (_(" [Nr] Name\n"));
5477e8a0 7946 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7947 }
7948 else
7949 printf
7950 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7951 }
f7a99963
NC
7952 else
7953 {
5477e8a0 7954 if (do_section_details)
595cf52e
L
7955 {
7956 printf (_(" [Nr] Name\n"));
5477e8a0
L
7957 printf (_(" Type Address Offset Link\n"));
7958 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7959 }
7960 else
7961 {
7962 printf (_(" [Nr] Name Type Address Offset\n"));
7963 printf (_(" Size EntSize Flags Link Info Align\n"));
7964 }
f7a99963 7965 }
252b5132 7966
5477e8a0
L
7967 if (do_section_details)
7968 printf (_(" Flags\n"));
7969
dda8d76d
NC
7970 for (i = 0, section = filedata->section_headers;
7971 i < filedata->file_header.e_shnum;
b34976b6 7972 i++, section++)
252b5132 7973 {
dd905818
NC
7974 /* Run some sanity checks on the section header. */
7975
7976 /* Check the sh_link field. */
7977 switch (section->sh_type)
7978 {
285e3f99
AM
7979 case SHT_REL:
7980 case SHT_RELA:
7981 if (section->sh_link == 0
7982 && (filedata->file_header.e_type == ET_EXEC
7983 || filedata->file_header.e_type == ET_DYN))
7984 /* A dynamic relocation section where all entries use a
7985 zero symbol index need not specify a symtab section. */
7986 break;
7987 /* Fall through. */
dd905818
NC
7988 case SHT_SYMTAB_SHNDX:
7989 case SHT_GROUP:
7990 case SHT_HASH:
7991 case SHT_GNU_HASH:
7992 case SHT_GNU_versym:
285e3f99 7993 if (section->sh_link == 0
dda8d76d
NC
7994 || section->sh_link >= filedata->file_header.e_shnum
7995 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7996 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7997 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7998 i, section->sh_link);
7999 break;
8000
8001 case SHT_DYNAMIC:
8002 case SHT_SYMTAB:
8003 case SHT_DYNSYM:
8004 case SHT_GNU_verneed:
8005 case SHT_GNU_verdef:
8006 case SHT_GNU_LIBLIST:
285e3f99 8007 if (section->sh_link == 0
dda8d76d
NC
8008 || section->sh_link >= filedata->file_header.e_shnum
8009 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8010 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8011 i, section->sh_link);
8012 break;
8013
8014 case SHT_INIT_ARRAY:
8015 case SHT_FINI_ARRAY:
8016 case SHT_PREINIT_ARRAY:
8017 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8018 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8019 i, section->sh_link);
8020 break;
8021
8022 default:
8023 /* FIXME: Add support for target specific section types. */
8024#if 0 /* Currently we do not check other section types as there are too
8025 many special cases. Stab sections for example have a type
8026 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8027 section. */
8028 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8029 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8030 i, section->sh_link);
8031#endif
8032 break;
8033 }
8034
8035 /* Check the sh_info field. */
8036 switch (section->sh_type)
8037 {
8038 case SHT_REL:
8039 case SHT_RELA:
285e3f99
AM
8040 if (section->sh_info == 0
8041 && (filedata->file_header.e_type == ET_EXEC
8042 || filedata->file_header.e_type == ET_DYN))
8043 /* Dynamic relocations apply to segments, so they do not
8044 need to specify the section they relocate. */
8045 break;
8046 if (section->sh_info == 0
dda8d76d
NC
8047 || section->sh_info >= filedata->file_header.e_shnum
8048 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8049 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8050 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8051 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8052 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8053 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8054 /* FIXME: Are other section types valid ? */
dda8d76d 8055 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8056 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8057 i, section->sh_info);
dd905818
NC
8058 break;
8059
8060 case SHT_DYNAMIC:
8061 case SHT_HASH:
8062 case SHT_SYMTAB_SHNDX:
8063 case SHT_INIT_ARRAY:
8064 case SHT_FINI_ARRAY:
8065 case SHT_PREINIT_ARRAY:
8066 if (section->sh_info != 0)
8067 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8068 i, section->sh_info);
8069 break;
8070
8071 case SHT_GROUP:
8072 case SHT_SYMTAB:
8073 case SHT_DYNSYM:
8074 /* A symbol index - we assume that it is valid. */
8075 break;
8076
8077 default:
8078 /* FIXME: Add support for target specific section types. */
8079 if (section->sh_type == SHT_NOBITS)
8080 /* NOBITS section headers with non-zero sh_info fields can be
8081 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8082 information. The stripped sections have their headers
8083 preserved but their types set to SHT_NOBITS. So do not check
8084 this type of section. */
dd905818
NC
8085 ;
8086 else if (section->sh_flags & SHF_INFO_LINK)
8087 {
dda8d76d 8088 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8089 warn (_("[%2u]: Expected link to another section in info field"), i);
8090 }
a91e1603
L
8091 else if (section->sh_type < SHT_LOOS
8092 && (section->sh_flags & SHF_GNU_MBIND) == 0
8093 && section->sh_info != 0)
dd905818
NC
8094 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8095 i, section->sh_info);
8096 break;
8097 }
8098
3e6b6445 8099 /* Check the sh_size field. */
dda8d76d 8100 if (section->sh_size > filedata->file_size
3e6b6445
NC
8101 && section->sh_type != SHT_NOBITS
8102 && section->sh_type != SHT_NULL
8103 && section->sh_type < SHT_LOOS)
8104 warn (_("Size of section %u is larger than the entire file!\n"), i);
8105
7bfd842d 8106 printf (" [%2u] ", i);
5477e8a0 8107 if (do_section_details)
dda8d76d 8108 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8109 else
b6ac461a 8110 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8111
ea52a088 8112 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8113 get_section_type_name (filedata, section->sh_type));
0b4362b0 8114
f7a99963
NC
8115 if (is_32bit_elf)
8116 {
cfcac11d
NC
8117 const char * link_too_big = NULL;
8118
f7a99963 8119 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8120
f7a99963
NC
8121 printf ( " %6.6lx %6.6lx %2.2lx",
8122 (unsigned long) section->sh_offset,
8123 (unsigned long) section->sh_size,
8124 (unsigned long) section->sh_entsize);
d1133906 8125
5477e8a0
L
8126 if (do_section_details)
8127 fputs (" ", stdout);
8128 else
dda8d76d 8129 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8130
dda8d76d 8131 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8132 {
8133 link_too_big = "";
8134 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8135 an error but it can have special values in Solaris binaries. */
dda8d76d 8136 switch (filedata->file_header.e_machine)
cfcac11d 8137 {
caa83f8b 8138 case EM_386:
22abe556 8139 case EM_IAMCU:
caa83f8b 8140 case EM_X86_64:
7f502d6c 8141 case EM_L1OM:
7a9068fe 8142 case EM_K1OM:
cfcac11d
NC
8143 case EM_OLD_SPARCV9:
8144 case EM_SPARC32PLUS:
8145 case EM_SPARCV9:
8146 case EM_SPARC:
8147 if (section->sh_link == (SHN_BEFORE & 0xffff))
8148 link_too_big = "BEFORE";
8149 else if (section->sh_link == (SHN_AFTER & 0xffff))
8150 link_too_big = "AFTER";
8151 break;
8152 default:
8153 break;
8154 }
8155 }
8156
8157 if (do_section_details)
8158 {
8159 if (link_too_big != NULL && * link_too_big)
8160 printf ("<%s> ", link_too_big);
8161 else
8162 printf ("%2u ", section->sh_link);
8163 printf ("%3u %2lu\n", section->sh_info,
8164 (unsigned long) section->sh_addralign);
8165 }
8166 else
8167 printf ("%2u %3u %2lu\n",
8168 section->sh_link,
8169 section->sh_info,
8170 (unsigned long) section->sh_addralign);
8171
8172 if (link_too_big && ! * link_too_big)
8173 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8174 i, section->sh_link);
f7a99963 8175 }
d974e256
JJ
8176 else if (do_wide)
8177 {
8178 print_vma (section->sh_addr, LONG_HEX);
8179
8180 if ((long) section->sh_offset == section->sh_offset)
8181 printf (" %6.6lx", (unsigned long) section->sh_offset);
8182 else
8183 {
8184 putchar (' ');
8185 print_vma (section->sh_offset, LONG_HEX);
8186 }
8187
8188 if ((unsigned long) section->sh_size == section->sh_size)
8189 printf (" %6.6lx", (unsigned long) section->sh_size);
8190 else
8191 {
8192 putchar (' ');
8193 print_vma (section->sh_size, LONG_HEX);
8194 }
8195
8196 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8197 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8198 else
8199 {
8200 putchar (' ');
8201 print_vma (section->sh_entsize, LONG_HEX);
8202 }
8203
5477e8a0
L
8204 if (do_section_details)
8205 fputs (" ", stdout);
8206 else
dda8d76d 8207 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8208
72de5009 8209 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8210
8211 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8212 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8213 else
8214 {
8215 print_vma (section->sh_addralign, DEC);
8216 putchar ('\n');
8217 }
8218 }
5477e8a0 8219 else if (do_section_details)
595cf52e 8220 {
55cc53e9 8221 putchar (' ');
595cf52e
L
8222 print_vma (section->sh_addr, LONG_HEX);
8223 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8224 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8225 else
8226 {
8227 printf (" ");
8228 print_vma (section->sh_offset, LONG_HEX);
8229 }
72de5009 8230 printf (" %u\n ", section->sh_link);
595cf52e 8231 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8232 putchar (' ');
595cf52e
L
8233 print_vma (section->sh_entsize, LONG_HEX);
8234
72de5009
AM
8235 printf (" %-16u %lu\n",
8236 section->sh_info,
595cf52e
L
8237 (unsigned long) section->sh_addralign);
8238 }
f7a99963
NC
8239 else
8240 {
8241 putchar (' ');
8242 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8243 if ((long) section->sh_offset == section->sh_offset)
8244 printf (" %8.8lx", (unsigned long) section->sh_offset);
8245 else
8246 {
8247 printf (" ");
8248 print_vma (section->sh_offset, LONG_HEX);
8249 }
f7a99963
NC
8250 printf ("\n ");
8251 print_vma (section->sh_size, LONG_HEX);
8252 printf (" ");
8253 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8254
dda8d76d 8255 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8256
72de5009
AM
8257 printf (" %2u %3u %lu\n",
8258 section->sh_link,
8259 section->sh_info,
f7a99963
NC
8260 (unsigned long) section->sh_addralign);
8261 }
5477e8a0
L
8262
8263 if (do_section_details)
77115a4a 8264 {
dda8d76d 8265 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8266 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8267 {
8268 /* Minimum section size is 12 bytes for 32-bit compression
8269 header + 12 bytes for compressed data header. */
8270 unsigned char buf[24];
d8024a91 8271
77115a4a 8272 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8273 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8274 sizeof (buf), _("compression header")))
8275 {
8276 Elf_Internal_Chdr chdr;
d8024a91 8277
5844b465
NC
8278 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8279 printf (_(" [<corrupt>]\n"));
77115a4a 8280 else
5844b465 8281 {
89dbeac7 8282 if (chdr.ch_type == ch_compress_zlib)
5844b465 8283 printf (" ZLIB, ");
89dbeac7 8284 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8285 printf (" ZSTD, ");
5844b465
NC
8286 else
8287 printf (_(" [<unknown>: 0x%x], "),
8288 chdr.ch_type);
8289 print_vma (chdr.ch_size, LONG_HEX);
8290 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8291 }
77115a4a
L
8292 }
8293 }
8294 }
252b5132
RH
8295 }
8296
5477e8a0 8297 if (!do_section_details)
3dbcc61d 8298 {
9fb71ee4
NC
8299 /* The ordering of the letters shown here matches the ordering of the
8300 corresponding SHF_xxx values, and hence the order in which these
8301 letters will be displayed to the user. */
8302 printf (_("Key to Flags:\n\
8303 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8304 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8305 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8306 switch (filedata->file_header.e_ident[EI_OSABI])
8307 {
8308 case ELFOSABI_GNU:
8309 case ELFOSABI_FREEBSD:
8310 printf (_("R (retain), "));
8311 /* Fall through */
8312 case ELFOSABI_NONE:
8313 printf (_("D (mbind), "));
8314 break;
8315 default:
8316 break;
8317 }
dda8d76d
NC
8318 if (filedata->file_header.e_machine == EM_X86_64
8319 || filedata->file_header.e_machine == EM_L1OM
8320 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8321 printf (_("l (large), "));
dda8d76d 8322 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8323 printf (_("y (purecode), "));
dda8d76d 8324 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8325 printf (_("v (VLE), "));
9fb71ee4 8326 printf ("p (processor specific)\n");
0b4362b0 8327 }
d1133906 8328
015dc7e1 8329 return true;
252b5132
RH
8330}
8331
015dc7e1 8332static bool
28d13567 8333get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
8334 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8335 char **strtab, uint64_t *strtablen)
28d13567
AM
8336{
8337 *strtab = NULL;
8338 *strtablen = 0;
4de91c10 8339 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8340
8341 if (*symtab == NULL)
015dc7e1 8342 return false;
28d13567
AM
8343
8344 if (symsec->sh_link != 0)
8345 {
8346 Elf_Internal_Shdr *strsec;
8347
8348 if (symsec->sh_link >= filedata->file_header.e_shnum)
8349 {
8350 error (_("Bad sh_link in symbol table section\n"));
8351 free (*symtab);
8352 *symtab = NULL;
8353 *nsyms = 0;
015dc7e1 8354 return false;
28d13567
AM
8355 }
8356
8357 strsec = filedata->section_headers + symsec->sh_link;
8358
8359 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8360 1, strsec->sh_size, _("string table"));
8361 if (*strtab == NULL)
8362 {
8363 free (*symtab);
8364 *symtab = NULL;
8365 *nsyms = 0;
015dc7e1 8366 return false;
28d13567
AM
8367 }
8368 *strtablen = strsec->sh_size;
8369 }
015dc7e1 8370 return true;
28d13567
AM
8371}
8372
f5842774
L
8373static const char *
8374get_group_flags (unsigned int flags)
8375{
1449284b 8376 static char buff[128];
220453ec 8377
6d913794
NC
8378 if (flags == 0)
8379 return "";
8380 else if (flags == GRP_COMDAT)
8381 return "COMDAT ";
f5842774 8382
89246a0e
AM
8383 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8384 flags,
8385 flags & GRP_MASKOS ? _("<OS specific>") : "",
8386 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8387 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8388 ? _("<unknown>") : ""));
6d913794 8389
f5842774
L
8390 return buff;
8391}
8392
015dc7e1 8393static bool
dda8d76d 8394process_section_groups (Filedata * filedata)
f5842774 8395{
2cf0635d 8396 Elf_Internal_Shdr * section;
f5842774 8397 unsigned int i;
2cf0635d
NC
8398 struct group * group;
8399 Elf_Internal_Shdr * symtab_sec;
8400 Elf_Internal_Shdr * strtab_sec;
8401 Elf_Internal_Sym * symtab;
26c527e6 8402 uint64_t num_syms;
2cf0635d 8403 char * strtab;
c256ffe7 8404 size_t strtab_size;
d1f5c6e3
L
8405
8406 /* Don't process section groups unless needed. */
8407 if (!do_unwind && !do_section_groups)
015dc7e1 8408 return true;
f5842774 8409
dda8d76d 8410 if (filedata->file_header.e_shnum == 0)
f5842774
L
8411 {
8412 if (do_section_groups)
ca0e11aa
NC
8413 {
8414 if (filedata->is_separate)
8415 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8416 filedata->file_name);
8417 else
8418 printf (_("\nThere are no section groups in this file.\n"));
8419 }
015dc7e1 8420 return true;
f5842774
L
8421 }
8422
dda8d76d 8423 if (filedata->section_headers == NULL)
f5842774
L
8424 {
8425 error (_("Section headers are not available!\n"));
fa1908fd 8426 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8427 return false;
f5842774
L
8428 }
8429
978c4450
AM
8430 filedata->section_headers_groups
8431 = (struct group **) calloc (filedata->file_header.e_shnum,
8432 sizeof (struct group *));
e4b17d5c 8433
978c4450 8434 if (filedata->section_headers_groups == NULL)
e4b17d5c 8435 {
8b73c356 8436 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8437 filedata->file_header.e_shnum);
015dc7e1 8438 return false;
e4b17d5c
L
8439 }
8440
f5842774 8441 /* Scan the sections for the group section. */
978c4450 8442 filedata->group_count = 0;
dda8d76d
NC
8443 for (i = 0, section = filedata->section_headers;
8444 i < filedata->file_header.e_shnum;
f5842774 8445 i++, section++)
e4b17d5c 8446 if (section->sh_type == SHT_GROUP)
978c4450 8447 filedata->group_count++;
e4b17d5c 8448
978c4450 8449 if (filedata->group_count == 0)
d1f5c6e3
L
8450 {
8451 if (do_section_groups)
ca0e11aa
NC
8452 {
8453 if (filedata->is_separate)
8454 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8455 filedata->file_name);
8456 else
8457 printf (_("\nThere are no section groups in this file.\n"));
8458 }
d1f5c6e3 8459
015dc7e1 8460 return true;
d1f5c6e3
L
8461 }
8462
978c4450
AM
8463 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8464 sizeof (struct group));
e4b17d5c 8465
978c4450 8466 if (filedata->section_groups == NULL)
e4b17d5c 8467 {
26c527e6 8468 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8469 return false;
e4b17d5c
L
8470 }
8471
d1f5c6e3
L
8472 symtab_sec = NULL;
8473 strtab_sec = NULL;
8474 symtab = NULL;
ba5cdace 8475 num_syms = 0;
d1f5c6e3 8476 strtab = NULL;
c256ffe7 8477 strtab_size = 0;
ca0e11aa
NC
8478
8479 if (filedata->is_separate)
8480 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8481
978c4450 8482 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8483 i < filedata->file_header.e_shnum;
e4b17d5c 8484 i++, section++)
f5842774
L
8485 {
8486 if (section->sh_type == SHT_GROUP)
8487 {
dda8d76d 8488 const char * name = printable_section_name (filedata, section);
74e1a04b 8489 const char * group_name;
2cf0635d
NC
8490 unsigned char * start;
8491 unsigned char * indices;
f5842774 8492 unsigned int entry, j, size;
2cf0635d
NC
8493 Elf_Internal_Shdr * sec;
8494 Elf_Internal_Sym * sym;
f5842774
L
8495
8496 /* Get the symbol table. */
dda8d76d
NC
8497 if (section->sh_link >= filedata->file_header.e_shnum
8498 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8499 != SHT_SYMTAB))
f5842774
L
8500 {
8501 error (_("Bad sh_link in group section `%s'\n"), name);
8502 continue;
8503 }
d1f5c6e3
L
8504
8505 if (symtab_sec != sec)
8506 {
8507 symtab_sec = sec;
9db70fc3 8508 free (symtab);
4de91c10 8509 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8510 }
f5842774 8511
dd24e3da
NC
8512 if (symtab == NULL)
8513 {
8514 error (_("Corrupt header in group section `%s'\n"), name);
8515 continue;
8516 }
8517
ba5cdace
NC
8518 if (section->sh_info >= num_syms)
8519 {
8520 error (_("Bad sh_info in group section `%s'\n"), name);
8521 continue;
8522 }
8523
f5842774
L
8524 sym = symtab + section->sh_info;
8525
8526 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8527 {
4fbb74a6 8528 if (sym->st_shndx == 0
dda8d76d 8529 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8530 {
8531 error (_("Bad sh_info in group section `%s'\n"), name);
8532 continue;
8533 }
ba2685cc 8534
b6ac461a
NC
8535 group_name = printable_section_name (filedata,
8536 filedata->section_headers
8537 + sym->st_shndx);
c256ffe7 8538 strtab_sec = NULL;
9db70fc3 8539 free (strtab);
f5842774 8540 strtab = NULL;
c256ffe7 8541 strtab_size = 0;
f5842774
L
8542 }
8543 else
8544 {
8545 /* Get the string table. */
dda8d76d 8546 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8547 {
8548 strtab_sec = NULL;
9db70fc3 8549 free (strtab);
c256ffe7
JJ
8550 strtab = NULL;
8551 strtab_size = 0;
8552 }
8553 else if (strtab_sec
dda8d76d 8554 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8555 {
8556 strtab_sec = sec;
9db70fc3 8557 free (strtab);
071436c6 8558
dda8d76d 8559 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8560 1, strtab_sec->sh_size,
8561 _("string table"));
c256ffe7 8562 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8563 }
c256ffe7 8564 group_name = sym->st_name < strtab_size
2b692964 8565 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8566 }
8567
c9c1d674
EG
8568 /* PR 17531: file: loop. */
8569 if (section->sh_entsize > section->sh_size)
8570 {
26c527e6
AM
8571 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8572 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8573 printable_section_name (filedata, section),
26c527e6
AM
8574 section->sh_entsize,
8575 section->sh_size);
61dd8e19 8576 continue;
c9c1d674
EG
8577 }
8578
dda8d76d 8579 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8580 1, section->sh_size,
8581 _("section data"));
59245841
NC
8582 if (start == NULL)
8583 continue;
f5842774
L
8584
8585 indices = start;
8586 size = (section->sh_size / section->sh_entsize) - 1;
8587 entry = byte_get (indices, 4);
8588 indices += 4;
e4b17d5c
L
8589
8590 if (do_section_groups)
8591 {
2b692964 8592 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8593 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8594
e4b17d5c
L
8595 printf (_(" [Index] Name\n"));
8596 }
8597
8598 group->group_index = i;
8599
f5842774
L
8600 for (j = 0; j < size; j++)
8601 {
2cf0635d 8602 struct group_list * g;
e4b17d5c 8603
f5842774
L
8604 entry = byte_get (indices, 4);
8605 indices += 4;
8606
dda8d76d 8607 if (entry >= filedata->file_header.e_shnum)
391cb864 8608 {
57028622
NC
8609 static unsigned num_group_errors = 0;
8610
8611 if (num_group_errors ++ < 10)
8612 {
8613 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8614 entry, i, filedata->file_header.e_shnum - 1);
57028622 8615 if (num_group_errors == 10)
67ce483b 8616 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8617 }
391cb864
L
8618 continue;
8619 }
391cb864 8620
978c4450 8621 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8622 {
d1f5c6e3
L
8623 if (entry)
8624 {
57028622
NC
8625 static unsigned num_errs = 0;
8626
8627 if (num_errs ++ < 10)
8628 {
8629 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8630 entry, i,
978c4450 8631 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8632 if (num_errs == 10)
8633 warn (_("Further error messages about already contained group sections suppressed\n"));
8634 }
d1f5c6e3
L
8635 continue;
8636 }
8637 else
8638 {
8639 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8640 section group. We just warn it the first time
d1f5c6e3 8641 and ignore it afterwards. */
015dc7e1 8642 static bool warned = false;
d1f5c6e3
L
8643 if (!warned)
8644 {
8645 error (_("section 0 in group section [%5u]\n"),
978c4450 8646 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8647 warned = true;
d1f5c6e3
L
8648 }
8649 }
e4b17d5c
L
8650 }
8651
978c4450 8652 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8653
8654 if (do_section_groups)
8655 {
dda8d76d
NC
8656 sec = filedata->section_headers + entry;
8657 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8658 }
8659
3f5e193b 8660 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8661 g->section_index = entry;
8662 g->next = group->root;
8663 group->root = g;
f5842774
L
8664 }
8665
9db70fc3 8666 free (start);
e4b17d5c
L
8667
8668 group++;
f5842774
L
8669 }
8670 }
8671
9db70fc3
AM
8672 free (symtab);
8673 free (strtab);
015dc7e1 8674 return true;
f5842774
L
8675}
8676
28f997cf
TG
8677/* Data used to display dynamic fixups. */
8678
8679struct ia64_vms_dynfixup
8680{
625d49fc
AM
8681 uint64_t needed_ident; /* Library ident number. */
8682 uint64_t needed; /* Index in the dstrtab of the library name. */
8683 uint64_t fixup_needed; /* Index of the library. */
8684 uint64_t fixup_rela_cnt; /* Number of fixups. */
8685 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8686};
8687
8688/* Data used to display dynamic relocations. */
8689
8690struct ia64_vms_dynimgrela
8691{
625d49fc
AM
8692 uint64_t img_rela_cnt; /* Number of relocations. */
8693 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8694};
8695
8696/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8697 library). */
8698
015dc7e1 8699static bool
dda8d76d
NC
8700dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8701 struct ia64_vms_dynfixup * fixup,
8702 const char * strtab,
8703 unsigned int strtab_sz)
28f997cf 8704{
32ec8896 8705 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8706 size_t i;
32ec8896 8707 const char * lib_name;
28f997cf 8708
978c4450
AM
8709 imfs = get_data (NULL, filedata,
8710 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8711 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8712 _("dynamic section image fixups"));
8713 if (!imfs)
015dc7e1 8714 return false;
28f997cf
TG
8715
8716 if (fixup->needed < strtab_sz)
8717 lib_name = strtab + fixup->needed;
8718 else
8719 {
26c527e6
AM
8720 warn (_("corrupt library name index of %#" PRIx64
8721 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8722 lib_name = "???";
8723 }
736990c4 8724
26c527e6
AM
8725 printf (_("\nImage fixups for needed library #%" PRId64
8726 ": %s - ident: %" PRIx64 "\n"),
8727 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8728 printf
8729 (_("Seg Offset Type SymVec DataType\n"));
8730
26c527e6 8731 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8732 {
8733 unsigned int type;
8734 const char *rtype;
8735
8736 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8737 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8738 type = BYTE_GET (imfs [i].type);
8739 rtype = elf_ia64_reloc_type (type);
8740 if (rtype == NULL)
f493c217 8741 printf ("0x%08x ", type);
28f997cf 8742 else
f493c217 8743 printf ("%-32s ", rtype);
28f997cf
TG
8744 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8745 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8746 }
8747
8748 free (imfs);
015dc7e1 8749 return true;
28f997cf
TG
8750}
8751
8752/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8753
015dc7e1 8754static bool
dda8d76d 8755dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8756{
8757 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8758 size_t i;
28f997cf 8759
978c4450
AM
8760 imrs = get_data (NULL, filedata,
8761 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8762 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8763 _("dynamic section image relocations"));
28f997cf 8764 if (!imrs)
015dc7e1 8765 return false;
28f997cf
TG
8766
8767 printf (_("\nImage relocs\n"));
8768 printf
8769 (_("Seg Offset Type Addend Seg Sym Off\n"));
8770
26c527e6 8771 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8772 {
8773 unsigned int type;
8774 const char *rtype;
8775
8776 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8777 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8778 type = BYTE_GET (imrs [i].type);
8779 rtype = elf_ia64_reloc_type (type);
8780 if (rtype == NULL)
8781 printf ("0x%08x ", type);
8782 else
8783 printf ("%-31s ", rtype);
8784 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8785 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8786 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8787 }
8788
8789 free (imrs);
015dc7e1 8790 return true;
28f997cf
TG
8791}
8792
8793/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8794
015dc7e1 8795static bool
dda8d76d 8796process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8797{
8798 struct ia64_vms_dynfixup fixup;
8799 struct ia64_vms_dynimgrela imgrela;
8800 Elf_Internal_Dyn *entry;
625d49fc
AM
8801 uint64_t strtab_off = 0;
8802 uint64_t strtab_sz = 0;
28f997cf 8803 char *strtab = NULL;
015dc7e1 8804 bool res = true;
28f997cf
TG
8805
8806 memset (&fixup, 0, sizeof (fixup));
8807 memset (&imgrela, 0, sizeof (imgrela));
8808
8809 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8810 for (entry = filedata->dynamic_section;
8811 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8812 entry++)
8813 {
8814 switch (entry->d_tag)
8815 {
8816 case DT_IA_64_VMS_STRTAB_OFFSET:
8817 strtab_off = entry->d_un.d_val;
8818 break;
8819 case DT_STRSZ:
8820 strtab_sz = entry->d_un.d_val;
8821 if (strtab == NULL)
978c4450
AM
8822 strtab = get_data (NULL, filedata,
8823 filedata->dynamic_addr + strtab_off,
28f997cf 8824 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8825 if (strtab == NULL)
8826 strtab_sz = 0;
28f997cf
TG
8827 break;
8828
8829 case DT_IA_64_VMS_NEEDED_IDENT:
8830 fixup.needed_ident = entry->d_un.d_val;
8831 break;
8832 case DT_NEEDED:
8833 fixup.needed = entry->d_un.d_val;
8834 break;
8835 case DT_IA_64_VMS_FIXUP_NEEDED:
8836 fixup.fixup_needed = entry->d_un.d_val;
8837 break;
8838 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8839 fixup.fixup_rela_cnt = entry->d_un.d_val;
8840 break;
8841 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8842 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8843 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8844 res = false;
28f997cf 8845 break;
28f997cf
TG
8846 case DT_IA_64_VMS_IMG_RELA_CNT:
8847 imgrela.img_rela_cnt = entry->d_un.d_val;
8848 break;
8849 case DT_IA_64_VMS_IMG_RELA_OFF:
8850 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8851 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8852 res = false;
28f997cf
TG
8853 break;
8854
8855 default:
8856 break;
8857 }
8858 }
8859
9db70fc3 8860 free (strtab);
28f997cf
TG
8861
8862 return res;
8863}
8864
85b1c36d 8865static struct
566b0d53 8866{
2cf0635d 8867 const char * name;
566b0d53
L
8868 int reloc;
8869 int size;
a7fd1186 8870 relocation_type rel_type;
32ec8896
NC
8871}
8872 dynamic_relocations [] =
566b0d53 8873{
a7fd1186
FS
8874 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8875 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8876 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8877 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8878};
8879
252b5132 8880/* Process the reloc section. */
18bd398b 8881
015dc7e1 8882static bool
dda8d76d 8883process_relocs (Filedata * filedata)
252b5132 8884{
26c527e6
AM
8885 uint64_t rel_size;
8886 uint64_t rel_offset;
252b5132 8887
252b5132 8888 if (!do_reloc)
015dc7e1 8889 return true;
252b5132
RH
8890
8891 if (do_using_dynamic)
8892 {
a7fd1186 8893 relocation_type rel_type;
2cf0635d 8894 const char * name;
015dc7e1 8895 bool has_dynamic_reloc;
566b0d53 8896 unsigned int i;
0de14b54 8897
015dc7e1 8898 has_dynamic_reloc = false;
252b5132 8899
566b0d53 8900 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8901 {
a7fd1186 8902 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8903 name = dynamic_relocations [i].name;
978c4450
AM
8904 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8905 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8906
32ec8896 8907 if (rel_size)
015dc7e1 8908 has_dynamic_reloc = true;
566b0d53 8909
a7fd1186 8910 if (rel_type == reltype_unknown)
aa903cfb 8911 {
566b0d53 8912 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8913 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8914 {
8915 case DT_REL:
a7fd1186 8916 rel_type = reltype_rel;
566b0d53
L
8917 break;
8918 case DT_RELA:
a7fd1186 8919 rel_type = reltype_rela;
566b0d53
L
8920 break;
8921 }
aa903cfb 8922 }
252b5132 8923
566b0d53
L
8924 if (rel_size)
8925 {
ca0e11aa
NC
8926 if (filedata->is_separate)
8927 printf
26c527e6
AM
8928 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8929 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8930 filedata->file_name, name, rel_offset, rel_size);
8931 else
8932 printf
26c527e6
AM
8933 (_("\n'%s' relocation section at offset %#" PRIx64
8934 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8935 name, rel_offset, rel_size);
252b5132 8936
dda8d76d
NC
8937 dump_relocations (filedata,
8938 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8939 rel_size,
978c4450
AM
8940 filedata->dynamic_symbols,
8941 filedata->num_dynamic_syms,
8942 filedata->dynamic_strings,
8943 filedata->dynamic_strings_length,
a7fd1186 8944 rel_type, true /* is_dynamic */);
566b0d53 8945 }
252b5132 8946 }
566b0d53 8947
dda8d76d
NC
8948 if (is_ia64_vms (filedata))
8949 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8950 has_dynamic_reloc = true;
28f997cf 8951
566b0d53 8952 if (! has_dynamic_reloc)
ca0e11aa
NC
8953 {
8954 if (filedata->is_separate)
8955 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8956 filedata->file_name);
8957 else
8958 printf (_("\nThere are no dynamic relocations in this file.\n"));
8959 }
252b5132
RH
8960 }
8961 else
8962 {
2cf0635d 8963 Elf_Internal_Shdr * section;
26c527e6 8964 size_t i;
015dc7e1 8965 bool found = false;
252b5132 8966
dda8d76d
NC
8967 for (i = 0, section = filedata->section_headers;
8968 i < filedata->file_header.e_shnum;
b34976b6 8969 i++, section++)
252b5132
RH
8970 {
8971 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8972 && section->sh_type != SHT_REL
8973 && section->sh_type != SHT_RELR)
252b5132
RH
8974 continue;
8975
8976 rel_offset = section->sh_offset;
8977 rel_size = section->sh_size;
8978
8979 if (rel_size)
8980 {
a7fd1186 8981 relocation_type rel_type;
26c527e6 8982 uint64_t num_rela;
103f02d3 8983
ca0e11aa
NC
8984 if (filedata->is_separate)
8985 printf (_("\nIn linked file '%s' relocation section "),
8986 filedata->file_name);
8987 else
8988 printf (_("\nRelocation section "));
252b5132 8989
dda8d76d 8990 if (filedata->string_table == NULL)
19936277 8991 printf ("%d", section->sh_name);
252b5132 8992 else
dda8d76d 8993 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8994
d3a49aa8 8995 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8996 printf (ngettext (" at offset %#" PRIx64
8997 " contains %" PRIu64 " entry:\n",
8998 " at offset %#" PRIx64
8999 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
9000 num_rela),
9001 rel_offset, num_rela);
252b5132 9002
a7fd1186
FS
9003 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
9004 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 9005
4fbb74a6 9006 if (section->sh_link != 0
dda8d76d 9007 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 9008 {
26c527e6
AM
9009 Elf_Internal_Shdr *symsec;
9010 Elf_Internal_Sym *symtab;
9011 uint64_t nsyms;
9012 uint64_t strtablen = 0;
9013 char *strtab = NULL;
57346661 9014
dda8d76d 9015 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
9016 if (symsec->sh_type != SHT_SYMTAB
9017 && symsec->sh_type != SHT_DYNSYM)
9018 continue;
9019
28d13567
AM
9020 if (!get_symtab (filedata, symsec,
9021 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 9022 continue;
252b5132 9023
dda8d76d 9024 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 9025 symtab, nsyms, strtab, strtablen,
a7fd1186 9026 rel_type,
bb4d2ac2 9027 symsec->sh_type == SHT_DYNSYM);
9db70fc3 9028 free (strtab);
d79b3d50
NC
9029 free (symtab);
9030 }
9031 else
dda8d76d 9032 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 9033 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 9034
015dc7e1 9035 found = true;
252b5132
RH
9036 }
9037 }
9038
9039 if (! found)
45ac8f4f
NC
9040 {
9041 /* Users sometimes forget the -D option, so try to be helpful. */
9042 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9043 {
978c4450 9044 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9045 {
ca0e11aa
NC
9046 if (filedata->is_separate)
9047 printf (_("\nThere are no static relocations in linked file '%s'."),
9048 filedata->file_name);
9049 else
9050 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9051 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9052
9053 break;
9054 }
9055 }
9056 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9057 {
9058 if (filedata->is_separate)
9059 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9060 filedata->file_name);
9061 else
9062 printf (_("\nThere are no relocations in this file.\n"));
9063 }
45ac8f4f 9064 }
252b5132
RH
9065 }
9066
015dc7e1 9067 return true;
252b5132
RH
9068}
9069
4d6ed7c8
NC
9070/* An absolute address consists of a section and an offset. If the
9071 section is NULL, the offset itself is the address, otherwise, the
9072 address equals to LOAD_ADDRESS(section) + offset. */
9073
9074struct absaddr
948f632f
DA
9075{
9076 unsigned short section;
625d49fc 9077 uint64_t offset;
948f632f 9078};
4d6ed7c8 9079
948f632f
DA
9080/* Find the nearest symbol at or below ADDR. Returns the symbol
9081 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9082
4d6ed7c8 9083static void
26c527e6
AM
9084find_symbol_for_address (Filedata *filedata,
9085 Elf_Internal_Sym *symtab,
9086 uint64_t nsyms,
9087 const char *strtab,
9088 uint64_t strtab_size,
9089 struct absaddr addr,
9090 const char **symname,
9091 uint64_t *offset)
4d6ed7c8 9092{
625d49fc 9093 uint64_t dist = 0x100000;
2cf0635d 9094 Elf_Internal_Sym * sym;
948f632f
DA
9095 Elf_Internal_Sym * beg;
9096 Elf_Internal_Sym * end;
2cf0635d 9097 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9098
0b6ae522 9099 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9100 beg = symtab;
9101 end = symtab + nsyms;
0b6ae522 9102
948f632f 9103 while (beg < end)
4d6ed7c8 9104 {
625d49fc 9105 uint64_t value;
948f632f
DA
9106
9107 sym = beg + (end - beg) / 2;
0b6ae522 9108
948f632f 9109 value = sym->st_value;
0b6ae522
DJ
9110 REMOVE_ARCH_BITS (value);
9111
948f632f 9112 if (sym->st_name != 0
4d6ed7c8 9113 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9114 && addr.offset >= value
9115 && addr.offset - value < dist)
4d6ed7c8
NC
9116 {
9117 best = sym;
0b6ae522 9118 dist = addr.offset - value;
4d6ed7c8
NC
9119 if (!dist)
9120 break;
9121 }
948f632f
DA
9122
9123 if (addr.offset < value)
9124 end = sym;
9125 else
9126 beg = sym + 1;
4d6ed7c8 9127 }
1b31d05e 9128
4d6ed7c8
NC
9129 if (best)
9130 {
57346661 9131 *symname = (best->st_name >= strtab_size
2b692964 9132 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9133 *offset = dist;
9134 return;
9135 }
1b31d05e 9136
4d6ed7c8
NC
9137 *symname = NULL;
9138 *offset = addr.offset;
9139}
9140
32ec8896 9141static /* signed */ int
948f632f
DA
9142symcmp (const void *p, const void *q)
9143{
9144 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9145 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9146
9147 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9148}
9149
9150/* Process the unwind section. */
9151
9152#include "unwind-ia64.h"
9153
9154struct ia64_unw_table_entry
9155{
9156 struct absaddr start;
9157 struct absaddr end;
9158 struct absaddr info;
9159};
9160
9161struct ia64_unw_aux_info
9162{
32ec8896 9163 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9164 uint64_t table_len; /* Length of unwind table. */
32ec8896 9165 unsigned char * info; /* Unwind info. */
26c527e6 9166 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9167 uint64_t info_addr; /* Starting address of unwind info. */
9168 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9169 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9170 uint64_t nsyms; /* Number of symbols. */
32ec8896 9171 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9172 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9173 char * strtab; /* The string table. */
26c527e6 9174 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9175};
9176
015dc7e1 9177static bool
dda8d76d 9178dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9179{
2cf0635d 9180 struct ia64_unw_table_entry * tp;
26c527e6 9181 size_t j, nfuns;
4d6ed7c8 9182 int in_body;
015dc7e1 9183 bool res = true;
7036c0e1 9184
948f632f
DA
9185 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9186 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9187 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9188 aux->funtab[nfuns++] = aux->symtab[j];
9189 aux->nfuns = nfuns;
9190 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9191
4d6ed7c8
NC
9192 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9193 {
625d49fc
AM
9194 uint64_t stamp;
9195 uint64_t offset;
2cf0635d
NC
9196 const unsigned char * dp;
9197 const unsigned char * head;
53774b7e 9198 const unsigned char * end;
2cf0635d 9199 const char * procname;
4d6ed7c8 9200
dda8d76d 9201 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9202 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9203
9204 fputs ("\n<", stdout);
9205
9206 if (procname)
9207 {
9208 fputs (procname, stdout);
9209
9210 if (offset)
26c527e6 9211 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9212 }
9213
9214 fputs (">: [", stdout);
9215 print_vma (tp->start.offset, PREFIX_HEX);
9216 fputc ('-', stdout);
9217 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9218 printf ("], info at +0x%" PRIx64 "\n",
9219 tp->info.offset - aux->seg_base);
4d6ed7c8 9220
53774b7e
NC
9221 /* PR 17531: file: 86232b32. */
9222 if (aux->info == NULL)
9223 continue;
9224
97c0a079
AM
9225 offset = tp->info.offset;
9226 if (tp->info.section)
9227 {
9228 if (tp->info.section >= filedata->file_header.e_shnum)
9229 {
26c527e6
AM
9230 warn (_("Invalid section %u in table entry %td\n"),
9231 tp->info.section, tp - aux->table);
015dc7e1 9232 res = false;
97c0a079
AM
9233 continue;
9234 }
9235 offset += filedata->section_headers[tp->info.section].sh_addr;
9236 }
9237 offset -= aux->info_addr;
53774b7e 9238 /* PR 17531: file: 0997b4d1. */
90679903
AM
9239 if (offset >= aux->info_size
9240 || aux->info_size - offset < 8)
53774b7e 9241 {
26c527e6
AM
9242 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9243 tp->info.offset, tp - aux->table);
015dc7e1 9244 res = false;
53774b7e
NC
9245 continue;
9246 }
9247
97c0a079 9248 head = aux->info + offset;
a4a00738 9249 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9250
86f55779 9251 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9252 (unsigned) UNW_VER (stamp),
9253 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9254 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9255 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9256 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9257
9258 if (UNW_VER (stamp) != 1)
9259 {
2b692964 9260 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9261 continue;
9262 }
9263
9264 in_body = 0;
53774b7e
NC
9265 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9266 /* PR 17531: file: 16ceda89. */
9267 if (end > aux->info + aux->info_size)
9268 end = aux->info + aux->info_size;
9269 for (dp = head + 8; dp < end;)
b4477bc8 9270 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9271 }
948f632f
DA
9272
9273 free (aux->funtab);
32ec8896
NC
9274
9275 return res;
4d6ed7c8
NC
9276}
9277
015dc7e1 9278static bool
dda8d76d
NC
9279slurp_ia64_unwind_table (Filedata * filedata,
9280 struct ia64_unw_aux_info * aux,
9281 Elf_Internal_Shdr * sec)
4d6ed7c8 9282{
26c527e6 9283 uint64_t size, nrelas, i;
2cf0635d
NC
9284 Elf_Internal_Phdr * seg;
9285 struct ia64_unw_table_entry * tep;
9286 Elf_Internal_Shdr * relsec;
9287 Elf_Internal_Rela * rela;
9288 Elf_Internal_Rela * rp;
9289 unsigned char * table;
9290 unsigned char * tp;
9291 Elf_Internal_Sym * sym;
9292 const char * relname;
4d6ed7c8 9293
53774b7e
NC
9294 aux->table_len = 0;
9295
4d6ed7c8
NC
9296 /* First, find the starting address of the segment that includes
9297 this section: */
9298
dda8d76d 9299 if (filedata->file_header.e_phnum)
4d6ed7c8 9300 {
dda8d76d 9301 if (! get_program_headers (filedata))
015dc7e1 9302 return false;
4d6ed7c8 9303
dda8d76d
NC
9304 for (seg = filedata->program_headers;
9305 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9306 ++seg)
4d6ed7c8
NC
9307 {
9308 if (seg->p_type != PT_LOAD)
9309 continue;
9310
9311 if (sec->sh_addr >= seg->p_vaddr
9312 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9313 {
9314 aux->seg_base = seg->p_vaddr;
9315 break;
9316 }
9317 }
4d6ed7c8
NC
9318 }
9319
9320 /* Second, build the unwind table from the contents of the unwind section: */
9321 size = sec->sh_size;
dda8d76d 9322 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9323 _("unwind table"));
a6e9f9df 9324 if (!table)
015dc7e1 9325 return false;
4d6ed7c8 9326
53774b7e 9327 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9328 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9329 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9330 tep = aux->table;
53774b7e
NC
9331
9332 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9333 {
9334 tep->start.section = SHN_UNDEF;
9335 tep->end.section = SHN_UNDEF;
9336 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9337 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9338 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9339 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9340 tep->start.offset += aux->seg_base;
9341 tep->end.offset += aux->seg_base;
9342 tep->info.offset += aux->seg_base;
9343 }
9344 free (table);
9345
41e92641 9346 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9347 for (relsec = filedata->section_headers;
9348 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9349 ++relsec)
9350 {
9351 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9352 || relsec->sh_info >= filedata->file_header.e_shnum
9353 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9354 continue;
9355
dda8d76d 9356 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9357 & rela, & nrelas))
53774b7e
NC
9358 {
9359 free (aux->table);
9360 aux->table = NULL;
9361 aux->table_len = 0;
015dc7e1 9362 return false;
53774b7e 9363 }
4d6ed7c8
NC
9364
9365 for (rp = rela; rp < rela + nrelas; ++rp)
9366 {
4770fb94 9367 unsigned int sym_ndx;
726bd37d
AM
9368 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9369 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9370
82b1b41b
NC
9371 /* PR 17531: file: 9fa67536. */
9372 if (relname == NULL)
9373 {
726bd37d 9374 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9375 continue;
9376 }
948f632f 9377
24d127aa 9378 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9379 {
82b1b41b 9380 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9381 continue;
9382 }
9383
89fac5e3 9384 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9385
53774b7e
NC
9386 /* PR 17531: file: 5bc8d9bf. */
9387 if (i >= aux->table_len)
9388 {
26c527e6
AM
9389 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9390 i);
53774b7e
NC
9391 continue;
9392 }
9393
4770fb94
AM
9394 sym_ndx = get_reloc_symindex (rp->r_info);
9395 if (sym_ndx >= aux->nsyms)
9396 {
9397 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9398 sym_ndx);
9399 continue;
9400 }
9401 sym = aux->symtab + sym_ndx;
9402
53774b7e 9403 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9404 {
9405 case 0:
9406 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9407 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9408 break;
9409 case 1:
9410 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9411 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9412 break;
9413 case 2:
9414 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9415 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9416 break;
9417 default:
9418 break;
9419 }
9420 }
9421
9422 free (rela);
9423 }
9424
015dc7e1 9425 return true;
4d6ed7c8
NC
9426}
9427
015dc7e1 9428static bool
dda8d76d 9429ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9430{
2cf0635d
NC
9431 Elf_Internal_Shdr * sec;
9432 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9433 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9434 struct ia64_unw_aux_info aux;
015dc7e1 9435 bool res = true;
f1467e33 9436
4d6ed7c8
NC
9437 memset (& aux, 0, sizeof (aux));
9438
dda8d76d 9439 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9440 {
28d13567 9441 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9442 {
28d13567 9443 if (aux.symtab)
4082ef84 9444 {
28d13567
AM
9445 error (_("Multiple symbol tables encountered\n"));
9446 free (aux.symtab);
9447 aux.symtab = NULL;
4082ef84 9448 free (aux.strtab);
28d13567 9449 aux.strtab = NULL;
4082ef84 9450 }
28d13567
AM
9451 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9452 &aux.strtab, &aux.strtab_size))
015dc7e1 9453 return false;
4d6ed7c8
NC
9454 }
9455 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9456 unwcount++;
9457 }
9458
9459 if (!unwcount)
9460 printf (_("\nThere are no unwind sections in this file.\n"));
9461
9462 while (unwcount-- > 0)
9463 {
84714f86 9464 const char *suffix;
579f31ac
JJ
9465 size_t len, len2;
9466
dda8d76d
NC
9467 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9468 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9469 if (sec->sh_type == SHT_IA_64_UNWIND)
9470 {
9471 unwsec = sec;
9472 break;
9473 }
4082ef84
NC
9474 /* We have already counted the number of SHT_IA64_UNWIND
9475 sections so the loop above should never fail. */
9476 assert (unwsec != NULL);
579f31ac
JJ
9477
9478 unwstart = i + 1;
9479 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9480
e4b17d5c
L
9481 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9482 {
9483 /* We need to find which section group it is in. */
4082ef84 9484 struct group_list * g;
e4b17d5c 9485
978c4450
AM
9486 if (filedata->section_headers_groups == NULL
9487 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9488 i = filedata->file_header.e_shnum;
4082ef84 9489 else
e4b17d5c 9490 {
978c4450 9491 g = filedata->section_headers_groups[i]->root;
18bd398b 9492
4082ef84
NC
9493 for (; g != NULL; g = g->next)
9494 {
dda8d76d 9495 sec = filedata->section_headers + g->section_index;
e4b17d5c 9496
84714f86
AM
9497 if (section_name_valid (filedata, sec)
9498 && streq (section_name (filedata, sec),
9499 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9500 break;
9501 }
9502
9503 if (g == NULL)
dda8d76d 9504 i = filedata->file_header.e_shnum;
4082ef84 9505 }
e4b17d5c 9506 }
84714f86
AM
9507 else if (section_name_valid (filedata, unwsec)
9508 && startswith (section_name (filedata, unwsec),
e9b095a5 9509 ELF_STRING_ia64_unwind_once))
579f31ac 9510 {
18bd398b 9511 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9512 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9513 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9514 for (i = 0, sec = filedata->section_headers;
9515 i < filedata->file_header.e_shnum;
579f31ac 9516 ++i, ++sec)
84714f86
AM
9517 if (section_name_valid (filedata, sec)
9518 && startswith (section_name (filedata, sec),
e9b095a5 9519 ELF_STRING_ia64_unwind_info_once)
84714f86 9520 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9521 break;
9522 }
9523 else
9524 {
9525 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9526 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9527 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9528 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9529 suffix = "";
84714f86
AM
9530 if (section_name_valid (filedata, unwsec)
9531 && startswith (section_name (filedata, unwsec),
9532 ELF_STRING_ia64_unwind))
9533 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9534 for (i = 0, sec = filedata->section_headers;
9535 i < filedata->file_header.e_shnum;
579f31ac 9536 ++i, ++sec)
84714f86
AM
9537 if (section_name_valid (filedata, sec)
9538 && startswith (section_name (filedata, sec),
9539 ELF_STRING_ia64_unwind_info)
9540 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9541 break;
9542 }
9543
dda8d76d 9544 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9545 {
9546 printf (_("\nCould not find unwind info section for "));
9547
dda8d76d 9548 if (filedata->string_table == NULL)
579f31ac
JJ
9549 printf ("%d", unwsec->sh_name);
9550 else
dda8d76d 9551 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9552 }
9553 else
4d6ed7c8 9554 {
4d6ed7c8 9555 aux.info_addr = sec->sh_addr;
dda8d76d 9556 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9557 sec->sh_size,
9558 _("unwind info"));
59245841 9559 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9560
579f31ac 9561 printf (_("\nUnwind section "));
4d6ed7c8 9562
dda8d76d 9563 if (filedata->string_table == NULL)
579f31ac
JJ
9564 printf ("%d", unwsec->sh_name);
9565 else
dda8d76d 9566 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9567
26c527e6
AM
9568 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9569 unwsec->sh_offset,
9570 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9571
dda8d76d 9572 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9573 && aux.table_len > 0)
dda8d76d 9574 dump_ia64_unwind (filedata, & aux);
579f31ac 9575
9db70fc3
AM
9576 free ((char *) aux.table);
9577 free ((char *) aux.info);
579f31ac
JJ
9578 aux.table = NULL;
9579 aux.info = NULL;
9580 }
4d6ed7c8 9581 }
4d6ed7c8 9582
9db70fc3
AM
9583 free (aux.symtab);
9584 free ((char *) aux.strtab);
32ec8896
NC
9585
9586 return res;
4d6ed7c8
NC
9587}
9588
3f5e193b 9589struct hppa_unw_table_entry
32ec8896
NC
9590{
9591 struct absaddr start;
9592 struct absaddr end;
9593 unsigned int Cannot_unwind:1; /* 0 */
9594 unsigned int Millicode:1; /* 1 */
9595 unsigned int Millicode_save_sr0:1; /* 2 */
9596 unsigned int Region_description:2; /* 3..4 */
9597 unsigned int reserved1:1; /* 5 */
9598 unsigned int Entry_SR:1; /* 6 */
9599 unsigned int Entry_FR:4; /* Number saved 7..10 */
9600 unsigned int Entry_GR:5; /* Number saved 11..15 */
9601 unsigned int Args_stored:1; /* 16 */
9602 unsigned int Variable_Frame:1; /* 17 */
9603 unsigned int Separate_Package_Body:1; /* 18 */
9604 unsigned int Frame_Extension_Millicode:1; /* 19 */
9605 unsigned int Stack_Overflow_Check:1; /* 20 */
9606 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9607 unsigned int Ada_Region:1; /* 22 */
9608 unsigned int cxx_info:1; /* 23 */
9609 unsigned int cxx_try_catch:1; /* 24 */
9610 unsigned int sched_entry_seq:1; /* 25 */
9611 unsigned int reserved2:1; /* 26 */
9612 unsigned int Save_SP:1; /* 27 */
9613 unsigned int Save_RP:1; /* 28 */
9614 unsigned int Save_MRP_in_frame:1; /* 29 */
9615 unsigned int extn_ptr_defined:1; /* 30 */
9616 unsigned int Cleanup_defined:1; /* 31 */
9617
9618 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9619 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9620 unsigned int Large_frame:1; /* 2 */
9621 unsigned int Pseudo_SP_Set:1; /* 3 */
9622 unsigned int reserved4:1; /* 4 */
9623 unsigned int Total_frame_size:27; /* 5..31 */
9624};
3f5e193b 9625
57346661 9626struct hppa_unw_aux_info
948f632f 9627{
32ec8896 9628 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9629 uint64_t table_len; /* Length of unwind table. */
625d49fc 9630 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9631 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9632 uint64_t nsyms; /* Number of symbols. */
32ec8896 9633 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9634 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9635 char * strtab; /* The string table. */
26c527e6 9636 uint64_t strtab_size; /* Size of string table. */
948f632f 9637};
57346661 9638
015dc7e1 9639static bool
dda8d76d 9640dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9641{
2cf0635d 9642 struct hppa_unw_table_entry * tp;
26c527e6 9643 uint64_t j, nfuns;
015dc7e1 9644 bool res = true;
948f632f
DA
9645
9646 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9647 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9648 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9649 aux->funtab[nfuns++] = aux->symtab[j];
9650 aux->nfuns = nfuns;
9651 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9652
57346661
AM
9653 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9654 {
625d49fc 9655 uint64_t offset;
2cf0635d 9656 const char * procname;
57346661 9657
dda8d76d 9658 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9659 aux->strtab_size, tp->start, &procname,
9660 &offset);
9661
9662 fputs ("\n<", stdout);
9663
9664 if (procname)
9665 {
9666 fputs (procname, stdout);
9667
9668 if (offset)
26c527e6 9669 printf ("+%" PRIx64, offset);
57346661
AM
9670 }
9671
9672 fputs (">: [", stdout);
9673 print_vma (tp->start.offset, PREFIX_HEX);
9674 fputc ('-', stdout);
9675 print_vma (tp->end.offset, PREFIX_HEX);
9676 printf ("]\n\t");
9677
18bd398b
NC
9678#define PF(_m) if (tp->_m) printf (#_m " ");
9679#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9680 PF(Cannot_unwind);
9681 PF(Millicode);
9682 PF(Millicode_save_sr0);
18bd398b 9683 /* PV(Region_description); */
57346661
AM
9684 PF(Entry_SR);
9685 PV(Entry_FR);
9686 PV(Entry_GR);
9687 PF(Args_stored);
9688 PF(Variable_Frame);
9689 PF(Separate_Package_Body);
9690 PF(Frame_Extension_Millicode);
9691 PF(Stack_Overflow_Check);
9692 PF(Two_Instruction_SP_Increment);
9693 PF(Ada_Region);
9694 PF(cxx_info);
9695 PF(cxx_try_catch);
9696 PF(sched_entry_seq);
9697 PF(Save_SP);
9698 PF(Save_RP);
9699 PF(Save_MRP_in_frame);
9700 PF(extn_ptr_defined);
9701 PF(Cleanup_defined);
9702 PF(MPE_XL_interrupt_marker);
9703 PF(HP_UX_interrupt_marker);
9704 PF(Large_frame);
9705 PF(Pseudo_SP_Set);
9706 PV(Total_frame_size);
9707#undef PF
9708#undef PV
9709 }
9710
18bd398b 9711 printf ("\n");
948f632f
DA
9712
9713 free (aux->funtab);
32ec8896
NC
9714
9715 return res;
57346661
AM
9716}
9717
015dc7e1 9718static bool
dda8d76d
NC
9719slurp_hppa_unwind_table (Filedata * filedata,
9720 struct hppa_unw_aux_info * aux,
9721 Elf_Internal_Shdr * sec)
57346661 9722{
26c527e6 9723 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9724 Elf_Internal_Phdr * seg;
9725 struct hppa_unw_table_entry * tep;
9726 Elf_Internal_Shdr * relsec;
9727 Elf_Internal_Rela * rela;
9728 Elf_Internal_Rela * rp;
9729 unsigned char * table;
9730 unsigned char * tp;
9731 Elf_Internal_Sym * sym;
9732 const char * relname;
57346661 9733
57346661
AM
9734 /* First, find the starting address of the segment that includes
9735 this section. */
dda8d76d 9736 if (filedata->file_header.e_phnum)
57346661 9737 {
dda8d76d 9738 if (! get_program_headers (filedata))
015dc7e1 9739 return false;
57346661 9740
dda8d76d
NC
9741 for (seg = filedata->program_headers;
9742 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9743 ++seg)
9744 {
9745 if (seg->p_type != PT_LOAD)
9746 continue;
9747
9748 if (sec->sh_addr >= seg->p_vaddr
9749 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9750 {
9751 aux->seg_base = seg->p_vaddr;
9752 break;
9753 }
9754 }
9755 }
9756
9757 /* Second, build the unwind table from the contents of the unwind
9758 section. */
9759 size = sec->sh_size;
dda8d76d 9760 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9761 _("unwind table"));
57346661 9762 if (!table)
015dc7e1 9763 return false;
57346661 9764
1c0751b2
DA
9765 unw_ent_size = 16;
9766 nentries = size / unw_ent_size;
9767 size = unw_ent_size * nentries;
57346661 9768
e3fdc001 9769 aux->table_len = nentries;
3f5e193b
NC
9770 tep = aux->table = (struct hppa_unw_table_entry *)
9771 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9772
1c0751b2 9773 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9774 {
9775 unsigned int tmp1, tmp2;
9776
9777 tep->start.section = SHN_UNDEF;
9778 tep->end.section = SHN_UNDEF;
9779
1c0751b2
DA
9780 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9781 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9782 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9783 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9784
9785 tep->start.offset += aux->seg_base;
9786 tep->end.offset += aux->seg_base;
57346661
AM
9787
9788 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9789 tep->Millicode = (tmp1 >> 30) & 0x1;
9790 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9791 tep->Region_description = (tmp1 >> 27) & 0x3;
9792 tep->reserved1 = (tmp1 >> 26) & 0x1;
9793 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9794 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9795 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9796 tep->Args_stored = (tmp1 >> 15) & 0x1;
9797 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9798 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9799 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9800 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9801 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9802 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9803 tep->cxx_info = (tmp1 >> 8) & 0x1;
9804 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9805 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9806 tep->reserved2 = (tmp1 >> 5) & 0x1;
9807 tep->Save_SP = (tmp1 >> 4) & 0x1;
9808 tep->Save_RP = (tmp1 >> 3) & 0x1;
9809 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9810 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9811 tep->Cleanup_defined = tmp1 & 0x1;
9812
9813 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9814 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9815 tep->Large_frame = (tmp2 >> 29) & 0x1;
9816 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9817 tep->reserved4 = (tmp2 >> 27) & 0x1;
9818 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9819 }
9820 free (table);
9821
9822 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9823 for (relsec = filedata->section_headers;
9824 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9825 ++relsec)
9826 {
9827 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9828 || relsec->sh_info >= filedata->file_header.e_shnum
9829 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9830 continue;
9831
dda8d76d 9832 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9833 & rela, & nrelas))
015dc7e1 9834 return false;
57346661
AM
9835
9836 for (rp = rela; rp < rela + nrelas; ++rp)
9837 {
4770fb94 9838 unsigned int sym_ndx;
726bd37d
AM
9839 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9840 relname = elf_hppa_reloc_type (r_type);
57346661 9841
726bd37d
AM
9842 if (relname == NULL)
9843 {
9844 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9845 continue;
9846 }
9847
57346661 9848 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9849 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9850 {
726bd37d 9851 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9852 continue;
9853 }
9854
9855 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9856 if (i >= aux->table_len)
9857 {
26c527e6
AM
9858 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9859 i);
726bd37d
AM
9860 continue;
9861 }
57346661 9862
4770fb94
AM
9863 sym_ndx = get_reloc_symindex (rp->r_info);
9864 if (sym_ndx >= aux->nsyms)
9865 {
9866 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9867 sym_ndx);
9868 continue;
9869 }
9870 sym = aux->symtab + sym_ndx;
9871
43f6cd05 9872 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9873 {
9874 case 0:
9875 aux->table[i].start.section = sym->st_shndx;
1e456d54 9876 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9877 break;
9878 case 1:
9879 aux->table[i].end.section = sym->st_shndx;
1e456d54 9880 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9881 break;
9882 default:
9883 break;
9884 }
9885 }
9886
9887 free (rela);
9888 }
9889
015dc7e1 9890 return true;
57346661
AM
9891}
9892
015dc7e1 9893static bool
dda8d76d 9894hppa_process_unwind (Filedata * filedata)
57346661 9895{
57346661 9896 struct hppa_unw_aux_info aux;
2cf0635d 9897 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9898 Elf_Internal_Shdr * sec;
26c527e6 9899 size_t i;
015dc7e1 9900 bool res = true;
57346661 9901
dda8d76d 9902 if (filedata->string_table == NULL)
015dc7e1 9903 return false;
1b31d05e
NC
9904
9905 memset (& aux, 0, sizeof (aux));
57346661 9906
dda8d76d 9907 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9908 {
28d13567 9909 if (sec->sh_type == SHT_SYMTAB)
57346661 9910 {
28d13567 9911 if (aux.symtab)
4082ef84 9912 {
28d13567
AM
9913 error (_("Multiple symbol tables encountered\n"));
9914 free (aux.symtab);
9915 aux.symtab = NULL;
4082ef84 9916 free (aux.strtab);
28d13567 9917 aux.strtab = NULL;
4082ef84 9918 }
28d13567
AM
9919 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9920 &aux.strtab, &aux.strtab_size))
015dc7e1 9921 return false;
57346661 9922 }
84714f86
AM
9923 else if (section_name_valid (filedata, sec)
9924 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9925 unwsec = sec;
9926 }
9927
9928 if (!unwsec)
9929 printf (_("\nThere are no unwind sections in this file.\n"));
9930
dda8d76d 9931 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9932 {
84714f86
AM
9933 if (section_name_valid (filedata, sec)
9934 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9935 {
26c527e6 9936 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9937
26c527e6
AM
9938 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9939 "contains %" PRIu64 " entry:\n",
9940 "\nUnwind section '%s' at offset %#" PRIx64 " "
9941 "contains %" PRIu64 " entries:\n",
d3a49aa8 9942 num_unwind),
dda8d76d 9943 printable_section_name (filedata, sec),
26c527e6 9944 sec->sh_offset,
d3a49aa8 9945 num_unwind);
57346661 9946
dda8d76d 9947 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9948 res = false;
66b09c7e
S
9949
9950 if (res && aux.table_len > 0)
32ec8896 9951 {
dda8d76d 9952 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9953 res = false;
32ec8896 9954 }
57346661 9955
9db70fc3 9956 free ((char *) aux.table);
57346661
AM
9957 aux.table = NULL;
9958 }
9959 }
9960
9db70fc3
AM
9961 free (aux.symtab);
9962 free ((char *) aux.strtab);
32ec8896
NC
9963
9964 return res;
57346661
AM
9965}
9966
0b6ae522
DJ
9967struct arm_section
9968{
a734115a
NC
9969 unsigned char * data; /* The unwind data. */
9970 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9971 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9972 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9973 unsigned int rel_type; /* REL or RELA ? */
9974 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9975};
9976
9977struct arm_unw_aux_info
9978{
dda8d76d 9979 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9980 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9981 uint64_t nsyms; /* Number of symbols. */
948f632f 9982 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9983 uint64_t nfuns; /* Number of these symbols. */
a734115a 9984 char * strtab; /* The file's string table. */
26c527e6 9985 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9986};
9987
9988static const char *
dda8d76d
NC
9989arm_print_vma_and_name (Filedata * filedata,
9990 struct arm_unw_aux_info * aux,
625d49fc 9991 uint64_t fn,
dda8d76d 9992 struct absaddr addr)
0b6ae522
DJ
9993{
9994 const char *procname;
625d49fc 9995 uint64_t sym_offset;
0b6ae522
DJ
9996
9997 if (addr.section == SHN_UNDEF)
9998 addr.offset = fn;
9999
dda8d76d 10000 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
10001 aux->strtab_size, addr, &procname,
10002 &sym_offset);
10003
10004 print_vma (fn, PREFIX_HEX);
10005
10006 if (procname)
10007 {
10008 fputs (" <", stdout);
10009 fputs (procname, stdout);
10010
10011 if (sym_offset)
26c527e6 10012 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10013 fputc ('>', stdout);
10014 }
10015
10016 return procname;
10017}
10018
10019static void
10020arm_free_section (struct arm_section *arm_sec)
10021{
9db70fc3
AM
10022 free (arm_sec->data);
10023 free (arm_sec->rela);
0b6ae522
DJ
10024}
10025
a734115a
NC
10026/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10027 cached section and install SEC instead.
10028 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10029 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10030 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10031 relocation's offset in ADDR.
1b31d05e
NC
10032 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10033 into the string table of the symbol associated with the reloc. If no
10034 reloc was applied store -1 there.
10035 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10036
015dc7e1 10037static bool
dda8d76d
NC
10038get_unwind_section_word (Filedata * filedata,
10039 struct arm_unw_aux_info * aux,
1b31d05e
NC
10040 struct arm_section * arm_sec,
10041 Elf_Internal_Shdr * sec,
625d49fc 10042 uint64_t word_offset,
1b31d05e
NC
10043 unsigned int * wordp,
10044 struct absaddr * addr,
625d49fc 10045 uint64_t * sym_name)
0b6ae522
DJ
10046{
10047 Elf_Internal_Rela *rp;
10048 Elf_Internal_Sym *sym;
10049 const char * relname;
10050 unsigned int word;
015dc7e1 10051 bool wrapped;
0b6ae522 10052
e0a31db1 10053 if (sec == NULL || arm_sec == NULL)
015dc7e1 10054 return false;
e0a31db1 10055
0b6ae522
DJ
10056 addr->section = SHN_UNDEF;
10057 addr->offset = 0;
10058
1b31d05e 10059 if (sym_name != NULL)
625d49fc 10060 *sym_name = (uint64_t) -1;
1b31d05e 10061
a734115a 10062 /* If necessary, update the section cache. */
0b6ae522
DJ
10063 if (sec != arm_sec->sec)
10064 {
10065 Elf_Internal_Shdr *relsec;
10066
10067 arm_free_section (arm_sec);
10068
10069 arm_sec->sec = sec;
dda8d76d 10070 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10071 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10072 arm_sec->rela = NULL;
10073 arm_sec->nrelas = 0;
10074
dda8d76d
NC
10075 for (relsec = filedata->section_headers;
10076 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10077 ++relsec)
10078 {
dda8d76d
NC
10079 if (relsec->sh_info >= filedata->file_header.e_shnum
10080 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10081 /* PR 15745: Check the section type as well. */
10082 || (relsec->sh_type != SHT_REL
10083 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10084 continue;
10085
a734115a 10086 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10087 if (relsec->sh_type == SHT_REL)
10088 {
dda8d76d 10089 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10090 relsec->sh_size,
10091 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10092 return false;
0b6ae522 10093 }
1ae40aa4 10094 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10095 {
dda8d76d 10096 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10097 relsec->sh_size,
10098 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10099 return false;
0b6ae522 10100 }
1ae40aa4 10101 break;
0b6ae522
DJ
10102 }
10103
10104 arm_sec->next_rela = arm_sec->rela;
10105 }
10106
a734115a 10107 /* If there is no unwind data we can do nothing. */
0b6ae522 10108 if (arm_sec->data == NULL)
015dc7e1 10109 return false;
0b6ae522 10110
e0a31db1 10111 /* If the offset is invalid then fail. */
f32ba729
NC
10112 if (/* PR 21343 *//* PR 18879 */
10113 sec->sh_size < 4
625d49fc 10114 || word_offset > sec->sh_size - 4)
015dc7e1 10115 return false;
e0a31db1 10116
a734115a 10117 /* Get the word at the required offset. */
0b6ae522
DJ
10118 word = byte_get (arm_sec->data + word_offset, 4);
10119
0eff7165
NC
10120 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10121 if (arm_sec->rela == NULL)
10122 {
10123 * wordp = word;
015dc7e1 10124 return true;
0eff7165
NC
10125 }
10126
a734115a 10127 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10128 wrapped = false;
0b6ae522
DJ
10129 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10130 {
625d49fc 10131 uint64_t prelval, offset;
0b6ae522
DJ
10132
10133 if (rp->r_offset > word_offset && !wrapped)
10134 {
10135 rp = arm_sec->rela;
015dc7e1 10136 wrapped = true;
0b6ae522
DJ
10137 }
10138 if (rp->r_offset > word_offset)
10139 break;
10140
10141 if (rp->r_offset & 3)
10142 {
26c527e6
AM
10143 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10144 rp->r_offset);
0b6ae522
DJ
10145 continue;
10146 }
10147
10148 if (rp->r_offset < word_offset)
10149 continue;
10150
74e1a04b
NC
10151 /* PR 17531: file: 027-161405-0.004 */
10152 if (aux->symtab == NULL)
10153 continue;
10154
0b6ae522
DJ
10155 if (arm_sec->rel_type == SHT_REL)
10156 {
10157 offset = word & 0x7fffffff;
10158 if (offset & 0x40000000)
625d49fc 10159 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10160 }
a734115a 10161 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10162 offset = rp->r_addend;
a734115a 10163 else
74e1a04b
NC
10164 {
10165 error (_("Unknown section relocation type %d encountered\n"),
10166 arm_sec->rel_type);
10167 break;
10168 }
0b6ae522 10169
071436c6
NC
10170 /* PR 17531 file: 027-1241568-0.004. */
10171 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10172 {
26c527e6
AM
10173 error (_("Bad symbol index in unwind relocation "
10174 "(%" PRIu64 " > %" PRIu64 ")\n"),
10175 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10176 break;
10177 }
10178
10179 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10180 offset += sym->st_value;
10181 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10182
a734115a 10183 /* Check that we are processing the expected reloc type. */
dda8d76d 10184 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10185 {
10186 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10187 if (relname == NULL)
10188 {
10189 warn (_("Skipping unknown ARM relocation type: %d\n"),
10190 (int) ELF32_R_TYPE (rp->r_info));
10191 continue;
10192 }
a734115a
NC
10193
10194 if (streq (relname, "R_ARM_NONE"))
10195 continue;
0b4362b0 10196
a734115a
NC
10197 if (! streq (relname, "R_ARM_PREL31"))
10198 {
071436c6 10199 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10200 continue;
10201 }
10202 }
dda8d76d 10203 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10204 {
10205 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10206 if (relname == NULL)
10207 {
10208 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10209 (int) ELF32_R_TYPE (rp->r_info));
10210 continue;
10211 }
0b4362b0 10212
a734115a
NC
10213 if (streq (relname, "R_C6000_NONE"))
10214 continue;
10215
10216 if (! streq (relname, "R_C6000_PREL31"))
10217 {
071436c6 10218 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10219 continue;
10220 }
10221
10222 prelval >>= 1;
10223 }
10224 else
74e1a04b
NC
10225 {
10226 /* This function currently only supports ARM and TI unwinders. */
10227 warn (_("Only TI and ARM unwinders are currently supported\n"));
10228 break;
10229 }
fa197c1c 10230
625d49fc 10231 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10232 addr->section = sym->st_shndx;
10233 addr->offset = offset;
74e1a04b 10234
1b31d05e
NC
10235 if (sym_name)
10236 * sym_name = sym->st_name;
0b6ae522
DJ
10237 break;
10238 }
10239
10240 *wordp = word;
10241 arm_sec->next_rela = rp;
10242
015dc7e1 10243 return true;
0b6ae522
DJ
10244}
10245
a734115a
NC
10246static const char *tic6x_unwind_regnames[16] =
10247{
0b4362b0
RM
10248 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10249 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10250 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10251};
fa197c1c 10252
0b6ae522 10253static void
fa197c1c 10254decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10255{
fa197c1c
PB
10256 int i;
10257
10258 for (i = 12; mask; mask >>= 1, i--)
10259 {
10260 if (mask & 1)
10261 {
10262 fputs (tic6x_unwind_regnames[i], stdout);
10263 if (mask > 1)
10264 fputs (", ", stdout);
10265 }
10266 }
10267}
0b6ae522
DJ
10268
10269#define ADVANCE \
10270 if (remaining == 0 && more_words) \
10271 { \
10272 data_offset += 4; \
dda8d76d 10273 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10274 data_offset, & word, & addr, NULL)) \
015dc7e1 10275 return false; \
0b6ae522
DJ
10276 remaining = 4; \
10277 more_words--; \
10278 } \
10279
10280#define GET_OP(OP) \
10281 ADVANCE; \
10282 if (remaining) \
10283 { \
10284 remaining--; \
10285 (OP) = word >> 24; \
10286 word <<= 8; \
10287 } \
10288 else \
10289 { \
2b692964 10290 printf (_("[Truncated opcode]\n")); \
015dc7e1 10291 return false; \
0b6ae522 10292 } \
cc5914eb 10293 printf ("0x%02x ", OP)
0b6ae522 10294
015dc7e1 10295static bool
dda8d76d
NC
10296decode_arm_unwind_bytecode (Filedata * filedata,
10297 struct arm_unw_aux_info * aux,
948f632f
DA
10298 unsigned int word,
10299 unsigned int remaining,
10300 unsigned int more_words,
625d49fc 10301 uint64_t data_offset,
948f632f
DA
10302 Elf_Internal_Shdr * data_sec,
10303 struct arm_section * data_arm_sec)
fa197c1c
PB
10304{
10305 struct absaddr addr;
015dc7e1 10306 bool res = true;
0b6ae522
DJ
10307
10308 /* Decode the unwinding instructions. */
10309 while (1)
10310 {
10311 unsigned int op, op2;
10312
10313 ADVANCE;
10314 if (remaining == 0)
10315 break;
10316 remaining--;
10317 op = word >> 24;
10318 word <<= 8;
10319
cc5914eb 10320 printf (" 0x%02x ", op);
0b6ae522
DJ
10321
10322 if ((op & 0xc0) == 0x00)
10323 {
10324 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10325
cc5914eb 10326 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10327 }
10328 else if ((op & 0xc0) == 0x40)
10329 {
10330 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10331
cc5914eb 10332 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10333 }
10334 else if ((op & 0xf0) == 0x80)
10335 {
10336 GET_OP (op2);
10337 if (op == 0x80 && op2 == 0)
10338 printf (_("Refuse to unwind"));
10339 else
10340 {
10341 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10342 bool first = true;
0b6ae522 10343 int i;
2b692964 10344
0b6ae522
DJ
10345 printf ("pop {");
10346 for (i = 0; i < 12; i++)
10347 if (mask & (1 << i))
10348 {
10349 if (first)
015dc7e1 10350 first = false;
0b6ae522
DJ
10351 else
10352 printf (", ");
10353 printf ("r%d", 4 + i);
10354 }
10355 printf ("}");
10356 }
10357 }
10358 else if ((op & 0xf0) == 0x90)
10359 {
10360 if (op == 0x9d || op == 0x9f)
10361 printf (_(" [Reserved]"));
10362 else
cc5914eb 10363 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10364 }
10365 else if ((op & 0xf0) == 0xa0)
10366 {
10367 int end = 4 + (op & 0x07);
015dc7e1 10368 bool first = true;
0b6ae522 10369 int i;
61865e30 10370
0b6ae522
DJ
10371 printf (" pop {");
10372 for (i = 4; i <= end; i++)
10373 {
10374 if (first)
015dc7e1 10375 first = false;
0b6ae522
DJ
10376 else
10377 printf (", ");
10378 printf ("r%d", i);
10379 }
10380 if (op & 0x08)
10381 {
1b31d05e 10382 if (!first)
0b6ae522
DJ
10383 printf (", ");
10384 printf ("r14");
10385 }
10386 printf ("}");
10387 }
10388 else if (op == 0xb0)
10389 printf (_(" finish"));
10390 else if (op == 0xb1)
10391 {
10392 GET_OP (op2);
10393 if (op2 == 0 || (op2 & 0xf0) != 0)
10394 printf (_("[Spare]"));
10395 else
10396 {
10397 unsigned int mask = op2 & 0x0f;
015dc7e1 10398 bool first = true;
0b6ae522 10399 int i;
61865e30 10400
0b6ae522
DJ
10401 printf ("pop {");
10402 for (i = 0; i < 12; i++)
10403 if (mask & (1 << i))
10404 {
10405 if (first)
015dc7e1 10406 first = false;
0b6ae522
DJ
10407 else
10408 printf (", ");
10409 printf ("r%d", i);
10410 }
10411 printf ("}");
10412 }
10413 }
10414 else if (op == 0xb2)
10415 {
b115cf96 10416 unsigned char buf[9];
0b6ae522 10417 unsigned int i, len;
26c527e6 10418 uint64_t offset;
61865e30 10419
b115cf96 10420 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10421 {
10422 GET_OP (buf[i]);
10423 if ((buf[i] & 0x80) == 0)
10424 break;
10425 }
4082ef84 10426 if (i == sizeof (buf))
32ec8896 10427 {
27a45f42 10428 error (_("corrupt change to vsp\n"));
015dc7e1 10429 res = false;
32ec8896 10430 }
4082ef84
NC
10431 else
10432 {
015dc7e1 10433 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10434 assert (len == i + 1);
10435 offset = offset * 4 + 0x204;
26c527e6 10436 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10437 }
0b6ae522 10438 }
61865e30 10439 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10440 {
61865e30
NC
10441 unsigned int first, last;
10442
10443 GET_OP (op2);
10444 first = op2 >> 4;
10445 last = op2 & 0x0f;
10446 if (op == 0xc8)
10447 first = first + 16;
10448 printf ("pop {D%d", first);
10449 if (last)
10450 printf ("-D%d", first + last);
10451 printf ("}");
10452 }
09854a88
TB
10453 else if (op == 0xb4)
10454 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10455 else if (op == 0xb5)
10456 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10457 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10458 {
10459 unsigned int count = op & 0x07;
10460
10461 printf ("pop {D8");
10462 if (count)
10463 printf ("-D%d", 8 + count);
10464 printf ("}");
10465 }
10466 else if (op >= 0xc0 && op <= 0xc5)
10467 {
10468 unsigned int count = op & 0x07;
10469
10470 printf (" pop {wR10");
10471 if (count)
10472 printf ("-wR%d", 10 + count);
10473 printf ("}");
10474 }
10475 else if (op == 0xc6)
10476 {
10477 unsigned int first, last;
10478
10479 GET_OP (op2);
10480 first = op2 >> 4;
10481 last = op2 & 0x0f;
10482 printf ("pop {wR%d", first);
10483 if (last)
10484 printf ("-wR%d", first + last);
10485 printf ("}");
10486 }
10487 else if (op == 0xc7)
10488 {
10489 GET_OP (op2);
10490 if (op2 == 0 || (op2 & 0xf0) != 0)
10491 printf (_("[Spare]"));
0b6ae522
DJ
10492 else
10493 {
61865e30 10494 unsigned int mask = op2 & 0x0f;
015dc7e1 10495 bool first = true;
61865e30
NC
10496 int i;
10497
10498 printf ("pop {");
10499 for (i = 0; i < 4; i++)
10500 if (mask & (1 << i))
10501 {
10502 if (first)
015dc7e1 10503 first = false;
61865e30
NC
10504 else
10505 printf (", ");
10506 printf ("wCGR%d", i);
10507 }
10508 printf ("}");
0b6ae522
DJ
10509 }
10510 }
61865e30 10511 else
32ec8896
NC
10512 {
10513 printf (_(" [unsupported opcode]"));
015dc7e1 10514 res = false;
32ec8896
NC
10515 }
10516
0b6ae522
DJ
10517 printf ("\n");
10518 }
32ec8896
NC
10519
10520 return res;
fa197c1c
PB
10521}
10522
015dc7e1 10523static bool
dda8d76d
NC
10524decode_tic6x_unwind_bytecode (Filedata * filedata,
10525 struct arm_unw_aux_info * aux,
948f632f
DA
10526 unsigned int word,
10527 unsigned int remaining,
10528 unsigned int more_words,
625d49fc 10529 uint64_t data_offset,
948f632f
DA
10530 Elf_Internal_Shdr * data_sec,
10531 struct arm_section * data_arm_sec)
fa197c1c
PB
10532{
10533 struct absaddr addr;
10534
10535 /* Decode the unwinding instructions. */
10536 while (1)
10537 {
10538 unsigned int op, op2;
10539
10540 ADVANCE;
10541 if (remaining == 0)
10542 break;
10543 remaining--;
10544 op = word >> 24;
10545 word <<= 8;
10546
9cf03b7e 10547 printf (" 0x%02x ", op);
fa197c1c
PB
10548
10549 if ((op & 0xc0) == 0x00)
10550 {
10551 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10552 printf (" sp = sp + %d", offset);
fa197c1c
PB
10553 }
10554 else if ((op & 0xc0) == 0x80)
10555 {
10556 GET_OP (op2);
10557 if (op == 0x80 && op2 == 0)
10558 printf (_("Refuse to unwind"));
10559 else
10560 {
10561 unsigned int mask = ((op & 0x1f) << 8) | op2;
10562 if (op & 0x20)
10563 printf ("pop compact {");
10564 else
10565 printf ("pop {");
10566
10567 decode_tic6x_unwind_regmask (mask);
10568 printf("}");
10569 }
10570 }
10571 else if ((op & 0xf0) == 0xc0)
10572 {
10573 unsigned int reg;
10574 unsigned int nregs;
10575 unsigned int i;
10576 const char *name;
a734115a
NC
10577 struct
10578 {
32ec8896
NC
10579 unsigned int offset;
10580 unsigned int reg;
fa197c1c
PB
10581 } regpos[16];
10582
10583 /* Scan entire instruction first so that GET_OP output is not
10584 interleaved with disassembly. */
10585 nregs = 0;
10586 for (i = 0; nregs < (op & 0xf); i++)
10587 {
10588 GET_OP (op2);
10589 reg = op2 >> 4;
10590 if (reg != 0xf)
10591 {
10592 regpos[nregs].offset = i * 2;
10593 regpos[nregs].reg = reg;
10594 nregs++;
10595 }
10596
10597 reg = op2 & 0xf;
10598 if (reg != 0xf)
10599 {
10600 regpos[nregs].offset = i * 2 + 1;
10601 regpos[nregs].reg = reg;
10602 nregs++;
10603 }
10604 }
10605
10606 printf (_("pop frame {"));
18344509 10607 if (nregs == 0)
fa197c1c 10608 {
18344509
NC
10609 printf (_("*corrupt* - no registers specified"));
10610 }
10611 else
10612 {
10613 reg = nregs - 1;
10614 for (i = i * 2; i > 0; i--)
fa197c1c 10615 {
18344509
NC
10616 if (regpos[reg].offset == i - 1)
10617 {
10618 name = tic6x_unwind_regnames[regpos[reg].reg];
10619 if (reg > 0)
10620 reg--;
10621 }
10622 else
10623 name = _("[pad]");
fa197c1c 10624
18344509
NC
10625 fputs (name, stdout);
10626 if (i > 1)
10627 printf (", ");
10628 }
fa197c1c
PB
10629 }
10630
10631 printf ("}");
10632 }
10633 else if (op == 0xd0)
10634 printf (" MOV FP, SP");
10635 else if (op == 0xd1)
10636 printf (" __c6xabi_pop_rts");
10637 else if (op == 0xd2)
10638 {
10639 unsigned char buf[9];
10640 unsigned int i, len;
26c527e6 10641 uint64_t offset;
a734115a 10642
fa197c1c
PB
10643 for (i = 0; i < sizeof (buf); i++)
10644 {
10645 GET_OP (buf[i]);
10646 if ((buf[i] & 0x80) == 0)
10647 break;
10648 }
0eff7165
NC
10649 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10650 if (i == sizeof (buf))
10651 {
0eff7165 10652 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10653 return false;
0eff7165 10654 }
948f632f 10655
015dc7e1 10656 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10657 assert (len == i + 1);
10658 offset = offset * 8 + 0x408;
26c527e6 10659 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10660 }
10661 else if ((op & 0xf0) == 0xe0)
10662 {
10663 if ((op & 0x0f) == 7)
10664 printf (" RETURN");
10665 else
10666 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10667 }
10668 else
10669 {
10670 printf (_(" [unsupported opcode]"));
10671 }
10672 putchar ('\n');
10673 }
32ec8896 10674
015dc7e1 10675 return true;
fa197c1c
PB
10676}
10677
625d49fc
AM
10678static uint64_t
10679arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10680{
625d49fc 10681 uint64_t offset;
fa197c1c
PB
10682
10683 offset = word & 0x7fffffff;
10684 if (offset & 0x40000000)
625d49fc 10685 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10686
dda8d76d 10687 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10688 offset <<= 1;
10689
10690 return offset + where;
10691}
10692
015dc7e1 10693static bool
dda8d76d
NC
10694decode_arm_unwind (Filedata * filedata,
10695 struct arm_unw_aux_info * aux,
1b31d05e
NC
10696 unsigned int word,
10697 unsigned int remaining,
625d49fc 10698 uint64_t data_offset,
1b31d05e
NC
10699 Elf_Internal_Shdr * data_sec,
10700 struct arm_section * data_arm_sec)
fa197c1c
PB
10701{
10702 int per_index;
10703 unsigned int more_words = 0;
37e14bc3 10704 struct absaddr addr;
625d49fc 10705 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10706 bool res = true;
fa197c1c
PB
10707
10708 if (remaining == 0)
10709 {
1b31d05e
NC
10710 /* Fetch the first word.
10711 Note - when decoding an object file the address extracted
10712 here will always be 0. So we also pass in the sym_name
10713 parameter so that we can find the symbol associated with
10714 the personality routine. */
dda8d76d 10715 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10716 & word, & addr, & sym_name))
015dc7e1 10717 return false;
1b31d05e 10718
fa197c1c
PB
10719 remaining = 4;
10720 }
c93dbb25
CZ
10721 else
10722 {
10723 addr.section = SHN_UNDEF;
10724 addr.offset = 0;
10725 }
fa197c1c
PB
10726
10727 if ((word & 0x80000000) == 0)
10728 {
10729 /* Expand prel31 for personality routine. */
625d49fc 10730 uint64_t fn;
fa197c1c
PB
10731 const char *procname;
10732
dda8d76d 10733 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10734 printf (_(" Personality routine: "));
1b31d05e
NC
10735 if (fn == 0
10736 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10737 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10738 {
10739 procname = aux->strtab + sym_name;
10740 print_vma (fn, PREFIX_HEX);
10741 if (procname)
10742 {
10743 fputs (" <", stdout);
10744 fputs (procname, stdout);
10745 fputc ('>', stdout);
10746 }
10747 }
10748 else
dda8d76d 10749 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10750 fputc ('\n', stdout);
10751
10752 /* The GCC personality routines use the standard compact
10753 encoding, starting with one byte giving the number of
10754 words. */
10755 if (procname != NULL
24d127aa
ML
10756 && (startswith (procname, "__gcc_personality_v0")
10757 || startswith (procname, "__gxx_personality_v0")
10758 || startswith (procname, "__gcj_personality_v0")
10759 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10760 {
10761 remaining = 0;
10762 more_words = 1;
10763 ADVANCE;
10764 if (!remaining)
10765 {
10766 printf (_(" [Truncated data]\n"));
015dc7e1 10767 return false;
fa197c1c
PB
10768 }
10769 more_words = word >> 24;
10770 word <<= 8;
10771 remaining--;
10772 per_index = -1;
10773 }
10774 else
015dc7e1 10775 return true;
fa197c1c
PB
10776 }
10777 else
10778 {
1b31d05e 10779 /* ARM EHABI Section 6.3:
0b4362b0 10780
1b31d05e 10781 An exception-handling table entry for the compact model looks like:
0b4362b0 10782
1b31d05e
NC
10783 31 30-28 27-24 23-0
10784 -- ----- ----- ----
10785 1 0 index Data for personalityRoutine[index] */
10786
dda8d76d 10787 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10788 && (word & 0x70000000))
32ec8896
NC
10789 {
10790 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10791 res = false;
32ec8896 10792 }
1b31d05e 10793
fa197c1c 10794 per_index = (word >> 24) & 0x7f;
1b31d05e 10795 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10796 if (per_index == 0)
10797 {
10798 more_words = 0;
10799 word <<= 8;
10800 remaining--;
10801 }
10802 else if (per_index < 3)
10803 {
10804 more_words = (word >> 16) & 0xff;
10805 word <<= 16;
10806 remaining -= 2;
10807 }
10808 }
10809
dda8d76d 10810 switch (filedata->file_header.e_machine)
fa197c1c
PB
10811 {
10812 case EM_ARM:
10813 if (per_index < 3)
10814 {
dda8d76d 10815 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10816 data_offset, data_sec, data_arm_sec))
015dc7e1 10817 res = false;
fa197c1c
PB
10818 }
10819 else
1b31d05e
NC
10820 {
10821 warn (_("Unknown ARM compact model index encountered\n"));
10822 printf (_(" [reserved]\n"));
015dc7e1 10823 res = false;
1b31d05e 10824 }
fa197c1c
PB
10825 break;
10826
10827 case EM_TI_C6000:
10828 if (per_index < 3)
10829 {
dda8d76d 10830 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10831 data_offset, data_sec, data_arm_sec))
015dc7e1 10832 res = false;
fa197c1c
PB
10833 }
10834 else if (per_index < 5)
10835 {
10836 if (((word >> 17) & 0x7f) == 0x7f)
10837 printf (_(" Restore stack from frame pointer\n"));
10838 else
10839 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10840 printf (_(" Registers restored: "));
10841 if (per_index == 4)
10842 printf (" (compact) ");
10843 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10844 putchar ('\n');
10845 printf (_(" Return register: %s\n"),
10846 tic6x_unwind_regnames[word & 0xf]);
10847 }
10848 else
1b31d05e 10849 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10850 break;
10851
10852 default:
74e1a04b 10853 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10854 filedata->file_header.e_machine);
015dc7e1 10855 res = false;
fa197c1c 10856 }
0b6ae522
DJ
10857
10858 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10859
10860 return res;
0b6ae522
DJ
10861}
10862
015dc7e1 10863static bool
dda8d76d
NC
10864dump_arm_unwind (Filedata * filedata,
10865 struct arm_unw_aux_info * aux,
10866 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10867{
10868 struct arm_section exidx_arm_sec, extab_arm_sec;
10869 unsigned int i, exidx_len;
26c527e6 10870 uint64_t j, nfuns;
015dc7e1 10871 bool res = true;
0b6ae522
DJ
10872
10873 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10874 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10875 exidx_len = exidx_sec->sh_size / 8;
10876
948f632f
DA
10877 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10878 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10879 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10880 aux->funtab[nfuns++] = aux->symtab[j];
10881 aux->nfuns = nfuns;
10882 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10883
0b6ae522
DJ
10884 for (i = 0; i < exidx_len; i++)
10885 {
10886 unsigned int exidx_fn, exidx_entry;
10887 struct absaddr fn_addr, entry_addr;
625d49fc 10888 uint64_t fn;
0b6ae522
DJ
10889
10890 fputc ('\n', stdout);
10891
dda8d76d 10892 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10893 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10894 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10895 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10896 {
948f632f 10897 free (aux->funtab);
1b31d05e
NC
10898 arm_free_section (& exidx_arm_sec);
10899 arm_free_section (& extab_arm_sec);
015dc7e1 10900 return false;
0b6ae522
DJ
10901 }
10902
83c257ca
NC
10903 /* ARM EHABI, Section 5:
10904 An index table entry consists of 2 words.
10905 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10906 if (exidx_fn & 0x80000000)
32ec8896
NC
10907 {
10908 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10909 res = false;
32ec8896 10910 }
83c257ca 10911
dda8d76d 10912 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10913
dda8d76d 10914 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10915 fputs (": ", stdout);
10916
10917 if (exidx_entry == 1)
10918 {
10919 print_vma (exidx_entry, PREFIX_HEX);
10920 fputs (" [cantunwind]\n", stdout);
10921 }
10922 else if (exidx_entry & 0x80000000)
10923 {
10924 print_vma (exidx_entry, PREFIX_HEX);
10925 fputc ('\n', stdout);
dda8d76d 10926 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10927 }
10928 else
10929 {
625d49fc 10930 uint64_t table, table_offset = 0;
0b6ae522
DJ
10931 Elf_Internal_Shdr *table_sec;
10932
10933 fputs ("@", stdout);
dda8d76d 10934 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10935 print_vma (table, PREFIX_HEX);
10936 printf ("\n");
10937
10938 /* Locate the matching .ARM.extab. */
10939 if (entry_addr.section != SHN_UNDEF
dda8d76d 10940 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10941 {
dda8d76d 10942 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10943 table_offset = entry_addr.offset;
1a915552 10944 /* PR 18879 */
625d49fc 10945 if (table_offset > table_sec->sh_size)
1a915552 10946 {
26c527e6
AM
10947 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10948 table_offset,
dda8d76d 10949 printable_section_name (filedata, table_sec));
015dc7e1 10950 res = false;
1a915552
NC
10951 continue;
10952 }
0b6ae522
DJ
10953 }
10954 else
10955 {
dda8d76d 10956 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10957 if (table_sec != NULL)
10958 table_offset = table - table_sec->sh_addr;
10959 }
32ec8896 10960
0b6ae522
DJ
10961 if (table_sec == NULL)
10962 {
26c527e6
AM
10963 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10964 table);
015dc7e1 10965 res = false;
0b6ae522
DJ
10966 continue;
10967 }
32ec8896 10968
dda8d76d 10969 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10970 &extab_arm_sec))
015dc7e1 10971 res = false;
0b6ae522
DJ
10972 }
10973 }
10974
10975 printf ("\n");
10976
948f632f 10977 free (aux->funtab);
0b6ae522
DJ
10978 arm_free_section (&exidx_arm_sec);
10979 arm_free_section (&extab_arm_sec);
32ec8896
NC
10980
10981 return res;
0b6ae522
DJ
10982}
10983
fa197c1c 10984/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10985
015dc7e1 10986static bool
dda8d76d 10987arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10988{
10989 struct arm_unw_aux_info aux;
10990 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10991 Elf_Internal_Shdr *sec;
26c527e6 10992 size_t i;
fa197c1c 10993 unsigned int sec_type;
015dc7e1 10994 bool res = true;
0b6ae522 10995
dda8d76d 10996 switch (filedata->file_header.e_machine)
fa197c1c
PB
10997 {
10998 case EM_ARM:
10999 sec_type = SHT_ARM_EXIDX;
11000 break;
11001
11002 case EM_TI_C6000:
11003 sec_type = SHT_C6000_UNWIND;
11004 break;
11005
0b4362b0 11006 default:
74e1a04b 11007 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11008 filedata->file_header.e_machine);
015dc7e1 11009 return false;
fa197c1c
PB
11010 }
11011
dda8d76d 11012 if (filedata->string_table == NULL)
015dc7e1 11013 return false;
1b31d05e
NC
11014
11015 memset (& aux, 0, sizeof (aux));
dda8d76d 11016 aux.filedata = filedata;
0b6ae522 11017
dda8d76d 11018 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11019 {
28d13567 11020 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11021 {
28d13567 11022 if (aux.symtab)
74e1a04b 11023 {
28d13567
AM
11024 error (_("Multiple symbol tables encountered\n"));
11025 free (aux.symtab);
11026 aux.symtab = NULL;
74e1a04b 11027 free (aux.strtab);
28d13567 11028 aux.strtab = NULL;
74e1a04b 11029 }
28d13567
AM
11030 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11031 &aux.strtab, &aux.strtab_size))
015dc7e1 11032 return false;
0b6ae522 11033 }
fa197c1c 11034 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11035 unwsec = sec;
11036 }
11037
1b31d05e 11038 if (unwsec == NULL)
0b6ae522 11039 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11040 else
dda8d76d 11041 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11042 {
11043 if (sec->sh_type == sec_type)
11044 {
26c527e6
AM
11045 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11046 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11047 "contains %" PRIu64 " entry:\n",
11048 "\nUnwind section '%s' at offset %#" PRIx64 " "
11049 "contains %" PRIu64 " entries:\n",
d3a49aa8 11050 num_unwind),
dda8d76d 11051 printable_section_name (filedata, sec),
26c527e6 11052 sec->sh_offset,
d3a49aa8 11053 num_unwind);
0b6ae522 11054
dda8d76d 11055 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11056 res = false;
1b31d05e
NC
11057 }
11058 }
0b6ae522 11059
9db70fc3
AM
11060 free (aux.symtab);
11061 free ((char *) aux.strtab);
32ec8896
NC
11062
11063 return res;
0b6ae522
DJ
11064}
11065
3ecc00ec
NC
11066static bool
11067no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11068{
11069 printf (_("No processor specific unwind information to decode\n"));
11070 return true;
11071}
11072
015dc7e1 11073static bool
dda8d76d 11074process_unwind (Filedata * filedata)
57346661 11075{
2cf0635d
NC
11076 struct unwind_handler
11077 {
32ec8896 11078 unsigned int machtype;
015dc7e1 11079 bool (* handler)(Filedata *);
2cf0635d
NC
11080 } handlers[] =
11081 {
0b6ae522 11082 { EM_ARM, arm_process_unwind },
57346661
AM
11083 { EM_IA_64, ia64_process_unwind },
11084 { EM_PARISC, hppa_process_unwind },
fa197c1c 11085 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11086 { EM_386, no_processor_specific_unwind },
11087 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11088 { 0, NULL }
57346661
AM
11089 };
11090 int i;
11091
11092 if (!do_unwind)
015dc7e1 11093 return true;
57346661
AM
11094
11095 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11096 if (filedata->file_header.e_machine == handlers[i].machtype)
11097 return handlers[i].handler (filedata);
57346661 11098
1b31d05e 11099 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11100 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11101 return true;
57346661
AM
11102}
11103
37c18eed
SD
11104static void
11105dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11106{
11107 switch (entry->d_tag)
11108 {
11109 case DT_AARCH64_BTI_PLT:
1dbade74 11110 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11111 break;
11112 default:
11113 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11114 break;
11115 }
11116 putchar ('\n');
11117}
11118
252b5132 11119static void
978c4450 11120dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11121{
11122 switch (entry->d_tag)
11123 {
11124 case DT_MIPS_FLAGS:
11125 if (entry->d_un.d_val == 0)
4b68bca3 11126 printf (_("NONE"));
252b5132
RH
11127 else
11128 {
11129 static const char * opts[] =
11130 {
11131 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11132 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11133 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11134 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11135 "RLD_ORDER_SAFE"
11136 };
11137 unsigned int cnt;
015dc7e1 11138 bool first = true;
2b692964 11139
60bca95a 11140 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11141 if (entry->d_un.d_val & (1 << cnt))
11142 {
11143 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11144 first = false;
252b5132 11145 }
252b5132
RH
11146 }
11147 break;
103f02d3 11148
252b5132 11149 case DT_MIPS_IVERSION:
84714f86 11150 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11151 printf (_("Interface Version: %s"),
84714f86 11152 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11153 else
f493c217 11154 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11155 entry->d_un.d_ptr);
252b5132 11156 break;
103f02d3 11157
252b5132
RH
11158 case DT_MIPS_TIME_STAMP:
11159 {
d5b07ef4 11160 char timebuf[128];
2cf0635d 11161 struct tm * tmp;
91d6fa6a 11162 time_t atime = entry->d_un.d_val;
82b1b41b 11163
91d6fa6a 11164 tmp = gmtime (&atime);
82b1b41b
NC
11165 /* PR 17531: file: 6accc532. */
11166 if (tmp == NULL)
11167 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11168 else
11169 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11170 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11171 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11172 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11173 }
11174 break;
103f02d3 11175
252b5132
RH
11176 case DT_MIPS_RLD_VERSION:
11177 case DT_MIPS_LOCAL_GOTNO:
11178 case DT_MIPS_CONFLICTNO:
11179 case DT_MIPS_LIBLISTNO:
11180 case DT_MIPS_SYMTABNO:
11181 case DT_MIPS_UNREFEXTNO:
11182 case DT_MIPS_HIPAGENO:
11183 case DT_MIPS_DELTA_CLASS_NO:
11184 case DT_MIPS_DELTA_INSTANCE_NO:
11185 case DT_MIPS_DELTA_RELOC_NO:
11186 case DT_MIPS_DELTA_SYM_NO:
11187 case DT_MIPS_DELTA_CLASSSYM_NO:
11188 case DT_MIPS_COMPACT_SIZE:
c69075ac 11189 print_vma (entry->d_un.d_val, DEC);
252b5132 11190 break;
103f02d3 11191
f16a9783 11192 case DT_MIPS_XHASH:
978c4450
AM
11193 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11194 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11195 /* Falls through. */
11196
103f02d3 11197 default:
4b68bca3 11198 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11199 }
4b68bca3 11200 putchar ('\n');
103f02d3
UD
11201}
11202
103f02d3 11203static void
2cf0635d 11204dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11205{
11206 switch (entry->d_tag)
11207 {
11208 case DT_HP_DLD_FLAGS:
11209 {
11210 static struct
11211 {
26c527e6 11212 unsigned int bit;
2cf0635d 11213 const char * str;
5e220199
NC
11214 }
11215 flags[] =
11216 {
11217 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11218 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11219 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11220 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11221 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11222 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11223 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11224 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11225 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11226 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11227 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11228 { DT_HP_GST, "HP_GST" },
11229 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11230 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11231 { DT_HP_NODELETE, "HP_NODELETE" },
11232 { DT_HP_GROUP, "HP_GROUP" },
11233 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11234 };
015dc7e1 11235 bool first = true;
5e220199 11236 size_t cnt;
625d49fc 11237 uint64_t val = entry->d_un.d_val;
103f02d3 11238
60bca95a 11239 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11240 if (val & flags[cnt].bit)
30800947
NC
11241 {
11242 if (! first)
11243 putchar (' ');
11244 fputs (flags[cnt].str, stdout);
015dc7e1 11245 first = false;
30800947
NC
11246 val ^= flags[cnt].bit;
11247 }
76da6bbe 11248
103f02d3 11249 if (val != 0 || first)
f7a99963
NC
11250 {
11251 if (! first)
11252 putchar (' ');
11253 print_vma (val, HEX);
11254 }
103f02d3
UD
11255 }
11256 break;
76da6bbe 11257
252b5132 11258 default:
f7a99963
NC
11259 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11260 break;
252b5132 11261 }
35b1837e 11262 putchar ('\n');
252b5132
RH
11263}
11264
28f997cf
TG
11265/* VMS vs Unix time offset and factor. */
11266
11267#define VMS_EPOCH_OFFSET 35067168000000000LL
11268#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11269#ifndef INT64_MIN
11270#define INT64_MIN (-9223372036854775807LL - 1)
11271#endif
28f997cf
TG
11272
11273/* Display a VMS time in a human readable format. */
11274
11275static void
0e3c1eeb 11276print_vms_time (int64_t vmstime)
28f997cf 11277{
dccc31de 11278 struct tm *tm = NULL;
28f997cf
TG
11279 time_t unxtime;
11280
dccc31de
AM
11281 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11282 {
11283 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11284 unxtime = vmstime;
11285 if (unxtime == vmstime)
11286 tm = gmtime (&unxtime);
11287 }
11288 if (tm != NULL)
11289 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11290 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11291 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11292}
28f997cf 11293
ecc51f48 11294static void
2cf0635d 11295dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11296{
11297 switch (entry->d_tag)
11298 {
0de14b54 11299 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11300 /* First 3 slots reserved. */
ecc51f48
NC
11301 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11302 printf (" -- ");
11303 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11304 break;
11305
28f997cf 11306 case DT_IA_64_VMS_LINKTIME:
28f997cf 11307 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11308 break;
11309
11310 case DT_IA_64_VMS_LNKFLAGS:
11311 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11312 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11313 printf (" CALL_DEBUG");
11314 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11315 printf (" NOP0BUFS");
11316 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11317 printf (" P0IMAGE");
11318 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11319 printf (" MKTHREADS");
11320 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11321 printf (" UPCALLS");
11322 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11323 printf (" IMGSTA");
11324 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11325 printf (" INITIALIZE");
11326 if (entry->d_un.d_val & VMS_LF_MAIN)
11327 printf (" MAIN");
11328 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11329 printf (" EXE_INIT");
11330 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11331 printf (" TBK_IN_IMG");
11332 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11333 printf (" DBG_IN_IMG");
11334 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11335 printf (" TBK_IN_DSF");
11336 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11337 printf (" DBG_IN_DSF");
11338 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11339 printf (" SIGNATURES");
11340 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11341 printf (" REL_SEG_OFF");
11342 break;
11343
bdf4d63a
JJ
11344 default:
11345 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11346 break;
ecc51f48 11347 }
bdf4d63a 11348 putchar ('\n');
ecc51f48
NC
11349}
11350
015dc7e1 11351static bool
dda8d76d 11352get_32bit_dynamic_section (Filedata * filedata)
252b5132 11353{
2cf0635d
NC
11354 Elf32_External_Dyn * edyn;
11355 Elf32_External_Dyn * ext;
11356 Elf_Internal_Dyn * entry;
103f02d3 11357
978c4450
AM
11358 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11359 filedata->dynamic_addr, 1,
11360 filedata->dynamic_size,
11361 _("dynamic section"));
a6e9f9df 11362 if (!edyn)
015dc7e1 11363 return false;
103f02d3 11364
071436c6
NC
11365 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11366 might not have the luxury of section headers. Look for the DT_NULL
11367 terminator to determine the number of entries. */
978c4450
AM
11368 for (ext = edyn, filedata->dynamic_nent = 0;
11369 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11370 ext++)
11371 {
978c4450 11372 filedata->dynamic_nent++;
ba2685cc
AM
11373 if (BYTE_GET (ext->d_tag) == DT_NULL)
11374 break;
11375 }
252b5132 11376
978c4450
AM
11377 filedata->dynamic_section
11378 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11379 if (filedata->dynamic_section == NULL)
252b5132 11380 {
26c527e6
AM
11381 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11382 filedata->dynamic_nent);
9ea033b2 11383 free (edyn);
015dc7e1 11384 return false;
9ea033b2 11385 }
252b5132 11386
978c4450
AM
11387 for (ext = edyn, entry = filedata->dynamic_section;
11388 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11389 ext++, entry++)
9ea033b2 11390 {
fb514b26
AM
11391 entry->d_tag = BYTE_GET (ext->d_tag);
11392 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11393 }
11394
9ea033b2
NC
11395 free (edyn);
11396
015dc7e1 11397 return true;
9ea033b2
NC
11398}
11399
015dc7e1 11400static bool
dda8d76d 11401get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11402{
2cf0635d
NC
11403 Elf64_External_Dyn * edyn;
11404 Elf64_External_Dyn * ext;
11405 Elf_Internal_Dyn * entry;
103f02d3 11406
071436c6 11407 /* Read in the data. */
978c4450
AM
11408 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11409 filedata->dynamic_addr, 1,
11410 filedata->dynamic_size,
11411 _("dynamic section"));
a6e9f9df 11412 if (!edyn)
015dc7e1 11413 return false;
103f02d3 11414
071436c6
NC
11415 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11416 might not have the luxury of section headers. Look for the DT_NULL
11417 terminator to determine the number of entries. */
978c4450 11418 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11419 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11420 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11421 ext++)
11422 {
978c4450 11423 filedata->dynamic_nent++;
66543521 11424 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11425 break;
11426 }
252b5132 11427
978c4450
AM
11428 filedata->dynamic_section
11429 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11430 if (filedata->dynamic_section == NULL)
252b5132 11431 {
26c527e6
AM
11432 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11433 filedata->dynamic_nent);
252b5132 11434 free (edyn);
015dc7e1 11435 return false;
252b5132
RH
11436 }
11437
071436c6 11438 /* Convert from external to internal formats. */
978c4450
AM
11439 for (ext = edyn, entry = filedata->dynamic_section;
11440 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11441 ext++, entry++)
252b5132 11442 {
66543521
AM
11443 entry->d_tag = BYTE_GET (ext->d_tag);
11444 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11445 }
11446
11447 free (edyn);
11448
015dc7e1 11449 return true;
9ea033b2
NC
11450}
11451
4de91c10
AM
11452static bool
11453get_dynamic_section (Filedata *filedata)
11454{
11455 if (filedata->dynamic_section)
11456 return true;
11457
11458 if (is_32bit_elf)
11459 return get_32bit_dynamic_section (filedata);
11460 else
11461 return get_64bit_dynamic_section (filedata);
11462}
11463
e9e44622 11464static void
625d49fc 11465print_dynamic_flags (uint64_t flags)
d1133906 11466{
015dc7e1 11467 bool first = true;
13ae64f3 11468
d1133906
NC
11469 while (flags)
11470 {
625d49fc 11471 uint64_t flag;
d1133906
NC
11472
11473 flag = flags & - flags;
11474 flags &= ~ flag;
11475
e9e44622 11476 if (first)
015dc7e1 11477 first = false;
e9e44622
JJ
11478 else
11479 putc (' ', stdout);
13ae64f3 11480
d1133906
NC
11481 switch (flag)
11482 {
e9e44622
JJ
11483 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11484 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11485 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11486 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11487 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11488 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11489 }
11490 }
e9e44622 11491 puts ("");
d1133906
NC
11492}
11493
625d49fc 11494static uint64_t *
be7d229a 11495get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11496{
11497 unsigned char * e_data;
625d49fc 11498 uint64_t * i_data;
10ca4b04 11499
be7d229a
AM
11500 /* If size_t is smaller than uint64_t, eg because you are building
11501 on a 32-bit host, then make sure that when number is cast to
11502 size_t no information is lost. */
11503 if ((size_t) number != number
11504 || ent_size * number / ent_size != number)
10ca4b04 11505 {
be7d229a 11506 error (_("Size overflow prevents reading %" PRIu64
b8281767 11507 " elements of size %u\n"),
be7d229a 11508 number, ent_size);
10ca4b04
L
11509 return NULL;
11510 }
11511
11512 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11513 attempting to allocate memory when the read is bound to fail. */
11514 if (ent_size * number > filedata->file_size)
11515 {
b8281767 11516 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11517 number);
10ca4b04
L
11518 return NULL;
11519 }
11520
11521 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11522 if (e_data == NULL)
11523 {
b8281767 11524 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11525 number);
10ca4b04
L
11526 return NULL;
11527 }
11528
11529 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11530 {
b8281767 11531 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11532 number * ent_size);
10ca4b04
L
11533 free (e_data);
11534 return NULL;
11535 }
11536
625d49fc 11537 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11538 if (i_data == NULL)
11539 {
b8281767 11540 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11541 number);
10ca4b04
L
11542 free (e_data);
11543 return NULL;
11544 }
11545
11546 while (number--)
11547 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11548
11549 free (e_data);
11550
11551 return i_data;
11552}
11553
26c527e6 11554static uint64_t
10ca4b04
L
11555get_num_dynamic_syms (Filedata * filedata)
11556{
26c527e6 11557 uint64_t num_of_syms = 0;
10ca4b04
L
11558
11559 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11560 return num_of_syms;
11561
978c4450 11562 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11563 {
11564 unsigned char nb[8];
11565 unsigned char nc[8];
11566 unsigned int hash_ent_size = 4;
11567
11568 if ((filedata->file_header.e_machine == EM_ALPHA
11569 || filedata->file_header.e_machine == EM_S390
11570 || filedata->file_header.e_machine == EM_S390_OLD)
11571 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11572 hash_ent_size = 8;
11573
63cf857e
AM
11574 if (fseek64 (filedata->handle,
11575 (filedata->archive_file_offset
11576 + offset_from_vma (filedata,
11577 filedata->dynamic_info[DT_HASH],
11578 sizeof nb + sizeof nc)),
11579 SEEK_SET))
10ca4b04
L
11580 {
11581 error (_("Unable to seek to start of dynamic information\n"));
11582 goto no_hash;
11583 }
11584
11585 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11586 {
11587 error (_("Failed to read in number of buckets\n"));
11588 goto no_hash;
11589 }
11590
11591 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11592 {
11593 error (_("Failed to read in number of chains\n"));
11594 goto no_hash;
11595 }
11596
978c4450
AM
11597 filedata->nbuckets = byte_get (nb, hash_ent_size);
11598 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11599
2482f306
AM
11600 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11601 {
11602 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11603 hash_ent_size);
11604 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11605 hash_ent_size);
001890e1 11606
2482f306
AM
11607 if (filedata->buckets != NULL && filedata->chains != NULL)
11608 num_of_syms = filedata->nchains;
11609 }
ceb9bf11 11610 no_hash:
10ca4b04
L
11611 if (num_of_syms == 0)
11612 {
9db70fc3
AM
11613 free (filedata->buckets);
11614 filedata->buckets = NULL;
11615 free (filedata->chains);
11616 filedata->chains = NULL;
978c4450 11617 filedata->nbuckets = 0;
10ca4b04
L
11618 }
11619 }
11620
978c4450 11621 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11622 {
11623 unsigned char nb[16];
625d49fc
AM
11624 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11625 uint64_t buckets_vma;
26c527e6 11626 uint64_t hn;
10ca4b04 11627
63cf857e
AM
11628 if (fseek64 (filedata->handle,
11629 (filedata->archive_file_offset
11630 + offset_from_vma (filedata,
11631 filedata->dynamic_info_DT_GNU_HASH,
11632 sizeof nb)),
11633 SEEK_SET))
10ca4b04
L
11634 {
11635 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11636 goto no_gnu_hash;
11637 }
11638
11639 if (fread (nb, 16, 1, filedata->handle) != 1)
11640 {
11641 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11642 goto no_gnu_hash;
11643 }
11644
978c4450
AM
11645 filedata->ngnubuckets = byte_get (nb, 4);
11646 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11647 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11648 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11649 if (is_32bit_elf)
11650 buckets_vma += bitmaskwords * 4;
11651 else
11652 buckets_vma += bitmaskwords * 8;
11653
63cf857e
AM
11654 if (fseek64 (filedata->handle,
11655 (filedata->archive_file_offset
11656 + offset_from_vma (filedata, buckets_vma, 4)),
11657 SEEK_SET))
10ca4b04
L
11658 {
11659 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11660 goto no_gnu_hash;
11661 }
11662
978c4450
AM
11663 filedata->gnubuckets
11664 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11665
978c4450 11666 if (filedata->gnubuckets == NULL)
90837ea7 11667 goto no_gnu_hash;
10ca4b04 11668
978c4450
AM
11669 for (i = 0; i < filedata->ngnubuckets; i++)
11670 if (filedata->gnubuckets[i] != 0)
10ca4b04 11671 {
978c4450 11672 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11673 goto no_gnu_hash;
10ca4b04 11674
978c4450
AM
11675 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11676 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11677 }
11678
11679 if (maxchain == 0xffffffff)
90837ea7 11680 goto no_gnu_hash;
10ca4b04 11681
978c4450 11682 maxchain -= filedata->gnusymidx;
10ca4b04 11683
63cf857e
AM
11684 if (fseek64 (filedata->handle,
11685 (filedata->archive_file_offset
11686 + offset_from_vma (filedata,
11687 buckets_vma + 4 * (filedata->ngnubuckets
11688 + maxchain),
11689 4)),
11690 SEEK_SET))
10ca4b04
L
11691 {
11692 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11693 goto no_gnu_hash;
11694 }
11695
11696 do
11697 {
11698 if (fread (nb, 4, 1, filedata->handle) != 1)
11699 {
11700 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11701 goto no_gnu_hash;
11702 }
11703
11704 if (maxchain + 1 == 0)
90837ea7 11705 goto no_gnu_hash;
10ca4b04
L
11706
11707 ++maxchain;
11708 }
11709 while ((byte_get (nb, 4) & 1) == 0);
11710
63cf857e
AM
11711 if (fseek64 (filedata->handle,
11712 (filedata->archive_file_offset
11713 + offset_from_vma (filedata, (buckets_vma
11714 + 4 * filedata->ngnubuckets),
11715 4)),
11716 SEEK_SET))
10ca4b04
L
11717 {
11718 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11719 goto no_gnu_hash;
11720 }
11721
978c4450
AM
11722 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11723 filedata->ngnuchains = maxchain;
10ca4b04 11724
978c4450 11725 if (filedata->gnuchains == NULL)
90837ea7 11726 goto no_gnu_hash;
10ca4b04 11727
978c4450 11728 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11729 {
63cf857e
AM
11730 if (fseek64 (filedata->handle,
11731 (filedata->archive_file_offset
11732 + offset_from_vma (filedata, (buckets_vma
11733 + 4 * (filedata->ngnubuckets
11734 + maxchain)), 4)),
11735 SEEK_SET))
10ca4b04
L
11736 {
11737 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11738 goto no_gnu_hash;
11739 }
11740
978c4450 11741 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11742 if (filedata->mipsxlat == NULL)
11743 goto no_gnu_hash;
10ca4b04
L
11744 }
11745
978c4450
AM
11746 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11747 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11748 {
625d49fc
AM
11749 uint64_t si = filedata->gnubuckets[hn];
11750 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11751
11752 do
11753 {
978c4450 11754 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11755 {
c31ab5a0
AM
11756 if (off < filedata->ngnuchains
11757 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11758 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11759 }
11760 else
11761 {
11762 if (si >= num_of_syms)
11763 num_of_syms = si + 1;
11764 }
11765 si++;
11766 }
978c4450
AM
11767 while (off < filedata->ngnuchains
11768 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11769 }
11770
90837ea7 11771 if (num_of_syms == 0)
10ca4b04 11772 {
90837ea7 11773 no_gnu_hash:
9db70fc3
AM
11774 free (filedata->mipsxlat);
11775 filedata->mipsxlat = NULL;
11776 free (filedata->gnuchains);
11777 filedata->gnuchains = NULL;
11778 free (filedata->gnubuckets);
11779 filedata->gnubuckets = NULL;
978c4450
AM
11780 filedata->ngnubuckets = 0;
11781 filedata->ngnuchains = 0;
10ca4b04
L
11782 }
11783 }
11784
11785 return num_of_syms;
11786}
11787
b2d38a17
NC
11788/* Parse and display the contents of the dynamic section. */
11789
015dc7e1 11790static bool
dda8d76d 11791process_dynamic_section (Filedata * filedata)
9ea033b2 11792{
2cf0635d 11793 Elf_Internal_Dyn * entry;
9ea033b2 11794
93df3340 11795 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11796 {
11797 if (do_dynamic)
ca0e11aa
NC
11798 {
11799 if (filedata->is_separate)
11800 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11801 filedata->file_name);
11802 else
11803 printf (_("\nThere is no dynamic section in this file.\n"));
11804 }
9ea033b2 11805
015dc7e1 11806 return true;
9ea033b2
NC
11807 }
11808
4de91c10
AM
11809 if (!get_dynamic_section (filedata))
11810 return false;
9ea033b2 11811
252b5132 11812 /* Find the appropriate symbol table. */
978c4450 11813 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11814 {
26c527e6 11815 uint64_t num_of_syms;
2482f306 11816
978c4450
AM
11817 for (entry = filedata->dynamic_section;
11818 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11819 ++entry)
10ca4b04 11820 if (entry->d_tag == DT_SYMTAB)
978c4450 11821 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11822 else if (entry->d_tag == DT_SYMENT)
978c4450 11823 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11824 else if (entry->d_tag == DT_HASH)
978c4450 11825 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11826 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11827 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11828 else if ((filedata->file_header.e_machine == EM_MIPS
11829 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11830 && entry->d_tag == DT_MIPS_XHASH)
11831 {
978c4450
AM
11832 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11833 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11834 }
252b5132 11835
2482f306
AM
11836 num_of_syms = get_num_dynamic_syms (filedata);
11837
11838 if (num_of_syms != 0
11839 && filedata->dynamic_symbols == NULL
11840 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11841 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11842 {
11843 Elf_Internal_Phdr *seg;
625d49fc 11844 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11845
2482f306
AM
11846 if (! get_program_headers (filedata))
11847 {
11848 error (_("Cannot interpret virtual addresses "
11849 "without program headers.\n"));
015dc7e1 11850 return false;
2482f306 11851 }
252b5132 11852
2482f306
AM
11853 for (seg = filedata->program_headers;
11854 seg < filedata->program_headers + filedata->file_header.e_phnum;
11855 ++seg)
11856 {
11857 if (seg->p_type != PT_LOAD)
11858 continue;
252b5132 11859
2482f306
AM
11860 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11861 {
11862 /* See PR 21379 for a reproducer. */
11863 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11864 return false;
2482f306 11865 }
252b5132 11866
2482f306
AM
11867 if (vma >= (seg->p_vaddr & -seg->p_align)
11868 && vma < seg->p_vaddr + seg->p_filesz)
11869 {
11870 /* Since we do not know how big the symbol table is,
11871 we default to reading in up to the end of PT_LOAD
11872 segment and processing that. This is overkill, I
11873 know, but it should work. */
11874 Elf_Internal_Shdr section;
11875 section.sh_offset = (vma - seg->p_vaddr
11876 + seg->p_offset);
11877 section.sh_size = (num_of_syms
11878 * filedata->dynamic_info[DT_SYMENT]);
11879 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11880
11881 if (do_checks
11882 && filedata->dynamic_symtab_section != NULL
11883 && ((filedata->dynamic_symtab_section->sh_offset
11884 != section.sh_offset)
11885 || (filedata->dynamic_symtab_section->sh_size
11886 != section.sh_size)
11887 || (filedata->dynamic_symtab_section->sh_entsize
11888 != section.sh_entsize)))
11889 warn (_("\
11890the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11891
2482f306
AM
11892 section.sh_name = filedata->string_table_length;
11893 filedata->dynamic_symbols
4de91c10 11894 = get_elf_symbols (filedata, &section,
2482f306
AM
11895 &filedata->num_dynamic_syms);
11896 if (filedata->dynamic_symbols == NULL
11897 || filedata->num_dynamic_syms != num_of_syms)
11898 {
11899 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11900 return false;
2482f306
AM
11901 }
11902 break;
11903 }
11904 }
11905 }
11906 }
252b5132
RH
11907
11908 /* Similarly find a string table. */
978c4450
AM
11909 if (filedata->dynamic_strings == NULL)
11910 for (entry = filedata->dynamic_section;
11911 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11912 ++entry)
11913 {
11914 if (entry->d_tag == DT_STRTAB)
978c4450 11915 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11916
10ca4b04 11917 if (entry->d_tag == DT_STRSZ)
978c4450 11918 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11919
978c4450
AM
11920 if (filedata->dynamic_info[DT_STRTAB]
11921 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11922 {
26c527e6 11923 uint64_t offset;
be7d229a 11924 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11925
11926 offset = offset_from_vma (filedata,
978c4450 11927 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11928 str_tab_len);
8ac10c5b
L
11929 if (do_checks
11930 && filedata->dynamic_strtab_section
11931 && ((filedata->dynamic_strtab_section->sh_offset
11932 != (file_ptr) offset)
11933 || (filedata->dynamic_strtab_section->sh_size
11934 != str_tab_len)))
11935 warn (_("\
11936the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11937
978c4450
AM
11938 filedata->dynamic_strings
11939 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11940 _("dynamic string table"));
11941 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11942 {
11943 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11944 break;
11945 }
e3d39609 11946
978c4450 11947 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11948 break;
11949 }
11950 }
252b5132
RH
11951
11952 /* And find the syminfo section if available. */
978c4450 11953 if (filedata->dynamic_syminfo == NULL)
252b5132 11954 {
26c527e6 11955 uint64_t syminsz = 0;
252b5132 11956
978c4450
AM
11957 for (entry = filedata->dynamic_section;
11958 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11959 ++entry)
252b5132
RH
11960 {
11961 if (entry->d_tag == DT_SYMINENT)
11962 {
11963 /* Note: these braces are necessary to avoid a syntax
11964 error from the SunOS4 C compiler. */
049b0c3a
NC
11965 /* PR binutils/17531: A corrupt file can trigger this test.
11966 So do not use an assert, instead generate an error message. */
11967 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11968 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11969 (int) entry->d_un.d_val);
252b5132
RH
11970 }
11971 else if (entry->d_tag == DT_SYMINSZ)
11972 syminsz = entry->d_un.d_val;
11973 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11974 filedata->dynamic_syminfo_offset
11975 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11976 }
11977
978c4450 11978 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11979 {
2cf0635d
NC
11980 Elf_External_Syminfo * extsyminfo;
11981 Elf_External_Syminfo * extsym;
11982 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11983
11984 /* There is a syminfo section. Read the data. */
3f5e193b 11985 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11986 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11987 1, syminsz, _("symbol information"));
a6e9f9df 11988 if (!extsyminfo)
015dc7e1 11989 return false;
252b5132 11990
978c4450 11991 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11992 {
11993 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11994 free (filedata->dynamic_syminfo);
e3d39609 11995 }
978c4450
AM
11996 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11997 if (filedata->dynamic_syminfo == NULL)
252b5132 11998 {
26c527e6
AM
11999 error (_("Out of memory allocating %" PRIu64
12000 " bytes for dynamic symbol info\n"),
12001 syminsz);
015dc7e1 12002 return false;
252b5132
RH
12003 }
12004
2482f306
AM
12005 filedata->dynamic_syminfo_nent
12006 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12007 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12008 syminfo < (filedata->dynamic_syminfo
12009 + filedata->dynamic_syminfo_nent);
86dba8ee 12010 ++syminfo, ++extsym)
252b5132 12011 {
86dba8ee
AM
12012 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12013 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12014 }
12015
12016 free (extsyminfo);
12017 }
12018 }
12019
978c4450 12020 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12021 {
f253158f 12022 if (filedata->is_separate)
26c527e6
AM
12023 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12024 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12025 filedata->dynamic_nent),
f253158f
NC
12026 filedata->file_name,
12027 filedata->dynamic_addr,
26c527e6 12028 filedata->dynamic_nent);
84a9f195 12029 else
02da71ee 12030 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12031 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12032 filedata->dynamic_nent),
84a9f195 12033 filedata->dynamic_addr,
26c527e6 12034 filedata->dynamic_nent);
ca0e11aa 12035 }
252b5132
RH
12036 if (do_dynamic)
12037 printf (_(" Tag Type Name/Value\n"));
12038
978c4450
AM
12039 for (entry = filedata->dynamic_section;
12040 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12041 entry++)
252b5132
RH
12042 {
12043 if (do_dynamic)
f7a99963 12044 {
2cf0635d 12045 const char * dtype;
e699b9ff 12046
f7a99963
NC
12047 putchar (' ');
12048 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12049 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12050 printf (" (%s)%*s", dtype,
32ec8896 12051 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12052 }
252b5132
RH
12053
12054 switch (entry->d_tag)
12055 {
d1133906
NC
12056 case DT_FLAGS:
12057 if (do_dynamic)
e9e44622 12058 print_dynamic_flags (entry->d_un.d_val);
d1133906 12059 break;
76da6bbe 12060
252b5132
RH
12061 case DT_AUXILIARY:
12062 case DT_FILTER:
019148e4
L
12063 case DT_CONFIG:
12064 case DT_DEPAUDIT:
12065 case DT_AUDIT:
252b5132
RH
12066 if (do_dynamic)
12067 {
019148e4 12068 switch (entry->d_tag)
b34976b6 12069 {
019148e4
L
12070 case DT_AUXILIARY:
12071 printf (_("Auxiliary library"));
12072 break;
12073
12074 case DT_FILTER:
12075 printf (_("Filter library"));
12076 break;
12077
b34976b6 12078 case DT_CONFIG:
019148e4
L
12079 printf (_("Configuration file"));
12080 break;
12081
12082 case DT_DEPAUDIT:
12083 printf (_("Dependency audit library"));
12084 break;
12085
12086 case DT_AUDIT:
12087 printf (_("Audit library"));
12088 break;
12089 }
252b5132 12090
84714f86 12091 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12092 printf (": [%s]\n",
84714f86 12093 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12094 else
f7a99963
NC
12095 {
12096 printf (": ");
12097 print_vma (entry->d_un.d_val, PREFIX_HEX);
12098 putchar ('\n');
12099 }
252b5132
RH
12100 }
12101 break;
12102
dcefbbbd 12103 case DT_FEATURE:
252b5132
RH
12104 if (do_dynamic)
12105 {
12106 printf (_("Flags:"));
86f55779 12107
252b5132
RH
12108 if (entry->d_un.d_val == 0)
12109 printf (_(" None\n"));
12110 else
12111 {
26c527e6 12112 uint64_t val = entry->d_un.d_val;
86f55779 12113
252b5132
RH
12114 if (val & DTF_1_PARINIT)
12115 {
12116 printf (" PARINIT");
12117 val ^= DTF_1_PARINIT;
12118 }
dcefbbbd
L
12119 if (val & DTF_1_CONFEXP)
12120 {
12121 printf (" CONFEXP");
12122 val ^= DTF_1_CONFEXP;
12123 }
252b5132 12124 if (val != 0)
26c527e6 12125 printf (" %" PRIx64, val);
252b5132
RH
12126 puts ("");
12127 }
12128 }
12129 break;
12130
12131 case DT_POSFLAG_1:
12132 if (do_dynamic)
12133 {
12134 printf (_("Flags:"));
86f55779 12135
252b5132
RH
12136 if (entry->d_un.d_val == 0)
12137 printf (_(" None\n"));
12138 else
12139 {
26c527e6 12140 uint64_t val = entry->d_un.d_val;
86f55779 12141
252b5132
RH
12142 if (val & DF_P1_LAZYLOAD)
12143 {
12144 printf (" LAZYLOAD");
12145 val ^= DF_P1_LAZYLOAD;
12146 }
12147 if (val & DF_P1_GROUPPERM)
12148 {
12149 printf (" GROUPPERM");
12150 val ^= DF_P1_GROUPPERM;
12151 }
12152 if (val != 0)
26c527e6 12153 printf (" %" PRIx64, val);
252b5132
RH
12154 puts ("");
12155 }
12156 }
12157 break;
12158
12159 case DT_FLAGS_1:
12160 if (do_dynamic)
12161 {
12162 printf (_("Flags:"));
12163 if (entry->d_un.d_val == 0)
12164 printf (_(" None\n"));
12165 else
12166 {
26c527e6 12167 uint64_t val = entry->d_un.d_val;
86f55779 12168
252b5132
RH
12169 if (val & DF_1_NOW)
12170 {
12171 printf (" NOW");
12172 val ^= DF_1_NOW;
12173 }
12174 if (val & DF_1_GLOBAL)
12175 {
12176 printf (" GLOBAL");
12177 val ^= DF_1_GLOBAL;
12178 }
12179 if (val & DF_1_GROUP)
12180 {
12181 printf (" GROUP");
12182 val ^= DF_1_GROUP;
12183 }
12184 if (val & DF_1_NODELETE)
12185 {
12186 printf (" NODELETE");
12187 val ^= DF_1_NODELETE;
12188 }
12189 if (val & DF_1_LOADFLTR)
12190 {
12191 printf (" LOADFLTR");
12192 val ^= DF_1_LOADFLTR;
12193 }
12194 if (val & DF_1_INITFIRST)
12195 {
12196 printf (" INITFIRST");
12197 val ^= DF_1_INITFIRST;
12198 }
12199 if (val & DF_1_NOOPEN)
12200 {
12201 printf (" NOOPEN");
12202 val ^= DF_1_NOOPEN;
12203 }
12204 if (val & DF_1_ORIGIN)
12205 {
12206 printf (" ORIGIN");
12207 val ^= DF_1_ORIGIN;
12208 }
12209 if (val & DF_1_DIRECT)
12210 {
12211 printf (" DIRECT");
12212 val ^= DF_1_DIRECT;
12213 }
12214 if (val & DF_1_TRANS)
12215 {
12216 printf (" TRANS");
12217 val ^= DF_1_TRANS;
12218 }
12219 if (val & DF_1_INTERPOSE)
12220 {
12221 printf (" INTERPOSE");
12222 val ^= DF_1_INTERPOSE;
12223 }
f7db6139 12224 if (val & DF_1_NODEFLIB)
dcefbbbd 12225 {
f7db6139
L
12226 printf (" NODEFLIB");
12227 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12228 }
12229 if (val & DF_1_NODUMP)
12230 {
12231 printf (" NODUMP");
12232 val ^= DF_1_NODUMP;
12233 }
34b60028 12234 if (val & DF_1_CONFALT)
dcefbbbd 12235 {
34b60028
L
12236 printf (" CONFALT");
12237 val ^= DF_1_CONFALT;
12238 }
12239 if (val & DF_1_ENDFILTEE)
12240 {
12241 printf (" ENDFILTEE");
12242 val ^= DF_1_ENDFILTEE;
12243 }
12244 if (val & DF_1_DISPRELDNE)
12245 {
12246 printf (" DISPRELDNE");
12247 val ^= DF_1_DISPRELDNE;
12248 }
12249 if (val & DF_1_DISPRELPND)
12250 {
12251 printf (" DISPRELPND");
12252 val ^= DF_1_DISPRELPND;
12253 }
12254 if (val & DF_1_NODIRECT)
12255 {
12256 printf (" NODIRECT");
12257 val ^= DF_1_NODIRECT;
12258 }
12259 if (val & DF_1_IGNMULDEF)
12260 {
12261 printf (" IGNMULDEF");
12262 val ^= DF_1_IGNMULDEF;
12263 }
12264 if (val & DF_1_NOKSYMS)
12265 {
12266 printf (" NOKSYMS");
12267 val ^= DF_1_NOKSYMS;
12268 }
12269 if (val & DF_1_NOHDR)
12270 {
12271 printf (" NOHDR");
12272 val ^= DF_1_NOHDR;
12273 }
12274 if (val & DF_1_EDITED)
12275 {
12276 printf (" EDITED");
12277 val ^= DF_1_EDITED;
12278 }
12279 if (val & DF_1_NORELOC)
12280 {
12281 printf (" NORELOC");
12282 val ^= DF_1_NORELOC;
12283 }
12284 if (val & DF_1_SYMINTPOSE)
12285 {
12286 printf (" SYMINTPOSE");
12287 val ^= DF_1_SYMINTPOSE;
12288 }
12289 if (val & DF_1_GLOBAUDIT)
12290 {
12291 printf (" GLOBAUDIT");
12292 val ^= DF_1_GLOBAUDIT;
12293 }
12294 if (val & DF_1_SINGLETON)
12295 {
12296 printf (" SINGLETON");
12297 val ^= DF_1_SINGLETON;
dcefbbbd 12298 }
5c383f02
RO
12299 if (val & DF_1_STUB)
12300 {
12301 printf (" STUB");
12302 val ^= DF_1_STUB;
12303 }
12304 if (val & DF_1_PIE)
12305 {
12306 printf (" PIE");
12307 val ^= DF_1_PIE;
12308 }
b1202ffa
L
12309 if (val & DF_1_KMOD)
12310 {
12311 printf (" KMOD");
12312 val ^= DF_1_KMOD;
12313 }
12314 if (val & DF_1_WEAKFILTER)
12315 {
12316 printf (" WEAKFILTER");
12317 val ^= DF_1_WEAKFILTER;
12318 }
12319 if (val & DF_1_NOCOMMON)
12320 {
12321 printf (" NOCOMMON");
12322 val ^= DF_1_NOCOMMON;
12323 }
252b5132 12324 if (val != 0)
26c527e6 12325 printf (" %" PRIx64, val);
252b5132
RH
12326 puts ("");
12327 }
12328 }
12329 break;
12330
12331 case DT_PLTREL:
978c4450 12332 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12333 if (do_dynamic)
dda8d76d 12334 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12335 break;
12336
12337 case DT_NULL :
12338 case DT_NEEDED :
12339 case DT_PLTGOT :
12340 case DT_HASH :
12341 case DT_STRTAB :
12342 case DT_SYMTAB :
12343 case DT_RELA :
12344 case DT_INIT :
12345 case DT_FINI :
12346 case DT_SONAME :
12347 case DT_RPATH :
12348 case DT_SYMBOLIC:
12349 case DT_REL :
a7fd1186 12350 case DT_RELR :
252b5132
RH
12351 case DT_DEBUG :
12352 case DT_TEXTREL :
12353 case DT_JMPREL :
019148e4 12354 case DT_RUNPATH :
978c4450 12355 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12356
12357 if (do_dynamic)
12358 {
84714f86 12359 const char *name;
252b5132 12360
84714f86
AM
12361 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12362 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12363 else
d79b3d50 12364 name = NULL;
252b5132
RH
12365
12366 if (name)
12367 {
12368 switch (entry->d_tag)
12369 {
12370 case DT_NEEDED:
12371 printf (_("Shared library: [%s]"), name);
12372
13acb58d
AM
12373 if (filedata->program_interpreter
12374 && streq (name, filedata->program_interpreter))
f7a99963 12375 printf (_(" program interpreter"));
252b5132
RH
12376 break;
12377
12378 case DT_SONAME:
f7a99963 12379 printf (_("Library soname: [%s]"), name);
252b5132
RH
12380 break;
12381
12382 case DT_RPATH:
f7a99963 12383 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12384 break;
12385
019148e4
L
12386 case DT_RUNPATH:
12387 printf (_("Library runpath: [%s]"), name);
12388 break;
12389
252b5132 12390 default:
f7a99963
NC
12391 print_vma (entry->d_un.d_val, PREFIX_HEX);
12392 break;
252b5132
RH
12393 }
12394 }
12395 else
f7a99963
NC
12396 print_vma (entry->d_un.d_val, PREFIX_HEX);
12397
12398 putchar ('\n');
252b5132
RH
12399 }
12400 break;
12401
12402 case DT_PLTRELSZ:
12403 case DT_RELASZ :
12404 case DT_STRSZ :
12405 case DT_RELSZ :
12406 case DT_RELAENT :
a7fd1186
FS
12407 case DT_RELRENT :
12408 case DT_RELRSZ :
252b5132
RH
12409 case DT_SYMENT :
12410 case DT_RELENT :
978c4450 12411 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12412 /* Fall through. */
252b5132
RH
12413 case DT_PLTPADSZ:
12414 case DT_MOVEENT :
12415 case DT_MOVESZ :
04d8355a 12416 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12417 case DT_INIT_ARRAYSZ:
12418 case DT_FINI_ARRAYSZ:
047b2264
JJ
12419 case DT_GNU_CONFLICTSZ:
12420 case DT_GNU_LIBLISTSZ:
252b5132 12421 if (do_dynamic)
f7a99963
NC
12422 {
12423 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12424 printf (_(" (bytes)\n"));
f7a99963 12425 }
252b5132
RH
12426 break;
12427
12428 case DT_VERDEFNUM:
12429 case DT_VERNEEDNUM:
12430 case DT_RELACOUNT:
12431 case DT_RELCOUNT:
12432 if (do_dynamic)
f7a99963
NC
12433 {
12434 print_vma (entry->d_un.d_val, UNSIGNED);
12435 putchar ('\n');
12436 }
252b5132
RH
12437 break;
12438
12439 case DT_SYMINSZ:
12440 case DT_SYMINENT:
12441 case DT_SYMINFO:
12442 case DT_USED:
12443 case DT_INIT_ARRAY:
12444 case DT_FINI_ARRAY:
12445 if (do_dynamic)
12446 {
d79b3d50 12447 if (entry->d_tag == DT_USED
84714f86 12448 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12449 {
84714f86
AM
12450 const char *name
12451 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12452
b34976b6 12453 if (*name)
252b5132
RH
12454 {
12455 printf (_("Not needed object: [%s]\n"), name);
12456 break;
12457 }
12458 }
103f02d3 12459
f7a99963
NC
12460 print_vma (entry->d_un.d_val, PREFIX_HEX);
12461 putchar ('\n');
252b5132
RH
12462 }
12463 break;
12464
12465 case DT_BIND_NOW:
12466 /* The value of this entry is ignored. */
35b1837e
AM
12467 if (do_dynamic)
12468 putchar ('\n');
252b5132 12469 break;
103f02d3 12470
047b2264
JJ
12471 case DT_GNU_PRELINKED:
12472 if (do_dynamic)
12473 {
2cf0635d 12474 struct tm * tmp;
91d6fa6a 12475 time_t atime = entry->d_un.d_val;
047b2264 12476
91d6fa6a 12477 tmp = gmtime (&atime);
071436c6
NC
12478 /* PR 17533 file: 041-1244816-0.004. */
12479 if (tmp == NULL)
26c527e6
AM
12480 printf (_("<corrupt time val: %" PRIx64),
12481 (uint64_t) atime);
071436c6
NC
12482 else
12483 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12484 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12485 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12486
12487 }
12488 break;
12489
fdc90cb4 12490 case DT_GNU_HASH:
978c4450 12491 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12492 if (do_dynamic)
12493 {
12494 print_vma (entry->d_un.d_val, PREFIX_HEX);
12495 putchar ('\n');
12496 }
12497 break;
12498
a5da3dee
VDM
12499 case DT_GNU_FLAGS_1:
12500 if (do_dynamic)
12501 {
12502 printf (_("Flags:"));
12503 if (entry->d_un.d_val == 0)
12504 printf (_(" None\n"));
12505 else
12506 {
26c527e6 12507 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12508
12509 if (val & DF_GNU_1_UNIQUE)
12510 {
12511 printf (" UNIQUE");
12512 val ^= DF_GNU_1_UNIQUE;
12513 }
12514 if (val != 0)
26c527e6 12515 printf (" %" PRIx64, val);
a5da3dee
VDM
12516 puts ("");
12517 }
12518 }
12519 break;
12520
252b5132
RH
12521 default:
12522 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12523 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12524 = entry->d_un.d_val;
252b5132
RH
12525
12526 if (do_dynamic)
12527 {
dda8d76d 12528 switch (filedata->file_header.e_machine)
252b5132 12529 {
37c18eed
SD
12530 case EM_AARCH64:
12531 dynamic_section_aarch64_val (entry);
12532 break;
252b5132 12533 case EM_MIPS:
4fe85591 12534 case EM_MIPS_RS3_LE:
978c4450 12535 dynamic_section_mips_val (filedata, entry);
252b5132 12536 break;
103f02d3 12537 case EM_PARISC:
b2d38a17 12538 dynamic_section_parisc_val (entry);
103f02d3 12539 break;
ecc51f48 12540 case EM_IA_64:
b2d38a17 12541 dynamic_section_ia64_val (entry);
ecc51f48 12542 break;
252b5132 12543 default:
f7a99963
NC
12544 print_vma (entry->d_un.d_val, PREFIX_HEX);
12545 putchar ('\n');
252b5132
RH
12546 }
12547 }
12548 break;
12549 }
12550 }
12551
015dc7e1 12552 return true;
252b5132
RH
12553}
12554
12555static char *
d3ba0551 12556get_ver_flags (unsigned int flags)
252b5132 12557{
6d4f21f6 12558 static char buff[128];
252b5132
RH
12559
12560 buff[0] = 0;
12561
12562 if (flags == 0)
12563 return _("none");
12564
12565 if (flags & VER_FLG_BASE)
7bb1ad17 12566 strcat (buff, "BASE");
252b5132
RH
12567
12568 if (flags & VER_FLG_WEAK)
12569 {
12570 if (flags & VER_FLG_BASE)
7bb1ad17 12571 strcat (buff, " | ");
252b5132 12572
7bb1ad17 12573 strcat (buff, "WEAK");
252b5132
RH
12574 }
12575
44ec90b9
RO
12576 if (flags & VER_FLG_INFO)
12577 {
12578 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12579 strcat (buff, " | ");
44ec90b9 12580
7bb1ad17 12581 strcat (buff, "INFO");
44ec90b9
RO
12582 }
12583
12584 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12585 {
12586 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12587 strcat (buff, " | ");
12588
12589 strcat (buff, _("<unknown>"));
12590 }
252b5132
RH
12591
12592 return buff;
12593}
12594
12595/* Display the contents of the version sections. */
98fb390a 12596
015dc7e1 12597static bool
dda8d76d 12598process_version_sections (Filedata * filedata)
252b5132 12599{
2cf0635d 12600 Elf_Internal_Shdr * section;
b34976b6 12601 unsigned i;
015dc7e1 12602 bool found = false;
252b5132
RH
12603
12604 if (! do_version)
015dc7e1 12605 return true;
252b5132 12606
dda8d76d
NC
12607 for (i = 0, section = filedata->section_headers;
12608 i < filedata->file_header.e_shnum;
b34976b6 12609 i++, section++)
252b5132
RH
12610 {
12611 switch (section->sh_type)
12612 {
12613 case SHT_GNU_verdef:
12614 {
2cf0635d 12615 Elf_External_Verdef * edefs;
26c527e6
AM
12616 size_t idx;
12617 size_t cnt;
2cf0635d 12618 char * endbuf;
252b5132 12619
015dc7e1 12620 found = true;
252b5132 12621
ca0e11aa
NC
12622 if (filedata->is_separate)
12623 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12624 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12625 section->sh_info),
12626 filedata->file_name,
12627 printable_section_name (filedata, section),
12628 section->sh_info);
12629 else
12630 printf (ngettext ("\nVersion definition section '%s' "
12631 "contains %u entry:\n",
12632 "\nVersion definition section '%s' "
12633 "contains %u entries:\n",
12634 section->sh_info),
12635 printable_section_name (filedata, section),
12636 section->sh_info);
047c3dbf 12637
625d49fc 12638 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12639 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12640 section->sh_offset, section->sh_link,
b6ac461a 12641 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12642
3f5e193b 12643 edefs = (Elf_External_Verdef *)
dda8d76d 12644 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12645 _("version definition section"));
a6e9f9df
AM
12646 if (!edefs)
12647 break;
59245841 12648 endbuf = (char *) edefs + section->sh_size;
252b5132 12649
1445030f 12650 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12651 {
2cf0635d
NC
12652 char * vstart;
12653 Elf_External_Verdef * edef;
b34976b6 12654 Elf_Internal_Verdef ent;
2cf0635d 12655 Elf_External_Verdaux * eaux;
b34976b6 12656 Elf_Internal_Verdaux aux;
26c527e6 12657 size_t isum;
b34976b6 12658 int j;
103f02d3 12659
252b5132 12660 vstart = ((char *) edefs) + idx;
54806181
AM
12661 if (vstart + sizeof (*edef) > endbuf)
12662 break;
252b5132
RH
12663
12664 edef = (Elf_External_Verdef *) vstart;
12665
12666 ent.vd_version = BYTE_GET (edef->vd_version);
12667 ent.vd_flags = BYTE_GET (edef->vd_flags);
12668 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12669 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12670 ent.vd_hash = BYTE_GET (edef->vd_hash);
12671 ent.vd_aux = BYTE_GET (edef->vd_aux);
12672 ent.vd_next = BYTE_GET (edef->vd_next);
12673
26c527e6 12674 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12675 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12676
12677 printf (_(" Index: %d Cnt: %d "),
12678 ent.vd_ndx, ent.vd_cnt);
12679
452bf675 12680 /* Check for overflow. */
1445030f 12681 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12682 break;
12683
252b5132
RH
12684 vstart += ent.vd_aux;
12685
1445030f
AM
12686 if (vstart + sizeof (*eaux) > endbuf)
12687 break;
252b5132
RH
12688 eaux = (Elf_External_Verdaux *) vstart;
12689
12690 aux.vda_name = BYTE_GET (eaux->vda_name);
12691 aux.vda_next = BYTE_GET (eaux->vda_next);
12692
84714f86 12693 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12694 printf (_("Name: %s\n"),
84714f86 12695 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12696 else
12697 printf (_("Name index: %ld\n"), aux.vda_name);
12698
12699 isum = idx + ent.vd_aux;
12700
b34976b6 12701 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12702 {
1445030f
AM
12703 if (aux.vda_next < sizeof (*eaux)
12704 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12705 {
12706 warn (_("Invalid vda_next field of %lx\n"),
12707 aux.vda_next);
12708 j = ent.vd_cnt;
12709 break;
12710 }
dd24e3da 12711 /* Check for overflow. */
7e26601c 12712 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12713 break;
12714
252b5132
RH
12715 isum += aux.vda_next;
12716 vstart += aux.vda_next;
12717
54806181
AM
12718 if (vstart + sizeof (*eaux) > endbuf)
12719 break;
1445030f 12720 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12721
12722 aux.vda_name = BYTE_GET (eaux->vda_name);
12723 aux.vda_next = BYTE_GET (eaux->vda_next);
12724
84714f86 12725 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12726 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12727 isum, j,
84714f86 12728 get_dynamic_name (filedata, aux.vda_name));
252b5132 12729 else
26c527e6 12730 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12731 isum, j, aux.vda_name);
12732 }
dd24e3da 12733
54806181
AM
12734 if (j < ent.vd_cnt)
12735 printf (_(" Version def aux past end of section\n"));
252b5132 12736
c9f02c3e
MR
12737 /* PR 17531:
12738 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12739 if (ent.vd_next < sizeof (*edef)
12740 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12741 {
12742 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12743 cnt = section->sh_info;
12744 break;
12745 }
452bf675 12746 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12747 break;
12748
252b5132
RH
12749 idx += ent.vd_next;
12750 }
dd24e3da 12751
54806181
AM
12752 if (cnt < section->sh_info)
12753 printf (_(" Version definition past end of section\n"));
252b5132
RH
12754
12755 free (edefs);
12756 }
12757 break;
103f02d3 12758
252b5132
RH
12759 case SHT_GNU_verneed:
12760 {
2cf0635d 12761 Elf_External_Verneed * eneed;
26c527e6
AM
12762 size_t idx;
12763 size_t cnt;
2cf0635d 12764 char * endbuf;
252b5132 12765
015dc7e1 12766 found = true;
252b5132 12767
ca0e11aa
NC
12768 if (filedata->is_separate)
12769 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12770 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12771 section->sh_info),
12772 filedata->file_name,
12773 printable_section_name (filedata, section),
12774 section->sh_info);
12775 else
12776 printf (ngettext ("\nVersion needs section '%s' "
12777 "contains %u entry:\n",
12778 "\nVersion needs section '%s' "
12779 "contains %u entries:\n",
12780 section->sh_info),
12781 printable_section_name (filedata, section),
12782 section->sh_info);
047c3dbf 12783
625d49fc 12784 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12785 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12786 section->sh_offset, section->sh_link,
b6ac461a 12787 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12788
dda8d76d 12789 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12790 section->sh_offset, 1,
12791 section->sh_size,
9cf03b7e 12792 _("Version Needs section"));
a6e9f9df
AM
12793 if (!eneed)
12794 break;
59245841 12795 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12796
12797 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12798 {
2cf0635d 12799 Elf_External_Verneed * entry;
b34976b6 12800 Elf_Internal_Verneed ent;
26c527e6 12801 size_t isum;
b34976b6 12802 int j;
2cf0635d 12803 char * vstart;
252b5132
RH
12804
12805 vstart = ((char *) eneed) + idx;
54806181
AM
12806 if (vstart + sizeof (*entry) > endbuf)
12807 break;
252b5132
RH
12808
12809 entry = (Elf_External_Verneed *) vstart;
12810
12811 ent.vn_version = BYTE_GET (entry->vn_version);
12812 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12813 ent.vn_file = BYTE_GET (entry->vn_file);
12814 ent.vn_aux = BYTE_GET (entry->vn_aux);
12815 ent.vn_next = BYTE_GET (entry->vn_next);
12816
26c527e6 12817 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12818
84714f86 12819 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12820 printf (_(" File: %s"),
84714f86 12821 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12822 else
12823 printf (_(" File: %lx"), ent.vn_file);
12824
12825 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12826
dd24e3da 12827 /* Check for overflow. */
7e26601c 12828 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12829 break;
252b5132
RH
12830 vstart += ent.vn_aux;
12831
12832 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12833 {
2cf0635d 12834 Elf_External_Vernaux * eaux;
b34976b6 12835 Elf_Internal_Vernaux aux;
252b5132 12836
54806181
AM
12837 if (vstart + sizeof (*eaux) > endbuf)
12838 break;
252b5132
RH
12839 eaux = (Elf_External_Vernaux *) vstart;
12840
12841 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12842 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12843 aux.vna_other = BYTE_GET (eaux->vna_other);
12844 aux.vna_name = BYTE_GET (eaux->vna_name);
12845 aux.vna_next = BYTE_GET (eaux->vna_next);
12846
84714f86 12847 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12848 printf (_(" %#06zx: Name: %s"),
84714f86 12849 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12850 else
26c527e6 12851 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12852 isum, aux.vna_name);
12853
12854 printf (_(" Flags: %s Version: %d\n"),
12855 get_ver_flags (aux.vna_flags), aux.vna_other);
12856
1445030f
AM
12857 if (aux.vna_next < sizeof (*eaux)
12858 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12859 {
12860 warn (_("Invalid vna_next field of %lx\n"),
12861 aux.vna_next);
12862 j = ent.vn_cnt;
12863 break;
12864 }
1445030f
AM
12865 /* Check for overflow. */
12866 if (aux.vna_next > (size_t) (endbuf - vstart))
12867 break;
252b5132
RH
12868 isum += aux.vna_next;
12869 vstart += aux.vna_next;
12870 }
9cf03b7e 12871
54806181 12872 if (j < ent.vn_cnt)
f9a6a8f0 12873 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12874
1445030f
AM
12875 if (ent.vn_next < sizeof (*entry)
12876 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12877 {
452bf675 12878 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12879 cnt = section->sh_info;
12880 break;
12881 }
1445030f
AM
12882 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12883 break;
252b5132
RH
12884 idx += ent.vn_next;
12885 }
9cf03b7e 12886
54806181 12887 if (cnt < section->sh_info)
9cf03b7e 12888 warn (_("Missing Version Needs information\n"));
103f02d3 12889
252b5132
RH
12890 free (eneed);
12891 }
12892 break;
12893
12894 case SHT_GNU_versym:
12895 {
2cf0635d 12896 Elf_Internal_Shdr * link_section;
26c527e6 12897 uint64_t total;
8b73c356 12898 unsigned int cnt;
2cf0635d
NC
12899 unsigned char * edata;
12900 unsigned short * data;
12901 char * strtab;
12902 Elf_Internal_Sym * symbols;
12903 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12904 uint64_t num_syms;
12905 uint64_t off;
252b5132 12906
dda8d76d 12907 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12908 break;
12909
dda8d76d 12910 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12911 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12912
dda8d76d 12913 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12914 break;
12915
015dc7e1 12916 found = true;
252b5132 12917
4de91c10 12918 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12919 if (symbols == NULL)
12920 break;
252b5132 12921
dda8d76d 12922 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12923
dda8d76d 12924 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12925 string_sec->sh_size,
12926 _("version string table"));
a6e9f9df 12927 if (!strtab)
0429c154
MS
12928 {
12929 free (symbols);
12930 break;
12931 }
252b5132 12932
ca0e11aa 12933 if (filedata->is_separate)
26c527e6
AM
12934 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12935 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12936 total),
12937 filedata->file_name,
12938 printable_section_name (filedata, section),
26c527e6 12939 total);
ca0e11aa
NC
12940 else
12941 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12942 "contains %" PRIu64 " entry:\n",
ca0e11aa 12943 "\nVersion symbols section '%s' "
26c527e6 12944 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12945 total),
12946 printable_section_name (filedata, section),
26c527e6 12947 total);
252b5132 12948
625d49fc 12949 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12950 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12951 section->sh_offset, section->sh_link,
dda8d76d 12952 printable_section_name (filedata, link_section));
252b5132 12953
dda8d76d 12954 off = offset_from_vma (filedata,
978c4450 12955 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12956 total * sizeof (short));
95099889
AM
12957 edata = (unsigned char *) get_data (NULL, filedata, off,
12958 sizeof (short), total,
12959 _("version symbol data"));
a6e9f9df
AM
12960 if (!edata)
12961 {
12962 free (strtab);
0429c154 12963 free (symbols);
a6e9f9df
AM
12964 break;
12965 }
252b5132 12966
3f5e193b 12967 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12968
12969 for (cnt = total; cnt --;)
b34976b6
AM
12970 data[cnt] = byte_get (edata + cnt * sizeof (short),
12971 sizeof (short));
252b5132
RH
12972
12973 free (edata);
12974
12975 for (cnt = 0; cnt < total; cnt += 4)
12976 {
12977 int j, nn;
ab273396
AM
12978 char *name;
12979 char *invalid = _("*invalid*");
252b5132
RH
12980
12981 printf (" %03x:", cnt);
12982
12983 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12984 switch (data[cnt + j])
252b5132
RH
12985 {
12986 case 0:
12987 fputs (_(" 0 (*local*) "), stdout);
12988 break;
12989
12990 case 1:
12991 fputs (_(" 1 (*global*) "), stdout);
12992 break;
12993
12994 default:
c244d050
NC
12995 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12996 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12997
dd24e3da 12998 /* If this index value is greater than the size of the symbols
ba5cdace 12999 array, break to avoid an out-of-bounds read. */
26c527e6 13000 if (cnt + j >= num_syms)
dd24e3da
NC
13001 {
13002 warn (_("invalid index into symbol array\n"));
13003 break;
13004 }
13005
ab273396 13006 name = NULL;
978c4450 13007 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13008 {
b34976b6 13009 Elf_Internal_Verneed ivn;
26c527e6 13010 uint64_t offset;
252b5132 13011
d93f0186 13012 offset = offset_from_vma
978c4450
AM
13013 (filedata,
13014 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13015 sizeof (Elf_External_Verneed));
252b5132 13016
b34976b6 13017 do
252b5132 13018 {
b34976b6
AM
13019 Elf_Internal_Vernaux ivna;
13020 Elf_External_Verneed evn;
13021 Elf_External_Vernaux evna;
26c527e6 13022 uint64_t a_off;
252b5132 13023
dda8d76d 13024 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13025 _("version need")) == NULL)
13026 break;
0b4362b0 13027
252b5132
RH
13028 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13029 ivn.vn_next = BYTE_GET (evn.vn_next);
13030
13031 a_off = offset + ivn.vn_aux;
13032
13033 do
13034 {
dda8d76d 13035 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13036 1, _("version need aux (2)")) == NULL)
13037 {
13038 ivna.vna_next = 0;
13039 ivna.vna_other = 0;
13040 }
13041 else
13042 {
13043 ivna.vna_next = BYTE_GET (evna.vna_next);
13044 ivna.vna_other = BYTE_GET (evna.vna_other);
13045 }
252b5132
RH
13046
13047 a_off += ivna.vna_next;
13048 }
b34976b6 13049 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13050 && ivna.vna_next != 0);
13051
b34976b6 13052 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13053 {
13054 ivna.vna_name = BYTE_GET (evna.vna_name);
13055
54806181 13056 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13057 name = invalid;
54806181
AM
13058 else
13059 name = strtab + ivna.vna_name;
252b5132
RH
13060 break;
13061 }
13062
13063 offset += ivn.vn_next;
13064 }
13065 while (ivn.vn_next);
13066 }
00d93f34 13067
ab273396 13068 if (data[cnt + j] != 0x8001
978c4450 13069 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13070 {
b34976b6
AM
13071 Elf_Internal_Verdef ivd;
13072 Elf_External_Verdef evd;
26c527e6 13073 uint64_t offset;
252b5132 13074
d93f0186 13075 offset = offset_from_vma
978c4450
AM
13076 (filedata,
13077 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13078 sizeof evd);
252b5132
RH
13079
13080 do
13081 {
dda8d76d 13082 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13083 _("version def")) == NULL)
13084 {
13085 ivd.vd_next = 0;
948f632f 13086 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13087 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13088 break;
59245841
NC
13089 }
13090 else
13091 {
13092 ivd.vd_next = BYTE_GET (evd.vd_next);
13093 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13094 }
252b5132
RH
13095
13096 offset += ivd.vd_next;
13097 }
c244d050 13098 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13099 && ivd.vd_next != 0);
13100
c244d050 13101 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13102 {
b34976b6
AM
13103 Elf_External_Verdaux evda;
13104 Elf_Internal_Verdaux ivda;
252b5132
RH
13105
13106 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13107
dda8d76d 13108 if (get_data (&evda, filedata,
59245841
NC
13109 offset - ivd.vd_next + ivd.vd_aux,
13110 sizeof (evda), 1,
13111 _("version def aux")) == NULL)
13112 break;
252b5132
RH
13113
13114 ivda.vda_name = BYTE_GET (evda.vda_name);
13115
54806181 13116 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13117 name = invalid;
13118 else if (name != NULL && name != invalid)
13119 name = _("*both*");
54806181
AM
13120 else
13121 name = strtab + ivda.vda_name;
252b5132
RH
13122 }
13123 }
ab273396
AM
13124 if (name != NULL)
13125 nn += printf ("(%s%-*s",
13126 name,
13127 12 - (int) strlen (name),
13128 ")");
252b5132
RH
13129
13130 if (nn < 18)
13131 printf ("%*c", 18 - nn, ' ');
13132 }
13133
13134 putchar ('\n');
13135 }
13136
13137 free (data);
13138 free (strtab);
13139 free (symbols);
13140 }
13141 break;
103f02d3 13142
252b5132
RH
13143 default:
13144 break;
13145 }
13146 }
13147
13148 if (! found)
ca0e11aa
NC
13149 {
13150 if (filedata->is_separate)
13151 printf (_("\nNo version information found in linked file '%s'.\n"),
13152 filedata->file_name);
13153 else
13154 printf (_("\nNo version information found in this file.\n"));
13155 }
252b5132 13156
015dc7e1 13157 return true;
252b5132
RH
13158}
13159
d1133906 13160static const char *
dda8d76d 13161get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13162{
89246a0e 13163 static char buff[64];
252b5132
RH
13164
13165 switch (binding)
13166 {
b34976b6
AM
13167 case STB_LOCAL: return "LOCAL";
13168 case STB_GLOBAL: return "GLOBAL";
13169 case STB_WEAK: return "WEAK";
252b5132
RH
13170 default:
13171 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13172 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13173 binding);
252b5132 13174 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13175 {
13176 if (binding == STB_GNU_UNIQUE
df3a023b 13177 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13178 return "UNIQUE";
13179 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13180 }
252b5132 13181 else
e9e44622 13182 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13183 return buff;
13184 }
13185}
13186
d1133906 13187static const char *
dda8d76d 13188get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13189{
89246a0e 13190 static char buff[64];
252b5132
RH
13191
13192 switch (type)
13193 {
b34976b6
AM
13194 case STT_NOTYPE: return "NOTYPE";
13195 case STT_OBJECT: return "OBJECT";
13196 case STT_FUNC: return "FUNC";
13197 case STT_SECTION: return "SECTION";
13198 case STT_FILE: return "FILE";
13199 case STT_COMMON: return "COMMON";
13200 case STT_TLS: return "TLS";
15ab5209
DB
13201 case STT_RELC: return "RELC";
13202 case STT_SRELC: return "SRELC";
252b5132
RH
13203 default:
13204 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13205 {
dda8d76d 13206 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13207 return "THUMB_FUNC";
103f02d3 13208
dda8d76d 13209 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13210 return "REGISTER";
13211
dda8d76d 13212 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13213 return "PARISC_MILLI";
13214
e9e44622 13215 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13216 }
252b5132 13217 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13218 {
dda8d76d 13219 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13220 {
13221 if (type == STT_HP_OPAQUE)
13222 return "HP_OPAQUE";
13223 if (type == STT_HP_STUB)
13224 return "HP_STUB";
13225 }
13226
8654c01f
ML
13227 if (type == STT_GNU_IFUNC
13228 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13229 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13230 return "IFUNC";
13231
e9e44622 13232 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13233 }
252b5132 13234 else
e9e44622 13235 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13236 return buff;
13237 }
13238}
13239
d1133906 13240static const char *
d3ba0551 13241get_symbol_visibility (unsigned int visibility)
d1133906
NC
13242{
13243 switch (visibility)
13244 {
b34976b6
AM
13245 case STV_DEFAULT: return "DEFAULT";
13246 case STV_INTERNAL: return "INTERNAL";
13247 case STV_HIDDEN: return "HIDDEN";
d1133906 13248 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13249 default:
27a45f42 13250 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13251 return _("<unknown>");
d1133906
NC
13252 }
13253}
13254
2057d69d
CZ
13255static const char *
13256get_alpha_symbol_other (unsigned int other)
9abca702 13257{
2057d69d
CZ
13258 switch (other)
13259 {
13260 case STO_ALPHA_NOPV: return "NOPV";
13261 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13262 default:
27a45f42 13263 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13264 return _("<unknown>");
9abca702 13265 }
2057d69d
CZ
13266}
13267
fd85a6a1
NC
13268static const char *
13269get_solaris_symbol_visibility (unsigned int visibility)
13270{
13271 switch (visibility)
13272 {
13273 case 4: return "EXPORTED";
13274 case 5: return "SINGLETON";
13275 case 6: return "ELIMINATE";
13276 default: return get_symbol_visibility (visibility);
13277 }
13278}
13279
2301ed1c
SN
13280static const char *
13281get_aarch64_symbol_other (unsigned int other)
13282{
13283 static char buf[32];
13284
13285 if (other & STO_AARCH64_VARIANT_PCS)
13286 {
13287 other &= ~STO_AARCH64_VARIANT_PCS;
13288 if (other == 0)
13289 return "VARIANT_PCS";
13290 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13291 return buf;
13292 }
13293 return NULL;
13294}
13295
5e2b0d47
NC
13296static const char *
13297get_mips_symbol_other (unsigned int other)
13298{
13299 switch (other)
13300 {
32ec8896
NC
13301 case STO_OPTIONAL: return "OPTIONAL";
13302 case STO_MIPS_PLT: return "MIPS PLT";
13303 case STO_MIPS_PIC: return "MIPS PIC";
13304 case STO_MICROMIPS: return "MICROMIPS";
13305 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13306 case STO_MIPS16: return "MIPS16";
13307 default: return NULL;
5e2b0d47
NC
13308 }
13309}
13310
28f997cf 13311static const char *
dda8d76d 13312get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13313{
dda8d76d 13314 if (is_ia64_vms (filedata))
28f997cf
TG
13315 {
13316 static char res[32];
13317
13318 res[0] = 0;
13319
13320 /* Function types is for images and .STB files only. */
dda8d76d 13321 switch (filedata->file_header.e_type)
28f997cf
TG
13322 {
13323 case ET_DYN:
13324 case ET_EXEC:
13325 switch (VMS_ST_FUNC_TYPE (other))
13326 {
13327 case VMS_SFT_CODE_ADDR:
13328 strcat (res, " CA");
13329 break;
13330 case VMS_SFT_SYMV_IDX:
13331 strcat (res, " VEC");
13332 break;
13333 case VMS_SFT_FD:
13334 strcat (res, " FD");
13335 break;
13336 case VMS_SFT_RESERVE:
13337 strcat (res, " RSV");
13338 break;
13339 default:
bee0ee85
NC
13340 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13341 VMS_ST_FUNC_TYPE (other));
13342 strcat (res, " <unknown>");
13343 break;
28f997cf
TG
13344 }
13345 break;
13346 default:
13347 break;
13348 }
13349 switch (VMS_ST_LINKAGE (other))
13350 {
13351 case VMS_STL_IGNORE:
13352 strcat (res, " IGN");
13353 break;
13354 case VMS_STL_RESERVE:
13355 strcat (res, " RSV");
13356 break;
13357 case VMS_STL_STD:
13358 strcat (res, " STD");
13359 break;
13360 case VMS_STL_LNK:
13361 strcat (res, " LNK");
13362 break;
13363 default:
bee0ee85
NC
13364 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13365 VMS_ST_LINKAGE (other));
13366 strcat (res, " <unknown>");
13367 break;
28f997cf
TG
13368 }
13369
13370 if (res[0] != 0)
13371 return res + 1;
13372 else
13373 return res;
13374 }
13375 return NULL;
13376}
13377
6911b7dc
AM
13378static const char *
13379get_ppc64_symbol_other (unsigned int other)
13380{
14732552
AM
13381 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13382 return NULL;
13383
13384 other >>= STO_PPC64_LOCAL_BIT;
13385 if (other <= 6)
6911b7dc 13386 {
89246a0e 13387 static char buf[64];
14732552
AM
13388 if (other >= 2)
13389 other = ppc64_decode_local_entry (other);
13390 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13391 return buf;
13392 }
13393 return NULL;
13394}
13395
8155b853
NC
13396static const char *
13397get_riscv_symbol_other (unsigned int other)
13398{
13399 static char buf[32];
13400 buf[0] = 0;
13401
13402 if (other & STO_RISCV_VARIANT_CC)
13403 {
13404 strcat (buf, _(" VARIANT_CC"));
13405 other &= ~STO_RISCV_VARIANT_CC;
13406 }
13407
13408 if (other != 0)
13409 snprintf (buf, sizeof buf, " %x", other);
13410
13411
13412 if (buf[0] != 0)
13413 return buf + 1;
13414 else
13415 return buf;
13416}
13417
5e2b0d47 13418static const char *
dda8d76d 13419get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13420{
13421 const char * result = NULL;
89246a0e 13422 static char buff [64];
5e2b0d47
NC
13423
13424 if (other == 0)
13425 return "";
13426
dda8d76d 13427 switch (filedata->file_header.e_machine)
5e2b0d47 13428 {
2057d69d
CZ
13429 case EM_ALPHA:
13430 result = get_alpha_symbol_other (other);
13431 break;
2301ed1c
SN
13432 case EM_AARCH64:
13433 result = get_aarch64_symbol_other (other);
13434 break;
5e2b0d47
NC
13435 case EM_MIPS:
13436 result = get_mips_symbol_other (other);
28f997cf
TG
13437 break;
13438 case EM_IA_64:
dda8d76d 13439 result = get_ia64_symbol_other (filedata, other);
28f997cf 13440 break;
6911b7dc
AM
13441 case EM_PPC64:
13442 result = get_ppc64_symbol_other (other);
13443 break;
8155b853
NC
13444 case EM_RISCV:
13445 result = get_riscv_symbol_other (other);
13446 break;
5e2b0d47 13447 default:
fd85a6a1 13448 result = NULL;
5e2b0d47
NC
13449 break;
13450 }
13451
13452 if (result)
13453 return result;
13454
13455 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13456 return buff;
13457}
13458
bb4d2ac2 13459static const char *
26c527e6
AM
13460get_symbol_version_string (Filedata *filedata,
13461 bool is_dynsym,
13462 const char *strtab,
13463 size_t strtab_size,
13464 unsigned int si,
13465 Elf_Internal_Sym *psym,
13466 enum versioned_symbol_info *sym_info,
13467 unsigned short *vna_other)
bb4d2ac2 13468{
ab273396
AM
13469 unsigned char data[2];
13470 unsigned short vers_data;
26c527e6 13471 uint64_t offset;
7a815dd5 13472 unsigned short max_vd_ndx;
bb4d2ac2 13473
ab273396 13474 if (!is_dynsym
978c4450 13475 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13476 return NULL;
bb4d2ac2 13477
978c4450
AM
13478 offset = offset_from_vma (filedata,
13479 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13480 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13481
dda8d76d 13482 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13483 sizeof (data), 1, _("version data")) == NULL)
13484 return NULL;
13485
13486 vers_data = byte_get (data, 2);
bb4d2ac2 13487
1f6f5dba 13488 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13489 return NULL;
bb4d2ac2 13490
0b8b7609 13491 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13492 max_vd_ndx = 0;
13493
ab273396
AM
13494 /* Usually we'd only see verdef for defined symbols, and verneed for
13495 undefined symbols. However, symbols defined by the linker in
13496 .dynbss for variables copied from a shared library in order to
13497 avoid text relocations are defined yet have verneed. We could
13498 use a heuristic to detect the special case, for example, check
13499 for verneed first on symbols defined in SHT_NOBITS sections, but
13500 it is simpler and more reliable to just look for both verdef and
13501 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13502
ab273396
AM
13503 if (psym->st_shndx != SHN_UNDEF
13504 && vers_data != 0x8001
978c4450 13505 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13506 {
13507 Elf_Internal_Verdef ivd;
13508 Elf_Internal_Verdaux ivda;
13509 Elf_External_Verdaux evda;
26c527e6 13510 uint64_t off;
bb4d2ac2 13511
dda8d76d 13512 off = offset_from_vma (filedata,
978c4450 13513 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13514 sizeof (Elf_External_Verdef));
13515
13516 do
bb4d2ac2 13517 {
ab273396
AM
13518 Elf_External_Verdef evd;
13519
dda8d76d 13520 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13521 _("version def")) == NULL)
13522 {
13523 ivd.vd_ndx = 0;
13524 ivd.vd_aux = 0;
13525 ivd.vd_next = 0;
1f6f5dba 13526 ivd.vd_flags = 0;
ab273396
AM
13527 }
13528 else
bb4d2ac2 13529 {
ab273396
AM
13530 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13531 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13532 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13533 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13534 }
bb4d2ac2 13535
7a815dd5
L
13536 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13537 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13538
ab273396
AM
13539 off += ivd.vd_next;
13540 }
13541 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13542
ab273396
AM
13543 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13544 {
9abca702 13545 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13546 return NULL;
13547
ab273396
AM
13548 off -= ivd.vd_next;
13549 off += ivd.vd_aux;
bb4d2ac2 13550
dda8d76d 13551 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13552 _("version def aux")) != NULL)
13553 {
13554 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13555
ab273396 13556 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13557 return (ivda.vda_name < strtab_size
13558 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13559 }
13560 }
13561 }
bb4d2ac2 13562
978c4450 13563 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13564 {
13565 Elf_External_Verneed evn;
13566 Elf_Internal_Verneed ivn;
13567 Elf_Internal_Vernaux ivna;
bb4d2ac2 13568
dda8d76d 13569 offset = offset_from_vma (filedata,
978c4450 13570 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13571 sizeof evn);
13572 do
13573 {
26c527e6 13574 uint64_t vna_off;
bb4d2ac2 13575
dda8d76d 13576 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13577 _("version need")) == NULL)
13578 {
13579 ivna.vna_next = 0;
13580 ivna.vna_other = 0;
13581 ivna.vna_name = 0;
13582 break;
13583 }
bb4d2ac2 13584
ab273396
AM
13585 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13586 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13587
ab273396 13588 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13589
ab273396
AM
13590 do
13591 {
13592 Elf_External_Vernaux evna;
bb4d2ac2 13593
dda8d76d 13594 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13595 _("version need aux (3)")) == NULL)
bb4d2ac2 13596 {
ab273396
AM
13597 ivna.vna_next = 0;
13598 ivna.vna_other = 0;
13599 ivna.vna_name = 0;
bb4d2ac2 13600 }
bb4d2ac2 13601 else
bb4d2ac2 13602 {
ab273396
AM
13603 ivna.vna_other = BYTE_GET (evna.vna_other);
13604 ivna.vna_next = BYTE_GET (evna.vna_next);
13605 ivna.vna_name = BYTE_GET (evna.vna_name);
13606 }
bb4d2ac2 13607
ab273396
AM
13608 vna_off += ivna.vna_next;
13609 }
13610 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13611
ab273396
AM
13612 if (ivna.vna_other == vers_data)
13613 break;
bb4d2ac2 13614
ab273396
AM
13615 offset += ivn.vn_next;
13616 }
13617 while (ivn.vn_next != 0);
bb4d2ac2 13618
ab273396
AM
13619 if (ivna.vna_other == vers_data)
13620 {
13621 *sym_info = symbol_undefined;
13622 *vna_other = ivna.vna_other;
13623 return (ivna.vna_name < strtab_size
13624 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13625 }
7a815dd5
L
13626 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13627 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13628 return _("<corrupt>");
bb4d2ac2 13629 }
ab273396 13630 return NULL;
bb4d2ac2
L
13631}
13632
047c3dbf
NL
13633/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13634
13635static unsigned int
b6ac461a 13636print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13637{
13638 switch (base)
13639 {
13640 case 8:
13641 return print_vma (vma, OCTAL_5);
13642
13643 case 10:
13644 return print_vma (vma, UNSIGNED_5);
13645
13646 case 16:
13647 return print_vma (vma, PREFIX_HEX_5);
13648
13649 case 0:
13650 default:
13651 return print_vma (vma, DEC_5);
13652 }
13653}
13654
b6ac461a
NC
13655/* Print information on a single symbol. */
13656
10ca4b04 13657static void
b6ac461a
NC
13658print_symbol (Filedata * filedata,
13659 uint64_t symbol_index,
13660 Elf_Internal_Sym * symtab,
13661 Elf_Internal_Shdr * section,
13662 char * strtab,
13663 size_t strtab_size)
252b5132 13664{
10ca4b04
L
13665 const char *version_string;
13666 enum versioned_symbol_info sym_info;
13667 unsigned short vna_other;
23356397 13668 const char * sstr;
b6ac461a 13669 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 13670
b6ac461a
NC
13671 /* FIXME: We should have a table of field widths,
13672 rather than using hard coded constants. */
13673 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
13674 print_vma (psym->st_value, LONG_HEX);
13675 putchar (' ');
b6ac461a 13676 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13677 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13678 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13679 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13680 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13681 else
252b5132 13682 {
10ca4b04 13683 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13684
10ca4b04 13685 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 13686
10ca4b04 13687 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
13688 FIXME: Displaying this information here disrupts the layout
13689 of the table being generated. */
10ca4b04
L
13690 if (psym->st_other ^ vis)
13691 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13692 }
0942c7ab 13693
b6ac461a
NC
13694 bool is_special;
13695
13696 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13697
13698 /* Print the symbol's section index. If the index is special
13699 then print the index's name rather than its number. */
13700 if (is_special)
13701 {
13702 int printed;
13703
13704 /* Special case: If there are no section headers, and the printable
13705 name is "<section 0x...." then just display the section number
13706 as a decimal. This happens when objcopy --strip -section-headers
13707 is used. */
13708 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13709 printed = printf (" %4d ", psym->st_shndx);
13710 else
13711 printed = printf (" %4s ", sstr);
13712
13713 if (extra_sym_info && printed < 16)
13714 printf ("%*s", 16 - printed, "");
13715 }
13716 else
13717 {
13718 printf (" %4u ", psym->st_shndx);
13719
13720 if (extra_sym_info)
13721 {
13722 /* Display the section name referenced by the section index. */
13723 int printed = printf ("(%s) ", sstr);
13724 if (printed < 10)
13725 printf ("%*s", 10 - printed, "");
13726 }
13727 }
13728
13729 /* Get the symbol's name. For section symbols without a
13730 specific name use the (already computed) section name. */
23356397 13731 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 13732 && section_index_real (filedata, psym->st_shndx)
23356397
NC
13733 && psym->st_name == 0)
13734 {
b6ac461a 13735 ;
23356397
NC
13736 }
13737 else
13738 {
b6ac461a
NC
13739 bool is_valid;
13740
84714f86 13741 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13742 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13743 }
10ca4b04
L
13744
13745 version_string
13746 = get_symbol_version_string (filedata,
13747 (section == NULL
13748 || section->sh_type == SHT_DYNSYM),
b6ac461a 13749 strtab, strtab_size, symbol_index,
10ca4b04 13750 psym, &sym_info, &vna_other);
b9e920ec 13751
0942c7ab
NC
13752 int len_avail = 21;
13753 if (! do_wide && version_string != NULL)
13754 {
ddb43bab 13755 char buffer[16];
0942c7ab 13756
ddb43bab 13757 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13758
13759 if (sym_info == symbol_undefined)
13760 len_avail -= sprintf (buffer," (%d)", vna_other);
13761 else if (sym_info != symbol_hidden)
13762 len_avail -= 1;
13763 }
13764
b6ac461a 13765 print_symbol_name (len_avail, sstr);
b9e920ec 13766
10ca4b04
L
13767 if (version_string)
13768 {
13769 if (sym_info == symbol_undefined)
13770 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13771 else
10ca4b04
L
13772 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13773 version_string);
13774 }
6bd1a22c 13775
10ca4b04 13776 putchar ('\n');
6bd1a22c 13777
10ca4b04
L
13778 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13779 && section != NULL
b6ac461a 13780 && symbol_index >= section->sh_info
10ca4b04
L
13781 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13782 && filedata->file_header.e_machine != EM_MIPS
13783 /* Solaris binaries have been found to violate this requirement as
13784 well. Not sure if this is a bug or an ABI requirement. */
13785 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13786 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 13787 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 13788}
f16a9783 13789
0f03783c
NC
13790static const char *
13791get_lto_kind (unsigned int kind)
13792{
13793 switch (kind)
13794 {
13795 case 0: return "DEF";
13796 case 1: return "WEAKDEF";
13797 case 2: return "UNDEF";
13798 case 3: return "WEAKUNDEF";
13799 case 4: return "COMMON";
13800 default:
13801 break;
13802 }
13803
13804 static char buffer[30];
13805 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13806 sprintf (buffer, "<unknown: %u>", kind);
13807 return buffer;
13808}
13809
13810static const char *
13811get_lto_visibility (unsigned int visibility)
13812{
13813 switch (visibility)
13814 {
13815 case 0: return "DEFAULT";
13816 case 1: return "PROTECTED";
13817 case 2: return "INTERNAL";
13818 case 3: return "HIDDEN";
13819 default:
13820 break;
13821 }
13822
13823 static char buffer[30];
13824 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13825 sprintf (buffer, "<unknown: %u>", visibility);
13826 return buffer;
13827}
13828
13829static const char *
13830get_lto_sym_type (unsigned int sym_type)
13831{
13832 switch (sym_type)
13833 {
13834 case 0: return "UNKNOWN";
13835 case 1: return "FUNCTION";
13836 case 2: return "VARIABLE";
13837 default:
13838 break;
13839 }
13840
13841 static char buffer[30];
13842 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13843 sprintf (buffer, "<unknown: %u>", sym_type);
13844 return buffer;
13845}
13846
13847/* Display an LTO format symbol table.
13848 FIXME: The format of LTO symbol tables is not formalized.
13849 So this code could need changing in the future. */
13850
015dc7e1 13851static bool
0f03783c
NC
13852display_lto_symtab (Filedata * filedata,
13853 Elf_Internal_Shdr * section)
13854{
13855 if (section->sh_size == 0)
13856 {
ca0e11aa
NC
13857 if (filedata->is_separate)
13858 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13859 printable_section_name (filedata, section),
13860 filedata->file_name);
13861 else
13862 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13863 printable_section_name (filedata, section));
047c3dbf 13864
015dc7e1 13865 return true;
0f03783c
NC
13866 }
13867
13868 if (section->sh_size > filedata->file_size)
13869 {
26c527e6 13870 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13871 printable_section_name (filedata, section),
26c527e6 13872 section->sh_size);
015dc7e1 13873 return false;
0f03783c
NC
13874 }
13875
13876 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13877 section->sh_size, 1, _("LTO symbols"));
13878 if (alloced_data == NULL)
015dc7e1 13879 return false;
0f03783c
NC
13880
13881 /* Look for extended data for the symbol table. */
765a0c0a 13882 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
13883 void * ext_data_orig = NULL;
13884 char * ext_data = NULL;
13885 char * ext_data_end = NULL;
13886 char * ext_name = NULL;
13887
13888 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13889 (section_name (filedata, section)
13890 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13891 && ext_name != NULL /* Paranoia. */
13892 && (ext = find_section (filedata, ext_name)) != NULL)
13893 {
13894 if (ext->sh_size < 3)
13895 error (_("LTO Symbol extension table '%s' is empty!\n"),
13896 printable_section_name (filedata, ext));
13897 else
13898 {
13899 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13900 ext->sh_size, 1,
13901 _("LTO ext symbol data"));
13902 if (ext_data != NULL)
13903 {
13904 ext_data_end = ext_data + ext->sh_size;
13905 if (* ext_data++ != 1)
13906 error (_("Unexpected version number in symbol extension table\n"));
13907 }
13908 }
13909 }
b9e920ec 13910
0f03783c
NC
13911 const unsigned char * data = (const unsigned char *) alloced_data;
13912 const unsigned char * end = data + section->sh_size;
13913
ca0e11aa
NC
13914 if (filedata->is_separate)
13915 printf (_("\nIn linked file '%s': "), filedata->file_name);
13916 else
13917 printf ("\n");
13918
0f03783c
NC
13919 if (ext_data_orig != NULL)
13920 {
13921 if (do_wide)
ca0e11aa 13922 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13923 printable_section_name (filedata, section),
13924 printable_section_name (filedata, ext));
13925 else
13926 {
ca0e11aa 13927 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13928 printable_section_name (filedata, section));
13929 printf (_(" and extension table '%s' contain:\n"),
13930 printable_section_name (filedata, ext));
13931 }
13932 }
13933 else
ca0e11aa 13934 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13935 printable_section_name (filedata, section));
b9e920ec 13936
0f03783c 13937 /* FIXME: Add a wide version. */
b9e920ec 13938 if (ext_data_orig != NULL)
0f03783c
NC
13939 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13940 else
13941 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13942
13943 /* FIXME: We do not handle style prefixes. */
13944
13945 while (data < end)
13946 {
13947 const unsigned char * sym_name = data;
13948 data += strnlen ((const char *) sym_name, end - data) + 1;
13949 if (data >= end)
13950 goto fail;
13951
13952 const unsigned char * comdat_key = data;
13953 data += strnlen ((const char *) comdat_key, end - data) + 1;
13954 if (data >= end)
13955 goto fail;
13956
13957 if (data + 2 + 8 + 4 > end)
13958 goto fail;
13959
13960 unsigned int kind = *data++;
13961 unsigned int visibility = *data++;
13962
928c411d 13963 uint64_t size = byte_get (data, 8);
0f03783c
NC
13964 data += 8;
13965
928c411d 13966 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13967 data += 4;
13968
13969 if (ext_data != NULL)
13970 {
13971 if (ext_data < (ext_data_end - 1))
13972 {
13973 unsigned int sym_type = * ext_data ++;
13974 unsigned int sec_kind = * ext_data ++;
13975
31e5a3a3 13976 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13977 * comdat_key == 0 ? "-" : (char *) comdat_key,
13978 get_lto_kind (kind),
13979 get_lto_visibility (visibility),
31e5a3a3
AM
13980 size,
13981 slot,
0f03783c 13982 get_lto_sym_type (sym_type),
31e5a3a3 13983 sec_kind);
b6ac461a 13984 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
13985 }
13986 else
13987 {
13988 error (_("Ran out of LTO symbol extension data\n"));
13989 ext_data = NULL;
13990 /* FIXME: return FAIL result ? */
13991 }
13992 }
13993 else
13994 {
31e5a3a3 13995 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13996 * comdat_key == 0 ? "-" : (char *) comdat_key,
13997 get_lto_kind (kind),
13998 get_lto_visibility (visibility),
31e5a3a3
AM
13999 size,
14000 slot);
b6ac461a 14001 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
14002 }
14003 putchar ('\n');
14004 }
14005
14006 if (ext_data != NULL && ext_data < ext_data_end)
14007 {
14008 error (_("Data remains in the LTO symbol extension table\n"));
14009 goto fail;
14010 }
14011
14012 free (alloced_data);
14013 free (ext_data_orig);
14014 free (ext_name);
015dc7e1 14015 return true;
b9e920ec 14016
0f03783c
NC
14017 fail:
14018 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14019 free (alloced_data);
14020 free (ext_data_orig);
14021 free (ext_name);
015dc7e1 14022 return false;
0f03783c
NC
14023}
14024
14025/* Display LTO symbol tables. */
14026
015dc7e1 14027static bool
0f03783c
NC
14028process_lto_symbol_tables (Filedata * filedata)
14029{
14030 Elf_Internal_Shdr * section;
14031 unsigned int i;
015dc7e1 14032 bool res = true;
0f03783c
NC
14033
14034 if (!do_lto_syms)
015dc7e1 14035 return true;
0f03783c
NC
14036
14037 if (filedata->section_headers == NULL)
015dc7e1 14038 return true;
0f03783c
NC
14039
14040 for (i = 0, section = filedata->section_headers;
14041 i < filedata->file_header.e_shnum;
14042 i++, section++)
84714f86
AM
14043 if (section_name_valid (filedata, section)
14044 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14045 res &= display_lto_symtab (filedata, section);
14046
b9e920ec 14047 return res;
0f03783c
NC
14048}
14049
b6ac461a
NC
14050static void
14051print_symbol_table_heading (void)
14052{
14053 /* FIXME: We should store the size of each field in the display in a table and
14054 then use the values inside print_symbol(), instead of that function using
14055 hard coded constants. */
14056 if (is_32bit_elf)
14057 {
14058 if (extra_sym_info)
14059 {
14060 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14061 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14062 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14063 }
14064 else if (do_wide)
14065 {
14066 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14067 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14068 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14069 }
14070 else
14071 {
14072 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14073 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14074 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14075 }
14076 }
14077 else
14078 {
14079 if (extra_sym_info)
14080 {
14081 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14082 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14083 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14084
14085 }
14086 else if (do_wide)
14087 {
14088 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14089 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14090 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14091 }
14092 else
14093 {
14094 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14095 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14096 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14097 }
14098 }
14099}
14100
10ca4b04 14101/* Dump the symbol table. */
0f03783c 14102
015dc7e1 14103static bool
10ca4b04
L
14104process_symbol_table (Filedata * filedata)
14105{
14106 Elf_Internal_Shdr * section;
f16a9783 14107
10ca4b04 14108 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14109 return true;
6bd1a22c 14110
978c4450 14111 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14112 && do_syms
14113 && do_using_dynamic
978c4450
AM
14114 && filedata->dynamic_strings != NULL
14115 && filedata->dynamic_symbols != NULL)
6bd1a22c 14116 {
26c527e6 14117 uint64_t si;
6bd1a22c 14118
ca0e11aa
NC
14119 if (filedata->is_separate)
14120 {
26c527e6
AM
14121 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14122 " contains %" PRIu64 " entry:\n",
14123 "\nIn linked file '%s' the dynamic symbol table"
14124 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14125 filedata->num_dynamic_syms),
14126 filedata->file_name,
14127 filedata->num_dynamic_syms);
14128 }
14129 else
14130 {
26c527e6
AM
14131 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14132 " entry:\n",
14133 "\nSymbol table for image contains %" PRIu64
14134 " entries:\n",
ca0e11aa
NC
14135 filedata->num_dynamic_syms),
14136 filedata->num_dynamic_syms);
14137 }
b6ac461a
NC
14138
14139 print_symbol_table_heading ();
6bd1a22c 14140
978c4450 14141 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14142 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14143 filedata->dynamic_strings,
14144 filedata->dynamic_strings_length);
252b5132 14145 }
8b73c356 14146 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14147 && filedata->section_headers != NULL)
252b5132 14148 {
b34976b6 14149 unsigned int i;
252b5132 14150
dda8d76d
NC
14151 for (i = 0, section = filedata->section_headers;
14152 i < filedata->file_header.e_shnum;
252b5132
RH
14153 i++, section++)
14154 {
2cf0635d 14155 char * strtab = NULL;
26c527e6 14156 uint64_t strtab_size = 0;
2cf0635d 14157 Elf_Internal_Sym * symtab;
26c527e6 14158 uint64_t si, num_syms;
252b5132 14159
2c610e4b
L
14160 if ((section->sh_type != SHT_SYMTAB
14161 && section->sh_type != SHT_DYNSYM)
14162 || (!do_syms
14163 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14164 continue;
14165
dd24e3da
NC
14166 if (section->sh_entsize == 0)
14167 {
14168 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 14169 printable_section_name (filedata, section));
dd24e3da
NC
14170 continue;
14171 }
14172
d3a49aa8 14173 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
14174
14175 if (filedata->is_separate)
26c527e6
AM
14176 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14177 " contains %" PRIu64 " entry:\n",
14178 "\nIn linked file '%s' symbol section '%s'"
14179 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14180 num_syms),
14181 filedata->file_name,
14182 printable_section_name (filedata, section),
14183 num_syms);
14184 else
26c527e6
AM
14185 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14186 " entry:\n",
14187 "\nSymbol table '%s' contains %" PRIu64
14188 " entries:\n",
ca0e11aa
NC
14189 num_syms),
14190 printable_section_name (filedata, section),
14191 num_syms);
dd24e3da 14192
b6ac461a 14193 print_symbol_table_heading ();
252b5132 14194
4de91c10 14195 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
14196 if (symtab == NULL)
14197 continue;
14198
dda8d76d 14199 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 14200 {
dda8d76d
NC
14201 strtab = filedata->string_table;
14202 strtab_size = filedata->string_table_length;
c256ffe7 14203 }
dda8d76d 14204 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 14205 {
2cf0635d 14206 Elf_Internal_Shdr * string_sec;
252b5132 14207
dda8d76d 14208 string_sec = filedata->section_headers + section->sh_link;
252b5132 14209
dda8d76d 14210 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
14211 1, string_sec->sh_size,
14212 _("string table"));
c256ffe7 14213 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
14214 }
14215
10ca4b04 14216 for (si = 0; si < num_syms; si++)
b6ac461a
NC
14217 print_symbol (filedata, si, symtab, section,
14218 strtab, strtab_size);
252b5132
RH
14219
14220 free (symtab);
dda8d76d 14221 if (strtab != filedata->string_table)
252b5132
RH
14222 free (strtab);
14223 }
14224 }
14225 else if (do_syms)
14226 printf
14227 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14228
978c4450 14229 if (do_histogram && filedata->buckets != NULL)
252b5132 14230 {
26c527e6
AM
14231 uint64_t *lengths;
14232 uint64_t *counts;
14233 uint64_t hn;
625d49fc 14234 uint64_t si;
26c527e6
AM
14235 uint64_t maxlength = 0;
14236 uint64_t nzero_counts = 0;
14237 uint64_t nsyms = 0;
6bd6a03d 14238 char *visited;
252b5132 14239
d3a49aa8 14240 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14241 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14242 "\nHistogram for bucket list length "
26c527e6
AM
14243 "(total of %" PRIu64 " buckets):\n",
14244 filedata->nbuckets),
14245 filedata->nbuckets);
252b5132 14246
26c527e6 14247 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14248 if (lengths == NULL)
14249 {
8b73c356 14250 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14251 goto err_out;
252b5132 14252 }
978c4450
AM
14253 visited = xcmalloc (filedata->nchains, 1);
14254 memset (visited, 0, filedata->nchains);
8b73c356
NC
14255
14256 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14257 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14258 {
978c4450 14259 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14260 {
b34976b6 14261 ++nsyms;
252b5132 14262 if (maxlength < ++lengths[hn])
b34976b6 14263 ++maxlength;
978c4450 14264 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14265 {
14266 error (_("histogram chain is corrupt\n"));
14267 break;
14268 }
14269 visited[si] = 1;
252b5132
RH
14270 }
14271 }
6bd6a03d 14272 free (visited);
252b5132 14273
26c527e6 14274 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14275 if (counts == NULL)
14276 {
b2e951ec 14277 free (lengths);
8b73c356 14278 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14279 goto err_out;
252b5132
RH
14280 }
14281
978c4450 14282 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14283 ++counts[lengths[hn]];
252b5132 14284
978c4450 14285 if (filedata->nbuckets > 0)
252b5132 14286 {
26c527e6
AM
14287 uint64_t i;
14288 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14289 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14290 for (i = 1; i <= maxlength; ++i)
103f02d3 14291 {
66543521 14292 nzero_counts += counts[i] * i;
26c527e6 14293 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14294 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14295 (nzero_counts * 100.0) / nsyms);
14296 }
252b5132
RH
14297 }
14298
14299 free (counts);
14300 free (lengths);
14301 }
14302
978c4450
AM
14303 free (filedata->buckets);
14304 filedata->buckets = NULL;
14305 filedata->nbuckets = 0;
14306 free (filedata->chains);
14307 filedata->chains = NULL;
252b5132 14308
978c4450 14309 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14310 {
26c527e6
AM
14311 uint64_t *lengths;
14312 uint64_t *counts;
14313 uint64_t hn;
14314 uint64_t maxlength = 0;
14315 uint64_t nzero_counts = 0;
14316 uint64_t nsyms = 0;
fdc90cb4 14317
f16a9783 14318 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14319 "(total of %" PRIu64 " bucket):\n",
f16a9783 14320 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14321 "(total of %" PRIu64 " buckets):\n",
14322 filedata->ngnubuckets),
978c4450 14323 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14324 filedata->ngnubuckets);
8b73c356 14325
26c527e6 14326 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14327 if (lengths == NULL)
14328 {
8b73c356 14329 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14330 goto err_out;
fdc90cb4
JJ
14331 }
14332
fdc90cb4
JJ
14333 printf (_(" Length Number %% of total Coverage\n"));
14334
978c4450
AM
14335 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14336 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14337 {
625d49fc 14338 uint64_t off, length = 1;
fdc90cb4 14339
978c4450 14340 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14341 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14342 off < filedata->ngnuchains
14343 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14344 ++off)
fdc90cb4
JJ
14345 ++length;
14346 lengths[hn] = length;
14347 if (length > maxlength)
14348 maxlength = length;
14349 nsyms += length;
14350 }
14351
26c527e6 14352 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14353 if (counts == NULL)
14354 {
b2e951ec 14355 free (lengths);
8b73c356 14356 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14357 goto err_out;
fdc90cb4
JJ
14358 }
14359
978c4450 14360 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14361 ++counts[lengths[hn]];
14362
978c4450 14363 if (filedata->ngnubuckets > 0)
fdc90cb4 14364 {
26c527e6
AM
14365 uint64_t j;
14366 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14367 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14368 for (j = 1; j <= maxlength; ++j)
14369 {
14370 nzero_counts += counts[j] * j;
26c527e6 14371 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14372 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14373 (nzero_counts * 100.0) / nsyms);
14374 }
14375 }
14376
14377 free (counts);
14378 free (lengths);
fdc90cb4 14379 }
978c4450
AM
14380 free (filedata->gnubuckets);
14381 filedata->gnubuckets = NULL;
14382 filedata->ngnubuckets = 0;
14383 free (filedata->gnuchains);
14384 filedata->gnuchains = NULL;
14385 filedata->ngnuchains = 0;
14386 free (filedata->mipsxlat);
14387 filedata->mipsxlat = NULL;
015dc7e1 14388 return true;
fd486f32
AM
14389
14390 err_out:
978c4450
AM
14391 free (filedata->gnubuckets);
14392 filedata->gnubuckets = NULL;
14393 filedata->ngnubuckets = 0;
14394 free (filedata->gnuchains);
14395 filedata->gnuchains = NULL;
14396 filedata->ngnuchains = 0;
14397 free (filedata->mipsxlat);
14398 filedata->mipsxlat = NULL;
14399 free (filedata->buckets);
14400 filedata->buckets = NULL;
14401 filedata->nbuckets = 0;
14402 free (filedata->chains);
14403 filedata->chains = NULL;
015dc7e1 14404 return false;
252b5132
RH
14405}
14406
015dc7e1 14407static bool
ca0e11aa 14408process_syminfo (Filedata * filedata)
252b5132 14409{
b4c96d0d 14410 unsigned int i;
252b5132 14411
978c4450 14412 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14413 || !do_dynamic)
14414 /* No syminfo, this is ok. */
015dc7e1 14415 return true;
252b5132
RH
14416
14417 /* There better should be a dynamic symbol section. */
978c4450 14418 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14419 return false;
252b5132 14420
ca0e11aa 14421 if (filedata->is_separate)
26c527e6
AM
14422 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14423 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14424 filedata->dynamic_syminfo_nent),
14425 filedata->file_name,
14426 filedata->dynamic_syminfo_offset,
14427 filedata->dynamic_syminfo_nent);
14428 else
26c527e6
AM
14429 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14430 " contains %d entry:\n",
14431 "\nDynamic info segment at offset %#" PRIx64
14432 " contains %d entries:\n",
978c4450 14433 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14434 filedata->dynamic_syminfo_offset,
14435 filedata->dynamic_syminfo_nent);
252b5132
RH
14436
14437 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14438 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14439 {
978c4450 14440 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14441
31104126 14442 printf ("%4d: ", i);
978c4450 14443 if (i >= filedata->num_dynamic_syms)
4082ef84 14444 printf (_("<corrupt index>"));
84714f86 14445 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14446 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14447 filedata->dynamic_symbols[i].st_name));
d79b3d50 14448 else
978c4450 14449 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14450 putchar (' ');
252b5132 14451
978c4450 14452 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14453 {
14454 case SYMINFO_BT_SELF:
14455 fputs ("SELF ", stdout);
14456 break;
14457 case SYMINFO_BT_PARENT:
14458 fputs ("PARENT ", stdout);
14459 break;
14460 default:
978c4450
AM
14461 if (filedata->dynamic_syminfo[i].si_boundto > 0
14462 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14463 && valid_dynamic_name (filedata,
978c4450 14464 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14465 {
b6ac461a 14466 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 14467 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14468 putchar (' ' );
14469 }
252b5132 14470 else
978c4450 14471 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14472 break;
14473 }
14474
14475 if (flags & SYMINFO_FLG_DIRECT)
14476 printf (" DIRECT");
14477 if (flags & SYMINFO_FLG_PASSTHRU)
14478 printf (" PASSTHRU");
14479 if (flags & SYMINFO_FLG_COPY)
14480 printf (" COPY");
14481 if (flags & SYMINFO_FLG_LAZYLOAD)
14482 printf (" LAZYLOAD");
14483
14484 puts ("");
14485 }
14486
015dc7e1 14487 return true;
252b5132
RH
14488}
14489
75802ccb
CE
14490/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14491 is contained by the region START .. END. The types of ADDR, START
14492 and END should all be the same. Note both ADDR + NELEM and END
14493 point to just beyond the end of the regions that are being tested. */
14494#define IN_RANGE(START,END,ADDR,NELEM) \
14495 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14496
cf13d699
NC
14497/* Check to see if the given reloc needs to be handled in a target specific
14498 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14499 FALSE.
14500
14501 If called with reloc == NULL, then this is a signal that reloc processing
14502 for the current section has finished, and any saved state should be
14503 discarded. */
09c11c86 14504
015dc7e1 14505static bool
26c527e6
AM
14506target_specific_reloc_handling (Filedata *filedata,
14507 Elf_Internal_Rela *reloc,
14508 unsigned char *start,
14509 unsigned char *end,
14510 Elf_Internal_Sym *symtab,
14511 uint64_t num_syms)
252b5132 14512{
f84ce13b 14513 unsigned int reloc_type = 0;
26c527e6 14514 uint64_t sym_index = 0;
f84ce13b
NC
14515
14516 if (reloc)
14517 {
dda8d76d 14518 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14519 sym_index = get_reloc_symindex (reloc->r_info);
14520 }
252b5132 14521
dda8d76d 14522 switch (filedata->file_header.e_machine)
252b5132 14523 {
76244462 14524 case EM_LOONGARCH:
14525 {
14526 switch (reloc_type)
14527 {
14528 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14529 at assembly time. */
14530 case 107: /* R_LARCH_ADD_ULEB128. */
14531 case 108: /* R_LARCH_SUB_ULEB128. */
14532 {
d3f34076 14533 uint64_t value = 0;
76244462 14534 unsigned int reloc_size = 0;
14535 int leb_ret = 0;
14536
89c70cd3
AM
14537 if (reloc->r_offset < (size_t) (end - start))
14538 value = read_leb128 (start + reloc->r_offset, end, false,
14539 &reloc_size, &leb_ret);
76244462 14540 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14541 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14542 "ULEB128 value\n"),
14543 (long) reloc->r_offset);
14544
74a965d8
AM
14545 else if (sym_index >= num_syms)
14546 error (_("%s reloc contains invalid symbol index "
14547 "%" PRIu64 "\n"),
14548 (reloc_type == 107
14549 ? "R_LARCH_ADD_ULEB128"
14550 : "R_LARCH_SUB_ULEB128"),
14551 sym_index);
14552 else
76244462 14553 {
74a965d8
AM
14554 if (reloc_type == 107)
14555 value += reloc->r_addend + symtab[sym_index].st_value;
14556 else
14557 value -= reloc->r_addend + symtab[sym_index].st_value;
14558
14559 /* Write uleb128 value to p. */
14560 bfd_byte *p = start + reloc->r_offset;
14561 do
14562 {
14563 bfd_byte c = value & 0x7f;
14564 value >>= 7;
14565 if (--reloc_size != 0)
14566 c |= 0x80;
14567 *p++ = c;
14568 }
14569 while (reloc_size);
76244462 14570 }
76244462 14571
14572 return true;
14573 }
14574 }
14575 break;
14576 }
14577
13761a11
NC
14578 case EM_MSP430:
14579 case EM_MSP430_OLD:
14580 {
14581 static Elf_Internal_Sym * saved_sym = NULL;
14582
f84ce13b
NC
14583 if (reloc == NULL)
14584 {
14585 saved_sym = NULL;
015dc7e1 14586 return true;
f84ce13b
NC
14587 }
14588
13761a11
NC
14589 switch (reloc_type)
14590 {
14591 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14592 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14593 if (uses_msp430x_relocs (filedata))
13761a11 14594 break;
1a0670f3 14595 /* Fall through. */
13761a11 14596 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14597 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14598 /* PR 21139. */
14599 if (sym_index >= num_syms)
74a965d8
AM
14600 error (_("%s reloc contains invalid symbol index "
14601 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14602 else
14603 saved_sym = symtab + sym_index;
015dc7e1 14604 return true;
13761a11
NC
14605
14606 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14607 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14608 goto handle_sym_diff;
0b4362b0 14609
13761a11
NC
14610 case 5: /* R_MSP430_16_BYTE */
14611 case 9: /* R_MSP430_8 */
7d81bc93 14612 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14613 if (uses_msp430x_relocs (filedata))
13761a11
NC
14614 break;
14615 goto handle_sym_diff;
14616
14617 case 2: /* R_MSP430_ABS16 */
14618 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14619 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14620 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14621 break;
14622 goto handle_sym_diff;
0b4362b0 14623
13761a11
NC
14624 handle_sym_diff:
14625 if (saved_sym != NULL)
14626 {
625d49fc 14627 uint64_t value;
5a805384 14628 unsigned int reloc_size = 0;
7d81bc93
JL
14629 int leb_ret = 0;
14630 switch (reloc_type)
14631 {
14632 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14633 reloc_size = 4;
14634 break;
14635 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14636 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14637 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14638 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14639 &reloc_size, &leb_ret);
7d81bc93
JL
14640 break;
14641 default:
14642 reloc_size = 2;
14643 break;
14644 }
13761a11 14645
5a805384 14646 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14647 error (_("MSP430 ULEB128 field at %#" PRIx64
14648 " contains invalid ULEB128 value\n"),
14649 reloc->r_offset);
7d81bc93 14650 else if (sym_index >= num_syms)
74a965d8
AM
14651 error (_("%s reloc contains invalid symbol index "
14652 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14653 else
f84ce13b
NC
14654 {
14655 value = reloc->r_addend + (symtab[sym_index].st_value
14656 - saved_sym->st_value);
14657
b32e566b 14658 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14659 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14660 else
14661 /* PR 21137 */
26c527e6
AM
14662 error (_("MSP430 sym diff reloc contains invalid offset: "
14663 "%#" PRIx64 "\n"),
14664 reloc->r_offset);
f84ce13b 14665 }
13761a11
NC
14666
14667 saved_sym = NULL;
015dc7e1 14668 return true;
13761a11
NC
14669 }
14670 break;
14671
14672 default:
14673 if (saved_sym != NULL)
071436c6 14674 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14675 break;
14676 }
14677 break;
14678 }
14679
cf13d699
NC
14680 case EM_MN10300:
14681 case EM_CYGNUS_MN10300:
14682 {
14683 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14684
f84ce13b
NC
14685 if (reloc == NULL)
14686 {
14687 saved_sym = NULL;
015dc7e1 14688 return true;
f84ce13b
NC
14689 }
14690
cf13d699
NC
14691 switch (reloc_type)
14692 {
14693 case 34: /* R_MN10300_ALIGN */
015dc7e1 14694 return true;
cf13d699 14695 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14696 if (sym_index >= num_syms)
74a965d8
AM
14697 error (_("%s reloc contains invalid symbol index "
14698 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14699 else
14700 saved_sym = symtab + sym_index;
015dc7e1 14701 return true;
f84ce13b 14702
cf13d699
NC
14703 case 1: /* R_MN10300_32 */
14704 case 2: /* R_MN10300_16 */
14705 if (saved_sym != NULL)
14706 {
03f7786e 14707 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14708 uint64_t value;
252b5132 14709
f84ce13b 14710 if (sym_index >= num_syms)
74a965d8
AM
14711 error (_("%s reloc contains invalid symbol index "
14712 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14713 else
f84ce13b
NC
14714 {
14715 value = reloc->r_addend + (symtab[sym_index].st_value
14716 - saved_sym->st_value);
14717
b32e566b 14718 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14719 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14720 else
26c527e6
AM
14721 error (_("MN10300 sym diff reloc contains invalid offset:"
14722 " %#" PRIx64 "\n"),
14723 reloc->r_offset);
f84ce13b 14724 }
252b5132 14725
cf13d699 14726 saved_sym = NULL;
015dc7e1 14727 return true;
cf13d699
NC
14728 }
14729 break;
14730 default:
14731 if (saved_sym != NULL)
071436c6 14732 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14733 break;
14734 }
14735 break;
14736 }
6ff71e76
NC
14737
14738 case EM_RL78:
14739 {
625d49fc
AM
14740 static uint64_t saved_sym1 = 0;
14741 static uint64_t saved_sym2 = 0;
14742 static uint64_t value;
6ff71e76 14743
f84ce13b
NC
14744 if (reloc == NULL)
14745 {
14746 saved_sym1 = saved_sym2 = 0;
015dc7e1 14747 return true;
f84ce13b
NC
14748 }
14749
6ff71e76
NC
14750 switch (reloc_type)
14751 {
14752 case 0x80: /* R_RL78_SYM. */
14753 saved_sym1 = saved_sym2;
f84ce13b 14754 if (sym_index >= num_syms)
74a965d8
AM
14755 error (_("%s reloc contains invalid symbol index "
14756 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14757 else
14758 {
14759 saved_sym2 = symtab[sym_index].st_value;
14760 saved_sym2 += reloc->r_addend;
14761 }
015dc7e1 14762 return true;
6ff71e76
NC
14763
14764 case 0x83: /* R_RL78_OPsub. */
14765 value = saved_sym1 - saved_sym2;
14766 saved_sym2 = saved_sym1 = 0;
015dc7e1 14767 return true;
6ff71e76
NC
14768 break;
14769
14770 case 0x41: /* R_RL78_ABS32. */
b32e566b 14771 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14772 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14773 else
26c527e6
AM
14774 error (_("RL78 sym diff reloc contains invalid offset: "
14775 "%#" PRIx64 "\n"),
14776 reloc->r_offset);
6ff71e76 14777 value = 0;
015dc7e1 14778 return true;
6ff71e76
NC
14779
14780 case 0x43: /* R_RL78_ABS16. */
b32e566b 14781 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14782 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14783 else
26c527e6
AM
14784 error (_("RL78 sym diff reloc contains invalid offset: "
14785 "%#" PRIx64 "\n"),
14786 reloc->r_offset);
6ff71e76 14787 value = 0;
015dc7e1 14788 return true;
6ff71e76
NC
14789
14790 default:
14791 break;
14792 }
14793 break;
14794 }
252b5132
RH
14795 }
14796
015dc7e1 14797 return false;
252b5132
RH
14798}
14799
aca88567
NC
14800/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14801 DWARF debug sections. This is a target specific test. Note - we do not
14802 go through the whole including-target-headers-multiple-times route, (as
14803 we have already done with <elf/h8.h>) because this would become very
14804 messy and even then this function would have to contain target specific
14805 information (the names of the relocs instead of their numeric values).
14806 FIXME: This is not the correct way to solve this problem. The proper way
14807 is to have target specific reloc sizing and typing functions created by
14808 the reloc-macros.h header, in the same way that it already creates the
14809 reloc naming functions. */
14810
015dc7e1 14811static bool
dda8d76d 14812is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14813{
d347c9df 14814 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14815 switch (filedata->file_header.e_machine)
aca88567 14816 {
41e92641 14817 case EM_386:
22abe556 14818 case EM_IAMCU:
41e92641 14819 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14820 case EM_68K:
14821 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14822 case EM_860:
14823 return reloc_type == 1; /* R_860_32. */
14824 case EM_960:
14825 return reloc_type == 2; /* R_960_32. */
a06ea964 14826 case EM_AARCH64:
9282b95a
JW
14827 return (reloc_type == 258
14828 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14829 case EM_BPF:
14830 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14831 case EM_ADAPTEVA_EPIPHANY:
14832 return reloc_type == 3;
aca88567 14833 case EM_ALPHA:
137b6b5f 14834 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14835 case EM_ARC:
14836 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14837 case EM_ARC_COMPACT:
14838 case EM_ARC_COMPACT2:
b5c37946
SJ
14839 case EM_ARC_COMPACT3:
14840 case EM_ARC_COMPACT3_64:
886a2506 14841 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14842 case EM_ARM:
14843 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14844 case EM_AVR_OLD:
aca88567
NC
14845 case EM_AVR:
14846 return reloc_type == 1;
14847 case EM_BLACKFIN:
14848 return reloc_type == 0x12; /* R_byte4_data. */
14849 case EM_CRIS:
14850 return reloc_type == 3; /* R_CRIS_32. */
14851 case EM_CR16:
14852 return reloc_type == 3; /* R_CR16_NUM32. */
14853 case EM_CRX:
14854 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14855 case EM_CSKY:
14856 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14857 case EM_CYGNUS_FRV:
14858 return reloc_type == 1;
41e92641
NC
14859 case EM_CYGNUS_D10V:
14860 case EM_D10V:
14861 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14862 case EM_CYGNUS_D30V:
14863 case EM_D30V:
14864 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14865 case EM_DLX:
14866 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14867 case EM_CYGNUS_FR30:
14868 case EM_FR30:
14869 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14870 case EM_FT32:
14871 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14872 case EM_H8S:
14873 case EM_H8_300:
14874 case EM_H8_300H:
14875 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14876 case EM_IA_64:
262cdac7
AM
14877 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14878 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14879 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14880 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14881 case EM_IP2K_OLD:
14882 case EM_IP2K:
14883 return reloc_type == 2; /* R_IP2K_32. */
14884 case EM_IQ2000:
14885 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
14886 case EM_KVX:
14887 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
14888 case EM_LATTICEMICO32:
14889 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14890 case EM_LOONGARCH:
14891 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14892 case EM_M32C_OLD:
aca88567
NC
14893 case EM_M32C:
14894 return reloc_type == 3; /* R_M32C_32. */
14895 case EM_M32R:
14896 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14897 case EM_68HC11:
14898 case EM_68HC12:
14899 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14900 case EM_S12Z:
2849d19f
JD
14901 return reloc_type == 7 || /* R_S12Z_EXT32 */
14902 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14903 case EM_MCORE:
14904 return reloc_type == 1; /* R_MCORE_ADDR32. */
14905 case EM_CYGNUS_MEP:
14906 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14907 case EM_METAG:
14908 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14909 case EM_MICROBLAZE:
14910 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14911 case EM_MIPS:
14912 return reloc_type == 2; /* R_MIPS_32. */
14913 case EM_MMIX:
14914 return reloc_type == 4; /* R_MMIX_32. */
14915 case EM_CYGNUS_MN10200:
14916 case EM_MN10200:
14917 return reloc_type == 1; /* R_MN10200_32. */
14918 case EM_CYGNUS_MN10300:
14919 case EM_MN10300:
14920 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14921 case EM_MOXIE:
14922 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14923 case EM_MSP430_OLD:
14924 case EM_MSP430:
13761a11 14925 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14926 case EM_MT:
14927 return reloc_type == 2; /* R_MT_32. */
35c08157 14928 case EM_NDS32:
81c5e376 14929 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14930 case EM_ALTERA_NIOS2:
36591ba1 14931 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14932 case EM_NIOS32:
14933 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14934 case EM_OR1K:
14935 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14936 case EM_PARISC:
9abca702 14937 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14938 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14939 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14940 case EM_PJ:
14941 case EM_PJ_OLD:
14942 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14943 case EM_PPC64:
14944 return reloc_type == 1; /* R_PPC64_ADDR32. */
14945 case EM_PPC:
14946 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14947 case EM_TI_PRU:
14948 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14949 case EM_RISCV:
14950 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14951 case EM_RL78:
14952 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14953 case EM_RX:
14954 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14955 case EM_S370:
14956 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14957 case EM_S390_OLD:
14958 case EM_S390:
14959 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14960 case EM_SCORE:
14961 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14962 case EM_SH:
14963 return reloc_type == 1; /* R_SH_DIR32. */
14964 case EM_SPARC32PLUS:
14965 case EM_SPARCV9:
14966 case EM_SPARC:
14967 return reloc_type == 3 /* R_SPARC_32. */
14968 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14969 case EM_SPU:
14970 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14971 case EM_TI_C6000:
14972 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14973 case EM_TILEGX:
14974 return reloc_type == 2; /* R_TILEGX_32. */
14975 case EM_TILEPRO:
14976 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14977 case EM_CYGNUS_V850:
14978 case EM_V850:
14979 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14980 case EM_V800:
14981 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14982 case EM_VAX:
14983 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14984 case EM_VISIUM:
14985 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14986 case EM_WEBASSEMBLY:
14987 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14988 case EM_X86_64:
8a9036a4 14989 case EM_L1OM:
7a9068fe 14990 case EM_K1OM:
aca88567 14991 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14992 case EM_XGATE:
14993 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14994 case EM_XSTORMY16:
14995 return reloc_type == 1; /* R_XSTROMY16_32. */
14996 case EM_XTENSA_OLD:
14997 case EM_XTENSA:
14998 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14999 case EM_Z80:
15000 return reloc_type == 6; /* R_Z80_32. */
aca88567 15001 default:
bee0ee85
NC
15002 {
15003 static unsigned int prev_warn = 0;
15004
15005 /* Avoid repeating the same warning multiple times. */
dda8d76d 15006 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15007 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15008 filedata->file_header.e_machine);
15009 prev_warn = filedata->file_header.e_machine;
015dc7e1 15010 return false;
bee0ee85 15011 }
aca88567
NC
15012 }
15013}
15014
15015/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15016 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15017
015dc7e1 15018static bool
dda8d76d 15019is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15020{
dda8d76d 15021 switch (filedata->file_header.e_machine)
d347c9df 15022 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15023 {
41e92641 15024 case EM_386:
22abe556 15025 case EM_IAMCU:
3e0873ac 15026 return reloc_type == 2; /* R_386_PC32. */
aca88567 15027 case EM_68K:
3e0873ac 15028 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15029 case EM_AARCH64:
15030 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15031 case EM_ADAPTEVA_EPIPHANY:
15032 return reloc_type == 6;
aca88567
NC
15033 case EM_ALPHA:
15034 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15035 case EM_ARC_COMPACT:
15036 case EM_ARC_COMPACT2:
b5c37946
SJ
15037 case EM_ARC_COMPACT3:
15038 case EM_ARC_COMPACT3_64:
726c18e1 15039 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15040 case EM_ARM:
3e0873ac 15041 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15042 case EM_AVR_OLD:
15043 case EM_AVR:
15044 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15045 case EM_LOONGARCH:
15046 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15047 case EM_MICROBLAZE:
15048 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15049 case EM_OR1K:
15050 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15051 case EM_PARISC:
85acf597 15052 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15053 case EM_PPC:
15054 return reloc_type == 26; /* R_PPC_REL32. */
15055 case EM_PPC64:
3e0873ac 15056 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15057 case EM_RISCV:
15058 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15059 case EM_S390_OLD:
15060 case EM_S390:
3e0873ac 15061 return reloc_type == 5; /* R_390_PC32. */
aca88567 15062 case EM_SH:
3e0873ac 15063 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15064 case EM_SPARC32PLUS:
15065 case EM_SPARCV9:
15066 case EM_SPARC:
3e0873ac 15067 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15068 case EM_SPU:
15069 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15070 case EM_TILEGX:
15071 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15072 case EM_TILEPRO:
15073 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15074 case EM_VISIUM:
15075 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15076 case EM_X86_64:
8a9036a4 15077 case EM_L1OM:
7a9068fe 15078 case EM_K1OM:
3e0873ac 15079 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15080 case EM_VAX:
15081 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15082 case EM_XTENSA_OLD:
15083 case EM_XTENSA:
15084 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15085 case EM_KVX:
15086 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15087 default:
15088 /* Do not abort or issue an error message here. Not all targets use
15089 pc-relative 32-bit relocs in their DWARF debug information and we
15090 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15091 more helpful warning message will be generated by apply_relocations
15092 anyway, so just return. */
015dc7e1 15093 return false;
aca88567
NC
15094 }
15095}
15096
15097/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15098 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15099
015dc7e1 15100static bool
dda8d76d 15101is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15102{
dda8d76d 15103 switch (filedata->file_header.e_machine)
aca88567 15104 {
a06ea964
NC
15105 case EM_AARCH64:
15106 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15107 case EM_ARC_COMPACT3_64:
15108 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15109 case EM_ALPHA:
15110 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15111 case EM_IA_64:
262cdac7
AM
15112 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15113 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15114 case EM_LOONGARCH:
15115 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15116 case EM_PARISC:
15117 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15118 case EM_PPC64:
15119 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15120 case EM_RISCV:
15121 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15122 case EM_SPARC32PLUS:
15123 case EM_SPARCV9:
15124 case EM_SPARC:
714da62f
NC
15125 return reloc_type == 32 /* R_SPARC_64. */
15126 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15127 case EM_X86_64:
8a9036a4 15128 case EM_L1OM:
7a9068fe 15129 case EM_K1OM:
aca88567 15130 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15131 case EM_S390_OLD:
15132 case EM_S390:
aa137e4d
NC
15133 return reloc_type == 22; /* R_S390_64. */
15134 case EM_TILEGX:
15135 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15136 case EM_MIPS:
aa137e4d 15137 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15138 case EM_KVX:
15139 return reloc_type == 3; /* R_KVX_64 */
aca88567 15140 default:
015dc7e1 15141 return false;
aca88567
NC
15142 }
15143}
15144
85acf597
RH
15145/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15146 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15147
015dc7e1 15148static bool
dda8d76d 15149is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15150{
dda8d76d 15151 switch (filedata->file_header.e_machine)
85acf597 15152 {
a06ea964
NC
15153 case EM_AARCH64:
15154 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15155 case EM_ALPHA:
aa137e4d 15156 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15157 case EM_IA_64:
262cdac7
AM
15158 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15159 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15160 case EM_PARISC:
aa137e4d 15161 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15162 case EM_PPC64:
aa137e4d 15163 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15164 case EM_SPARC32PLUS:
15165 case EM_SPARCV9:
15166 case EM_SPARC:
aa137e4d 15167 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15168 case EM_X86_64:
8a9036a4 15169 case EM_L1OM:
7a9068fe 15170 case EM_K1OM:
aa137e4d 15171 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15172 case EM_S390_OLD:
15173 case EM_S390:
aa137e4d
NC
15174 return reloc_type == 23; /* R_S390_PC64. */
15175 case EM_TILEGX:
15176 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15177 default:
015dc7e1 15178 return false;
85acf597
RH
15179 }
15180}
15181
4dc3c23d
AM
15182/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15183 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15184
015dc7e1 15185static bool
dda8d76d 15186is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15187{
dda8d76d 15188 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15189 {
15190 case EM_CYGNUS_MN10200:
15191 case EM_MN10200:
15192 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15193 case EM_FT32:
15194 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15195 case EM_Z80:
15196 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15197 default:
015dc7e1 15198 return false;
4dc3c23d
AM
15199 }
15200}
15201
aca88567
NC
15202/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15203 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15204
015dc7e1 15205static bool
dda8d76d 15206is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15207{
d347c9df 15208 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15209 switch (filedata->file_header.e_machine)
4b78141a 15210 {
886a2506
NC
15211 case EM_ARC:
15212 case EM_ARC_COMPACT:
15213 case EM_ARC_COMPACT2:
b5c37946
SJ
15214 case EM_ARC_COMPACT3:
15215 case EM_ARC_COMPACT3_64:
886a2506 15216 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15217 case EM_ADAPTEVA_EPIPHANY:
15218 return reloc_type == 5;
aca88567
NC
15219 case EM_AVR_OLD:
15220 case EM_AVR:
15221 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15222 case EM_CYGNUS_D10V:
15223 case EM_D10V:
15224 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15225 case EM_FT32:
15226 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15227 case EM_H8S:
15228 case EM_H8_300:
15229 case EM_H8_300H:
aca88567
NC
15230 return reloc_type == R_H8_DIR16;
15231 case EM_IP2K_OLD:
15232 case EM_IP2K:
15233 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15234 case EM_M32C_OLD:
f4236fe4
DD
15235 case EM_M32C:
15236 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15237 case EM_CYGNUS_MN10200:
15238 case EM_MN10200:
15239 return reloc_type == 2; /* R_MN10200_16. */
15240 case EM_CYGNUS_MN10300:
15241 case EM_MN10300:
15242 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15243 case EM_KVX:
15244 return reloc_type == 1; /* R_KVX_16 */
aca88567 15245 case EM_MSP430:
dda8d76d 15246 if (uses_msp430x_relocs (filedata))
13761a11 15247 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15248 /* Fall through. */
78c8d46c 15249 case EM_MSP430_OLD:
aca88567 15250 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15251 case EM_NDS32:
81c5e376 15252 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15253 case EM_ALTERA_NIOS2:
36591ba1 15254 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15255 case EM_NIOS32:
15256 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15257 case EM_OR1K:
15258 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15259 case EM_RISCV:
15260 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15261 case EM_TI_PRU:
15262 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15263 case EM_TI_C6000:
15264 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15265 case EM_VISIUM:
15266 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15267 case EM_XGATE:
15268 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15269 case EM_Z80:
15270 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15271 default:
015dc7e1 15272 return false;
4b78141a
NC
15273 }
15274}
15275
39e07931
AS
15276/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15277 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15278
015dc7e1 15279static bool
39e07931
AS
15280is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15281{
15282 switch (filedata->file_header.e_machine)
15283 {
15284 case EM_RISCV:
15285 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15286 case EM_Z80:
15287 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15288 case EM_MICROBLAZE:
15289 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15290 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15291 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15292 default:
015dc7e1 15293 return false;
39e07931
AS
15294 }
15295}
15296
15297/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15298 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15299
015dc7e1 15300static bool
39e07931
AS
15301is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15302{
15303 switch (filedata->file_header.e_machine)
15304 {
15305 case EM_RISCV:
15306 return reloc_type == 53; /* R_RISCV_SET6. */
15307 default:
015dc7e1 15308 return false;
39e07931
AS
15309 }
15310}
15311
03336641
JW
15312/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15313 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15314
015dc7e1 15315static bool
03336641
JW
15316is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15317{
15318 /* Please keep this table alpha-sorted for ease of visual lookup. */
15319 switch (filedata->file_header.e_machine)
15320 {
76244462 15321 case EM_LOONGARCH:
15322 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15323 case EM_RISCV:
15324 return reloc_type == 35; /* R_RISCV_ADD32. */
15325 default:
015dc7e1 15326 return false;
03336641
JW
15327 }
15328}
15329
15330/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15331 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15332
015dc7e1 15333static bool
03336641
JW
15334is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15335{
15336 /* Please keep this table alpha-sorted for ease of visual lookup. */
15337 switch (filedata->file_header.e_machine)
15338 {
76244462 15339 case EM_LOONGARCH:
15340 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15341 case EM_RISCV:
15342 return reloc_type == 39; /* R_RISCV_SUB32. */
15343 default:
015dc7e1 15344 return false;
03336641
JW
15345 }
15346}
15347
15348/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15349 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15350
015dc7e1 15351static bool
03336641
JW
15352is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15353{
15354 /* Please keep this table alpha-sorted for ease of visual lookup. */
15355 switch (filedata->file_header.e_machine)
15356 {
76244462 15357 case EM_LOONGARCH:
15358 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15359 case EM_RISCV:
15360 return reloc_type == 36; /* R_RISCV_ADD64. */
15361 default:
015dc7e1 15362 return false;
03336641
JW
15363 }
15364}
15365
15366/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15367 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15368
015dc7e1 15369static bool
03336641
JW
15370is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15371{
15372 /* Please keep this table alpha-sorted for ease of visual lookup. */
15373 switch (filedata->file_header.e_machine)
15374 {
76244462 15375 case EM_LOONGARCH:
15376 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15377 case EM_RISCV:
15378 return reloc_type == 40; /* R_RISCV_SUB64. */
15379 default:
015dc7e1 15380 return false;
03336641
JW
15381 }
15382}
15383
15384/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15385 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15386
015dc7e1 15387static bool
03336641
JW
15388is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15389{
15390 /* Please keep this table alpha-sorted for ease of visual lookup. */
15391 switch (filedata->file_header.e_machine)
15392 {
76244462 15393 case EM_LOONGARCH:
15394 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15395 case EM_RISCV:
15396 return reloc_type == 34; /* R_RISCV_ADD16. */
15397 default:
015dc7e1 15398 return false;
03336641
JW
15399 }
15400}
15401
15402/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15403 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15404
015dc7e1 15405static bool
03336641
JW
15406is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15407{
15408 /* Please keep this table alpha-sorted for ease of visual lookup. */
15409 switch (filedata->file_header.e_machine)
15410 {
76244462 15411 case EM_LOONGARCH:
15412 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15413 case EM_RISCV:
15414 return reloc_type == 38; /* R_RISCV_SUB16. */
15415 default:
015dc7e1 15416 return false;
03336641
JW
15417 }
15418}
15419
15420/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15421 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15422
015dc7e1 15423static bool
03336641
JW
15424is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15425{
15426 /* Please keep this table alpha-sorted for ease of visual lookup. */
15427 switch (filedata->file_header.e_machine)
15428 {
76244462 15429 case EM_LOONGARCH:
15430 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15431 case EM_RISCV:
15432 return reloc_type == 33; /* R_RISCV_ADD8. */
15433 default:
015dc7e1 15434 return false;
03336641
JW
15435 }
15436}
15437
15438/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15439 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15440
015dc7e1 15441static bool
03336641
JW
15442is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15443{
15444 /* Please keep this table alpha-sorted for ease of visual lookup. */
15445 switch (filedata->file_header.e_machine)
15446 {
76244462 15447 case EM_LOONGARCH:
15448 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15449 case EM_RISCV:
15450 return reloc_type == 37; /* R_RISCV_SUB8. */
15451 default:
015dc7e1 15452 return false;
03336641
JW
15453 }
15454}
15455
76244462 15456/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15457 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15458
15459static bool
15460is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15461{
15462 switch (filedata->file_header.e_machine)
15463 {
15464 case EM_LOONGARCH:
15465 return reloc_type == 105; /* R_LARCH_ADD6. */
15466 default:
15467 return false;
15468 }
15469}
15470
39e07931
AS
15471/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15472 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15473
015dc7e1 15474static bool
39e07931
AS
15475is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15476{
15477 switch (filedata->file_header.e_machine)
15478 {
76244462 15479 case EM_LOONGARCH:
15480 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15481 case EM_RISCV:
15482 return reloc_type == 52; /* R_RISCV_SUB6. */
15483 default:
015dc7e1 15484 return false;
39e07931
AS
15485 }
15486}
15487
2a7b2e88
JK
15488/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15489 relocation entries (possibly formerly used for SHT_GROUP sections). */
15490
015dc7e1 15491static bool
dda8d76d 15492is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15493{
dda8d76d 15494 switch (filedata->file_header.e_machine)
2a7b2e88 15495 {
cb8f3167 15496 case EM_386: /* R_386_NONE. */
d347c9df 15497 case EM_68K: /* R_68K_NONE. */
cfb8c092 15498 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15499 case EM_ALPHA: /* R_ALPHA_NONE. */
15500 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15501 case EM_ARC: /* R_ARC_NONE. */
886a2506 15502 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15503 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15504 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15505 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15506 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15507 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15508 case EM_FT32: /* R_FT32_NONE. */
15509 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15510 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15511 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15512 case EM_L1OM: /* R_X86_64_NONE. */
15513 case EM_M32R: /* R_M32R_NONE. */
15514 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15515 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15516 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15517 case EM_NIOS32: /* R_NIOS_NONE. */
15518 case EM_OR1K: /* R_OR1K_NONE. */
15519 case EM_PARISC: /* R_PARISC_NONE. */
15520 case EM_PPC64: /* R_PPC64_NONE. */
15521 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15522 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15523 case EM_S390: /* R_390_NONE. */
15524 case EM_S390_OLD:
15525 case EM_SH: /* R_SH_NONE. */
15526 case EM_SPARC32PLUS:
15527 case EM_SPARC: /* R_SPARC_NONE. */
15528 case EM_SPARCV9:
aa137e4d
NC
15529 case EM_TILEGX: /* R_TILEGX_NONE. */
15530 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15531 case EM_TI_C6000:/* R_C6000_NONE. */
15532 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15533 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15534 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15535 return reloc_type == 0;
d347c9df 15536
a06ea964
NC
15537 case EM_AARCH64:
15538 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15539 case EM_AVR_OLD:
15540 case EM_AVR:
15541 return (reloc_type == 0 /* R_AVR_NONE. */
15542 || reloc_type == 30 /* R_AVR_DIFF8. */
15543 || reloc_type == 31 /* R_AVR_DIFF16. */
15544 || reloc_type == 32 /* R_AVR_DIFF32. */);
15545 case EM_METAG:
15546 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15547 case EM_NDS32:
81c5e376
AM
15548 return (reloc_type == 0 /* R_NDS32_NONE. */
15549 || reloc_type == 205 /* R_NDS32_DIFF8. */
15550 || reloc_type == 206 /* R_NDS32_DIFF16. */
15551 || reloc_type == 207 /* R_NDS32_DIFF32. */
15552 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15553 case EM_TI_PRU:
15554 return (reloc_type == 0 /* R_PRU_NONE. */
15555 || reloc_type == 65 /* R_PRU_DIFF8. */
15556 || reloc_type == 66 /* R_PRU_DIFF16. */
15557 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15558 case EM_XTENSA_OLD:
15559 case EM_XTENSA:
4dc3c23d
AM
15560 return (reloc_type == 0 /* R_XTENSA_NONE. */
15561 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15562 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15563 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15564 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15565 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15566 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15567 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15568 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15569 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15570 }
015dc7e1 15571 return false;
2a7b2e88
JK
15572}
15573
d1c4b12b
NC
15574/* Returns TRUE if there is a relocation against
15575 section NAME at OFFSET bytes. */
15576
015dc7e1 15577bool
31e5a3a3 15578reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15579{
15580 Elf_Internal_Rela * relocs;
15581 Elf_Internal_Rela * rp;
15582
15583 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15584 return false;
d1c4b12b
NC
15585
15586 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15587
15588 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15589 if (rp->r_offset == offset)
015dc7e1 15590 return true;
d1c4b12b 15591
015dc7e1 15592 return false;
d1c4b12b
NC
15593}
15594
cf13d699 15595/* Apply relocations to a section.
32ec8896
NC
15596 Returns TRUE upon success, FALSE otherwise.
15597 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15598 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15599 will be set to the number of relocs loaded.
15600
cf13d699 15601 Note: So far support has been added only for those relocations
32ec8896
NC
15602 which can be found in debug sections. FIXME: Add support for
15603 more relocations ? */
1b315056 15604
015dc7e1 15605static bool
be7d229a
AM
15606apply_relocations (Filedata *filedata,
15607 const Elf_Internal_Shdr *section,
15608 unsigned char *start,
15609 size_t size,
15610 void **relocs_return,
26c527e6 15611 uint64_t *num_relocs_return)
1b315056 15612{
cf13d699 15613 Elf_Internal_Shdr * relsec;
0d2a7a93 15614 unsigned char * end = start + size;
cb8f3167 15615
d1c4b12b
NC
15616 if (relocs_return != NULL)
15617 {
15618 * (Elf_Internal_Rela **) relocs_return = NULL;
15619 * num_relocs_return = 0;
15620 }
15621
dda8d76d 15622 if (filedata->file_header.e_type != ET_REL)
32ec8896 15623 /* No relocs to apply. */
015dc7e1 15624 return true;
1b315056 15625
cf13d699 15626 /* Find the reloc section associated with the section. */
dda8d76d
NC
15627 for (relsec = filedata->section_headers;
15628 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15629 ++relsec)
252b5132 15630 {
015dc7e1 15631 bool is_rela;
26c527e6 15632 uint64_t num_relocs;
2cf0635d
NC
15633 Elf_Internal_Rela * relocs;
15634 Elf_Internal_Rela * rp;
15635 Elf_Internal_Shdr * symsec;
15636 Elf_Internal_Sym * symtab;
26c527e6 15637 uint64_t num_syms;
2cf0635d 15638 Elf_Internal_Sym * sym;
252b5132 15639
41e92641 15640 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15641 || relsec->sh_info >= filedata->file_header.e_shnum
15642 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15643 || relsec->sh_size == 0
dda8d76d 15644 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15645 continue;
428409d5 15646
a788aedd
AM
15647 symsec = filedata->section_headers + relsec->sh_link;
15648 if (symsec->sh_type != SHT_SYMTAB
15649 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15650 return false;
a788aedd 15651
41e92641
NC
15652 is_rela = relsec->sh_type == SHT_RELA;
15653
15654 if (is_rela)
15655 {
dda8d76d 15656 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15657 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15658 return false;
41e92641
NC
15659 }
15660 else
15661 {
dda8d76d 15662 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15663 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15664 return false;
41e92641
NC
15665 }
15666
15667 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15668 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15669 is_rela = false;
428409d5 15670
4de91c10 15671 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15672
41e92641 15673 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15674 {
625d49fc 15675 uint64_t addend;
015dc7e1
AM
15676 unsigned int reloc_type;
15677 unsigned int reloc_size;
15678 bool reloc_inplace = false;
15679 bool reloc_subtract = false;
15680 unsigned char *rloc;
26c527e6 15681 uint64_t sym_index;
4b78141a 15682
dda8d76d 15683 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15684
dda8d76d 15685 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15686 continue;
dda8d76d 15687 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15688 continue;
dda8d76d
NC
15689 else if (is_32bit_abs_reloc (filedata, reloc_type)
15690 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15691 reloc_size = 4;
dda8d76d
NC
15692 else if (is_64bit_abs_reloc (filedata, reloc_type)
15693 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15694 reloc_size = 8;
dda8d76d 15695 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15696 reloc_size = 3;
dda8d76d 15697 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15698 reloc_size = 2;
39e07931
AS
15699 else if (is_8bit_abs_reloc (filedata, reloc_type)
15700 || is_6bit_abs_reloc (filedata, reloc_type))
15701 reloc_size = 1;
03336641
JW
15702 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15703 reloc_type))
15704 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15705 {
15706 reloc_size = 4;
015dc7e1 15707 reloc_inplace = true;
03336641
JW
15708 }
15709 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15710 reloc_type))
15711 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15712 {
15713 reloc_size = 8;
015dc7e1 15714 reloc_inplace = true;
03336641
JW
15715 }
15716 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15717 reloc_type))
15718 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15719 {
15720 reloc_size = 2;
015dc7e1 15721 reloc_inplace = true;
03336641
JW
15722 }
15723 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15724 reloc_type))
15725 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15726 {
15727 reloc_size = 1;
015dc7e1 15728 reloc_inplace = true;
03336641 15729 }
39e07931 15730 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15731 reloc_type))
15732 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15733 {
15734 reloc_size = 1;
015dc7e1 15735 reloc_inplace = true;
39e07931 15736 }
aca88567 15737 else
4b78141a 15738 {
bee0ee85 15739 static unsigned int prev_reloc = 0;
dda8d76d 15740
bee0ee85
NC
15741 if (reloc_type != prev_reloc)
15742 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15743 reloc_type, printable_section_name (filedata, section));
bee0ee85 15744 prev_reloc = reloc_type;
4b78141a
NC
15745 continue;
15746 }
103f02d3 15747
91d6fa6a 15748 rloc = start + rp->r_offset;
75802ccb 15749 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15750 {
26c527e6
AM
15751 warn (_("skipping invalid relocation offset %#" PRIx64
15752 " in section %s\n"),
15753 rp->r_offset,
dda8d76d 15754 printable_section_name (filedata, section));
700dd8b7
L
15755 continue;
15756 }
103f02d3 15757
26c527e6 15758 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15759 if (sym_index >= num_syms)
15760 {
26c527e6
AM
15761 warn (_("skipping invalid relocation symbol index %#" PRIx64
15762 " in section %s\n"),
dda8d76d 15763 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15764 continue;
15765 }
15766 sym = symtab + sym_index;
41e92641
NC
15767
15768 /* If the reloc has a symbol associated with it,
55f25fc3
L
15769 make sure that it is of an appropriate type.
15770
15771 Relocations against symbols without type can happen.
15772 Gcc -feliminate-dwarf2-dups may generate symbols
15773 without type for debug info.
15774
15775 Icc generates relocations against function symbols
15776 instead of local labels.
15777
15778 Relocations against object symbols can happen, eg when
15779 referencing a global array. For an example of this see
15780 the _clz.o binary in libgcc.a. */
aca88567 15781 if (sym != symtab
b8871f35 15782 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15783 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15784 {
26c527e6 15785 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15786 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15787 printable_section_name (filedata, relsec),
26c527e6 15788 rp - relocs);
aca88567 15789 continue;
5b18a4bc 15790 }
252b5132 15791
4dc3c23d
AM
15792 addend = 0;
15793 if (is_rela)
15794 addend += rp->r_addend;
c47320c3
AM
15795 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15796 partial_inplace. */
4dc3c23d 15797 if (!is_rela
dda8d76d 15798 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15799 && reloc_type == 1)
dda8d76d
NC
15800 || ((filedata->file_header.e_machine == EM_PJ
15801 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15802 && reloc_type == 1)
dda8d76d
NC
15803 || ((filedata->file_header.e_machine == EM_D30V
15804 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15805 && reloc_type == 12)
15806 || reloc_inplace)
39e07931
AS
15807 {
15808 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15809 addend += byte_get (rloc, reloc_size) & 0x3f;
15810 else
15811 addend += byte_get (rloc, reloc_size);
15812 }
cb8f3167 15813
dda8d76d
NC
15814 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15815 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15816 {
15817 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15818 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15819 addend -= 8;
91d6fa6a 15820 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15821 reloc_size);
15822 }
39e07931 15823 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15824 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15825 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15826 {
15827 if (reloc_subtract)
15828 addend -= sym->st_value;
15829 else
15830 addend += sym->st_value;
15831 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15832 byte_put (rloc, addend, reloc_size);
15833 }
03336641
JW
15834 else if (reloc_subtract)
15835 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15836 else
91d6fa6a 15837 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15838 }
252b5132 15839
5b18a4bc 15840 free (symtab);
f84ce13b
NC
15841 /* Let the target specific reloc processing code know that
15842 we have finished with these relocs. */
dda8d76d 15843 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15844
15845 if (relocs_return)
15846 {
15847 * (Elf_Internal_Rela **) relocs_return = relocs;
15848 * num_relocs_return = num_relocs;
15849 }
15850 else
15851 free (relocs);
15852
5b18a4bc
NC
15853 break;
15854 }
32ec8896 15855
015dc7e1 15856 return true;
5b18a4bc 15857}
103f02d3 15858
cf13d699 15859#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15860static bool
dda8d76d 15861disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15862{
dda8d76d 15863 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15864
74e1a04b 15865 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15866
015dc7e1 15867 return true;
cf13d699
NC
15868}
15869#endif
15870
15871/* Reads in the contents of SECTION from FILE, returning a pointer
15872 to a malloc'ed buffer or NULL if something went wrong. */
15873
15874static char *
dda8d76d 15875get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15876{
be7d229a 15877 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15878
15879 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15880 {
c6b78c96 15881 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15882 printable_section_name (filedata, section));
cf13d699
NC
15883 return NULL;
15884 }
15885
dda8d76d 15886 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15887 _("section contents"));
cf13d699
NC
15888}
15889
1f5a3546 15890/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15891
015dc7e1 15892static bool
45f5fe46
NC
15893uncompress_section_contents (bool is_zstd,
15894 unsigned char ** buffer,
15895 uint64_t uncompressed_size,
15896 uint64_t * size,
15897 uint64_t file_size)
0e602686 15898{
31e5a3a3
AM
15899 uint64_t compressed_size = *size;
15900 unsigned char *compressed_buffer = *buffer;
45f5fe46 15901 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15902 z_stream strm;
15903 int rc;
15904
45f5fe46
NC
15905 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15906 upper limit of ~10x compression. Any compression larger than that is
15907 thought to be due to fuzzing of the compression header. */
15908 if (uncompressed_size > file_size * 10)
15909 {
15910 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15911 uncompressed_size);
15912 goto fail;
15913 }
15914
15915 uncompressed_buffer = xmalloc (uncompressed_size);
15916
1f5a3546
FS
15917 if (is_zstd)
15918 {
15919#ifdef HAVE_ZSTD
15920 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15921 compressed_buffer, compressed_size);
15922 if (ZSTD_isError (ret))
15923 goto fail;
15924#endif
15925 }
15926 else
15927 {
15928 /* It is possible the section consists of several compressed
15929 buffers concatenated together, so we uncompress in a loop. */
15930 /* PR 18313: The state field in the z_stream structure is supposed
15931 to be invisible to the user (ie us), but some compilers will
15932 still complain about it being used without initialisation. So
15933 we first zero the entire z_stream structure and then set the fields
15934 that we need. */
15935 memset (&strm, 0, sizeof strm);
15936 strm.avail_in = compressed_size;
15937 strm.next_in = (Bytef *)compressed_buffer;
15938 strm.avail_out = uncompressed_size;
15939
15940 rc = inflateInit (&strm);
15941 while (strm.avail_in > 0)
15942 {
15943 if (rc != Z_OK)
15944 break;
15945 strm.next_out = ((Bytef *)uncompressed_buffer
15946 + (uncompressed_size - strm.avail_out));
15947 rc = inflate (&strm, Z_FINISH);
15948 if (rc != Z_STREAM_END)
15949 break;
15950 rc = inflateReset (&strm);
15951 }
15952 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15953 goto fail;
15954 }
0e602686
NC
15955
15956 *buffer = uncompressed_buffer;
15957 *size = uncompressed_size;
015dc7e1 15958 return true;
0e602686
NC
15959
15960 fail:
15961 free (uncompressed_buffer);
15962 /* Indicate decompression failure. */
15963 *buffer = NULL;
015dc7e1 15964 return false;
0e602686 15965}
dd24e3da 15966
fab62191
NC
15967static uint64_t
15968maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
15969 Filedata * filedata,
15970 unsigned char ** start_ptr,
15971 bool relocate)
cf13d699 15972{
fab62191
NC
15973 uint64_t section_size = section->sh_size;
15974 unsigned char * start = * start_ptr;
15975
0e602686
NC
15976 if (decompress_dumps)
15977 {
fab62191 15978 uint64_t new_size = section_size;
31e5a3a3 15979 uint64_t uncompressed_size = 0;
1f5a3546 15980 bool is_zstd = false;
0e602686
NC
15981
15982 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15983 {
15984 Elf_Internal_Chdr chdr;
15985 unsigned int compression_header_size
fab62191
NC
15986 = get_compression_header (& chdr, start, section_size);
15987
5844b465
NC
15988 if (compression_header_size == 0)
15989 /* An error message will have already been generated
15990 by get_compression_header. */
fab62191 15991 return (uint64_t) -1;
0e602686 15992
89dbeac7 15993 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15994 ;
15995#ifdef HAVE_ZSTD
89dbeac7 15996 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15997 is_zstd = true;
15998#endif
15999 else
0e602686 16000 {
813dabb9 16001 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16002 printable_section_name (filedata, section), chdr.ch_type);
fab62191 16003 return (uint64_t) -1;
813dabb9 16004 }
fab62191 16005
813dabb9
L
16006 uncompressed_size = chdr.ch_size;
16007 start += compression_header_size;
16008 new_size -= compression_header_size;
0e602686
NC
16009 }
16010 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16011 {
16012 /* Read the zlib header. In this case, it should be "ZLIB"
16013 followed by the uncompressed section size, 8 bytes in
16014 big-endian order. */
16015 uncompressed_size = start[4]; uncompressed_size <<= 8;
16016 uncompressed_size += start[5]; uncompressed_size <<= 8;
16017 uncompressed_size += start[6]; uncompressed_size <<= 8;
16018 uncompressed_size += start[7]; uncompressed_size <<= 8;
16019 uncompressed_size += start[8]; uncompressed_size <<= 8;
16020 uncompressed_size += start[9]; uncompressed_size <<= 8;
16021 uncompressed_size += start[10]; uncompressed_size <<= 8;
16022 uncompressed_size += start[11];
16023 start += 12;
16024 new_size -= 12;
16025 }
16026
1835f746
NC
16027 if (uncompressed_size)
16028 {
1f5a3546 16029 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16030 &new_size, filedata->file_size))
fab62191 16031 section_size = new_size;
1835f746
NC
16032 else
16033 {
16034 error (_("Unable to decompress section %s\n"),
dda8d76d 16035 printable_section_name (filedata, section));
fab62191 16036 return (uint64_t) -1;
1835f746
NC
16037 }
16038 }
bc303e5d 16039 else
fab62191
NC
16040 start = * start_ptr;
16041 }
16042 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16043 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16044 {
16045 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
0e602686 16046 }
fd8008d8 16047
fab62191 16048 if (relocate)
cf13d699 16049 {
fab62191
NC
16050 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16051 return (uint64_t) -1;
16052 }
16053 else
16054 {
16055 Elf_Internal_Shdr *relsec;
cf13d699 16056
fab62191
NC
16057 /* If the section being dumped has relocations against it the user might
16058 be expecting these relocations to have been applied. Check for this
16059 case and issue a warning message in order to avoid confusion.
16060 FIXME: Maybe we ought to have an option that dumps a section with
16061 relocs applied ? */
16062 for (relsec = filedata->section_headers;
16063 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16064 ++relsec)
16065 {
16066 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16067 || relsec->sh_info >= filedata->file_header.e_shnum
16068 || filedata->section_headers + relsec->sh_info != section
16069 || relsec->sh_size == 0
16070 || relsec->sh_link >= filedata->file_header.e_shnum)
16071 continue;
16072
16073 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16074 break;
16075 }
cf13d699
NC
16076 }
16077
fab62191
NC
16078 * start_ptr = start;
16079 return section_size;
16080}
16081
16082static bool
16083dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16084{
16085 uint64_t num_bytes;
16086 unsigned char *data;
16087 unsigned char *end;
16088 unsigned char *real_start;
16089 unsigned char *start;
16090 bool some_strings_shown;
16091
16092 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16093 if (start == NULL)
16094 /* PR 21820: Do not fail if the section was empty. */
16095 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16096
16097 num_bytes = section->sh_size;
16098
16099 if (filedata->is_separate)
16100 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16101 printable_section_name (filedata, section),
16102 filedata->file_name);
16103 else
16104 printf (_("\nString dump of section '%s':\n"),
16105 printable_section_name (filedata, section));
16106
16107 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16108 if (num_bytes == (uint64_t) -1)
16109 goto error_out;
16110
cf13d699
NC
16111 data = start;
16112 end = start + num_bytes;
015dc7e1 16113 some_strings_shown = false;
cf13d699 16114
ba3265d0
NC
16115#ifdef HAVE_MBSTATE_T
16116 mbstate_t state;
16117 /* Initialise the multibyte conversion state. */
16118 memset (& state, 0, sizeof (state));
16119#endif
16120
015dc7e1 16121 bool continuing = false;
ba3265d0 16122
cf13d699
NC
16123 while (data < end)
16124 {
16125 while (!ISPRINT (* data))
16126 if (++ data >= end)
16127 break;
16128
16129 if (data < end)
16130 {
071436c6
NC
16131 size_t maxlen = end - data;
16132
ba3265d0
NC
16133 if (continuing)
16134 {
16135 printf (" ");
015dc7e1 16136 continuing = false;
ba3265d0
NC
16137 }
16138 else
16139 {
26c527e6 16140 printf (" [%6tx] ", data - start);
ba3265d0
NC
16141 }
16142
4082ef84
NC
16143 if (maxlen > 0)
16144 {
f3da8a96 16145 char c = 0;
ba3265d0
NC
16146
16147 while (maxlen)
16148 {
16149 c = *data++;
16150
16151 if (c == 0)
16152 break;
16153
16154 /* PR 25543: Treat new-lines as string-ending characters. */
16155 if (c == '\n')
16156 {
16157 printf ("\\n\n");
16158 if (*data != 0)
015dc7e1 16159 continuing = true;
ba3265d0
NC
16160 break;
16161 }
16162
16163 /* Do not print control characters directly as they can affect terminal
16164 settings. Such characters usually appear in the names generated
16165 by the assembler for local labels. */
16166 if (ISCNTRL (c))
16167 {
16168 printf ("^%c", c + 0x40);
16169 }
16170 else if (ISPRINT (c))
16171 {
16172 putchar (c);
16173 }
16174 else
16175 {
16176 size_t n;
16177#ifdef HAVE_MBSTATE_T
16178 wchar_t w;
16179#endif
16180 /* Let printf do the hard work of displaying multibyte characters. */
16181 printf ("%.1s", data - 1);
16182#ifdef HAVE_MBSTATE_T
16183 /* Try to find out how many bytes made up the character that was
16184 just printed. Advance the symbol pointer past the bytes that
16185 were displayed. */
16186 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16187#else
16188 n = 1;
16189#endif
16190 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16191 data += (n - 1);
16192 }
16193 }
16194
16195 if (c != '\n')
16196 putchar ('\n');
4082ef84
NC
16197 }
16198 else
16199 {
16200 printf (_("<corrupt>\n"));
16201 data = end;
16202 }
015dc7e1 16203 some_strings_shown = true;
cf13d699
NC
16204 }
16205 }
16206
16207 if (! some_strings_shown)
16208 printf (_(" No strings found in this section."));
16209
0e602686 16210 free (real_start);
cf13d699
NC
16211
16212 putchar ('\n');
015dc7e1 16213 return true;
f761cb13
AM
16214
16215error_out:
16216 free (real_start);
015dc7e1 16217 return false;
cf13d699
NC
16218}
16219
015dc7e1
AM
16220static bool
16221dump_section_as_bytes (Elf_Internal_Shdr *section,
16222 Filedata *filedata,
16223 bool relocate)
cf13d699 16224{
be7d229a
AM
16225 size_t bytes;
16226 uint64_t section_size;
625d49fc 16227 uint64_t addr;
be7d229a
AM
16228 unsigned char *data;
16229 unsigned char *real_start;
16230 unsigned char *start;
0e602686 16231
dda8d76d 16232 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16233 if (start == NULL)
c6b78c96 16234 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16235 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16236
0e602686 16237 section_size = section->sh_size;
cf13d699 16238
835f2fae
NC
16239 if (filedata->is_separate)
16240 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16241 printable_section_name (filedata, section),
16242 filedata->file_name);
16243 else
16244 printf (_("\nHex dump of section '%s':\n"),
16245 printable_section_name (filedata, section));
cf13d699 16246
fab62191
NC
16247 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16248 if (section_size == (uint64_t) -1)
16249 goto error_out;
cf13d699
NC
16250
16251 addr = section->sh_addr;
0e602686 16252 bytes = section_size;
cf13d699
NC
16253 data = start;
16254
16255 while (bytes)
16256 {
16257 int j;
16258 int k;
16259 int lbytes;
16260
16261 lbytes = (bytes > 16 ? 16 : bytes);
16262
26c527e6 16263 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16264
16265 for (j = 0; j < 16; j++)
16266 {
16267 if (j < lbytes)
16268 printf ("%2.2x", data[j]);
16269 else
16270 printf (" ");
16271
16272 if ((j & 3) == 3)
16273 printf (" ");
16274 }
16275
16276 for (j = 0; j < lbytes; j++)
16277 {
16278 k = data[j];
16279 if (k >= ' ' && k < 0x7f)
16280 printf ("%c", k);
16281 else
16282 printf (".");
16283 }
16284
16285 putchar ('\n');
16286
16287 data += lbytes;
16288 addr += lbytes;
16289 bytes -= lbytes;
16290 }
16291
0e602686 16292 free (real_start);
cf13d699
NC
16293
16294 putchar ('\n');
015dc7e1 16295 return true;
f761cb13
AM
16296
16297 error_out:
16298 free (real_start);
015dc7e1 16299 return false;
cf13d699
NC
16300}
16301
094e34f2 16302#ifdef ENABLE_LIBCTF
7d9813f1
NA
16303static ctf_sect_t *
16304shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16305{
b6ac461a 16306 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16307 buf->cts_size = shdr->sh_size;
16308 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16309
16310 return buf;
16311}
16312
16313/* Formatting callback function passed to ctf_dump. Returns either the pointer
16314 it is passed, or a pointer to newly-allocated storage, in which case
16315 dump_ctf() will free it when it no longer needs it. */
16316
2f6ecaed
NA
16317static char *
16318dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16319 char *s, void *arg)
7d9813f1 16320{
3e50a591 16321 const char *blanks = arg;
7d9813f1
NA
16322 char *new_s;
16323
3e50a591 16324 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16325 return s;
16326 return new_s;
16327}
16328
926c9e76
NA
16329/* Dump CTF errors/warnings. */
16330static void
139633c3 16331dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16332{
16333 ctf_next_t *it = NULL;
16334 char *errtext;
16335 int is_warning;
16336 int err;
16337
16338 /* Dump accumulated errors and warnings. */
16339 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16340 {
5e9b84f7 16341 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16342 errtext);
16343 free (errtext);
16344 }
16345 if (err != ECTF_NEXT_END)
16346 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16347}
16348
2f6ecaed
NA
16349/* Dump one CTF archive member. */
16350
80b56fad
NA
16351static void
16352dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16353 size_t member)
2f6ecaed 16354{
2f6ecaed
NA
16355 const char *things[] = {"Header", "Labels", "Data objects",
16356 "Function objects", "Variables", "Types", "Strings",
16357 ""};
16358 const char **thing;
16359 size_t i;
16360
80b56fad
NA
16361 /* Don't print out the name of the default-named archive member if it appears
16362 first in the list. The name .ctf appears everywhere, even for things that
16363 aren't really archives, so printing it out is liable to be confusing; also,
16364 the common case by far is for only one archive member to exist, and hiding
16365 it in that case seems worthwhile. */
2f6ecaed 16366
80b56fad
NA
16367 if (strcmp (name, ".ctf") != 0 || member != 0)
16368 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16369
80b56fad
NA
16370 if (ctf_parent_name (ctf) != NULL)
16371 ctf_import (ctf, parent);
2f6ecaed
NA
16372
16373 for (i = 0, thing = things; *thing[0]; thing++, i++)
16374 {
16375 ctf_dump_state_t *s = NULL;
16376 char *item;
16377
16378 printf ("\n %s:\n", *thing);
16379 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16380 (void *) " ")) != NULL)
16381 {
16382 printf ("%s\n", item);
16383 free (item);
16384 }
16385
16386 if (ctf_errno (ctf))
16387 {
16388 error (_("Iteration failed: %s, %s\n"), *thing,
16389 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16390 break;
2f6ecaed
NA
16391 }
16392 }
8b37e7b6 16393
926c9e76 16394 dump_ctf_errs (ctf);
2f6ecaed
NA
16395}
16396
015dc7e1 16397static bool
7d9813f1
NA
16398dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16399{
7d9813f1
NA
16400 Elf_Internal_Shdr * symtab_sec = NULL;
16401 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16402 void * data = NULL;
16403 void * symdata = NULL;
16404 void * strdata = NULL;
80b56fad 16405 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16406 ctf_sect_t * symsectp = NULL;
16407 ctf_sect_t * strsectp = NULL;
2f6ecaed 16408 ctf_archive_t * ctfa = NULL;
139633c3 16409 ctf_dict_t * parent = NULL;
80b56fad 16410 ctf_dict_t * fp;
7d9813f1 16411
80b56fad
NA
16412 ctf_next_t *i = NULL;
16413 const char *name;
16414 size_t member = 0;
7d9813f1 16415 int err;
015dc7e1 16416 bool ret = false;
7d9813f1
NA
16417
16418 shdr_to_ctf_sect (&ctfsect, section, filedata);
16419 data = get_section_contents (section, filedata);
16420 ctfsect.cts_data = data;
16421
616febde 16422 if (!dump_ctf_symtab_name)
3d16b64e 16423 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16424
16425 if (!dump_ctf_strtab_name)
3d16b64e 16426 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16427
16428 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16429 {
16430 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16431 {
16432 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16433 goto fail;
16434 }
16435 if ((symdata = (void *) get_data (NULL, filedata,
16436 symtab_sec->sh_offset, 1,
16437 symtab_sec->sh_size,
16438 _("symbols"))) == NULL)
16439 goto fail;
16440 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16441 symsect.cts_data = symdata;
16442 }
835f2fae 16443
df16e041 16444 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16445 {
16446 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16447 {
16448 error (_("No string table section named %s\n"),
16449 dump_ctf_strtab_name);
16450 goto fail;
16451 }
16452 if ((strdata = (void *) get_data (NULL, filedata,
16453 strtab_sec->sh_offset, 1,
16454 strtab_sec->sh_size,
16455 _("strings"))) == NULL)
16456 goto fail;
16457 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16458 strsect.cts_data = strdata;
16459 }
835f2fae 16460
2f6ecaed
NA
16461 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16462 libctf papers over the difference, so we can pretend it is always an
80b56fad 16463 archive. */
7d9813f1 16464
2f6ecaed 16465 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16466 {
926c9e76 16467 dump_ctf_errs (NULL);
7d9813f1
NA
16468 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16469 goto fail;
16470 }
16471
96c61be5
NA
16472 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16473 != ELFDATA2MSB);
16474
80b56fad
NA
16475 /* Preload the parent dict, since it will need to be imported into every
16476 child in turn. */
16477 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16478 {
926c9e76 16479 dump_ctf_errs (NULL);
2f6ecaed
NA
16480 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16481 goto fail;
7d9813f1
NA
16482 }
16483
015dc7e1 16484 ret = true;
7d9813f1 16485
835f2fae
NC
16486 if (filedata->is_separate)
16487 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16488 printable_section_name (filedata, section),
16489 filedata->file_name);
16490 else
16491 printf (_("\nDump of CTF section '%s':\n"),
16492 printable_section_name (filedata, section));
7d9813f1 16493
80b56fad
NA
16494 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16495 dump_ctf_archive_member (fp, name, parent, member++);
16496 if (err != ECTF_NEXT_END)
16497 {
16498 dump_ctf_errs (NULL);
16499 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16500 ret = false;
16501 }
7d9813f1
NA
16502
16503 fail:
139633c3 16504 ctf_dict_close (parent);
2f6ecaed 16505 ctf_close (ctfa);
7d9813f1
NA
16506 free (data);
16507 free (symdata);
16508 free (strdata);
16509 return ret;
16510}
094e34f2 16511#endif
7d9813f1 16512
42b6953b
IB
16513static bool
16514dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16515{
16516 void * data = NULL;
16517 sframe_decoder_ctx *sfd_ctx = NULL;
16518 const char *print_name = printable_section_name (filedata, section);
16519
16520 bool ret = true;
16521 size_t sf_size;
16522 int err = 0;
16523
16524 if (strcmp (print_name, "") == 0)
16525 {
16526 error (_("Section name must be provided \n"));
16527 ret = false;
16528 return ret;
16529 }
16530
16531 data = get_section_contents (section, filedata);
16532 sf_size = section->sh_size;
16533 /* Decode the contents of the section. */
16534 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16535 if (!sfd_ctx)
16536 {
16537 ret = false;
16538 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16539 goto fail;
16540 }
16541
16542 printf (_("Contents of the SFrame section %s:"), print_name);
16543 /* Dump the contents as text. */
16544 dump_sframe (sfd_ctx, section->sh_addr);
16545
16546 fail:
16547 free (data);
16548 return ret;
16549}
16550
015dc7e1 16551static bool
dda8d76d
NC
16552load_specific_debug_section (enum dwarf_section_display_enum debug,
16553 const Elf_Internal_Shdr * sec,
16554 void * data)
1007acb3 16555{
2cf0635d 16556 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16557 char buf [64];
dda8d76d 16558 Filedata * filedata = (Filedata *) data;
9abca702 16559
19e6b90e 16560 if (section->start != NULL)
dda8d76d
NC
16561 {
16562 /* If it is already loaded, do nothing. */
16563 if (streq (section->filename, filedata->file_name))
015dc7e1 16564 return true;
dda8d76d
NC
16565 free (section->start);
16566 }
1007acb3 16567
19e6b90e
L
16568 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16569 section->address = sec->sh_addr;
dda8d76d
NC
16570 section->filename = filedata->file_name;
16571 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16572 sec->sh_offset, 1,
16573 sec->sh_size, buf);
59245841
NC
16574 if (section->start == NULL)
16575 section->size = 0;
16576 else
16577 {
77115a4a 16578 unsigned char *start = section->start;
31e5a3a3
AM
16579 uint64_t size = sec->sh_size;
16580 uint64_t uncompressed_size = 0;
1f5a3546 16581 bool is_zstd = false;
77115a4a
L
16582
16583 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16584 {
16585 Elf_Internal_Chdr chdr;
d8024a91
NC
16586 unsigned int compression_header_size;
16587
f53be977
L
16588 if (size < (is_32bit_elf
16589 ? sizeof (Elf32_External_Chdr)
16590 : sizeof (Elf64_External_Chdr)))
d8024a91 16591 {
55be8fd0 16592 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16593 section->name);
015dc7e1 16594 return false;
d8024a91
NC
16595 }
16596
ebdf1ebf 16597 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16598 if (compression_header_size == 0)
16599 /* An error message will have already been generated
16600 by get_compression_header. */
015dc7e1 16601 return false;
d8024a91 16602
89dbeac7 16603 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16604 ;
16605#ifdef HAVE_ZSTD
89dbeac7 16606 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16607 is_zstd = true;
16608#endif
16609 else
813dabb9
L
16610 {
16611 warn (_("section '%s' has unsupported compress type: %d\n"),
16612 section->name, chdr.ch_type);
015dc7e1 16613 return false;
813dabb9 16614 }
dab394de 16615 uncompressed_size = chdr.ch_size;
77115a4a
L
16616 start += compression_header_size;
16617 size -= compression_header_size;
16618 }
dab394de
L
16619 else if (size > 12 && streq ((char *) start, "ZLIB"))
16620 {
16621 /* Read the zlib header. In this case, it should be "ZLIB"
16622 followed by the uncompressed section size, 8 bytes in
16623 big-endian order. */
16624 uncompressed_size = start[4]; uncompressed_size <<= 8;
16625 uncompressed_size += start[5]; uncompressed_size <<= 8;
16626 uncompressed_size += start[6]; uncompressed_size <<= 8;
16627 uncompressed_size += start[7]; uncompressed_size <<= 8;
16628 uncompressed_size += start[8]; uncompressed_size <<= 8;
16629 uncompressed_size += start[9]; uncompressed_size <<= 8;
16630 uncompressed_size += start[10]; uncompressed_size <<= 8;
16631 uncompressed_size += start[11];
16632 start += 12;
16633 size -= 12;
16634 }
16635
1835f746 16636 if (uncompressed_size)
77115a4a 16637 {
1f5a3546 16638 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16639 &size, filedata->file_size))
1835f746
NC
16640 {
16641 /* Free the compressed buffer, update the section buffer
16642 and the section size if uncompress is successful. */
16643 free (section->start);
16644 section->start = start;
16645 }
16646 else
16647 {
16648 error (_("Unable to decompress section %s\n"),
dda8d76d 16649 printable_section_name (filedata, sec));
015dc7e1 16650 return false;
1835f746 16651 }
77115a4a 16652 }
bc303e5d 16653
77115a4a 16654 section->size = size;
59245841 16655 }
4a114e3e 16656
1b315056 16657 if (section->start == NULL)
015dc7e1 16658 return false;
1b315056 16659
19e6b90e 16660 if (debug_displays [debug].relocate)
32ec8896 16661 {
dda8d76d 16662 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16663 & section->reloc_info, & section->num_relocs))
015dc7e1 16664 return false;
32ec8896 16665 }
d1c4b12b
NC
16666 else
16667 {
16668 section->reloc_info = NULL;
16669 section->num_relocs = 0;
16670 }
1007acb3 16671
015dc7e1 16672 return true;
1007acb3
L
16673}
16674
301a9420
AM
16675#if HAVE_LIBDEBUGINFOD
16676/* Return a hex string representation of the build-id. */
16677unsigned char *
16678get_build_id (void * data)
16679{
ca0e11aa 16680 Filedata * filedata = (Filedata *) data;
301a9420 16681 Elf_Internal_Shdr * shdr;
26c527e6 16682 size_t i;
301a9420 16683
55be8fd0
NC
16684 /* Iterate through notes to find note.gnu.build-id.
16685 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16686 for (i = 0, shdr = filedata->section_headers;
16687 i < filedata->file_header.e_shnum && shdr != NULL;
16688 i++, shdr++)
16689 {
16690 if (shdr->sh_type != SHT_NOTE)
16691 continue;
16692
16693 char * next;
16694 char * end;
16695 size_t data_remaining;
16696 size_t min_notesz;
16697 Elf_External_Note * enote;
16698 Elf_Internal_Note inote;
16699
625d49fc
AM
16700 uint64_t offset = shdr->sh_offset;
16701 uint64_t align = shdr->sh_addralign;
16702 uint64_t length = shdr->sh_size;
301a9420
AM
16703
16704 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16705 if (enote == NULL)
16706 continue;
16707
16708 if (align < 4)
16709 align = 4;
16710 else if (align != 4 && align != 8)
f761cb13
AM
16711 {
16712 free (enote);
16713 continue;
16714 }
301a9420
AM
16715
16716 end = (char *) enote + length;
16717 data_remaining = end - (char *) enote;
16718
16719 if (!is_ia64_vms (filedata))
16720 {
16721 min_notesz = offsetof (Elf_External_Note, name);
16722 if (data_remaining < min_notesz)
16723 {
55be8fd0
NC
16724 warn (_("\
16725malformed note encountered in section %s whilst scanning for build-id note\n"),
16726 printable_section_name (filedata, shdr));
f761cb13 16727 free (enote);
55be8fd0 16728 continue;
301a9420
AM
16729 }
16730 data_remaining -= min_notesz;
16731
16732 inote.type = BYTE_GET (enote->type);
16733 inote.namesz = BYTE_GET (enote->namesz);
16734 inote.namedata = enote->name;
16735 inote.descsz = BYTE_GET (enote->descsz);
16736 inote.descdata = ((char *) enote
16737 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16738 inote.descpos = offset + (inote.descdata - (char *) enote);
16739 next = ((char *) enote
16740 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16741 }
16742 else
16743 {
16744 Elf64_External_VMS_Note *vms_enote;
16745
16746 /* PR binutils/15191
16747 Make sure that there is enough data to read. */
16748 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16749 if (data_remaining < min_notesz)
16750 {
55be8fd0
NC
16751 warn (_("\
16752malformed note encountered in section %s whilst scanning for build-id note\n"),
16753 printable_section_name (filedata, shdr));
f761cb13 16754 free (enote);
55be8fd0 16755 continue;
301a9420
AM
16756 }
16757 data_remaining -= min_notesz;
16758
16759 vms_enote = (Elf64_External_VMS_Note *) enote;
16760 inote.type = BYTE_GET (vms_enote->type);
16761 inote.namesz = BYTE_GET (vms_enote->namesz);
16762 inote.namedata = vms_enote->name;
16763 inote.descsz = BYTE_GET (vms_enote->descsz);
16764 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16765 inote.descpos = offset + (inote.descdata - (char *) enote);
16766 next = inote.descdata + align_power (inote.descsz, 3);
16767 }
16768
16769 /* Skip malformed notes. */
16770 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16771 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16772 || (size_t) (next - inote.descdata) < inote.descsz
16773 || ((size_t) (next - inote.descdata)
16774 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16775 {
55be8fd0
NC
16776 warn (_("\
16777malformed note encountered in section %s whilst scanning for build-id note\n"),
16778 printable_section_name (filedata, shdr));
f761cb13 16779 free (enote);
301a9420
AM
16780 continue;
16781 }
16782
16783 /* Check if this is the build-id note. If so then convert the build-id
16784 bytes to a hex string. */
16785 if (inote.namesz > 0
24d127aa 16786 && startswith (inote.namedata, "GNU")
301a9420
AM
16787 && inote.type == NT_GNU_BUILD_ID)
16788 {
26c527e6 16789 size_t j;
301a9420
AM
16790 char * build_id;
16791
16792 build_id = malloc (inote.descsz * 2 + 1);
16793 if (build_id == NULL)
f761cb13
AM
16794 {
16795 free (enote);
16796 return NULL;
16797 }
301a9420
AM
16798
16799 for (j = 0; j < inote.descsz; ++j)
16800 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16801 build_id[inote.descsz * 2] = '\0';
f761cb13 16802 free (enote);
301a9420 16803
55be8fd0 16804 return (unsigned char *) build_id;
301a9420 16805 }
f761cb13 16806 free (enote);
301a9420
AM
16807 }
16808
16809 return NULL;
16810}
16811#endif /* HAVE_LIBDEBUGINFOD */
16812
657d0d47
CC
16813/* If this is not NULL, load_debug_section will only look for sections
16814 within the list of sections given here. */
32ec8896 16815static unsigned int * section_subset = NULL;
657d0d47 16816
015dc7e1 16817bool
dda8d76d 16818load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16819{
2cf0635d
NC
16820 struct dwarf_section * section = &debug_displays [debug].section;
16821 Elf_Internal_Shdr * sec;
dda8d76d
NC
16822 Filedata * filedata = (Filedata *) data;
16823
e1dbfc17
L
16824 if (!dump_any_debugging)
16825 return false;
16826
f425ec66
NC
16827 /* Without section headers we cannot find any sections. */
16828 if (filedata->section_headers == NULL)
015dc7e1 16829 return false;
f425ec66 16830
9c1ce108
AM
16831 if (filedata->string_table == NULL
16832 && filedata->file_header.e_shstrndx != SHN_UNDEF
16833 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16834 {
16835 Elf_Internal_Shdr * strs;
16836
16837 /* Read in the string table, so that we have section names to scan. */
16838 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16839
4dff97b2 16840 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16841 {
9c1ce108
AM
16842 filedata->string_table
16843 = (char *) get_data (NULL, filedata, strs->sh_offset,
16844 1, strs->sh_size, _("string table"));
dda8d76d 16845
9c1ce108
AM
16846 filedata->string_table_length
16847 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16848 }
16849 }
d966045b
DJ
16850
16851 /* Locate the debug section. */
dda8d76d 16852 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16853 if (sec != NULL)
16854 section->name = section->uncompressed_name;
16855 else
16856 {
dda8d76d 16857 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16858 if (sec != NULL)
16859 section->name = section->compressed_name;
16860 }
16861 if (sec == NULL)
015dc7e1 16862 return false;
d966045b 16863
657d0d47
CC
16864 /* If we're loading from a subset of sections, and we've loaded
16865 a section matching this name before, it's likely that it's a
16866 different one. */
16867 if (section_subset != NULL)
16868 free_debug_section (debug);
16869
dda8d76d 16870 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16871}
16872
19e6b90e
L
16873void
16874free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16875{
2cf0635d 16876 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16877
19e6b90e
L
16878 if (section->start == NULL)
16879 return;
1007acb3 16880
19e6b90e
L
16881 free ((char *) section->start);
16882 section->start = NULL;
16883 section->address = 0;
16884 section->size = 0;
a788aedd 16885
9db70fc3
AM
16886 free (section->reloc_info);
16887 section->reloc_info = NULL;
16888 section->num_relocs = 0;
1007acb3
L
16889}
16890
015dc7e1 16891static bool
dda8d76d 16892display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16893{
84714f86
AM
16894 const char *name = (section_name_valid (filedata, section)
16895 ? section_name (filedata, section) : "");
16896 const char *print_name = printable_section_name (filedata, section);
be7d229a 16897 uint64_t length;
015dc7e1 16898 bool result = true;
3f5e193b 16899 int i;
1007acb3 16900
19e6b90e
L
16901 length = section->sh_size;
16902 if (length == 0)
1007acb3 16903 {
74e1a04b 16904 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16905 return true;
1007acb3 16906 }
5dff79d8
NC
16907 if (section->sh_type == SHT_NOBITS)
16908 {
16909 /* There is no point in dumping the contents of a debugging section
16910 which has the NOBITS type - the bits in the file will be random.
16911 This can happen when a file containing a .eh_frame section is
16912 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16913 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16914 print_name);
015dc7e1 16915 return false;
5dff79d8 16916 }
1007acb3 16917
24d127aa 16918 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16919 name = ".debug_info";
1007acb3 16920
19e6b90e
L
16921 /* See if we know how to display the contents of this section. */
16922 for (i = 0; i < max; i++)
d85bf2ba
NC
16923 {
16924 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16925 struct dwarf_section_display * display = debug_displays + i;
16926 struct dwarf_section * sec = & display->section;
d966045b 16927
d85bf2ba 16928 if (streq (sec->uncompressed_name, name)
24d127aa 16929 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16930 || streq (sec->compressed_name, name))
16931 {
015dc7e1 16932 bool secondary = (section != find_section (filedata, name));
1007acb3 16933
d85bf2ba
NC
16934 if (secondary)
16935 free_debug_section (id);
dda8d76d 16936
24d127aa 16937 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16938 sec->name = name;
16939 else if (streq (sec->uncompressed_name, name))
16940 sec->name = sec->uncompressed_name;
16941 else
16942 sec->name = sec->compressed_name;
657d0d47 16943
d85bf2ba
NC
16944 if (load_specific_debug_section (id, section, filedata))
16945 {
16946 /* If this debug section is part of a CU/TU set in a .dwp file,
16947 restrict load_debug_section to the sections in that set. */
16948 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16949
d85bf2ba 16950 result &= display->display (sec, filedata);
657d0d47 16951
d85bf2ba 16952 section_subset = NULL;
1007acb3 16953
44266f36 16954 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16955 free_debug_section (id);
16956 }
16957 break;
16958 }
16959 }
1007acb3 16960
19e6b90e 16961 if (i == max)
1007acb3 16962 {
74e1a04b 16963 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16964 result = false;
1007acb3
L
16965 }
16966
19e6b90e 16967 return result;
5b18a4bc 16968}
103f02d3 16969
aef1f6d0
DJ
16970/* Set DUMP_SECTS for all sections where dumps were requested
16971 based on section name. */
16972
16973static void
dda8d76d 16974initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16975{
2cf0635d 16976 struct dump_list_entry * cur;
aef1f6d0
DJ
16977
16978 for (cur = dump_sects_byname; cur; cur = cur->next)
16979 {
16980 unsigned int i;
015dc7e1 16981 bool any = false;
aef1f6d0 16982
dda8d76d 16983 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16984 if (section_name_valid (filedata, filedata->section_headers + i)
16985 && streq (section_name (filedata, filedata->section_headers + i),
16986 cur->name))
aef1f6d0 16987 {
6431e409 16988 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16989 any = true;
aef1f6d0
DJ
16990 }
16991
835f2fae
NC
16992 if (!any && !filedata->is_separate)
16993 warn (_("Section '%s' was not dumped because it does not exist\n"),
16994 cur->name);
aef1f6d0
DJ
16995 }
16996}
16997
015dc7e1 16998static bool
dda8d76d 16999process_section_contents (Filedata * filedata)
5b18a4bc 17000{
2cf0635d 17001 Elf_Internal_Shdr * section;
19e6b90e 17002 unsigned int i;
015dc7e1 17003 bool res = true;
103f02d3 17004
19e6b90e 17005 if (! do_dump)
015dc7e1 17006 return true;
103f02d3 17007
dda8d76d 17008 initialise_dumps_byname (filedata);
aef1f6d0 17009
dda8d76d 17010 for (i = 0, section = filedata->section_headers;
6431e409 17011 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17012 i++, section++)
17013 {
6431e409 17014 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17015
d6bfbc39
NC
17016 if (filedata->is_separate && ! process_links)
17017 dump &= DEBUG_DUMP;
047c3dbf 17018
19e6b90e 17019#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17020 if (dump & DISASS_DUMP)
17021 {
17022 if (! disassemble_section (section, filedata))
015dc7e1 17023 res = false;
dda8d76d 17024 }
19e6b90e 17025#endif
dda8d76d 17026 if (dump & HEX_DUMP)
32ec8896 17027 {
015dc7e1
AM
17028 if (! dump_section_as_bytes (section, filedata, false))
17029 res = false;
32ec8896 17030 }
103f02d3 17031
dda8d76d 17032 if (dump & RELOC_DUMP)
32ec8896 17033 {
015dc7e1
AM
17034 if (! dump_section_as_bytes (section, filedata, true))
17035 res = false;
32ec8896 17036 }
09c11c86 17037
dda8d76d 17038 if (dump & STRING_DUMP)
32ec8896 17039 {
dda8d76d 17040 if (! dump_section_as_strings (section, filedata))
015dc7e1 17041 res = false;
32ec8896 17042 }
cf13d699 17043
dda8d76d 17044 if (dump & DEBUG_DUMP)
32ec8896 17045 {
dda8d76d 17046 if (! display_debug_section (i, section, filedata))
015dc7e1 17047 res = false;
32ec8896 17048 }
7d9813f1 17049
094e34f2 17050#ifdef ENABLE_LIBCTF
7d9813f1
NA
17051 if (dump & CTF_DUMP)
17052 {
17053 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17054 res = false;
7d9813f1 17055 }
094e34f2 17056#endif
42b6953b
IB
17057 if (dump & SFRAME_DUMP)
17058 {
17059 if (! dump_section_as_sframe (section, filedata))
17060 res = false;
17061 }
5b18a4bc 17062 }
103f02d3 17063
835f2fae 17064 if (! filedata->is_separate)
0ee3043f 17065 {
835f2fae
NC
17066 /* Check to see if the user requested a
17067 dump of a section that does not exist. */
17068 for (; i < filedata->dump.num_dump_sects; i++)
17069 if (filedata->dump.dump_sects[i])
17070 {
ca0e11aa 17071 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17072 res = false;
835f2fae 17073 }
0ee3043f 17074 }
32ec8896
NC
17075
17076 return res;
5b18a4bc 17077}
103f02d3 17078
5b18a4bc 17079static void
19e6b90e 17080process_mips_fpe_exception (int mask)
5b18a4bc 17081{
19e6b90e
L
17082 if (mask)
17083 {
015dc7e1 17084 bool first = true;
32ec8896 17085
19e6b90e 17086 if (mask & OEX_FPU_INEX)
015dc7e1 17087 fputs ("INEX", stdout), first = false;
19e6b90e 17088 if (mask & OEX_FPU_UFLO)
015dc7e1 17089 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17090 if (mask & OEX_FPU_OFLO)
015dc7e1 17091 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17092 if (mask & OEX_FPU_DIV0)
015dc7e1 17093 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17094 if (mask & OEX_FPU_INVAL)
17095 printf ("%sINVAL", first ? "" : "|");
17096 }
5b18a4bc 17097 else
19e6b90e 17098 fputs ("0", stdout);
5b18a4bc 17099}
103f02d3 17100
f6f0e17b
NC
17101/* Display's the value of TAG at location P. If TAG is
17102 greater than 0 it is assumed to be an unknown tag, and
17103 a message is printed to this effect. Otherwise it is
17104 assumed that a message has already been printed.
17105
17106 If the bottom bit of TAG is set it assumed to have a
17107 string value, otherwise it is assumed to have an integer
17108 value.
17109
17110 Returns an updated P pointing to the first unread byte
17111 beyond the end of TAG's value.
17112
17113 Reads at or beyond END will not be made. */
17114
17115static unsigned char *
60abdbed 17116display_tag_value (signed int tag,
f6f0e17b
NC
17117 unsigned char * p,
17118 const unsigned char * const end)
17119{
26c527e6 17120 uint64_t val;
f6f0e17b
NC
17121
17122 if (tag > 0)
17123 printf (" Tag_unknown_%d: ", tag);
17124
17125 if (p >= end)
17126 {
4082ef84 17127 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17128 }
17129 else if (tag & 1)
17130 {
071436c6
NC
17131 /* PR 17531 file: 027-19978-0.004. */
17132 size_t maxlen = (end - p) - 1;
17133
17134 putchar ('"');
4082ef84
NC
17135 if (maxlen > 0)
17136 {
b6ac461a 17137 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17138 p += strnlen ((char *) p, maxlen) + 1;
17139 }
17140 else
17141 {
17142 printf (_("<corrupt string tag>"));
17143 p = (unsigned char *) end;
17144 }
071436c6 17145 printf ("\"\n");
f6f0e17b
NC
17146 }
17147 else
17148 {
cd30bcef 17149 READ_ULEB (val, p, end);
26c527e6 17150 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17151 }
17152
4082ef84 17153 assert (p <= end);
f6f0e17b
NC
17154 return p;
17155}
17156
53a346d8
CZ
17157/* ARC ABI attributes section. */
17158
17159static unsigned char *
17160display_arc_attribute (unsigned char * p,
17161 const unsigned char * const end)
17162{
17163 unsigned int tag;
53a346d8
CZ
17164 unsigned int val;
17165
cd30bcef 17166 READ_ULEB (tag, p, end);
53a346d8
CZ
17167
17168 switch (tag)
17169 {
17170 case Tag_ARC_PCS_config:
cd30bcef 17171 READ_ULEB (val, p, end);
53a346d8
CZ
17172 printf (" Tag_ARC_PCS_config: ");
17173 switch (val)
17174 {
17175 case 0:
17176 printf (_("Absent/Non standard\n"));
17177 break;
17178 case 1:
17179 printf (_("Bare metal/mwdt\n"));
17180 break;
17181 case 2:
17182 printf (_("Bare metal/newlib\n"));
17183 break;
17184 case 3:
17185 printf (_("Linux/uclibc\n"));
17186 break;
17187 case 4:
17188 printf (_("Linux/glibc\n"));
17189 break;
17190 default:
17191 printf (_("Unknown\n"));
17192 break;
17193 }
17194 break;
17195
17196 case Tag_ARC_CPU_base:
cd30bcef 17197 READ_ULEB (val, p, end);
53a346d8
CZ
17198 printf (" Tag_ARC_CPU_base: ");
17199 switch (val)
17200 {
17201 default:
17202 case TAG_CPU_NONE:
17203 printf (_("Absent\n"));
17204 break;
17205 case TAG_CPU_ARC6xx:
17206 printf ("ARC6xx\n");
17207 break;
17208 case TAG_CPU_ARC7xx:
17209 printf ("ARC7xx\n");
17210 break;
17211 case TAG_CPU_ARCEM:
17212 printf ("ARCEM\n");
17213 break;
17214 case TAG_CPU_ARCHS:
17215 printf ("ARCHS\n");
17216 break;
17217 }
17218 break;
17219
17220 case Tag_ARC_CPU_variation:
cd30bcef 17221 READ_ULEB (val, p, end);
53a346d8
CZ
17222 printf (" Tag_ARC_CPU_variation: ");
17223 switch (val)
17224 {
17225 default:
17226 if (val > 0 && val < 16)
53a346d8 17227 printf ("Core%d\n", val);
d8cbc93b
JL
17228 else
17229 printf ("Unknown\n");
17230 break;
17231
53a346d8
CZ
17232 case 0:
17233 printf (_("Absent\n"));
17234 break;
17235 }
17236 break;
17237
17238 case Tag_ARC_CPU_name:
17239 printf (" Tag_ARC_CPU_name: ");
17240 p = display_tag_value (-1, p, end);
17241 break;
17242
17243 case Tag_ARC_ABI_rf16:
cd30bcef 17244 READ_ULEB (val, p, end);
53a346d8
CZ
17245 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17246 break;
17247
17248 case Tag_ARC_ABI_osver:
cd30bcef 17249 READ_ULEB (val, p, end);
53a346d8
CZ
17250 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17251 break;
17252
17253 case Tag_ARC_ABI_pic:
17254 case Tag_ARC_ABI_sda:
cd30bcef 17255 READ_ULEB (val, p, end);
53a346d8
CZ
17256 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17257 : " Tag_ARC_ABI_pic: ");
17258 switch (val)
17259 {
17260 case 0:
17261 printf (_("Absent\n"));
17262 break;
17263 case 1:
17264 printf ("MWDT\n");
17265 break;
17266 case 2:
17267 printf ("GNU\n");
17268 break;
17269 default:
17270 printf (_("Unknown\n"));
17271 break;
17272 }
17273 break;
17274
17275 case Tag_ARC_ABI_tls:
cd30bcef 17276 READ_ULEB (val, p, end);
53a346d8
CZ
17277 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17278 break;
17279
17280 case Tag_ARC_ABI_enumsize:
cd30bcef 17281 READ_ULEB (val, p, end);
53a346d8
CZ
17282 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17283 _("smallest"));
17284 break;
17285
17286 case Tag_ARC_ABI_exceptions:
cd30bcef 17287 READ_ULEB (val, p, end);
53a346d8
CZ
17288 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17289 : _("default"));
17290 break;
17291
17292 case Tag_ARC_ABI_double_size:
cd30bcef 17293 READ_ULEB (val, p, end);
53a346d8
CZ
17294 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17295 break;
17296
17297 case Tag_ARC_ISA_config:
17298 printf (" Tag_ARC_ISA_config: ");
17299 p = display_tag_value (-1, p, end);
17300 break;
17301
17302 case Tag_ARC_ISA_apex:
17303 printf (" Tag_ARC_ISA_apex: ");
17304 p = display_tag_value (-1, p, end);
17305 break;
17306
17307 case Tag_ARC_ISA_mpy_option:
cd30bcef 17308 READ_ULEB (val, p, end);
53a346d8
CZ
17309 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17310 break;
17311
db1e1b45 17312 case Tag_ARC_ATR_version:
cd30bcef 17313 READ_ULEB (val, p, end);
db1e1b45 17314 printf (" Tag_ARC_ATR_version: %d\n", val);
17315 break;
17316
53a346d8
CZ
17317 default:
17318 return display_tag_value (tag & 1, p, end);
17319 }
17320
17321 return p;
17322}
17323
11c1ff18
PB
17324/* ARM EABI attributes section. */
17325typedef struct
17326{
70e99720 17327 unsigned int tag;
2cf0635d 17328 const char * name;
11c1ff18 17329 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17330 unsigned int type;
288f0ba2 17331 const char *const *table;
11c1ff18
PB
17332} arm_attr_public_tag;
17333
288f0ba2 17334static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17335 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17336 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17337 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17338 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17339static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17340static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17341 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17342static const char *const arm_attr_tag_FP_arch[] =
bca38921 17343 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17344 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17345static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17346static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17347 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17348 "NEON for ARMv8.1"};
288f0ba2 17349static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17350 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17351 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17352static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17353 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17354static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17355 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17356static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17357 {"Absolute", "PC-relative", "None"};
288f0ba2 17358static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17359 {"None", "direct", "GOT-indirect"};
288f0ba2 17360static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17361 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17362static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17363static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17364 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17365static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17366static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17367static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17368 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17369static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17370 {"Unused", "small", "int", "forced to int"};
288f0ba2 17371static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17372 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17373static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17374 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17375static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17376 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17377static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17378 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17379 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17380static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17381 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17382 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17383static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17384static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17385 {"Not Allowed", "Allowed"};
288f0ba2 17386static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17387 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17388static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17389 {"Follow architecture", "Allowed"};
288f0ba2 17390static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17391 {"Not Allowed", "Allowed"};
288f0ba2 17392static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17393 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17394 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17395static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17396static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17397 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17398 "TrustZone and Virtualization Extensions"};
288f0ba2 17399static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17400 {"Not Allowed", "Allowed"};
11c1ff18 17401
288f0ba2 17402static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17403 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17404
99db83d0
AC
17405static const char * arm_attr_tag_PAC_extension[] =
17406 {"No PAC/AUT instructions",
17407 "PAC/AUT instructions permitted in the NOP space",
17408 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17409
4b535030
AC
17410static const char * arm_attr_tag_BTI_extension[] =
17411 {"BTI instructions not permitted",
17412 "BTI instructions permitted in the NOP space",
17413 "BTI instructions permitted in the NOP and in the non-NOP space"};
17414
b81ee92f
AC
17415static const char * arm_attr_tag_BTI_use[] =
17416 {"Compiled without branch target enforcement",
17417 "Compiled with branch target enforcement"};
17418
c9fed665
AC
17419static const char * arm_attr_tag_PACRET_use[] =
17420 {"Compiled without return address signing and authentication",
17421 "Compiled with return address signing and authentication"};
17422
11c1ff18
PB
17423#define LOOKUP(id, name) \
17424 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17425static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17426{
17427 {4, "CPU_raw_name", 1, NULL},
17428 {5, "CPU_name", 1, NULL},
17429 LOOKUP(6, CPU_arch),
17430 {7, "CPU_arch_profile", 0, NULL},
17431 LOOKUP(8, ARM_ISA_use),
17432 LOOKUP(9, THUMB_ISA_use),
75375b3e 17433 LOOKUP(10, FP_arch),
11c1ff18 17434 LOOKUP(11, WMMX_arch),
f5f53991
AS
17435 LOOKUP(12, Advanced_SIMD_arch),
17436 LOOKUP(13, PCS_config),
11c1ff18
PB
17437 LOOKUP(14, ABI_PCS_R9_use),
17438 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17439 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17440 LOOKUP(17, ABI_PCS_GOT_use),
17441 LOOKUP(18, ABI_PCS_wchar_t),
17442 LOOKUP(19, ABI_FP_rounding),
17443 LOOKUP(20, ABI_FP_denormal),
17444 LOOKUP(21, ABI_FP_exceptions),
17445 LOOKUP(22, ABI_FP_user_exceptions),
17446 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17447 {24, "ABI_align_needed", 0, NULL},
17448 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17449 LOOKUP(26, ABI_enum_size),
17450 LOOKUP(27, ABI_HardFP_use),
17451 LOOKUP(28, ABI_VFP_args),
17452 LOOKUP(29, ABI_WMMX_args),
17453 LOOKUP(30, ABI_optimization_goals),
17454 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17455 {32, "compatibility", 0, NULL},
f5f53991 17456 LOOKUP(34, CPU_unaligned_access),
75375b3e 17457 LOOKUP(36, FP_HP_extension),
8e79c3df 17458 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17459 LOOKUP(42, MPextension_use),
17460 LOOKUP(44, DIV_use),
15afaa63 17461 LOOKUP(46, DSP_extension),
a7ad558c 17462 LOOKUP(48, MVE_arch),
99db83d0 17463 LOOKUP(50, PAC_extension),
4b535030 17464 LOOKUP(52, BTI_extension),
b81ee92f 17465 LOOKUP(74, BTI_use),
c9fed665 17466 LOOKUP(76, PACRET_use),
f5f53991
AS
17467 {64, "nodefaults", 0, NULL},
17468 {65, "also_compatible_with", 0, NULL},
17469 LOOKUP(66, T2EE_use),
17470 {67, "conformance", 1, NULL},
17471 LOOKUP(68, Virtualization_use),
cd21e546 17472 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17473};
17474#undef LOOKUP
17475
11c1ff18 17476static unsigned char *
f6f0e17b
NC
17477display_arm_attribute (unsigned char * p,
17478 const unsigned char * const end)
11c1ff18 17479{
70e99720 17480 unsigned int tag;
70e99720 17481 unsigned int val;
2cf0635d 17482 arm_attr_public_tag * attr;
11c1ff18 17483 unsigned i;
70e99720 17484 unsigned int type;
11c1ff18 17485
cd30bcef 17486 READ_ULEB (tag, p, end);
11c1ff18 17487 attr = NULL;
2cf0635d 17488 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17489 {
17490 if (arm_attr_public_tags[i].tag == tag)
17491 {
17492 attr = &arm_attr_public_tags[i];
17493 break;
17494 }
17495 }
17496
17497 if (attr)
17498 {
17499 printf (" Tag_%s: ", attr->name);
17500 switch (attr->type)
17501 {
17502 case 0:
17503 switch (tag)
17504 {
17505 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17506 READ_ULEB (val, p, end);
11c1ff18
PB
17507 switch (val)
17508 {
2b692964
NC
17509 case 0: printf (_("None\n")); break;
17510 case 'A': printf (_("Application\n")); break;
17511 case 'R': printf (_("Realtime\n")); break;
17512 case 'M': printf (_("Microcontroller\n")); break;
17513 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17514 default: printf ("??? (%d)\n", val); break;
17515 }
17516 break;
17517
75375b3e 17518 case 24: /* Tag_align_needed. */
cd30bcef 17519 READ_ULEB (val, p, end);
75375b3e
MGD
17520 switch (val)
17521 {
2b692964
NC
17522 case 0: printf (_("None\n")); break;
17523 case 1: printf (_("8-byte\n")); break;
17524 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17525 case 3: printf ("??? 3\n"); break;
17526 default:
17527 if (val <= 12)
dd24e3da 17528 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17529 1 << val);
17530 else
17531 printf ("??? (%d)\n", val);
17532 break;
17533 }
17534 break;
17535
17536 case 25: /* Tag_align_preserved. */
cd30bcef 17537 READ_ULEB (val, p, end);
75375b3e
MGD
17538 switch (val)
17539 {
2b692964
NC
17540 case 0: printf (_("None\n")); break;
17541 case 1: printf (_("8-byte, except leaf SP\n")); break;
17542 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17543 case 3: printf ("??? 3\n"); break;
17544 default:
17545 if (val <= 12)
dd24e3da 17546 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17547 1 << val);
17548 else
17549 printf ("??? (%d)\n", val);
17550 break;
17551 }
17552 break;
17553
11c1ff18 17554 case 32: /* Tag_compatibility. */
071436c6 17555 {
cd30bcef 17556 READ_ULEB (val, p, end);
071436c6 17557 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17558 if (p < end - 1)
17559 {
17560 size_t maxlen = (end - p) - 1;
17561
b6ac461a 17562 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17563 p += strnlen ((char *) p, maxlen) + 1;
17564 }
17565 else
17566 {
17567 printf (_("<corrupt>"));
17568 p = (unsigned char *) end;
17569 }
071436c6 17570 putchar ('\n');
071436c6 17571 }
11c1ff18
PB
17572 break;
17573
f5f53991 17574 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17575 /* PR 17531: file: 001-505008-0.01. */
17576 if (p < end)
17577 p++;
2b692964 17578 printf (_("True\n"));
f5f53991
AS
17579 break;
17580
17581 case 65: /* Tag_also_compatible_with. */
cd30bcef 17582 READ_ULEB (val, p, end);
f5f53991
AS
17583 if (val == 6 /* Tag_CPU_arch. */)
17584 {
cd30bcef 17585 READ_ULEB (val, p, end);
071436c6 17586 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17587 printf ("??? (%d)\n", val);
17588 else
17589 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17590 }
17591 else
17592 printf ("???\n");
071436c6
NC
17593 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17594 ;
f5f53991
AS
17595 break;
17596
11c1ff18 17597 default:
bee0ee85
NC
17598 printf (_("<unknown: %d>\n"), tag);
17599 break;
11c1ff18
PB
17600 }
17601 return p;
17602
17603 case 1:
f6f0e17b 17604 return display_tag_value (-1, p, end);
11c1ff18 17605 case 2:
f6f0e17b 17606 return display_tag_value (0, p, end);
11c1ff18
PB
17607
17608 default:
17609 assert (attr->type & 0x80);
cd30bcef 17610 READ_ULEB (val, p, end);
11c1ff18
PB
17611 type = attr->type & 0x7f;
17612 if (val >= type)
17613 printf ("??? (%d)\n", val);
17614 else
17615 printf ("%s\n", attr->table[val]);
17616 return p;
17617 }
17618 }
11c1ff18 17619
f6f0e17b 17620 return display_tag_value (tag, p, end);
11c1ff18
PB
17621}
17622
104d59d1 17623static unsigned char *
60bca95a 17624display_gnu_attribute (unsigned char * p,
60abdbed 17625 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17626 const unsigned char * const end)
104d59d1 17627{
cd30bcef 17628 unsigned int tag;
60abdbed 17629 unsigned int val;
104d59d1 17630
cd30bcef 17631 READ_ULEB (tag, p, end);
104d59d1
JM
17632
17633 /* Tag_compatibility is the only generic GNU attribute defined at
17634 present. */
17635 if (tag == 32)
17636 {
cd30bcef 17637 READ_ULEB (val, p, end);
071436c6
NC
17638
17639 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17640 if (p == end)
17641 {
071436c6 17642 printf (_("<corrupt>\n"));
f6f0e17b
NC
17643 warn (_("corrupt vendor attribute\n"));
17644 }
17645 else
17646 {
4082ef84
NC
17647 if (p < end - 1)
17648 {
17649 size_t maxlen = (end - p) - 1;
071436c6 17650
b6ac461a 17651 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17652 p += strnlen ((char *) p, maxlen) + 1;
17653 }
17654 else
17655 {
17656 printf (_("<corrupt>"));
17657 p = (unsigned char *) end;
17658 }
071436c6 17659 putchar ('\n');
f6f0e17b 17660 }
104d59d1
JM
17661 return p;
17662 }
17663
17664 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17665 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17666
f6f0e17b 17667 return display_tag_value (tag, p, end);
104d59d1
JM
17668}
17669
85f7484a
PB
17670static unsigned char *
17671display_m68k_gnu_attribute (unsigned char * p,
17672 unsigned int tag,
17673 const unsigned char * const end)
17674{
17675 unsigned int val;
17676
17677 if (tag == Tag_GNU_M68K_ABI_FP)
17678 {
17679 printf (" Tag_GNU_M68K_ABI_FP: ");
17680 if (p == end)
17681 {
17682 printf (_("<corrupt>\n"));
17683 return p;
17684 }
17685 READ_ULEB (val, p, end);
17686
17687 if (val > 3)
17688 printf ("(%#x), ", val);
17689
17690 switch (val & 3)
17691 {
17692 case 0:
17693 printf (_("unspecified hard/soft float\n"));
17694 break;
17695 case 1:
17696 printf (_("hard float\n"));
17697 break;
17698 case 2:
17699 printf (_("soft float\n"));
17700 break;
17701 }
17702 return p;
17703 }
17704
17705 return display_tag_value (tag & 1, p, end);
17706}
17707
34c8bcba 17708static unsigned char *
f6f0e17b 17709display_power_gnu_attribute (unsigned char * p,
60abdbed 17710 unsigned int tag,
f6f0e17b 17711 const unsigned char * const end)
34c8bcba 17712{
005d79fd 17713 unsigned int val;
34c8bcba
JM
17714
17715 if (tag == Tag_GNU_Power_ABI_FP)
17716 {
34c8bcba 17717 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17718 if (p == end)
005d79fd
AM
17719 {
17720 printf (_("<corrupt>\n"));
17721 return p;
17722 }
cd30bcef 17723 READ_ULEB (val, p, end);
60bca95a 17724
005d79fd
AM
17725 if (val > 15)
17726 printf ("(%#x), ", val);
17727
17728 switch (val & 3)
34c8bcba
JM
17729 {
17730 case 0:
005d79fd 17731 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17732 break;
17733 case 1:
005d79fd 17734 printf (_("hard float, "));
34c8bcba
JM
17735 break;
17736 case 2:
005d79fd 17737 printf (_("soft float, "));
34c8bcba 17738 break;
3c7b9897 17739 case 3:
005d79fd 17740 printf (_("single-precision hard float, "));
3c7b9897 17741 break;
005d79fd
AM
17742 }
17743
17744 switch (val & 0xC)
17745 {
17746 case 0:
17747 printf (_("unspecified long double\n"));
17748 break;
17749 case 4:
17750 printf (_("128-bit IBM long double\n"));
17751 break;
17752 case 8:
17753 printf (_("64-bit long double\n"));
17754 break;
17755 case 12:
17756 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17757 break;
17758 }
17759 return p;
005d79fd 17760 }
34c8bcba 17761
c6e65352
DJ
17762 if (tag == Tag_GNU_Power_ABI_Vector)
17763 {
c6e65352 17764 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17765 if (p == end)
005d79fd
AM
17766 {
17767 printf (_("<corrupt>\n"));
17768 return p;
17769 }
cd30bcef 17770 READ_ULEB (val, p, end);
005d79fd
AM
17771
17772 if (val > 3)
17773 printf ("(%#x), ", val);
17774
17775 switch (val & 3)
c6e65352
DJ
17776 {
17777 case 0:
005d79fd 17778 printf (_("unspecified\n"));
c6e65352
DJ
17779 break;
17780 case 1:
005d79fd 17781 printf (_("generic\n"));
c6e65352
DJ
17782 break;
17783 case 2:
17784 printf ("AltiVec\n");
17785 break;
17786 case 3:
17787 printf ("SPE\n");
17788 break;
c6e65352
DJ
17789 }
17790 return p;
005d79fd 17791 }
c6e65352 17792
f82e0623
NF
17793 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17794 {
005d79fd 17795 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17796 if (p == end)
f6f0e17b 17797 {
005d79fd 17798 printf (_("<corrupt>\n"));
f6f0e17b
NC
17799 return p;
17800 }
cd30bcef 17801 READ_ULEB (val, p, end);
0b4362b0 17802
005d79fd
AM
17803 if (val > 2)
17804 printf ("(%#x), ", val);
17805
17806 switch (val & 3)
17807 {
17808 case 0:
17809 printf (_("unspecified\n"));
17810 break;
17811 case 1:
17812 printf ("r3/r4\n");
17813 break;
17814 case 2:
17815 printf (_("memory\n"));
17816 break;
17817 case 3:
17818 printf ("???\n");
17819 break;
17820 }
f82e0623
NF
17821 return p;
17822 }
17823
f6f0e17b 17824 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17825}
17826
643f7afb
AK
17827static unsigned char *
17828display_s390_gnu_attribute (unsigned char * p,
60abdbed 17829 unsigned int tag,
643f7afb
AK
17830 const unsigned char * const end)
17831{
cd30bcef 17832 unsigned int val;
643f7afb
AK
17833
17834 if (tag == Tag_GNU_S390_ABI_Vector)
17835 {
643f7afb 17836 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17837 READ_ULEB (val, p, end);
643f7afb
AK
17838
17839 switch (val)
17840 {
17841 case 0:
17842 printf (_("any\n"));
17843 break;
17844 case 1:
17845 printf (_("software\n"));
17846 break;
17847 case 2:
17848 printf (_("hardware\n"));
17849 break;
17850 default:
17851 printf ("??? (%d)\n", val);
17852 break;
17853 }
17854 return p;
17855 }
17856
17857 return display_tag_value (tag & 1, p, end);
17858}
17859
9e8c70f9 17860static void
60abdbed 17861display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17862{
17863 if (mask)
17864 {
015dc7e1 17865 bool first = true;
071436c6 17866
9e8c70f9 17867 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17868 fputs ("mul32", stdout), first = false;
9e8c70f9 17869 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17870 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17871 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17872 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17873 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17874 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17875 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17876 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17877 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17878 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17879 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17880 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17881 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17882 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17883 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17884 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17885 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17886 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17887 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17888 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17889 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17890 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17891 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17892 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17893 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17894 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17895 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17896 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17897 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17898 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17899 }
17900 else
071436c6
NC
17901 fputc ('0', stdout);
17902 fputc ('\n', stdout);
9e8c70f9
DM
17903}
17904
3d68f91c 17905static void
60abdbed 17906display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17907{
17908 if (mask)
17909 {
015dc7e1 17910 bool first = true;
071436c6 17911
3d68f91c 17912 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17913 fputs ("fjathplus", stdout), first = false;
3d68f91c 17914 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17915 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17916 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17917 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17918 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17919 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17920 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17921 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17922 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17923 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17924 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17925 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17926 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17927 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17928 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17929 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17930 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17931 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17932 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17933 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17934 }
17935 else
071436c6
NC
17936 fputc ('0', stdout);
17937 fputc ('\n', stdout);
3d68f91c
JM
17938}
17939
9e8c70f9 17940static unsigned char *
f6f0e17b 17941display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17942 unsigned int tag,
f6f0e17b 17943 const unsigned char * const end)
9e8c70f9 17944{
cd30bcef 17945 unsigned int val;
3d68f91c 17946
9e8c70f9
DM
17947 if (tag == Tag_GNU_Sparc_HWCAPS)
17948 {
cd30bcef 17949 READ_ULEB (val, p, end);
9e8c70f9 17950 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17951 display_sparc_hwcaps (val);
17952 return p;
3d68f91c
JM
17953 }
17954 if (tag == Tag_GNU_Sparc_HWCAPS2)
17955 {
cd30bcef 17956 READ_ULEB (val, p, end);
3d68f91c
JM
17957 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17958 display_sparc_hwcaps2 (val);
17959 return p;
17960 }
9e8c70f9 17961
f6f0e17b 17962 return display_tag_value (tag, p, end);
9e8c70f9
DM
17963}
17964
351cdf24 17965static void
32ec8896 17966print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17967{
17968 switch (val)
17969 {
17970 case Val_GNU_MIPS_ABI_FP_ANY:
17971 printf (_("Hard or soft float\n"));
17972 break;
17973 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17974 printf (_("Hard float (double precision)\n"));
17975 break;
17976 case Val_GNU_MIPS_ABI_FP_SINGLE:
17977 printf (_("Hard float (single precision)\n"));
17978 break;
17979 case Val_GNU_MIPS_ABI_FP_SOFT:
17980 printf (_("Soft float\n"));
17981 break;
17982 case Val_GNU_MIPS_ABI_FP_OLD_64:
17983 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17984 break;
17985 case Val_GNU_MIPS_ABI_FP_XX:
17986 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17987 break;
17988 case Val_GNU_MIPS_ABI_FP_64:
17989 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17990 break;
17991 case Val_GNU_MIPS_ABI_FP_64A:
17992 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17993 break;
3350cc01
CM
17994 case Val_GNU_MIPS_ABI_FP_NAN2008:
17995 printf (_("NaN 2008 compatibility\n"));
17996 break;
351cdf24
MF
17997 default:
17998 printf ("??? (%d)\n", val);
17999 break;
18000 }
18001}
18002
2cf19d5c 18003static unsigned char *
f6f0e17b 18004display_mips_gnu_attribute (unsigned char * p,
60abdbed 18005 unsigned int tag,
f6f0e17b 18006 const unsigned char * const end)
2cf19d5c 18007{
2cf19d5c
JM
18008 if (tag == Tag_GNU_MIPS_ABI_FP)
18009 {
32ec8896 18010 unsigned int val;
f6f0e17b 18011
2cf19d5c 18012 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18013 READ_ULEB (val, p, end);
351cdf24 18014 print_mips_fp_abi_value (val);
2cf19d5c
JM
18015 return p;
18016 }
18017
a9f58168
CF
18018 if (tag == Tag_GNU_MIPS_ABI_MSA)
18019 {
32ec8896 18020 unsigned int val;
a9f58168 18021
a9f58168 18022 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18023 READ_ULEB (val, p, end);
a9f58168
CF
18024
18025 switch (val)
18026 {
18027 case Val_GNU_MIPS_ABI_MSA_ANY:
18028 printf (_("Any MSA or not\n"));
18029 break;
18030 case Val_GNU_MIPS_ABI_MSA_128:
18031 printf (_("128-bit MSA\n"));
18032 break;
18033 default:
18034 printf ("??? (%d)\n", val);
18035 break;
18036 }
18037 return p;
18038 }
18039
f6f0e17b 18040 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18041}
18042
59e6276b 18043static unsigned char *
f6f0e17b
NC
18044display_tic6x_attribute (unsigned char * p,
18045 const unsigned char * const end)
59e6276b 18046{
60abdbed 18047 unsigned int tag;
cd30bcef 18048 unsigned int val;
59e6276b 18049
cd30bcef 18050 READ_ULEB (tag, p, end);
59e6276b
JM
18051
18052 switch (tag)
18053 {
75fa6dc1 18054 case Tag_ISA:
75fa6dc1 18055 printf (" Tag_ISA: ");
cd30bcef 18056 READ_ULEB (val, p, end);
59e6276b
JM
18057
18058 switch (val)
18059 {
75fa6dc1 18060 case C6XABI_Tag_ISA_none:
59e6276b
JM
18061 printf (_("None\n"));
18062 break;
75fa6dc1 18063 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18064 printf ("C62x\n");
18065 break;
75fa6dc1 18066 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18067 printf ("C67x\n");
18068 break;
75fa6dc1 18069 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18070 printf ("C67x+\n");
18071 break;
75fa6dc1 18072 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18073 printf ("C64x\n");
18074 break;
75fa6dc1 18075 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18076 printf ("C64x+\n");
18077 break;
75fa6dc1 18078 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18079 printf ("C674x\n");
18080 break;
18081 default:
18082 printf ("??? (%d)\n", val);
18083 break;
18084 }
18085 return p;
18086
87779176 18087 case Tag_ABI_wchar_t:
87779176 18088 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18089 READ_ULEB (val, p, end);
87779176
JM
18090 switch (val)
18091 {
18092 case 0:
18093 printf (_("Not used\n"));
18094 break;
18095 case 1:
18096 printf (_("2 bytes\n"));
18097 break;
18098 case 2:
18099 printf (_("4 bytes\n"));
18100 break;
18101 default:
18102 printf ("??? (%d)\n", val);
18103 break;
18104 }
18105 return p;
18106
18107 case Tag_ABI_stack_align_needed:
87779176 18108 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18109 READ_ULEB (val, p, end);
87779176
JM
18110 switch (val)
18111 {
18112 case 0:
18113 printf (_("8-byte\n"));
18114 break;
18115 case 1:
18116 printf (_("16-byte\n"));
18117 break;
18118 default:
18119 printf ("??? (%d)\n", val);
18120 break;
18121 }
18122 return p;
18123
18124 case Tag_ABI_stack_align_preserved:
cd30bcef 18125 READ_ULEB (val, p, end);
87779176
JM
18126 printf (" Tag_ABI_stack_align_preserved: ");
18127 switch (val)
18128 {
18129 case 0:
18130 printf (_("8-byte\n"));
18131 break;
18132 case 1:
18133 printf (_("16-byte\n"));
18134 break;
18135 default:
18136 printf ("??? (%d)\n", val);
18137 break;
18138 }
18139 return p;
18140
b5593623 18141 case Tag_ABI_DSBT:
cd30bcef 18142 READ_ULEB (val, p, end);
b5593623
JM
18143 printf (" Tag_ABI_DSBT: ");
18144 switch (val)
18145 {
18146 case 0:
18147 printf (_("DSBT addressing not used\n"));
18148 break;
18149 case 1:
18150 printf (_("DSBT addressing used\n"));
18151 break;
18152 default:
18153 printf ("??? (%d)\n", val);
18154 break;
18155 }
18156 return p;
18157
87779176 18158 case Tag_ABI_PID:
cd30bcef 18159 READ_ULEB (val, p, end);
87779176
JM
18160 printf (" Tag_ABI_PID: ");
18161 switch (val)
18162 {
18163 case 0:
18164 printf (_("Data addressing position-dependent\n"));
18165 break;
18166 case 1:
18167 printf (_("Data addressing position-independent, GOT near DP\n"));
18168 break;
18169 case 2:
18170 printf (_("Data addressing position-independent, GOT far from DP\n"));
18171 break;
18172 default:
18173 printf ("??? (%d)\n", val);
18174 break;
18175 }
18176 return p;
18177
18178 case Tag_ABI_PIC:
cd30bcef 18179 READ_ULEB (val, p, end);
87779176
JM
18180 printf (" Tag_ABI_PIC: ");
18181 switch (val)
18182 {
18183 case 0:
18184 printf (_("Code addressing position-dependent\n"));
18185 break;
18186 case 1:
18187 printf (_("Code addressing position-independent\n"));
18188 break;
18189 default:
18190 printf ("??? (%d)\n", val);
18191 break;
18192 }
18193 return p;
18194
18195 case Tag_ABI_array_object_alignment:
cd30bcef 18196 READ_ULEB (val, p, end);
87779176
JM
18197 printf (" Tag_ABI_array_object_alignment: ");
18198 switch (val)
18199 {
18200 case 0:
18201 printf (_("8-byte\n"));
18202 break;
18203 case 1:
18204 printf (_("4-byte\n"));
18205 break;
18206 case 2:
18207 printf (_("16-byte\n"));
18208 break;
18209 default:
18210 printf ("??? (%d)\n", val);
18211 break;
18212 }
18213 return p;
18214
18215 case Tag_ABI_array_object_align_expected:
cd30bcef 18216 READ_ULEB (val, p, end);
87779176
JM
18217 printf (" Tag_ABI_array_object_align_expected: ");
18218 switch (val)
18219 {
18220 case 0:
18221 printf (_("8-byte\n"));
18222 break;
18223 case 1:
18224 printf (_("4-byte\n"));
18225 break;
18226 case 2:
18227 printf (_("16-byte\n"));
18228 break;
18229 default:
18230 printf ("??? (%d)\n", val);
18231 break;
18232 }
18233 return p;
18234
3cbd1c06 18235 case Tag_ABI_compatibility:
071436c6 18236 {
cd30bcef 18237 READ_ULEB (val, p, end);
071436c6 18238 printf (" Tag_ABI_compatibility: ");
071436c6 18239 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18240 if (p < end - 1)
18241 {
18242 size_t maxlen = (end - p) - 1;
18243
b6ac461a 18244 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18245 p += strnlen ((char *) p, maxlen) + 1;
18246 }
18247 else
18248 {
18249 printf (_("<corrupt>"));
18250 p = (unsigned char *) end;
18251 }
071436c6 18252 putchar ('\n');
071436c6
NC
18253 return p;
18254 }
87779176
JM
18255
18256 case Tag_ABI_conformance:
071436c6 18257 {
4082ef84
NC
18258 printf (" Tag_ABI_conformance: \"");
18259 if (p < end - 1)
18260 {
18261 size_t maxlen = (end - p) - 1;
071436c6 18262
b6ac461a 18263 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18264 p += strnlen ((char *) p, maxlen) + 1;
18265 }
18266 else
18267 {
18268 printf (_("<corrupt>"));
18269 p = (unsigned char *) end;
18270 }
071436c6 18271 printf ("\"\n");
071436c6
NC
18272 return p;
18273 }
59e6276b
JM
18274 }
18275
f6f0e17b
NC
18276 return display_tag_value (tag, p, end);
18277}
59e6276b 18278
f6f0e17b 18279static void
60abdbed 18280display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18281{
26c527e6 18282 uint64_t addr = 0;
f6f0e17b
NC
18283 size_t bytes = end - p;
18284
feceaa59 18285 assert (end >= p);
f6f0e17b 18286 while (bytes)
87779176 18287 {
f6f0e17b
NC
18288 int j;
18289 int k;
18290 int lbytes = (bytes > 16 ? 16 : bytes);
18291
26c527e6 18292 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18293
18294 for (j = 0; j < 16; j++)
18295 {
18296 if (j < lbytes)
18297 printf ("%2.2x", p[j]);
18298 else
18299 printf (" ");
18300
18301 if ((j & 3) == 3)
18302 printf (" ");
18303 }
18304
18305 for (j = 0; j < lbytes; j++)
18306 {
18307 k = p[j];
18308 if (k >= ' ' && k < 0x7f)
18309 printf ("%c", k);
18310 else
18311 printf (".");
18312 }
18313
18314 putchar ('\n');
18315
18316 p += lbytes;
18317 bytes -= lbytes;
18318 addr += lbytes;
87779176 18319 }
59e6276b 18320
f6f0e17b 18321 putchar ('\n');
59e6276b
JM
18322}
18323
13761a11 18324static unsigned char *
b0191216 18325display_msp430_attribute (unsigned char * p,
26c527e6 18326 const unsigned char * const end)
13761a11 18327{
26c527e6
AM
18328 uint64_t val;
18329 uint64_t tag;
13761a11 18330
cd30bcef 18331 READ_ULEB (tag, p, end);
0b4362b0 18332
13761a11
NC
18333 switch (tag)
18334 {
18335 case OFBA_MSPABI_Tag_ISA:
13761a11 18336 printf (" Tag_ISA: ");
cd30bcef 18337 READ_ULEB (val, p, end);
13761a11
NC
18338 switch (val)
18339 {
18340 case 0: printf (_("None\n")); break;
18341 case 1: printf (_("MSP430\n")); break;
18342 case 2: printf (_("MSP430X\n")); break;
26c527e6 18343 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18344 }
18345 break;
18346
18347 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18348 printf (" Tag_Code_Model: ");
cd30bcef 18349 READ_ULEB (val, p, end);
13761a11
NC
18350 switch (val)
18351 {
18352 case 0: printf (_("None\n")); break;
18353 case 1: printf (_("Small\n")); break;
18354 case 2: printf (_("Large\n")); break;
26c527e6 18355 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18356 }
18357 break;
18358
18359 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18360 printf (" Tag_Data_Model: ");
cd30bcef 18361 READ_ULEB (val, p, end);
13761a11
NC
18362 switch (val)
18363 {
18364 case 0: printf (_("None\n")); break;
18365 case 1: printf (_("Small\n")); break;
18366 case 2: printf (_("Large\n")); break;
18367 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18368 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18369 }
18370 break;
18371
18372 default:
26c527e6 18373 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18374
18375 if (tag & 1)
18376 {
071436c6 18377 putchar ('"');
4082ef84
NC
18378 if (p < end - 1)
18379 {
18380 size_t maxlen = (end - p) - 1;
18381
b6ac461a 18382 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18383 p += strnlen ((char *) p, maxlen) + 1;
18384 }
18385 else
18386 {
18387 printf (_("<corrupt>"));
18388 p = (unsigned char *) end;
18389 }
071436c6 18390 printf ("\"\n");
13761a11
NC
18391 }
18392 else
18393 {
cd30bcef 18394 READ_ULEB (val, p, end);
26c527e6 18395 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18396 }
18397 break;
18398 }
18399
4082ef84 18400 assert (p <= end);
13761a11
NC
18401 return p;
18402}
18403
c0ea7c52
JL
18404static unsigned char *
18405display_msp430_gnu_attribute (unsigned char * p,
18406 unsigned int tag,
18407 const unsigned char * const end)
18408{
18409 if (tag == Tag_GNU_MSP430_Data_Region)
18410 {
26c527e6 18411 uint64_t val;
c0ea7c52 18412
c0ea7c52 18413 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18414 READ_ULEB (val, p, end);
c0ea7c52
JL
18415
18416 switch (val)
18417 {
18418 case Val_GNU_MSP430_Data_Region_Any:
18419 printf (_("Any Region\n"));
18420 break;
18421 case Val_GNU_MSP430_Data_Region_Lower:
18422 printf (_("Lower Region Only\n"));
18423 break;
18424 default:
26c527e6 18425 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18426 }
18427 return p;
18428 }
18429 return display_tag_value (tag & 1, p, end);
18430}
18431
2dc8dd17
JW
18432struct riscv_attr_tag_t {
18433 const char *name;
cd30bcef 18434 unsigned int tag;
2dc8dd17
JW
18435};
18436
18437static struct riscv_attr_tag_t riscv_attr_tag[] =
18438{
18439#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18440 T(arch),
18441 T(priv_spec),
18442 T(priv_spec_minor),
18443 T(priv_spec_revision),
18444 T(unaligned_access),
18445 T(stack_align),
18446#undef T
18447};
18448
18449static unsigned char *
18450display_riscv_attribute (unsigned char *p,
18451 const unsigned char * const end)
18452{
26c527e6
AM
18453 uint64_t val;
18454 uint64_t tag;
2dc8dd17
JW
18455 struct riscv_attr_tag_t *attr = NULL;
18456 unsigned i;
18457
cd30bcef 18458 READ_ULEB (tag, p, end);
2dc8dd17
JW
18459
18460 /* Find the name of attribute. */
18461 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18462 {
18463 if (riscv_attr_tag[i].tag == tag)
18464 {
18465 attr = &riscv_attr_tag[i];
18466 break;
18467 }
18468 }
18469
18470 if (attr)
18471 printf (" %s: ", attr->name);
18472 else
18473 return display_tag_value (tag, p, end);
18474
18475 switch (tag)
18476 {
18477 case Tag_RISCV_priv_spec:
18478 case Tag_RISCV_priv_spec_minor:
18479 case Tag_RISCV_priv_spec_revision:
cd30bcef 18480 READ_ULEB (val, p, end);
26c527e6 18481 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18482 break;
18483 case Tag_RISCV_unaligned_access:
cd30bcef 18484 READ_ULEB (val, p, end);
2dc8dd17
JW
18485 switch (val)
18486 {
18487 case 0:
18488 printf (_("No unaligned access\n"));
18489 break;
18490 case 1:
18491 printf (_("Unaligned access\n"));
18492 break;
18493 }
18494 break;
18495 case Tag_RISCV_stack_align:
cd30bcef 18496 READ_ULEB (val, p, end);
26c527e6 18497 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18498 break;
18499 case Tag_RISCV_arch:
18500 p = display_tag_value (-1, p, end);
18501 break;
18502 default:
18503 return display_tag_value (tag, p, end);
18504 }
18505
18506 return p;
18507}
18508
0861f561
CQ
18509static unsigned char *
18510display_csky_attribute (unsigned char * p,
18511 const unsigned char * const end)
18512{
26c527e6
AM
18513 uint64_t tag;
18514 uint64_t val;
0861f561
CQ
18515 READ_ULEB (tag, p, end);
18516
18517 if (tag >= Tag_CSKY_MAX)
18518 {
18519 return display_tag_value (-1, p, end);
18520 }
18521
18522 switch (tag)
18523 {
18524 case Tag_CSKY_ARCH_NAME:
18525 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18526 return display_tag_value (-1, p, end);
18527 case Tag_CSKY_CPU_NAME:
18528 printf (" Tag_CSKY_CPU_NAME:\t\t");
18529 return display_tag_value (-1, p, end);
18530
18531 case Tag_CSKY_ISA_FLAGS:
18532 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18533 return display_tag_value (0, p, end);
18534 case Tag_CSKY_ISA_EXT_FLAGS:
18535 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18536 return display_tag_value (0, p, end);
18537
18538 case Tag_CSKY_DSP_VERSION:
18539 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18540 READ_ULEB (val, p, end);
18541 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18542 printf ("DSP Extension\n");
18543 else if (val == VAL_CSKY_DSP_VERSION_2)
18544 printf ("DSP 2.0\n");
18545 break;
18546
18547 case Tag_CSKY_VDSP_VERSION:
18548 printf (" Tag_CSKY_VDSP_VERSION:\t");
18549 READ_ULEB (val, p, end);
26c527e6 18550 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18551 break;
18552
18553 case Tag_CSKY_FPU_VERSION:
18554 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18555 READ_ULEB (val, p, end);
18556 if (val == VAL_CSKY_FPU_VERSION_1)
18557 printf ("ABIV1 FPU Version 1\n");
18558 else if (val == VAL_CSKY_FPU_VERSION_2)
18559 printf ("FPU Version 2\n");
18560 break;
18561
18562 case Tag_CSKY_FPU_ABI:
18563 printf (" Tag_CSKY_FPU_ABI:\t\t");
18564 READ_ULEB (val, p, end);
18565 if (val == VAL_CSKY_FPU_ABI_HARD)
18566 printf ("Hard\n");
18567 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18568 printf ("SoftFP\n");
18569 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18570 printf ("Soft\n");
18571 break;
18572 case Tag_CSKY_FPU_ROUNDING:
18573 READ_ULEB (val, p, end);
f253158f
NC
18574 if (val == 1)
18575 {
18576 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18577 printf ("Needed\n");
18578 }
0861f561
CQ
18579 break;
18580 case Tag_CSKY_FPU_DENORMAL:
18581 READ_ULEB (val, p, end);
f253158f
NC
18582 if (val == 1)
18583 {
18584 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18585 printf ("Needed\n");
18586 }
0861f561
CQ
18587 break;
18588 case Tag_CSKY_FPU_Exception:
18589 READ_ULEB (val, p, end);
f253158f
NC
18590 if (val == 1)
18591 {
18592 printf (" Tag_CSKY_FPU_Exception:\t");
18593 printf ("Needed\n");
18594 }
0861f561
CQ
18595 break;
18596 case Tag_CSKY_FPU_NUMBER_MODULE:
18597 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18598 return display_tag_value (-1, p, end);
18599 case Tag_CSKY_FPU_HARDFP:
18600 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18601 READ_ULEB (val, p, end);
18602 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18603 printf (" Half");
18604 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18605 printf (" Single");
18606 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18607 printf (" Double");
18608 printf ("\n");
18609 break;
18610 default:
18611 return display_tag_value (tag, p, end);
18612 }
18613 return p;
18614}
18615
015dc7e1 18616static bool
dda8d76d 18617process_attributes (Filedata * filedata,
60bca95a 18618 const char * public_name,
104d59d1 18619 unsigned int proc_type,
f6f0e17b 18620 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18621 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18622{
2cf0635d 18623 Elf_Internal_Shdr * sect;
11c1ff18 18624 unsigned i;
015dc7e1 18625 bool res = true;
11c1ff18
PB
18626
18627 /* Find the section header so that we get the size. */
dda8d76d
NC
18628 for (i = 0, sect = filedata->section_headers;
18629 i < filedata->file_header.e_shnum;
11c1ff18
PB
18630 i++, sect++)
18631 {
071436c6
NC
18632 unsigned char * contents;
18633 unsigned char * p;
18634
104d59d1 18635 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18636 continue;
18637
dda8d76d 18638 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18639 sect->sh_size, _("attributes"));
60bca95a 18640 if (contents == NULL)
32ec8896 18641 {
015dc7e1 18642 res = false;
32ec8896
NC
18643 continue;
18644 }
60bca95a 18645
11c1ff18 18646 p = contents;
60abdbed
NC
18647 /* The first character is the version of the attributes.
18648 Currently only version 1, (aka 'A') is recognised here. */
18649 if (*p != 'A')
32ec8896
NC
18650 {
18651 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18652 res = false;
32ec8896 18653 }
60abdbed 18654 else
11c1ff18 18655 {
625d49fc 18656 uint64_t section_len;
071436c6
NC
18657
18658 section_len = sect->sh_size - 1;
11c1ff18 18659 p++;
60bca95a 18660
071436c6 18661 while (section_len > 0)
11c1ff18 18662 {
625d49fc 18663 uint64_t attr_len;
e9847026 18664 unsigned int namelen;
015dc7e1
AM
18665 bool public_section;
18666 bool gnu_section;
11c1ff18 18667
071436c6 18668 if (section_len <= 4)
e0a31db1
NC
18669 {
18670 error (_("Tag section ends prematurely\n"));
015dc7e1 18671 res = false;
e0a31db1
NC
18672 break;
18673 }
071436c6 18674 attr_len = byte_get (p, 4);
11c1ff18 18675 p += 4;
60bca95a 18676
071436c6 18677 if (attr_len > section_len)
11c1ff18 18678 {
071436c6
NC
18679 error (_("Bad attribute length (%u > %u)\n"),
18680 (unsigned) attr_len, (unsigned) section_len);
18681 attr_len = section_len;
015dc7e1 18682 res = false;
11c1ff18 18683 }
74e1a04b 18684 /* PR 17531: file: 001-101425-0.004 */
071436c6 18685 else if (attr_len < 5)
74e1a04b 18686 {
071436c6 18687 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18688 res = false;
74e1a04b
NC
18689 break;
18690 }
e9847026 18691
071436c6
NC
18692 section_len -= attr_len;
18693 attr_len -= 4;
18694
18695 namelen = strnlen ((char *) p, attr_len) + 1;
18696 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18697 {
18698 error (_("Corrupt attribute section name\n"));
015dc7e1 18699 res = false;
e9847026
NC
18700 break;
18701 }
18702
071436c6 18703 printf (_("Attribute Section: "));
b6ac461a 18704 print_symbol_name (INT_MAX, (const char *) p);
071436c6 18705 putchar ('\n');
60bca95a
NC
18706
18707 if (public_name && streq ((char *) p, public_name))
015dc7e1 18708 public_section = true;
11c1ff18 18709 else
015dc7e1 18710 public_section = false;
60bca95a
NC
18711
18712 if (streq ((char *) p, "gnu"))
015dc7e1 18713 gnu_section = true;
104d59d1 18714 else
015dc7e1 18715 gnu_section = false;
60bca95a 18716
11c1ff18 18717 p += namelen;
071436c6 18718 attr_len -= namelen;
e0a31db1 18719
071436c6 18720 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18721 {
e0a31db1 18722 int tag;
cd30bcef 18723 unsigned int val;
625d49fc 18724 uint64_t size;
071436c6 18725 unsigned char * end;
60bca95a 18726
e0a31db1 18727 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18728 if (attr_len < 6)
e0a31db1
NC
18729 {
18730 error (_("Unused bytes at end of section\n"));
015dc7e1 18731 res = false;
e0a31db1
NC
18732 section_len = 0;
18733 break;
18734 }
18735
18736 tag = *(p++);
11c1ff18 18737 size = byte_get (p, 4);
071436c6 18738 if (size > attr_len)
11c1ff18 18739 {
e9847026 18740 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18741 (unsigned) size, (unsigned) attr_len);
015dc7e1 18742 res = false;
071436c6 18743 size = attr_len;
11c1ff18 18744 }
e0a31db1
NC
18745 /* PR binutils/17531: Safe handling of corrupt files. */
18746 if (size < 6)
18747 {
18748 error (_("Bad subsection length (%u < 6)\n"),
18749 (unsigned) size);
015dc7e1 18750 res = false;
e0a31db1
NC
18751 section_len = 0;
18752 break;
18753 }
60bca95a 18754
071436c6 18755 attr_len -= size;
11c1ff18 18756 end = p + size - 1;
071436c6 18757 assert (end <= contents + sect->sh_size);
11c1ff18 18758 p += 4;
60bca95a 18759
11c1ff18
PB
18760 switch (tag)
18761 {
18762 case 1:
2b692964 18763 printf (_("File Attributes\n"));
11c1ff18
PB
18764 break;
18765 case 2:
2b692964 18766 printf (_("Section Attributes:"));
11c1ff18
PB
18767 goto do_numlist;
18768 case 3:
2b692964 18769 printf (_("Symbol Attributes:"));
1a0670f3 18770 /* Fall through. */
11c1ff18
PB
18771 do_numlist:
18772 for (;;)
18773 {
cd30bcef 18774 READ_ULEB (val, p, end);
11c1ff18
PB
18775 if (val == 0)
18776 break;
18777 printf (" %d", val);
18778 }
18779 printf ("\n");
18780 break;
18781 default:
2b692964 18782 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18783 public_section = false;
11c1ff18
PB
18784 break;
18785 }
60bca95a 18786
071436c6 18787 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18788 {
18789 while (p < end)
f6f0e17b 18790 p = display_pub_attribute (p, end);
60abdbed 18791 assert (p == end);
104d59d1 18792 }
071436c6 18793 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18794 {
18795 while (p < end)
18796 p = display_gnu_attribute (p,
f6f0e17b
NC
18797 display_proc_gnu_attribute,
18798 end);
60abdbed 18799 assert (p == end);
11c1ff18 18800 }
071436c6 18801 else if (p < end)
11c1ff18 18802 {
071436c6 18803 printf (_(" Unknown attribute:\n"));
f6f0e17b 18804 display_raw_attribute (p, end);
11c1ff18
PB
18805 p = end;
18806 }
071436c6
NC
18807 else
18808 attr_len = 0;
11c1ff18
PB
18809 }
18810 }
18811 }
d70c5fc7 18812
60bca95a 18813 free (contents);
11c1ff18 18814 }
32ec8896
NC
18815
18816 return res;
11c1ff18
PB
18817}
18818
ccb4c951
RS
18819/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18820 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18821 and return the VMA of the next entry, or -1 if there was a problem.
18822 Does not read from DATA_END or beyond. */
ccb4c951 18823
625d49fc
AM
18824static uint64_t
18825print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18826 unsigned char * data_end)
ccb4c951
RS
18827{
18828 printf (" ");
18829 print_vma (addr, LONG_HEX);
18830 printf (" ");
18831 if (addr < pltgot + 0xfff0)
18832 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18833 else
18834 printf ("%10s", "");
18835 printf (" ");
18836 if (data == NULL)
2b692964 18837 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18838 else
18839 {
625d49fc 18840 uint64_t entry;
82b1b41b 18841 unsigned char * from = data + addr - pltgot;
ccb4c951 18842
82b1b41b
NC
18843 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18844 {
18845 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18846 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18847 return (uint64_t) -1;
82b1b41b
NC
18848 }
18849 else
18850 {
18851 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18852 print_vma (entry, LONG_HEX);
18853 }
ccb4c951
RS
18854 }
18855 return addr + (is_32bit_elf ? 4 : 8);
18856}
18857
861fb55a
DJ
18858/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18859 PLTGOT. Print the Address and Initial fields of an entry at VMA
18860 ADDR and return the VMA of the next entry. */
18861
625d49fc
AM
18862static uint64_t
18863print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18864{
18865 printf (" ");
18866 print_vma (addr, LONG_HEX);
18867 printf (" ");
18868 if (data == NULL)
2b692964 18869 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18870 else
18871 {
625d49fc 18872 uint64_t entry;
861fb55a
DJ
18873
18874 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18875 print_vma (entry, LONG_HEX);
18876 }
18877 return addr + (is_32bit_elf ? 4 : 8);
18878}
18879
351cdf24
MF
18880static void
18881print_mips_ases (unsigned int mask)
18882{
18883 if (mask & AFL_ASE_DSP)
18884 fputs ("\n\tDSP ASE", stdout);
18885 if (mask & AFL_ASE_DSPR2)
18886 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18887 if (mask & AFL_ASE_DSPR3)
18888 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18889 if (mask & AFL_ASE_EVA)
18890 fputs ("\n\tEnhanced VA Scheme", stdout);
18891 if (mask & AFL_ASE_MCU)
18892 fputs ("\n\tMCU (MicroController) ASE", stdout);
18893 if (mask & AFL_ASE_MDMX)
18894 fputs ("\n\tMDMX ASE", stdout);
18895 if (mask & AFL_ASE_MIPS3D)
18896 fputs ("\n\tMIPS-3D ASE", stdout);
18897 if (mask & AFL_ASE_MT)
18898 fputs ("\n\tMT ASE", stdout);
18899 if (mask & AFL_ASE_SMARTMIPS)
18900 fputs ("\n\tSmartMIPS ASE", stdout);
18901 if (mask & AFL_ASE_VIRT)
18902 fputs ("\n\tVZ ASE", stdout);
18903 if (mask & AFL_ASE_MSA)
18904 fputs ("\n\tMSA ASE", stdout);
18905 if (mask & AFL_ASE_MIPS16)
18906 fputs ("\n\tMIPS16 ASE", stdout);
18907 if (mask & AFL_ASE_MICROMIPS)
18908 fputs ("\n\tMICROMIPS ASE", stdout);
18909 if (mask & AFL_ASE_XPA)
18910 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18911 if (mask & AFL_ASE_MIPS16E2)
18912 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18913 if (mask & AFL_ASE_CRC)
18914 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18915 if (mask & AFL_ASE_GINV)
18916 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18917 if (mask & AFL_ASE_LOONGSON_MMI)
18918 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18919 if (mask & AFL_ASE_LOONGSON_CAM)
18920 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18921 if (mask & AFL_ASE_LOONGSON_EXT)
18922 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18923 if (mask & AFL_ASE_LOONGSON_EXT2)
18924 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18925 if (mask == 0)
18926 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18927 else if ((mask & ~AFL_ASE_MASK) != 0)
18928 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18929}
18930
18931static void
18932print_mips_isa_ext (unsigned int isa_ext)
18933{
18934 switch (isa_ext)
18935 {
18936 case 0:
18937 fputs (_("None"), stdout);
18938 break;
18939 case AFL_EXT_XLR:
18940 fputs ("RMI XLR", stdout);
18941 break;
2c629856
N
18942 case AFL_EXT_OCTEON3:
18943 fputs ("Cavium Networks Octeon3", stdout);
18944 break;
351cdf24
MF
18945 case AFL_EXT_OCTEON2:
18946 fputs ("Cavium Networks Octeon2", stdout);
18947 break;
18948 case AFL_EXT_OCTEONP:
18949 fputs ("Cavium Networks OcteonP", stdout);
18950 break;
351cdf24
MF
18951 case AFL_EXT_OCTEON:
18952 fputs ("Cavium Networks Octeon", stdout);
18953 break;
18954 case AFL_EXT_5900:
18955 fputs ("Toshiba R5900", stdout);
18956 break;
18957 case AFL_EXT_4650:
18958 fputs ("MIPS R4650", stdout);
18959 break;
18960 case AFL_EXT_4010:
18961 fputs ("LSI R4010", stdout);
18962 break;
18963 case AFL_EXT_4100:
18964 fputs ("NEC VR4100", stdout);
18965 break;
18966 case AFL_EXT_3900:
18967 fputs ("Toshiba R3900", stdout);
18968 break;
18969 case AFL_EXT_10000:
18970 fputs ("MIPS R10000", stdout);
18971 break;
18972 case AFL_EXT_SB1:
18973 fputs ("Broadcom SB-1", stdout);
18974 break;
18975 case AFL_EXT_4111:
18976 fputs ("NEC VR4111/VR4181", stdout);
18977 break;
18978 case AFL_EXT_4120:
18979 fputs ("NEC VR4120", stdout);
18980 break;
18981 case AFL_EXT_5400:
18982 fputs ("NEC VR5400", stdout);
18983 break;
18984 case AFL_EXT_5500:
18985 fputs ("NEC VR5500", stdout);
18986 break;
18987 case AFL_EXT_LOONGSON_2E:
18988 fputs ("ST Microelectronics Loongson 2E", stdout);
18989 break;
18990 case AFL_EXT_LOONGSON_2F:
18991 fputs ("ST Microelectronics Loongson 2F", stdout);
18992 break;
38bf472a
MR
18993 case AFL_EXT_INTERAPTIV_MR2:
18994 fputs ("Imagination interAptiv MR2", stdout);
18995 break;
351cdf24 18996 default:
00ac7aa0 18997 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18998 }
18999}
19000
32ec8896 19001static signed int
351cdf24
MF
19002get_mips_reg_size (int reg_size)
19003{
19004 return (reg_size == AFL_REG_NONE) ? 0
19005 : (reg_size == AFL_REG_32) ? 32
19006 : (reg_size == AFL_REG_64) ? 64
19007 : (reg_size == AFL_REG_128) ? 128
19008 : -1;
19009}
19010
015dc7e1 19011static bool
dda8d76d 19012process_mips_specific (Filedata * filedata)
5b18a4bc 19013{
2cf0635d 19014 Elf_Internal_Dyn * entry;
351cdf24 19015 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19016 size_t liblist_offset = 0;
19017 size_t liblistno = 0;
19018 size_t conflictsno = 0;
19019 size_t options_offset = 0;
19020 size_t conflicts_offset = 0;
861fb55a
DJ
19021 size_t pltrelsz = 0;
19022 size_t pltrel = 0;
625d49fc
AM
19023 uint64_t pltgot = 0;
19024 uint64_t mips_pltgot = 0;
19025 uint64_t jmprel = 0;
19026 uint64_t local_gotno = 0;
19027 uint64_t gotsym = 0;
19028 uint64_t symtabno = 0;
015dc7e1 19029 bool res = true;
103f02d3 19030
dda8d76d 19031 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19032 display_mips_gnu_attribute))
015dc7e1 19033 res = false;
2cf19d5c 19034
dda8d76d 19035 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19036
19037 if (sect != NULL)
19038 {
19039 Elf_External_ABIFlags_v0 *abiflags_ext;
19040 Elf_Internal_ABIFlags_v0 abiflags_in;
19041
19042 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19043 {
19044 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19045 res = false;
32ec8896 19046 }
351cdf24
MF
19047 else
19048 {
dda8d76d 19049 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19050 sect->sh_size, _("MIPS ABI Flags section"));
19051 if (abiflags_ext)
19052 {
19053 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19054 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19055 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19056 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19057 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19058 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19059 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19060 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19061 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19062 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19063 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19064
19065 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19066 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19067 if (abiflags_in.isa_rev > 1)
19068 printf ("r%d", abiflags_in.isa_rev);
19069 printf ("\nGPR size: %d",
19070 get_mips_reg_size (abiflags_in.gpr_size));
19071 printf ("\nCPR1 size: %d",
19072 get_mips_reg_size (abiflags_in.cpr1_size));
19073 printf ("\nCPR2 size: %d",
19074 get_mips_reg_size (abiflags_in.cpr2_size));
19075 fputs ("\nFP ABI: ", stdout);
19076 print_mips_fp_abi_value (abiflags_in.fp_abi);
19077 fputs ("ISA Extension: ", stdout);
19078 print_mips_isa_ext (abiflags_in.isa_ext);
19079 fputs ("\nASEs:", stdout);
19080 print_mips_ases (abiflags_in.ases);
19081 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19082 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19083 fputc ('\n', stdout);
19084 free (abiflags_ext);
19085 }
19086 }
19087 }
19088
19e6b90e 19089 /* We have a lot of special sections. Thanks SGI! */
978c4450 19090 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19091 {
19092 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19093 sect = find_section (filedata, ".got");
bbdd9a68
MR
19094 if (sect != NULL)
19095 {
19096 unsigned char *data_end;
19097 unsigned char *data;
625d49fc 19098 uint64_t ent, end;
bbdd9a68
MR
19099 int addr_size;
19100
19101 pltgot = sect->sh_addr;
19102
19103 ent = pltgot;
19104 addr_size = (is_32bit_elf ? 4 : 8);
19105 end = pltgot + sect->sh_size;
19106
dda8d76d 19107 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19108 end - pltgot, 1,
19109 _("Global Offset Table data"));
19110 /* PR 12855: Null data is handled gracefully throughout. */
19111 data_end = data + (end - pltgot);
19112
19113 printf (_("\nStatic GOT:\n"));
19114 printf (_(" Canonical gp value: "));
19115 print_vma (ent + 0x7ff0, LONG_HEX);
19116 printf ("\n\n");
19117
19118 /* In a dynamic binary GOT[0] is reserved for the dynamic
19119 loader to store the lazy resolver pointer, however in
19120 a static binary it may well have been omitted and GOT
19121 reduced to a table of addresses.
19122 PR 21344: Check for the entry being fully available
19123 before fetching it. */
19124 if (data
19125 && data + ent - pltgot + addr_size <= data_end
19126 && byte_get (data + ent - pltgot, addr_size) == 0)
19127 {
19128 printf (_(" Reserved entries:\n"));
19129 printf (_(" %*s %10s %*s\n"),
19130 addr_size * 2, _("Address"), _("Access"),
19131 addr_size * 2, _("Value"));
19132 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19133 printf ("\n");
625d49fc 19134 if (ent == (uint64_t) -1)
bbdd9a68
MR
19135 goto sgot_print_fail;
19136
19137 /* Check for the MSB of GOT[1] being set, identifying a
19138 GNU object. This entry will be used by some runtime
19139 loaders, to store the module pointer. Otherwise this
19140 is an ordinary local entry.
19141 PR 21344: Check for the entry being fully available
19142 before fetching it. */
19143 if (data
19144 && data + ent - pltgot + addr_size <= data_end
19145 && (byte_get (data + ent - pltgot, addr_size)
19146 >> (addr_size * 8 - 1)) != 0)
19147 {
19148 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19149 printf ("\n");
625d49fc 19150 if (ent == (uint64_t) -1)
bbdd9a68
MR
19151 goto sgot_print_fail;
19152 }
19153 printf ("\n");
19154 }
19155
f17e9d8a 19156 if (data != NULL && ent < end)
bbdd9a68
MR
19157 {
19158 printf (_(" Local entries:\n"));
19159 printf (" %*s %10s %*s\n",
19160 addr_size * 2, _("Address"), _("Access"),
19161 addr_size * 2, _("Value"));
19162 while (ent < end)
19163 {
19164 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19165 printf ("\n");
625d49fc 19166 if (ent == (uint64_t) -1)
bbdd9a68
MR
19167 goto sgot_print_fail;
19168 }
19169 printf ("\n");
19170 }
19171
19172 sgot_print_fail:
9db70fc3 19173 free (data);
bbdd9a68
MR
19174 }
19175 return res;
19176 }
252b5132 19177
978c4450 19178 for (entry = filedata->dynamic_section;
071436c6 19179 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19180 (entry < filedata->dynamic_section + filedata->dynamic_nent
19181 && entry->d_tag != DT_NULL);
071436c6 19182 ++entry)
252b5132
RH
19183 switch (entry->d_tag)
19184 {
19185 case DT_MIPS_LIBLIST:
d93f0186 19186 liblist_offset
dda8d76d 19187 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19188 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19189 break;
19190 case DT_MIPS_LIBLISTNO:
19191 liblistno = entry->d_un.d_val;
19192 break;
19193 case DT_MIPS_OPTIONS:
dda8d76d 19194 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19195 break;
19196 case DT_MIPS_CONFLICT:
d93f0186 19197 conflicts_offset
dda8d76d 19198 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19199 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19200 break;
19201 case DT_MIPS_CONFLICTNO:
19202 conflictsno = entry->d_un.d_val;
19203 break;
ccb4c951 19204 case DT_PLTGOT:
861fb55a
DJ
19205 pltgot = entry->d_un.d_ptr;
19206 break;
ccb4c951
RS
19207 case DT_MIPS_LOCAL_GOTNO:
19208 local_gotno = entry->d_un.d_val;
19209 break;
19210 case DT_MIPS_GOTSYM:
19211 gotsym = entry->d_un.d_val;
19212 break;
19213 case DT_MIPS_SYMTABNO:
19214 symtabno = entry->d_un.d_val;
19215 break;
861fb55a
DJ
19216 case DT_MIPS_PLTGOT:
19217 mips_pltgot = entry->d_un.d_ptr;
19218 break;
19219 case DT_PLTREL:
19220 pltrel = entry->d_un.d_val;
19221 break;
19222 case DT_PLTRELSZ:
19223 pltrelsz = entry->d_un.d_val;
19224 break;
19225 case DT_JMPREL:
19226 jmprel = entry->d_un.d_ptr;
19227 break;
252b5132
RH
19228 default:
19229 break;
19230 }
19231
19232 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19233 {
2cf0635d 19234 Elf32_External_Lib * elib;
252b5132
RH
19235 size_t cnt;
19236
dda8d76d 19237 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19238 sizeof (Elf32_External_Lib),
19239 liblistno,
19240 _("liblist section data"));
a6e9f9df 19241 if (elib)
252b5132 19242 {
26c527e6
AM
19243 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19244 "\nSection '.liblist' contains %zu entries:\n",
19245 liblistno),
19246 liblistno);
2b692964 19247 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19248 stdout);
19249
19250 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19251 {
a6e9f9df 19252 Elf32_Lib liblist;
91d6fa6a 19253 time_t atime;
d5b07ef4 19254 char timebuf[128];
2cf0635d 19255 struct tm * tmp;
a6e9f9df
AM
19256
19257 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19258 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19259 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19260 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19261 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19262
91d6fa6a 19263 tmp = gmtime (&atime);
e9e44622
JJ
19264 snprintf (timebuf, sizeof (timebuf),
19265 "%04u-%02u-%02uT%02u:%02u:%02u",
19266 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19267 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19268
26c527e6 19269 printf ("%3zu: ", cnt);
84714f86 19270 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19271 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19272 else
2b692964 19273 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19274 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19275 liblist.l_version);
a6e9f9df
AM
19276
19277 if (liblist.l_flags == 0)
2b692964 19278 puts (_(" NONE"));
a6e9f9df
AM
19279 else
19280 {
19281 static const struct
252b5132 19282 {
2cf0635d 19283 const char * name;
a6e9f9df 19284 int bit;
252b5132 19285 }
a6e9f9df
AM
19286 l_flags_vals[] =
19287 {
19288 { " EXACT_MATCH", LL_EXACT_MATCH },
19289 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19290 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19291 { " EXPORTS", LL_EXPORTS },
19292 { " DELAY_LOAD", LL_DELAY_LOAD },
19293 { " DELTA", LL_DELTA }
19294 };
19295 int flags = liblist.l_flags;
19296 size_t fcnt;
19297
60bca95a 19298 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19299 if ((flags & l_flags_vals[fcnt].bit) != 0)
19300 {
19301 fputs (l_flags_vals[fcnt].name, stdout);
19302 flags ^= l_flags_vals[fcnt].bit;
19303 }
19304 if (flags != 0)
19305 printf (" %#x", (unsigned int) flags);
252b5132 19306
a6e9f9df
AM
19307 puts ("");
19308 }
252b5132 19309 }
252b5132 19310
a6e9f9df
AM
19311 free (elib);
19312 }
32ec8896 19313 else
015dc7e1 19314 res = false;
252b5132
RH
19315 }
19316
19317 if (options_offset != 0)
19318 {
2cf0635d 19319 Elf_External_Options * eopt;
252b5132
RH
19320 size_t offset;
19321 int cnt;
19322
19323 /* Find the section header so that we get the size. */
dda8d76d 19324 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19325 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19326 if (sect == NULL)
19327 {
19328 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19329 return false;
071436c6 19330 }
7fc0c668
NC
19331 /* PR 24243 */
19332 if (sect->sh_size < sizeof (* eopt))
19333 {
19334 error (_("The MIPS options section is too small.\n"));
015dc7e1 19335 return false;
7fc0c668 19336 }
252b5132 19337
dda8d76d 19338 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19339 sect->sh_size, _("options"));
a6e9f9df 19340 if (eopt)
252b5132 19341 {
fd17d1e6 19342 Elf_Internal_Options option;
76da6bbe 19343
a6e9f9df 19344 offset = cnt = 0;
82b1b41b 19345 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19346 {
2cf0635d 19347 Elf_External_Options * eoption;
fd17d1e6 19348 unsigned int optsize;
252b5132 19349
a6e9f9df 19350 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19351
fd17d1e6 19352 optsize = BYTE_GET (eoption->size);
76da6bbe 19353
82b1b41b 19354 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19355 if (optsize < sizeof (* eopt)
19356 || optsize > sect->sh_size - offset)
82b1b41b 19357 {
645f43a8 19358 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19359 optsize);
645f43a8 19360 free (eopt);
015dc7e1 19361 return false;
82b1b41b 19362 }
fd17d1e6 19363 offset += optsize;
a6e9f9df
AM
19364 ++cnt;
19365 }
252b5132 19366
d3a49aa8
AM
19367 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19368 "\nSection '%s' contains %d entries:\n",
19369 cnt),
dda8d76d 19370 printable_section_name (filedata, sect), cnt);
76da6bbe 19371
82b1b41b 19372 offset = 0;
a6e9f9df 19373 while (cnt-- > 0)
252b5132 19374 {
a6e9f9df 19375 size_t len;
fd17d1e6
AM
19376 Elf_External_Options * eoption;
19377
19378 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19379
19380 option.kind = BYTE_GET (eoption->kind);
19381 option.size = BYTE_GET (eoption->size);
19382 option.section = BYTE_GET (eoption->section);
19383 option.info = BYTE_GET (eoption->info);
a6e9f9df 19384
fd17d1e6 19385 switch (option.kind)
252b5132 19386 {
a6e9f9df
AM
19387 case ODK_NULL:
19388 /* This shouldn't happen. */
d0c4e780 19389 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19390 option.section, option.info);
a6e9f9df 19391 break;
2e6be59c 19392
a6e9f9df
AM
19393 case ODK_REGINFO:
19394 printf (" REGINFO ");
dda8d76d 19395 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19396 {
2cf0635d 19397 Elf32_External_RegInfo * ereg;
b34976b6 19398 Elf32_RegInfo reginfo;
a6e9f9df 19399
2e6be59c 19400 /* 32bit form. */
fd17d1e6
AM
19401 if (option.size < (sizeof (Elf_External_Options)
19402 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19403 {
19404 printf (_("<corrupt>\n"));
19405 error (_("Truncated MIPS REGINFO option\n"));
19406 cnt = 0;
19407 break;
19408 }
19409
fd17d1e6 19410 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19411
a6e9f9df
AM
19412 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19413 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19414 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19415 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19416 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19417 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19418
d0c4e780
AM
19419 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19420 reginfo.ri_gprmask, reginfo.ri_gp_value);
19421 printf (" "
19422 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19423 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19424 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19425 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19426 }
19427 else
19428 {
19429 /* 64 bit form. */
2cf0635d 19430 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19431 Elf64_Internal_RegInfo reginfo;
19432
fd17d1e6
AM
19433 if (option.size < (sizeof (Elf_External_Options)
19434 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19435 {
19436 printf (_("<corrupt>\n"));
19437 error (_("Truncated MIPS REGINFO option\n"));
19438 cnt = 0;
19439 break;
19440 }
19441
fd17d1e6 19442 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19443 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19444 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19445 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19446 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19447 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19448 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19449
d0c4e780
AM
19450 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19451 reginfo.ri_gprmask, reginfo.ri_gp_value);
19452 printf (" "
19453 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19454 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19455 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19456 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19457 }
fd17d1e6 19458 offset += option.size;
a6e9f9df 19459 continue;
2e6be59c 19460
a6e9f9df
AM
19461 case ODK_EXCEPTIONS:
19462 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19463 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19464 fputs (") fpe_max(", stdout);
fd17d1e6 19465 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19466 fputs (")", stdout);
19467
fd17d1e6 19468 if (option.info & OEX_PAGE0)
a6e9f9df 19469 fputs (" PAGE0", stdout);
fd17d1e6 19470 if (option.info & OEX_SMM)
a6e9f9df 19471 fputs (" SMM", stdout);
fd17d1e6 19472 if (option.info & OEX_FPDBUG)
a6e9f9df 19473 fputs (" FPDBUG", stdout);
fd17d1e6 19474 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19475 fputs (" DISMISS", stdout);
19476 break;
2e6be59c 19477
a6e9f9df
AM
19478 case ODK_PAD:
19479 fputs (" PAD ", stdout);
fd17d1e6 19480 if (option.info & OPAD_PREFIX)
a6e9f9df 19481 fputs (" PREFIX", stdout);
fd17d1e6 19482 if (option.info & OPAD_POSTFIX)
a6e9f9df 19483 fputs (" POSTFIX", stdout);
fd17d1e6 19484 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19485 fputs (" SYMBOL", stdout);
19486 break;
2e6be59c 19487
a6e9f9df
AM
19488 case ODK_HWPATCH:
19489 fputs (" HWPATCH ", stdout);
fd17d1e6 19490 if (option.info & OHW_R4KEOP)
a6e9f9df 19491 fputs (" R4KEOP", stdout);
fd17d1e6 19492 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19493 fputs (" R8KPFETCH", stdout);
fd17d1e6 19494 if (option.info & OHW_R5KEOP)
a6e9f9df 19495 fputs (" R5KEOP", stdout);
fd17d1e6 19496 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19497 fputs (" R5KCVTL", stdout);
19498 break;
2e6be59c 19499
a6e9f9df
AM
19500 case ODK_FILL:
19501 fputs (" FILL ", stdout);
19502 /* XXX Print content of info word? */
19503 break;
2e6be59c 19504
a6e9f9df
AM
19505 case ODK_TAGS:
19506 fputs (" TAGS ", stdout);
19507 /* XXX Print content of info word? */
19508 break;
2e6be59c 19509
a6e9f9df
AM
19510 case ODK_HWAND:
19511 fputs (" HWAND ", stdout);
fd17d1e6 19512 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19513 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19514 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19515 fputs (" R4KEOP_CLEAN", stdout);
19516 break;
2e6be59c 19517
a6e9f9df
AM
19518 case ODK_HWOR:
19519 fputs (" HWOR ", stdout);
fd17d1e6 19520 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19521 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19522 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19523 fputs (" R4KEOP_CLEAN", stdout);
19524 break;
2e6be59c 19525
a6e9f9df 19526 case ODK_GP_GROUP:
d0c4e780 19527 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19528 option.info & OGP_GROUP,
19529 (option.info & OGP_SELF) >> 16);
a6e9f9df 19530 break;
2e6be59c 19531
a6e9f9df 19532 case ODK_IDENT:
d0c4e780 19533 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19534 option.info & OGP_GROUP,
19535 (option.info & OGP_SELF) >> 16);
a6e9f9df 19536 break;
2e6be59c 19537
a6e9f9df
AM
19538 default:
19539 /* This shouldn't happen. */
d0c4e780 19540 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19541 option.kind, option.section, option.info);
a6e9f9df 19542 break;
252b5132 19543 }
a6e9f9df 19544
2cf0635d 19545 len = sizeof (* eopt);
fd17d1e6 19546 while (len < option.size)
82b1b41b 19547 {
fd17d1e6 19548 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19549
82b1b41b
NC
19550 if (ISPRINT (datum))
19551 printf ("%c", datum);
19552 else
19553 printf ("\\%03o", datum);
19554 len ++;
19555 }
a6e9f9df 19556 fputs ("\n", stdout);
82b1b41b 19557
fd17d1e6 19558 offset += option.size;
252b5132 19559 }
a6e9f9df 19560 free (eopt);
252b5132 19561 }
32ec8896 19562 else
015dc7e1 19563 res = false;
252b5132
RH
19564 }
19565
19566 if (conflicts_offset != 0 && conflictsno != 0)
19567 {
2cf0635d 19568 Elf32_Conflict * iconf;
252b5132
RH
19569 size_t cnt;
19570
978c4450 19571 if (filedata->dynamic_symbols == NULL)
252b5132 19572 {
591a748a 19573 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19574 return false;
252b5132
RH
19575 }
19576
7296a62a
NC
19577 /* PR 21345 - print a slightly more helpful error message
19578 if we are sure that the cmalloc will fail. */
645f43a8 19579 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19580 {
26c527e6
AM
19581 error (_("Overlarge number of conflicts detected: %zx\n"),
19582 conflictsno);
015dc7e1 19583 return false;
7296a62a
NC
19584 }
19585
3f5e193b 19586 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19587 if (iconf == NULL)
19588 {
8b73c356 19589 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19590 return false;
252b5132
RH
19591 }
19592
9ea033b2 19593 if (is_32bit_elf)
252b5132 19594 {
2cf0635d 19595 Elf32_External_Conflict * econf32;
a6e9f9df 19596
3f5e193b 19597 econf32 = (Elf32_External_Conflict *)
95099889
AM
19598 get_data (NULL, filedata, conflicts_offset,
19599 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19600 if (!econf32)
5a814d6d
AM
19601 {
19602 free (iconf);
015dc7e1 19603 return false;
5a814d6d 19604 }
252b5132
RH
19605
19606 for (cnt = 0; cnt < conflictsno; ++cnt)
19607 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19608
19609 free (econf32);
252b5132
RH
19610 }
19611 else
19612 {
2cf0635d 19613 Elf64_External_Conflict * econf64;
a6e9f9df 19614
3f5e193b 19615 econf64 = (Elf64_External_Conflict *)
95099889
AM
19616 get_data (NULL, filedata, conflicts_offset,
19617 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19618 if (!econf64)
5a814d6d
AM
19619 {
19620 free (iconf);
015dc7e1 19621 return false;
5a814d6d 19622 }
252b5132
RH
19623
19624 for (cnt = 0; cnt < conflictsno; ++cnt)
19625 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19626
19627 free (econf64);
252b5132
RH
19628 }
19629
26c527e6
AM
19630 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19631 "\nSection '.conflict' contains %zu entries:\n",
19632 conflictsno),
19633 conflictsno);
252b5132
RH
19634 puts (_(" Num: Index Value Name"));
19635
19636 for (cnt = 0; cnt < conflictsno; ++cnt)
19637 {
26c527e6 19638 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19639
978c4450 19640 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19641 printf (_("<corrupt symbol index>"));
d79b3d50 19642 else
e0a31db1
NC
19643 {
19644 Elf_Internal_Sym * psym;
19645
978c4450 19646 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19647 print_vma (psym->st_value, FULL_HEX);
19648 putchar (' ');
84714f86 19649 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19650 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19651 else
19652 printf (_("<corrupt: %14ld>"), psym->st_name);
19653 }
31104126 19654 putchar ('\n');
252b5132
RH
19655 }
19656
252b5132
RH
19657 free (iconf);
19658 }
19659
ccb4c951
RS
19660 if (pltgot != 0 && local_gotno != 0)
19661 {
625d49fc 19662 uint64_t ent, local_end, global_end;
bbeee7ea 19663 size_t i, offset;
2cf0635d 19664 unsigned char * data;
82b1b41b 19665 unsigned char * data_end;
bbeee7ea 19666 int addr_size;
ccb4c951 19667
91d6fa6a 19668 ent = pltgot;
ccb4c951
RS
19669 addr_size = (is_32bit_elf ? 4 : 8);
19670 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19671
74e1a04b
NC
19672 /* PR binutils/17533 file: 012-111227-0.004 */
19673 if (symtabno < gotsym)
19674 {
26c527e6
AM
19675 error (_("The GOT symbol offset (%" PRIu64
19676 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19677 gotsym, symtabno);
015dc7e1 19678 return false;
74e1a04b 19679 }
82b1b41b 19680
74e1a04b 19681 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19682 /* PR 17531: file: 54c91a34. */
19683 if (global_end < local_end)
19684 {
26c527e6 19685 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19686 return false;
82b1b41b 19687 }
948f632f 19688
dda8d76d
NC
19689 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19690 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19691 global_end - pltgot, 1,
19692 _("Global Offset Table data"));
919383ac 19693 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19694 data_end = data + (global_end - pltgot);
59245841 19695
ccb4c951
RS
19696 printf (_("\nPrimary GOT:\n"));
19697 printf (_(" Canonical gp value: "));
19698 print_vma (pltgot + 0x7ff0, LONG_HEX);
19699 printf ("\n\n");
19700
19701 printf (_(" Reserved entries:\n"));
19702 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19703 addr_size * 2, _("Address"), _("Access"),
19704 addr_size * 2, _("Initial"));
82b1b41b 19705 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19706 printf (_(" Lazy resolver\n"));
625d49fc 19707 if (ent == (uint64_t) -1)
82b1b41b 19708 goto got_print_fail;
75ec1fdb 19709
c4ab9505
MR
19710 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19711 This entry will be used by some runtime loaders, to store the
19712 module pointer. Otherwise this is an ordinary local entry.
19713 PR 21344: Check for the entry being fully available before
19714 fetching it. */
19715 if (data
19716 && data + ent - pltgot + addr_size <= data_end
19717 && (byte_get (data + ent - pltgot, addr_size)
19718 >> (addr_size * 8 - 1)) != 0)
19719 {
19720 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19721 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19722 if (ent == (uint64_t) -1)
c4ab9505 19723 goto got_print_fail;
ccb4c951
RS
19724 }
19725 printf ("\n");
19726
f17e9d8a 19727 if (data != NULL && ent < local_end)
ccb4c951
RS
19728 {
19729 printf (_(" Local entries:\n"));
cc5914eb 19730 printf (" %*s %10s %*s\n",
2b692964
NC
19731 addr_size * 2, _("Address"), _("Access"),
19732 addr_size * 2, _("Initial"));
91d6fa6a 19733 while (ent < local_end)
ccb4c951 19734 {
82b1b41b 19735 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19736 printf ("\n");
625d49fc 19737 if (ent == (uint64_t) -1)
82b1b41b 19738 goto got_print_fail;
ccb4c951
RS
19739 }
19740 printf ("\n");
19741 }
19742
f17e9d8a 19743 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19744 {
19745 int sym_width;
19746
19747 printf (_(" Global entries:\n"));
cc5914eb 19748 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19749 addr_size * 2, _("Address"),
19750 _("Access"),
2b692964 19751 addr_size * 2, _("Initial"),
9cf03b7e
NC
19752 addr_size * 2, _("Sym.Val."),
19753 _("Type"),
19754 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19755 _("Ndx"), _("Name"));
0b4362b0 19756
ccb4c951 19757 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19758
ccb4c951
RS
19759 for (i = gotsym; i < symtabno; i++)
19760 {
82b1b41b 19761 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19762 printf (" ");
e0a31db1 19763
978c4450 19764 if (filedata->dynamic_symbols == NULL)
e0a31db1 19765 printf (_("<no dynamic symbols>"));
978c4450 19766 else if (i < filedata->num_dynamic_syms)
e0a31db1 19767 {
978c4450 19768 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19769
19770 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
19771 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
19772
19773 bool is_special;
19774 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
19775 if (is_special)
19776 printf ("%3s ", s);
19777 else
19778 printf ("%3u ", psym->st_shndx);
e0a31db1 19779
84714f86 19780 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19781 print_symbol_name (sym_width,
84714f86 19782 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19783 else
19784 printf (_("<corrupt: %14ld>"), psym->st_name);
19785 }
ccb4c951 19786 else
26c527e6
AM
19787 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19788 i);
e0a31db1 19789
ccb4c951 19790 printf ("\n");
625d49fc 19791 if (ent == (uint64_t) -1)
82b1b41b 19792 break;
ccb4c951
RS
19793 }
19794 printf ("\n");
19795 }
19796
82b1b41b 19797 got_print_fail:
9db70fc3 19798 free (data);
ccb4c951
RS
19799 }
19800
861fb55a
DJ
19801 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19802 {
625d49fc 19803 uint64_t ent, end;
26c527e6
AM
19804 uint64_t offset, rel_offset;
19805 uint64_t count, i;
2cf0635d 19806 unsigned char * data;
861fb55a 19807 int addr_size, sym_width;
2cf0635d 19808 Elf_Internal_Rela * rels;
861fb55a 19809
dda8d76d 19810 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19811 if (pltrel == DT_RELA)
19812 {
dda8d76d 19813 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19814 return false;
861fb55a
DJ
19815 }
19816 else
19817 {
dda8d76d 19818 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19819 return false;
861fb55a
DJ
19820 }
19821
91d6fa6a 19822 ent = mips_pltgot;
861fb55a
DJ
19823 addr_size = (is_32bit_elf ? 4 : 8);
19824 end = mips_pltgot + (2 + count) * addr_size;
19825
dda8d76d
NC
19826 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19827 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19828 1, _("Procedure Linkage Table data"));
59245841 19829 if (data == NULL)
288f0ba2
AM
19830 {
19831 free (rels);
015dc7e1 19832 return false;
288f0ba2 19833 }
59245841 19834
9cf03b7e 19835 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19836 printf (_(" Reserved entries:\n"));
19837 printf (_(" %*s %*s Purpose\n"),
2b692964 19838 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19839 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19840 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19841 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19842 printf (_(" Module pointer\n"));
861fb55a
DJ
19843 printf ("\n");
19844
19845 printf (_(" Entries:\n"));
cc5914eb 19846 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19847 addr_size * 2, _("Address"),
19848 addr_size * 2, _("Initial"),
19849 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19850 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19851 for (i = 0; i < count; i++)
19852 {
26c527e6 19853 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19854
91d6fa6a 19855 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19856 printf (" ");
e0a31db1 19857
978c4450 19858 if (idx >= filedata->num_dynamic_syms)
26c527e6 19859 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19860 else
e0a31db1 19861 {
978c4450 19862 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19863
19864 print_vma (psym->st_value, LONG_HEX);
19865 printf (" %-7s %3s ",
dda8d76d 19866 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 19867 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 19868 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19869 print_symbol_name (sym_width,
84714f86 19870 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19871 else
19872 printf (_("<corrupt: %14ld>"), psym->st_name);
19873 }
861fb55a
DJ
19874 printf ("\n");
19875 }
19876 printf ("\n");
19877
9db70fc3 19878 free (data);
861fb55a
DJ
19879 free (rels);
19880 }
19881
32ec8896 19882 return res;
252b5132
RH
19883}
19884
015dc7e1 19885static bool
dda8d76d 19886process_nds32_specific (Filedata * filedata)
35c08157
KLC
19887{
19888 Elf_Internal_Shdr *sect = NULL;
19889
dda8d76d 19890 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19891 if (sect != NULL && sect->sh_size >= 4)
35c08157 19892 {
9c7b8e9b
AM
19893 unsigned char *buf;
19894 unsigned int flag;
35c08157
KLC
19895
19896 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19897 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19898 _("NDS32 elf flags section"));
35c08157 19899
9c7b8e9b 19900 if (buf == NULL)
015dc7e1 19901 return false;
32ec8896 19902
9c7b8e9b
AM
19903 flag = byte_get (buf, 4);
19904 free (buf);
19905 switch (flag & 0x3)
35c08157
KLC
19906 {
19907 case 0:
19908 printf ("(VEC_SIZE):\tNo entry.\n");
19909 break;
19910 case 1:
19911 printf ("(VEC_SIZE):\t4 bytes\n");
19912 break;
19913 case 2:
19914 printf ("(VEC_SIZE):\t16 bytes\n");
19915 break;
19916 case 3:
19917 printf ("(VEC_SIZE):\treserved\n");
19918 break;
19919 }
19920 }
19921
015dc7e1 19922 return true;
35c08157
KLC
19923}
19924
015dc7e1 19925static bool
dda8d76d 19926process_gnu_liblist (Filedata * filedata)
047b2264 19927{
2cf0635d
NC
19928 Elf_Internal_Shdr * section;
19929 Elf_Internal_Shdr * string_sec;
19930 Elf32_External_Lib * elib;
19931 char * strtab;
c256ffe7 19932 size_t strtab_size;
047b2264 19933 size_t cnt;
26c527e6 19934 uint64_t num_liblist;
047b2264 19935 unsigned i;
015dc7e1 19936 bool res = true;
047b2264
JJ
19937
19938 if (! do_arch)
015dc7e1 19939 return true;
047b2264 19940
dda8d76d
NC
19941 for (i = 0, section = filedata->section_headers;
19942 i < filedata->file_header.e_shnum;
b34976b6 19943 i++, section++)
047b2264
JJ
19944 {
19945 switch (section->sh_type)
19946 {
19947 case SHT_GNU_LIBLIST:
dda8d76d 19948 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19949 break;
19950
3f5e193b 19951 elib = (Elf32_External_Lib *)
dda8d76d 19952 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19953 _("liblist section data"));
047b2264
JJ
19954
19955 if (elib == NULL)
32ec8896 19956 {
015dc7e1 19957 res = false;
32ec8896
NC
19958 break;
19959 }
047b2264 19960
dda8d76d
NC
19961 string_sec = filedata->section_headers + section->sh_link;
19962 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19963 string_sec->sh_size,
19964 _("liblist string table"));
047b2264
JJ
19965 if (strtab == NULL
19966 || section->sh_entsize != sizeof (Elf32_External_Lib))
19967 {
19968 free (elib);
2842702f 19969 free (strtab);
015dc7e1 19970 res = false;
047b2264
JJ
19971 break;
19972 }
59245841 19973 strtab_size = string_sec->sh_size;
047b2264 19974
d3a49aa8 19975 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
19976 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
19977 " entries:\n",
19978 "\nLibrary list section '%s' contains %" PRIu64
19979 " entries:\n",
d3a49aa8 19980 num_liblist),
dda8d76d 19981 printable_section_name (filedata, section),
d3a49aa8 19982 num_liblist);
047b2264 19983
2b692964 19984 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19985
19986 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19987 ++cnt)
19988 {
19989 Elf32_Lib liblist;
91d6fa6a 19990 time_t atime;
d5b07ef4 19991 char timebuf[128];
2cf0635d 19992 struct tm * tmp;
047b2264
JJ
19993
19994 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19995 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19996 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19997 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19998 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19999
91d6fa6a 20000 tmp = gmtime (&atime);
e9e44622
JJ
20001 snprintf (timebuf, sizeof (timebuf),
20002 "%04u-%02u-%02uT%02u:%02u:%02u",
20003 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20004 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20005
26c527e6 20006 printf ("%3zu: ", cnt);
047b2264 20007 if (do_wide)
c256ffe7 20008 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20009 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20010 else
c256ffe7 20011 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20012 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20013 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20014 liblist.l_version, liblist.l_flags);
20015 }
20016
20017 free (elib);
2842702f 20018 free (strtab);
047b2264
JJ
20019 }
20020 }
20021
32ec8896 20022 return res;
047b2264
JJ
20023}
20024
9437c45b 20025static const char *
dda8d76d 20026get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20027{
20028 static char buff[64];
103f02d3 20029
dda8d76d 20030 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20031 switch (e_type)
20032 {
57346661 20033 case NT_AUXV:
1ec5cd37 20034 return _("NT_AUXV (auxiliary vector)");
57346661 20035 case NT_PRSTATUS:
1ec5cd37 20036 return _("NT_PRSTATUS (prstatus structure)");
57346661 20037 case NT_FPREGSET:
1ec5cd37 20038 return _("NT_FPREGSET (floating point registers)");
57346661 20039 case NT_PRPSINFO:
1ec5cd37 20040 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20041 case NT_TASKSTRUCT:
1ec5cd37 20042 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20043 case NT_GDB_TDESC:
20044 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20045 case NT_PRXFPREG:
1ec5cd37 20046 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20047 case NT_PPC_VMX:
20048 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20049 case NT_PPC_VSX:
20050 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20051 case NT_PPC_TAR:
20052 return _("NT_PPC_TAR (ppc TAR register)");
20053 case NT_PPC_PPR:
20054 return _("NT_PPC_PPR (ppc PPR register)");
20055 case NT_PPC_DSCR:
20056 return _("NT_PPC_DSCR (ppc DSCR register)");
20057 case NT_PPC_EBB:
20058 return _("NT_PPC_EBB (ppc EBB registers)");
20059 case NT_PPC_PMU:
20060 return _("NT_PPC_PMU (ppc PMU registers)");
20061 case NT_PPC_TM_CGPR:
20062 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20063 case NT_PPC_TM_CFPR:
20064 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20065 case NT_PPC_TM_CVMX:
20066 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20067 case NT_PPC_TM_CVSX:
3fd21718 20068 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20069 case NT_PPC_TM_SPR:
20070 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20071 case NT_PPC_TM_CTAR:
20072 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20073 case NT_PPC_TM_CPPR:
20074 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20075 case NT_PPC_TM_CDSCR:
20076 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20077 case NT_386_TLS:
20078 return _("NT_386_TLS (x86 TLS information)");
20079 case NT_386_IOPERM:
20080 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20081 case NT_X86_XSTATE:
20082 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20083 case NT_X86_CET:
20084 return _("NT_X86_CET (x86 CET state)");
eccdc733
SC
20085 case NT_X86_SHSTK:
20086 return _("NT_X86_SHSTK (x86 SHSTK state)");
0675e188
UW
20087 case NT_S390_HIGH_GPRS:
20088 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20089 case NT_S390_TIMER:
20090 return _("NT_S390_TIMER (s390 timer register)");
20091 case NT_S390_TODCMP:
20092 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20093 case NT_S390_TODPREG:
20094 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20095 case NT_S390_CTRS:
20096 return _("NT_S390_CTRS (s390 control registers)");
20097 case NT_S390_PREFIX:
20098 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20099 case NT_S390_LAST_BREAK:
20100 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20101 case NT_S390_SYSTEM_CALL:
20102 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20103 case NT_S390_TDB:
20104 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20105 case NT_S390_VXRS_LOW:
20106 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20107 case NT_S390_VXRS_HIGH:
20108 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20109 case NT_S390_GS_CB:
20110 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20111 case NT_S390_GS_BC:
20112 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20113 case NT_ARM_VFP:
20114 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20115 case NT_ARM_TLS:
20116 return _("NT_ARM_TLS (AArch TLS registers)");
20117 case NT_ARM_HW_BREAK:
20118 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20119 case NT_ARM_HW_WATCH:
20120 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20121 case NT_ARM_SYSTEM_CALL:
20122 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20123 case NT_ARM_SVE:
20124 return _("NT_ARM_SVE (AArch SVE registers)");
20125 case NT_ARM_PAC_MASK:
20126 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20127 case NT_ARM_PACA_KEYS:
20128 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20129 case NT_ARM_PACG_KEYS:
20130 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20131 case NT_ARM_TAGGED_ADDR_CTRL:
20132 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20133 case NT_ARM_SSVE:
20134 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20135 case NT_ARM_ZA:
20136 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20137 case NT_ARM_ZT:
20138 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20139 case NT_ARM_PAC_ENABLED_KEYS:
20140 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20141 case NT_ARC_V2:
20142 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20143 case NT_RISCV_CSR:
20144 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20145 case NT_PSTATUS:
1ec5cd37 20146 return _("NT_PSTATUS (pstatus structure)");
57346661 20147 case NT_FPREGS:
1ec5cd37 20148 return _("NT_FPREGS (floating point registers)");
57346661 20149 case NT_PSINFO:
1ec5cd37 20150 return _("NT_PSINFO (psinfo structure)");
57346661 20151 case NT_LWPSTATUS:
1ec5cd37 20152 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20153 case NT_LWPSINFO:
1ec5cd37 20154 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20155 case NT_WIN32PSTATUS:
1ec5cd37 20156 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20157 case NT_SIGINFO:
20158 return _("NT_SIGINFO (siginfo_t data)");
20159 case NT_FILE:
20160 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20161 default:
20162 break;
20163 }
20164 else
20165 switch (e_type)
20166 {
20167 case NT_VERSION:
20168 return _("NT_VERSION (version)");
20169 case NT_ARCH:
20170 return _("NT_ARCH (architecture)");
9ef920e9 20171 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20172 return _("OPEN");
9ef920e9 20173 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20174 return _("func");
c8795e1f
NC
20175 case NT_GO_BUILDID:
20176 return _("GO BUILDID");
3ac925fc
LB
20177 case FDO_PACKAGING_METADATA:
20178 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20179 default:
20180 break;
20181 }
20182
e9e44622 20183 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20184 return buff;
779fe533
NC
20185}
20186
015dc7e1 20187static bool
9ece1fa9
TT
20188print_core_note (Elf_Internal_Note *pnote)
20189{
20190 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20191 uint64_t count, page_size;
9ece1fa9
TT
20192 unsigned char *descdata, *filenames, *descend;
20193
20194 if (pnote->type != NT_FILE)
04ac15ab
AS
20195 {
20196 if (do_wide)
20197 printf ("\n");
015dc7e1 20198 return true;
04ac15ab 20199 }
9ece1fa9 20200
9ece1fa9
TT
20201 if (pnote->descsz < 2 * addr_size)
20202 {
32ec8896 20203 error (_(" Malformed note - too short for header\n"));
015dc7e1 20204 return false;
9ece1fa9
TT
20205 }
20206
20207 descdata = (unsigned char *) pnote->descdata;
20208 descend = descdata + pnote->descsz;
20209
20210 if (descdata[pnote->descsz - 1] != '\0')
20211 {
32ec8896 20212 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20213 return false;
9ece1fa9
TT
20214 }
20215
20216 count = byte_get (descdata, addr_size);
20217 descdata += addr_size;
20218
20219 page_size = byte_get (descdata, addr_size);
20220 descdata += addr_size;
20221
625d49fc 20222 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20223 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20224 {
32ec8896 20225 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20226 return false;
9ece1fa9
TT
20227 }
20228
20229 printf (_(" Page size: "));
20230 print_vma (page_size, DEC);
20231 printf ("\n");
20232
20233 printf (_(" %*s%*s%*s\n"),
20234 (int) (2 + 2 * addr_size), _("Start"),
20235 (int) (4 + 2 * addr_size), _("End"),
20236 (int) (4 + 2 * addr_size), _("Page Offset"));
20237 filenames = descdata + count * 3 * addr_size;
595712bb 20238 while (count-- > 0)
9ece1fa9 20239 {
625d49fc 20240 uint64_t start, end, file_ofs;
9ece1fa9
TT
20241
20242 if (filenames == descend)
20243 {
32ec8896 20244 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20245 return false;
9ece1fa9
TT
20246 }
20247
20248 start = byte_get (descdata, addr_size);
20249 descdata += addr_size;
20250 end = byte_get (descdata, addr_size);
20251 descdata += addr_size;
20252 file_ofs = byte_get (descdata, addr_size);
20253 descdata += addr_size;
20254
20255 printf (" ");
20256 print_vma (start, FULL_HEX);
20257 printf (" ");
20258 print_vma (end, FULL_HEX);
20259 printf (" ");
20260 print_vma (file_ofs, FULL_HEX);
20261 printf ("\n %s\n", filenames);
20262
20263 filenames += 1 + strlen ((char *) filenames);
20264 }
20265
015dc7e1 20266 return true;
9ece1fa9
TT
20267}
20268
1118d252
RM
20269static const char *
20270get_gnu_elf_note_type (unsigned e_type)
20271{
1449284b 20272 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20273 switch (e_type)
20274 {
20275 case NT_GNU_ABI_TAG:
20276 return _("NT_GNU_ABI_TAG (ABI version tag)");
20277 case NT_GNU_HWCAP:
20278 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20279 case NT_GNU_BUILD_ID:
20280 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20281 case NT_GNU_GOLD_VERSION:
20282 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20283 case NT_GNU_PROPERTY_TYPE_0:
20284 return _("NT_GNU_PROPERTY_TYPE_0");
20285 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20286 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20287 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20288 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20289 default:
1449284b
NC
20290 {
20291 static char buff[64];
1118d252 20292
1449284b
NC
20293 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20294 return buff;
20295 }
20296 }
1118d252
RM
20297}
20298
a9eafb08
L
20299static void
20300decode_x86_compat_isa (unsigned int bitmask)
20301{
20302 while (bitmask)
20303 {
20304 unsigned int bit = bitmask & (- bitmask);
20305
20306 bitmask &= ~ bit;
20307 switch (bit)
20308 {
20309 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20310 printf ("i486");
20311 break;
20312 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20313 printf ("586");
20314 break;
20315 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20316 printf ("686");
20317 break;
20318 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20319 printf ("SSE");
20320 break;
20321 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20322 printf ("SSE2");
20323 break;
20324 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20325 printf ("SSE3");
20326 break;
20327 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20328 printf ("SSSE3");
20329 break;
20330 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20331 printf ("SSE4_1");
20332 break;
20333 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20334 printf ("SSE4_2");
20335 break;
20336 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20337 printf ("AVX");
20338 break;
20339 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20340 printf ("AVX2");
20341 break;
20342 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20343 printf ("AVX512F");
20344 break;
20345 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20346 printf ("AVX512CD");
20347 break;
20348 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20349 printf ("AVX512ER");
20350 break;
20351 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20352 printf ("AVX512PF");
20353 break;
20354 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20355 printf ("AVX512VL");
20356 break;
20357 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20358 printf ("AVX512DQ");
20359 break;
20360 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20361 printf ("AVX512BW");
20362 break;
65b3d26e
L
20363 default:
20364 printf (_("<unknown: %x>"), bit);
20365 break;
a9eafb08
L
20366 }
20367 if (bitmask)
20368 printf (", ");
20369 }
20370}
20371
9ef920e9 20372static void
32930e4e 20373decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20374{
0a59decb 20375 if (!bitmask)
90c745dc
L
20376 {
20377 printf (_("<None>"));
20378 return;
20379 }
90c745dc 20380
9ef920e9
NC
20381 while (bitmask)
20382 {
1fc87489 20383 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20384
20385 bitmask &= ~ bit;
20386 switch (bit)
20387 {
32930e4e 20388 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20389 printf ("CMOV");
20390 break;
32930e4e 20391 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20392 printf ("SSE");
20393 break;
32930e4e 20394 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20395 printf ("SSE2");
20396 break;
32930e4e 20397 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20398 printf ("SSE3");
20399 break;
32930e4e 20400 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20401 printf ("SSSE3");
20402 break;
32930e4e 20403 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20404 printf ("SSE4_1");
20405 break;
32930e4e 20406 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20407 printf ("SSE4_2");
20408 break;
32930e4e 20409 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20410 printf ("AVX");
20411 break;
32930e4e 20412 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20413 printf ("AVX2");
20414 break;
32930e4e 20415 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20416 printf ("FMA");
20417 break;
32930e4e 20418 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20419 printf ("AVX512F");
20420 break;
32930e4e 20421 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20422 printf ("AVX512CD");
20423 break;
32930e4e 20424 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20425 printf ("AVX512ER");
20426 break;
32930e4e 20427 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20428 printf ("AVX512PF");
20429 break;
32930e4e 20430 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20431 printf ("AVX512VL");
20432 break;
32930e4e 20433 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20434 printf ("AVX512DQ");
20435 break;
32930e4e 20436 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20437 printf ("AVX512BW");
20438 break;
32930e4e 20439 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20440 printf ("AVX512_4FMAPS");
20441 break;
32930e4e 20442 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20443 printf ("AVX512_4VNNIW");
20444 break;
32930e4e 20445 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20446 printf ("AVX512_BITALG");
20447 break;
32930e4e 20448 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20449 printf ("AVX512_IFMA");
20450 break;
32930e4e 20451 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20452 printf ("AVX512_VBMI");
20453 break;
32930e4e 20454 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20455 printf ("AVX512_VBMI2");
20456 break;
32930e4e 20457 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20458 printf ("AVX512_VNNI");
20459 break;
32930e4e 20460 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20461 printf ("AVX512_BF16");
20462 break;
65b3d26e
L
20463 default:
20464 printf (_("<unknown: %x>"), bit);
20465 break;
9ef920e9
NC
20466 }
20467 if (bitmask)
20468 printf (", ");
20469 }
20470}
20471
28cdbb18
SM
20472static const char *
20473get_amdgpu_elf_note_type (unsigned int e_type)
20474{
20475 switch (e_type)
20476 {
20477 case NT_AMDGPU_METADATA:
20478 return _("NT_AMDGPU_METADATA (code object metadata)");
20479 default:
20480 {
20481 static char buf[64];
20482 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20483 return buf;
20484 }
20485 }
20486}
20487
32930e4e
L
20488static void
20489decode_x86_isa (unsigned int bitmask)
20490{
32930e4e
L
20491 while (bitmask)
20492 {
20493 unsigned int bit = bitmask & (- bitmask);
20494
20495 bitmask &= ~ bit;
20496 switch (bit)
20497 {
b0ab0693
L
20498 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20499 printf ("x86-64-baseline");
20500 break;
32930e4e
L
20501 case GNU_PROPERTY_X86_ISA_1_V2:
20502 printf ("x86-64-v2");
20503 break;
20504 case GNU_PROPERTY_X86_ISA_1_V3:
20505 printf ("x86-64-v3");
20506 break;
20507 case GNU_PROPERTY_X86_ISA_1_V4:
20508 printf ("x86-64-v4");
20509 break;
20510 default:
20511 printf (_("<unknown: %x>"), bit);
20512 break;
20513 }
20514 if (bitmask)
20515 printf (", ");
20516 }
20517}
20518
ee2fdd6f 20519static void
a9eafb08 20520decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20521{
0a59decb 20522 if (!bitmask)
90c745dc
L
20523 {
20524 printf (_("<None>"));
20525 return;
20526 }
90c745dc 20527
ee2fdd6f
L
20528 while (bitmask)
20529 {
20530 unsigned int bit = bitmask & (- bitmask);
20531
20532 bitmask &= ~ bit;
20533 switch (bit)
20534 {
20535 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20536 printf ("IBT");
ee2fdd6f 20537 break;
48580982 20538 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20539 printf ("SHSTK");
48580982 20540 break;
279d901e
L
20541 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20542 printf ("LAM_U48");
20543 break;
20544 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20545 printf ("LAM_U57");
20546 break;
ee2fdd6f
L
20547 default:
20548 printf (_("<unknown: %x>"), bit);
20549 break;
20550 }
20551 if (bitmask)
20552 printf (", ");
20553 }
20554}
20555
a9eafb08
L
20556static void
20557decode_x86_feature_2 (unsigned int bitmask)
20558{
0a59decb 20559 if (!bitmask)
90c745dc
L
20560 {
20561 printf (_("<None>"));
20562 return;
20563 }
90c745dc 20564
a9eafb08
L
20565 while (bitmask)
20566 {
20567 unsigned int bit = bitmask & (- bitmask);
20568
20569 bitmask &= ~ bit;
20570 switch (bit)
20571 {
20572 case GNU_PROPERTY_X86_FEATURE_2_X86:
20573 printf ("x86");
20574 break;
20575 case GNU_PROPERTY_X86_FEATURE_2_X87:
20576 printf ("x87");
20577 break;
20578 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20579 printf ("MMX");
20580 break;
20581 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20582 printf ("XMM");
20583 break;
20584 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20585 printf ("YMM");
20586 break;
20587 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20588 printf ("ZMM");
20589 break;
a308b89d
L
20590 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20591 printf ("TMM");
20592 break;
32930e4e
L
20593 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20594 printf ("MASK");
20595 break;
a9eafb08
L
20596 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20597 printf ("FXSR");
20598 break;
20599 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20600 printf ("XSAVE");
20601 break;
20602 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20603 printf ("XSAVEOPT");
20604 break;
20605 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20606 printf ("XSAVEC");
20607 break;
65b3d26e
L
20608 default:
20609 printf (_("<unknown: %x>"), bit);
20610 break;
a9eafb08
L
20611 }
20612 if (bitmask)
20613 printf (", ");
20614 }
20615}
20616
cd702818
SD
20617static void
20618decode_aarch64_feature_1_and (unsigned int bitmask)
20619{
20620 while (bitmask)
20621 {
20622 unsigned int bit = bitmask & (- bitmask);
20623
20624 bitmask &= ~ bit;
20625 switch (bit)
20626 {
20627 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20628 printf ("BTI");
20629 break;
20630
20631 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20632 printf ("PAC");
20633 break;
20634
20635 default:
20636 printf (_("<unknown: %x>"), bit);
20637 break;
20638 }
20639 if (bitmask)
20640 printf (", ");
20641 }
20642}
20643
6320fd00
L
20644static void
20645decode_1_needed (unsigned int bitmask)
20646{
20647 while (bitmask)
20648 {
20649 unsigned int bit = bitmask & (- bitmask);
20650
20651 bitmask &= ~ bit;
20652 switch (bit)
20653 {
20654 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20655 printf ("indirect external access");
20656 break;
20657 default:
20658 printf (_("<unknown: %x>"), bit);
20659 break;
20660 }
20661 if (bitmask)
20662 printf (", ");
20663 }
20664}
20665
9ef920e9 20666static void
dda8d76d 20667print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20668{
20669 unsigned char * ptr = (unsigned char *) pnote->descdata;
20670 unsigned char * ptr_end = ptr + pnote->descsz;
20671 unsigned int size = is_32bit_elf ? 4 : 8;
20672
20673 printf (_(" Properties: "));
20674
1fc87489 20675 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20676 {
20677 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20678 return;
20679 }
20680
6ab2c4ed 20681 while (ptr < ptr_end)
9ef920e9 20682 {
1fc87489 20683 unsigned int j;
6ab2c4ed
MC
20684 unsigned int type;
20685 unsigned int datasz;
20686
20687 if ((size_t) (ptr_end - ptr) < 8)
20688 {
20689 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20690 break;
20691 }
20692
20693 type = byte_get (ptr, 4);
20694 datasz = byte_get (ptr + 4, 4);
9ef920e9 20695
1fc87489 20696 ptr += 8;
9ef920e9 20697
6ab2c4ed 20698 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20699 {
1fc87489
L
20700 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20701 type, datasz);
9ef920e9 20702 break;
1fc87489 20703 }
9ef920e9 20704
1fc87489
L
20705 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20706 {
dda8d76d
NC
20707 if (filedata->file_header.e_machine == EM_X86_64
20708 || filedata->file_header.e_machine == EM_IAMCU
20709 || filedata->file_header.e_machine == EM_386)
1fc87489 20710 {
aa7bca9b
L
20711 unsigned int bitmask;
20712
20713 if (datasz == 4)
0a59decb 20714 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20715 else
20716 bitmask = 0;
20717
1fc87489
L
20718 switch (type)
20719 {
20720 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20721 if (datasz != 4)
aa7bca9b
L
20722 printf (_("x86 ISA used: <corrupt length: %#x> "),
20723 datasz);
1fc87489 20724 else
aa7bca9b
L
20725 {
20726 printf ("x86 ISA used: ");
20727 decode_x86_isa (bitmask);
20728 }
1fc87489 20729 goto next;
9ef920e9 20730
1fc87489 20731 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20732 if (datasz != 4)
aa7bca9b
L
20733 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20734 datasz);
1fc87489 20735 else
aa7bca9b
L
20736 {
20737 printf ("x86 ISA needed: ");
20738 decode_x86_isa (bitmask);
20739 }
1fc87489 20740 goto next;
9ef920e9 20741
ee2fdd6f 20742 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20743 if (datasz != 4)
aa7bca9b
L
20744 printf (_("x86 feature: <corrupt length: %#x> "),
20745 datasz);
ee2fdd6f 20746 else
aa7bca9b
L
20747 {
20748 printf ("x86 feature: ");
a9eafb08
L
20749 decode_x86_feature_1 (bitmask);
20750 }
20751 goto next;
20752
20753 case GNU_PROPERTY_X86_FEATURE_2_USED:
20754 if (datasz != 4)
20755 printf (_("x86 feature used: <corrupt length: %#x> "),
20756 datasz);
20757 else
20758 {
20759 printf ("x86 feature used: ");
20760 decode_x86_feature_2 (bitmask);
20761 }
20762 goto next;
20763
20764 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20765 if (datasz != 4)
20766 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20767 else
20768 {
20769 printf ("x86 feature needed: ");
20770 decode_x86_feature_2 (bitmask);
20771 }
20772 goto next;
20773
20774 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20775 if (datasz != 4)
20776 printf (_("x86 ISA used: <corrupt length: %#x> "),
20777 datasz);
20778 else
20779 {
20780 printf ("x86 ISA used: ");
20781 decode_x86_compat_isa (bitmask);
20782 }
20783 goto next;
20784
20785 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20786 if (datasz != 4)
20787 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20788 datasz);
20789 else
20790 {
20791 printf ("x86 ISA needed: ");
20792 decode_x86_compat_isa (bitmask);
aa7bca9b 20793 }
ee2fdd6f
L
20794 goto next;
20795
32930e4e
L
20796 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20797 if (datasz != 4)
20798 printf (_("x86 ISA used: <corrupt length: %#x> "),
20799 datasz);
20800 else
20801 {
20802 printf ("x86 ISA used: ");
20803 decode_x86_compat_2_isa (bitmask);
20804 }
20805 goto next;
20806
20807 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20808 if (datasz != 4)
20809 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20810 datasz);
20811 else
20812 {
20813 printf ("x86 ISA needed: ");
20814 decode_x86_compat_2_isa (bitmask);
20815 }
20816 goto next;
20817
1fc87489
L
20818 default:
20819 break;
20820 }
20821 }
cd702818
SD
20822 else if (filedata->file_header.e_machine == EM_AARCH64)
20823 {
20824 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20825 {
20826 printf ("AArch64 feature: ");
20827 if (datasz != 4)
20828 printf (_("<corrupt length: %#x> "), datasz);
20829 else
20830 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20831 goto next;
20832 }
20833 }
1fc87489
L
20834 }
20835 else
20836 {
20837 switch (type)
9ef920e9 20838 {
1fc87489
L
20839 case GNU_PROPERTY_STACK_SIZE:
20840 printf (_("stack size: "));
20841 if (datasz != size)
20842 printf (_("<corrupt length: %#x> "), datasz);
20843 else
26c527e6 20844 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20845 goto next;
20846
20847 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20848 printf ("no copy on protected ");
20849 if (datasz)
20850 printf (_("<corrupt length: %#x> "), datasz);
20851 goto next;
20852
20853 default:
5a767724
L
20854 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20855 && type <= GNU_PROPERTY_UINT32_AND_HI)
20856 || (type >= GNU_PROPERTY_UINT32_OR_LO
20857 && type <= GNU_PROPERTY_UINT32_OR_HI))
20858 {
6320fd00
L
20859 switch (type)
20860 {
20861 case GNU_PROPERTY_1_NEEDED:
20862 if (datasz != 4)
20863 printf (_("1_needed: <corrupt length: %#x> "),
20864 datasz);
20865 else
20866 {
20867 unsigned int bitmask = byte_get (ptr, 4);
20868 printf ("1_needed: ");
20869 decode_1_needed (bitmask);
20870 }
20871 goto next;
20872
20873 default:
20874 break;
20875 }
5a767724
L
20876 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20877 printf (_("UINT32_AND (%#x): "), type);
20878 else
20879 printf (_("UINT32_OR (%#x): "), type);
20880 if (datasz != 4)
20881 printf (_("<corrupt length: %#x> "), datasz);
20882 else
20883 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20884 goto next;
20885 }
9ef920e9
NC
20886 break;
20887 }
9ef920e9
NC
20888 }
20889
1fc87489
L
20890 if (type < GNU_PROPERTY_LOPROC)
20891 printf (_("<unknown type %#x data: "), type);
20892 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20893 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20894 else
20895 printf (_("<application-specific type %#x data: "), type);
20896 for (j = 0; j < datasz; ++j)
20897 printf ("%02x ", ptr[j] & 0xff);
20898 printf (">");
20899
dc1e8a47 20900 next:
9ef920e9 20901 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20902 if (ptr == ptr_end)
20903 break;
1fc87489 20904
6ab2c4ed
MC
20905 if (do_wide)
20906 printf (", ");
20907 else
20908 printf ("\n\t");
9ef920e9
NC
20909 }
20910
20911 printf ("\n");
20912}
20913
015dc7e1 20914static bool
dda8d76d 20915print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20916{
1449284b 20917 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20918 switch (pnote->type)
20919 {
20920 case NT_GNU_BUILD_ID:
20921 {
26c527e6 20922 size_t i;
664f90a3
TT
20923
20924 printf (_(" Build ID: "));
20925 for (i = 0; i < pnote->descsz; ++i)
20926 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20927 printf ("\n");
664f90a3
TT
20928 }
20929 break;
20930
20931 case NT_GNU_ABI_TAG:
20932 {
26c527e6 20933 unsigned int os, major, minor, subminor;
664f90a3
TT
20934 const char *osname;
20935
3102e897
NC
20936 /* PR 17531: file: 030-599401-0.004. */
20937 if (pnote->descsz < 16)
20938 {
20939 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20940 break;
20941 }
20942
664f90a3
TT
20943 os = byte_get ((unsigned char *) pnote->descdata, 4);
20944 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20945 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20946 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20947
20948 switch (os)
20949 {
20950 case GNU_ABI_TAG_LINUX:
20951 osname = "Linux";
20952 break;
20953 case GNU_ABI_TAG_HURD:
20954 osname = "Hurd";
20955 break;
20956 case GNU_ABI_TAG_SOLARIS:
20957 osname = "Solaris";
20958 break;
20959 case GNU_ABI_TAG_FREEBSD:
20960 osname = "FreeBSD";
20961 break;
20962 case GNU_ABI_TAG_NETBSD:
20963 osname = "NetBSD";
20964 break;
14ae95f2
RM
20965 case GNU_ABI_TAG_SYLLABLE:
20966 osname = "Syllable";
20967 break;
20968 case GNU_ABI_TAG_NACL:
20969 osname = "NaCl";
20970 break;
664f90a3
TT
20971 default:
20972 osname = "Unknown";
20973 break;
20974 }
20975
26c527e6 20976 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
20977 major, minor, subminor);
20978 }
20979 break;
926c5385
CC
20980
20981 case NT_GNU_GOLD_VERSION:
20982 {
26c527e6 20983 size_t i;
926c5385
CC
20984
20985 printf (_(" Version: "));
20986 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20987 printf ("%c", pnote->descdata[i]);
20988 printf ("\n");
20989 }
20990 break;
1449284b
NC
20991
20992 case NT_GNU_HWCAP:
20993 {
26c527e6 20994 unsigned int num_entries, mask;
1449284b
NC
20995
20996 /* Hardware capabilities information. Word 0 is the number of entries.
20997 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20998 is a series of entries, where each entry is a single byte followed
20999 by a nul terminated string. The byte gives the bit number to test
21000 if enabled in the bitmask. */
21001 printf (_(" Hardware Capabilities: "));
21002 if (pnote->descsz < 8)
21003 {
32ec8896 21004 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21005 return false;
1449284b
NC
21006 }
21007 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21008 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21009 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21010 /* FIXME: Add code to display the entries... */
21011 }
21012 break;
21013
9ef920e9 21014 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21015 print_gnu_property_note (filedata, pnote);
9ef920e9 21016 break;
9abca702 21017
1449284b
NC
21018 default:
21019 /* Handle unrecognised types. An error message should have already been
21020 created by get_gnu_elf_note_type(), so all that we need to do is to
21021 display the data. */
21022 {
26c527e6 21023 size_t i;
1449284b
NC
21024
21025 printf (_(" Description data: "));
21026 for (i = 0; i < pnote->descsz; ++i)
21027 printf ("%02x ", pnote->descdata[i] & 0xff);
21028 printf ("\n");
21029 }
21030 break;
664f90a3
TT
21031 }
21032
015dc7e1 21033 return true;
664f90a3
TT
21034}
21035
685080f2
NC
21036static const char *
21037get_v850_elf_note_type (enum v850_notes n_type)
21038{
21039 static char buff[64];
21040
21041 switch (n_type)
21042 {
21043 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21044 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21045 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21046 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21047 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21048 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21049 default:
21050 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21051 return buff;
21052 }
21053}
21054
015dc7e1 21055static bool
685080f2
NC
21056print_v850_note (Elf_Internal_Note * pnote)
21057{
21058 unsigned int val;
21059
21060 if (pnote->descsz != 4)
015dc7e1 21061 return false;
32ec8896 21062
685080f2
NC
21063 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21064
21065 if (val == 0)
21066 {
21067 printf (_("not set\n"));
015dc7e1 21068 return true;
685080f2
NC
21069 }
21070
21071 switch (pnote->type)
21072 {
21073 case V850_NOTE_ALIGNMENT:
21074 switch (val)
21075 {
015dc7e1
AM
21076 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21077 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21078 }
21079 break;
14ae95f2 21080
685080f2
NC
21081 case V850_NOTE_DATA_SIZE:
21082 switch (val)
21083 {
015dc7e1
AM
21084 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21085 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21086 }
21087 break;
14ae95f2 21088
685080f2
NC
21089 case V850_NOTE_FPU_INFO:
21090 switch (val)
21091 {
015dc7e1
AM
21092 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21093 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21094 }
21095 break;
14ae95f2 21096
685080f2
NC
21097 case V850_NOTE_MMU_INFO:
21098 case V850_NOTE_CACHE_INFO:
21099 case V850_NOTE_SIMD_INFO:
21100 if (val == EF_RH850_SIMD)
21101 {
21102 printf (_("yes\n"));
015dc7e1 21103 return true;
685080f2
NC
21104 }
21105 break;
21106
21107 default:
21108 /* An 'unknown note type' message will already have been displayed. */
21109 break;
21110 }
21111
21112 printf (_("unknown value: %x\n"), val);
015dc7e1 21113 return false;
685080f2
NC
21114}
21115
015dc7e1 21116static bool
c6056a74
SF
21117process_netbsd_elf_note (Elf_Internal_Note * pnote)
21118{
21119 unsigned int version;
21120
21121 switch (pnote->type)
21122 {
21123 case NT_NETBSD_IDENT:
b966f55f
AM
21124 if (pnote->descsz < 1)
21125 break;
c6056a74
SF
21126 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21127 if ((version / 10000) % 100)
b966f55f 21128 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21129 version, version / 100000000, (version / 1000000) % 100,
21130 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21131 'A' + (version / 10000) % 26);
c6056a74
SF
21132 else
21133 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21134 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21135 (version / 100) % 100);
015dc7e1 21136 return true;
c6056a74
SF
21137
21138 case NT_NETBSD_MARCH:
9abca702 21139 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21140 pnote->descdata);
015dc7e1 21141 return true;
c6056a74 21142
9abca702 21143 case NT_NETBSD_PAX:
b966f55f
AM
21144 if (pnote->descsz < 1)
21145 break;
9abca702
CZ
21146 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21147 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21148 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21149 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21150 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21151 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21152 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21153 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21154 return true;
c6056a74 21155 }
b966f55f
AM
21156
21157 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21158 pnote->descsz, pnote->type);
015dc7e1 21159 return false;
c6056a74
SF
21160}
21161
f4ddf30f 21162static const char *
dda8d76d 21163get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21164{
f4ddf30f
JB
21165 switch (e_type)
21166 {
21167 case NT_FREEBSD_THRMISC:
21168 return _("NT_THRMISC (thrmisc structure)");
21169 case NT_FREEBSD_PROCSTAT_PROC:
21170 return _("NT_PROCSTAT_PROC (proc data)");
21171 case NT_FREEBSD_PROCSTAT_FILES:
21172 return _("NT_PROCSTAT_FILES (files data)");
21173 case NT_FREEBSD_PROCSTAT_VMMAP:
21174 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21175 case NT_FREEBSD_PROCSTAT_GROUPS:
21176 return _("NT_PROCSTAT_GROUPS (groups data)");
21177 case NT_FREEBSD_PROCSTAT_UMASK:
21178 return _("NT_PROCSTAT_UMASK (umask data)");
21179 case NT_FREEBSD_PROCSTAT_RLIMIT:
21180 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21181 case NT_FREEBSD_PROCSTAT_OSREL:
21182 return _("NT_PROCSTAT_OSREL (osreldate data)");
21183 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21184 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21185 case NT_FREEBSD_PROCSTAT_AUXV:
21186 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21187 case NT_FREEBSD_PTLWPINFO:
21188 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21189 case NT_FREEBSD_X86_SEGBASES:
21190 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21191 }
dda8d76d 21192 return get_note_type (filedata, e_type);
f4ddf30f
JB
21193}
21194
9437c45b 21195static const char *
dda8d76d 21196get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21197{
21198 static char buff[64];
21199
540e6170
CZ
21200 switch (e_type)
21201 {
21202 case NT_NETBSDCORE_PROCINFO:
21203 /* NetBSD core "procinfo" structure. */
21204 return _("NetBSD procinfo structure");
9437c45b 21205
540e6170
CZ
21206 case NT_NETBSDCORE_AUXV:
21207 return _("NetBSD ELF auxiliary vector data");
9437c45b 21208
06d949ec
KR
21209 case NT_NETBSDCORE_LWPSTATUS:
21210 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21211
540e6170 21212 default:
06d949ec 21213 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21214 defined for NetBSD core files. If the note type is less
21215 than the start of the machine-dependent note types, we don't
21216 understand it. */
21217
21218 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21219 {
21220 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21221 return buff;
21222 }
21223 break;
9437c45b
JT
21224 }
21225
dda8d76d 21226 switch (filedata->file_header.e_machine)
9437c45b
JT
21227 {
21228 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21229 and PT_GETFPREGS == mach+2. */
21230
21231 case EM_OLD_ALPHA:
21232 case EM_ALPHA:
21233 case EM_SPARC:
21234 case EM_SPARC32PLUS:
21235 case EM_SPARCV9:
21236 switch (e_type)
21237 {
2b692964 21238 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21239 return _("PT_GETREGS (reg structure)");
2b692964 21240 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21241 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21242 default:
21243 break;
21244 }
21245 break;
21246
c0d38b0e
CZ
21247 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21248 There's also old PT___GETREGS40 == mach + 1 for old reg
21249 structure which lacks GBR. */
21250 case EM_SH:
21251 switch (e_type)
21252 {
21253 case NT_NETBSDCORE_FIRSTMACH + 1:
21254 return _("PT___GETREGS40 (old reg structure)");
21255 case NT_NETBSDCORE_FIRSTMACH + 3:
21256 return _("PT_GETREGS (reg structure)");
21257 case NT_NETBSDCORE_FIRSTMACH + 5:
21258 return _("PT_GETFPREGS (fpreg structure)");
21259 default:
21260 break;
21261 }
21262 break;
21263
9437c45b
JT
21264 /* On all other arch's, PT_GETREGS == mach+1 and
21265 PT_GETFPREGS == mach+3. */
21266 default:
21267 switch (e_type)
21268 {
2b692964 21269 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21270 return _("PT_GETREGS (reg structure)");
2b692964 21271 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21272 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21273 default:
21274 break;
21275 }
21276 }
21277
9cf03b7e 21278 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21279 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21280 return buff;
21281}
21282
98ca73af
FC
21283static const char *
21284get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21285{
21286 switch (e_type)
21287 {
21288 case NT_OPENBSD_PROCINFO:
21289 return _("OpenBSD procinfo structure");
21290 case NT_OPENBSD_AUXV:
21291 return _("OpenBSD ELF auxiliary vector data");
21292 case NT_OPENBSD_REGS:
21293 return _("OpenBSD regular registers");
21294 case NT_OPENBSD_FPREGS:
21295 return _("OpenBSD floating point registers");
21296 case NT_OPENBSD_WCOOKIE:
21297 return _("OpenBSD window cookie");
21298 }
21299
21300 return get_note_type (filedata, e_type);
21301}
21302
e263a66b
CC
21303static const char *
21304get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21305{
21306 switch (e_type)
21307 {
21308 case QNT_DEBUG_FULLPATH:
21309 return _("QNX debug fullpath");
21310 case QNT_DEBUG_RELOC:
21311 return _("QNX debug relocation");
21312 case QNT_STACK:
21313 return _("QNX stack");
21314 case QNT_GENERATOR:
21315 return _("QNX generator");
21316 case QNT_DEFAULT_LIB:
21317 return _("QNX default library");
21318 case QNT_CORE_SYSINFO:
21319 return _("QNX core sysinfo");
21320 case QNT_CORE_INFO:
21321 return _("QNX core info");
21322 case QNT_CORE_STATUS:
21323 return _("QNX core status");
21324 case QNT_CORE_GREG:
21325 return _("QNX general registers");
21326 case QNT_CORE_FPREG:
21327 return _("QNX floating point registers");
21328 case QNT_LINK_MAP:
21329 return _("QNX link map");
21330 }
21331
21332 return get_note_type (filedata, e_type);
21333}
21334
70616151
TT
21335static const char *
21336get_stapsdt_note_type (unsigned e_type)
21337{
21338 static char buff[64];
21339
21340 switch (e_type)
21341 {
21342 case NT_STAPSDT:
21343 return _("NT_STAPSDT (SystemTap probe descriptors)");
21344
21345 default:
21346 break;
21347 }
21348
21349 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21350 return buff;
21351}
21352
015dc7e1 21353static bool
c6a9fc58
TT
21354print_stapsdt_note (Elf_Internal_Note *pnote)
21355{
3ca60c57 21356 size_t len, maxlen;
26c527e6 21357 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21358 char *data = pnote->descdata;
21359 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21360 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21361 char *provider, *probe, *arg_fmt;
21362
3ca60c57
NC
21363 if (pnote->descsz < (addr_size * 3))
21364 goto stapdt_note_too_small;
21365
c6a9fc58
TT
21366 pc = byte_get ((unsigned char *) data, addr_size);
21367 data += addr_size;
3ca60c57 21368
c6a9fc58
TT
21369 base_addr = byte_get ((unsigned char *) data, addr_size);
21370 data += addr_size;
3ca60c57 21371
c6a9fc58
TT
21372 semaphore = byte_get ((unsigned char *) data, addr_size);
21373 data += addr_size;
21374
3ca60c57
NC
21375 if (data >= data_end)
21376 goto stapdt_note_too_small;
21377 maxlen = data_end - data;
21378 len = strnlen (data, maxlen);
21379 if (len < maxlen)
21380 {
21381 provider = data;
21382 data += len + 1;
21383 }
21384 else
21385 goto stapdt_note_too_small;
21386
21387 if (data >= data_end)
21388 goto stapdt_note_too_small;
21389 maxlen = data_end - data;
21390 len = strnlen (data, maxlen);
21391 if (len < maxlen)
21392 {
21393 probe = data;
21394 data += len + 1;
21395 }
21396 else
21397 goto stapdt_note_too_small;
9abca702 21398
3ca60c57
NC
21399 if (data >= data_end)
21400 goto stapdt_note_too_small;
21401 maxlen = data_end - data;
21402 len = strnlen (data, maxlen);
21403 if (len < maxlen)
21404 {
21405 arg_fmt = data;
21406 data += len + 1;
21407 }
21408 else
21409 goto stapdt_note_too_small;
c6a9fc58
TT
21410
21411 printf (_(" Provider: %s\n"), provider);
21412 printf (_(" Name: %s\n"), probe);
21413 printf (_(" Location: "));
21414 print_vma (pc, FULL_HEX);
21415 printf (_(", Base: "));
21416 print_vma (base_addr, FULL_HEX);
21417 printf (_(", Semaphore: "));
21418 print_vma (semaphore, FULL_HEX);
9cf03b7e 21419 printf ("\n");
c6a9fc58
TT
21420 printf (_(" Arguments: %s\n"), arg_fmt);
21421
21422 return data == data_end;
3ca60c57
NC
21423
21424 stapdt_note_too_small:
21425 printf (_(" <corrupt - note is too small>\n"));
21426 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21427 return false;
c6a9fc58
TT
21428}
21429
e5382207
LB
21430static bool
21431print_fdo_note (Elf_Internal_Note * pnote)
21432{
21433 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21434 {
21435 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21436 return true;
21437 }
21438 return false;
21439}
21440
00e98fc7
TG
21441static const char *
21442get_ia64_vms_note_type (unsigned e_type)
21443{
21444 static char buff[64];
21445
21446 switch (e_type)
21447 {
21448 case NT_VMS_MHD:
21449 return _("NT_VMS_MHD (module header)");
21450 case NT_VMS_LNM:
21451 return _("NT_VMS_LNM (language name)");
21452 case NT_VMS_SRC:
21453 return _("NT_VMS_SRC (source files)");
21454 case NT_VMS_TITLE:
9cf03b7e 21455 return "NT_VMS_TITLE";
00e98fc7
TG
21456 case NT_VMS_EIDC:
21457 return _("NT_VMS_EIDC (consistency check)");
21458 case NT_VMS_FPMODE:
21459 return _("NT_VMS_FPMODE (FP mode)");
21460 case NT_VMS_LINKTIME:
9cf03b7e 21461 return "NT_VMS_LINKTIME";
00e98fc7
TG
21462 case NT_VMS_IMGNAM:
21463 return _("NT_VMS_IMGNAM (image name)");
21464 case NT_VMS_IMGID:
21465 return _("NT_VMS_IMGID (image id)");
21466 case NT_VMS_LINKID:
21467 return _("NT_VMS_LINKID (link id)");
21468 case NT_VMS_IMGBID:
21469 return _("NT_VMS_IMGBID (build id)");
21470 case NT_VMS_GSTNAM:
21471 return _("NT_VMS_GSTNAM (sym table name)");
21472 case NT_VMS_ORIG_DYN:
9cf03b7e 21473 return "NT_VMS_ORIG_DYN";
00e98fc7 21474 case NT_VMS_PATCHTIME:
9cf03b7e 21475 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21476 default:
21477 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21478 return buff;
21479 }
21480}
21481
015dc7e1 21482static bool
00e98fc7
TG
21483print_ia64_vms_note (Elf_Internal_Note * pnote)
21484{
26c527e6 21485 unsigned int maxlen = pnote->descsz;
8d18bf79 21486
26c527e6 21487 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21488 goto desc_size_fail;
21489
00e98fc7
TG
21490 switch (pnote->type)
21491 {
21492 case NT_VMS_MHD:
8d18bf79
NC
21493 if (maxlen <= 36)
21494 goto desc_size_fail;
21495
26c527e6 21496 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21497
21498 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21499 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21500 if (l + 34 < maxlen)
21501 {
21502 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21503 if (l + 35 < maxlen)
21504 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21505 else
21506 printf (_(" Module version : <missing>\n"));
21507 }
00e98fc7 21508 else
8d18bf79
NC
21509 {
21510 printf (_(" Module name : <missing>\n"));
21511 printf (_(" Module version : <missing>\n"));
21512 }
00e98fc7 21513 break;
8d18bf79 21514
00e98fc7 21515 case NT_VMS_LNM:
8d18bf79 21516 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21517 break;
8d18bf79 21518
00e98fc7 21519 case NT_VMS_FPMODE:
9cf03b7e 21520 printf (_(" Floating Point mode: "));
8d18bf79
NC
21521 if (maxlen < 8)
21522 goto desc_size_fail;
21523 /* FIXME: Generate an error if descsz > 8 ? */
21524
b8281767 21525 printf ("0x%016" PRIx64 "\n",
625d49fc 21526 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21527 break;
8d18bf79 21528
00e98fc7
TG
21529 case NT_VMS_LINKTIME:
21530 printf (_(" Link time: "));
8d18bf79
NC
21531 if (maxlen < 8)
21532 goto desc_size_fail;
21533 /* FIXME: Generate an error if descsz > 8 ? */
21534
0e3c1eeb 21535 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21536 printf ("\n");
21537 break;
8d18bf79 21538
00e98fc7
TG
21539 case NT_VMS_PATCHTIME:
21540 printf (_(" Patch time: "));
8d18bf79
NC
21541 if (maxlen < 8)
21542 goto desc_size_fail;
21543 /* FIXME: Generate an error if descsz > 8 ? */
21544
0e3c1eeb 21545 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21546 printf ("\n");
21547 break;
8d18bf79 21548
00e98fc7 21549 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21550 if (maxlen < 34)
21551 goto desc_size_fail;
21552
00e98fc7 21553 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21554 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21555 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21556 printf (_(" Last modified : "));
0e3c1eeb 21557 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21558 printf (_("\n Link flags : "));
b8281767 21559 printf ("0x%016" PRIx64 "\n",
625d49fc 21560 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21561 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21562 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21563 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21564 break;
8d18bf79 21565
00e98fc7 21566 case NT_VMS_IMGNAM:
8d18bf79 21567 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21568 break;
8d18bf79 21569
00e98fc7 21570 case NT_VMS_GSTNAM:
8d18bf79 21571 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21572 break;
8d18bf79 21573
00e98fc7 21574 case NT_VMS_IMGID:
8d18bf79 21575 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21576 break;
8d18bf79 21577
00e98fc7 21578 case NT_VMS_LINKID:
8d18bf79 21579 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21580 break;
8d18bf79 21581
00e98fc7 21582 default:
015dc7e1 21583 return false;
00e98fc7 21584 }
8d18bf79 21585
015dc7e1 21586 return true;
8d18bf79
NC
21587
21588 desc_size_fail:
21589 printf (_(" <corrupt - data size is too small>\n"));
21590 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21591 return false;
00e98fc7
TG
21592}
21593
fd486f32
AM
21594struct build_attr_cache {
21595 Filedata *filedata;
21596 char *strtab;
26c527e6 21597 uint64_t strtablen;
fd486f32 21598 Elf_Internal_Sym *symtab;
26c527e6 21599 uint64_t nsyms;
fd486f32
AM
21600} ba_cache;
21601
6f156d7a
NC
21602/* Find the symbol associated with a build attribute that is attached
21603 to address OFFSET. If PNAME is non-NULL then store the name of
21604 the symbol (if found) in the provided pointer, Returns NULL if a
21605 symbol could not be found. */
c799a79d 21606
6f156d7a 21607static Elf_Internal_Sym *
015dc7e1 21608get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21609 uint64_t offset,
015dc7e1
AM
21610 bool is_open_attr,
21611 const char **pname)
9ef920e9 21612{
fd486f32
AM
21613 Elf_Internal_Sym *saved_sym = NULL;
21614 Elf_Internal_Sym *sym;
9ef920e9 21615
dda8d76d 21616 if (filedata->section_headers != NULL
fd486f32 21617 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21618 {
c799a79d 21619 Elf_Internal_Shdr * symsec;
9ef920e9 21620
fd486f32
AM
21621 free (ba_cache.strtab);
21622 ba_cache.strtab = NULL;
21623 free (ba_cache.symtab);
21624 ba_cache.symtab = NULL;
21625
c799a79d 21626 /* Load the symbol and string sections. */
dda8d76d
NC
21627 for (symsec = filedata->section_headers;
21628 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21629 symsec ++)
9ef920e9 21630 {
28d13567
AM
21631 if (symsec->sh_type == SHT_SYMTAB
21632 && get_symtab (filedata, symsec,
21633 &ba_cache.symtab, &ba_cache.nsyms,
21634 &ba_cache.strtab, &ba_cache.strtablen))
21635 break;
9ef920e9 21636 }
fd486f32 21637 ba_cache.filedata = filedata;
9ef920e9
NC
21638 }
21639
fd486f32 21640 if (ba_cache.symtab == NULL)
6f156d7a 21641 return NULL;
9ef920e9 21642
c799a79d 21643 /* Find a symbol whose value matches offset. */
fd486f32 21644 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21645 if (sym->st_value == offset)
21646 {
fd486f32 21647 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21648 /* Huh ? This should not happen. */
21649 continue;
9ef920e9 21650
fd486f32 21651 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21652 continue;
9ef920e9 21653
9b9b1092 21654 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21655 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21656 if (ba_cache.strtab[sym->st_name] == '$'
21657 && ba_cache.strtab[sym->st_name + 1] != 0
21658 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21659 continue;
21660
c799a79d
NC
21661 if (is_open_attr)
21662 {
21663 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21664 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21665 FUNC symbols entirely. */
21666 switch (ELF_ST_TYPE (sym->st_info))
21667 {
c799a79d 21668 case STT_OBJECT:
6f156d7a 21669 case STT_FILE:
c799a79d 21670 saved_sym = sym;
6f156d7a
NC
21671 if (sym->st_size)
21672 {
21673 /* If the symbol has a size associated
21674 with it then we can stop searching. */
fd486f32 21675 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21676 }
c799a79d 21677 continue;
9ef920e9 21678
c799a79d
NC
21679 case STT_FUNC:
21680 /* Ignore function symbols. */
21681 continue;
21682
21683 default:
21684 break;
21685 }
21686
21687 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21688 {
c799a79d
NC
21689 case STB_GLOBAL:
21690 if (saved_sym == NULL
21691 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21692 saved_sym = sym;
21693 break;
c871dade 21694
c799a79d
NC
21695 case STB_LOCAL:
21696 if (saved_sym == NULL)
21697 saved_sym = sym;
21698 break;
21699
21700 default:
9ef920e9
NC
21701 break;
21702 }
21703 }
c799a79d
NC
21704 else
21705 {
21706 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21707 continue;
21708
21709 saved_sym = sym;
21710 break;
21711 }
21712 }
21713
6f156d7a 21714 if (saved_sym && pname)
fd486f32 21715 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21716
21717 return saved_sym;
c799a79d
NC
21718}
21719
d20e98ab
NC
21720/* Returns true iff addr1 and addr2 are in the same section. */
21721
015dc7e1 21722static bool
26c527e6 21723same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21724{
21725 Elf_Internal_Shdr * a1;
21726 Elf_Internal_Shdr * a2;
21727
21728 a1 = find_section_by_address (filedata, addr1);
21729 a2 = find_section_by_address (filedata, addr2);
9abca702 21730
d20e98ab
NC
21731 return a1 == a2 && a1 != NULL;
21732}
21733
015dc7e1 21734static bool
dda8d76d
NC
21735print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21736 Filedata * filedata)
c799a79d 21737{
26c527e6
AM
21738 static uint64_t global_offset = 0;
21739 static uint64_t global_end = 0;
21740 static uint64_t func_offset = 0;
21741 static uint64_t func_end = 0;
c871dade 21742
015dc7e1
AM
21743 Elf_Internal_Sym *sym;
21744 const char *name;
26c527e6
AM
21745 uint64_t start;
21746 uint64_t end;
015dc7e1 21747 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21748
21749 switch (pnote->descsz)
c799a79d 21750 {
6f156d7a
NC
21751 case 0:
21752 /* A zero-length description means that the range of
21753 the previous note of the same type should be used. */
c799a79d 21754 if (is_open_attr)
c871dade 21755 {
6f156d7a 21756 if (global_end > global_offset)
26c527e6
AM
21757 printf (_(" Applies to region from %#" PRIx64
21758 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21759 else
26c527e6
AM
21760 printf (_(" Applies to region from %#" PRIx64
21761 "\n"), global_offset);
c799a79d
NC
21762 }
21763 else
21764 {
6f156d7a 21765 if (func_end > func_offset)
26c527e6
AM
21766 printf (_(" Applies to region from %#" PRIx64
21767 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21768 else
26c527e6
AM
21769 printf (_(" Applies to region from %#" PRIx64
21770 "\n"), func_offset);
c871dade 21771 }
015dc7e1 21772 return true;
9ef920e9 21773
6f156d7a
NC
21774 case 4:
21775 start = byte_get ((unsigned char *) pnote->descdata, 4);
21776 end = 0;
21777 break;
21778
21779 case 8:
c74147bb
NC
21780 start = byte_get ((unsigned char *) pnote->descdata, 4);
21781 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21782 break;
21783
21784 case 16:
21785 start = byte_get ((unsigned char *) pnote->descdata, 8);
21786 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21787 break;
9abca702 21788
6f156d7a 21789 default:
c799a79d
NC
21790 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21791 printf (_(" <invalid descsz>"));
015dc7e1 21792 return false;
c799a79d
NC
21793 }
21794
6f156d7a
NC
21795 name = NULL;
21796 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21797 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21798 in order to avoid them being confused with the start address of the
21799 first function in the file... */
21800 if (sym == NULL && is_open_attr)
21801 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21802 & name);
6f156d7a
NC
21803
21804 if (end == 0 && sym != NULL && sym->st_size > 0)
21805 end = start + sym->st_size;
c799a79d
NC
21806
21807 if (is_open_attr)
21808 {
d20e98ab
NC
21809 /* FIXME: Need to properly allow for section alignment.
21810 16 is just the alignment used on x86_64. */
21811 if (global_end > 0
21812 && start > BFD_ALIGN (global_end, 16)
21813 /* Build notes are not guaranteed to be organised in order of
21814 increasing address, but we should find the all of the notes
21815 for one section in the same place. */
21816 && same_section (filedata, start, global_end))
26c527e6
AM
21817 warn (_("Gap in build notes detected from %#" PRIx64
21818 " to %#" PRIx64 "\n"),
6f156d7a
NC
21819 global_end + 1, start - 1);
21820
26c527e6 21821 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21822 global_offset = start;
21823
21824 if (end)
21825 {
26c527e6 21826 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21827 global_end = end;
21828 }
c799a79d
NC
21829 }
21830 else
21831 {
26c527e6 21832 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21833 func_offset = start;
21834
21835 if (end)
21836 {
26c527e6 21837 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21838 func_end = end;
21839 }
c799a79d
NC
21840 }
21841
6f156d7a
NC
21842 if (sym && name)
21843 printf (_(" (%s)"), name);
21844
21845 printf ("\n");
015dc7e1 21846 return true;
9ef920e9
NC
21847}
21848
015dc7e1 21849static bool
9ef920e9
NC
21850print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21851{
1d15e434
NC
21852 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21853 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21854 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21855 char name_type;
21856 char name_attribute;
1d15e434 21857 const char * expected_types;
9ef920e9
NC
21858 const char * name = pnote->namedata;
21859 const char * text;
88305e1b 21860 signed int left;
9ef920e9
NC
21861
21862 if (name == NULL || pnote->namesz < 2)
21863 {
21864 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21865 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21866 return false;
9ef920e9
NC
21867 }
21868
6f156d7a
NC
21869 if (do_wide)
21870 left = 28;
21871 else
21872 left = 20;
88305e1b
NC
21873
21874 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21875 if (name[0] == 'G' && name[1] == 'A')
21876 {
6f156d7a
NC
21877 if (pnote->namesz < 4)
21878 {
21879 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21880 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21881 return false;
6f156d7a
NC
21882 }
21883
88305e1b
NC
21884 printf ("GA");
21885 name += 2;
21886 left -= 2;
21887 }
21888
9ef920e9
NC
21889 switch ((name_type = * name))
21890 {
21891 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21892 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21893 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21894 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21895 printf ("%c", * name);
88305e1b 21896 left --;
9ef920e9
NC
21897 break;
21898 default:
21899 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 21900 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 21901 return false;
9ef920e9
NC
21902 }
21903
9ef920e9
NC
21904 ++ name;
21905 text = NULL;
21906
21907 switch ((name_attribute = * name))
21908 {
21909 case GNU_BUILD_ATTRIBUTE_VERSION:
21910 text = _("<version>");
1d15e434 21911 expected_types = string_expected;
9ef920e9
NC
21912 ++ name;
21913 break;
21914 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21915 text = _("<stack prot>");
75d7d298 21916 expected_types = "!+*";
9ef920e9
NC
21917 ++ name;
21918 break;
21919 case GNU_BUILD_ATTRIBUTE_RELRO:
21920 text = _("<relro>");
1d15e434 21921 expected_types = bool_expected;
9ef920e9
NC
21922 ++ name;
21923 break;
21924 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21925 text = _("<stack size>");
1d15e434 21926 expected_types = number_expected;
9ef920e9
NC
21927 ++ name;
21928 break;
21929 case GNU_BUILD_ATTRIBUTE_TOOL:
21930 text = _("<tool>");
1d15e434 21931 expected_types = string_expected;
9ef920e9
NC
21932 ++ name;
21933 break;
21934 case GNU_BUILD_ATTRIBUTE_ABI:
21935 text = _("<ABI>");
21936 expected_types = "$*";
21937 ++ name;
21938 break;
21939 case GNU_BUILD_ATTRIBUTE_PIC:
21940 text = _("<PIC>");
1d15e434 21941 expected_types = number_expected;
9ef920e9
NC
21942 ++ name;
21943 break;
a8be5506
NC
21944 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21945 text = _("<short enum>");
1d15e434 21946 expected_types = bool_expected;
a8be5506
NC
21947 ++ name;
21948 break;
9ef920e9
NC
21949 default:
21950 if (ISPRINT (* name))
21951 {
21952 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21953
21954 if (len > left && ! do_wide)
21955 len = left;
75d7d298 21956 printf ("%.*s:", len, name);
9ef920e9 21957 left -= len;
0dd6ae21 21958 name += len;
9ef920e9
NC
21959 }
21960 else
21961 {
3e6b6445 21962 static char tmpbuf [128];
88305e1b 21963
3e6b6445
NC
21964 error (_("unrecognised byte in name field: %d\n"), * name);
21965 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21966 text = tmpbuf;
21967 name ++;
9ef920e9
NC
21968 }
21969 expected_types = "*$!+";
21970 break;
21971 }
21972
21973 if (text)
88305e1b 21974 left -= printf ("%s", text);
9ef920e9
NC
21975
21976 if (strchr (expected_types, name_type) == NULL)
75d7d298 21977 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 21978
26c527e6 21979 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 21980 {
26c527e6
AM
21981 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
21982 pnote->namesz,
21983 name - pnote->namedata);
015dc7e1 21984 return false;
9ef920e9
NC
21985 }
21986
21987 if (left < 1 && ! do_wide)
015dc7e1 21988 return true;
9ef920e9
NC
21989
21990 switch (name_type)
21991 {
21992 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21993 {
26c527e6
AM
21994 unsigned int bytes;
21995 uint64_t val = 0;
21996 unsigned int shift = 0;
21997 char *decoded = NULL;
ddef72cd 21998
b06b2c92
NC
21999 bytes = pnote->namesz - (name - pnote->namedata);
22000 if (bytes > 0)
22001 /* The -1 is because the name field is always 0 terminated, and we
22002 want to be able to ensure that the shift in the while loop below
22003 will not overflow. */
22004 -- bytes;
22005
ddef72cd
NC
22006 if (bytes > sizeof (val))
22007 {
3e6b6445
NC
22008 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22009 bytes);
22010 bytes = sizeof (val);
ddef72cd 22011 }
3e6b6445
NC
22012 /* We do not bother to warn if bytes == 0 as this can
22013 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22014
22015 while (bytes --)
22016 {
26c527e6 22017 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22018
22019 val |= byte << shift;
9ef920e9
NC
22020 shift += 8;
22021 }
22022
75d7d298 22023 switch (name_attribute)
9ef920e9 22024 {
75d7d298 22025 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22026 switch (val)
22027 {
75d7d298
NC
22028 case 0: decoded = "static"; break;
22029 case 1: decoded = "pic"; break;
22030 case 2: decoded = "PIC"; break;
22031 case 3: decoded = "pie"; break;
22032 case 4: decoded = "PIE"; break;
22033 default: break;
9ef920e9 22034 }
75d7d298
NC
22035 break;
22036 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22037 switch (val)
9ef920e9 22038 {
75d7d298
NC
22039 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22040 case 0: decoded = "off"; break;
22041 case 1: decoded = "on"; break;
22042 case 2: decoded = "all"; break;
22043 case 3: decoded = "strong"; break;
22044 case 4: decoded = "explicit"; break;
22045 default: break;
9ef920e9 22046 }
75d7d298
NC
22047 break;
22048 default:
22049 break;
9ef920e9
NC
22050 }
22051
75d7d298 22052 if (decoded != NULL)
3e6b6445 22053 {
b6ac461a 22054 print_symbol_name (-left, decoded);
3e6b6445
NC
22055 left = 0;
22056 }
22057 else if (val == 0)
22058 {
22059 printf ("0x0");
22060 left -= 3;
22061 }
9ef920e9 22062 else
75d7d298
NC
22063 {
22064 if (do_wide)
26c527e6 22065 left -= printf ("0x%" PRIx64, val);
75d7d298 22066 else
26c527e6 22067 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22068 }
9ef920e9
NC
22069 }
22070 break;
22071 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22072 left -= print_symbol_name (- left, name);
9ef920e9
NC
22073 break;
22074 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22075 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22076 break;
22077 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22078 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22079 break;
22080 }
22081
22082 if (do_wide && left > 0)
22083 printf ("%-*s", left, " ");
9abca702 22084
015dc7e1 22085 return true;
9ef920e9
NC
22086}
22087
2952f10c
SM
22088/* Print the contents of PNOTE as hex. */
22089
22090static void
22091print_note_contents_hex (Elf_Internal_Note *pnote)
22092{
22093 if (pnote->descsz)
22094 {
26c527e6 22095 size_t i;
2952f10c
SM
22096
22097 printf (_(" description data: "));
22098 for (i = 0; i < pnote->descsz; i++)
22099 printf ("%02x ", pnote->descdata[i] & 0xff);
22100 if (!do_wide)
22101 printf ("\n");
22102 }
22103
22104 if (do_wide)
22105 printf ("\n");
22106}
22107
22108#if defined HAVE_MSGPACK
22109
22110static void
22111print_indents (int n)
22112{
22113 printf (" ");
22114
22115 for (int i = 0; i < n; i++)
22116 printf (" ");
22117}
22118
22119/* Print OBJ in human-readable form. */
22120
22121static void
22122dump_msgpack_obj (const msgpack_object *obj, int indent)
22123{
22124 switch (obj->type)
22125 {
22126 case MSGPACK_OBJECT_NIL:
22127 printf ("(nil)");
22128 break;
22129
22130 case MSGPACK_OBJECT_BOOLEAN:
22131 printf ("%s", obj->via.boolean ? "true" : "false");
22132 break;
22133
22134 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22135 printf ("%" PRIu64, obj->via.u64);
22136 break;
22137
22138 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22139 printf ("%" PRIi64, obj->via.i64);
22140 break;
22141
22142 case MSGPACK_OBJECT_FLOAT32:
22143 case MSGPACK_OBJECT_FLOAT64:
22144 printf ("%f", obj->via.f64);
22145 break;
22146
22147 case MSGPACK_OBJECT_STR:
22148 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22149 break;
22150
22151 case MSGPACK_OBJECT_ARRAY:
22152 {
22153 const msgpack_object_array *array = &obj->via.array;
22154
22155 printf ("[\n");
22156 ++indent;
22157
22158 for (uint32_t i = 0; i < array->size; ++i)
22159 {
22160 const msgpack_object *item = &array->ptr[i];
22161
22162 print_indents (indent);
22163 dump_msgpack_obj (item, indent);
22164 printf (",\n");
22165 }
22166
22167 --indent;
22168 print_indents (indent);
22169 printf ("]");
22170 break;
22171 }
22172 break;
22173
22174 case MSGPACK_OBJECT_MAP:
22175 {
22176 const msgpack_object_map *map = &obj->via.map;
22177
22178 printf ("{\n");
22179 ++indent;
22180
22181 for (uint32_t i = 0; i < map->size; ++i)
22182 {
22183 const msgpack_object_kv *kv = &map->ptr[i];
22184 const msgpack_object *key = &kv->key;
22185 const msgpack_object *val = &kv->val;
22186
22187 print_indents (indent);
22188 dump_msgpack_obj (key, indent);
22189 printf (": ");
22190 dump_msgpack_obj (val, indent);
22191
22192 printf (",\n");
22193 }
22194
22195 --indent;
22196 print_indents (indent);
22197 printf ("}");
22198
22199 break;
22200 }
22201
22202 case MSGPACK_OBJECT_BIN:
22203 printf ("(bin)");
22204 break;
22205
22206 case MSGPACK_OBJECT_EXT:
22207 printf ("(ext)");
22208 break;
22209 }
22210}
22211
22212static void
22213dump_msgpack (const msgpack_unpacked *msg)
22214{
22215 print_indents (0);
22216 dump_msgpack_obj (&msg->data, 0);
22217 printf ("\n");
22218}
22219
22220#endif /* defined HAVE_MSGPACK */
22221
22222static bool
22223print_amdgpu_note (Elf_Internal_Note *pnote)
22224{
22225#if defined HAVE_MSGPACK
22226 /* If msgpack is available, decode and dump the note's content. */
22227 bool ret;
22228 msgpack_unpacked msg;
22229 msgpack_unpack_return msgpack_ret;
22230
22231 assert (pnote->type == NT_AMDGPU_METADATA);
22232
22233 msgpack_unpacked_init (&msg);
22234 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22235 NULL);
22236
22237 switch (msgpack_ret)
22238 {
22239 case MSGPACK_UNPACK_SUCCESS:
22240 dump_msgpack (&msg);
22241 ret = true;
22242 break;
22243
22244 default:
22245 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22246 ret = false;
22247 break;
22248 }
22249
22250 msgpack_unpacked_destroy (&msg);
22251 return ret;
22252#else
22253 /* msgpack is not available, dump contents as hex. */
22254 print_note_contents_hex (pnote);
22255 return true;
22256#endif
22257}
22258
e263a66b
CC
22259static bool
22260print_qnx_note (Elf_Internal_Note *pnote)
22261{
22262 switch (pnote->type)
22263 {
22264 case QNT_STACK:
22265 if (pnote->descsz != 12)
22266 goto desc_size_fail;
22267
22268 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22269 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22270 printf (_(" Stack allocated: %" PRIx32 "\n"),
22271 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22272 printf (_(" Executable: %s\n"),
22273 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22274 break;
22275
22276 default:
22277 print_note_contents_hex(pnote);
22278 }
22279 return true;
22280
22281desc_size_fail:
22282 printf (_(" <corrupt - data size is too small>\n"));
22283 error (_("corrupt QNX note: data size is too small\n"));
22284 return false;
22285}
22286
22287
6d118b09
NC
22288/* Note that by the ELF standard, the name field is already null byte
22289 terminated, and namesz includes the terminating null byte.
22290 I.E. the value of namesz for the name "FSF" is 4.
22291
e3c8793a 22292 If the value of namesz is zero, there is no name present. */
9ef920e9 22293
015dc7e1 22294static bool
9ef920e9 22295process_note (Elf_Internal_Note * pnote,
dda8d76d 22296 Filedata * filedata)
779fe533 22297{
2cf0635d
NC
22298 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22299 const char * nt;
9437c45b
JT
22300
22301 if (pnote->namesz == 0)
1ec5cd37
NC
22302 /* If there is no note name, then use the default set of
22303 note type strings. */
dda8d76d 22304 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22305
24d127aa 22306 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22307 /* GNU-specific object file notes. */
22308 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22309
28cdbb18
SM
22310 else if (startswith (pnote->namedata, "AMDGPU"))
22311 /* AMDGPU-specific object file notes. */
22312 nt = get_amdgpu_elf_note_type (pnote->type);
22313
24d127aa 22314 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22315 /* FreeBSD-specific core file notes. */
dda8d76d 22316 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22317
24d127aa 22318 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22319 /* NetBSD-specific core file notes. */
dda8d76d 22320 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22321
24d127aa 22322 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22323 /* NetBSD-specific core file notes. */
22324 return process_netbsd_elf_note (pnote);
22325
24d127aa 22326 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22327 /* NetBSD-specific core file notes. */
22328 return process_netbsd_elf_note (pnote);
22329
98ca73af
FC
22330 else if (startswith (pnote->namedata, "OpenBSD"))
22331 /* OpenBSD-specific core file notes. */
22332 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22333
e263a66b
CC
22334 else if (startswith (pnote->namedata, "QNX"))
22335 /* QNX-specific core file notes. */
22336 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22337
e9b095a5 22338 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22339 {
22340 /* SPU-specific core file notes. */
22341 nt = pnote->namedata + 4;
22342 name = "SPU";
22343 }
22344
24d127aa 22345 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22346 /* VMS/ia64-specific file notes. */
22347 nt = get_ia64_vms_note_type (pnote->type);
22348
24d127aa 22349 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22350 nt = get_stapsdt_note_type (pnote->type);
22351
9437c45b 22352 else
1ec5cd37
NC
22353 /* Don't recognize this note name; just use the default set of
22354 note type strings. */
dda8d76d 22355 nt = get_note_type (filedata, pnote->type);
9437c45b 22356
1449284b 22357 printf (" ");
9ef920e9 22358
24d127aa 22359 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22360 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22361 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22362 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22363 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22364 print_gnu_build_attribute_name (pnote);
22365 else
b6ac461a 22366 print_symbol_name (-20, name);
9ef920e9
NC
22367
22368 if (do_wide)
22369 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22370 else
22371 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22372
24d127aa 22373 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22374 return print_ia64_vms_note (pnote);
24d127aa 22375 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22376 return print_gnu_note (filedata, pnote);
24d127aa 22377 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22378 return print_stapsdt_note (pnote);
24d127aa 22379 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22380 return print_core_note (pnote);
e5382207
LB
22381 else if (startswith (pnote->namedata, "FDO"))
22382 return print_fdo_note (pnote);
24d127aa 22383 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22384 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22385 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22386 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22387 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22388 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22389 else if (startswith (pnote->namedata, "AMDGPU")
22390 && pnote->type == NT_AMDGPU_METADATA)
22391 return print_amdgpu_note (pnote);
e263a66b
CC
22392 else if (startswith (pnote->namedata, "QNX"))
22393 return print_qnx_note (pnote);
779fe533 22394
2952f10c 22395 print_note_contents_hex (pnote);
015dc7e1 22396 return true;
1449284b 22397}
6d118b09 22398
015dc7e1 22399static bool
dda8d76d
NC
22400process_notes_at (Filedata * filedata,
22401 Elf_Internal_Shdr * section,
625d49fc
AM
22402 uint64_t offset,
22403 uint64_t length,
22404 uint64_t align)
779fe533 22405{
015dc7e1
AM
22406 Elf_External_Note *pnotes;
22407 Elf_External_Note *external;
22408 char *end;
22409 bool res = true;
103f02d3 22410
779fe533 22411 if (length <= 0)
015dc7e1 22412 return false;
103f02d3 22413
1449284b
NC
22414 if (section)
22415 {
dda8d76d 22416 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22417 if (pnotes)
32ec8896 22418 {
dda8d76d 22419 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22420 {
22421 free (pnotes);
015dc7e1 22422 return false;
f761cb13 22423 }
32ec8896 22424 }
1449284b
NC
22425 }
22426 else
82ed9683 22427 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22428 _("notes"));
4dff97b2 22429
dd24e3da 22430 if (pnotes == NULL)
015dc7e1 22431 return false;
779fe533 22432
103f02d3 22433 external = pnotes;
103f02d3 22434
ca0e11aa
NC
22435 if (filedata->is_separate)
22436 printf (_("In linked file '%s': "), filedata->file_name);
22437 else
22438 printf ("\n");
1449284b 22439 if (section)
ca0e11aa 22440 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22441 else
26c527e6
AM
22442 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22443 " with length 0x%08" PRIx64 ":\n"),
22444 offset, length);
1449284b 22445
82ed9683
L
22446 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22447 specifies that notes should be aligned to 4 bytes in 32-bit
22448 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22449 we also support 4 byte alignment in 64-bit objects. If section
22450 alignment is less than 4, we treate alignment as 4 bytes. */
22451 if (align < 4)
22452 align = 4;
22453 else if (align != 4 && align != 8)
22454 {
26c527e6
AM
22455 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22456 align);
a788aedd 22457 free (pnotes);
015dc7e1 22458 return false;
82ed9683
L
22459 }
22460
dbe15e4e 22461 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22462
c8071705
NC
22463 end = (char *) pnotes + length;
22464 while ((char *) external < end)
779fe533 22465 {
b34976b6 22466 Elf_Internal_Note inote;
15b42fb0 22467 size_t min_notesz;
4dff97b2 22468 char * next;
2cf0635d 22469 char * temp = NULL;
c8071705 22470 size_t data_remaining = end - (char *) external;
6d118b09 22471
dda8d76d 22472 if (!is_ia64_vms (filedata))
15b42fb0 22473 {
9dd3a467
NC
22474 /* PR binutils/15191
22475 Make sure that there is enough data to read. */
15b42fb0
AM
22476 min_notesz = offsetof (Elf_External_Note, name);
22477 if (data_remaining < min_notesz)
9dd3a467 22478 {
26c527e6 22479 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22480 "not enough for a full note\n",
26c527e6 22481 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22482 "not enough for a full note\n",
22483 data_remaining),
26c527e6 22484 data_remaining);
9dd3a467
NC
22485 break;
22486 }
5396a86e
AM
22487 data_remaining -= min_notesz;
22488
15b42fb0
AM
22489 inote.type = BYTE_GET (external->type);
22490 inote.namesz = BYTE_GET (external->namesz);
22491 inote.namedata = external->name;
22492 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22493 inote.descdata = ((char *) external
4dff97b2 22494 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22495 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22496 next = ((char *) external
4dff97b2 22497 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22498 }
00e98fc7 22499 else
15b42fb0
AM
22500 {
22501 Elf64_External_VMS_Note *vms_external;
00e98fc7 22502
9dd3a467
NC
22503 /* PR binutils/15191
22504 Make sure that there is enough data to read. */
15b42fb0
AM
22505 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22506 if (data_remaining < min_notesz)
9dd3a467 22507 {
26c527e6 22508 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22509 "not enough for a full note\n",
26c527e6 22510 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22511 "not enough for a full note\n",
22512 data_remaining),
26c527e6 22513 data_remaining);
9dd3a467
NC
22514 break;
22515 }
5396a86e 22516 data_remaining -= min_notesz;
3e55a963 22517
15b42fb0
AM
22518 vms_external = (Elf64_External_VMS_Note *) external;
22519 inote.type = BYTE_GET (vms_external->type);
22520 inote.namesz = BYTE_GET (vms_external->namesz);
22521 inote.namedata = vms_external->name;
22522 inote.descsz = BYTE_GET (vms_external->descsz);
22523 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22524 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22525 next = inote.descdata + align_power (inote.descsz, 3);
22526 }
22527
5396a86e
AM
22528 /* PR 17531: file: 3443835e. */
22529 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22530 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22531 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22532 || (size_t) (next - inote.descdata) < inote.descsz
22533 || ((size_t) (next - inote.descdata)
22534 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22535 {
26c527e6
AM
22536 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22537 (char *) external - (char *) pnotes);
22538 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22539 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22540 break;
22541 }
22542
15b42fb0 22543 external = (Elf_External_Note *) next;
dd24e3da 22544
6d118b09
NC
22545 /* Verify that name is null terminated. It appears that at least
22546 one version of Linux (RedHat 6.0) generates corefiles that don't
22547 comply with the ELF spec by failing to include the null byte in
22548 namesz. */
18344509 22549 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22550 {
5396a86e 22551 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22552 {
5396a86e
AM
22553 temp = (char *) malloc (inote.namesz + 1);
22554 if (temp == NULL)
22555 {
22556 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22557 res = false;
5396a86e
AM
22558 break;
22559 }
76da6bbe 22560
5396a86e
AM
22561 memcpy (temp, inote.namedata, inote.namesz);
22562 inote.namedata = temp;
22563 }
22564 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22565 }
22566
dda8d76d 22567 if (! process_note (& inote, filedata))
015dc7e1 22568 res = false;
103f02d3 22569
9db70fc3
AM
22570 free (temp);
22571 temp = NULL;
779fe533
NC
22572 }
22573
22574 free (pnotes);
103f02d3 22575
779fe533
NC
22576 return res;
22577}
22578
015dc7e1 22579static bool
dda8d76d 22580process_corefile_note_segments (Filedata * filedata)
779fe533 22581{
015dc7e1 22582 Elf_Internal_Phdr *segment;
b34976b6 22583 unsigned int i;
015dc7e1 22584 bool res = true;
103f02d3 22585
dda8d76d 22586 if (! get_program_headers (filedata))
015dc7e1 22587 return true;
103f02d3 22588
dda8d76d
NC
22589 for (i = 0, segment = filedata->program_headers;
22590 i < filedata->file_header.e_phnum;
b34976b6 22591 i++, segment++)
779fe533
NC
22592 {
22593 if (segment->p_type == PT_NOTE)
625d49fc
AM
22594 if (! process_notes_at (filedata, NULL, segment->p_offset,
22595 segment->p_filesz, segment->p_align))
015dc7e1 22596 res = false;
779fe533 22597 }
103f02d3 22598
779fe533
NC
22599 return res;
22600}
22601
015dc7e1 22602static bool
625d49fc 22603process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22604{
22605 Elf_External_Note * pnotes;
22606 Elf_External_Note * external;
c8071705 22607 char * end;
015dc7e1 22608 bool res = true;
685080f2
NC
22609
22610 if (length <= 0)
015dc7e1 22611 return false;
685080f2 22612
dda8d76d 22613 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22614 _("v850 notes"));
22615 if (pnotes == NULL)
015dc7e1 22616 return false;
685080f2
NC
22617
22618 external = pnotes;
c8071705 22619 end = (char*) pnotes + length;
685080f2 22620
26c527e6
AM
22621 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22622 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22623 offset, length);
685080f2 22624
c8071705 22625 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22626 {
22627 Elf_External_Note * next;
22628 Elf_Internal_Note inote;
22629
22630 inote.type = BYTE_GET (external->type);
22631 inote.namesz = BYTE_GET (external->namesz);
22632 inote.namedata = external->name;
22633 inote.descsz = BYTE_GET (external->descsz);
22634 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22635 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22636
c8071705
NC
22637 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22638 {
22639 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22640 inote.descdata = inote.namedata;
22641 inote.namesz = 0;
22642 }
22643
685080f2
NC
22644 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22645
c8071705 22646 if ( ((char *) next > end)
685080f2
NC
22647 || ((char *) next < (char *) pnotes))
22648 {
26c527e6
AM
22649 warn (_("corrupt descsz found in note at offset %#tx\n"),
22650 (char *) external - (char *) pnotes);
22651 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22652 inote.type, inote.namesz, inote.descsz);
22653 break;
22654 }
22655
22656 external = next;
22657
22658 /* Prevent out-of-bounds indexing. */
c8071705 22659 if ( inote.namedata + inote.namesz > end
685080f2
NC
22660 || inote.namedata + inote.namesz < inote.namedata)
22661 {
26c527e6
AM
22662 warn (_("corrupt namesz found in note at offset %#zx\n"),
22663 (char *) external - (char *) pnotes);
22664 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22665 inote.type, inote.namesz, inote.descsz);
22666 break;
22667 }
22668
22669 printf (" %s: ", get_v850_elf_note_type (inote.type));
22670
22671 if (! print_v850_note (& inote))
22672 {
015dc7e1 22673 res = false;
26c527e6 22674 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22675 inote.namesz, inote.descsz);
22676 }
22677 }
22678
22679 free (pnotes);
22680
22681 return res;
22682}
22683
015dc7e1 22684static bool
dda8d76d 22685process_note_sections (Filedata * filedata)
1ec5cd37 22686{
015dc7e1 22687 Elf_Internal_Shdr *section;
26c527e6 22688 size_t i;
32ec8896 22689 unsigned int n = 0;
015dc7e1 22690 bool res = true;
1ec5cd37 22691
dda8d76d
NC
22692 for (i = 0, section = filedata->section_headers;
22693 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22694 i++, section++)
685080f2
NC
22695 {
22696 if (section->sh_type == SHT_NOTE)
22697 {
625d49fc
AM
22698 if (! process_notes_at (filedata, section, section->sh_offset,
22699 section->sh_size, section->sh_addralign))
015dc7e1 22700 res = false;
685080f2
NC
22701 n++;
22702 }
22703
dda8d76d
NC
22704 if (( filedata->file_header.e_machine == EM_V800
22705 || filedata->file_header.e_machine == EM_V850
22706 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22707 && section->sh_type == SHT_RENESAS_INFO)
22708 {
625d49fc
AM
22709 if (! process_v850_notes (filedata, section->sh_offset,
22710 section->sh_size))
015dc7e1 22711 res = false;
685080f2
NC
22712 n++;
22713 }
22714 }
df565f32
NC
22715
22716 if (n == 0)
22717 /* Try processing NOTE segments instead. */
dda8d76d 22718 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22719
22720 return res;
22721}
22722
015dc7e1 22723static bool
dda8d76d 22724process_notes (Filedata * filedata)
779fe533
NC
22725{
22726 /* If we have not been asked to display the notes then do nothing. */
22727 if (! do_notes)
015dc7e1 22728 return true;
103f02d3 22729
dda8d76d
NC
22730 if (filedata->file_header.e_type != ET_CORE)
22731 return process_note_sections (filedata);
103f02d3 22732
779fe533 22733 /* No program headers means no NOTE segment. */
dda8d76d
NC
22734 if (filedata->file_header.e_phnum > 0)
22735 return process_corefile_note_segments (filedata);
779fe533 22736
ca0e11aa
NC
22737 if (filedata->is_separate)
22738 printf (_("No notes found in linked file '%s'.\n"),
22739 filedata->file_name);
22740 else
22741 printf (_("No notes found file.\n"));
22742
015dc7e1 22743 return true;
779fe533
NC
22744}
22745
60abdbed
NC
22746static unsigned char *
22747display_public_gnu_attributes (unsigned char * start,
22748 const unsigned char * const end)
22749{
22750 printf (_(" Unknown GNU attribute: %s\n"), start);
22751
22752 start += strnlen ((char *) start, end - start);
22753 display_raw_attribute (start, end);
22754
22755 return (unsigned char *) end;
22756}
22757
22758static unsigned char *
22759display_generic_attribute (unsigned char * start,
22760 unsigned int tag,
22761 const unsigned char * const end)
22762{
22763 if (tag == 0)
22764 return (unsigned char *) end;
22765
22766 return display_tag_value (tag, start, end);
22767}
22768
015dc7e1 22769static bool
dda8d76d 22770process_arch_specific (Filedata * filedata)
252b5132 22771{
a952a375 22772 if (! do_arch)
015dc7e1 22773 return true;
a952a375 22774
dda8d76d 22775 switch (filedata->file_header.e_machine)
252b5132 22776 {
53a346d8
CZ
22777 case EM_ARC:
22778 case EM_ARC_COMPACT:
22779 case EM_ARC_COMPACT2:
b5c37946
SJ
22780 case EM_ARC_COMPACT3:
22781 case EM_ARC_COMPACT3_64:
dda8d76d 22782 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22783 display_arc_attribute,
22784 display_generic_attribute);
11c1ff18 22785 case EM_ARM:
dda8d76d 22786 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22787 display_arm_attribute,
22788 display_generic_attribute);
22789
252b5132 22790 case EM_MIPS:
4fe85591 22791 case EM_MIPS_RS3_LE:
dda8d76d 22792 return process_mips_specific (filedata);
60abdbed
NC
22793
22794 case EM_MSP430:
dda8d76d 22795 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22796 display_msp430_attribute,
c0ea7c52 22797 display_msp430_gnu_attribute);
60abdbed 22798
2dc8dd17
JW
22799 case EM_RISCV:
22800 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22801 display_riscv_attribute,
22802 display_generic_attribute);
22803
35c08157 22804 case EM_NDS32:
dda8d76d 22805 return process_nds32_specific (filedata);
60abdbed 22806
85f7484a
PB
22807 case EM_68K:
22808 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22809 display_m68k_gnu_attribute);
22810
34c8bcba 22811 case EM_PPC:
b82317dd 22812 case EM_PPC64:
dda8d76d 22813 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22814 display_power_gnu_attribute);
22815
643f7afb
AK
22816 case EM_S390:
22817 case EM_S390_OLD:
dda8d76d 22818 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22819 display_s390_gnu_attribute);
22820
9e8c70f9
DM
22821 case EM_SPARC:
22822 case EM_SPARC32PLUS:
22823 case EM_SPARCV9:
dda8d76d 22824 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22825 display_sparc_gnu_attribute);
22826
59e6276b 22827 case EM_TI_C6000:
dda8d76d 22828 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22829 display_tic6x_attribute,
22830 display_generic_attribute);
22831
0861f561
CQ
22832 case EM_CSKY:
22833 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22834 display_csky_attribute, NULL);
22835
252b5132 22836 default:
dda8d76d 22837 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22838 display_public_gnu_attributes,
22839 display_generic_attribute);
252b5132 22840 }
252b5132
RH
22841}
22842
015dc7e1 22843static bool
dda8d76d 22844get_file_header (Filedata * filedata)
252b5132 22845{
9ea033b2 22846 /* Read in the identity array. */
dda8d76d 22847 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22848 return false;
252b5132 22849
9ea033b2 22850 /* Determine how to read the rest of the header. */
dda8d76d 22851 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22852 {
1a0670f3
AM
22853 default:
22854 case ELFDATANONE:
adab8cdc
AO
22855 case ELFDATA2LSB:
22856 byte_get = byte_get_little_endian;
22857 byte_put = byte_put_little_endian;
22858 break;
22859 case ELFDATA2MSB:
22860 byte_get = byte_get_big_endian;
22861 byte_put = byte_put_big_endian;
22862 break;
9ea033b2
NC
22863 }
22864
22865 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22866 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22867
22868 /* Read in the rest of the header. */
22869 if (is_32bit_elf)
22870 {
22871 Elf32_External_Ehdr ehdr32;
252b5132 22872
dda8d76d 22873 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22874 return false;
103f02d3 22875
dda8d76d
NC
22876 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22877 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22878 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22879 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22880 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22881 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22882 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22883 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22884 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22885 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22886 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22887 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22888 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22889 }
252b5132 22890 else
9ea033b2
NC
22891 {
22892 Elf64_External_Ehdr ehdr64;
a952a375 22893
dda8d76d 22894 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22895 return false;
103f02d3 22896
dda8d76d
NC
22897 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22898 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22899 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22900 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22901 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22902 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22903 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22904 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22905 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22906 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22907 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22908 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22909 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22910 }
252b5132 22911
015dc7e1 22912 return true;
252b5132
RH
22913}
22914
13acb58d
AM
22915static void
22916free_filedata (Filedata *filedata)
22917{
22918 free (filedata->program_interpreter);
13acb58d 22919 free (filedata->program_headers);
13acb58d 22920 free (filedata->section_headers);
13acb58d 22921 free (filedata->string_table);
13acb58d 22922 free (filedata->dump.dump_sects);
13acb58d 22923 free (filedata->dynamic_strings);
13acb58d 22924 free (filedata->dynamic_symbols);
13acb58d 22925 free (filedata->dynamic_syminfo);
13acb58d 22926 free (filedata->dynamic_section);
13acb58d
AM
22927
22928 while (filedata->symtab_shndx_list != NULL)
22929 {
22930 elf_section_list *next = filedata->symtab_shndx_list->next;
22931 free (filedata->symtab_shndx_list);
22932 filedata->symtab_shndx_list = next;
22933 }
22934
22935 free (filedata->section_headers_groups);
13acb58d
AM
22936
22937 if (filedata->section_groups)
22938 {
22939 size_t i;
22940 struct group_list * g;
22941 struct group_list * next;
22942
22943 for (i = 0; i < filedata->group_count; i++)
22944 {
22945 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22946 {
22947 next = g->next;
22948 free (g);
22949 }
22950 }
22951
22952 free (filedata->section_groups);
13acb58d 22953 }
066f8fbe
AM
22954 memset (&filedata->section_headers, 0,
22955 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22956}
22957
dda8d76d
NC
22958static void
22959close_file (Filedata * filedata)
22960{
22961 if (filedata)
22962 {
22963 if (filedata->handle)
22964 fclose (filedata->handle);
22965 free (filedata);
22966 }
22967}
22968
22969void
22970close_debug_file (void * data)
22971{
13acb58d 22972 free_filedata ((Filedata *) data);
dda8d76d
NC
22973 close_file ((Filedata *) data);
22974}
22975
22976static Filedata *
015dc7e1 22977open_file (const char * pathname, bool is_separate)
dda8d76d
NC
22978{
22979 struct stat statbuf;
22980 Filedata * filedata = NULL;
22981
22982 if (stat (pathname, & statbuf) < 0
22983 || ! S_ISREG (statbuf.st_mode))
22984 goto fail;
22985
22986 filedata = calloc (1, sizeof * filedata);
22987 if (filedata == NULL)
22988 goto fail;
22989
22990 filedata->handle = fopen (pathname, "rb");
22991 if (filedata->handle == NULL)
22992 goto fail;
22993
be7d229a 22994 filedata->file_size = statbuf.st_size;
dda8d76d 22995 filedata->file_name = pathname;
ca0e11aa 22996 filedata->is_separate = is_separate;
dda8d76d
NC
22997
22998 if (! get_file_header (filedata))
22999 goto fail;
23000
4de91c10
AM
23001 if (!get_section_headers (filedata, false))
23002 goto fail;
dda8d76d
NC
23003
23004 return filedata;
23005
23006 fail:
23007 if (filedata)
23008 {
23009 if (filedata->handle)
23010 fclose (filedata->handle);
23011 free (filedata);
23012 }
23013 return NULL;
23014}
23015
23016void *
23017open_debug_file (const char * pathname)
23018{
015dc7e1 23019 return open_file (pathname, true);
dda8d76d
NC
23020}
23021
835f2fae
NC
23022static void
23023initialise_dump_sects (Filedata * filedata)
23024{
23025 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23026 Note we do this even if cmdline_dump_sects is empty because we
23027 must make sure that the dump_sets array is zeroed out before each
23028 object file is processed. */
23029 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23030 memset (filedata->dump.dump_sects, 0,
23031 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23032
23033 if (cmdline.num_dump_sects > 0)
23034 {
23035 if (filedata->dump.num_dump_sects == 0)
23036 /* A sneaky way of allocating the dump_sects array. */
23037 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23038
23039 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23040 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23041 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23042 }
23043}
23044
94585d6d
NC
23045static bool
23046might_need_separate_debug_info (Filedata * filedata)
23047{
23048 /* Debuginfo files do not need further separate file loading. */
23049 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23050 return false;
23051
23052 /* Since do_follow_links might be enabled by default, only treat it as an
23053 indication that separate files should be loaded if setting it was a
23054 deliberate user action. */
23055 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23056 return true;
23057
23058 if (process_links || do_syms || do_unwind
23059 || dump_any_debugging || do_dump || do_debugging)
23060 return true;
23061
23062 return false;
23063}
23064
fb52b2f4
NC
23065/* Process one ELF object file according to the command line options.
23066 This file may actually be stored in an archive. The file is
32ec8896
NC
23067 positioned at the start of the ELF object. Returns TRUE if no
23068 problems were encountered, FALSE otherwise. */
fb52b2f4 23069
015dc7e1 23070static bool
dda8d76d 23071process_object (Filedata * filedata)
252b5132 23072{
015dc7e1 23073 bool have_separate_files;
252b5132 23074 unsigned int i;
015dc7e1 23075 bool res;
252b5132 23076
dda8d76d 23077 if (! get_file_header (filedata))
252b5132 23078 {
dda8d76d 23079 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23080 return false;
252b5132
RH
23081 }
23082
23083 /* Initialise per file variables. */
978c4450
AM
23084 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23085 filedata->version_info[i] = 0;
252b5132 23086
978c4450
AM
23087 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23088 filedata->dynamic_info[i] = 0;
23089 filedata->dynamic_info_DT_GNU_HASH = 0;
23090 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23091
23092 /* Process the file. */
23093 if (show_name)
dda8d76d 23094 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23095
835f2fae 23096 initialise_dump_sects (filedata);
d70c5fc7 23097
4de91c10
AM
23098 /* There may be some extensions in the first section header. Don't
23099 bomb if we can't read it. */
23100 get_section_headers (filedata, true);
23101
dda8d76d 23102 if (! process_file_header (filedata))
4de91c10
AM
23103 {
23104 res = false;
23105 goto out;
23106 }
252b5132 23107
e331b18d
AM
23108 /* Throw away the single section header read above, so that we
23109 re-read the entire set. */
23110 free (filedata->section_headers);
23111 filedata->section_headers = NULL;
23112
dda8d76d 23113 if (! process_section_headers (filedata))
2f62977e 23114 {
32ec8896 23115 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23116 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23117
2f62977e 23118 if (! do_using_dynamic)
015dc7e1 23119 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23120 }
252b5132 23121
dda8d76d 23122 if (! process_section_groups (filedata))
32ec8896 23123 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23124 do_unwind = false;
d1f5c6e3 23125
93df3340
AM
23126 process_program_headers (filedata);
23127
23128 res = process_dynamic_section (filedata);
252b5132 23129
dda8d76d 23130 if (! process_relocs (filedata))
015dc7e1 23131 res = false;
252b5132 23132
dda8d76d 23133 if (! process_unwind (filedata))
015dc7e1 23134 res = false;
4d6ed7c8 23135
dda8d76d 23136 if (! process_symbol_table (filedata))
015dc7e1 23137 res = false;
252b5132 23138
0f03783c 23139 if (! process_lto_symbol_tables (filedata))
015dc7e1 23140 res = false;
b9e920ec 23141
dda8d76d 23142 if (! process_syminfo (filedata))
015dc7e1 23143 res = false;
252b5132 23144
dda8d76d 23145 if (! process_version_sections (filedata))
015dc7e1 23146 res = false;
252b5132 23147
94585d6d 23148 if (might_need_separate_debug_info (filedata))
24841daa 23149 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23150 else
015dc7e1 23151 have_separate_files = false;
dda8d76d
NC
23152
23153 if (! process_section_contents (filedata))
015dc7e1 23154 res = false;
f5842774 23155
24841daa 23156 if (have_separate_files)
dda8d76d 23157 {
24841daa
NC
23158 separate_info * d;
23159
23160 for (d = first_separate_info; d != NULL; d = d->next)
23161 {
835f2fae
NC
23162 initialise_dump_sects (d->handle);
23163
ca0e11aa 23164 if (process_links && ! process_file_header (d->handle))
015dc7e1 23165 res = false;
ca0e11aa 23166 else if (! process_section_headers (d->handle))
015dc7e1 23167 res = false;
d6bfbc39 23168 else if (! process_section_contents (d->handle))
015dc7e1 23169 res = false;
ca0e11aa
NC
23170 else if (process_links)
23171 {
ca0e11aa 23172 if (! process_section_groups (d->handle))
015dc7e1 23173 res = false;
93df3340 23174 process_program_headers (d->handle);
ca0e11aa 23175 if (! process_dynamic_section (d->handle))
015dc7e1 23176 res = false;
ca0e11aa 23177 if (! process_relocs (d->handle))
015dc7e1 23178 res = false;
ca0e11aa 23179 if (! process_unwind (d->handle))
015dc7e1 23180 res = false;
ca0e11aa 23181 if (! process_symbol_table (d->handle))
015dc7e1 23182 res = false;
ca0e11aa 23183 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23184 res = false;
ca0e11aa 23185 if (! process_syminfo (d->handle))
015dc7e1 23186 res = false;
ca0e11aa 23187 if (! process_version_sections (d->handle))
015dc7e1 23188 res = false;
ca0e11aa 23189 if (! process_notes (d->handle))
015dc7e1 23190 res = false;
ca0e11aa 23191 }
24841daa
NC
23192 }
23193
23194 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23195 }
23196
23197 if (! process_notes (filedata))
015dc7e1 23198 res = false;
103f02d3 23199
dda8d76d 23200 if (! process_gnu_liblist (filedata))
015dc7e1 23201 res = false;
047b2264 23202
dda8d76d 23203 if (! process_arch_specific (filedata))
015dc7e1 23204 res = false;
252b5132 23205
4de91c10 23206 out:
13acb58d 23207 free_filedata (filedata);
e4b17d5c 23208
19e6b90e 23209 free_debug_memory ();
18bd398b 23210
32ec8896 23211 return res;
252b5132
RH
23212}
23213
2cf0635d 23214/* Process an ELF archive.
32ec8896
NC
23215 On entry the file is positioned just after the ARMAG string.
23216 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23217
015dc7e1
AM
23218static bool
23219process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23220{
23221 struct archive_info arch;
23222 struct archive_info nested_arch;
23223 size_t got;
015dc7e1 23224 bool ret = true;
2cf0635d 23225
015dc7e1 23226 show_name = true;
2cf0635d
NC
23227
23228 /* The ARCH structure is used to hold information about this archive. */
23229 arch.file_name = NULL;
23230 arch.file = NULL;
23231 arch.index_array = NULL;
23232 arch.sym_table = NULL;
23233 arch.longnames = NULL;
23234
23235 /* The NESTED_ARCH structure is used as a single-item cache of information
23236 about a nested archive (when members of a thin archive reside within
23237 another regular archive file). */
23238 nested_arch.file_name = NULL;
23239 nested_arch.file = NULL;
23240 nested_arch.index_array = NULL;
23241 nested_arch.sym_table = NULL;
23242 nested_arch.longnames = NULL;
23243
dda8d76d 23244 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23245 filedata->file_size, is_thin_archive,
23246 do_archive_index) != 0)
2cf0635d 23247 {
015dc7e1 23248 ret = false;
2cf0635d 23249 goto out;
4145f1d5 23250 }
fb52b2f4 23251
4145f1d5
NC
23252 if (do_archive_index)
23253 {
2cf0635d 23254 if (arch.sym_table == NULL)
1cb7d8b1
AM
23255 error (_("%s: unable to dump the index as none was found\n"),
23256 filedata->file_name);
4145f1d5
NC
23257 else
23258 {
26c527e6
AM
23259 uint64_t i, l;
23260 uint64_t current_pos;
4145f1d5 23261
26c527e6
AM
23262 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23263 " %#" PRIx64 " bytes in the symbol table)\n"),
23264 filedata->file_name, arch.index_num,
1cb7d8b1 23265 arch.sym_size);
dda8d76d
NC
23266
23267 current_pos = ftell (filedata->handle);
4145f1d5 23268
2cf0635d 23269 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23270 {
1cb7d8b1
AM
23271 if (i == 0
23272 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23273 {
23274 char * member_name
23275 = get_archive_member_name_at (&arch, arch.index_array[i],
23276 &nested_arch);
2cf0635d 23277
1cb7d8b1
AM
23278 if (member_name != NULL)
23279 {
23280 char * qualified_name
23281 = make_qualified_name (&arch, &nested_arch,
23282 member_name);
2cf0635d 23283
1cb7d8b1
AM
23284 if (qualified_name != NULL)
23285 {
23286 printf (_("Contents of binary %s at offset "),
23287 qualified_name);
c2a7d3f5
NC
23288 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23289 putchar ('\n');
1cb7d8b1
AM
23290 free (qualified_name);
23291 }
fd486f32 23292 free (member_name);
4145f1d5
NC
23293 }
23294 }
2cf0635d
NC
23295
23296 if (l >= arch.sym_size)
4145f1d5 23297 {
1cb7d8b1
AM
23298 error (_("%s: end of the symbol table reached "
23299 "before the end of the index\n"),
dda8d76d 23300 filedata->file_name);
015dc7e1 23301 ret = false;
cb8f3167 23302 break;
4145f1d5 23303 }
591f7597 23304 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23305 printf ("\t%.*s\n",
23306 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23307 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23308 }
23309
67ce483b 23310 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23311 l = (l + 7) & ~ 7;
23312 else
23313 l += l & 1;
23314
2cf0635d 23315 if (l < arch.sym_size)
32ec8896 23316 {
26c527e6 23317 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23318 "but without corresponding entries in "
23319 "the index table\n",
26c527e6 23320 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23321 "but without corresponding entries in "
23322 "the index table\n",
23323 arch.sym_size - l),
dda8d76d 23324 filedata->file_name, arch.sym_size - l);
015dc7e1 23325 ret = false;
32ec8896 23326 }
4145f1d5 23327
63cf857e 23328 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23329 {
1cb7d8b1
AM
23330 error (_("%s: failed to seek back to start of object files "
23331 "in the archive\n"),
dda8d76d 23332 filedata->file_name);
015dc7e1 23333 ret = false;
2cf0635d 23334 goto out;
4145f1d5 23335 }
fb52b2f4 23336 }
4145f1d5
NC
23337
23338 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23339 && !do_segments && !do_header && !do_dump && !do_version
23340 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23341 && !do_section_groups && !do_dyn_syms)
2cf0635d 23342 {
015dc7e1 23343 ret = true; /* Archive index only. */
2cf0635d
NC
23344 goto out;
23345 }
fb52b2f4
NC
23346 }
23347
fb52b2f4
NC
23348 while (1)
23349 {
2cf0635d
NC
23350 char * name;
23351 size_t namelen;
23352 char * qualified_name;
23353
23354 /* Read the next archive header. */
63cf857e 23355 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23356 {
23357 error (_("%s: failed to seek to next archive header\n"),
23358 arch.file_name);
015dc7e1 23359 ret = false;
1cb7d8b1
AM
23360 break;
23361 }
dda8d76d 23362 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23363 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23364 {
23365 if (got == 0)
2cf0635d 23366 break;
28e817cc
NC
23367 /* PR 24049 - we cannot use filedata->file_name as this will
23368 have already been freed. */
23369 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23370
015dc7e1 23371 ret = false;
1cb7d8b1
AM
23372 break;
23373 }
2cf0635d 23374 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23375 {
23376 error (_("%s: did not find a valid archive header\n"),
23377 arch.file_name);
015dc7e1 23378 ret = false;
1cb7d8b1
AM
23379 break;
23380 }
2cf0635d
NC
23381
23382 arch.next_arhdr_offset += sizeof arch.arhdr;
23383
978c4450 23384 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23385
23386 name = get_archive_member_name (&arch, &nested_arch);
23387 if (name == NULL)
fb52b2f4 23388 {
28e817cc 23389 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23390 ret = false;
d989285c 23391 break;
fb52b2f4 23392 }
2cf0635d 23393 namelen = strlen (name);
fb52b2f4 23394
2cf0635d
NC
23395 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23396 if (qualified_name == NULL)
fb52b2f4 23397 {
28e817cc 23398 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23399 free (name);
015dc7e1 23400 ret = false;
d989285c 23401 break;
fb52b2f4
NC
23402 }
23403
2cf0635d 23404 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23405 {
23406 /* This is a proxy for an external member of a thin archive. */
23407 Filedata * member_filedata;
23408 char * member_file_name = adjust_relative_path
dda8d76d 23409 (filedata->file_name, name, namelen);
32ec8896 23410
fd486f32 23411 free (name);
1cb7d8b1
AM
23412 if (member_file_name == NULL)
23413 {
fd486f32 23414 free (qualified_name);
015dc7e1 23415 ret = false;
1cb7d8b1
AM
23416 break;
23417 }
2cf0635d 23418
015dc7e1 23419 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23420 if (member_filedata == NULL)
23421 {
23422 error (_("Input file '%s' is not readable.\n"), member_file_name);
23423 free (member_file_name);
fd486f32 23424 free (qualified_name);
015dc7e1 23425 ret = false;
1cb7d8b1
AM
23426 break;
23427 }
2cf0635d 23428
978c4450 23429 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23430 member_filedata->file_name = qualified_name;
2cf0635d 23431
75a2da57
AH
23432 /* The call to process_object() expects the file to be at the beginning. */
23433 rewind (member_filedata->handle);
23434
1cb7d8b1 23435 if (! process_object (member_filedata))
015dc7e1 23436 ret = false;
2cf0635d 23437
1cb7d8b1
AM
23438 close_file (member_filedata);
23439 free (member_file_name);
1cb7d8b1 23440 }
2cf0635d 23441 else if (is_thin_archive)
1cb7d8b1
AM
23442 {
23443 Filedata thin_filedata;
eb02c04d 23444
1cb7d8b1 23445 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23446
a043396b
NC
23447 /* PR 15140: Allow for corrupt thin archives. */
23448 if (nested_arch.file == NULL)
23449 {
23450 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23451 qualified_name, name);
fd486f32
AM
23452 free (qualified_name);
23453 free (name);
015dc7e1 23454 ret = false;
a043396b
NC
23455 break;
23456 }
fd486f32 23457 free (name);
a043396b 23458
1cb7d8b1 23459 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23460 filedata->archive_file_offset
23461 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23462
1cb7d8b1
AM
23463 /* The nested archive file will have been opened and setup by
23464 get_archive_member_name. */
63cf857e
AM
23465 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23466 SEEK_SET) != 0)
1cb7d8b1
AM
23467 {
23468 error (_("%s: failed to seek to archive member.\n"),
23469 nested_arch.file_name);
fd486f32 23470 free (qualified_name);
015dc7e1 23471 ret = false;
1cb7d8b1
AM
23472 break;
23473 }
2cf0635d 23474
dda8d76d
NC
23475 thin_filedata.handle = nested_arch.file;
23476 thin_filedata.file_name = qualified_name;
9abca702 23477
1cb7d8b1 23478 if (! process_object (& thin_filedata))
015dc7e1 23479 ret = false;
1cb7d8b1 23480 }
2cf0635d 23481 else
1cb7d8b1 23482 {
fd486f32 23483 free (name);
978c4450 23484 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23485 filedata->file_name = qualified_name;
1cb7d8b1 23486 if (! process_object (filedata))
015dc7e1 23487 ret = false;
237877b8 23488 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23489 /* Stop looping with "negative" archive_file_size. */
978c4450 23490 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23491 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23492 }
fb52b2f4 23493
2cf0635d 23494 free (qualified_name);
fb52b2f4
NC
23495 }
23496
4145f1d5 23497 out:
2cf0635d
NC
23498 if (nested_arch.file != NULL)
23499 fclose (nested_arch.file);
23500 release_archive (&nested_arch);
23501 release_archive (&arch);
fb52b2f4 23502
d989285c 23503 return ret;
fb52b2f4
NC
23504}
23505
015dc7e1 23506static bool
2cf0635d 23507process_file (char * file_name)
fb52b2f4 23508{
dda8d76d 23509 Filedata * filedata = NULL;
fb52b2f4
NC
23510 struct stat statbuf;
23511 char armag[SARMAG];
015dc7e1 23512 bool ret = true;
fb52b2f4
NC
23513
23514 if (stat (file_name, &statbuf) < 0)
23515 {
f24ddbdd
NC
23516 if (errno == ENOENT)
23517 error (_("'%s': No such file\n"), file_name);
23518 else
23519 error (_("Could not locate '%s'. System error message: %s\n"),
23520 file_name, strerror (errno));
015dc7e1 23521 return false;
f24ddbdd
NC
23522 }
23523
23524 if (! S_ISREG (statbuf.st_mode))
23525 {
23526 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23527 return false;
fb52b2f4
NC
23528 }
23529
dda8d76d
NC
23530 filedata = calloc (1, sizeof * filedata);
23531 if (filedata == NULL)
23532 {
23533 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23534 return false;
dda8d76d
NC
23535 }
23536
23537 filedata->file_name = file_name;
23538 filedata->handle = fopen (file_name, "rb");
23539 if (filedata->handle == NULL)
fb52b2f4 23540 {
f24ddbdd 23541 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23542 free (filedata);
015dc7e1 23543 return false;
fb52b2f4
NC
23544 }
23545
dda8d76d 23546 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23547 {
4145f1d5 23548 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23549 fclose (filedata->handle);
23550 free (filedata);
015dc7e1 23551 return false;
fb52b2f4
NC
23552 }
23553
be7d229a 23554 filedata->file_size = statbuf.st_size;
015dc7e1 23555 filedata->is_separate = false;
f54498b4 23556
fb52b2f4 23557 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23558 {
015dc7e1
AM
23559 if (! process_archive (filedata, false))
23560 ret = false;
32ec8896 23561 }
2cf0635d 23562 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23563 {
015dc7e1
AM
23564 if ( ! process_archive (filedata, true))
23565 ret = false;
32ec8896 23566 }
fb52b2f4
NC
23567 else
23568 {
1b513401 23569 if (do_archive_index && !check_all)
4145f1d5
NC
23570 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23571 file_name);
23572
dda8d76d 23573 rewind (filedata->handle);
978c4450 23574 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23575
dda8d76d 23576 if (! process_object (filedata))
015dc7e1 23577 ret = false;
fb52b2f4
NC
23578 }
23579
dda8d76d 23580 fclose (filedata->handle);
8fb879cd
AM
23581 free (filedata->section_headers);
23582 free (filedata->program_headers);
23583 free (filedata->string_table);
6431e409 23584 free (filedata->dump.dump_sects);
dda8d76d 23585 free (filedata);
32ec8896 23586
fd486f32 23587 free (ba_cache.strtab);
1bd6175a 23588 ba_cache.strtab = NULL;
fd486f32 23589 free (ba_cache.symtab);
1bd6175a 23590 ba_cache.symtab = NULL;
fd486f32
AM
23591 ba_cache.filedata = NULL;
23592
fb52b2f4
NC
23593 return ret;
23594}
23595
252b5132
RH
23596#ifdef SUPPORT_DISASSEMBLY
23597/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23598 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23599 symbols. */
252b5132
RH
23600
23601void
2cf0635d 23602print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23603{
23604 fprintf (outfile,"0x%8.8x", addr);
23605}
23606
e3c8793a 23607/* Needed by the i386 disassembler. */
dda8d76d 23608
252b5132
RH
23609void
23610db_task_printsym (unsigned int addr)
23611{
23612 print_address (addr, stderr);
23613}
23614#endif
23615
23616int
2cf0635d 23617main (int argc, char ** argv)
252b5132 23618{
ff78d6d6
L
23619 int err;
23620
87b9f255 23621#ifdef HAVE_LC_MESSAGES
252b5132 23622 setlocale (LC_MESSAGES, "");
3882b010 23623#endif
3882b010 23624 setlocale (LC_CTYPE, "");
252b5132
RH
23625 bindtextdomain (PACKAGE, LOCALEDIR);
23626 textdomain (PACKAGE);
23627
869b9d07
MM
23628 expandargv (&argc, &argv);
23629
dda8d76d 23630 parse_args (& cmdline, argc, argv);
59f14fc0 23631
18bd398b 23632 if (optind < (argc - 1))
1b513401
NC
23633 /* When displaying information for more than one file,
23634 prefix the information with the file name. */
015dc7e1 23635 show_name = true;
5656ba2c
L
23636 else if (optind >= argc)
23637 {
1b513401 23638 /* Ensure that the warning is always displayed. */
015dc7e1 23639 do_checks = true;
1b513401 23640
5656ba2c
L
23641 warn (_("Nothing to do.\n"));
23642 usage (stderr);
23643 }
18bd398b 23644
015dc7e1 23645 err = false;
252b5132 23646 while (optind < argc)
32ec8896 23647 if (! process_file (argv[optind++]))
015dc7e1 23648 err = true;
252b5132 23649
9db70fc3 23650 free (cmdline.dump_sects);
252b5132 23651
7d9813f1
NA
23652 free (dump_ctf_symtab_name);
23653 free (dump_ctf_strtab_name);
23654 free (dump_ctf_parent_name);
23655
32ec8896 23656 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23657}