]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Correct formatting errors in elf32-microblaze.c
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
d87bef3a 2 Copyright (C) 1998-2023 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")
4555 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4556 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4557 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4558 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4559 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4560 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4561 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4562 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4563 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4564 default:
f8c4789c 4565 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4566 break;
4567#undef AMDGPU_CASE
4568 }
4569
c077c580
SM
4570 e_flags &= ~EF_AMDGPU_MACH;
4571
4572 if ((osabi == ELFOSABI_AMDGPU_HSA
4573 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4574 || osabi != ELFOSABI_AMDGPU_HSA)
4575 {
4576 /* For HSA v3 and other OS ABIs. */
4577 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4578 {
f8c4789c 4579 out = stpcpy (out, ", xnack on");
c077c580
SM
4580 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4581 }
4582
4583 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4584 {
f8c4789c 4585 out = stpcpy (out, ", sramecc on");
c077c580
SM
4586 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4587 }
4588 }
4589 else
4590 {
4591 /* For HSA v4+. */
4592 int xnack, sramecc;
4593
4594 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4595 switch (xnack)
4596 {
4597 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4598 break;
4599
4600 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4601 out = stpcpy (out, ", xnack any");
c077c580
SM
4602 break;
4603
4604 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4605 out = stpcpy (out, ", xnack off");
c077c580
SM
4606 break;
4607
4608 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4609 out = stpcpy (out, ", xnack on");
c077c580
SM
4610 break;
4611
4612 default:
f8c4789c 4613 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4614 break;
4615 }
4616
c077c580
SM
4617 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4618
4619 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4620 switch (sramecc)
4621 {
4622 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4623 break;
4624
4625 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4626 out = stpcpy (out, ", sramecc any");
c077c580
SM
4627 break;
4628
4629 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4630 out = stpcpy (out, ", sramecc off");
c077c580
SM
4631 break;
4632
4633 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4634 out = stpcpy (out, ", sramecc on");
c077c580
SM
4635 break;
4636
4637 default:
f8c4789c 4638 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4639 break;
4640 }
4641
c077c580
SM
4642 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4643 }
4644
4645 if (e_flags != 0)
f8c4789c
AM
4646 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4647 return out;
c077c580
SM
4648}
4649
252b5132 4650static char *
dda8d76d 4651get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4652{
b34976b6 4653 static char buf[1024];
f8c4789c 4654 char *out = buf;
252b5132
RH
4655
4656 buf[0] = '\0';
76da6bbe 4657
252b5132
RH
4658 if (e_flags)
4659 {
4660 switch (e_machine)
4661 {
4662 default:
4663 break;
4664
b5c37946 4665 case EM_ARC_COMPACT3:
f8c4789c 4666 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4667 break;
4668
4669 case EM_ARC_COMPACT3_64:
f8c4789c 4670 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4671 break;
4672
886a2506 4673 case EM_ARC_COMPACT2:
886a2506 4674 case EM_ARC_COMPACT:
f8c4789c
AM
4675 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4676 break;
886a2506 4677
f3485b74 4678 case EM_ARM:
f8c4789c 4679 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4680 break;
76da6bbe 4681
f8c4789c
AM
4682 case EM_AVR:
4683 out = decode_AVR_machine_flags (out, e_flags);
4684 break;
343433df 4685
781303ce 4686 case EM_BLACKFIN:
f8c4789c 4687 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4688 break;
4689
ec2dfb42 4690 case EM_CYGNUS_FRV:
f8c4789c 4691 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4692 break;
ec2dfb42 4693
53c7db4b 4694 case EM_68K:
f8c4789c 4695 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4696 break;
33c63f9d 4697
c077c580 4698 case EM_AMDGPU:
f8c4789c 4699 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4700 break;
4701
153a2776 4702 case EM_CYGNUS_MEP:
f8c4789c 4703 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4704 break;
4705
252b5132
RH
4706 case EM_PPC:
4707 if (e_flags & EF_PPC_EMB)
f8c4789c 4708 out = stpcpy (out, ", emb");
252b5132
RH
4709
4710 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4711 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4712
4713 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4714 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4715 break;
4716
ee67d69a
AM
4717 case EM_PPC64:
4718 if (e_flags & EF_PPC64_ABI)
f8c4789c 4719 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4720 break;
4721
708e2187 4722 case EM_V800:
f8c4789c 4723 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4724 break;
4725
2b0337b0 4726 case EM_V850:
252b5132 4727 case EM_CYGNUS_V850:
f8c4789c 4728 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4729 break;
4730
2b0337b0 4731 case EM_M32R:
252b5132
RH
4732 case EM_CYGNUS_M32R:
4733 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4734 out = stpcpy (out, ", m32r");
252b5132
RH
4735 break;
4736
4737 case EM_MIPS:
4fe85591 4738 case EM_MIPS_RS3_LE:
f8c4789c 4739 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4740 break;
351b4b40 4741
35c08157 4742 case EM_NDS32:
f8c4789c 4743 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4744 break;
4745
fe944acf
FT
4746 case EM_NFP:
4747 switch (EF_NFP_MACH (e_flags))
4748 {
4749 case E_NFP_MACH_3200:
f8c4789c 4750 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4751 break;
4752 case E_NFP_MACH_6000:
f8c4789c 4753 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4754 break;
4755 }
4756 break;
4757
e23eba97 4758 case EM_RISCV:
f8c4789c 4759 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4760 break;
4761
ccde1100 4762 case EM_SH:
f8c4789c 4763 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4764 break;
948f632f 4765
f8c4789c
AM
4766 case EM_OR1K:
4767 if (e_flags & EF_OR1K_NODELAY)
4768 out = stpcpy (out, ", no delay");
4769 break;
57346661 4770
f8c4789c
AM
4771 case EM_BPF:
4772 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4773 break;
b5c37946 4774
351b4b40 4775 case EM_SPARCV9:
f8c4789c 4776 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4777 break;
7d466069 4778
103f02d3 4779 case EM_PARISC:
f8c4789c 4780 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4781 break;
76da6bbe 4782
7d466069 4783 case EM_PJ:
2b0337b0 4784 case EM_PJ_OLD:
7d466069 4785 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4786 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4787
4788 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4789 out = stpcpy (out, ", gnu calling convention");
7d466069 4790 break;
4d6ed7c8
NC
4791
4792 case EM_IA_64:
f8c4789c 4793 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4794 break;
179d3252
JT
4795
4796 case EM_VAX:
4797 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4798 out = stpcpy (out, ", non-PIC");
179d3252 4799 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4800 out = stpcpy (out, ", D-Float");
179d3252 4801 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4802 out = stpcpy (out, ", G-Float");
179d3252 4803 break;
c7927a3c 4804
f8c4789c 4805 case EM_VISIUM:
619ed720 4806 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4807 out = stpcpy (out, ", mcm");
619ed720 4808 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4809 out = stpcpy (out, ", mcm24");
619ed720 4810 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4811 out = stpcpy (out, ", gr6");
619ed720
EB
4812 break;
4813
4046d87a 4814 case EM_RL78:
f8c4789c 4815 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4816 break;
0b4362b0 4817
c7927a3c 4818 case EM_RX:
f8c4789c 4819 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4820 break;
55786da2
AK
4821
4822 case EM_S390:
4823 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4824 out = stpcpy (out, ", highgprs");
d4cb0ea0 4825 break;
40b36596
JM
4826
4827 case EM_TI_C6000:
4828 if ((e_flags & EF_C6000_REL))
f8c4789c 4829 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4830 break;
13761a11 4831
6e712424
PI
4832 case EM_KVX:
4833 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4834 strcat (buf, ", Kalray VLIW kv3-1");
4835 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4836 strcat (buf, ", Kalray VLIW kv3-2");
4837 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4838 strcat (buf, ", Kalray VLIW kv4-1");
4839 else
4840 strcat (buf, ", unknown KVX MPPA");
4841 break;
4842
13761a11 4843 case EM_MSP430:
f8c4789c 4844 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4845 break;
4846
4847 case EM_Z80:
f8c4789c 4848 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4849 break;
c4a7e6b5 4850
f8c4789c
AM
4851 case EM_LOONGARCH:
4852 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4853 break;
252b5132
RH
4854 }
4855 }
4856
4857 return buf;
4858}
4859
252b5132 4860static const char *
dda8d76d 4861get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4862{
4863 static char buff[32];
4864
4865 switch (osabi)
4866 {
4867 case ELFOSABI_NONE: return "UNIX - System V";
4868 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4869 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4870 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4871 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4872 case ELFOSABI_AIX: return "UNIX - AIX";
4873 case ELFOSABI_IRIX: return "UNIX - IRIX";
4874 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4875 case ELFOSABI_TRU64: return "UNIX - TRU64";
4876 case ELFOSABI_MODESTO: return "Novell - Modesto";
4877 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4878 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4879 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4880 case ELFOSABI_AROS: return "AROS";
11636f9e 4881 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4882 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4883 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4884 default:
40b36596 4885 if (osabi >= 64)
dda8d76d 4886 switch (filedata->file_header.e_machine)
40b36596 4887 {
37870be8
SM
4888 case EM_AMDGPU:
4889 switch (osabi)
4890 {
4891 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4892 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4893 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4894 default:
4895 break;
4896 }
4897 break;
4898
40b36596
JM
4899 case EM_ARM:
4900 switch (osabi)
4901 {
4902 case ELFOSABI_ARM: return "ARM";
18a20338 4903 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4904 default:
4905 break;
4906 }
4907 break;
4908
4909 case EM_MSP430:
4910 case EM_MSP430_OLD:
619ed720 4911 case EM_VISIUM:
40b36596
JM
4912 switch (osabi)
4913 {
4914 case ELFOSABI_STANDALONE: return _("Standalone App");
4915 default:
4916 break;
4917 }
4918 break;
4919
4920 case EM_TI_C6000:
4921 switch (osabi)
4922 {
4923 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4924 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4925 default:
4926 break;
4927 }
4928 break;
4929
4930 default:
4931 break;
4932 }
e9e44622 4933 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4934 return buff;
4935 }
4936}
4937
a06ea964
NC
4938static const char *
4939get_aarch64_segment_type (unsigned long type)
4940{
4941 switch (type)
4942 {
32ec8896 4943 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4944 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4945 default: return NULL;
a06ea964 4946 }
a06ea964
NC
4947}
4948
b294bdf8
MM
4949static const char *
4950get_arm_segment_type (unsigned long type)
4951{
4952 switch (type)
4953 {
32ec8896
NC
4954 case PT_ARM_EXIDX: return "EXIDX";
4955 default: return NULL;
b294bdf8 4956 }
b294bdf8
MM
4957}
4958
b4cbbe8f
AK
4959static const char *
4960get_s390_segment_type (unsigned long type)
4961{
4962 switch (type)
4963 {
4964 case PT_S390_PGSTE: return "S390_PGSTE";
4965 default: return NULL;
4966 }
4967}
4968
d3ba0551
AM
4969static const char *
4970get_mips_segment_type (unsigned long type)
252b5132
RH
4971{
4972 switch (type)
4973 {
32ec8896
NC
4974 case PT_MIPS_REGINFO: return "REGINFO";
4975 case PT_MIPS_RTPROC: return "RTPROC";
4976 case PT_MIPS_OPTIONS: return "OPTIONS";
4977 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4978 default: return NULL;
252b5132 4979 }
252b5132
RH
4980}
4981
103f02d3 4982static const char *
d3ba0551 4983get_parisc_segment_type (unsigned long type)
103f02d3
UD
4984{
4985 switch (type)
4986 {
103f02d3
UD
4987 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4988 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4989 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4990 default: return NULL;
103f02d3 4991 }
103f02d3
UD
4992}
4993
4d6ed7c8 4994static const char *
d3ba0551 4995get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4996{
4997 switch (type)
4998 {
4999 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5000 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5001 default: return NULL;
4d6ed7c8 5002 }
4d6ed7c8
NC
5003}
5004
40b36596
JM
5005static const char *
5006get_tic6x_segment_type (unsigned long type)
5007{
5008 switch (type)
5009 {
32ec8896
NC
5010 case PT_C6000_PHATTR: return "C6000_PHATTR";
5011 default: return NULL;
40b36596 5012 }
40b36596
JM
5013}
5014
fbc95f1e
KC
5015static const char *
5016get_riscv_segment_type (unsigned long type)
5017{
5018 switch (type)
5019 {
5020 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5021 default: return NULL;
5022 }
5023}
5024
df3a023b
AM
5025static const char *
5026get_hpux_segment_type (unsigned long type, unsigned e_machine)
5027{
5028 if (e_machine == EM_PARISC)
5029 switch (type)
5030 {
5031 case PT_HP_TLS: return "HP_TLS";
5032 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5033 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5034 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5035 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5036 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5037 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5038 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5039 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5040 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5041 case PT_HP_PARALLEL: return "HP_PARALLEL";
5042 case PT_HP_FASTBIND: return "HP_FASTBIND";
5043 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5044 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5045 case PT_HP_STACK: return "HP_STACK";
5046 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5047 default: return NULL;
5048 }
5049
5050 if (e_machine == EM_IA_64)
5051 switch (type)
5052 {
5053 case PT_HP_TLS: return "HP_TLS";
5054 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5055 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5056 case PT_IA_64_HP_STACK: return "HP_STACK";
5057 default: return NULL;
5058 }
5059
5060 return NULL;
5061}
5062
5522f910
NC
5063static const char *
5064get_solaris_segment_type (unsigned long type)
5065{
5066 switch (type)
5067 {
5068 case 0x6464e550: return "PT_SUNW_UNWIND";
5069 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5070 case 0x6ffffff7: return "PT_LOSUNW";
5071 case 0x6ffffffa: return "PT_SUNWBSS";
5072 case 0x6ffffffb: return "PT_SUNWSTACK";
5073 case 0x6ffffffc: return "PT_SUNWDTRACE";
5074 case 0x6ffffffd: return "PT_SUNWCAP";
5075 case 0x6fffffff: return "PT_HISUNW";
32ec8896 5076 default: return NULL;
5522f910
NC
5077 }
5078}
5079
252b5132 5080static const char *
dda8d76d 5081get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5082{
b34976b6 5083 static char buff[32];
252b5132
RH
5084
5085 switch (p_type)
5086 {
b34976b6
AM
5087 case PT_NULL: return "NULL";
5088 case PT_LOAD: return "LOAD";
252b5132 5089 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5090 case PT_INTERP: return "INTERP";
5091 case PT_NOTE: return "NOTE";
5092 case PT_SHLIB: return "SHLIB";
5093 case PT_PHDR: return "PHDR";
13ae64f3 5094 case PT_TLS: return "TLS";
32ec8896 5095 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5096 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5097 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5098 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5099 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5100
80251d41 5101 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5102 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5103 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
73b22419 5104 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
3eba3ef3 5105 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5106
252b5132 5107 default:
df3a023b 5108 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5109 {
2cf0635d 5110 const char * result;
103f02d3 5111
dda8d76d 5112 switch (filedata->file_header.e_machine)
252b5132 5113 {
a06ea964
NC
5114 case EM_AARCH64:
5115 result = get_aarch64_segment_type (p_type);
5116 break;
b294bdf8
MM
5117 case EM_ARM:
5118 result = get_arm_segment_type (p_type);
5119 break;
252b5132 5120 case EM_MIPS:
4fe85591 5121 case EM_MIPS_RS3_LE:
252b5132
RH
5122 result = get_mips_segment_type (p_type);
5123 break;
103f02d3
UD
5124 case EM_PARISC:
5125 result = get_parisc_segment_type (p_type);
5126 break;
4d6ed7c8
NC
5127 case EM_IA_64:
5128 result = get_ia64_segment_type (p_type);
5129 break;
40b36596
JM
5130 case EM_TI_C6000:
5131 result = get_tic6x_segment_type (p_type);
5132 break;
b4cbbe8f
AK
5133 case EM_S390:
5134 case EM_S390_OLD:
5135 result = get_s390_segment_type (p_type);
5136 break;
fbc95f1e
KC
5137 case EM_RISCV:
5138 result = get_riscv_segment_type (p_type);
5139 break;
252b5132
RH
5140 default:
5141 result = NULL;
5142 break;
5143 }
103f02d3 5144
252b5132
RH
5145 if (result != NULL)
5146 return result;
103f02d3 5147
1a9ccd70 5148 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5149 }
5150 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5151 {
df3a023b 5152 const char * result = NULL;
103f02d3 5153
df3a023b 5154 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5155 {
df3a023b
AM
5156 case ELFOSABI_GNU:
5157 case ELFOSABI_FREEBSD:
5158 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5159 {
5160 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5161 result = buff;
5162 }
103f02d3 5163 break;
df3a023b
AM
5164 case ELFOSABI_HPUX:
5165 result = get_hpux_segment_type (p_type,
5166 filedata->file_header.e_machine);
5167 break;
5168 case ELFOSABI_SOLARIS:
5169 result = get_solaris_segment_type (p_type);
00428cca 5170 break;
103f02d3 5171 default:
103f02d3
UD
5172 break;
5173 }
103f02d3
UD
5174 if (result != NULL)
5175 return result;
5176
1a9ccd70 5177 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5178 }
252b5132 5179 else
e9e44622 5180 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5181
5182 return buff;
5183 }
5184}
5185
53a346d8
CZ
5186static const char *
5187get_arc_section_type_name (unsigned int sh_type)
5188{
5189 switch (sh_type)
5190 {
5191 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5192 default:
5193 break;
5194 }
5195 return NULL;
5196}
5197
252b5132 5198static const char *
d3ba0551 5199get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5200{
5201 switch (sh_type)
5202 {
b34976b6
AM
5203 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5204 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5205 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5206 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5207 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5208 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5209 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5210 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5211 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5212 case SHT_MIPS_RELD: return "MIPS_RELD";
5213 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5214 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5215 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5216 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5217 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5218 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5219 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5220 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5221 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5222 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5223 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5224 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5225 case SHT_MIPS_LINE: return "MIPS_LINE";
5226 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5227 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5228 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5229 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5230 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5231 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5232 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5233 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5234 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5235 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5236 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5237 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5238 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5239 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5240 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5241 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5242 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5243 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5244 default:
5245 break;
5246 }
5247 return NULL;
5248}
5249
103f02d3 5250static const char *
d3ba0551 5251get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5252{
5253 switch (sh_type)
5254 {
5255 case SHT_PARISC_EXT: return "PARISC_EXT";
5256 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5257 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5258 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5259 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5260 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5261 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5262 default: return NULL;
103f02d3 5263 }
103f02d3
UD
5264}
5265
4d6ed7c8 5266static const char *
dda8d76d 5267get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5268{
18bd398b 5269 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5270 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5271 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5272
4d6ed7c8
NC
5273 switch (sh_type)
5274 {
148b93f2
NC
5275 case SHT_IA_64_EXT: return "IA_64_EXT";
5276 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5277 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5278 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5279 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5280 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5281 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5282 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5283 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5284 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5285 default:
5286 break;
5287 }
5288 return NULL;
5289}
5290
d2b2c203
DJ
5291static const char *
5292get_x86_64_section_type_name (unsigned int sh_type)
5293{
5294 switch (sh_type)
5295 {
5296 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5297 default: return NULL;
d2b2c203 5298 }
d2b2c203
DJ
5299}
5300
a06ea964
NC
5301static const char *
5302get_aarch64_section_type_name (unsigned int sh_type)
5303{
5304 switch (sh_type)
5305 {
32ec8896
NC
5306 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5307 default: return NULL;
a06ea964 5308 }
a06ea964
NC
5309}
5310
40a18ebd
NC
5311static const char *
5312get_arm_section_type_name (unsigned int sh_type)
5313{
5314 switch (sh_type)
5315 {
7f6fed87
NC
5316 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5317 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5318 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5319 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5320 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5321 default: return NULL;
40a18ebd 5322 }
40a18ebd
NC
5323}
5324
40b36596
JM
5325static const char *
5326get_tic6x_section_type_name (unsigned int sh_type)
5327{
5328 switch (sh_type)
5329 {
32ec8896
NC
5330 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5331 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5332 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5333 case SHT_TI_ICODE: return "TI_ICODE";
5334 case SHT_TI_XREF: return "TI_XREF";
5335 case SHT_TI_HANDLER: return "TI_HANDLER";
5336 case SHT_TI_INITINFO: return "TI_INITINFO";
5337 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5338 default: return NULL;
40b36596 5339 }
40b36596
JM
5340}
5341
13761a11 5342static const char *
b0191216 5343get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5344{
5345 switch (sh_type)
5346 {
32ec8896
NC
5347 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5348 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5349 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5350 default: return NULL;
13761a11
NC
5351 }
5352}
5353
fe944acf
FT
5354static const char *
5355get_nfp_section_type_name (unsigned int sh_type)
5356{
5357 switch (sh_type)
5358 {
5359 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5360 case SHT_NFP_INITREG: return "NFP_INITREG";
5361 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5362 default: return NULL;
5363 }
5364}
5365
685080f2
NC
5366static const char *
5367get_v850_section_type_name (unsigned int sh_type)
5368{
5369 switch (sh_type)
5370 {
32ec8896
NC
5371 case SHT_V850_SCOMMON: return "V850 Small Common";
5372 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5373 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5374 case SHT_RENESAS_IOP: return "RENESAS IOP";
5375 case SHT_RENESAS_INFO: return "RENESAS INFO";
5376 default: return NULL;
685080f2
NC
5377 }
5378}
5379
2dc8dd17
JW
5380static const char *
5381get_riscv_section_type_name (unsigned int sh_type)
5382{
5383 switch (sh_type)
5384 {
5385 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5386 default: return NULL;
5387 }
5388}
5389
0861f561
CQ
5390static const char *
5391get_csky_section_type_name (unsigned int sh_type)
5392{
5393 switch (sh_type)
5394 {
5395 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5396 default: return NULL;
5397 }
5398}
5399
252b5132 5400static const char *
dda8d76d 5401get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5402{
b34976b6 5403 static char buff[32];
9fb71ee4 5404 const char * result;
252b5132
RH
5405
5406 switch (sh_type)
5407 {
5408 case SHT_NULL: return "NULL";
5409 case SHT_PROGBITS: return "PROGBITS";
5410 case SHT_SYMTAB: return "SYMTAB";
5411 case SHT_STRTAB: return "STRTAB";
5412 case SHT_RELA: return "RELA";
dd207c13 5413 case SHT_RELR: return "RELR";
252b5132
RH
5414 case SHT_HASH: return "HASH";
5415 case SHT_DYNAMIC: return "DYNAMIC";
5416 case SHT_NOTE: return "NOTE";
5417 case SHT_NOBITS: return "NOBITS";
5418 case SHT_REL: return "REL";
5419 case SHT_SHLIB: return "SHLIB";
5420 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
5421 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5422 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5423 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 5424 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 5425 case SHT_GROUP: return "GROUP";
67ce483b 5426 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
5427 case SHT_GNU_verdef: return "VERDEF";
5428 case SHT_GNU_verneed: return "VERNEED";
5429 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
5430 case 0x6ffffff0: return "VERSYM";
5431 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5432 case 0x7ffffffd: return "AUXILIARY";
5433 case 0x7fffffff: return "FILTER";
047b2264 5434 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
5435
5436 default:
5437 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5438 {
dda8d76d 5439 switch (filedata->file_header.e_machine)
252b5132 5440 {
53a346d8
CZ
5441 case EM_ARC:
5442 case EM_ARC_COMPACT:
5443 case EM_ARC_COMPACT2:
b5c37946
SJ
5444 case EM_ARC_COMPACT3:
5445 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5446 result = get_arc_section_type_name (sh_type);
5447 break;
252b5132 5448 case EM_MIPS:
4fe85591 5449 case EM_MIPS_RS3_LE:
252b5132
RH
5450 result = get_mips_section_type_name (sh_type);
5451 break;
103f02d3
UD
5452 case EM_PARISC:
5453 result = get_parisc_section_type_name (sh_type);
5454 break;
4d6ed7c8 5455 case EM_IA_64:
dda8d76d 5456 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5457 break;
d2b2c203 5458 case EM_X86_64:
8a9036a4 5459 case EM_L1OM:
7a9068fe 5460 case EM_K1OM:
d2b2c203
DJ
5461 result = get_x86_64_section_type_name (sh_type);
5462 break;
a06ea964
NC
5463 case EM_AARCH64:
5464 result = get_aarch64_section_type_name (sh_type);
5465 break;
40a18ebd
NC
5466 case EM_ARM:
5467 result = get_arm_section_type_name (sh_type);
5468 break;
40b36596
JM
5469 case EM_TI_C6000:
5470 result = get_tic6x_section_type_name (sh_type);
5471 break;
13761a11 5472 case EM_MSP430:
b0191216 5473 result = get_msp430_section_type_name (sh_type);
13761a11 5474 break;
fe944acf
FT
5475 case EM_NFP:
5476 result = get_nfp_section_type_name (sh_type);
5477 break;
685080f2
NC
5478 case EM_V800:
5479 case EM_V850:
5480 case EM_CYGNUS_V850:
5481 result = get_v850_section_type_name (sh_type);
5482 break;
2dc8dd17
JW
5483 case EM_RISCV:
5484 result = get_riscv_section_type_name (sh_type);
5485 break;
0861f561
CQ
5486 case EM_CSKY:
5487 result = get_csky_section_type_name (sh_type);
5488 break;
252b5132
RH
5489 default:
5490 result = NULL;
5491 break;
5492 }
5493
5494 if (result != NULL)
5495 return result;
5496
9fb71ee4 5497 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5498 }
5499 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5500 {
dda8d76d 5501 switch (filedata->file_header.e_machine)
148b93f2
NC
5502 {
5503 case EM_IA_64:
dda8d76d 5504 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5505 break;
5506 default:
dda8d76d 5507 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5508 result = get_solaris_section_type (sh_type);
5509 else
1b4b80bf
NC
5510 {
5511 switch (sh_type)
5512 {
5513 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5514 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5515 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5516 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5517 default:
5518 result = NULL;
5519 break;
5520 }
5521 }
148b93f2
NC
5522 break;
5523 }
5524
5525 if (result != NULL)
5526 return result;
5527
9fb71ee4 5528 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5529 }
252b5132 5530 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5531 {
dda8d76d 5532 switch (filedata->file_header.e_machine)
685080f2
NC
5533 {
5534 case EM_V800:
5535 case EM_V850:
5536 case EM_CYGNUS_V850:
9fb71ee4 5537 result = get_v850_section_type_name (sh_type);
a9fb83be 5538 break;
685080f2 5539 default:
9fb71ee4 5540 result = NULL;
685080f2
NC
5541 break;
5542 }
5543
9fb71ee4
NC
5544 if (result != NULL)
5545 return result;
5546
5547 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5548 }
252b5132 5549 else
a7dbfd1c
NC
5550 /* This message is probably going to be displayed in a 15
5551 character wide field, so put the hex value first. */
5552 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5553
252b5132
RH
5554 return buff;
5555 }
5556}
5557
79bc120c
NC
5558enum long_option_values
5559{
5560 OPTION_DEBUG_DUMP = 512,
5561 OPTION_DYN_SYMS,
0f03783c 5562 OPTION_LTO_SYMS,
79bc120c
NC
5563 OPTION_DWARF_DEPTH,
5564 OPTION_DWARF_START,
5565 OPTION_DWARF_CHECK,
5566 OPTION_CTF_DUMP,
5567 OPTION_CTF_PARENT,
5568 OPTION_CTF_SYMBOLS,
5569 OPTION_CTF_STRINGS,
42b6953b 5570 OPTION_SFRAME_DUMP,
79bc120c
NC
5571 OPTION_WITH_SYMBOL_VERSIONS,
5572 OPTION_RECURSE_LIMIT,
5573 OPTION_NO_RECURSE_LIMIT,
047c3dbf 5574 OPTION_NO_DEMANGLING,
b6ac461a 5575 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 5576 OPTION_SYM_BASE
79bc120c 5577};
2979dc34 5578
85b1c36d 5579static struct option options[] =
252b5132 5580{
79bc120c
NC
5581 /* Note - This table is alpha-sorted on the 'val'
5582 field in order to make adding new options easier. */
5583 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5584 {"all", no_argument, 0, 'a'},
79bc120c
NC
5585 {"demangle", optional_argument, 0, 'C'},
5586 {"archive-index", no_argument, 0, 'c'},
5587 {"use-dynamic", no_argument, 0, 'D'},
5588 {"dynamic", no_argument, 0, 'd'},
b34976b6 5589 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5590 {"section-groups", no_argument, 0, 'g'},
5591 {"help", no_argument, 0, 'H'},
5592 {"file-header", no_argument, 0, 'h'},
b34976b6 5593 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5594 {"lint", no_argument, 0, 'L'},
5595 {"enable-checks", no_argument, 0, 'L'},
5596 {"program-headers", no_argument, 0, 'l'},
b34976b6 5597 {"segments", no_argument, 0, 'l'},
595cf52e 5598 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5599 {"notes", no_argument, 0, 'n'},
ca0e11aa 5600 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5601 {"string-dump", required_argument, 0, 'p'},
5602 {"relocated-dump", required_argument, 0, 'R'},
5603 {"relocs", no_argument, 0, 'r'},
5604 {"section-headers", no_argument, 0, 'S'},
5605 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5606 {"symbols", no_argument, 0, 's'},
5607 {"syms", no_argument, 0, 's'},
79bc120c
NC
5608 {"silent-truncation",no_argument, 0, 'T'},
5609 {"section-details", no_argument, 0, 't'},
b3aa80b4 5610 {"unicode", required_argument, NULL, 'U'},
09c11c86 5611 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5612 {"version-info", no_argument, 0, 'V'},
5613 {"version", no_argument, 0, 'v'},
5614 {"wide", no_argument, 0, 'W'},
b6ac461a 5615 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 5616 {"hex-dump", required_argument, 0, 'x'},
0e602686 5617 {"decompress", no_argument, 0, 'z'},
252b5132 5618
79bc120c 5619 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 5620 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
5621 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5622 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5623 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5624 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5625 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5626 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5627 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5628 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5629 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5630#ifdef ENABLE_LIBCTF
d344b407 5631 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5632 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5633 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5634 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5635#endif
42b6953b 5636 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5637 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5638
b34976b6 5639 {0, no_argument, 0, 0}
252b5132
RH
5640};
5641
5642static void
2cf0635d 5643usage (FILE * stream)
252b5132 5644{
92f01d61
JM
5645 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5646 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5647 fprintf (stream, _(" Options are:\n"));
5648 fprintf (stream, _("\
5649 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5650 fprintf (stream, _("\
5651 -h --file-header Display the ELF file header\n"));
5652 fprintf (stream, _("\
5653 -l --program-headers Display the program headers\n"));
5654 fprintf (stream, _("\
5655 --segments An alias for --program-headers\n"));
5656 fprintf (stream, _("\
5657 -S --section-headers Display the sections' header\n"));
5658 fprintf (stream, _("\
5659 --sections An alias for --section-headers\n"));
5660 fprintf (stream, _("\
5661 -g --section-groups Display the section groups\n"));
5662 fprintf (stream, _("\
5663 -t --section-details Display the section details\n"));
5664 fprintf (stream, _("\
5665 -e --headers Equivalent to: -h -l -S\n"));
5666 fprintf (stream, _("\
5667 -s --syms Display the symbol table\n"));
5668 fprintf (stream, _("\
5669 --symbols An alias for --syms\n"));
5670 fprintf (stream, _("\
5671 --dyn-syms Display the dynamic symbol table\n"));
5672 fprintf (stream, _("\
5673 --lto-syms Display LTO symbol tables\n"));
5674 fprintf (stream, _("\
047c3dbf
NL
5675 --sym-base=[0|8|10|16] \n\
5676 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5677 mixed (the default), octal, decimal, hexadecimal.\n"));
5678 fprintf (stream, _("\
0d646226
AM
5679 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5680 display_demangler_styles (stream, _("\
5681 STYLE can be "));
d6249f5f
AM
5682 fprintf (stream, _("\
5683 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5684 fprintf (stream, _("\
5685 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5686 fprintf (stream, _("\
5687 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5688 fprintf (stream, _("\
5689 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5690 Display unicode characters as determined by the current locale\n\
5691 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5692 escape sequences, or treat them as invalid and display as\n\
5693 \"{hex sequences}\"\n"));
d6249f5f 5694 fprintf (stream, _("\
b6ac461a
NC
5695 -X --extra-sym-info Display extra information when showing symbols\n"));
5696 fprintf (stream, _("\
5697 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5698 fprintf (stream, _("\
5699 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
5700 fprintf (stream, _("\
5701 -r --relocs Display the relocations (if present)\n"));
5702 fprintf (stream, _("\
5703 -u --unwind Display the unwind info (if present)\n"));
5704 fprintf (stream, _("\
5705 -d --dynamic Display the dynamic section (if present)\n"));
5706 fprintf (stream, _("\
5707 -V --version-info Display the version sections (if present)\n"));
5708 fprintf (stream, _("\
5709 -A --arch-specific Display architecture specific information (if any)\n"));
5710 fprintf (stream, _("\
5711 -c --archive-index Display the symbol/file index in an archive\n"));
5712 fprintf (stream, _("\
5713 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5714 fprintf (stream, _("\
5715 -L --lint|--enable-checks\n\
5716 Display warning messages for possible problems\n"));
5717 fprintf (stream, _("\
09c11c86 5718 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5719 Dump the contents of section <number|name> as bytes\n"));
5720 fprintf (stream, _("\
09c11c86 5721 -p --string-dump=<number|name>\n\
d6249f5f
AM
5722 Dump the contents of section <number|name> as strings\n"));
5723 fprintf (stream, _("\
cf13d699 5724 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5725 Dump the relocated contents of section <number|name>\n"));
5726 fprintf (stream, _("\
5727 -z --decompress Decompress section before dumping it\n"));
5728 fprintf (stream, _("\
5729 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5730 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5731 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5732 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5733 U/=trace_info]\n\
5734 Display the contents of DWARF debug sections\n"));
5735 fprintf (stream, _("\
5736 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5737 debuginfo files\n"));
5738 fprintf (stream, _("\
5739 -P --process-links Display the contents of non-debug sections in separate\n\
5740 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5741#if DEFAULT_FOR_FOLLOW_LINKS
5742 fprintf (stream, _("\
d6249f5f
AM
5743 -wK --debug-dump=follow-links\n\
5744 Follow links to separate debug info files (default)\n"));
5745 fprintf (stream, _("\
5746 -wN --debug-dump=no-follow-links\n\
5747 Do not follow links to separate debug info files\n"));
c46b7066
NC
5748#else
5749 fprintf (stream, _("\
d6249f5f
AM
5750 -wK --debug-dump=follow-links\n\
5751 Follow links to separate debug info files\n"));
5752 fprintf (stream, _("\
5753 -wN --debug-dump=no-follow-links\n\
5754 Do not follow links to separate debug info files\n\
5755 (default)\n"));
bed566bb
NC
5756#endif
5757#if HAVE_LIBDEBUGINFOD
5758 fprintf (stream, _("\
5759 -wD --debug-dump=use-debuginfod\n\
5760 When following links, also query debuginfod servers (default)\n"));
5761 fprintf (stream, _("\
5762 -wE --debug-dump=do-not-use-debuginfod\n\
5763 When following links, do not query debuginfod servers\n"));
c46b7066 5764#endif
fd2f0033 5765 fprintf (stream, _("\
d6249f5f
AM
5766 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5767 fprintf (stream, _("\
5768 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5769#ifdef ENABLE_LIBCTF
7d9813f1 5770 fprintf (stream, _("\
d6249f5f
AM
5771 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5772 fprintf (stream, _("\
80b56fad 5773 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5774 fprintf (stream, _("\
7d9813f1 5775 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5776 Use section <number|name> as the CTF external symtab\n"));
5777 fprintf (stream, _("\
7d9813f1 5778 --ctf-strings=<number|name>\n\
d6249f5f 5779 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5780#endif
42b6953b
IB
5781 fprintf (stream, _("\
5782 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5783
252b5132 5784#ifdef SUPPORT_DISASSEMBLY
92f01d61 5785 fprintf (stream, _("\
09c11c86
NC
5786 -i --instruction-dump=<number|name>\n\
5787 Disassemble the contents of section <number|name>\n"));
252b5132 5788#endif
92f01d61 5789 fprintf (stream, _("\
d6249f5f
AM
5790 -I --histogram Display histogram of bucket list lengths\n"));
5791 fprintf (stream, _("\
5792 -W --wide Allow output width to exceed 80 characters\n"));
5793 fprintf (stream, _("\
5794 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5795 fprintf (stream, _("\
5796 @<file> Read options from <file>\n"));
5797 fprintf (stream, _("\
5798 -H --help Display this information\n"));
5799 fprintf (stream, _("\
8b53311e 5800 -v --version Display the version number of readelf\n"));
1118d252 5801
92f01d61
JM
5802 if (REPORT_BUGS_TO[0] && stream == stdout)
5803 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5804
92f01d61 5805 exit (stream == stdout ? 0 : 1);
252b5132
RH
5806}
5807
18bd398b
NC
5808/* Record the fact that the user wants the contents of section number
5809 SECTION to be displayed using the method(s) encoded as flags bits
5810 in TYPE. Note, TYPE can be zero if we are creating the array for
5811 the first time. */
5812
252b5132 5813static void
6431e409
AM
5814request_dump_bynumber (struct dump_data *dumpdata,
5815 unsigned int section, dump_type type)
252b5132 5816{
6431e409 5817 if (section >= dumpdata->num_dump_sects)
252b5132 5818 {
2cf0635d 5819 dump_type * new_dump_sects;
252b5132 5820
3f5e193b 5821 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5822 sizeof (* new_dump_sects));
252b5132
RH
5823
5824 if (new_dump_sects == NULL)
591a748a 5825 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5826 else
5827 {
6431e409 5828 if (dumpdata->dump_sects)
21b65bac
NC
5829 {
5830 /* Copy current flag settings. */
6431e409
AM
5831 memcpy (new_dump_sects, dumpdata->dump_sects,
5832 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5833
6431e409 5834 free (dumpdata->dump_sects);
21b65bac 5835 }
252b5132 5836
6431e409
AM
5837 dumpdata->dump_sects = new_dump_sects;
5838 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5839 }
5840 }
5841
6431e409
AM
5842 if (dumpdata->dump_sects)
5843 dumpdata->dump_sects[section] |= type;
252b5132
RH
5844}
5845
aef1f6d0
DJ
5846/* Request a dump by section name. */
5847
5848static void
2cf0635d 5849request_dump_byname (const char * section, dump_type type)
aef1f6d0 5850{
2cf0635d 5851 struct dump_list_entry * new_request;
aef1f6d0 5852
3f5e193b
NC
5853 new_request = (struct dump_list_entry *)
5854 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5855 if (!new_request)
591a748a 5856 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5857
5858 new_request->name = strdup (section);
5859 if (!new_request->name)
591a748a 5860 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5861
5862 new_request->type = type;
5863
5864 new_request->next = dump_sects_byname;
5865 dump_sects_byname = new_request;
5866}
5867
cf13d699 5868static inline void
6431e409 5869request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5870{
5871 int section;
5872 char * cp;
5873
015dc7e1 5874 do_dump = true;
cf13d699
NC
5875 section = strtoul (optarg, & cp, 0);
5876
5877 if (! *cp && section >= 0)
6431e409 5878 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5879 else
5880 request_dump_byname (optarg, type);
5881}
5882
252b5132 5883static void
6431e409 5884parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5885{
5886 int c;
5887
5888 if (argc < 2)
92f01d61 5889 usage (stderr);
252b5132
RH
5890
5891 while ((c = getopt_long
b6ac461a 5892 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5893 {
252b5132
RH
5894 switch (c)
5895 {
5896 case 0:
5897 /* Long options. */
5898 break;
5899 case 'H':
92f01d61 5900 usage (stdout);
252b5132
RH
5901 break;
5902
5903 case 'a':
015dc7e1
AM
5904 do_syms = true;
5905 do_reloc = true;
5906 do_unwind = true;
5907 do_dynamic = true;
5908 do_header = true;
5909 do_sections = true;
5910 do_section_groups = true;
5911 do_segments = true;
5912 do_version = true;
5913 do_histogram = true;
5914 do_arch = true;
5915 do_notes = true;
252b5132 5916 break;
79bc120c 5917
f5842774 5918 case 'g':
015dc7e1 5919 do_section_groups = true;
f5842774 5920 break;
5477e8a0 5921 case 't':
595cf52e 5922 case 'N':
015dc7e1
AM
5923 do_sections = true;
5924 do_section_details = true;
595cf52e 5925 break;
252b5132 5926 case 'e':
015dc7e1
AM
5927 do_header = true;
5928 do_sections = true;
5929 do_segments = true;
252b5132 5930 break;
a952a375 5931 case 'A':
015dc7e1 5932 do_arch = true;
a952a375 5933 break;
252b5132 5934 case 'D':
015dc7e1 5935 do_using_dynamic = true;
252b5132
RH
5936 break;
5937 case 'r':
015dc7e1 5938 do_reloc = true;
252b5132 5939 break;
4d6ed7c8 5940 case 'u':
015dc7e1 5941 do_unwind = true;
4d6ed7c8 5942 break;
252b5132 5943 case 'h':
015dc7e1 5944 do_header = true;
252b5132
RH
5945 break;
5946 case 'l':
015dc7e1 5947 do_segments = true;
252b5132
RH
5948 break;
5949 case 's':
015dc7e1 5950 do_syms = true;
252b5132
RH
5951 break;
5952 case 'S':
015dc7e1 5953 do_sections = true;
252b5132
RH
5954 break;
5955 case 'd':
015dc7e1 5956 do_dynamic = true;
252b5132 5957 break;
a952a375 5958 case 'I':
015dc7e1 5959 do_histogram = true;
a952a375 5960 break;
779fe533 5961 case 'n':
015dc7e1 5962 do_notes = true;
779fe533 5963 break;
4145f1d5 5964 case 'c':
015dc7e1 5965 do_archive_index = true;
4145f1d5 5966 break;
1b513401 5967 case 'L':
015dc7e1 5968 do_checks = true;
1b513401 5969 break;
ca0e11aa 5970 case 'P':
015dc7e1
AM
5971 process_links = true;
5972 do_follow_links = true;
e1dbfc17 5973 dump_any_debugging = true;
ca0e11aa 5974 break;
252b5132 5975 case 'x':
6431e409 5976 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5977 break;
09c11c86 5978 case 'p':
6431e409 5979 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5980 break;
5981 case 'R':
6431e409 5982 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5983 break;
0e602686 5984 case 'z':
015dc7e1 5985 decompress_dumps = true;
0e602686 5986 break;
252b5132 5987 case 'w':
0f03783c 5988 if (optarg == NULL)
613ff48b 5989 {
015dc7e1 5990 do_debugging = true;
94585d6d
NC
5991 do_dump = true;
5992 dump_any_debugging = true;
613ff48b
CC
5993 dwarf_select_sections_all ();
5994 }
252b5132
RH
5995 else
5996 {
015dc7e1 5997 do_debugging = false;
94585d6d
NC
5998 if (dwarf_select_sections_by_letters (optarg))
5999 {
6000 do_dump = true;
6001 dump_any_debugging = true;
6002 }
252b5132
RH
6003 }
6004 break;
2979dc34 6005 case OPTION_DEBUG_DUMP:
0f03783c 6006 if (optarg == NULL)
d6249f5f 6007 {
94585d6d 6008 do_dump = true;
d6249f5f 6009 do_debugging = true;
94585d6d 6010 dump_any_debugging = true;
d6249f5f
AM
6011 dwarf_select_sections_all ();
6012 }
2979dc34
JJ
6013 else
6014 {
015dc7e1 6015 do_debugging = false;
94585d6d
NC
6016 if (dwarf_select_sections_by_names (optarg))
6017 {
6018 do_dump = true;
6019 dump_any_debugging = true;
6020 }
2979dc34
JJ
6021 }
6022 break;
fd2f0033
TT
6023 case OPTION_DWARF_DEPTH:
6024 {
6025 char *cp;
6026
6027 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6028 }
6029 break;
6030 case OPTION_DWARF_START:
6031 {
6032 char *cp;
6033
6034 dwarf_start_die = strtoul (optarg, & cp, 0);
6035 }
6036 break;
4723351a 6037 case OPTION_DWARF_CHECK:
015dc7e1 6038 dwarf_check = true;
4723351a 6039 break;
7d9813f1 6040 case OPTION_CTF_DUMP:
015dc7e1 6041 do_ctf = true;
6431e409 6042 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6043 break;
6044 case OPTION_CTF_SYMBOLS:
df16e041 6045 free (dump_ctf_symtab_name);
7d9813f1
NA
6046 dump_ctf_symtab_name = strdup (optarg);
6047 break;
6048 case OPTION_CTF_STRINGS:
df16e041 6049 free (dump_ctf_strtab_name);
7d9813f1
NA
6050 dump_ctf_strtab_name = strdup (optarg);
6051 break;
6052 case OPTION_CTF_PARENT:
df16e041 6053 free (dump_ctf_parent_name);
7d9813f1
NA
6054 dump_ctf_parent_name = strdup (optarg);
6055 break;
42b6953b
IB
6056 case OPTION_SFRAME_DUMP:
6057 do_sframe = true;
6058 /* Providing section name is optional. request_dump (), however,
6059 thrives on non NULL optarg. Handle it explicitly here. */
6060 if (optarg != NULL)
6061 request_dump (dumpdata, SFRAME_DUMP);
6062 else
6063 {
6064 do_dump = true;
6065 const char *sframe_sec_name = strdup (".sframe");
6066 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6067 }
6068 break;
2c610e4b 6069 case OPTION_DYN_SYMS:
015dc7e1 6070 do_dyn_syms = true;
2c610e4b 6071 break;
0f03783c 6072 case OPTION_LTO_SYMS:
015dc7e1 6073 do_lto_syms = true;
0f03783c 6074 break;
b6ac461a
NC
6075 case 'X':
6076 extra_sym_info = true;
6077 break;
6078 case OPTION_NO_EXTRA_SYM_INFO:
6079 extra_sym_info = false;
6080 break;
6081
252b5132
RH
6082#ifdef SUPPORT_DISASSEMBLY
6083 case 'i':
6431e409 6084 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6085 break;
252b5132
RH
6086#endif
6087 case 'v':
6088 print_version (program_name);
6089 break;
6090 case 'V':
015dc7e1 6091 do_version = true;
252b5132 6092 break;
d974e256 6093 case 'W':
015dc7e1 6094 do_wide = true;
d974e256 6095 break;
0942c7ab 6096 case 'T':
015dc7e1 6097 do_not_show_symbol_truncation = true;
0942c7ab 6098 break;
79bc120c 6099 case 'C':
015dc7e1 6100 do_demangle = true;
79bc120c
NC
6101 if (optarg != NULL)
6102 {
6103 enum demangling_styles style;
6104
6105 style = cplus_demangle_name_to_style (optarg);
6106 if (style == unknown_demangling)
6107 error (_("unknown demangling style `%s'"), optarg);
6108
6109 cplus_demangle_set_style (style);
6110 }
6111 break;
6112 case OPTION_NO_DEMANGLING:
015dc7e1 6113 do_demangle = false;
79bc120c
NC
6114 break;
6115 case OPTION_RECURSE_LIMIT:
6116 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6117 break;
6118 case OPTION_NO_RECURSE_LIMIT:
6119 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6120 break;
6121 case OPTION_WITH_SYMBOL_VERSIONS:
6122 /* Ignored for backward compatibility. */
6123 break;
b9e920ec 6124
b3aa80b4
NC
6125 case 'U':
6126 if (optarg == NULL)
6127 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6128 else if (streq (optarg, "default") || streq (optarg, "d"))
6129 unicode_display = unicode_default;
6130 else if (streq (optarg, "locale") || streq (optarg, "l"))
6131 unicode_display = unicode_locale;
6132 else if (streq (optarg, "escape") || streq (optarg, "e"))
6133 unicode_display = unicode_escape;
6134 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6135 unicode_display = unicode_invalid;
6136 else if (streq (optarg, "hex") || streq (optarg, "x"))
6137 unicode_display = unicode_hex;
6138 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6139 unicode_display = unicode_highlight;
6140 else
6141 error (_("invalid argument to -U/--unicode: %s"), optarg);
6142 break;
6143
047c3dbf
NL
6144 case OPTION_SYM_BASE:
6145 sym_base = 0;
6146 if (optarg != NULL)
6147 {
6148 sym_base = strtoul (optarg, NULL, 0);
6149 switch (sym_base)
6150 {
6151 case 0:
6152 case 8:
6153 case 10:
6154 case 16:
6155 break;
6156
6157 default:
6158 sym_base = 0;
6159 break;
6160 }
6161 }
6162 break;
6163
252b5132 6164 default:
252b5132
RH
6165 /* xgettext:c-format */
6166 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6167 /* Fall through. */
252b5132 6168 case '?':
92f01d61 6169 usage (stderr);
252b5132
RH
6170 }
6171 }
6172
4d6ed7c8 6173 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6174 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6175 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6176 && !do_section_groups && !do_archive_index
0f03783c 6177 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6178 {
6179 if (do_checks)
6180 {
015dc7e1
AM
6181 check_all = true;
6182 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6183 do_segments = do_header = do_dump = do_version = true;
6184 do_histogram = do_debugging = do_arch = do_notes = true;
6185 do_section_groups = do_archive_index = do_dyn_syms = true;
6186 do_lto_syms = true;
1b513401
NC
6187 }
6188 else
6189 usage (stderr);
6190 }
252b5132
RH
6191}
6192
6193static const char *
d3ba0551 6194get_elf_class (unsigned int elf_class)
252b5132 6195{
b34976b6 6196 static char buff[32];
103f02d3 6197
252b5132
RH
6198 switch (elf_class)
6199 {
6200 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6201 case ELFCLASS32: return "ELF32";
6202 case ELFCLASS64: return "ELF64";
ab5e7794 6203 default:
e9e44622 6204 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6205 return buff;
252b5132
RH
6206 }
6207}
6208
6209static const char *
d3ba0551 6210get_data_encoding (unsigned int encoding)
252b5132 6211{
b34976b6 6212 static char buff[32];
103f02d3 6213
252b5132
RH
6214 switch (encoding)
6215 {
6216 case ELFDATANONE: return _("none");
33c63f9d
CM
6217 case ELFDATA2LSB: return _("2's complement, little endian");
6218 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6219 default:
e9e44622 6220 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6221 return buff;
252b5132
RH
6222 }
6223}
6224
521f7268
NC
6225static bool
6226check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6227{
6228 if (header->e_ident[EI_MAG0] == ELFMAG0
6229 && header->e_ident[EI_MAG1] == ELFMAG1
6230 && header->e_ident[EI_MAG2] == ELFMAG2
6231 && header->e_ident[EI_MAG3] == ELFMAG3)
6232 return true;
6233
6234 /* Some compilers produce object files that are not in the ELF file format.
6235 As an aid to users of readelf, try to identify these cases and suggest
6236 alternative tools.
6237
6238 FIXME: It is not clear if all four bytes are used as constant magic
6239 valus by all compilers. It may be necessary to recode this function if
6240 different tools use different length sequences. */
6241
6242 static struct
6243 {
6244 unsigned char magic[4];
6245 const char * obj_message;
6246 const char * ar_message;
6247 }
6248 known_magic[] =
6249 {
6250 { { 'B', 'C', 0xc0, 0xde },
6251 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6252 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6253 },
6254 { { 'g', 'o', ' ', 'o' },
6255 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6256 NULL
6257 }
6258 };
6259 int i;
6260
6261 for (i = ARRAY_SIZE (known_magic); i--;)
6262 {
6263 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6264 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6265 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6266 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6267 {
6268 /* Some compiler's analyzer tools do not handle archives,
6269 so we provide two different kinds of error message. */
6270 if (filedata->archive_file_size > 0
6271 && known_magic[i].ar_message != NULL)
b3ea2010 6272 error ("%s", known_magic[i].ar_message);
521f7268 6273 else
b3ea2010 6274 error ("%s", known_magic[i].obj_message);
521f7268
NC
6275 return false;
6276 }
6277 }
6278
6279 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6280 return false;
6281}
6282
dda8d76d 6283/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6284
015dc7e1 6285static bool
dda8d76d 6286process_file_header (Filedata * filedata)
252b5132 6287{
dda8d76d
NC
6288 Elf_Internal_Ehdr * header = & filedata->file_header;
6289
521f7268
NC
6290 if (! check_magic_number (filedata, header))
6291 return false;
252b5132 6292
ca0e11aa
NC
6293 if (! filedata->is_separate)
6294 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6295
252b5132
RH
6296 if (do_header)
6297 {
32ec8896 6298 unsigned i;
252b5132 6299
ca0e11aa
NC
6300 if (filedata->is_separate)
6301 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6302 else
6303 printf (_("ELF Header:\n"));
252b5132 6304 printf (_(" Magic: "));
b34976b6 6305 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6306 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6307 printf ("\n");
6308 printf (_(" Class: %s\n"),
dda8d76d 6309 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6310 printf (_(" Data: %s\n"),
dda8d76d 6311 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6312 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6313 header->e_ident[EI_VERSION],
6314 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6315 ? _(" (current)")
dda8d76d 6316 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6317 ? _(" <unknown>")
789be9f7 6318 : "")));
252b5132 6319 printf (_(" OS/ABI: %s\n"),
dda8d76d 6320 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6321 printf (_(" ABI Version: %d\n"),
dda8d76d 6322 header->e_ident[EI_ABIVERSION]);
252b5132 6323 printf (_(" Type: %s\n"),
93df3340 6324 get_file_type (filedata));
252b5132 6325 printf (_(" Machine: %s\n"),
dda8d76d 6326 get_machine_name (header->e_machine));
252b5132 6327 printf (_(" Version: 0x%lx\n"),
e8a64888 6328 header->e_version);
76da6bbe 6329
f7a99963 6330 printf (_(" Entry point address: "));
e8a64888 6331 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6332 printf (_("\n Start of program headers: "));
e8a64888 6333 print_vma (header->e_phoff, DEC);
f7a99963 6334 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6335 print_vma (header->e_shoff, DEC);
f7a99963 6336 printf (_(" (bytes into file)\n"));
76da6bbe 6337
252b5132 6338 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6339 header->e_flags,
dda8d76d 6340 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6341 printf (_(" Size of this header: %u (bytes)\n"),
6342 header->e_ehsize);
6343 printf (_(" Size of program headers: %u (bytes)\n"),
6344 header->e_phentsize);
6345 printf (_(" Number of program headers: %u"),
6346 header->e_phnum);
dda8d76d
NC
6347 if (filedata->section_headers != NULL
6348 && header->e_phnum == PN_XNUM
6349 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6350 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6351 putc ('\n', stdout);
e8a64888
AM
6352 printf (_(" Size of section headers: %u (bytes)\n"),
6353 header->e_shentsize);
6354 printf (_(" Number of section headers: %u"),
6355 header->e_shnum);
dda8d76d 6356 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6357 {
6358 header->e_shnum = filedata->section_headers[0].sh_size;
6359 printf (" (%u)", header->e_shnum);
6360 }
560f3c1c 6361 putc ('\n', stdout);
e8a64888
AM
6362 printf (_(" Section header string table index: %u"),
6363 header->e_shstrndx);
dda8d76d
NC
6364 if (filedata->section_headers != NULL
6365 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6366 {
6367 header->e_shstrndx = filedata->section_headers[0].sh_link;
6368 printf (" (%u)", header->e_shstrndx);
6369 }
6370 if (header->e_shstrndx != SHN_UNDEF
6371 && header->e_shstrndx >= header->e_shnum)
6372 {
6373 header->e_shstrndx = SHN_UNDEF;
6374 printf (_(" <corrupt: out of range>"));
6375 }
560f3c1c
AM
6376 putc ('\n', stdout);
6377 }
6378
dda8d76d 6379 if (filedata->section_headers != NULL)
560f3c1c 6380 {
dda8d76d
NC
6381 if (header->e_phnum == PN_XNUM
6382 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6383 {
6384 /* Throw away any cached read of PN_XNUM headers. */
6385 free (filedata->program_headers);
6386 filedata->program_headers = NULL;
6387 header->e_phnum = filedata->section_headers[0].sh_info;
6388 }
dda8d76d
NC
6389 if (header->e_shnum == SHN_UNDEF)
6390 header->e_shnum = filedata->section_headers[0].sh_size;
6391 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6392 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6393 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6394 header->e_shstrndx = SHN_UNDEF;
252b5132 6395 }
103f02d3 6396
015dc7e1 6397 return true;
9ea033b2
NC
6398}
6399
dda8d76d
NC
6400/* Read in the program headers from FILEDATA and store them in PHEADERS.
6401 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6402
015dc7e1 6403static bool
dda8d76d 6404get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6405{
2cf0635d
NC
6406 Elf32_External_Phdr * phdrs;
6407 Elf32_External_Phdr * external;
6408 Elf_Internal_Phdr * internal;
b34976b6 6409 unsigned int i;
dda8d76d
NC
6410 unsigned int size = filedata->file_header.e_phentsize;
6411 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6412
6413 /* PR binutils/17531: Cope with unexpected section header sizes. */
6414 if (size == 0 || num == 0)
015dc7e1 6415 return false;
e0a31db1
NC
6416 if (size < sizeof * phdrs)
6417 {
6418 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6419 return false;
e0a31db1
NC
6420 }
6421 if (size > sizeof * phdrs)
6422 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6423
dda8d76d 6424 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6425 size, num, _("program headers"));
6426 if (phdrs == NULL)
015dc7e1 6427 return false;
9ea033b2 6428
91d6fa6a 6429 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6430 i < filedata->file_header.e_phnum;
b34976b6 6431 i++, internal++, external++)
252b5132 6432 {
9ea033b2
NC
6433 internal->p_type = BYTE_GET (external->p_type);
6434 internal->p_offset = BYTE_GET (external->p_offset);
6435 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6436 internal->p_paddr = BYTE_GET (external->p_paddr);
6437 internal->p_filesz = BYTE_GET (external->p_filesz);
6438 internal->p_memsz = BYTE_GET (external->p_memsz);
6439 internal->p_flags = BYTE_GET (external->p_flags);
6440 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6441 }
6442
9ea033b2 6443 free (phdrs);
015dc7e1 6444 return true;
252b5132
RH
6445}
6446
dda8d76d
NC
6447/* Read in the program headers from FILEDATA and store them in PHEADERS.
6448 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6449
015dc7e1 6450static bool
dda8d76d 6451get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6452{
2cf0635d
NC
6453 Elf64_External_Phdr * phdrs;
6454 Elf64_External_Phdr * external;
6455 Elf_Internal_Phdr * internal;
b34976b6 6456 unsigned int i;
dda8d76d
NC
6457 unsigned int size = filedata->file_header.e_phentsize;
6458 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6459
6460 /* PR binutils/17531: Cope with unexpected section header sizes. */
6461 if (size == 0 || num == 0)
015dc7e1 6462 return false;
e0a31db1
NC
6463 if (size < sizeof * phdrs)
6464 {
6465 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6466 return false;
e0a31db1
NC
6467 }
6468 if (size > sizeof * phdrs)
6469 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6470
dda8d76d 6471 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6472 size, num, _("program headers"));
a6e9f9df 6473 if (!phdrs)
015dc7e1 6474 return false;
9ea033b2 6475
91d6fa6a 6476 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6477 i < filedata->file_header.e_phnum;
b34976b6 6478 i++, internal++, external++)
9ea033b2
NC
6479 {
6480 internal->p_type = BYTE_GET (external->p_type);
6481 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6482 internal->p_offset = BYTE_GET (external->p_offset);
6483 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6484 internal->p_paddr = BYTE_GET (external->p_paddr);
6485 internal->p_filesz = BYTE_GET (external->p_filesz);
6486 internal->p_memsz = BYTE_GET (external->p_memsz);
6487 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6488 }
6489
6490 free (phdrs);
015dc7e1 6491 return true;
9ea033b2 6492}
252b5132 6493
32ec8896 6494/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6495
015dc7e1 6496static bool
dda8d76d 6497get_program_headers (Filedata * filedata)
d93f0186 6498{
2cf0635d 6499 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6500
6501 /* Check cache of prior read. */
dda8d76d 6502 if (filedata->program_headers != NULL)
015dc7e1 6503 return true;
d93f0186 6504
82156ab7
NC
6505 /* Be kind to memory checkers by looking for
6506 e_phnum values which we know must be invalid. */
dda8d76d 6507 if (filedata->file_header.e_phnum
82156ab7 6508 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6509 >= filedata->file_size)
82156ab7
NC
6510 {
6511 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6512 filedata->file_header.e_phnum);
015dc7e1 6513 return false;
82156ab7 6514 }
d93f0186 6515
dda8d76d 6516 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6517 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6518 if (phdrs == NULL)
6519 {
8b73c356 6520 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6521 filedata->file_header.e_phnum);
015dc7e1 6522 return false;
d93f0186
NC
6523 }
6524
6525 if (is_32bit_elf
dda8d76d
NC
6526 ? get_32bit_program_headers (filedata, phdrs)
6527 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6528 {
dda8d76d 6529 filedata->program_headers = phdrs;
015dc7e1 6530 return true;
d93f0186
NC
6531 }
6532
6533 free (phdrs);
015dc7e1 6534 return false;
d93f0186
NC
6535}
6536
93df3340 6537/* Print program header info and locate dynamic section. */
2f62977e 6538
93df3340 6539static void
dda8d76d 6540process_program_headers (Filedata * filedata)
252b5132 6541{
2cf0635d 6542 Elf_Internal_Phdr * segment;
b34976b6 6543 unsigned int i;
1a9ccd70 6544 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6545
dda8d76d 6546 if (filedata->file_header.e_phnum == 0)
252b5132 6547 {
82f2dbf7 6548 /* PR binutils/12467. */
dda8d76d 6549 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6550 warn (_("possibly corrupt ELF header - it has a non-zero program"
6551 " header offset, but no program headers\n"));
82f2dbf7 6552 else if (do_segments)
ca0e11aa
NC
6553 {
6554 if (filedata->is_separate)
6555 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6556 filedata->file_name);
6557 else
6558 printf (_("\nThere are no program headers in this file.\n"));
6559 }
93df3340 6560 goto no_headers;
252b5132
RH
6561 }
6562
6563 if (do_segments && !do_header)
6564 {
ca0e11aa
NC
6565 if (filedata->is_separate)
6566 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6567 filedata->file_name, get_file_type (filedata));
ca0e11aa 6568 else
93df3340 6569 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6570 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6571 filedata->file_header.e_entry);
b8281767
AM
6572 printf (ngettext ("There is %d program header,"
6573 " starting at offset %" PRIu64 "\n",
6574 "There are %d program headers,"
6575 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6576 filedata->file_header.e_phnum),
6577 filedata->file_header.e_phnum,
625d49fc 6578 filedata->file_header.e_phoff);
252b5132
RH
6579 }
6580
dda8d76d 6581 if (! get_program_headers (filedata))
93df3340 6582 goto no_headers;
103f02d3 6583
252b5132
RH
6584 if (do_segments)
6585 {
dda8d76d 6586 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6587 printf (_("\nProgram Headers:\n"));
6588 else
6589 printf (_("\nProgram Headers:\n"));
76da6bbe 6590
f7a99963
NC
6591 if (is_32bit_elf)
6592 printf
6593 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6594 else if (do_wide)
6595 printf
6596 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6597 else
6598 {
6599 printf
6600 (_(" Type Offset VirtAddr PhysAddr\n"));
6601 printf
6602 (_(" FileSiz MemSiz Flags Align\n"));
6603 }
252b5132
RH
6604 }
6605
26c527e6 6606 uint64_t dynamic_addr = 0;
be7d229a 6607 uint64_t dynamic_size = 0;
dda8d76d
NC
6608 for (i = 0, segment = filedata->program_headers;
6609 i < filedata->file_header.e_phnum;
b34976b6 6610 i++, segment++)
252b5132
RH
6611 {
6612 if (do_segments)
6613 {
dda8d76d 6614 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6615
6616 if (is_32bit_elf)
6617 {
6618 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6619 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6620 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6621 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6622 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6623 printf ("%c%c%c ",
6624 (segment->p_flags & PF_R ? 'R' : ' '),
6625 (segment->p_flags & PF_W ? 'W' : ' '),
6626 (segment->p_flags & PF_X ? 'E' : ' '));
6627 printf ("%#lx", (unsigned long) segment->p_align);
6628 }
d974e256
JJ
6629 else if (do_wide)
6630 {
6631 if ((unsigned long) segment->p_offset == segment->p_offset)
6632 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6633 else
6634 {
6635 print_vma (segment->p_offset, FULL_HEX);
6636 putchar (' ');
6637 }
6638
6639 print_vma (segment->p_vaddr, FULL_HEX);
6640 putchar (' ');
6641 print_vma (segment->p_paddr, FULL_HEX);
6642 putchar (' ');
6643
6644 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6645 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6646 else
6647 {
6648 print_vma (segment->p_filesz, FULL_HEX);
6649 putchar (' ');
6650 }
6651
6652 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6653 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6654 else
6655 {
f48e6c45 6656 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6657 }
6658
6659 printf (" %c%c%c ",
6660 (segment->p_flags & PF_R ? 'R' : ' '),
6661 (segment->p_flags & PF_W ? 'W' : ' '),
6662 (segment->p_flags & PF_X ? 'E' : ' '));
6663
6664 if ((unsigned long) segment->p_align == segment->p_align)
6665 printf ("%#lx", (unsigned long) segment->p_align);
6666 else
6667 {
6668 print_vma (segment->p_align, PREFIX_HEX);
6669 }
6670 }
f7a99963
NC
6671 else
6672 {
6673 print_vma (segment->p_offset, FULL_HEX);
6674 putchar (' ');
6675 print_vma (segment->p_vaddr, FULL_HEX);
6676 putchar (' ');
6677 print_vma (segment->p_paddr, FULL_HEX);
6678 printf ("\n ");
6679 print_vma (segment->p_filesz, FULL_HEX);
6680 putchar (' ');
6681 print_vma (segment->p_memsz, FULL_HEX);
6682 printf (" %c%c%c ",
6683 (segment->p_flags & PF_R ? 'R' : ' '),
6684 (segment->p_flags & PF_W ? 'W' : ' '),
6685 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6686 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6687 }
252b5132 6688
1a9ccd70
NC
6689 putc ('\n', stdout);
6690 }
f54498b4 6691
252b5132
RH
6692 switch (segment->p_type)
6693 {
1a9ccd70 6694 case PT_LOAD:
502d895c
NC
6695#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6696 required by the ELF standard, several programs, including the Linux
6697 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6698 if (previous_load
6699 && previous_load->p_vaddr > segment->p_vaddr)
6700 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6701#endif
1a9ccd70
NC
6702 if (segment->p_memsz < segment->p_filesz)
6703 error (_("the segment's file size is larger than its memory size\n"));
6704 previous_load = segment;
6705 break;
6706
6707 case PT_PHDR:
6708 /* PR 20815 - Verify that the program header is loaded into memory. */
6709 if (i > 0 && previous_load != NULL)
6710 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6711 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6712 {
6713 unsigned int j;
6714
dda8d76d 6715 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6716 {
6717 Elf_Internal_Phdr *load = filedata->program_headers + j;
6718 if (load->p_type == PT_LOAD
6719 && load->p_offset <= segment->p_offset
6720 && (load->p_offset + load->p_filesz
6721 >= segment->p_offset + segment->p_filesz)
6722 && load->p_vaddr <= segment->p_vaddr
6723 && (load->p_vaddr + load->p_filesz
6724 >= segment->p_vaddr + segment->p_filesz))
6725 break;
6726 }
dda8d76d 6727 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6728 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6729 }
6730 break;
6731
252b5132 6732 case PT_DYNAMIC:
93df3340 6733 if (dynamic_addr)
252b5132
RH
6734 error (_("more than one dynamic segment\n"));
6735
20737c13
AM
6736 /* By default, assume that the .dynamic section is the first
6737 section in the DYNAMIC segment. */
93df3340
AM
6738 dynamic_addr = segment->p_offset;
6739 dynamic_size = segment->p_filesz;
20737c13 6740
b2d38a17
NC
6741 /* Try to locate the .dynamic section. If there is
6742 a section header table, we can easily locate it. */
dda8d76d 6743 if (filedata->section_headers != NULL)
b2d38a17 6744 {
2cf0635d 6745 Elf_Internal_Shdr * sec;
b2d38a17 6746
dda8d76d 6747 sec = find_section (filedata, ".dynamic");
89fac5e3 6748 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6749 {
93df3340
AM
6750 /* A corresponding .dynamic section is expected, but on
6751 IA-64/OpenVMS it is OK for it to be missing. */
6752 if (!is_ia64_vms (filedata))
6753 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6754 break;
6755 }
6756
42bb2e33 6757 if (sec->sh_type == SHT_NOBITS)
20737c13 6758 {
93df3340
AM
6759 dynamic_addr = 0;
6760 dynamic_size = 0;
20737c13
AM
6761 break;
6762 }
42bb2e33 6763
93df3340
AM
6764 dynamic_addr = sec->sh_offset;
6765 dynamic_size = sec->sh_size;
b2d38a17 6766
8ac10c5b
L
6767 /* The PT_DYNAMIC segment, which is used by the run-time
6768 loader, should exactly match the .dynamic section. */
6769 if (do_checks
93df3340
AM
6770 && (dynamic_addr != segment->p_offset
6771 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6772 warn (_("\
6773the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6774 }
39e224f6
MW
6775
6776 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6777 segment. Check this after matching against the section headers
6778 so we don't warn on debuginfo file (which have NOBITS .dynamic
6779 sections). */
93df3340
AM
6780 if (dynamic_addr > filedata->file_size
6781 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6782 {
6783 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6784 dynamic_addr = 0;
6785 dynamic_size = 0;
39e224f6 6786 }
252b5132
RH
6787 break;
6788
6789 case PT_INTERP:
13acb58d
AM
6790 if (segment->p_offset >= filedata->file_size
6791 || segment->p_filesz > filedata->file_size - segment->p_offset
6792 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6793 || fseek64 (filedata->handle,
6794 filedata->archive_file_offset + segment->p_offset,
6795 SEEK_SET))
252b5132
RH
6796 error (_("Unable to find program interpreter name\n"));
6797 else
6798 {
13acb58d
AM
6799 size_t len = segment->p_filesz;
6800 free (filedata->program_interpreter);
6801 filedata->program_interpreter = xmalloc (len + 1);
6802 len = fread (filedata->program_interpreter, 1, len,
6803 filedata->handle);
6804 filedata->program_interpreter[len] = 0;
252b5132
RH
6805
6806 if (do_segments)
f54498b4 6807 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6808 filedata->program_interpreter);
252b5132
RH
6809 }
6810 break;
6811 }
252b5132
RH
6812 }
6813
dda8d76d
NC
6814 if (do_segments
6815 && filedata->section_headers != NULL
6816 && filedata->string_table != NULL)
252b5132
RH
6817 {
6818 printf (_("\n Section to Segment mapping:\n"));
6819 printf (_(" Segment Sections...\n"));
6820
dda8d76d 6821 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6822 {
9ad5cbcf 6823 unsigned int j;
2cf0635d 6824 Elf_Internal_Shdr * section;
252b5132 6825
dda8d76d
NC
6826 segment = filedata->program_headers + i;
6827 section = filedata->section_headers + 1;
252b5132
RH
6828
6829 printf (" %2.2d ", i);
6830
dda8d76d 6831 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6832 {
f4638467
AM
6833 if (!ELF_TBSS_SPECIAL (section, segment)
6834 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6835 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6836 }
6837
6838 putc ('\n',stdout);
6839 }
6840 }
6841
93df3340
AM
6842 filedata->dynamic_addr = dynamic_addr;
6843 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6844 return;
6845
6846 no_headers:
6847 filedata->dynamic_addr = 0;
6848 filedata->dynamic_size = 1;
252b5132
RH
6849}
6850
6851
d93f0186
NC
6852/* Find the file offset corresponding to VMA by using the program headers. */
6853
26c527e6 6854static int64_t
625d49fc 6855offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6856{
2cf0635d 6857 Elf_Internal_Phdr * seg;
d93f0186 6858
dda8d76d 6859 if (! get_program_headers (filedata))
d93f0186
NC
6860 {
6861 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6862 return (long) vma;
6863 }
6864
dda8d76d
NC
6865 for (seg = filedata->program_headers;
6866 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6867 ++seg)
6868 {
6869 if (seg->p_type != PT_LOAD)
6870 continue;
6871
6872 if (vma >= (seg->p_vaddr & -seg->p_align)
6873 && vma + size <= seg->p_vaddr + seg->p_filesz)
6874 return vma - seg->p_vaddr + seg->p_offset;
6875 }
6876
26c527e6
AM
6877 warn (_("Virtual address %#" PRIx64
6878 " not located in any PT_LOAD segment.\n"), vma);
6879 return vma;
d93f0186
NC
6880}
6881
6882
dda8d76d
NC
6883/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6884 If PROBE is true, this is just a probe and we do not generate any error
6885 messages if the load fails. */
049b0c3a 6886
015dc7e1
AM
6887static bool
6888get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6889{
2cf0635d
NC
6890 Elf32_External_Shdr * shdrs;
6891 Elf_Internal_Shdr * internal;
dda8d76d
NC
6892 unsigned int i;
6893 unsigned int size = filedata->file_header.e_shentsize;
6894 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6895
6896 /* PR binutils/17531: Cope with unexpected section header sizes. */
6897 if (size == 0 || num == 0)
015dc7e1 6898 return false;
907b52f4
NC
6899
6900 /* The section header cannot be at the start of the file - that is
6901 where the ELF file header is located. A file with absolutely no
6902 sections in it will use a shoff of 0. */
6903 if (filedata->file_header.e_shoff == 0)
6904 return false;
6905
049b0c3a
NC
6906 if (size < sizeof * shdrs)
6907 {
6908 if (! probe)
6909 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6910 return false;
049b0c3a
NC
6911 }
6912 if (!probe && size > sizeof * shdrs)
6913 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6914
dda8d76d 6915 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6916 size, num,
6917 probe ? NULL : _("section headers"));
6918 if (shdrs == NULL)
015dc7e1 6919 return false;
252b5132 6920
dda8d76d
NC
6921 filedata->section_headers = (Elf_Internal_Shdr *)
6922 cmalloc (num, sizeof (Elf_Internal_Shdr));
6923 if (filedata->section_headers == NULL)
252b5132 6924 {
049b0c3a 6925 if (!probe)
8b73c356 6926 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6927 free (shdrs);
015dc7e1 6928 return false;
252b5132
RH
6929 }
6930
dda8d76d 6931 for (i = 0, internal = filedata->section_headers;
560f3c1c 6932 i < num;
b34976b6 6933 i++, internal++)
252b5132
RH
6934 {
6935 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6936 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6937 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6938 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6939 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6940 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6941 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6942 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6943 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6944 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6945 if (!probe && internal->sh_link > num)
6946 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6947 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6948 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6949 }
6950
6951 free (shdrs);
015dc7e1 6952 return true;
252b5132
RH
6953}
6954
dda8d76d
NC
6955/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6956
015dc7e1
AM
6957static bool
6958get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6959{
dda8d76d
NC
6960 Elf64_External_Shdr * shdrs;
6961 Elf_Internal_Shdr * internal;
6962 unsigned int i;
6963 unsigned int size = filedata->file_header.e_shentsize;
6964 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6965
6966 /* PR binutils/17531: Cope with unexpected section header sizes. */
6967 if (size == 0 || num == 0)
015dc7e1 6968 return false;
dda8d76d 6969
907b52f4
NC
6970 /* The section header cannot be at the start of the file - that is
6971 where the ELF file header is located. A file with absolutely no
6972 sections in it will use a shoff of 0. */
6973 if (filedata->file_header.e_shoff == 0)
6974 return false;
6975
049b0c3a
NC
6976 if (size < sizeof * shdrs)
6977 {
6978 if (! probe)
6979 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6980 return false;
049b0c3a 6981 }
dda8d76d 6982
049b0c3a
NC
6983 if (! probe && size > sizeof * shdrs)
6984 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6985
dda8d76d
NC
6986 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6987 filedata->file_header.e_shoff,
049b0c3a
NC
6988 size, num,
6989 probe ? NULL : _("section headers"));
6990 if (shdrs == NULL)
015dc7e1 6991 return false;
9ea033b2 6992
dda8d76d
NC
6993 filedata->section_headers = (Elf_Internal_Shdr *)
6994 cmalloc (num, sizeof (Elf_Internal_Shdr));
6995 if (filedata->section_headers == NULL)
9ea033b2 6996 {
049b0c3a 6997 if (! probe)
8b73c356 6998 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6999 free (shdrs);
015dc7e1 7000 return false;
9ea033b2
NC
7001 }
7002
dda8d76d 7003 for (i = 0, internal = filedata->section_headers;
560f3c1c 7004 i < num;
b34976b6 7005 i++, internal++)
9ea033b2
NC
7006 {
7007 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7008 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7009 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7010 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7011 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7012 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7013 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7014 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7015 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7016 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7017 if (!probe && internal->sh_link > num)
7018 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7019 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7020 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7021 }
7022
7023 free (shdrs);
015dc7e1 7024 return true;
9ea033b2
NC
7025}
7026
4de91c10
AM
7027static bool
7028get_section_headers (Filedata *filedata, bool probe)
7029{
7030 if (filedata->section_headers != NULL)
7031 return true;
7032
4de91c10
AM
7033 if (is_32bit_elf)
7034 return get_32bit_section_headers (filedata, probe);
7035 else
7036 return get_64bit_section_headers (filedata, probe);
7037}
7038
252b5132 7039static Elf_Internal_Sym *
26c527e6
AM
7040get_32bit_elf_symbols (Filedata *filedata,
7041 Elf_Internal_Shdr *section,
7042 uint64_t *num_syms_return)
252b5132 7043{
26c527e6 7044 uint64_t number = 0;
dd24e3da 7045 Elf32_External_Sym * esyms = NULL;
ba5cdace 7046 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7047 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7048 Elf_Internal_Sym * psym;
b34976b6 7049 unsigned int j;
e3d39609 7050 elf_section_list * entry;
252b5132 7051
c9c1d674
EG
7052 if (section->sh_size == 0)
7053 {
7054 if (num_syms_return != NULL)
7055 * num_syms_return = 0;
7056 return NULL;
7057 }
7058
dd24e3da 7059 /* Run some sanity checks first. */
c9c1d674 7060 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7061 {
26c527e6 7062 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7063 printable_section_name (filedata, section),
26c527e6 7064 section->sh_entsize);
ba5cdace 7065 goto exit_point;
dd24e3da
NC
7066 }
7067
dda8d76d 7068 if (section->sh_size > filedata->file_size)
f54498b4 7069 {
26c527e6 7070 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7071 printable_section_name (filedata, section),
26c527e6 7072 section->sh_size);
f54498b4
NC
7073 goto exit_point;
7074 }
7075
dd24e3da
NC
7076 number = section->sh_size / section->sh_entsize;
7077
7078 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7079 {
26c527e6
AM
7080 error (_("Size (%#" PRIx64 ") of section %s "
7081 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7082 section->sh_size,
dda8d76d 7083 printable_section_name (filedata, section),
26c527e6 7084 section->sh_entsize);
ba5cdace 7085 goto exit_point;
dd24e3da
NC
7086 }
7087
dda8d76d 7088 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7089 section->sh_size, _("symbols"));
dd24e3da 7090 if (esyms == NULL)
ba5cdace 7091 goto exit_point;
252b5132 7092
e3d39609 7093 shndx = NULL;
978c4450 7094 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7095 {
26c527e6 7096 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7097 continue;
7098
7099 if (shndx != NULL)
7100 {
7101 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7102 free (shndx);
7103 }
7104
7105 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7106 entry->hdr->sh_offset,
7107 1, entry->hdr->sh_size,
7108 _("symbol table section indices"));
7109 if (shndx == NULL)
7110 goto exit_point;
7111
7112 /* PR17531: file: heap-buffer-overflow */
7113 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7114 {
26c527e6 7115 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7116 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7117 entry->hdr->sh_size,
7118 section->sh_size);
e3d39609 7119 goto exit_point;
c9c1d674 7120 }
e3d39609 7121 }
9ad5cbcf 7122
3f5e193b 7123 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7124
7125 if (isyms == NULL)
7126 {
26c527e6 7127 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7128 goto exit_point;
252b5132
RH
7129 }
7130
dd24e3da 7131 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7132 {
7133 psym->st_name = BYTE_GET (esyms[j].st_name);
7134 psym->st_value = BYTE_GET (esyms[j].st_value);
7135 psym->st_size = BYTE_GET (esyms[j].st_size);
7136 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7137 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7138 psym->st_shndx
7139 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7140 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7141 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7142 psym->st_info = BYTE_GET (esyms[j].st_info);
7143 psym->st_other = BYTE_GET (esyms[j].st_other);
7144 }
7145
dd24e3da 7146 exit_point:
e3d39609
NC
7147 free (shndx);
7148 free (esyms);
252b5132 7149
ba5cdace
NC
7150 if (num_syms_return != NULL)
7151 * num_syms_return = isyms == NULL ? 0 : number;
7152
252b5132
RH
7153 return isyms;
7154}
7155
9ea033b2 7156static Elf_Internal_Sym *
26c527e6
AM
7157get_64bit_elf_symbols (Filedata *filedata,
7158 Elf_Internal_Shdr *section,
7159 uint64_t *num_syms_return)
9ea033b2 7160{
26c527e6 7161 uint64_t number = 0;
ba5cdace
NC
7162 Elf64_External_Sym * esyms = NULL;
7163 Elf_External_Sym_Shndx * shndx = NULL;
7164 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7165 Elf_Internal_Sym * psym;
b34976b6 7166 unsigned int j;
e3d39609 7167 elf_section_list * entry;
9ea033b2 7168
c9c1d674
EG
7169 if (section->sh_size == 0)
7170 {
7171 if (num_syms_return != NULL)
7172 * num_syms_return = 0;
7173 return NULL;
7174 }
7175
dd24e3da 7176 /* Run some sanity checks first. */
c9c1d674 7177 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7178 {
26c527e6 7179 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7180 printable_section_name (filedata, section),
26c527e6 7181 section->sh_entsize);
ba5cdace 7182 goto exit_point;
dd24e3da
NC
7183 }
7184
dda8d76d 7185 if (section->sh_size > filedata->file_size)
f54498b4 7186 {
26c527e6 7187 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7188 printable_section_name (filedata, section),
26c527e6 7189 section->sh_size);
f54498b4
NC
7190 goto exit_point;
7191 }
7192
dd24e3da
NC
7193 number = section->sh_size / section->sh_entsize;
7194
7195 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7196 {
26c527e6
AM
7197 error (_("Size (%#" PRIx64 ") of section %s "
7198 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7199 section->sh_size,
dda8d76d 7200 printable_section_name (filedata, section),
26c527e6 7201 section->sh_entsize);
ba5cdace 7202 goto exit_point;
dd24e3da
NC
7203 }
7204
dda8d76d 7205 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7206 section->sh_size, _("symbols"));
a6e9f9df 7207 if (!esyms)
ba5cdace 7208 goto exit_point;
9ea033b2 7209
e3d39609 7210 shndx = NULL;
978c4450 7211 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7212 {
26c527e6 7213 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7214 continue;
7215
7216 if (shndx != NULL)
7217 {
7218 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7219 free (shndx);
c9c1d674 7220 }
e3d39609
NC
7221
7222 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7223 entry->hdr->sh_offset,
7224 1, entry->hdr->sh_size,
7225 _("symbol table section indices"));
7226 if (shndx == NULL)
7227 goto exit_point;
7228
7229 /* PR17531: file: heap-buffer-overflow */
7230 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7231 {
26c527e6 7232 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7233 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7234 entry->hdr->sh_size,
7235 section->sh_size);
e3d39609
NC
7236 goto exit_point;
7237 }
7238 }
9ad5cbcf 7239
3f5e193b 7240 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7241
7242 if (isyms == NULL)
7243 {
26c527e6 7244 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7245 goto exit_point;
9ea033b2
NC
7246 }
7247
ba5cdace 7248 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7249 {
7250 psym->st_name = BYTE_GET (esyms[j].st_name);
7251 psym->st_info = BYTE_GET (esyms[j].st_info);
7252 psym->st_other = BYTE_GET (esyms[j].st_other);
7253 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7254
4fbb74a6 7255 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7256 psym->st_shndx
7257 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7258 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7259 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7260
66543521
AM
7261 psym->st_value = BYTE_GET (esyms[j].st_value);
7262 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7263 }
7264
ba5cdace 7265 exit_point:
e3d39609
NC
7266 free (shndx);
7267 free (esyms);
ba5cdace
NC
7268
7269 if (num_syms_return != NULL)
7270 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7271
7272 return isyms;
7273}
7274
4de91c10
AM
7275static Elf_Internal_Sym *
7276get_elf_symbols (Filedata *filedata,
7277 Elf_Internal_Shdr *section,
26c527e6 7278 uint64_t *num_syms_return)
4de91c10
AM
7279{
7280 if (is_32bit_elf)
7281 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7282 else
7283 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7284}
7285
d1133906 7286static const char *
625d49fc 7287get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7288{
5477e8a0 7289 static char buff[1024];
2cf0635d 7290 char * p = buff;
32ec8896
NC
7291 unsigned int field_size = is_32bit_elf ? 8 : 16;
7292 signed int sindex;
7293 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7294 uint64_t os_flags = 0;
7295 uint64_t proc_flags = 0;
7296 uint64_t unknown_flags = 0;
148b93f2 7297 static const struct
5477e8a0 7298 {
2cf0635d 7299 const char * str;
32ec8896 7300 unsigned int len;
5477e8a0
L
7301 }
7302 flags [] =
7303 {
cfcac11d
NC
7304 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7305 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7306 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7307 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7308 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7309 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7310 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7311 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7312 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7313 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7314 /* IA-64 specific. */
7315 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7316 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7317 /* IA-64 OpenVMS specific. */
7318 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7319 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7320 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7321 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7322 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7323 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7324 /* Generic. */
cfcac11d 7325 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7326 /* SPARC specific. */
77115a4a 7327 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7328 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7329 /* ARM specific. */
7330 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7331 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7332 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7333 /* GNU specific. */
7334 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7335 /* VLE specific. */
7336 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7337 /* GNU specific. */
7338 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7339 };
7340
7341 if (do_section_details)
f8c4789c
AM
7342 p += sprintf (p, "[%*.*lx]: ",
7343 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7344
d1133906
NC
7345 while (sh_flags)
7346 {
625d49fc 7347 uint64_t flag;
d1133906
NC
7348
7349 flag = sh_flags & - sh_flags;
7350 sh_flags &= ~ flag;
76da6bbe 7351
5477e8a0 7352 if (do_section_details)
d1133906 7353 {
5477e8a0
L
7354 switch (flag)
7355 {
91d6fa6a
NC
7356 case SHF_WRITE: sindex = 0; break;
7357 case SHF_ALLOC: sindex = 1; break;
7358 case SHF_EXECINSTR: sindex = 2; break;
7359 case SHF_MERGE: sindex = 3; break;
7360 case SHF_STRINGS: sindex = 4; break;
7361 case SHF_INFO_LINK: sindex = 5; break;
7362 case SHF_LINK_ORDER: sindex = 6; break;
7363 case SHF_OS_NONCONFORMING: sindex = 7; break;
7364 case SHF_GROUP: sindex = 8; break;
7365 case SHF_TLS: sindex = 9; break;
18ae9cc1 7366 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7367 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7368
5477e8a0 7369 default:
91d6fa6a 7370 sindex = -1;
dda8d76d 7371 switch (filedata->file_header.e_machine)
148b93f2 7372 {
cfcac11d 7373 case EM_IA_64:
148b93f2 7374 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7375 sindex = 10;
148b93f2 7376 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7377 sindex = 11;
dda8d76d 7378 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7379 switch (flag)
7380 {
91d6fa6a
NC
7381 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7382 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7383 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7384 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7385 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7386 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7387 default: break;
7388 }
cfcac11d
NC
7389 break;
7390
caa83f8b 7391 case EM_386:
22abe556 7392 case EM_IAMCU:
caa83f8b 7393 case EM_X86_64:
7f502d6c 7394 case EM_L1OM:
7a9068fe 7395 case EM_K1OM:
cfcac11d
NC
7396 case EM_OLD_SPARCV9:
7397 case EM_SPARC32PLUS:
7398 case EM_SPARCV9:
7399 case EM_SPARC:
18ae9cc1 7400 if (flag == SHF_ORDERED)
91d6fa6a 7401 sindex = 19;
cfcac11d 7402 break;
ac4c9b04
MG
7403
7404 case EM_ARM:
7405 switch (flag)
7406 {
7407 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7408 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7409 case SHF_COMDEF: sindex = 23; break;
7410 default: break;
7411 }
7412 break;
83eef883
AFB
7413 case EM_PPC:
7414 if (flag == SHF_PPC_VLE)
7415 sindex = 25;
7416 break;
99fabbc9
JL
7417 default:
7418 break;
7419 }
ac4c9b04 7420
99fabbc9
JL
7421 switch (filedata->file_header.e_ident[EI_OSABI])
7422 {
7423 case ELFOSABI_GNU:
7424 case ELFOSABI_FREEBSD:
7425 if (flag == SHF_GNU_RETAIN)
7426 sindex = 26;
7427 /* Fall through */
7428 case ELFOSABI_NONE:
7429 if (flag == SHF_GNU_MBIND)
7430 /* We should not recognize SHF_GNU_MBIND for
7431 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7432 not set the EI_OSABI header byte. */
7433 sindex = 24;
7434 break;
cfcac11d
NC
7435 default:
7436 break;
148b93f2 7437 }
99fabbc9 7438 break;
5477e8a0
L
7439 }
7440
91d6fa6a 7441 if (sindex != -1)
5477e8a0 7442 {
8d5ff12c
L
7443 if (p != buff + field_size + 4)
7444 {
7445 if (size < (10 + 2))
bee0ee85
NC
7446 {
7447 warn (_("Internal error: not enough buffer room for section flag info"));
7448 return _("<unknown>");
7449 }
8d5ff12c
L
7450 size -= 2;
7451 *p++ = ',';
7452 *p++ = ' ';
7453 }
7454
91d6fa6a
NC
7455 size -= flags [sindex].len;
7456 p = stpcpy (p, flags [sindex].str);
5477e8a0 7457 }
3b22753a 7458 else if (flag & SHF_MASKOS)
8d5ff12c 7459 os_flags |= flag;
d1133906 7460 else if (flag & SHF_MASKPROC)
8d5ff12c 7461 proc_flags |= flag;
d1133906 7462 else
8d5ff12c 7463 unknown_flags |= flag;
5477e8a0
L
7464 }
7465 else
7466 {
7467 switch (flag)
7468 {
7469 case SHF_WRITE: *p = 'W'; break;
7470 case SHF_ALLOC: *p = 'A'; break;
7471 case SHF_EXECINSTR: *p = 'X'; break;
7472 case SHF_MERGE: *p = 'M'; break;
7473 case SHF_STRINGS: *p = 'S'; break;
7474 case SHF_INFO_LINK: *p = 'I'; break;
7475 case SHF_LINK_ORDER: *p = 'L'; break;
7476 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7477 case SHF_GROUP: *p = 'G'; break;
7478 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7479 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7480 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7481
7482 default:
dda8d76d
NC
7483 if ((filedata->file_header.e_machine == EM_X86_64
7484 || filedata->file_header.e_machine == EM_L1OM
7485 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7486 && flag == SHF_X86_64_LARGE)
7487 *p = 'l';
dda8d76d 7488 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7489 && flag == SHF_ARM_PURECODE)
99fabbc9 7490 *p = 'y';
dda8d76d 7491 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7492 && flag == SHF_PPC_VLE)
99fabbc9 7493 *p = 'v';
5477e8a0
L
7494 else if (flag & SHF_MASKOS)
7495 {
99fabbc9
JL
7496 switch (filedata->file_header.e_ident[EI_OSABI])
7497 {
7498 case ELFOSABI_GNU:
7499 case ELFOSABI_FREEBSD:
7500 if (flag == SHF_GNU_RETAIN)
7501 {
7502 *p = 'R';
7503 break;
7504 }
7505 /* Fall through */
7506 case ELFOSABI_NONE:
7507 if (flag == SHF_GNU_MBIND)
7508 {
7509 /* We should not recognize SHF_GNU_MBIND for
7510 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7511 not set the EI_OSABI header byte. */
7512 *p = 'D';
7513 break;
7514 }
7515 /* Fall through */
7516 default:
7517 *p = 'o';
7518 sh_flags &= ~SHF_MASKOS;
7519 break;
7520 }
5477e8a0
L
7521 }
7522 else if (flag & SHF_MASKPROC)
7523 {
7524 *p = 'p';
7525 sh_flags &= ~ SHF_MASKPROC;
7526 }
7527 else
7528 *p = 'x';
7529 break;
7530 }
7531 p++;
d1133906
NC
7532 }
7533 }
76da6bbe 7534
8d5ff12c
L
7535 if (do_section_details)
7536 {
7537 if (os_flags)
7538 {
8d5ff12c
L
7539 if (p != buff + field_size + 4)
7540 {
f8c4789c 7541 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7542 {
7543 warn (_("Internal error: not enough buffer room for section flag info"));
7544 return _("<unknown>");
7545 }
8d5ff12c
L
7546 size -= 2;
7547 *p++ = ',';
7548 *p++ = ' ';
7549 }
f8c4789c
AM
7550 size -= 5 + field_size;
7551 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7552 (unsigned long) os_flags);
8d5ff12c
L
7553 }
7554 if (proc_flags)
7555 {
8d5ff12c
L
7556 if (p != buff + field_size + 4)
7557 {
f8c4789c 7558 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7559 {
7560 warn (_("Internal error: not enough buffer room for section flag info"));
7561 return _("<unknown>");
7562 }
8d5ff12c
L
7563 size -= 2;
7564 *p++ = ',';
7565 *p++ = ' ';
7566 }
f8c4789c
AM
7567 size -= 7 + field_size;
7568 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7569 (unsigned long) proc_flags);
8d5ff12c
L
7570 }
7571 if (unknown_flags)
7572 {
8d5ff12c
L
7573 if (p != buff + field_size + 4)
7574 {
f8c4789c 7575 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7576 {
7577 warn (_("Internal error: not enough buffer room for section flag info"));
7578 return _("<unknown>");
7579 }
8d5ff12c
L
7580 size -= 2;
7581 *p++ = ',';
7582 *p++ = ' ';
7583 }
f8c4789c
AM
7584 size -= 10 + field_size;
7585 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7586 (unsigned long) unknown_flags);
8d5ff12c
L
7587 }
7588 }
7589
e9e44622 7590 *p = '\0';
d1133906
NC
7591 return buff;
7592}
7593
5844b465 7594static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7595get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7596 uint64_t size)
77115a4a
L
7597{
7598 if (is_32bit_elf)
7599 {
7600 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7601
ebdf1ebf
NC
7602 if (size < sizeof (* echdr))
7603 {
7604 error (_("Compressed section is too small even for a compression header\n"));
7605 return 0;
7606 }
7607
77115a4a
L
7608 chdr->ch_type = BYTE_GET (echdr->ch_type);
7609 chdr->ch_size = BYTE_GET (echdr->ch_size);
7610 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7611 return sizeof (*echdr);
7612 }
7613 else
7614 {
7615 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7616
ebdf1ebf
NC
7617 if (size < sizeof (* echdr))
7618 {
7619 error (_("Compressed section is too small even for a compression header\n"));
7620 return 0;
7621 }
7622
77115a4a
L
7623 chdr->ch_type = BYTE_GET (echdr->ch_type);
7624 chdr->ch_size = BYTE_GET (echdr->ch_size);
7625 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7626 return sizeof (*echdr);
7627 }
7628}
7629
015dc7e1 7630static bool
dda8d76d 7631process_section_headers (Filedata * filedata)
252b5132 7632{
2cf0635d 7633 Elf_Internal_Shdr * section;
b34976b6 7634 unsigned int i;
252b5132 7635
dda8d76d 7636 if (filedata->file_header.e_shnum == 0)
252b5132 7637 {
82f2dbf7 7638 /* PR binutils/12467. */
dda8d76d 7639 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7640 {
7641 warn (_("possibly corrupt ELF file header - it has a non-zero"
7642 " section header offset, but no section headers\n"));
015dc7e1 7643 return false;
32ec8896 7644 }
82f2dbf7 7645 else if (do_sections)
252b5132
RH
7646 printf (_("\nThere are no sections in this file.\n"));
7647
015dc7e1 7648 return true;
252b5132
RH
7649 }
7650
7651 if (do_sections && !do_header)
ca0e11aa
NC
7652 {
7653 if (filedata->is_separate && process_links)
7654 printf (_("In linked file '%s': "), filedata->file_name);
7655 if (! filedata->is_separate || process_links)
7656 printf (ngettext ("There is %d section header, "
26c527e6 7657 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7658 "There are %d section headers, "
26c527e6 7659 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7660 filedata->file_header.e_shnum),
7661 filedata->file_header.e_shnum,
26c527e6 7662 filedata->file_header.e_shoff);
ca0e11aa 7663 }
252b5132 7664
4de91c10
AM
7665 if (!get_section_headers (filedata, false))
7666 return false;
252b5132
RH
7667
7668 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7669 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7670 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7671 {
dda8d76d 7672 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7673
c256ffe7
JJ
7674 if (section->sh_size != 0)
7675 {
dda8d76d
NC
7676 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7677 1, section->sh_size,
7678 _("string table"));
0de14b54 7679
dda8d76d 7680 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7681 }
252b5132
RH
7682 }
7683
7684 /* Scan the sections for the dynamic symbol table
e3c8793a 7685 and dynamic string table and debug sections. */
89fac5e3 7686 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7687 switch (filedata->file_header.e_machine)
89fac5e3
RS
7688 {
7689 case EM_MIPS:
7690 case EM_MIPS_RS3_LE:
7691 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7692 FDE addresses. However, the ABI also has a semi-official ILP32
7693 variant for which the normal FDE address size rules apply.
7694
7695 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7696 section, where XX is the size of longs in bits. Unfortunately,
7697 earlier compilers provided no way of distinguishing ILP32 objects
7698 from LP64 objects, so if there's any doubt, we should assume that
7699 the official LP64 form is being used. */
d173146d 7700 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 7701 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7702 eh_addr_size = 8;
7703 break;
0f56a26a
DD
7704
7705 case EM_H8_300:
7706 case EM_H8_300H:
dda8d76d 7707 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7708 {
7709 case E_H8_MACH_H8300:
7710 case E_H8_MACH_H8300HN:
7711 case E_H8_MACH_H8300SN:
7712 case E_H8_MACH_H8300SXN:
7713 eh_addr_size = 2;
7714 break;
7715 case E_H8_MACH_H8300H:
7716 case E_H8_MACH_H8300S:
7717 case E_H8_MACH_H8300SX:
7718 eh_addr_size = 4;
7719 break;
7720 }
f4236fe4
DD
7721 break;
7722
ff7eeb89 7723 case EM_M32C_OLD:
f4236fe4 7724 case EM_M32C:
dda8d76d 7725 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7726 {
7727 case EF_M32C_CPU_M16C:
7728 eh_addr_size = 2;
7729 break;
7730 }
7731 break;
89fac5e3
RS
7732 }
7733
76ca31c0
NC
7734#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7735 do \
7736 { \
be7d229a 7737 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7738 if (section->sh_entsize != expected_entsize) \
9dd3a467 7739 { \
f493c217 7740 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7741 i, section->sh_entsize); \
f493c217 7742 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7743 expected_entsize); \
9dd3a467 7744 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7745 } \
7746 } \
08d8fa11 7747 while (0)
9dd3a467
NC
7748
7749#define CHECK_ENTSIZE(section, i, type) \
1b513401 7750 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7751 sizeof (Elf64_External_##type))
7752
dda8d76d
NC
7753 for (i = 0, section = filedata->section_headers;
7754 i < filedata->file_header.e_shnum;
b34976b6 7755 i++, section++)
252b5132 7756 {
b6ac461a 7757 const char *name = printable_section_name (filedata, section);
252b5132 7758
1b513401
NC
7759 /* Run some sanity checks on the headers and
7760 possibly fill in some file data as well. */
7761 switch (section->sh_type)
252b5132 7762 {
1b513401 7763 case SHT_DYNSYM:
978c4450 7764 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7765 {
7766 error (_("File contains multiple dynamic symbol tables\n"));
7767 continue;
7768 }
7769
08d8fa11 7770 CHECK_ENTSIZE (section, i, Sym);
978c4450 7771 filedata->dynamic_symbols
4de91c10 7772 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7773 filedata->dynamic_symtab_section = section;
1b513401
NC
7774 break;
7775
7776 case SHT_STRTAB:
7777 if (streq (name, ".dynstr"))
252b5132 7778 {
1b513401
NC
7779 if (filedata->dynamic_strings != NULL)
7780 {
7781 error (_("File contains multiple dynamic string tables\n"));
7782 continue;
7783 }
7784
7785 filedata->dynamic_strings
7786 = (char *) get_data (NULL, filedata, section->sh_offset,
7787 1, section->sh_size, _("dynamic strings"));
7788 filedata->dynamic_strings_length
7789 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7790 filedata->dynamic_strtab_section = section;
252b5132 7791 }
1b513401
NC
7792 break;
7793
7794 case SHT_SYMTAB_SHNDX:
7795 {
7796 elf_section_list * entry = xmalloc (sizeof * entry);
7797
7798 entry->hdr = section;
7799 entry->next = filedata->symtab_shndx_list;
7800 filedata->symtab_shndx_list = entry;
7801 }
7802 break;
7803
7804 case SHT_SYMTAB:
7805 CHECK_ENTSIZE (section, i, Sym);
7806 break;
7807
7808 case SHT_GROUP:
7809 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7810 break;
252b5132 7811
1b513401
NC
7812 case SHT_REL:
7813 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7814 if (do_checks && section->sh_size == 0)
1b513401
NC
7815 warn (_("Section '%s': zero-sized relocation section\n"), name);
7816 break;
7817
7818 case SHT_RELA:
7819 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7820 if (do_checks && section->sh_size == 0)
1b513401
NC
7821 warn (_("Section '%s': zero-sized relocation section\n"), name);
7822 break;
7823
682351b9
AM
7824 case SHT_RELR:
7825 CHECK_ENTSIZE (section, i, Relr);
7826 break;
7827
1b513401
NC
7828 case SHT_NOTE:
7829 case SHT_PROGBITS:
546cb2d8
NC
7830 /* Having a zero sized section is not illegal according to the
7831 ELF standard, but it might be an indication that something
7832 is wrong. So issue a warning if we are running in lint mode. */
7833 if (do_checks && section->sh_size == 0)
1b513401
NC
7834 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7835 break;
7836
7837 default:
7838 break;
7839 }
7840
7841 if ((do_debugging || do_debug_info || do_debug_abbrevs
7842 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7843 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7844 || do_debug_str || do_debug_str_offsets || do_debug_loc
7845 || do_debug_ranges
1b513401 7846 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7847 && (startswith (name, ".debug_")
7848 || startswith (name, ".zdebug_")))
252b5132 7849 {
1b315056
CS
7850 if (name[1] == 'z')
7851 name += sizeof (".zdebug_") - 1;
7852 else
7853 name += sizeof (".debug_") - 1;
252b5132
RH
7854
7855 if (do_debugging
24d127aa
ML
7856 || (do_debug_info && startswith (name, "info"))
7857 || (do_debug_info && startswith (name, "types"))
7858 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7859 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7860 || (do_debug_lines && startswith (name, "line."))
7861 || (do_debug_pubnames && startswith (name, "pubnames"))
7862 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7863 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7864 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7865 || (do_debug_aranges && startswith (name, "aranges"))
7866 || (do_debug_ranges && startswith (name, "ranges"))
7867 || (do_debug_ranges && startswith (name, "rnglists"))
7868 || (do_debug_frames && startswith (name, "frame"))
7869 || (do_debug_macinfo && startswith (name, "macinfo"))
7870 || (do_debug_macinfo && startswith (name, "macro"))
7871 || (do_debug_str && startswith (name, "str"))
7872 || (do_debug_links && startswith (name, "sup"))
7873 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7874 || (do_debug_loc && startswith (name, "loc"))
7875 || (do_debug_loc && startswith (name, "loclists"))
7876 || (do_debug_addr && startswith (name, "addr"))
7877 || (do_debug_cu_index && startswith (name, "cu_index"))
7878 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7879 )
6431e409 7880 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7881 }
a262ae96 7882 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7883 else if ((do_debugging || do_debug_info)
24d127aa 7884 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7885 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7886 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7887 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7888 else if (do_gdb_index && (streq (name, ".gdb_index")
7889 || streq (name, ".debug_names")))
6431e409 7890 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7891 /* Trace sections for Itanium VMS. */
7892 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7893 || do_trace_aranges)
24d127aa 7894 && startswith (name, ".trace_"))
6f875884
TG
7895 {
7896 name += sizeof (".trace_") - 1;
7897
7898 if (do_debugging
7899 || (do_trace_info && streq (name, "info"))
7900 || (do_trace_abbrevs && streq (name, "abbrev"))
7901 || (do_trace_aranges && streq (name, "aranges"))
7902 )
6431e409 7903 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7904 }
dda8d76d 7905 else if ((do_debugging || do_debug_links)
24d127aa
ML
7906 && (startswith (name, ".gnu_debuglink")
7907 || startswith (name, ".gnu_debugaltlink")))
6431e409 7908 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7909 }
7910
7911 if (! do_sections)
015dc7e1 7912 return true;
252b5132 7913
ca0e11aa 7914 if (filedata->is_separate && ! process_links)
015dc7e1 7915 return true;
ca0e11aa
NC
7916
7917 if (filedata->is_separate)
7918 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7919 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7920 printf (_("\nSection Headers:\n"));
7921 else
7922 printf (_("\nSection Header:\n"));
76da6bbe 7923
f7a99963 7924 if (is_32bit_elf)
595cf52e 7925 {
5477e8a0 7926 if (do_section_details)
595cf52e
L
7927 {
7928 printf (_(" [Nr] Name\n"));
5477e8a0 7929 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7930 }
7931 else
7932 printf
7933 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7934 }
d974e256 7935 else if (do_wide)
595cf52e 7936 {
5477e8a0 7937 if (do_section_details)
595cf52e
L
7938 {
7939 printf (_(" [Nr] Name\n"));
5477e8a0 7940 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7941 }
7942 else
7943 printf
7944 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7945 }
f7a99963
NC
7946 else
7947 {
5477e8a0 7948 if (do_section_details)
595cf52e
L
7949 {
7950 printf (_(" [Nr] Name\n"));
5477e8a0
L
7951 printf (_(" Type Address Offset Link\n"));
7952 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7953 }
7954 else
7955 {
7956 printf (_(" [Nr] Name Type Address Offset\n"));
7957 printf (_(" Size EntSize Flags Link Info Align\n"));
7958 }
f7a99963 7959 }
252b5132 7960
5477e8a0
L
7961 if (do_section_details)
7962 printf (_(" Flags\n"));
7963
dda8d76d
NC
7964 for (i = 0, section = filedata->section_headers;
7965 i < filedata->file_header.e_shnum;
b34976b6 7966 i++, section++)
252b5132 7967 {
dd905818
NC
7968 /* Run some sanity checks on the section header. */
7969
7970 /* Check the sh_link field. */
7971 switch (section->sh_type)
7972 {
285e3f99
AM
7973 case SHT_REL:
7974 case SHT_RELA:
7975 if (section->sh_link == 0
7976 && (filedata->file_header.e_type == ET_EXEC
7977 || filedata->file_header.e_type == ET_DYN))
7978 /* A dynamic relocation section where all entries use a
7979 zero symbol index need not specify a symtab section. */
7980 break;
7981 /* Fall through. */
dd905818
NC
7982 case SHT_SYMTAB_SHNDX:
7983 case SHT_GROUP:
7984 case SHT_HASH:
7985 case SHT_GNU_HASH:
7986 case SHT_GNU_versym:
285e3f99 7987 if (section->sh_link == 0
dda8d76d
NC
7988 || section->sh_link >= filedata->file_header.e_shnum
7989 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7990 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7991 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7992 i, section->sh_link);
7993 break;
7994
7995 case SHT_DYNAMIC:
7996 case SHT_SYMTAB:
7997 case SHT_DYNSYM:
7998 case SHT_GNU_verneed:
7999 case SHT_GNU_verdef:
8000 case SHT_GNU_LIBLIST:
285e3f99 8001 if (section->sh_link == 0
dda8d76d
NC
8002 || section->sh_link >= filedata->file_header.e_shnum
8003 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8004 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8005 i, section->sh_link);
8006 break;
8007
8008 case SHT_INIT_ARRAY:
8009 case SHT_FINI_ARRAY:
8010 case SHT_PREINIT_ARRAY:
8011 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8012 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8013 i, section->sh_link);
8014 break;
8015
8016 default:
8017 /* FIXME: Add support for target specific section types. */
8018#if 0 /* Currently we do not check other section types as there are too
8019 many special cases. Stab sections for example have a type
8020 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8021 section. */
8022 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8023 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8024 i, section->sh_link);
8025#endif
8026 break;
8027 }
8028
8029 /* Check the sh_info field. */
8030 switch (section->sh_type)
8031 {
8032 case SHT_REL:
8033 case SHT_RELA:
285e3f99
AM
8034 if (section->sh_info == 0
8035 && (filedata->file_header.e_type == ET_EXEC
8036 || filedata->file_header.e_type == ET_DYN))
8037 /* Dynamic relocations apply to segments, so they do not
8038 need to specify the section they relocate. */
8039 break;
8040 if (section->sh_info == 0
dda8d76d
NC
8041 || section->sh_info >= filedata->file_header.e_shnum
8042 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8043 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8044 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8045 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8046 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8047 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8048 /* FIXME: Are other section types valid ? */
dda8d76d 8049 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8050 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8051 i, section->sh_info);
dd905818
NC
8052 break;
8053
8054 case SHT_DYNAMIC:
8055 case SHT_HASH:
8056 case SHT_SYMTAB_SHNDX:
8057 case SHT_INIT_ARRAY:
8058 case SHT_FINI_ARRAY:
8059 case SHT_PREINIT_ARRAY:
8060 if (section->sh_info != 0)
8061 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8062 i, section->sh_info);
8063 break;
8064
8065 case SHT_GROUP:
8066 case SHT_SYMTAB:
8067 case SHT_DYNSYM:
8068 /* A symbol index - we assume that it is valid. */
8069 break;
8070
8071 default:
8072 /* FIXME: Add support for target specific section types. */
8073 if (section->sh_type == SHT_NOBITS)
8074 /* NOBITS section headers with non-zero sh_info fields can be
8075 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8076 information. The stripped sections have their headers
8077 preserved but their types set to SHT_NOBITS. So do not check
8078 this type of section. */
dd905818
NC
8079 ;
8080 else if (section->sh_flags & SHF_INFO_LINK)
8081 {
dda8d76d 8082 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8083 warn (_("[%2u]: Expected link to another section in info field"), i);
8084 }
a91e1603
L
8085 else if (section->sh_type < SHT_LOOS
8086 && (section->sh_flags & SHF_GNU_MBIND) == 0
8087 && section->sh_info != 0)
dd905818
NC
8088 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8089 i, section->sh_info);
8090 break;
8091 }
8092
3e6b6445 8093 /* Check the sh_size field. */
dda8d76d 8094 if (section->sh_size > filedata->file_size
3e6b6445
NC
8095 && section->sh_type != SHT_NOBITS
8096 && section->sh_type != SHT_NULL
8097 && section->sh_type < SHT_LOOS)
8098 warn (_("Size of section %u is larger than the entire file!\n"), i);
8099
7bfd842d 8100 printf (" [%2u] ", i);
5477e8a0 8101 if (do_section_details)
dda8d76d 8102 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8103 else
b6ac461a 8104 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8105
ea52a088 8106 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8107 get_section_type_name (filedata, section->sh_type));
0b4362b0 8108
f7a99963
NC
8109 if (is_32bit_elf)
8110 {
cfcac11d
NC
8111 const char * link_too_big = NULL;
8112
f7a99963 8113 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8114
f7a99963
NC
8115 printf ( " %6.6lx %6.6lx %2.2lx",
8116 (unsigned long) section->sh_offset,
8117 (unsigned long) section->sh_size,
8118 (unsigned long) section->sh_entsize);
d1133906 8119
5477e8a0
L
8120 if (do_section_details)
8121 fputs (" ", stdout);
8122 else
dda8d76d 8123 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8124
dda8d76d 8125 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8126 {
8127 link_too_big = "";
8128 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8129 an error but it can have special values in Solaris binaries. */
dda8d76d 8130 switch (filedata->file_header.e_machine)
cfcac11d 8131 {
caa83f8b 8132 case EM_386:
22abe556 8133 case EM_IAMCU:
caa83f8b 8134 case EM_X86_64:
7f502d6c 8135 case EM_L1OM:
7a9068fe 8136 case EM_K1OM:
cfcac11d
NC
8137 case EM_OLD_SPARCV9:
8138 case EM_SPARC32PLUS:
8139 case EM_SPARCV9:
8140 case EM_SPARC:
8141 if (section->sh_link == (SHN_BEFORE & 0xffff))
8142 link_too_big = "BEFORE";
8143 else if (section->sh_link == (SHN_AFTER & 0xffff))
8144 link_too_big = "AFTER";
8145 break;
8146 default:
8147 break;
8148 }
8149 }
8150
8151 if (do_section_details)
8152 {
8153 if (link_too_big != NULL && * link_too_big)
8154 printf ("<%s> ", link_too_big);
8155 else
8156 printf ("%2u ", section->sh_link);
8157 printf ("%3u %2lu\n", section->sh_info,
8158 (unsigned long) section->sh_addralign);
8159 }
8160 else
8161 printf ("%2u %3u %2lu\n",
8162 section->sh_link,
8163 section->sh_info,
8164 (unsigned long) section->sh_addralign);
8165
8166 if (link_too_big && ! * link_too_big)
8167 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8168 i, section->sh_link);
f7a99963 8169 }
d974e256
JJ
8170 else if (do_wide)
8171 {
8172 print_vma (section->sh_addr, LONG_HEX);
8173
8174 if ((long) section->sh_offset == section->sh_offset)
8175 printf (" %6.6lx", (unsigned long) section->sh_offset);
8176 else
8177 {
8178 putchar (' ');
8179 print_vma (section->sh_offset, LONG_HEX);
8180 }
8181
8182 if ((unsigned long) section->sh_size == section->sh_size)
8183 printf (" %6.6lx", (unsigned long) section->sh_size);
8184 else
8185 {
8186 putchar (' ');
8187 print_vma (section->sh_size, LONG_HEX);
8188 }
8189
8190 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8191 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8192 else
8193 {
8194 putchar (' ');
8195 print_vma (section->sh_entsize, LONG_HEX);
8196 }
8197
5477e8a0
L
8198 if (do_section_details)
8199 fputs (" ", stdout);
8200 else
dda8d76d 8201 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8202
72de5009 8203 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8204
8205 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8206 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8207 else
8208 {
8209 print_vma (section->sh_addralign, DEC);
8210 putchar ('\n');
8211 }
8212 }
5477e8a0 8213 else if (do_section_details)
595cf52e 8214 {
55cc53e9 8215 putchar (' ');
595cf52e
L
8216 print_vma (section->sh_addr, LONG_HEX);
8217 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8218 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8219 else
8220 {
8221 printf (" ");
8222 print_vma (section->sh_offset, LONG_HEX);
8223 }
72de5009 8224 printf (" %u\n ", section->sh_link);
595cf52e 8225 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8226 putchar (' ');
595cf52e
L
8227 print_vma (section->sh_entsize, LONG_HEX);
8228
72de5009
AM
8229 printf (" %-16u %lu\n",
8230 section->sh_info,
595cf52e
L
8231 (unsigned long) section->sh_addralign);
8232 }
f7a99963
NC
8233 else
8234 {
8235 putchar (' ');
8236 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8237 if ((long) section->sh_offset == section->sh_offset)
8238 printf (" %8.8lx", (unsigned long) section->sh_offset);
8239 else
8240 {
8241 printf (" ");
8242 print_vma (section->sh_offset, LONG_HEX);
8243 }
f7a99963
NC
8244 printf ("\n ");
8245 print_vma (section->sh_size, LONG_HEX);
8246 printf (" ");
8247 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8248
dda8d76d 8249 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8250
72de5009
AM
8251 printf (" %2u %3u %lu\n",
8252 section->sh_link,
8253 section->sh_info,
f7a99963
NC
8254 (unsigned long) section->sh_addralign);
8255 }
5477e8a0
L
8256
8257 if (do_section_details)
77115a4a 8258 {
dda8d76d 8259 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8260 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8261 {
8262 /* Minimum section size is 12 bytes for 32-bit compression
8263 header + 12 bytes for compressed data header. */
8264 unsigned char buf[24];
d8024a91 8265
77115a4a 8266 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8267 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8268 sizeof (buf), _("compression header")))
8269 {
8270 Elf_Internal_Chdr chdr;
d8024a91 8271
5844b465
NC
8272 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8273 printf (_(" [<corrupt>]\n"));
77115a4a 8274 else
5844b465 8275 {
89dbeac7 8276 if (chdr.ch_type == ch_compress_zlib)
5844b465 8277 printf (" ZLIB, ");
89dbeac7 8278 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8279 printf (" ZSTD, ");
5844b465
NC
8280 else
8281 printf (_(" [<unknown>: 0x%x], "),
8282 chdr.ch_type);
8283 print_vma (chdr.ch_size, LONG_HEX);
8284 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8285 }
77115a4a
L
8286 }
8287 }
8288 }
252b5132
RH
8289 }
8290
5477e8a0 8291 if (!do_section_details)
3dbcc61d 8292 {
9fb71ee4
NC
8293 /* The ordering of the letters shown here matches the ordering of the
8294 corresponding SHF_xxx values, and hence the order in which these
8295 letters will be displayed to the user. */
8296 printf (_("Key to Flags:\n\
8297 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8298 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8299 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8300 switch (filedata->file_header.e_ident[EI_OSABI])
8301 {
8302 case ELFOSABI_GNU:
8303 case ELFOSABI_FREEBSD:
8304 printf (_("R (retain), "));
8305 /* Fall through */
8306 case ELFOSABI_NONE:
8307 printf (_("D (mbind), "));
8308 break;
8309 default:
8310 break;
8311 }
dda8d76d
NC
8312 if (filedata->file_header.e_machine == EM_X86_64
8313 || filedata->file_header.e_machine == EM_L1OM
8314 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8315 printf (_("l (large), "));
dda8d76d 8316 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8317 printf (_("y (purecode), "));
dda8d76d 8318 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8319 printf (_("v (VLE), "));
9fb71ee4 8320 printf ("p (processor specific)\n");
0b4362b0 8321 }
d1133906 8322
015dc7e1 8323 return true;
252b5132
RH
8324}
8325
015dc7e1 8326static bool
28d13567 8327get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
8328 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8329 char **strtab, uint64_t *strtablen)
28d13567
AM
8330{
8331 *strtab = NULL;
8332 *strtablen = 0;
4de91c10 8333 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8334
8335 if (*symtab == NULL)
015dc7e1 8336 return false;
28d13567
AM
8337
8338 if (symsec->sh_link != 0)
8339 {
8340 Elf_Internal_Shdr *strsec;
8341
8342 if (symsec->sh_link >= filedata->file_header.e_shnum)
8343 {
8344 error (_("Bad sh_link in symbol table section\n"));
8345 free (*symtab);
8346 *symtab = NULL;
8347 *nsyms = 0;
015dc7e1 8348 return false;
28d13567
AM
8349 }
8350
8351 strsec = filedata->section_headers + symsec->sh_link;
8352
8353 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8354 1, strsec->sh_size, _("string table"));
8355 if (*strtab == NULL)
8356 {
8357 free (*symtab);
8358 *symtab = NULL;
8359 *nsyms = 0;
015dc7e1 8360 return false;
28d13567
AM
8361 }
8362 *strtablen = strsec->sh_size;
8363 }
015dc7e1 8364 return true;
28d13567
AM
8365}
8366
f5842774
L
8367static const char *
8368get_group_flags (unsigned int flags)
8369{
1449284b 8370 static char buff[128];
220453ec 8371
6d913794
NC
8372 if (flags == 0)
8373 return "";
8374 else if (flags == GRP_COMDAT)
8375 return "COMDAT ";
f5842774 8376
89246a0e
AM
8377 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8378 flags,
8379 flags & GRP_MASKOS ? _("<OS specific>") : "",
8380 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8381 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8382 ? _("<unknown>") : ""));
6d913794 8383
f5842774
L
8384 return buff;
8385}
8386
015dc7e1 8387static bool
dda8d76d 8388process_section_groups (Filedata * filedata)
f5842774 8389{
2cf0635d 8390 Elf_Internal_Shdr * section;
f5842774 8391 unsigned int i;
2cf0635d
NC
8392 struct group * group;
8393 Elf_Internal_Shdr * symtab_sec;
8394 Elf_Internal_Shdr * strtab_sec;
8395 Elf_Internal_Sym * symtab;
26c527e6 8396 uint64_t num_syms;
2cf0635d 8397 char * strtab;
c256ffe7 8398 size_t strtab_size;
d1f5c6e3
L
8399
8400 /* Don't process section groups unless needed. */
8401 if (!do_unwind && !do_section_groups)
015dc7e1 8402 return true;
f5842774 8403
dda8d76d 8404 if (filedata->file_header.e_shnum == 0)
f5842774
L
8405 {
8406 if (do_section_groups)
ca0e11aa
NC
8407 {
8408 if (filedata->is_separate)
8409 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8410 filedata->file_name);
8411 else
8412 printf (_("\nThere are no section groups in this file.\n"));
8413 }
015dc7e1 8414 return true;
f5842774
L
8415 }
8416
dda8d76d 8417 if (filedata->section_headers == NULL)
f5842774
L
8418 {
8419 error (_("Section headers are not available!\n"));
fa1908fd 8420 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8421 return false;
f5842774
L
8422 }
8423
978c4450
AM
8424 filedata->section_headers_groups
8425 = (struct group **) calloc (filedata->file_header.e_shnum,
8426 sizeof (struct group *));
e4b17d5c 8427
978c4450 8428 if (filedata->section_headers_groups == NULL)
e4b17d5c 8429 {
8b73c356 8430 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8431 filedata->file_header.e_shnum);
015dc7e1 8432 return false;
e4b17d5c
L
8433 }
8434
f5842774 8435 /* Scan the sections for the group section. */
978c4450 8436 filedata->group_count = 0;
dda8d76d
NC
8437 for (i = 0, section = filedata->section_headers;
8438 i < filedata->file_header.e_shnum;
f5842774 8439 i++, section++)
e4b17d5c 8440 if (section->sh_type == SHT_GROUP)
978c4450 8441 filedata->group_count++;
e4b17d5c 8442
978c4450 8443 if (filedata->group_count == 0)
d1f5c6e3
L
8444 {
8445 if (do_section_groups)
ca0e11aa
NC
8446 {
8447 if (filedata->is_separate)
8448 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8449 filedata->file_name);
8450 else
8451 printf (_("\nThere are no section groups in this file.\n"));
8452 }
d1f5c6e3 8453
015dc7e1 8454 return true;
d1f5c6e3
L
8455 }
8456
978c4450
AM
8457 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8458 sizeof (struct group));
e4b17d5c 8459
978c4450 8460 if (filedata->section_groups == NULL)
e4b17d5c 8461 {
26c527e6 8462 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8463 return false;
e4b17d5c
L
8464 }
8465
d1f5c6e3
L
8466 symtab_sec = NULL;
8467 strtab_sec = NULL;
8468 symtab = NULL;
ba5cdace 8469 num_syms = 0;
d1f5c6e3 8470 strtab = NULL;
c256ffe7 8471 strtab_size = 0;
ca0e11aa
NC
8472
8473 if (filedata->is_separate)
8474 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8475
978c4450 8476 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8477 i < filedata->file_header.e_shnum;
e4b17d5c 8478 i++, section++)
f5842774
L
8479 {
8480 if (section->sh_type == SHT_GROUP)
8481 {
dda8d76d 8482 const char * name = printable_section_name (filedata, section);
74e1a04b 8483 const char * group_name;
2cf0635d
NC
8484 unsigned char * start;
8485 unsigned char * indices;
f5842774 8486 unsigned int entry, j, size;
2cf0635d
NC
8487 Elf_Internal_Shdr * sec;
8488 Elf_Internal_Sym * sym;
f5842774
L
8489
8490 /* Get the symbol table. */
dda8d76d
NC
8491 if (section->sh_link >= filedata->file_header.e_shnum
8492 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8493 != SHT_SYMTAB))
f5842774
L
8494 {
8495 error (_("Bad sh_link in group section `%s'\n"), name);
8496 continue;
8497 }
d1f5c6e3
L
8498
8499 if (symtab_sec != sec)
8500 {
8501 symtab_sec = sec;
9db70fc3 8502 free (symtab);
4de91c10 8503 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8504 }
f5842774 8505
dd24e3da
NC
8506 if (symtab == NULL)
8507 {
8508 error (_("Corrupt header in group section `%s'\n"), name);
8509 continue;
8510 }
8511
ba5cdace
NC
8512 if (section->sh_info >= num_syms)
8513 {
8514 error (_("Bad sh_info in group section `%s'\n"), name);
8515 continue;
8516 }
8517
f5842774
L
8518 sym = symtab + section->sh_info;
8519
8520 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8521 {
4fbb74a6 8522 if (sym->st_shndx == 0
dda8d76d 8523 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8524 {
8525 error (_("Bad sh_info in group section `%s'\n"), name);
8526 continue;
8527 }
ba2685cc 8528
b6ac461a
NC
8529 group_name = printable_section_name (filedata,
8530 filedata->section_headers
8531 + sym->st_shndx);
c256ffe7 8532 strtab_sec = NULL;
9db70fc3 8533 free (strtab);
f5842774 8534 strtab = NULL;
c256ffe7 8535 strtab_size = 0;
f5842774
L
8536 }
8537 else
8538 {
8539 /* Get the string table. */
dda8d76d 8540 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8541 {
8542 strtab_sec = NULL;
9db70fc3 8543 free (strtab);
c256ffe7
JJ
8544 strtab = NULL;
8545 strtab_size = 0;
8546 }
8547 else if (strtab_sec
dda8d76d 8548 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8549 {
8550 strtab_sec = sec;
9db70fc3 8551 free (strtab);
071436c6 8552
dda8d76d 8553 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8554 1, strtab_sec->sh_size,
8555 _("string table"));
c256ffe7 8556 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8557 }
c256ffe7 8558 group_name = sym->st_name < strtab_size
2b692964 8559 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8560 }
8561
c9c1d674
EG
8562 /* PR 17531: file: loop. */
8563 if (section->sh_entsize > section->sh_size)
8564 {
26c527e6
AM
8565 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8566 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8567 printable_section_name (filedata, section),
26c527e6
AM
8568 section->sh_entsize,
8569 section->sh_size);
61dd8e19 8570 continue;
c9c1d674
EG
8571 }
8572
dda8d76d 8573 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8574 1, section->sh_size,
8575 _("section data"));
59245841
NC
8576 if (start == NULL)
8577 continue;
f5842774
L
8578
8579 indices = start;
8580 size = (section->sh_size / section->sh_entsize) - 1;
8581 entry = byte_get (indices, 4);
8582 indices += 4;
e4b17d5c
L
8583
8584 if (do_section_groups)
8585 {
2b692964 8586 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8587 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8588
e4b17d5c
L
8589 printf (_(" [Index] Name\n"));
8590 }
8591
8592 group->group_index = i;
8593
f5842774
L
8594 for (j = 0; j < size; j++)
8595 {
2cf0635d 8596 struct group_list * g;
e4b17d5c 8597
f5842774
L
8598 entry = byte_get (indices, 4);
8599 indices += 4;
8600
dda8d76d 8601 if (entry >= filedata->file_header.e_shnum)
391cb864 8602 {
57028622
NC
8603 static unsigned num_group_errors = 0;
8604
8605 if (num_group_errors ++ < 10)
8606 {
8607 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8608 entry, i, filedata->file_header.e_shnum - 1);
57028622 8609 if (num_group_errors == 10)
67ce483b 8610 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8611 }
391cb864
L
8612 continue;
8613 }
391cb864 8614
978c4450 8615 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8616 {
d1f5c6e3
L
8617 if (entry)
8618 {
57028622
NC
8619 static unsigned num_errs = 0;
8620
8621 if (num_errs ++ < 10)
8622 {
8623 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8624 entry, i,
978c4450 8625 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8626 if (num_errs == 10)
8627 warn (_("Further error messages about already contained group sections suppressed\n"));
8628 }
d1f5c6e3
L
8629 continue;
8630 }
8631 else
8632 {
8633 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8634 section group. We just warn it the first time
d1f5c6e3 8635 and ignore it afterwards. */
015dc7e1 8636 static bool warned = false;
d1f5c6e3
L
8637 if (!warned)
8638 {
8639 error (_("section 0 in group section [%5u]\n"),
978c4450 8640 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8641 warned = true;
d1f5c6e3
L
8642 }
8643 }
e4b17d5c
L
8644 }
8645
978c4450 8646 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8647
8648 if (do_section_groups)
8649 {
dda8d76d
NC
8650 sec = filedata->section_headers + entry;
8651 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8652 }
8653
3f5e193b 8654 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8655 g->section_index = entry;
8656 g->next = group->root;
8657 group->root = g;
f5842774
L
8658 }
8659
9db70fc3 8660 free (start);
e4b17d5c
L
8661
8662 group++;
f5842774
L
8663 }
8664 }
8665
9db70fc3
AM
8666 free (symtab);
8667 free (strtab);
015dc7e1 8668 return true;
f5842774
L
8669}
8670
28f997cf
TG
8671/* Data used to display dynamic fixups. */
8672
8673struct ia64_vms_dynfixup
8674{
625d49fc
AM
8675 uint64_t needed_ident; /* Library ident number. */
8676 uint64_t needed; /* Index in the dstrtab of the library name. */
8677 uint64_t fixup_needed; /* Index of the library. */
8678 uint64_t fixup_rela_cnt; /* Number of fixups. */
8679 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8680};
8681
8682/* Data used to display dynamic relocations. */
8683
8684struct ia64_vms_dynimgrela
8685{
625d49fc
AM
8686 uint64_t img_rela_cnt; /* Number of relocations. */
8687 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8688};
8689
8690/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8691 library). */
8692
015dc7e1 8693static bool
dda8d76d
NC
8694dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8695 struct ia64_vms_dynfixup * fixup,
8696 const char * strtab,
8697 unsigned int strtab_sz)
28f997cf 8698{
32ec8896 8699 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8700 size_t i;
32ec8896 8701 const char * lib_name;
28f997cf 8702
978c4450
AM
8703 imfs = get_data (NULL, filedata,
8704 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8705 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8706 _("dynamic section image fixups"));
8707 if (!imfs)
015dc7e1 8708 return false;
28f997cf
TG
8709
8710 if (fixup->needed < strtab_sz)
8711 lib_name = strtab + fixup->needed;
8712 else
8713 {
26c527e6
AM
8714 warn (_("corrupt library name index of %#" PRIx64
8715 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8716 lib_name = "???";
8717 }
736990c4 8718
26c527e6
AM
8719 printf (_("\nImage fixups for needed library #%" PRId64
8720 ": %s - ident: %" PRIx64 "\n"),
8721 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8722 printf
8723 (_("Seg Offset Type SymVec DataType\n"));
8724
26c527e6 8725 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8726 {
8727 unsigned int type;
8728 const char *rtype;
8729
8730 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8731 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8732 type = BYTE_GET (imfs [i].type);
8733 rtype = elf_ia64_reloc_type (type);
8734 if (rtype == NULL)
f493c217 8735 printf ("0x%08x ", type);
28f997cf 8736 else
f493c217 8737 printf ("%-32s ", rtype);
28f997cf
TG
8738 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8739 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8740 }
8741
8742 free (imfs);
015dc7e1 8743 return true;
28f997cf
TG
8744}
8745
8746/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8747
015dc7e1 8748static bool
dda8d76d 8749dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8750{
8751 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8752 size_t i;
28f997cf 8753
978c4450
AM
8754 imrs = get_data (NULL, filedata,
8755 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8756 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8757 _("dynamic section image relocations"));
28f997cf 8758 if (!imrs)
015dc7e1 8759 return false;
28f997cf
TG
8760
8761 printf (_("\nImage relocs\n"));
8762 printf
8763 (_("Seg Offset Type Addend Seg Sym Off\n"));
8764
26c527e6 8765 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8766 {
8767 unsigned int type;
8768 const char *rtype;
8769
8770 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8771 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8772 type = BYTE_GET (imrs [i].type);
8773 rtype = elf_ia64_reloc_type (type);
8774 if (rtype == NULL)
8775 printf ("0x%08x ", type);
8776 else
8777 printf ("%-31s ", rtype);
8778 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8779 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8780 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8781 }
8782
8783 free (imrs);
015dc7e1 8784 return true;
28f997cf
TG
8785}
8786
8787/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8788
015dc7e1 8789static bool
dda8d76d 8790process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8791{
8792 struct ia64_vms_dynfixup fixup;
8793 struct ia64_vms_dynimgrela imgrela;
8794 Elf_Internal_Dyn *entry;
625d49fc
AM
8795 uint64_t strtab_off = 0;
8796 uint64_t strtab_sz = 0;
28f997cf 8797 char *strtab = NULL;
015dc7e1 8798 bool res = true;
28f997cf
TG
8799
8800 memset (&fixup, 0, sizeof (fixup));
8801 memset (&imgrela, 0, sizeof (imgrela));
8802
8803 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8804 for (entry = filedata->dynamic_section;
8805 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8806 entry++)
8807 {
8808 switch (entry->d_tag)
8809 {
8810 case DT_IA_64_VMS_STRTAB_OFFSET:
8811 strtab_off = entry->d_un.d_val;
8812 break;
8813 case DT_STRSZ:
8814 strtab_sz = entry->d_un.d_val;
8815 if (strtab == NULL)
978c4450
AM
8816 strtab = get_data (NULL, filedata,
8817 filedata->dynamic_addr + strtab_off,
28f997cf 8818 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8819 if (strtab == NULL)
8820 strtab_sz = 0;
28f997cf
TG
8821 break;
8822
8823 case DT_IA_64_VMS_NEEDED_IDENT:
8824 fixup.needed_ident = entry->d_un.d_val;
8825 break;
8826 case DT_NEEDED:
8827 fixup.needed = entry->d_un.d_val;
8828 break;
8829 case DT_IA_64_VMS_FIXUP_NEEDED:
8830 fixup.fixup_needed = entry->d_un.d_val;
8831 break;
8832 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8833 fixup.fixup_rela_cnt = entry->d_un.d_val;
8834 break;
8835 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8836 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8837 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8838 res = false;
28f997cf 8839 break;
28f997cf
TG
8840 case DT_IA_64_VMS_IMG_RELA_CNT:
8841 imgrela.img_rela_cnt = entry->d_un.d_val;
8842 break;
8843 case DT_IA_64_VMS_IMG_RELA_OFF:
8844 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8845 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8846 res = false;
28f997cf
TG
8847 break;
8848
8849 default:
8850 break;
8851 }
8852 }
8853
9db70fc3 8854 free (strtab);
28f997cf
TG
8855
8856 return res;
8857}
8858
85b1c36d 8859static struct
566b0d53 8860{
2cf0635d 8861 const char * name;
566b0d53
L
8862 int reloc;
8863 int size;
a7fd1186 8864 relocation_type rel_type;
32ec8896
NC
8865}
8866 dynamic_relocations [] =
566b0d53 8867{
a7fd1186
FS
8868 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8869 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8870 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8871 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8872};
8873
252b5132 8874/* Process the reloc section. */
18bd398b 8875
015dc7e1 8876static bool
dda8d76d 8877process_relocs (Filedata * filedata)
252b5132 8878{
26c527e6
AM
8879 uint64_t rel_size;
8880 uint64_t rel_offset;
252b5132 8881
252b5132 8882 if (!do_reloc)
015dc7e1 8883 return true;
252b5132
RH
8884
8885 if (do_using_dynamic)
8886 {
a7fd1186 8887 relocation_type rel_type;
2cf0635d 8888 const char * name;
015dc7e1 8889 bool has_dynamic_reloc;
566b0d53 8890 unsigned int i;
0de14b54 8891
015dc7e1 8892 has_dynamic_reloc = false;
252b5132 8893
566b0d53 8894 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8895 {
a7fd1186 8896 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8897 name = dynamic_relocations [i].name;
978c4450
AM
8898 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8899 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8900
32ec8896 8901 if (rel_size)
015dc7e1 8902 has_dynamic_reloc = true;
566b0d53 8903
a7fd1186 8904 if (rel_type == reltype_unknown)
aa903cfb 8905 {
566b0d53 8906 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8907 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8908 {
8909 case DT_REL:
a7fd1186 8910 rel_type = reltype_rel;
566b0d53
L
8911 break;
8912 case DT_RELA:
a7fd1186 8913 rel_type = reltype_rela;
566b0d53
L
8914 break;
8915 }
aa903cfb 8916 }
252b5132 8917
566b0d53
L
8918 if (rel_size)
8919 {
ca0e11aa
NC
8920 if (filedata->is_separate)
8921 printf
26c527e6
AM
8922 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8923 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8924 filedata->file_name, name, rel_offset, rel_size);
8925 else
8926 printf
26c527e6
AM
8927 (_("\n'%s' relocation section at offset %#" PRIx64
8928 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8929 name, rel_offset, rel_size);
252b5132 8930
dda8d76d
NC
8931 dump_relocations (filedata,
8932 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8933 rel_size,
978c4450
AM
8934 filedata->dynamic_symbols,
8935 filedata->num_dynamic_syms,
8936 filedata->dynamic_strings,
8937 filedata->dynamic_strings_length,
a7fd1186 8938 rel_type, true /* is_dynamic */);
566b0d53 8939 }
252b5132 8940 }
566b0d53 8941
dda8d76d
NC
8942 if (is_ia64_vms (filedata))
8943 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8944 has_dynamic_reloc = true;
28f997cf 8945
566b0d53 8946 if (! has_dynamic_reloc)
ca0e11aa
NC
8947 {
8948 if (filedata->is_separate)
8949 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8950 filedata->file_name);
8951 else
8952 printf (_("\nThere are no dynamic relocations in this file.\n"));
8953 }
252b5132
RH
8954 }
8955 else
8956 {
2cf0635d 8957 Elf_Internal_Shdr * section;
26c527e6 8958 size_t i;
015dc7e1 8959 bool found = false;
252b5132 8960
dda8d76d
NC
8961 for (i = 0, section = filedata->section_headers;
8962 i < filedata->file_header.e_shnum;
b34976b6 8963 i++, section++)
252b5132
RH
8964 {
8965 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8966 && section->sh_type != SHT_REL
8967 && section->sh_type != SHT_RELR)
252b5132
RH
8968 continue;
8969
8970 rel_offset = section->sh_offset;
8971 rel_size = section->sh_size;
8972
8973 if (rel_size)
8974 {
a7fd1186 8975 relocation_type rel_type;
26c527e6 8976 uint64_t num_rela;
103f02d3 8977
ca0e11aa
NC
8978 if (filedata->is_separate)
8979 printf (_("\nIn linked file '%s' relocation section "),
8980 filedata->file_name);
8981 else
8982 printf (_("\nRelocation section "));
252b5132 8983
dda8d76d 8984 if (filedata->string_table == NULL)
19936277 8985 printf ("%d", section->sh_name);
252b5132 8986 else
dda8d76d 8987 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8988
d3a49aa8 8989 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8990 printf (ngettext (" at offset %#" PRIx64
8991 " contains %" PRIu64 " entry:\n",
8992 " at offset %#" PRIx64
8993 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8994 num_rela),
8995 rel_offset, num_rela);
252b5132 8996
a7fd1186
FS
8997 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8998 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8999
4fbb74a6 9000 if (section->sh_link != 0
dda8d76d 9001 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 9002 {
26c527e6
AM
9003 Elf_Internal_Shdr *symsec;
9004 Elf_Internal_Sym *symtab;
9005 uint64_t nsyms;
9006 uint64_t strtablen = 0;
9007 char *strtab = NULL;
57346661 9008
dda8d76d 9009 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
9010 if (symsec->sh_type != SHT_SYMTAB
9011 && symsec->sh_type != SHT_DYNSYM)
9012 continue;
9013
28d13567
AM
9014 if (!get_symtab (filedata, symsec,
9015 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 9016 continue;
252b5132 9017
dda8d76d 9018 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 9019 symtab, nsyms, strtab, strtablen,
a7fd1186 9020 rel_type,
bb4d2ac2 9021 symsec->sh_type == SHT_DYNSYM);
9db70fc3 9022 free (strtab);
d79b3d50
NC
9023 free (symtab);
9024 }
9025 else
dda8d76d 9026 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 9027 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 9028
015dc7e1 9029 found = true;
252b5132
RH
9030 }
9031 }
9032
9033 if (! found)
45ac8f4f
NC
9034 {
9035 /* Users sometimes forget the -D option, so try to be helpful. */
9036 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9037 {
978c4450 9038 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9039 {
ca0e11aa
NC
9040 if (filedata->is_separate)
9041 printf (_("\nThere are no static relocations in linked file '%s'."),
9042 filedata->file_name);
9043 else
9044 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9045 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9046
9047 break;
9048 }
9049 }
9050 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9051 {
9052 if (filedata->is_separate)
9053 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9054 filedata->file_name);
9055 else
9056 printf (_("\nThere are no relocations in this file.\n"));
9057 }
45ac8f4f 9058 }
252b5132
RH
9059 }
9060
015dc7e1 9061 return true;
252b5132
RH
9062}
9063
4d6ed7c8
NC
9064/* An absolute address consists of a section and an offset. If the
9065 section is NULL, the offset itself is the address, otherwise, the
9066 address equals to LOAD_ADDRESS(section) + offset. */
9067
9068struct absaddr
948f632f
DA
9069{
9070 unsigned short section;
625d49fc 9071 uint64_t offset;
948f632f 9072};
4d6ed7c8 9073
948f632f
DA
9074/* Find the nearest symbol at or below ADDR. Returns the symbol
9075 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9076
4d6ed7c8 9077static void
26c527e6
AM
9078find_symbol_for_address (Filedata *filedata,
9079 Elf_Internal_Sym *symtab,
9080 uint64_t nsyms,
9081 const char *strtab,
9082 uint64_t strtab_size,
9083 struct absaddr addr,
9084 const char **symname,
9085 uint64_t *offset)
4d6ed7c8 9086{
625d49fc 9087 uint64_t dist = 0x100000;
2cf0635d 9088 Elf_Internal_Sym * sym;
948f632f
DA
9089 Elf_Internal_Sym * beg;
9090 Elf_Internal_Sym * end;
2cf0635d 9091 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9092
0b6ae522 9093 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9094 beg = symtab;
9095 end = symtab + nsyms;
0b6ae522 9096
948f632f 9097 while (beg < end)
4d6ed7c8 9098 {
625d49fc 9099 uint64_t value;
948f632f
DA
9100
9101 sym = beg + (end - beg) / 2;
0b6ae522 9102
948f632f 9103 value = sym->st_value;
0b6ae522
DJ
9104 REMOVE_ARCH_BITS (value);
9105
948f632f 9106 if (sym->st_name != 0
4d6ed7c8 9107 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9108 && addr.offset >= value
9109 && addr.offset - value < dist)
4d6ed7c8
NC
9110 {
9111 best = sym;
0b6ae522 9112 dist = addr.offset - value;
4d6ed7c8
NC
9113 if (!dist)
9114 break;
9115 }
948f632f
DA
9116
9117 if (addr.offset < value)
9118 end = sym;
9119 else
9120 beg = sym + 1;
4d6ed7c8 9121 }
1b31d05e 9122
4d6ed7c8
NC
9123 if (best)
9124 {
57346661 9125 *symname = (best->st_name >= strtab_size
2b692964 9126 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9127 *offset = dist;
9128 return;
9129 }
1b31d05e 9130
4d6ed7c8
NC
9131 *symname = NULL;
9132 *offset = addr.offset;
9133}
9134
32ec8896 9135static /* signed */ int
948f632f
DA
9136symcmp (const void *p, const void *q)
9137{
9138 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9139 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9140
9141 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9142}
9143
9144/* Process the unwind section. */
9145
9146#include "unwind-ia64.h"
9147
9148struct ia64_unw_table_entry
9149{
9150 struct absaddr start;
9151 struct absaddr end;
9152 struct absaddr info;
9153};
9154
9155struct ia64_unw_aux_info
9156{
32ec8896 9157 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9158 uint64_t table_len; /* Length of unwind table. */
32ec8896 9159 unsigned char * info; /* Unwind info. */
26c527e6 9160 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9161 uint64_t info_addr; /* Starting address of unwind info. */
9162 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9163 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9164 uint64_t nsyms; /* Number of symbols. */
32ec8896 9165 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9166 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9167 char * strtab; /* The string table. */
26c527e6 9168 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9169};
9170
015dc7e1 9171static bool
dda8d76d 9172dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9173{
2cf0635d 9174 struct ia64_unw_table_entry * tp;
26c527e6 9175 size_t j, nfuns;
4d6ed7c8 9176 int in_body;
015dc7e1 9177 bool res = true;
7036c0e1 9178
948f632f
DA
9179 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9180 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9181 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9182 aux->funtab[nfuns++] = aux->symtab[j];
9183 aux->nfuns = nfuns;
9184 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9185
4d6ed7c8
NC
9186 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9187 {
625d49fc
AM
9188 uint64_t stamp;
9189 uint64_t offset;
2cf0635d
NC
9190 const unsigned char * dp;
9191 const unsigned char * head;
53774b7e 9192 const unsigned char * end;
2cf0635d 9193 const char * procname;
4d6ed7c8 9194
dda8d76d 9195 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9196 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9197
9198 fputs ("\n<", stdout);
9199
9200 if (procname)
9201 {
9202 fputs (procname, stdout);
9203
9204 if (offset)
26c527e6 9205 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9206 }
9207
9208 fputs (">: [", stdout);
9209 print_vma (tp->start.offset, PREFIX_HEX);
9210 fputc ('-', stdout);
9211 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9212 printf ("], info at +0x%" PRIx64 "\n",
9213 tp->info.offset - aux->seg_base);
4d6ed7c8 9214
53774b7e
NC
9215 /* PR 17531: file: 86232b32. */
9216 if (aux->info == NULL)
9217 continue;
9218
97c0a079
AM
9219 offset = tp->info.offset;
9220 if (tp->info.section)
9221 {
9222 if (tp->info.section >= filedata->file_header.e_shnum)
9223 {
26c527e6
AM
9224 warn (_("Invalid section %u in table entry %td\n"),
9225 tp->info.section, tp - aux->table);
015dc7e1 9226 res = false;
97c0a079
AM
9227 continue;
9228 }
9229 offset += filedata->section_headers[tp->info.section].sh_addr;
9230 }
9231 offset -= aux->info_addr;
53774b7e 9232 /* PR 17531: file: 0997b4d1. */
90679903
AM
9233 if (offset >= aux->info_size
9234 || aux->info_size - offset < 8)
53774b7e 9235 {
26c527e6
AM
9236 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9237 tp->info.offset, tp - aux->table);
015dc7e1 9238 res = false;
53774b7e
NC
9239 continue;
9240 }
9241
97c0a079 9242 head = aux->info + offset;
a4a00738 9243 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9244
86f55779 9245 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9246 (unsigned) UNW_VER (stamp),
9247 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9248 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9249 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9250 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9251
9252 if (UNW_VER (stamp) != 1)
9253 {
2b692964 9254 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9255 continue;
9256 }
9257
9258 in_body = 0;
53774b7e
NC
9259 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9260 /* PR 17531: file: 16ceda89. */
9261 if (end > aux->info + aux->info_size)
9262 end = aux->info + aux->info_size;
9263 for (dp = head + 8; dp < end;)
b4477bc8 9264 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9265 }
948f632f
DA
9266
9267 free (aux->funtab);
32ec8896
NC
9268
9269 return res;
4d6ed7c8
NC
9270}
9271
015dc7e1 9272static bool
dda8d76d
NC
9273slurp_ia64_unwind_table (Filedata * filedata,
9274 struct ia64_unw_aux_info * aux,
9275 Elf_Internal_Shdr * sec)
4d6ed7c8 9276{
26c527e6 9277 uint64_t size, nrelas, i;
2cf0635d
NC
9278 Elf_Internal_Phdr * seg;
9279 struct ia64_unw_table_entry * tep;
9280 Elf_Internal_Shdr * relsec;
9281 Elf_Internal_Rela * rela;
9282 Elf_Internal_Rela * rp;
9283 unsigned char * table;
9284 unsigned char * tp;
9285 Elf_Internal_Sym * sym;
9286 const char * relname;
4d6ed7c8 9287
53774b7e
NC
9288 aux->table_len = 0;
9289
4d6ed7c8
NC
9290 /* First, find the starting address of the segment that includes
9291 this section: */
9292
dda8d76d 9293 if (filedata->file_header.e_phnum)
4d6ed7c8 9294 {
dda8d76d 9295 if (! get_program_headers (filedata))
015dc7e1 9296 return false;
4d6ed7c8 9297
dda8d76d
NC
9298 for (seg = filedata->program_headers;
9299 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9300 ++seg)
4d6ed7c8
NC
9301 {
9302 if (seg->p_type != PT_LOAD)
9303 continue;
9304
9305 if (sec->sh_addr >= seg->p_vaddr
9306 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9307 {
9308 aux->seg_base = seg->p_vaddr;
9309 break;
9310 }
9311 }
4d6ed7c8
NC
9312 }
9313
9314 /* Second, build the unwind table from the contents of the unwind section: */
9315 size = sec->sh_size;
dda8d76d 9316 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9317 _("unwind table"));
a6e9f9df 9318 if (!table)
015dc7e1 9319 return false;
4d6ed7c8 9320
53774b7e 9321 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9322 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9323 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9324 tep = aux->table;
53774b7e
NC
9325
9326 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9327 {
9328 tep->start.section = SHN_UNDEF;
9329 tep->end.section = SHN_UNDEF;
9330 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9331 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9332 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9333 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9334 tep->start.offset += aux->seg_base;
9335 tep->end.offset += aux->seg_base;
9336 tep->info.offset += aux->seg_base;
9337 }
9338 free (table);
9339
41e92641 9340 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9341 for (relsec = filedata->section_headers;
9342 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9343 ++relsec)
9344 {
9345 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9346 || relsec->sh_info >= filedata->file_header.e_shnum
9347 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9348 continue;
9349
dda8d76d 9350 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9351 & rela, & nrelas))
53774b7e
NC
9352 {
9353 free (aux->table);
9354 aux->table = NULL;
9355 aux->table_len = 0;
015dc7e1 9356 return false;
53774b7e 9357 }
4d6ed7c8
NC
9358
9359 for (rp = rela; rp < rela + nrelas; ++rp)
9360 {
4770fb94 9361 unsigned int sym_ndx;
726bd37d
AM
9362 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9363 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9364
82b1b41b
NC
9365 /* PR 17531: file: 9fa67536. */
9366 if (relname == NULL)
9367 {
726bd37d 9368 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9369 continue;
9370 }
948f632f 9371
24d127aa 9372 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9373 {
82b1b41b 9374 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9375 continue;
9376 }
9377
89fac5e3 9378 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9379
53774b7e
NC
9380 /* PR 17531: file: 5bc8d9bf. */
9381 if (i >= aux->table_len)
9382 {
26c527e6
AM
9383 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9384 i);
53774b7e
NC
9385 continue;
9386 }
9387
4770fb94
AM
9388 sym_ndx = get_reloc_symindex (rp->r_info);
9389 if (sym_ndx >= aux->nsyms)
9390 {
9391 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9392 sym_ndx);
9393 continue;
9394 }
9395 sym = aux->symtab + sym_ndx;
9396
53774b7e 9397 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9398 {
9399 case 0:
9400 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9401 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9402 break;
9403 case 1:
9404 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9405 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9406 break;
9407 case 2:
9408 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9409 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9410 break;
9411 default:
9412 break;
9413 }
9414 }
9415
9416 free (rela);
9417 }
9418
015dc7e1 9419 return true;
4d6ed7c8
NC
9420}
9421
015dc7e1 9422static bool
dda8d76d 9423ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9424{
2cf0635d
NC
9425 Elf_Internal_Shdr * sec;
9426 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9427 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9428 struct ia64_unw_aux_info aux;
015dc7e1 9429 bool res = true;
f1467e33 9430
4d6ed7c8
NC
9431 memset (& aux, 0, sizeof (aux));
9432
dda8d76d 9433 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9434 {
28d13567 9435 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9436 {
28d13567 9437 if (aux.symtab)
4082ef84 9438 {
28d13567
AM
9439 error (_("Multiple symbol tables encountered\n"));
9440 free (aux.symtab);
9441 aux.symtab = NULL;
4082ef84 9442 free (aux.strtab);
28d13567 9443 aux.strtab = NULL;
4082ef84 9444 }
28d13567
AM
9445 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9446 &aux.strtab, &aux.strtab_size))
015dc7e1 9447 return false;
4d6ed7c8
NC
9448 }
9449 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9450 unwcount++;
9451 }
9452
9453 if (!unwcount)
9454 printf (_("\nThere are no unwind sections in this file.\n"));
9455
9456 while (unwcount-- > 0)
9457 {
84714f86 9458 const char *suffix;
579f31ac
JJ
9459 size_t len, len2;
9460
dda8d76d
NC
9461 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9462 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9463 if (sec->sh_type == SHT_IA_64_UNWIND)
9464 {
9465 unwsec = sec;
9466 break;
9467 }
4082ef84
NC
9468 /* We have already counted the number of SHT_IA64_UNWIND
9469 sections so the loop above should never fail. */
9470 assert (unwsec != NULL);
579f31ac
JJ
9471
9472 unwstart = i + 1;
9473 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9474
e4b17d5c
L
9475 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9476 {
9477 /* We need to find which section group it is in. */
4082ef84 9478 struct group_list * g;
e4b17d5c 9479
978c4450
AM
9480 if (filedata->section_headers_groups == NULL
9481 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9482 i = filedata->file_header.e_shnum;
4082ef84 9483 else
e4b17d5c 9484 {
978c4450 9485 g = filedata->section_headers_groups[i]->root;
18bd398b 9486
4082ef84
NC
9487 for (; g != NULL; g = g->next)
9488 {
dda8d76d 9489 sec = filedata->section_headers + g->section_index;
e4b17d5c 9490
84714f86
AM
9491 if (section_name_valid (filedata, sec)
9492 && streq (section_name (filedata, sec),
9493 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9494 break;
9495 }
9496
9497 if (g == NULL)
dda8d76d 9498 i = filedata->file_header.e_shnum;
4082ef84 9499 }
e4b17d5c 9500 }
84714f86
AM
9501 else if (section_name_valid (filedata, unwsec)
9502 && startswith (section_name (filedata, unwsec),
e9b095a5 9503 ELF_STRING_ia64_unwind_once))
579f31ac 9504 {
18bd398b 9505 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9506 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9507 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9508 for (i = 0, sec = filedata->section_headers;
9509 i < filedata->file_header.e_shnum;
579f31ac 9510 ++i, ++sec)
84714f86
AM
9511 if (section_name_valid (filedata, sec)
9512 && startswith (section_name (filedata, sec),
e9b095a5 9513 ELF_STRING_ia64_unwind_info_once)
84714f86 9514 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9515 break;
9516 }
9517 else
9518 {
9519 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9520 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9521 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9522 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9523 suffix = "";
84714f86
AM
9524 if (section_name_valid (filedata, unwsec)
9525 && startswith (section_name (filedata, unwsec),
9526 ELF_STRING_ia64_unwind))
9527 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9528 for (i = 0, sec = filedata->section_headers;
9529 i < filedata->file_header.e_shnum;
579f31ac 9530 ++i, ++sec)
84714f86
AM
9531 if (section_name_valid (filedata, sec)
9532 && startswith (section_name (filedata, sec),
9533 ELF_STRING_ia64_unwind_info)
9534 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9535 break;
9536 }
9537
dda8d76d 9538 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9539 {
9540 printf (_("\nCould not find unwind info section for "));
9541
dda8d76d 9542 if (filedata->string_table == NULL)
579f31ac
JJ
9543 printf ("%d", unwsec->sh_name);
9544 else
dda8d76d 9545 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9546 }
9547 else
4d6ed7c8 9548 {
4d6ed7c8 9549 aux.info_addr = sec->sh_addr;
dda8d76d 9550 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9551 sec->sh_size,
9552 _("unwind info"));
59245841 9553 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9554
579f31ac 9555 printf (_("\nUnwind section "));
4d6ed7c8 9556
dda8d76d 9557 if (filedata->string_table == NULL)
579f31ac
JJ
9558 printf ("%d", unwsec->sh_name);
9559 else
dda8d76d 9560 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9561
26c527e6
AM
9562 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9563 unwsec->sh_offset,
9564 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9565
dda8d76d 9566 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9567 && aux.table_len > 0)
dda8d76d 9568 dump_ia64_unwind (filedata, & aux);
579f31ac 9569
9db70fc3
AM
9570 free ((char *) aux.table);
9571 free ((char *) aux.info);
579f31ac
JJ
9572 aux.table = NULL;
9573 aux.info = NULL;
9574 }
4d6ed7c8 9575 }
4d6ed7c8 9576
9db70fc3
AM
9577 free (aux.symtab);
9578 free ((char *) aux.strtab);
32ec8896
NC
9579
9580 return res;
4d6ed7c8
NC
9581}
9582
3f5e193b 9583struct hppa_unw_table_entry
32ec8896
NC
9584{
9585 struct absaddr start;
9586 struct absaddr end;
9587 unsigned int Cannot_unwind:1; /* 0 */
9588 unsigned int Millicode:1; /* 1 */
9589 unsigned int Millicode_save_sr0:1; /* 2 */
9590 unsigned int Region_description:2; /* 3..4 */
9591 unsigned int reserved1:1; /* 5 */
9592 unsigned int Entry_SR:1; /* 6 */
9593 unsigned int Entry_FR:4; /* Number saved 7..10 */
9594 unsigned int Entry_GR:5; /* Number saved 11..15 */
9595 unsigned int Args_stored:1; /* 16 */
9596 unsigned int Variable_Frame:1; /* 17 */
9597 unsigned int Separate_Package_Body:1; /* 18 */
9598 unsigned int Frame_Extension_Millicode:1; /* 19 */
9599 unsigned int Stack_Overflow_Check:1; /* 20 */
9600 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9601 unsigned int Ada_Region:1; /* 22 */
9602 unsigned int cxx_info:1; /* 23 */
9603 unsigned int cxx_try_catch:1; /* 24 */
9604 unsigned int sched_entry_seq:1; /* 25 */
9605 unsigned int reserved2:1; /* 26 */
9606 unsigned int Save_SP:1; /* 27 */
9607 unsigned int Save_RP:1; /* 28 */
9608 unsigned int Save_MRP_in_frame:1; /* 29 */
9609 unsigned int extn_ptr_defined:1; /* 30 */
9610 unsigned int Cleanup_defined:1; /* 31 */
9611
9612 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9613 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9614 unsigned int Large_frame:1; /* 2 */
9615 unsigned int Pseudo_SP_Set:1; /* 3 */
9616 unsigned int reserved4:1; /* 4 */
9617 unsigned int Total_frame_size:27; /* 5..31 */
9618};
3f5e193b 9619
57346661 9620struct hppa_unw_aux_info
948f632f 9621{
32ec8896 9622 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9623 uint64_t table_len; /* Length of unwind table. */
625d49fc 9624 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9625 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9626 uint64_t nsyms; /* Number of symbols. */
32ec8896 9627 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9628 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9629 char * strtab; /* The string table. */
26c527e6 9630 uint64_t strtab_size; /* Size of string table. */
948f632f 9631};
57346661 9632
015dc7e1 9633static bool
dda8d76d 9634dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9635{
2cf0635d 9636 struct hppa_unw_table_entry * tp;
26c527e6 9637 uint64_t j, nfuns;
015dc7e1 9638 bool res = true;
948f632f
DA
9639
9640 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9641 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9642 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9643 aux->funtab[nfuns++] = aux->symtab[j];
9644 aux->nfuns = nfuns;
9645 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9646
57346661
AM
9647 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9648 {
625d49fc 9649 uint64_t offset;
2cf0635d 9650 const char * procname;
57346661 9651
dda8d76d 9652 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9653 aux->strtab_size, tp->start, &procname,
9654 &offset);
9655
9656 fputs ("\n<", stdout);
9657
9658 if (procname)
9659 {
9660 fputs (procname, stdout);
9661
9662 if (offset)
26c527e6 9663 printf ("+%" PRIx64, offset);
57346661
AM
9664 }
9665
9666 fputs (">: [", stdout);
9667 print_vma (tp->start.offset, PREFIX_HEX);
9668 fputc ('-', stdout);
9669 print_vma (tp->end.offset, PREFIX_HEX);
9670 printf ("]\n\t");
9671
18bd398b
NC
9672#define PF(_m) if (tp->_m) printf (#_m " ");
9673#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9674 PF(Cannot_unwind);
9675 PF(Millicode);
9676 PF(Millicode_save_sr0);
18bd398b 9677 /* PV(Region_description); */
57346661
AM
9678 PF(Entry_SR);
9679 PV(Entry_FR);
9680 PV(Entry_GR);
9681 PF(Args_stored);
9682 PF(Variable_Frame);
9683 PF(Separate_Package_Body);
9684 PF(Frame_Extension_Millicode);
9685 PF(Stack_Overflow_Check);
9686 PF(Two_Instruction_SP_Increment);
9687 PF(Ada_Region);
9688 PF(cxx_info);
9689 PF(cxx_try_catch);
9690 PF(sched_entry_seq);
9691 PF(Save_SP);
9692 PF(Save_RP);
9693 PF(Save_MRP_in_frame);
9694 PF(extn_ptr_defined);
9695 PF(Cleanup_defined);
9696 PF(MPE_XL_interrupt_marker);
9697 PF(HP_UX_interrupt_marker);
9698 PF(Large_frame);
9699 PF(Pseudo_SP_Set);
9700 PV(Total_frame_size);
9701#undef PF
9702#undef PV
9703 }
9704
18bd398b 9705 printf ("\n");
948f632f
DA
9706
9707 free (aux->funtab);
32ec8896
NC
9708
9709 return res;
57346661
AM
9710}
9711
015dc7e1 9712static bool
dda8d76d
NC
9713slurp_hppa_unwind_table (Filedata * filedata,
9714 struct hppa_unw_aux_info * aux,
9715 Elf_Internal_Shdr * sec)
57346661 9716{
26c527e6 9717 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9718 Elf_Internal_Phdr * seg;
9719 struct hppa_unw_table_entry * tep;
9720 Elf_Internal_Shdr * relsec;
9721 Elf_Internal_Rela * rela;
9722 Elf_Internal_Rela * rp;
9723 unsigned char * table;
9724 unsigned char * tp;
9725 Elf_Internal_Sym * sym;
9726 const char * relname;
57346661 9727
57346661
AM
9728 /* First, find the starting address of the segment that includes
9729 this section. */
dda8d76d 9730 if (filedata->file_header.e_phnum)
57346661 9731 {
dda8d76d 9732 if (! get_program_headers (filedata))
015dc7e1 9733 return false;
57346661 9734
dda8d76d
NC
9735 for (seg = filedata->program_headers;
9736 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9737 ++seg)
9738 {
9739 if (seg->p_type != PT_LOAD)
9740 continue;
9741
9742 if (sec->sh_addr >= seg->p_vaddr
9743 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9744 {
9745 aux->seg_base = seg->p_vaddr;
9746 break;
9747 }
9748 }
9749 }
9750
9751 /* Second, build the unwind table from the contents of the unwind
9752 section. */
9753 size = sec->sh_size;
dda8d76d 9754 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9755 _("unwind table"));
57346661 9756 if (!table)
015dc7e1 9757 return false;
57346661 9758
1c0751b2
DA
9759 unw_ent_size = 16;
9760 nentries = size / unw_ent_size;
9761 size = unw_ent_size * nentries;
57346661 9762
e3fdc001 9763 aux->table_len = nentries;
3f5e193b
NC
9764 tep = aux->table = (struct hppa_unw_table_entry *)
9765 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9766
1c0751b2 9767 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9768 {
9769 unsigned int tmp1, tmp2;
9770
9771 tep->start.section = SHN_UNDEF;
9772 tep->end.section = SHN_UNDEF;
9773
1c0751b2
DA
9774 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9775 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9776 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9777 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9778
9779 tep->start.offset += aux->seg_base;
9780 tep->end.offset += aux->seg_base;
57346661
AM
9781
9782 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9783 tep->Millicode = (tmp1 >> 30) & 0x1;
9784 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9785 tep->Region_description = (tmp1 >> 27) & 0x3;
9786 tep->reserved1 = (tmp1 >> 26) & 0x1;
9787 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9788 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9789 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9790 tep->Args_stored = (tmp1 >> 15) & 0x1;
9791 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9792 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9793 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9794 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9795 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9796 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9797 tep->cxx_info = (tmp1 >> 8) & 0x1;
9798 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9799 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9800 tep->reserved2 = (tmp1 >> 5) & 0x1;
9801 tep->Save_SP = (tmp1 >> 4) & 0x1;
9802 tep->Save_RP = (tmp1 >> 3) & 0x1;
9803 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9804 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9805 tep->Cleanup_defined = tmp1 & 0x1;
9806
9807 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9808 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9809 tep->Large_frame = (tmp2 >> 29) & 0x1;
9810 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9811 tep->reserved4 = (tmp2 >> 27) & 0x1;
9812 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9813 }
9814 free (table);
9815
9816 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9817 for (relsec = filedata->section_headers;
9818 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9819 ++relsec)
9820 {
9821 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9822 || relsec->sh_info >= filedata->file_header.e_shnum
9823 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9824 continue;
9825
dda8d76d 9826 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9827 & rela, & nrelas))
015dc7e1 9828 return false;
57346661
AM
9829
9830 for (rp = rela; rp < rela + nrelas; ++rp)
9831 {
4770fb94 9832 unsigned int sym_ndx;
726bd37d
AM
9833 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9834 relname = elf_hppa_reloc_type (r_type);
57346661 9835
726bd37d
AM
9836 if (relname == NULL)
9837 {
9838 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9839 continue;
9840 }
9841
57346661 9842 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9843 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9844 {
726bd37d 9845 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9846 continue;
9847 }
9848
9849 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9850 if (i >= aux->table_len)
9851 {
26c527e6
AM
9852 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9853 i);
726bd37d
AM
9854 continue;
9855 }
57346661 9856
4770fb94
AM
9857 sym_ndx = get_reloc_symindex (rp->r_info);
9858 if (sym_ndx >= aux->nsyms)
9859 {
9860 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9861 sym_ndx);
9862 continue;
9863 }
9864 sym = aux->symtab + sym_ndx;
9865
43f6cd05 9866 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9867 {
9868 case 0:
9869 aux->table[i].start.section = sym->st_shndx;
1e456d54 9870 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9871 break;
9872 case 1:
9873 aux->table[i].end.section = sym->st_shndx;
1e456d54 9874 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9875 break;
9876 default:
9877 break;
9878 }
9879 }
9880
9881 free (rela);
9882 }
9883
015dc7e1 9884 return true;
57346661
AM
9885}
9886
015dc7e1 9887static bool
dda8d76d 9888hppa_process_unwind (Filedata * filedata)
57346661 9889{
57346661 9890 struct hppa_unw_aux_info aux;
2cf0635d 9891 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9892 Elf_Internal_Shdr * sec;
26c527e6 9893 size_t i;
015dc7e1 9894 bool res = true;
57346661 9895
dda8d76d 9896 if (filedata->string_table == NULL)
015dc7e1 9897 return false;
1b31d05e
NC
9898
9899 memset (& aux, 0, sizeof (aux));
57346661 9900
dda8d76d 9901 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9902 {
28d13567 9903 if (sec->sh_type == SHT_SYMTAB)
57346661 9904 {
28d13567 9905 if (aux.symtab)
4082ef84 9906 {
28d13567
AM
9907 error (_("Multiple symbol tables encountered\n"));
9908 free (aux.symtab);
9909 aux.symtab = NULL;
4082ef84 9910 free (aux.strtab);
28d13567 9911 aux.strtab = NULL;
4082ef84 9912 }
28d13567
AM
9913 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9914 &aux.strtab, &aux.strtab_size))
015dc7e1 9915 return false;
57346661 9916 }
84714f86
AM
9917 else if (section_name_valid (filedata, sec)
9918 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9919 unwsec = sec;
9920 }
9921
9922 if (!unwsec)
9923 printf (_("\nThere are no unwind sections in this file.\n"));
9924
dda8d76d 9925 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9926 {
84714f86
AM
9927 if (section_name_valid (filedata, sec)
9928 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9929 {
26c527e6 9930 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9931
26c527e6
AM
9932 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9933 "contains %" PRIu64 " entry:\n",
9934 "\nUnwind section '%s' at offset %#" PRIx64 " "
9935 "contains %" PRIu64 " entries:\n",
d3a49aa8 9936 num_unwind),
dda8d76d 9937 printable_section_name (filedata, sec),
26c527e6 9938 sec->sh_offset,
d3a49aa8 9939 num_unwind);
57346661 9940
dda8d76d 9941 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9942 res = false;
66b09c7e
S
9943
9944 if (res && aux.table_len > 0)
32ec8896 9945 {
dda8d76d 9946 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9947 res = false;
32ec8896 9948 }
57346661 9949
9db70fc3 9950 free ((char *) aux.table);
57346661
AM
9951 aux.table = NULL;
9952 }
9953 }
9954
9db70fc3
AM
9955 free (aux.symtab);
9956 free ((char *) aux.strtab);
32ec8896
NC
9957
9958 return res;
57346661
AM
9959}
9960
0b6ae522
DJ
9961struct arm_section
9962{
a734115a
NC
9963 unsigned char * data; /* The unwind data. */
9964 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9965 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9966 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9967 unsigned int rel_type; /* REL or RELA ? */
9968 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9969};
9970
9971struct arm_unw_aux_info
9972{
dda8d76d 9973 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9974 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9975 uint64_t nsyms; /* Number of symbols. */
948f632f 9976 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9977 uint64_t nfuns; /* Number of these symbols. */
a734115a 9978 char * strtab; /* The file's string table. */
26c527e6 9979 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9980};
9981
9982static const char *
dda8d76d
NC
9983arm_print_vma_and_name (Filedata * filedata,
9984 struct arm_unw_aux_info * aux,
625d49fc 9985 uint64_t fn,
dda8d76d 9986 struct absaddr addr)
0b6ae522
DJ
9987{
9988 const char *procname;
625d49fc 9989 uint64_t sym_offset;
0b6ae522
DJ
9990
9991 if (addr.section == SHN_UNDEF)
9992 addr.offset = fn;
9993
dda8d76d 9994 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9995 aux->strtab_size, addr, &procname,
9996 &sym_offset);
9997
9998 print_vma (fn, PREFIX_HEX);
9999
10000 if (procname)
10001 {
10002 fputs (" <", stdout);
10003 fputs (procname, stdout);
10004
10005 if (sym_offset)
26c527e6 10006 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10007 fputc ('>', stdout);
10008 }
10009
10010 return procname;
10011}
10012
10013static void
10014arm_free_section (struct arm_section *arm_sec)
10015{
9db70fc3
AM
10016 free (arm_sec->data);
10017 free (arm_sec->rela);
0b6ae522
DJ
10018}
10019
a734115a
NC
10020/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10021 cached section and install SEC instead.
10022 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10023 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10024 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10025 relocation's offset in ADDR.
1b31d05e
NC
10026 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10027 into the string table of the symbol associated with the reloc. If no
10028 reloc was applied store -1 there.
10029 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10030
015dc7e1 10031static bool
dda8d76d
NC
10032get_unwind_section_word (Filedata * filedata,
10033 struct arm_unw_aux_info * aux,
1b31d05e
NC
10034 struct arm_section * arm_sec,
10035 Elf_Internal_Shdr * sec,
625d49fc 10036 uint64_t word_offset,
1b31d05e
NC
10037 unsigned int * wordp,
10038 struct absaddr * addr,
625d49fc 10039 uint64_t * sym_name)
0b6ae522
DJ
10040{
10041 Elf_Internal_Rela *rp;
10042 Elf_Internal_Sym *sym;
10043 const char * relname;
10044 unsigned int word;
015dc7e1 10045 bool wrapped;
0b6ae522 10046
e0a31db1 10047 if (sec == NULL || arm_sec == NULL)
015dc7e1 10048 return false;
e0a31db1 10049
0b6ae522
DJ
10050 addr->section = SHN_UNDEF;
10051 addr->offset = 0;
10052
1b31d05e 10053 if (sym_name != NULL)
625d49fc 10054 *sym_name = (uint64_t) -1;
1b31d05e 10055
a734115a 10056 /* If necessary, update the section cache. */
0b6ae522
DJ
10057 if (sec != arm_sec->sec)
10058 {
10059 Elf_Internal_Shdr *relsec;
10060
10061 arm_free_section (arm_sec);
10062
10063 arm_sec->sec = sec;
dda8d76d 10064 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10065 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10066 arm_sec->rela = NULL;
10067 arm_sec->nrelas = 0;
10068
dda8d76d
NC
10069 for (relsec = filedata->section_headers;
10070 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10071 ++relsec)
10072 {
dda8d76d
NC
10073 if (relsec->sh_info >= filedata->file_header.e_shnum
10074 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10075 /* PR 15745: Check the section type as well. */
10076 || (relsec->sh_type != SHT_REL
10077 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10078 continue;
10079
a734115a 10080 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10081 if (relsec->sh_type == SHT_REL)
10082 {
dda8d76d 10083 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10084 relsec->sh_size,
10085 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10086 return false;
0b6ae522 10087 }
1ae40aa4 10088 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10089 {
dda8d76d 10090 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10091 relsec->sh_size,
10092 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10093 return false;
0b6ae522 10094 }
1ae40aa4 10095 break;
0b6ae522
DJ
10096 }
10097
10098 arm_sec->next_rela = arm_sec->rela;
10099 }
10100
a734115a 10101 /* If there is no unwind data we can do nothing. */
0b6ae522 10102 if (arm_sec->data == NULL)
015dc7e1 10103 return false;
0b6ae522 10104
e0a31db1 10105 /* If the offset is invalid then fail. */
f32ba729
NC
10106 if (/* PR 21343 *//* PR 18879 */
10107 sec->sh_size < 4
625d49fc 10108 || word_offset > sec->sh_size - 4)
015dc7e1 10109 return false;
e0a31db1 10110
a734115a 10111 /* Get the word at the required offset. */
0b6ae522
DJ
10112 word = byte_get (arm_sec->data + word_offset, 4);
10113
0eff7165
NC
10114 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10115 if (arm_sec->rela == NULL)
10116 {
10117 * wordp = word;
015dc7e1 10118 return true;
0eff7165
NC
10119 }
10120
a734115a 10121 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10122 wrapped = false;
0b6ae522
DJ
10123 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10124 {
625d49fc 10125 uint64_t prelval, offset;
0b6ae522
DJ
10126
10127 if (rp->r_offset > word_offset && !wrapped)
10128 {
10129 rp = arm_sec->rela;
015dc7e1 10130 wrapped = true;
0b6ae522
DJ
10131 }
10132 if (rp->r_offset > word_offset)
10133 break;
10134
10135 if (rp->r_offset & 3)
10136 {
26c527e6
AM
10137 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10138 rp->r_offset);
0b6ae522
DJ
10139 continue;
10140 }
10141
10142 if (rp->r_offset < word_offset)
10143 continue;
10144
74e1a04b
NC
10145 /* PR 17531: file: 027-161405-0.004 */
10146 if (aux->symtab == NULL)
10147 continue;
10148
0b6ae522
DJ
10149 if (arm_sec->rel_type == SHT_REL)
10150 {
10151 offset = word & 0x7fffffff;
10152 if (offset & 0x40000000)
625d49fc 10153 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10154 }
a734115a 10155 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10156 offset = rp->r_addend;
a734115a 10157 else
74e1a04b
NC
10158 {
10159 error (_("Unknown section relocation type %d encountered\n"),
10160 arm_sec->rel_type);
10161 break;
10162 }
0b6ae522 10163
071436c6
NC
10164 /* PR 17531 file: 027-1241568-0.004. */
10165 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10166 {
26c527e6
AM
10167 error (_("Bad symbol index in unwind relocation "
10168 "(%" PRIu64 " > %" PRIu64 ")\n"),
10169 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10170 break;
10171 }
10172
10173 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10174 offset += sym->st_value;
10175 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10176
a734115a 10177 /* Check that we are processing the expected reloc type. */
dda8d76d 10178 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10179 {
10180 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10181 if (relname == NULL)
10182 {
10183 warn (_("Skipping unknown ARM relocation type: %d\n"),
10184 (int) ELF32_R_TYPE (rp->r_info));
10185 continue;
10186 }
a734115a
NC
10187
10188 if (streq (relname, "R_ARM_NONE"))
10189 continue;
0b4362b0 10190
a734115a
NC
10191 if (! streq (relname, "R_ARM_PREL31"))
10192 {
071436c6 10193 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10194 continue;
10195 }
10196 }
dda8d76d 10197 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10198 {
10199 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10200 if (relname == NULL)
10201 {
10202 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10203 (int) ELF32_R_TYPE (rp->r_info));
10204 continue;
10205 }
0b4362b0 10206
a734115a
NC
10207 if (streq (relname, "R_C6000_NONE"))
10208 continue;
10209
10210 if (! streq (relname, "R_C6000_PREL31"))
10211 {
071436c6 10212 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10213 continue;
10214 }
10215
10216 prelval >>= 1;
10217 }
10218 else
74e1a04b
NC
10219 {
10220 /* This function currently only supports ARM and TI unwinders. */
10221 warn (_("Only TI and ARM unwinders are currently supported\n"));
10222 break;
10223 }
fa197c1c 10224
625d49fc 10225 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10226 addr->section = sym->st_shndx;
10227 addr->offset = offset;
74e1a04b 10228
1b31d05e
NC
10229 if (sym_name)
10230 * sym_name = sym->st_name;
0b6ae522
DJ
10231 break;
10232 }
10233
10234 *wordp = word;
10235 arm_sec->next_rela = rp;
10236
015dc7e1 10237 return true;
0b6ae522
DJ
10238}
10239
a734115a
NC
10240static const char *tic6x_unwind_regnames[16] =
10241{
0b4362b0
RM
10242 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10243 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10244 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10245};
fa197c1c 10246
0b6ae522 10247static void
fa197c1c 10248decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10249{
fa197c1c
PB
10250 int i;
10251
10252 for (i = 12; mask; mask >>= 1, i--)
10253 {
10254 if (mask & 1)
10255 {
10256 fputs (tic6x_unwind_regnames[i], stdout);
10257 if (mask > 1)
10258 fputs (", ", stdout);
10259 }
10260 }
10261}
0b6ae522
DJ
10262
10263#define ADVANCE \
10264 if (remaining == 0 && more_words) \
10265 { \
10266 data_offset += 4; \
dda8d76d 10267 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10268 data_offset, & word, & addr, NULL)) \
015dc7e1 10269 return false; \
0b6ae522
DJ
10270 remaining = 4; \
10271 more_words--; \
10272 } \
10273
10274#define GET_OP(OP) \
10275 ADVANCE; \
10276 if (remaining) \
10277 { \
10278 remaining--; \
10279 (OP) = word >> 24; \
10280 word <<= 8; \
10281 } \
10282 else \
10283 { \
2b692964 10284 printf (_("[Truncated opcode]\n")); \
015dc7e1 10285 return false; \
0b6ae522 10286 } \
cc5914eb 10287 printf ("0x%02x ", OP)
0b6ae522 10288
015dc7e1 10289static bool
dda8d76d
NC
10290decode_arm_unwind_bytecode (Filedata * filedata,
10291 struct arm_unw_aux_info * aux,
948f632f
DA
10292 unsigned int word,
10293 unsigned int remaining,
10294 unsigned int more_words,
625d49fc 10295 uint64_t data_offset,
948f632f
DA
10296 Elf_Internal_Shdr * data_sec,
10297 struct arm_section * data_arm_sec)
fa197c1c
PB
10298{
10299 struct absaddr addr;
015dc7e1 10300 bool res = true;
0b6ae522
DJ
10301
10302 /* Decode the unwinding instructions. */
10303 while (1)
10304 {
10305 unsigned int op, op2;
10306
10307 ADVANCE;
10308 if (remaining == 0)
10309 break;
10310 remaining--;
10311 op = word >> 24;
10312 word <<= 8;
10313
cc5914eb 10314 printf (" 0x%02x ", op);
0b6ae522
DJ
10315
10316 if ((op & 0xc0) == 0x00)
10317 {
10318 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10319
cc5914eb 10320 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10321 }
10322 else if ((op & 0xc0) == 0x40)
10323 {
10324 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10325
cc5914eb 10326 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10327 }
10328 else if ((op & 0xf0) == 0x80)
10329 {
10330 GET_OP (op2);
10331 if (op == 0x80 && op2 == 0)
10332 printf (_("Refuse to unwind"));
10333 else
10334 {
10335 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10336 bool first = true;
0b6ae522 10337 int i;
2b692964 10338
0b6ae522
DJ
10339 printf ("pop {");
10340 for (i = 0; i < 12; i++)
10341 if (mask & (1 << i))
10342 {
10343 if (first)
015dc7e1 10344 first = false;
0b6ae522
DJ
10345 else
10346 printf (", ");
10347 printf ("r%d", 4 + i);
10348 }
10349 printf ("}");
10350 }
10351 }
10352 else if ((op & 0xf0) == 0x90)
10353 {
10354 if (op == 0x9d || op == 0x9f)
10355 printf (_(" [Reserved]"));
10356 else
cc5914eb 10357 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10358 }
10359 else if ((op & 0xf0) == 0xa0)
10360 {
10361 int end = 4 + (op & 0x07);
015dc7e1 10362 bool first = true;
0b6ae522 10363 int i;
61865e30 10364
0b6ae522
DJ
10365 printf (" pop {");
10366 for (i = 4; i <= end; i++)
10367 {
10368 if (first)
015dc7e1 10369 first = false;
0b6ae522
DJ
10370 else
10371 printf (", ");
10372 printf ("r%d", i);
10373 }
10374 if (op & 0x08)
10375 {
1b31d05e 10376 if (!first)
0b6ae522
DJ
10377 printf (", ");
10378 printf ("r14");
10379 }
10380 printf ("}");
10381 }
10382 else if (op == 0xb0)
10383 printf (_(" finish"));
10384 else if (op == 0xb1)
10385 {
10386 GET_OP (op2);
10387 if (op2 == 0 || (op2 & 0xf0) != 0)
10388 printf (_("[Spare]"));
10389 else
10390 {
10391 unsigned int mask = op2 & 0x0f;
015dc7e1 10392 bool first = true;
0b6ae522 10393 int i;
61865e30 10394
0b6ae522
DJ
10395 printf ("pop {");
10396 for (i = 0; i < 12; i++)
10397 if (mask & (1 << i))
10398 {
10399 if (first)
015dc7e1 10400 first = false;
0b6ae522
DJ
10401 else
10402 printf (", ");
10403 printf ("r%d", i);
10404 }
10405 printf ("}");
10406 }
10407 }
10408 else if (op == 0xb2)
10409 {
b115cf96 10410 unsigned char buf[9];
0b6ae522 10411 unsigned int i, len;
26c527e6 10412 uint64_t offset;
61865e30 10413
b115cf96 10414 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10415 {
10416 GET_OP (buf[i]);
10417 if ((buf[i] & 0x80) == 0)
10418 break;
10419 }
4082ef84 10420 if (i == sizeof (buf))
32ec8896 10421 {
27a45f42 10422 error (_("corrupt change to vsp\n"));
015dc7e1 10423 res = false;
32ec8896 10424 }
4082ef84
NC
10425 else
10426 {
015dc7e1 10427 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10428 assert (len == i + 1);
10429 offset = offset * 4 + 0x204;
26c527e6 10430 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10431 }
0b6ae522 10432 }
61865e30 10433 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10434 {
61865e30
NC
10435 unsigned int first, last;
10436
10437 GET_OP (op2);
10438 first = op2 >> 4;
10439 last = op2 & 0x0f;
10440 if (op == 0xc8)
10441 first = first + 16;
10442 printf ("pop {D%d", first);
10443 if (last)
10444 printf ("-D%d", first + last);
10445 printf ("}");
10446 }
09854a88
TB
10447 else if (op == 0xb4)
10448 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10449 else if (op == 0xb5)
10450 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10451 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10452 {
10453 unsigned int count = op & 0x07;
10454
10455 printf ("pop {D8");
10456 if (count)
10457 printf ("-D%d", 8 + count);
10458 printf ("}");
10459 }
10460 else if (op >= 0xc0 && op <= 0xc5)
10461 {
10462 unsigned int count = op & 0x07;
10463
10464 printf (" pop {wR10");
10465 if (count)
10466 printf ("-wR%d", 10 + count);
10467 printf ("}");
10468 }
10469 else if (op == 0xc6)
10470 {
10471 unsigned int first, last;
10472
10473 GET_OP (op2);
10474 first = op2 >> 4;
10475 last = op2 & 0x0f;
10476 printf ("pop {wR%d", first);
10477 if (last)
10478 printf ("-wR%d", first + last);
10479 printf ("}");
10480 }
10481 else if (op == 0xc7)
10482 {
10483 GET_OP (op2);
10484 if (op2 == 0 || (op2 & 0xf0) != 0)
10485 printf (_("[Spare]"));
0b6ae522
DJ
10486 else
10487 {
61865e30 10488 unsigned int mask = op2 & 0x0f;
015dc7e1 10489 bool first = true;
61865e30
NC
10490 int i;
10491
10492 printf ("pop {");
10493 for (i = 0; i < 4; i++)
10494 if (mask & (1 << i))
10495 {
10496 if (first)
015dc7e1 10497 first = false;
61865e30
NC
10498 else
10499 printf (", ");
10500 printf ("wCGR%d", i);
10501 }
10502 printf ("}");
0b6ae522
DJ
10503 }
10504 }
61865e30 10505 else
32ec8896
NC
10506 {
10507 printf (_(" [unsupported opcode]"));
015dc7e1 10508 res = false;
32ec8896
NC
10509 }
10510
0b6ae522
DJ
10511 printf ("\n");
10512 }
32ec8896
NC
10513
10514 return res;
fa197c1c
PB
10515}
10516
015dc7e1 10517static bool
dda8d76d
NC
10518decode_tic6x_unwind_bytecode (Filedata * filedata,
10519 struct arm_unw_aux_info * aux,
948f632f
DA
10520 unsigned int word,
10521 unsigned int remaining,
10522 unsigned int more_words,
625d49fc 10523 uint64_t data_offset,
948f632f
DA
10524 Elf_Internal_Shdr * data_sec,
10525 struct arm_section * data_arm_sec)
fa197c1c
PB
10526{
10527 struct absaddr addr;
10528
10529 /* Decode the unwinding instructions. */
10530 while (1)
10531 {
10532 unsigned int op, op2;
10533
10534 ADVANCE;
10535 if (remaining == 0)
10536 break;
10537 remaining--;
10538 op = word >> 24;
10539 word <<= 8;
10540
9cf03b7e 10541 printf (" 0x%02x ", op);
fa197c1c
PB
10542
10543 if ((op & 0xc0) == 0x00)
10544 {
10545 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10546 printf (" sp = sp + %d", offset);
fa197c1c
PB
10547 }
10548 else if ((op & 0xc0) == 0x80)
10549 {
10550 GET_OP (op2);
10551 if (op == 0x80 && op2 == 0)
10552 printf (_("Refuse to unwind"));
10553 else
10554 {
10555 unsigned int mask = ((op & 0x1f) << 8) | op2;
10556 if (op & 0x20)
10557 printf ("pop compact {");
10558 else
10559 printf ("pop {");
10560
10561 decode_tic6x_unwind_regmask (mask);
10562 printf("}");
10563 }
10564 }
10565 else if ((op & 0xf0) == 0xc0)
10566 {
10567 unsigned int reg;
10568 unsigned int nregs;
10569 unsigned int i;
10570 const char *name;
a734115a
NC
10571 struct
10572 {
32ec8896
NC
10573 unsigned int offset;
10574 unsigned int reg;
fa197c1c
PB
10575 } regpos[16];
10576
10577 /* Scan entire instruction first so that GET_OP output is not
10578 interleaved with disassembly. */
10579 nregs = 0;
10580 for (i = 0; nregs < (op & 0xf); i++)
10581 {
10582 GET_OP (op2);
10583 reg = op2 >> 4;
10584 if (reg != 0xf)
10585 {
10586 regpos[nregs].offset = i * 2;
10587 regpos[nregs].reg = reg;
10588 nregs++;
10589 }
10590
10591 reg = op2 & 0xf;
10592 if (reg != 0xf)
10593 {
10594 regpos[nregs].offset = i * 2 + 1;
10595 regpos[nregs].reg = reg;
10596 nregs++;
10597 }
10598 }
10599
10600 printf (_("pop frame {"));
18344509 10601 if (nregs == 0)
fa197c1c 10602 {
18344509
NC
10603 printf (_("*corrupt* - no registers specified"));
10604 }
10605 else
10606 {
10607 reg = nregs - 1;
10608 for (i = i * 2; i > 0; i--)
fa197c1c 10609 {
18344509
NC
10610 if (regpos[reg].offset == i - 1)
10611 {
10612 name = tic6x_unwind_regnames[regpos[reg].reg];
10613 if (reg > 0)
10614 reg--;
10615 }
10616 else
10617 name = _("[pad]");
fa197c1c 10618
18344509
NC
10619 fputs (name, stdout);
10620 if (i > 1)
10621 printf (", ");
10622 }
fa197c1c
PB
10623 }
10624
10625 printf ("}");
10626 }
10627 else if (op == 0xd0)
10628 printf (" MOV FP, SP");
10629 else if (op == 0xd1)
10630 printf (" __c6xabi_pop_rts");
10631 else if (op == 0xd2)
10632 {
10633 unsigned char buf[9];
10634 unsigned int i, len;
26c527e6 10635 uint64_t offset;
a734115a 10636
fa197c1c
PB
10637 for (i = 0; i < sizeof (buf); i++)
10638 {
10639 GET_OP (buf[i]);
10640 if ((buf[i] & 0x80) == 0)
10641 break;
10642 }
0eff7165
NC
10643 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10644 if (i == sizeof (buf))
10645 {
0eff7165 10646 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10647 return false;
0eff7165 10648 }
948f632f 10649
015dc7e1 10650 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10651 assert (len == i + 1);
10652 offset = offset * 8 + 0x408;
26c527e6 10653 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10654 }
10655 else if ((op & 0xf0) == 0xe0)
10656 {
10657 if ((op & 0x0f) == 7)
10658 printf (" RETURN");
10659 else
10660 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10661 }
10662 else
10663 {
10664 printf (_(" [unsupported opcode]"));
10665 }
10666 putchar ('\n');
10667 }
32ec8896 10668
015dc7e1 10669 return true;
fa197c1c
PB
10670}
10671
625d49fc
AM
10672static uint64_t
10673arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10674{
625d49fc 10675 uint64_t offset;
fa197c1c
PB
10676
10677 offset = word & 0x7fffffff;
10678 if (offset & 0x40000000)
625d49fc 10679 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10680
dda8d76d 10681 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10682 offset <<= 1;
10683
10684 return offset + where;
10685}
10686
015dc7e1 10687static bool
dda8d76d
NC
10688decode_arm_unwind (Filedata * filedata,
10689 struct arm_unw_aux_info * aux,
1b31d05e
NC
10690 unsigned int word,
10691 unsigned int remaining,
625d49fc 10692 uint64_t data_offset,
1b31d05e
NC
10693 Elf_Internal_Shdr * data_sec,
10694 struct arm_section * data_arm_sec)
fa197c1c
PB
10695{
10696 int per_index;
10697 unsigned int more_words = 0;
37e14bc3 10698 struct absaddr addr;
625d49fc 10699 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10700 bool res = true;
fa197c1c
PB
10701
10702 if (remaining == 0)
10703 {
1b31d05e
NC
10704 /* Fetch the first word.
10705 Note - when decoding an object file the address extracted
10706 here will always be 0. So we also pass in the sym_name
10707 parameter so that we can find the symbol associated with
10708 the personality routine. */
dda8d76d 10709 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10710 & word, & addr, & sym_name))
015dc7e1 10711 return false;
1b31d05e 10712
fa197c1c
PB
10713 remaining = 4;
10714 }
c93dbb25
CZ
10715 else
10716 {
10717 addr.section = SHN_UNDEF;
10718 addr.offset = 0;
10719 }
fa197c1c
PB
10720
10721 if ((word & 0x80000000) == 0)
10722 {
10723 /* Expand prel31 for personality routine. */
625d49fc 10724 uint64_t fn;
fa197c1c
PB
10725 const char *procname;
10726
dda8d76d 10727 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10728 printf (_(" Personality routine: "));
1b31d05e
NC
10729 if (fn == 0
10730 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10731 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10732 {
10733 procname = aux->strtab + sym_name;
10734 print_vma (fn, PREFIX_HEX);
10735 if (procname)
10736 {
10737 fputs (" <", stdout);
10738 fputs (procname, stdout);
10739 fputc ('>', stdout);
10740 }
10741 }
10742 else
dda8d76d 10743 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10744 fputc ('\n', stdout);
10745
10746 /* The GCC personality routines use the standard compact
10747 encoding, starting with one byte giving the number of
10748 words. */
10749 if (procname != NULL
24d127aa
ML
10750 && (startswith (procname, "__gcc_personality_v0")
10751 || startswith (procname, "__gxx_personality_v0")
10752 || startswith (procname, "__gcj_personality_v0")
10753 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10754 {
10755 remaining = 0;
10756 more_words = 1;
10757 ADVANCE;
10758 if (!remaining)
10759 {
10760 printf (_(" [Truncated data]\n"));
015dc7e1 10761 return false;
fa197c1c
PB
10762 }
10763 more_words = word >> 24;
10764 word <<= 8;
10765 remaining--;
10766 per_index = -1;
10767 }
10768 else
015dc7e1 10769 return true;
fa197c1c
PB
10770 }
10771 else
10772 {
1b31d05e 10773 /* ARM EHABI Section 6.3:
0b4362b0 10774
1b31d05e 10775 An exception-handling table entry for the compact model looks like:
0b4362b0 10776
1b31d05e
NC
10777 31 30-28 27-24 23-0
10778 -- ----- ----- ----
10779 1 0 index Data for personalityRoutine[index] */
10780
dda8d76d 10781 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10782 && (word & 0x70000000))
32ec8896
NC
10783 {
10784 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10785 res = false;
32ec8896 10786 }
1b31d05e 10787
fa197c1c 10788 per_index = (word >> 24) & 0x7f;
1b31d05e 10789 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10790 if (per_index == 0)
10791 {
10792 more_words = 0;
10793 word <<= 8;
10794 remaining--;
10795 }
10796 else if (per_index < 3)
10797 {
10798 more_words = (word >> 16) & 0xff;
10799 word <<= 16;
10800 remaining -= 2;
10801 }
10802 }
10803
dda8d76d 10804 switch (filedata->file_header.e_machine)
fa197c1c
PB
10805 {
10806 case EM_ARM:
10807 if (per_index < 3)
10808 {
dda8d76d 10809 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10810 data_offset, data_sec, data_arm_sec))
015dc7e1 10811 res = false;
fa197c1c
PB
10812 }
10813 else
1b31d05e
NC
10814 {
10815 warn (_("Unknown ARM compact model index encountered\n"));
10816 printf (_(" [reserved]\n"));
015dc7e1 10817 res = false;
1b31d05e 10818 }
fa197c1c
PB
10819 break;
10820
10821 case EM_TI_C6000:
10822 if (per_index < 3)
10823 {
dda8d76d 10824 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10825 data_offset, data_sec, data_arm_sec))
015dc7e1 10826 res = false;
fa197c1c
PB
10827 }
10828 else if (per_index < 5)
10829 {
10830 if (((word >> 17) & 0x7f) == 0x7f)
10831 printf (_(" Restore stack from frame pointer\n"));
10832 else
10833 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10834 printf (_(" Registers restored: "));
10835 if (per_index == 4)
10836 printf (" (compact) ");
10837 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10838 putchar ('\n');
10839 printf (_(" Return register: %s\n"),
10840 tic6x_unwind_regnames[word & 0xf]);
10841 }
10842 else
1b31d05e 10843 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10844 break;
10845
10846 default:
74e1a04b 10847 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10848 filedata->file_header.e_machine);
015dc7e1 10849 res = false;
fa197c1c 10850 }
0b6ae522
DJ
10851
10852 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10853
10854 return res;
0b6ae522
DJ
10855}
10856
015dc7e1 10857static bool
dda8d76d
NC
10858dump_arm_unwind (Filedata * filedata,
10859 struct arm_unw_aux_info * aux,
10860 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10861{
10862 struct arm_section exidx_arm_sec, extab_arm_sec;
10863 unsigned int i, exidx_len;
26c527e6 10864 uint64_t j, nfuns;
015dc7e1 10865 bool res = true;
0b6ae522
DJ
10866
10867 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10868 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10869 exidx_len = exidx_sec->sh_size / 8;
10870
948f632f
DA
10871 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10872 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10873 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10874 aux->funtab[nfuns++] = aux->symtab[j];
10875 aux->nfuns = nfuns;
10876 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10877
0b6ae522
DJ
10878 for (i = 0; i < exidx_len; i++)
10879 {
10880 unsigned int exidx_fn, exidx_entry;
10881 struct absaddr fn_addr, entry_addr;
625d49fc 10882 uint64_t fn;
0b6ae522
DJ
10883
10884 fputc ('\n', stdout);
10885
dda8d76d 10886 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10887 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10888 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10889 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10890 {
948f632f 10891 free (aux->funtab);
1b31d05e
NC
10892 arm_free_section (& exidx_arm_sec);
10893 arm_free_section (& extab_arm_sec);
015dc7e1 10894 return false;
0b6ae522
DJ
10895 }
10896
83c257ca
NC
10897 /* ARM EHABI, Section 5:
10898 An index table entry consists of 2 words.
10899 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10900 if (exidx_fn & 0x80000000)
32ec8896
NC
10901 {
10902 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10903 res = false;
32ec8896 10904 }
83c257ca 10905
dda8d76d 10906 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10907
dda8d76d 10908 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10909 fputs (": ", stdout);
10910
10911 if (exidx_entry == 1)
10912 {
10913 print_vma (exidx_entry, PREFIX_HEX);
10914 fputs (" [cantunwind]\n", stdout);
10915 }
10916 else if (exidx_entry & 0x80000000)
10917 {
10918 print_vma (exidx_entry, PREFIX_HEX);
10919 fputc ('\n', stdout);
dda8d76d 10920 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10921 }
10922 else
10923 {
625d49fc 10924 uint64_t table, table_offset = 0;
0b6ae522
DJ
10925 Elf_Internal_Shdr *table_sec;
10926
10927 fputs ("@", stdout);
dda8d76d 10928 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10929 print_vma (table, PREFIX_HEX);
10930 printf ("\n");
10931
10932 /* Locate the matching .ARM.extab. */
10933 if (entry_addr.section != SHN_UNDEF
dda8d76d 10934 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10935 {
dda8d76d 10936 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10937 table_offset = entry_addr.offset;
1a915552 10938 /* PR 18879 */
625d49fc 10939 if (table_offset > table_sec->sh_size)
1a915552 10940 {
26c527e6
AM
10941 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10942 table_offset,
dda8d76d 10943 printable_section_name (filedata, table_sec));
015dc7e1 10944 res = false;
1a915552
NC
10945 continue;
10946 }
0b6ae522
DJ
10947 }
10948 else
10949 {
dda8d76d 10950 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10951 if (table_sec != NULL)
10952 table_offset = table - table_sec->sh_addr;
10953 }
32ec8896 10954
0b6ae522
DJ
10955 if (table_sec == NULL)
10956 {
26c527e6
AM
10957 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10958 table);
015dc7e1 10959 res = false;
0b6ae522
DJ
10960 continue;
10961 }
32ec8896 10962
dda8d76d 10963 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10964 &extab_arm_sec))
015dc7e1 10965 res = false;
0b6ae522
DJ
10966 }
10967 }
10968
10969 printf ("\n");
10970
948f632f 10971 free (aux->funtab);
0b6ae522
DJ
10972 arm_free_section (&exidx_arm_sec);
10973 arm_free_section (&extab_arm_sec);
32ec8896
NC
10974
10975 return res;
0b6ae522
DJ
10976}
10977
fa197c1c 10978/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10979
015dc7e1 10980static bool
dda8d76d 10981arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10982{
10983 struct arm_unw_aux_info aux;
10984 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10985 Elf_Internal_Shdr *sec;
26c527e6 10986 size_t i;
fa197c1c 10987 unsigned int sec_type;
015dc7e1 10988 bool res = true;
0b6ae522 10989
dda8d76d 10990 switch (filedata->file_header.e_machine)
fa197c1c
PB
10991 {
10992 case EM_ARM:
10993 sec_type = SHT_ARM_EXIDX;
10994 break;
10995
10996 case EM_TI_C6000:
10997 sec_type = SHT_C6000_UNWIND;
10998 break;
10999
0b4362b0 11000 default:
74e1a04b 11001 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11002 filedata->file_header.e_machine);
015dc7e1 11003 return false;
fa197c1c
PB
11004 }
11005
dda8d76d 11006 if (filedata->string_table == NULL)
015dc7e1 11007 return false;
1b31d05e
NC
11008
11009 memset (& aux, 0, sizeof (aux));
dda8d76d 11010 aux.filedata = filedata;
0b6ae522 11011
dda8d76d 11012 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11013 {
28d13567 11014 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11015 {
28d13567 11016 if (aux.symtab)
74e1a04b 11017 {
28d13567
AM
11018 error (_("Multiple symbol tables encountered\n"));
11019 free (aux.symtab);
11020 aux.symtab = NULL;
74e1a04b 11021 free (aux.strtab);
28d13567 11022 aux.strtab = NULL;
74e1a04b 11023 }
28d13567
AM
11024 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11025 &aux.strtab, &aux.strtab_size))
015dc7e1 11026 return false;
0b6ae522 11027 }
fa197c1c 11028 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11029 unwsec = sec;
11030 }
11031
1b31d05e 11032 if (unwsec == NULL)
0b6ae522 11033 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11034 else
dda8d76d 11035 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11036 {
11037 if (sec->sh_type == sec_type)
11038 {
26c527e6
AM
11039 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11040 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11041 "contains %" PRIu64 " entry:\n",
11042 "\nUnwind section '%s' at offset %#" PRIx64 " "
11043 "contains %" PRIu64 " entries:\n",
d3a49aa8 11044 num_unwind),
dda8d76d 11045 printable_section_name (filedata, sec),
26c527e6 11046 sec->sh_offset,
d3a49aa8 11047 num_unwind);
0b6ae522 11048
dda8d76d 11049 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11050 res = false;
1b31d05e
NC
11051 }
11052 }
0b6ae522 11053
9db70fc3
AM
11054 free (aux.symtab);
11055 free ((char *) aux.strtab);
32ec8896
NC
11056
11057 return res;
0b6ae522
DJ
11058}
11059
3ecc00ec
NC
11060static bool
11061no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11062{
11063 printf (_("No processor specific unwind information to decode\n"));
11064 return true;
11065}
11066
015dc7e1 11067static bool
dda8d76d 11068process_unwind (Filedata * filedata)
57346661 11069{
2cf0635d
NC
11070 struct unwind_handler
11071 {
32ec8896 11072 unsigned int machtype;
015dc7e1 11073 bool (* handler)(Filedata *);
2cf0635d
NC
11074 } handlers[] =
11075 {
0b6ae522 11076 { EM_ARM, arm_process_unwind },
57346661
AM
11077 { EM_IA_64, ia64_process_unwind },
11078 { EM_PARISC, hppa_process_unwind },
fa197c1c 11079 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11080 { EM_386, no_processor_specific_unwind },
11081 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11082 { 0, NULL }
57346661
AM
11083 };
11084 int i;
11085
11086 if (!do_unwind)
015dc7e1 11087 return true;
57346661
AM
11088
11089 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11090 if (filedata->file_header.e_machine == handlers[i].machtype)
11091 return handlers[i].handler (filedata);
57346661 11092
1b31d05e 11093 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11094 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11095 return true;
57346661
AM
11096}
11097
37c18eed
SD
11098static void
11099dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11100{
11101 switch (entry->d_tag)
11102 {
11103 case DT_AARCH64_BTI_PLT:
1dbade74 11104 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11105 break;
11106 default:
11107 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11108 break;
11109 }
11110 putchar ('\n');
11111}
11112
252b5132 11113static void
978c4450 11114dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11115{
11116 switch (entry->d_tag)
11117 {
11118 case DT_MIPS_FLAGS:
11119 if (entry->d_un.d_val == 0)
4b68bca3 11120 printf (_("NONE"));
252b5132
RH
11121 else
11122 {
11123 static const char * opts[] =
11124 {
11125 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11126 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11127 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11128 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11129 "RLD_ORDER_SAFE"
11130 };
11131 unsigned int cnt;
015dc7e1 11132 bool first = true;
2b692964 11133
60bca95a 11134 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11135 if (entry->d_un.d_val & (1 << cnt))
11136 {
11137 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11138 first = false;
252b5132 11139 }
252b5132
RH
11140 }
11141 break;
103f02d3 11142
252b5132 11143 case DT_MIPS_IVERSION:
84714f86 11144 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11145 printf (_("Interface Version: %s"),
84714f86 11146 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11147 else
f493c217 11148 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11149 entry->d_un.d_ptr);
252b5132 11150 break;
103f02d3 11151
252b5132
RH
11152 case DT_MIPS_TIME_STAMP:
11153 {
d5b07ef4 11154 char timebuf[128];
2cf0635d 11155 struct tm * tmp;
91d6fa6a 11156 time_t atime = entry->d_un.d_val;
82b1b41b 11157
91d6fa6a 11158 tmp = gmtime (&atime);
82b1b41b
NC
11159 /* PR 17531: file: 6accc532. */
11160 if (tmp == NULL)
11161 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11162 else
11163 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11164 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11165 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11166 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11167 }
11168 break;
103f02d3 11169
252b5132
RH
11170 case DT_MIPS_RLD_VERSION:
11171 case DT_MIPS_LOCAL_GOTNO:
11172 case DT_MIPS_CONFLICTNO:
11173 case DT_MIPS_LIBLISTNO:
11174 case DT_MIPS_SYMTABNO:
11175 case DT_MIPS_UNREFEXTNO:
11176 case DT_MIPS_HIPAGENO:
11177 case DT_MIPS_DELTA_CLASS_NO:
11178 case DT_MIPS_DELTA_INSTANCE_NO:
11179 case DT_MIPS_DELTA_RELOC_NO:
11180 case DT_MIPS_DELTA_SYM_NO:
11181 case DT_MIPS_DELTA_CLASSSYM_NO:
11182 case DT_MIPS_COMPACT_SIZE:
c69075ac 11183 print_vma (entry->d_un.d_val, DEC);
252b5132 11184 break;
103f02d3 11185
f16a9783 11186 case DT_MIPS_XHASH:
978c4450
AM
11187 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11188 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11189 /* Falls through. */
11190
103f02d3 11191 default:
4b68bca3 11192 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11193 }
4b68bca3 11194 putchar ('\n');
103f02d3
UD
11195}
11196
103f02d3 11197static void
2cf0635d 11198dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11199{
11200 switch (entry->d_tag)
11201 {
11202 case DT_HP_DLD_FLAGS:
11203 {
11204 static struct
11205 {
26c527e6 11206 unsigned int bit;
2cf0635d 11207 const char * str;
5e220199
NC
11208 }
11209 flags[] =
11210 {
11211 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11212 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11213 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11214 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11215 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11216 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11217 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11218 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11219 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11220 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11221 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11222 { DT_HP_GST, "HP_GST" },
11223 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11224 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11225 { DT_HP_NODELETE, "HP_NODELETE" },
11226 { DT_HP_GROUP, "HP_GROUP" },
11227 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11228 };
015dc7e1 11229 bool first = true;
5e220199 11230 size_t cnt;
625d49fc 11231 uint64_t val = entry->d_un.d_val;
103f02d3 11232
60bca95a 11233 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11234 if (val & flags[cnt].bit)
30800947
NC
11235 {
11236 if (! first)
11237 putchar (' ');
11238 fputs (flags[cnt].str, stdout);
015dc7e1 11239 first = false;
30800947
NC
11240 val ^= flags[cnt].bit;
11241 }
76da6bbe 11242
103f02d3 11243 if (val != 0 || first)
f7a99963
NC
11244 {
11245 if (! first)
11246 putchar (' ');
11247 print_vma (val, HEX);
11248 }
103f02d3
UD
11249 }
11250 break;
76da6bbe 11251
252b5132 11252 default:
f7a99963
NC
11253 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11254 break;
252b5132 11255 }
35b1837e 11256 putchar ('\n');
252b5132
RH
11257}
11258
28f997cf
TG
11259/* VMS vs Unix time offset and factor. */
11260
11261#define VMS_EPOCH_OFFSET 35067168000000000LL
11262#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11263#ifndef INT64_MIN
11264#define INT64_MIN (-9223372036854775807LL - 1)
11265#endif
28f997cf
TG
11266
11267/* Display a VMS time in a human readable format. */
11268
11269static void
0e3c1eeb 11270print_vms_time (int64_t vmstime)
28f997cf 11271{
dccc31de 11272 struct tm *tm = NULL;
28f997cf
TG
11273 time_t unxtime;
11274
dccc31de
AM
11275 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11276 {
11277 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11278 unxtime = vmstime;
11279 if (unxtime == vmstime)
11280 tm = gmtime (&unxtime);
11281 }
11282 if (tm != NULL)
11283 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11284 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11285 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11286}
28f997cf 11287
ecc51f48 11288static void
2cf0635d 11289dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11290{
11291 switch (entry->d_tag)
11292 {
0de14b54 11293 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11294 /* First 3 slots reserved. */
ecc51f48
NC
11295 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11296 printf (" -- ");
11297 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11298 break;
11299
28f997cf 11300 case DT_IA_64_VMS_LINKTIME:
28f997cf 11301 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11302 break;
11303
11304 case DT_IA_64_VMS_LNKFLAGS:
11305 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11306 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11307 printf (" CALL_DEBUG");
11308 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11309 printf (" NOP0BUFS");
11310 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11311 printf (" P0IMAGE");
11312 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11313 printf (" MKTHREADS");
11314 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11315 printf (" UPCALLS");
11316 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11317 printf (" IMGSTA");
11318 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11319 printf (" INITIALIZE");
11320 if (entry->d_un.d_val & VMS_LF_MAIN)
11321 printf (" MAIN");
11322 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11323 printf (" EXE_INIT");
11324 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11325 printf (" TBK_IN_IMG");
11326 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11327 printf (" DBG_IN_IMG");
11328 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11329 printf (" TBK_IN_DSF");
11330 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11331 printf (" DBG_IN_DSF");
11332 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11333 printf (" SIGNATURES");
11334 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11335 printf (" REL_SEG_OFF");
11336 break;
11337
bdf4d63a
JJ
11338 default:
11339 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11340 break;
ecc51f48 11341 }
bdf4d63a 11342 putchar ('\n');
ecc51f48
NC
11343}
11344
015dc7e1 11345static bool
dda8d76d 11346get_32bit_dynamic_section (Filedata * filedata)
252b5132 11347{
2cf0635d
NC
11348 Elf32_External_Dyn * edyn;
11349 Elf32_External_Dyn * ext;
11350 Elf_Internal_Dyn * entry;
103f02d3 11351
978c4450
AM
11352 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11353 filedata->dynamic_addr, 1,
11354 filedata->dynamic_size,
11355 _("dynamic section"));
a6e9f9df 11356 if (!edyn)
015dc7e1 11357 return false;
103f02d3 11358
071436c6
NC
11359 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11360 might not have the luxury of section headers. Look for the DT_NULL
11361 terminator to determine the number of entries. */
978c4450
AM
11362 for (ext = edyn, filedata->dynamic_nent = 0;
11363 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11364 ext++)
11365 {
978c4450 11366 filedata->dynamic_nent++;
ba2685cc
AM
11367 if (BYTE_GET (ext->d_tag) == DT_NULL)
11368 break;
11369 }
252b5132 11370
978c4450
AM
11371 filedata->dynamic_section
11372 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11373 if (filedata->dynamic_section == NULL)
252b5132 11374 {
26c527e6
AM
11375 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11376 filedata->dynamic_nent);
9ea033b2 11377 free (edyn);
015dc7e1 11378 return false;
9ea033b2 11379 }
252b5132 11380
978c4450
AM
11381 for (ext = edyn, entry = filedata->dynamic_section;
11382 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11383 ext++, entry++)
9ea033b2 11384 {
fb514b26
AM
11385 entry->d_tag = BYTE_GET (ext->d_tag);
11386 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11387 }
11388
9ea033b2
NC
11389 free (edyn);
11390
015dc7e1 11391 return true;
9ea033b2
NC
11392}
11393
015dc7e1 11394static bool
dda8d76d 11395get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11396{
2cf0635d
NC
11397 Elf64_External_Dyn * edyn;
11398 Elf64_External_Dyn * ext;
11399 Elf_Internal_Dyn * entry;
103f02d3 11400
071436c6 11401 /* Read in the data. */
978c4450
AM
11402 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11403 filedata->dynamic_addr, 1,
11404 filedata->dynamic_size,
11405 _("dynamic section"));
a6e9f9df 11406 if (!edyn)
015dc7e1 11407 return false;
103f02d3 11408
071436c6
NC
11409 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11410 might not have the luxury of section headers. Look for the DT_NULL
11411 terminator to determine the number of entries. */
978c4450 11412 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11413 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11414 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11415 ext++)
11416 {
978c4450 11417 filedata->dynamic_nent++;
66543521 11418 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11419 break;
11420 }
252b5132 11421
978c4450
AM
11422 filedata->dynamic_section
11423 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11424 if (filedata->dynamic_section == NULL)
252b5132 11425 {
26c527e6
AM
11426 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11427 filedata->dynamic_nent);
252b5132 11428 free (edyn);
015dc7e1 11429 return false;
252b5132
RH
11430 }
11431
071436c6 11432 /* Convert from external to internal formats. */
978c4450
AM
11433 for (ext = edyn, entry = filedata->dynamic_section;
11434 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11435 ext++, entry++)
252b5132 11436 {
66543521
AM
11437 entry->d_tag = BYTE_GET (ext->d_tag);
11438 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11439 }
11440
11441 free (edyn);
11442
015dc7e1 11443 return true;
9ea033b2
NC
11444}
11445
4de91c10
AM
11446static bool
11447get_dynamic_section (Filedata *filedata)
11448{
11449 if (filedata->dynamic_section)
11450 return true;
11451
11452 if (is_32bit_elf)
11453 return get_32bit_dynamic_section (filedata);
11454 else
11455 return get_64bit_dynamic_section (filedata);
11456}
11457
e9e44622 11458static void
625d49fc 11459print_dynamic_flags (uint64_t flags)
d1133906 11460{
015dc7e1 11461 bool first = true;
13ae64f3 11462
d1133906
NC
11463 while (flags)
11464 {
625d49fc 11465 uint64_t flag;
d1133906
NC
11466
11467 flag = flags & - flags;
11468 flags &= ~ flag;
11469
e9e44622 11470 if (first)
015dc7e1 11471 first = false;
e9e44622
JJ
11472 else
11473 putc (' ', stdout);
13ae64f3 11474
d1133906
NC
11475 switch (flag)
11476 {
e9e44622
JJ
11477 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11478 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11479 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11480 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11481 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11482 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11483 }
11484 }
e9e44622 11485 puts ("");
d1133906
NC
11486}
11487
625d49fc 11488static uint64_t *
be7d229a 11489get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11490{
11491 unsigned char * e_data;
625d49fc 11492 uint64_t * i_data;
10ca4b04 11493
be7d229a
AM
11494 /* If size_t is smaller than uint64_t, eg because you are building
11495 on a 32-bit host, then make sure that when number is cast to
11496 size_t no information is lost. */
11497 if ((size_t) number != number
11498 || ent_size * number / ent_size != number)
10ca4b04 11499 {
be7d229a 11500 error (_("Size overflow prevents reading %" PRIu64
b8281767 11501 " elements of size %u\n"),
be7d229a 11502 number, ent_size);
10ca4b04
L
11503 return NULL;
11504 }
11505
11506 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11507 attempting to allocate memory when the read is bound to fail. */
11508 if (ent_size * number > filedata->file_size)
11509 {
b8281767 11510 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11511 number);
10ca4b04
L
11512 return NULL;
11513 }
11514
11515 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11516 if (e_data == NULL)
11517 {
b8281767 11518 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11519 number);
10ca4b04
L
11520 return NULL;
11521 }
11522
11523 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11524 {
b8281767 11525 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11526 number * ent_size);
10ca4b04
L
11527 free (e_data);
11528 return NULL;
11529 }
11530
625d49fc 11531 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11532 if (i_data == NULL)
11533 {
b8281767 11534 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11535 number);
10ca4b04
L
11536 free (e_data);
11537 return NULL;
11538 }
11539
11540 while (number--)
11541 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11542
11543 free (e_data);
11544
11545 return i_data;
11546}
11547
26c527e6 11548static uint64_t
10ca4b04
L
11549get_num_dynamic_syms (Filedata * filedata)
11550{
26c527e6 11551 uint64_t num_of_syms = 0;
10ca4b04
L
11552
11553 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11554 return num_of_syms;
11555
978c4450 11556 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11557 {
11558 unsigned char nb[8];
11559 unsigned char nc[8];
11560 unsigned int hash_ent_size = 4;
11561
11562 if ((filedata->file_header.e_machine == EM_ALPHA
11563 || filedata->file_header.e_machine == EM_S390
11564 || filedata->file_header.e_machine == EM_S390_OLD)
11565 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11566 hash_ent_size = 8;
11567
63cf857e
AM
11568 if (fseek64 (filedata->handle,
11569 (filedata->archive_file_offset
11570 + offset_from_vma (filedata,
11571 filedata->dynamic_info[DT_HASH],
11572 sizeof nb + sizeof nc)),
11573 SEEK_SET))
10ca4b04
L
11574 {
11575 error (_("Unable to seek to start of dynamic information\n"));
11576 goto no_hash;
11577 }
11578
11579 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11580 {
11581 error (_("Failed to read in number of buckets\n"));
11582 goto no_hash;
11583 }
11584
11585 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11586 {
11587 error (_("Failed to read in number of chains\n"));
11588 goto no_hash;
11589 }
11590
978c4450
AM
11591 filedata->nbuckets = byte_get (nb, hash_ent_size);
11592 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11593
2482f306
AM
11594 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11595 {
11596 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11597 hash_ent_size);
11598 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11599 hash_ent_size);
001890e1 11600
2482f306
AM
11601 if (filedata->buckets != NULL && filedata->chains != NULL)
11602 num_of_syms = filedata->nchains;
11603 }
ceb9bf11 11604 no_hash:
10ca4b04
L
11605 if (num_of_syms == 0)
11606 {
9db70fc3
AM
11607 free (filedata->buckets);
11608 filedata->buckets = NULL;
11609 free (filedata->chains);
11610 filedata->chains = NULL;
978c4450 11611 filedata->nbuckets = 0;
10ca4b04
L
11612 }
11613 }
11614
978c4450 11615 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11616 {
11617 unsigned char nb[16];
625d49fc
AM
11618 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11619 uint64_t buckets_vma;
26c527e6 11620 uint64_t hn;
10ca4b04 11621
63cf857e
AM
11622 if (fseek64 (filedata->handle,
11623 (filedata->archive_file_offset
11624 + offset_from_vma (filedata,
11625 filedata->dynamic_info_DT_GNU_HASH,
11626 sizeof nb)),
11627 SEEK_SET))
10ca4b04
L
11628 {
11629 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11630 goto no_gnu_hash;
11631 }
11632
11633 if (fread (nb, 16, 1, filedata->handle) != 1)
11634 {
11635 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11636 goto no_gnu_hash;
11637 }
11638
978c4450
AM
11639 filedata->ngnubuckets = byte_get (nb, 4);
11640 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11641 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11642 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11643 if (is_32bit_elf)
11644 buckets_vma += bitmaskwords * 4;
11645 else
11646 buckets_vma += bitmaskwords * 8;
11647
63cf857e
AM
11648 if (fseek64 (filedata->handle,
11649 (filedata->archive_file_offset
11650 + offset_from_vma (filedata, buckets_vma, 4)),
11651 SEEK_SET))
10ca4b04
L
11652 {
11653 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11654 goto no_gnu_hash;
11655 }
11656
978c4450
AM
11657 filedata->gnubuckets
11658 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11659
978c4450 11660 if (filedata->gnubuckets == NULL)
90837ea7 11661 goto no_gnu_hash;
10ca4b04 11662
978c4450
AM
11663 for (i = 0; i < filedata->ngnubuckets; i++)
11664 if (filedata->gnubuckets[i] != 0)
10ca4b04 11665 {
978c4450 11666 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11667 goto no_gnu_hash;
10ca4b04 11668
978c4450
AM
11669 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11670 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11671 }
11672
11673 if (maxchain == 0xffffffff)
90837ea7 11674 goto no_gnu_hash;
10ca4b04 11675
978c4450 11676 maxchain -= filedata->gnusymidx;
10ca4b04 11677
63cf857e
AM
11678 if (fseek64 (filedata->handle,
11679 (filedata->archive_file_offset
11680 + offset_from_vma (filedata,
11681 buckets_vma + 4 * (filedata->ngnubuckets
11682 + maxchain),
11683 4)),
11684 SEEK_SET))
10ca4b04
L
11685 {
11686 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11687 goto no_gnu_hash;
11688 }
11689
11690 do
11691 {
11692 if (fread (nb, 4, 1, filedata->handle) != 1)
11693 {
11694 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11695 goto no_gnu_hash;
11696 }
11697
11698 if (maxchain + 1 == 0)
90837ea7 11699 goto no_gnu_hash;
10ca4b04
L
11700
11701 ++maxchain;
11702 }
11703 while ((byte_get (nb, 4) & 1) == 0);
11704
63cf857e
AM
11705 if (fseek64 (filedata->handle,
11706 (filedata->archive_file_offset
11707 + offset_from_vma (filedata, (buckets_vma
11708 + 4 * filedata->ngnubuckets),
11709 4)),
11710 SEEK_SET))
10ca4b04
L
11711 {
11712 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11713 goto no_gnu_hash;
11714 }
11715
978c4450
AM
11716 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11717 filedata->ngnuchains = maxchain;
10ca4b04 11718
978c4450 11719 if (filedata->gnuchains == NULL)
90837ea7 11720 goto no_gnu_hash;
10ca4b04 11721
978c4450 11722 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11723 {
63cf857e
AM
11724 if (fseek64 (filedata->handle,
11725 (filedata->archive_file_offset
11726 + offset_from_vma (filedata, (buckets_vma
11727 + 4 * (filedata->ngnubuckets
11728 + maxchain)), 4)),
11729 SEEK_SET))
10ca4b04
L
11730 {
11731 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11732 goto no_gnu_hash;
11733 }
11734
978c4450 11735 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11736 if (filedata->mipsxlat == NULL)
11737 goto no_gnu_hash;
10ca4b04
L
11738 }
11739
978c4450
AM
11740 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11741 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11742 {
625d49fc
AM
11743 uint64_t si = filedata->gnubuckets[hn];
11744 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11745
11746 do
11747 {
978c4450 11748 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11749 {
c31ab5a0
AM
11750 if (off < filedata->ngnuchains
11751 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11752 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11753 }
11754 else
11755 {
11756 if (si >= num_of_syms)
11757 num_of_syms = si + 1;
11758 }
11759 si++;
11760 }
978c4450
AM
11761 while (off < filedata->ngnuchains
11762 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11763 }
11764
90837ea7 11765 if (num_of_syms == 0)
10ca4b04 11766 {
90837ea7 11767 no_gnu_hash:
9db70fc3
AM
11768 free (filedata->mipsxlat);
11769 filedata->mipsxlat = NULL;
11770 free (filedata->gnuchains);
11771 filedata->gnuchains = NULL;
11772 free (filedata->gnubuckets);
11773 filedata->gnubuckets = NULL;
978c4450
AM
11774 filedata->ngnubuckets = 0;
11775 filedata->ngnuchains = 0;
10ca4b04
L
11776 }
11777 }
11778
11779 return num_of_syms;
11780}
11781
b2d38a17
NC
11782/* Parse and display the contents of the dynamic section. */
11783
015dc7e1 11784static bool
dda8d76d 11785process_dynamic_section (Filedata * filedata)
9ea033b2 11786{
2cf0635d 11787 Elf_Internal_Dyn * entry;
9ea033b2 11788
93df3340 11789 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11790 {
11791 if (do_dynamic)
ca0e11aa
NC
11792 {
11793 if (filedata->is_separate)
11794 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11795 filedata->file_name);
11796 else
11797 printf (_("\nThere is no dynamic section in this file.\n"));
11798 }
9ea033b2 11799
015dc7e1 11800 return true;
9ea033b2
NC
11801 }
11802
4de91c10
AM
11803 if (!get_dynamic_section (filedata))
11804 return false;
9ea033b2 11805
252b5132 11806 /* Find the appropriate symbol table. */
978c4450 11807 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11808 {
26c527e6 11809 uint64_t num_of_syms;
2482f306 11810
978c4450
AM
11811 for (entry = filedata->dynamic_section;
11812 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11813 ++entry)
10ca4b04 11814 if (entry->d_tag == DT_SYMTAB)
978c4450 11815 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11816 else if (entry->d_tag == DT_SYMENT)
978c4450 11817 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11818 else if (entry->d_tag == DT_HASH)
978c4450 11819 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11820 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11821 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11822 else if ((filedata->file_header.e_machine == EM_MIPS
11823 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11824 && entry->d_tag == DT_MIPS_XHASH)
11825 {
978c4450
AM
11826 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11827 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11828 }
252b5132 11829
2482f306
AM
11830 num_of_syms = get_num_dynamic_syms (filedata);
11831
11832 if (num_of_syms != 0
11833 && filedata->dynamic_symbols == NULL
11834 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11835 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11836 {
11837 Elf_Internal_Phdr *seg;
625d49fc 11838 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11839
2482f306
AM
11840 if (! get_program_headers (filedata))
11841 {
11842 error (_("Cannot interpret virtual addresses "
11843 "without program headers.\n"));
015dc7e1 11844 return false;
2482f306 11845 }
252b5132 11846
2482f306
AM
11847 for (seg = filedata->program_headers;
11848 seg < filedata->program_headers + filedata->file_header.e_phnum;
11849 ++seg)
11850 {
11851 if (seg->p_type != PT_LOAD)
11852 continue;
252b5132 11853
2482f306
AM
11854 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11855 {
11856 /* See PR 21379 for a reproducer. */
11857 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11858 return false;
2482f306 11859 }
252b5132 11860
2482f306
AM
11861 if (vma >= (seg->p_vaddr & -seg->p_align)
11862 && vma < seg->p_vaddr + seg->p_filesz)
11863 {
11864 /* Since we do not know how big the symbol table is,
11865 we default to reading in up to the end of PT_LOAD
11866 segment and processing that. This is overkill, I
11867 know, but it should work. */
11868 Elf_Internal_Shdr section;
11869 section.sh_offset = (vma - seg->p_vaddr
11870 + seg->p_offset);
11871 section.sh_size = (num_of_syms
11872 * filedata->dynamic_info[DT_SYMENT]);
11873 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11874
11875 if (do_checks
11876 && filedata->dynamic_symtab_section != NULL
11877 && ((filedata->dynamic_symtab_section->sh_offset
11878 != section.sh_offset)
11879 || (filedata->dynamic_symtab_section->sh_size
11880 != section.sh_size)
11881 || (filedata->dynamic_symtab_section->sh_entsize
11882 != section.sh_entsize)))
11883 warn (_("\
11884the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11885
2482f306
AM
11886 section.sh_name = filedata->string_table_length;
11887 filedata->dynamic_symbols
4de91c10 11888 = get_elf_symbols (filedata, &section,
2482f306
AM
11889 &filedata->num_dynamic_syms);
11890 if (filedata->dynamic_symbols == NULL
11891 || filedata->num_dynamic_syms != num_of_syms)
11892 {
11893 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11894 return false;
2482f306
AM
11895 }
11896 break;
11897 }
11898 }
11899 }
11900 }
252b5132
RH
11901
11902 /* Similarly find a string table. */
978c4450
AM
11903 if (filedata->dynamic_strings == NULL)
11904 for (entry = filedata->dynamic_section;
11905 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11906 ++entry)
11907 {
11908 if (entry->d_tag == DT_STRTAB)
978c4450 11909 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11910
10ca4b04 11911 if (entry->d_tag == DT_STRSZ)
978c4450 11912 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11913
978c4450
AM
11914 if (filedata->dynamic_info[DT_STRTAB]
11915 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11916 {
26c527e6 11917 uint64_t offset;
be7d229a 11918 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11919
11920 offset = offset_from_vma (filedata,
978c4450 11921 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11922 str_tab_len);
8ac10c5b
L
11923 if (do_checks
11924 && filedata->dynamic_strtab_section
11925 && ((filedata->dynamic_strtab_section->sh_offset
11926 != (file_ptr) offset)
11927 || (filedata->dynamic_strtab_section->sh_size
11928 != str_tab_len)))
11929 warn (_("\
11930the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11931
978c4450
AM
11932 filedata->dynamic_strings
11933 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11934 _("dynamic string table"));
11935 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11936 {
11937 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11938 break;
11939 }
e3d39609 11940
978c4450 11941 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11942 break;
11943 }
11944 }
252b5132
RH
11945
11946 /* And find the syminfo section if available. */
978c4450 11947 if (filedata->dynamic_syminfo == NULL)
252b5132 11948 {
26c527e6 11949 uint64_t syminsz = 0;
252b5132 11950
978c4450
AM
11951 for (entry = filedata->dynamic_section;
11952 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11953 ++entry)
252b5132
RH
11954 {
11955 if (entry->d_tag == DT_SYMINENT)
11956 {
11957 /* Note: these braces are necessary to avoid a syntax
11958 error from the SunOS4 C compiler. */
049b0c3a
NC
11959 /* PR binutils/17531: A corrupt file can trigger this test.
11960 So do not use an assert, instead generate an error message. */
11961 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11962 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11963 (int) entry->d_un.d_val);
252b5132
RH
11964 }
11965 else if (entry->d_tag == DT_SYMINSZ)
11966 syminsz = entry->d_un.d_val;
11967 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11968 filedata->dynamic_syminfo_offset
11969 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11970 }
11971
978c4450 11972 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11973 {
2cf0635d
NC
11974 Elf_External_Syminfo * extsyminfo;
11975 Elf_External_Syminfo * extsym;
11976 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11977
11978 /* There is a syminfo section. Read the data. */
3f5e193b 11979 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11980 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11981 1, syminsz, _("symbol information"));
a6e9f9df 11982 if (!extsyminfo)
015dc7e1 11983 return false;
252b5132 11984
978c4450 11985 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11986 {
11987 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11988 free (filedata->dynamic_syminfo);
e3d39609 11989 }
978c4450
AM
11990 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11991 if (filedata->dynamic_syminfo == NULL)
252b5132 11992 {
26c527e6
AM
11993 error (_("Out of memory allocating %" PRIu64
11994 " bytes for dynamic symbol info\n"),
11995 syminsz);
015dc7e1 11996 return false;
252b5132
RH
11997 }
11998
2482f306
AM
11999 filedata->dynamic_syminfo_nent
12000 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12001 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12002 syminfo < (filedata->dynamic_syminfo
12003 + filedata->dynamic_syminfo_nent);
86dba8ee 12004 ++syminfo, ++extsym)
252b5132 12005 {
86dba8ee
AM
12006 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12007 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12008 }
12009
12010 free (extsyminfo);
12011 }
12012 }
12013
978c4450 12014 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12015 {
f253158f 12016 if (filedata->is_separate)
26c527e6
AM
12017 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12018 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12019 filedata->dynamic_nent),
f253158f
NC
12020 filedata->file_name,
12021 filedata->dynamic_addr,
26c527e6 12022 filedata->dynamic_nent);
84a9f195 12023 else
02da71ee 12024 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12025 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12026 filedata->dynamic_nent),
84a9f195 12027 filedata->dynamic_addr,
26c527e6 12028 filedata->dynamic_nent);
ca0e11aa 12029 }
252b5132
RH
12030 if (do_dynamic)
12031 printf (_(" Tag Type Name/Value\n"));
12032
978c4450
AM
12033 for (entry = filedata->dynamic_section;
12034 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12035 entry++)
252b5132
RH
12036 {
12037 if (do_dynamic)
f7a99963 12038 {
2cf0635d 12039 const char * dtype;
e699b9ff 12040
f7a99963
NC
12041 putchar (' ');
12042 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12043 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12044 printf (" (%s)%*s", dtype,
32ec8896 12045 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12046 }
252b5132
RH
12047
12048 switch (entry->d_tag)
12049 {
d1133906
NC
12050 case DT_FLAGS:
12051 if (do_dynamic)
e9e44622 12052 print_dynamic_flags (entry->d_un.d_val);
d1133906 12053 break;
76da6bbe 12054
252b5132
RH
12055 case DT_AUXILIARY:
12056 case DT_FILTER:
019148e4
L
12057 case DT_CONFIG:
12058 case DT_DEPAUDIT:
12059 case DT_AUDIT:
252b5132
RH
12060 if (do_dynamic)
12061 {
019148e4 12062 switch (entry->d_tag)
b34976b6 12063 {
019148e4
L
12064 case DT_AUXILIARY:
12065 printf (_("Auxiliary library"));
12066 break;
12067
12068 case DT_FILTER:
12069 printf (_("Filter library"));
12070 break;
12071
b34976b6 12072 case DT_CONFIG:
019148e4
L
12073 printf (_("Configuration file"));
12074 break;
12075
12076 case DT_DEPAUDIT:
12077 printf (_("Dependency audit library"));
12078 break;
12079
12080 case DT_AUDIT:
12081 printf (_("Audit library"));
12082 break;
12083 }
252b5132 12084
84714f86 12085 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12086 printf (": [%s]\n",
84714f86 12087 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12088 else
f7a99963
NC
12089 {
12090 printf (": ");
12091 print_vma (entry->d_un.d_val, PREFIX_HEX);
12092 putchar ('\n');
12093 }
252b5132
RH
12094 }
12095 break;
12096
dcefbbbd 12097 case DT_FEATURE:
252b5132
RH
12098 if (do_dynamic)
12099 {
12100 printf (_("Flags:"));
86f55779 12101
252b5132
RH
12102 if (entry->d_un.d_val == 0)
12103 printf (_(" None\n"));
12104 else
12105 {
26c527e6 12106 uint64_t val = entry->d_un.d_val;
86f55779 12107
252b5132
RH
12108 if (val & DTF_1_PARINIT)
12109 {
12110 printf (" PARINIT");
12111 val ^= DTF_1_PARINIT;
12112 }
dcefbbbd
L
12113 if (val & DTF_1_CONFEXP)
12114 {
12115 printf (" CONFEXP");
12116 val ^= DTF_1_CONFEXP;
12117 }
252b5132 12118 if (val != 0)
26c527e6 12119 printf (" %" PRIx64, val);
252b5132
RH
12120 puts ("");
12121 }
12122 }
12123 break;
12124
12125 case DT_POSFLAG_1:
12126 if (do_dynamic)
12127 {
12128 printf (_("Flags:"));
86f55779 12129
252b5132
RH
12130 if (entry->d_un.d_val == 0)
12131 printf (_(" None\n"));
12132 else
12133 {
26c527e6 12134 uint64_t val = entry->d_un.d_val;
86f55779 12135
252b5132
RH
12136 if (val & DF_P1_LAZYLOAD)
12137 {
12138 printf (" LAZYLOAD");
12139 val ^= DF_P1_LAZYLOAD;
12140 }
12141 if (val & DF_P1_GROUPPERM)
12142 {
12143 printf (" GROUPPERM");
12144 val ^= DF_P1_GROUPPERM;
12145 }
12146 if (val != 0)
26c527e6 12147 printf (" %" PRIx64, val);
252b5132
RH
12148 puts ("");
12149 }
12150 }
12151 break;
12152
12153 case DT_FLAGS_1:
12154 if (do_dynamic)
12155 {
12156 printf (_("Flags:"));
12157 if (entry->d_un.d_val == 0)
12158 printf (_(" None\n"));
12159 else
12160 {
26c527e6 12161 uint64_t val = entry->d_un.d_val;
86f55779 12162
252b5132
RH
12163 if (val & DF_1_NOW)
12164 {
12165 printf (" NOW");
12166 val ^= DF_1_NOW;
12167 }
12168 if (val & DF_1_GLOBAL)
12169 {
12170 printf (" GLOBAL");
12171 val ^= DF_1_GLOBAL;
12172 }
12173 if (val & DF_1_GROUP)
12174 {
12175 printf (" GROUP");
12176 val ^= DF_1_GROUP;
12177 }
12178 if (val & DF_1_NODELETE)
12179 {
12180 printf (" NODELETE");
12181 val ^= DF_1_NODELETE;
12182 }
12183 if (val & DF_1_LOADFLTR)
12184 {
12185 printf (" LOADFLTR");
12186 val ^= DF_1_LOADFLTR;
12187 }
12188 if (val & DF_1_INITFIRST)
12189 {
12190 printf (" INITFIRST");
12191 val ^= DF_1_INITFIRST;
12192 }
12193 if (val & DF_1_NOOPEN)
12194 {
12195 printf (" NOOPEN");
12196 val ^= DF_1_NOOPEN;
12197 }
12198 if (val & DF_1_ORIGIN)
12199 {
12200 printf (" ORIGIN");
12201 val ^= DF_1_ORIGIN;
12202 }
12203 if (val & DF_1_DIRECT)
12204 {
12205 printf (" DIRECT");
12206 val ^= DF_1_DIRECT;
12207 }
12208 if (val & DF_1_TRANS)
12209 {
12210 printf (" TRANS");
12211 val ^= DF_1_TRANS;
12212 }
12213 if (val & DF_1_INTERPOSE)
12214 {
12215 printf (" INTERPOSE");
12216 val ^= DF_1_INTERPOSE;
12217 }
f7db6139 12218 if (val & DF_1_NODEFLIB)
dcefbbbd 12219 {
f7db6139
L
12220 printf (" NODEFLIB");
12221 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12222 }
12223 if (val & DF_1_NODUMP)
12224 {
12225 printf (" NODUMP");
12226 val ^= DF_1_NODUMP;
12227 }
34b60028 12228 if (val & DF_1_CONFALT)
dcefbbbd 12229 {
34b60028
L
12230 printf (" CONFALT");
12231 val ^= DF_1_CONFALT;
12232 }
12233 if (val & DF_1_ENDFILTEE)
12234 {
12235 printf (" ENDFILTEE");
12236 val ^= DF_1_ENDFILTEE;
12237 }
12238 if (val & DF_1_DISPRELDNE)
12239 {
12240 printf (" DISPRELDNE");
12241 val ^= DF_1_DISPRELDNE;
12242 }
12243 if (val & DF_1_DISPRELPND)
12244 {
12245 printf (" DISPRELPND");
12246 val ^= DF_1_DISPRELPND;
12247 }
12248 if (val & DF_1_NODIRECT)
12249 {
12250 printf (" NODIRECT");
12251 val ^= DF_1_NODIRECT;
12252 }
12253 if (val & DF_1_IGNMULDEF)
12254 {
12255 printf (" IGNMULDEF");
12256 val ^= DF_1_IGNMULDEF;
12257 }
12258 if (val & DF_1_NOKSYMS)
12259 {
12260 printf (" NOKSYMS");
12261 val ^= DF_1_NOKSYMS;
12262 }
12263 if (val & DF_1_NOHDR)
12264 {
12265 printf (" NOHDR");
12266 val ^= DF_1_NOHDR;
12267 }
12268 if (val & DF_1_EDITED)
12269 {
12270 printf (" EDITED");
12271 val ^= DF_1_EDITED;
12272 }
12273 if (val & DF_1_NORELOC)
12274 {
12275 printf (" NORELOC");
12276 val ^= DF_1_NORELOC;
12277 }
12278 if (val & DF_1_SYMINTPOSE)
12279 {
12280 printf (" SYMINTPOSE");
12281 val ^= DF_1_SYMINTPOSE;
12282 }
12283 if (val & DF_1_GLOBAUDIT)
12284 {
12285 printf (" GLOBAUDIT");
12286 val ^= DF_1_GLOBAUDIT;
12287 }
12288 if (val & DF_1_SINGLETON)
12289 {
12290 printf (" SINGLETON");
12291 val ^= DF_1_SINGLETON;
dcefbbbd 12292 }
5c383f02
RO
12293 if (val & DF_1_STUB)
12294 {
12295 printf (" STUB");
12296 val ^= DF_1_STUB;
12297 }
12298 if (val & DF_1_PIE)
12299 {
12300 printf (" PIE");
12301 val ^= DF_1_PIE;
12302 }
b1202ffa
L
12303 if (val & DF_1_KMOD)
12304 {
12305 printf (" KMOD");
12306 val ^= DF_1_KMOD;
12307 }
12308 if (val & DF_1_WEAKFILTER)
12309 {
12310 printf (" WEAKFILTER");
12311 val ^= DF_1_WEAKFILTER;
12312 }
12313 if (val & DF_1_NOCOMMON)
12314 {
12315 printf (" NOCOMMON");
12316 val ^= DF_1_NOCOMMON;
12317 }
252b5132 12318 if (val != 0)
26c527e6 12319 printf (" %" PRIx64, val);
252b5132
RH
12320 puts ("");
12321 }
12322 }
12323 break;
12324
12325 case DT_PLTREL:
978c4450 12326 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12327 if (do_dynamic)
dda8d76d 12328 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12329 break;
12330
12331 case DT_NULL :
12332 case DT_NEEDED :
12333 case DT_PLTGOT :
12334 case DT_HASH :
12335 case DT_STRTAB :
12336 case DT_SYMTAB :
12337 case DT_RELA :
12338 case DT_INIT :
12339 case DT_FINI :
12340 case DT_SONAME :
12341 case DT_RPATH :
12342 case DT_SYMBOLIC:
12343 case DT_REL :
a7fd1186 12344 case DT_RELR :
252b5132
RH
12345 case DT_DEBUG :
12346 case DT_TEXTREL :
12347 case DT_JMPREL :
019148e4 12348 case DT_RUNPATH :
978c4450 12349 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12350
12351 if (do_dynamic)
12352 {
84714f86 12353 const char *name;
252b5132 12354
84714f86
AM
12355 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12356 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12357 else
d79b3d50 12358 name = NULL;
252b5132
RH
12359
12360 if (name)
12361 {
12362 switch (entry->d_tag)
12363 {
12364 case DT_NEEDED:
12365 printf (_("Shared library: [%s]"), name);
12366
13acb58d
AM
12367 if (filedata->program_interpreter
12368 && streq (name, filedata->program_interpreter))
f7a99963 12369 printf (_(" program interpreter"));
252b5132
RH
12370 break;
12371
12372 case DT_SONAME:
f7a99963 12373 printf (_("Library soname: [%s]"), name);
252b5132
RH
12374 break;
12375
12376 case DT_RPATH:
f7a99963 12377 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12378 break;
12379
019148e4
L
12380 case DT_RUNPATH:
12381 printf (_("Library runpath: [%s]"), name);
12382 break;
12383
252b5132 12384 default:
f7a99963
NC
12385 print_vma (entry->d_un.d_val, PREFIX_HEX);
12386 break;
252b5132
RH
12387 }
12388 }
12389 else
f7a99963
NC
12390 print_vma (entry->d_un.d_val, PREFIX_HEX);
12391
12392 putchar ('\n');
252b5132
RH
12393 }
12394 break;
12395
12396 case DT_PLTRELSZ:
12397 case DT_RELASZ :
12398 case DT_STRSZ :
12399 case DT_RELSZ :
12400 case DT_RELAENT :
a7fd1186
FS
12401 case DT_RELRENT :
12402 case DT_RELRSZ :
252b5132
RH
12403 case DT_SYMENT :
12404 case DT_RELENT :
978c4450 12405 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12406 /* Fall through. */
252b5132
RH
12407 case DT_PLTPADSZ:
12408 case DT_MOVEENT :
12409 case DT_MOVESZ :
04d8355a 12410 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12411 case DT_INIT_ARRAYSZ:
12412 case DT_FINI_ARRAYSZ:
047b2264
JJ
12413 case DT_GNU_CONFLICTSZ:
12414 case DT_GNU_LIBLISTSZ:
252b5132 12415 if (do_dynamic)
f7a99963
NC
12416 {
12417 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12418 printf (_(" (bytes)\n"));
f7a99963 12419 }
252b5132
RH
12420 break;
12421
12422 case DT_VERDEFNUM:
12423 case DT_VERNEEDNUM:
12424 case DT_RELACOUNT:
12425 case DT_RELCOUNT:
12426 if (do_dynamic)
f7a99963
NC
12427 {
12428 print_vma (entry->d_un.d_val, UNSIGNED);
12429 putchar ('\n');
12430 }
252b5132
RH
12431 break;
12432
12433 case DT_SYMINSZ:
12434 case DT_SYMINENT:
12435 case DT_SYMINFO:
12436 case DT_USED:
12437 case DT_INIT_ARRAY:
12438 case DT_FINI_ARRAY:
12439 if (do_dynamic)
12440 {
d79b3d50 12441 if (entry->d_tag == DT_USED
84714f86 12442 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12443 {
84714f86
AM
12444 const char *name
12445 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12446
b34976b6 12447 if (*name)
252b5132
RH
12448 {
12449 printf (_("Not needed object: [%s]\n"), name);
12450 break;
12451 }
12452 }
103f02d3 12453
f7a99963
NC
12454 print_vma (entry->d_un.d_val, PREFIX_HEX);
12455 putchar ('\n');
252b5132
RH
12456 }
12457 break;
12458
12459 case DT_BIND_NOW:
12460 /* The value of this entry is ignored. */
35b1837e
AM
12461 if (do_dynamic)
12462 putchar ('\n');
252b5132 12463 break;
103f02d3 12464
047b2264
JJ
12465 case DT_GNU_PRELINKED:
12466 if (do_dynamic)
12467 {
2cf0635d 12468 struct tm * tmp;
91d6fa6a 12469 time_t atime = entry->d_un.d_val;
047b2264 12470
91d6fa6a 12471 tmp = gmtime (&atime);
071436c6
NC
12472 /* PR 17533 file: 041-1244816-0.004. */
12473 if (tmp == NULL)
26c527e6
AM
12474 printf (_("<corrupt time val: %" PRIx64),
12475 (uint64_t) atime);
071436c6
NC
12476 else
12477 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12478 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12479 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12480
12481 }
12482 break;
12483
fdc90cb4 12484 case DT_GNU_HASH:
978c4450 12485 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12486 if (do_dynamic)
12487 {
12488 print_vma (entry->d_un.d_val, PREFIX_HEX);
12489 putchar ('\n');
12490 }
12491 break;
12492
a5da3dee
VDM
12493 case DT_GNU_FLAGS_1:
12494 if (do_dynamic)
12495 {
12496 printf (_("Flags:"));
12497 if (entry->d_un.d_val == 0)
12498 printf (_(" None\n"));
12499 else
12500 {
26c527e6 12501 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12502
12503 if (val & DF_GNU_1_UNIQUE)
12504 {
12505 printf (" UNIQUE");
12506 val ^= DF_GNU_1_UNIQUE;
12507 }
12508 if (val != 0)
26c527e6 12509 printf (" %" PRIx64, val);
a5da3dee
VDM
12510 puts ("");
12511 }
12512 }
12513 break;
12514
252b5132
RH
12515 default:
12516 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12517 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12518 = entry->d_un.d_val;
252b5132
RH
12519
12520 if (do_dynamic)
12521 {
dda8d76d 12522 switch (filedata->file_header.e_machine)
252b5132 12523 {
37c18eed
SD
12524 case EM_AARCH64:
12525 dynamic_section_aarch64_val (entry);
12526 break;
252b5132 12527 case EM_MIPS:
4fe85591 12528 case EM_MIPS_RS3_LE:
978c4450 12529 dynamic_section_mips_val (filedata, entry);
252b5132 12530 break;
103f02d3 12531 case EM_PARISC:
b2d38a17 12532 dynamic_section_parisc_val (entry);
103f02d3 12533 break;
ecc51f48 12534 case EM_IA_64:
b2d38a17 12535 dynamic_section_ia64_val (entry);
ecc51f48 12536 break;
252b5132 12537 default:
f7a99963
NC
12538 print_vma (entry->d_un.d_val, PREFIX_HEX);
12539 putchar ('\n');
252b5132
RH
12540 }
12541 }
12542 break;
12543 }
12544 }
12545
015dc7e1 12546 return true;
252b5132
RH
12547}
12548
12549static char *
d3ba0551 12550get_ver_flags (unsigned int flags)
252b5132 12551{
6d4f21f6 12552 static char buff[128];
252b5132
RH
12553
12554 buff[0] = 0;
12555
12556 if (flags == 0)
12557 return _("none");
12558
12559 if (flags & VER_FLG_BASE)
7bb1ad17 12560 strcat (buff, "BASE");
252b5132
RH
12561
12562 if (flags & VER_FLG_WEAK)
12563 {
12564 if (flags & VER_FLG_BASE)
7bb1ad17 12565 strcat (buff, " | ");
252b5132 12566
7bb1ad17 12567 strcat (buff, "WEAK");
252b5132
RH
12568 }
12569
44ec90b9
RO
12570 if (flags & VER_FLG_INFO)
12571 {
12572 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12573 strcat (buff, " | ");
44ec90b9 12574
7bb1ad17 12575 strcat (buff, "INFO");
44ec90b9
RO
12576 }
12577
12578 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12579 {
12580 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12581 strcat (buff, " | ");
12582
12583 strcat (buff, _("<unknown>"));
12584 }
252b5132
RH
12585
12586 return buff;
12587}
12588
12589/* Display the contents of the version sections. */
98fb390a 12590
015dc7e1 12591static bool
dda8d76d 12592process_version_sections (Filedata * filedata)
252b5132 12593{
2cf0635d 12594 Elf_Internal_Shdr * section;
b34976b6 12595 unsigned i;
015dc7e1 12596 bool found = false;
252b5132
RH
12597
12598 if (! do_version)
015dc7e1 12599 return true;
252b5132 12600
dda8d76d
NC
12601 for (i = 0, section = filedata->section_headers;
12602 i < filedata->file_header.e_shnum;
b34976b6 12603 i++, section++)
252b5132
RH
12604 {
12605 switch (section->sh_type)
12606 {
12607 case SHT_GNU_verdef:
12608 {
2cf0635d 12609 Elf_External_Verdef * edefs;
26c527e6
AM
12610 size_t idx;
12611 size_t cnt;
2cf0635d 12612 char * endbuf;
252b5132 12613
015dc7e1 12614 found = true;
252b5132 12615
ca0e11aa
NC
12616 if (filedata->is_separate)
12617 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12618 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12619 section->sh_info),
12620 filedata->file_name,
12621 printable_section_name (filedata, section),
12622 section->sh_info);
12623 else
12624 printf (ngettext ("\nVersion definition section '%s' "
12625 "contains %u entry:\n",
12626 "\nVersion definition section '%s' "
12627 "contains %u entries:\n",
12628 section->sh_info),
12629 printable_section_name (filedata, section),
12630 section->sh_info);
047c3dbf 12631
625d49fc 12632 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12633 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12634 section->sh_offset, section->sh_link,
b6ac461a 12635 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12636
3f5e193b 12637 edefs = (Elf_External_Verdef *)
dda8d76d 12638 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12639 _("version definition section"));
a6e9f9df
AM
12640 if (!edefs)
12641 break;
59245841 12642 endbuf = (char *) edefs + section->sh_size;
252b5132 12643
1445030f 12644 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12645 {
2cf0635d
NC
12646 char * vstart;
12647 Elf_External_Verdef * edef;
b34976b6 12648 Elf_Internal_Verdef ent;
2cf0635d 12649 Elf_External_Verdaux * eaux;
b34976b6 12650 Elf_Internal_Verdaux aux;
26c527e6 12651 size_t isum;
b34976b6 12652 int j;
103f02d3 12653
252b5132 12654 vstart = ((char *) edefs) + idx;
54806181
AM
12655 if (vstart + sizeof (*edef) > endbuf)
12656 break;
252b5132
RH
12657
12658 edef = (Elf_External_Verdef *) vstart;
12659
12660 ent.vd_version = BYTE_GET (edef->vd_version);
12661 ent.vd_flags = BYTE_GET (edef->vd_flags);
12662 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12663 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12664 ent.vd_hash = BYTE_GET (edef->vd_hash);
12665 ent.vd_aux = BYTE_GET (edef->vd_aux);
12666 ent.vd_next = BYTE_GET (edef->vd_next);
12667
26c527e6 12668 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12669 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12670
12671 printf (_(" Index: %d Cnt: %d "),
12672 ent.vd_ndx, ent.vd_cnt);
12673
452bf675 12674 /* Check for overflow. */
1445030f 12675 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12676 break;
12677
252b5132
RH
12678 vstart += ent.vd_aux;
12679
1445030f
AM
12680 if (vstart + sizeof (*eaux) > endbuf)
12681 break;
252b5132
RH
12682 eaux = (Elf_External_Verdaux *) vstart;
12683
12684 aux.vda_name = BYTE_GET (eaux->vda_name);
12685 aux.vda_next = BYTE_GET (eaux->vda_next);
12686
84714f86 12687 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12688 printf (_("Name: %s\n"),
84714f86 12689 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12690 else
12691 printf (_("Name index: %ld\n"), aux.vda_name);
12692
12693 isum = idx + ent.vd_aux;
12694
b34976b6 12695 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12696 {
1445030f
AM
12697 if (aux.vda_next < sizeof (*eaux)
12698 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12699 {
12700 warn (_("Invalid vda_next field of %lx\n"),
12701 aux.vda_next);
12702 j = ent.vd_cnt;
12703 break;
12704 }
dd24e3da 12705 /* Check for overflow. */
7e26601c 12706 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12707 break;
12708
252b5132
RH
12709 isum += aux.vda_next;
12710 vstart += aux.vda_next;
12711
54806181
AM
12712 if (vstart + sizeof (*eaux) > endbuf)
12713 break;
1445030f 12714 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12715
12716 aux.vda_name = BYTE_GET (eaux->vda_name);
12717 aux.vda_next = BYTE_GET (eaux->vda_next);
12718
84714f86 12719 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12720 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12721 isum, j,
84714f86 12722 get_dynamic_name (filedata, aux.vda_name));
252b5132 12723 else
26c527e6 12724 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12725 isum, j, aux.vda_name);
12726 }
dd24e3da 12727
54806181
AM
12728 if (j < ent.vd_cnt)
12729 printf (_(" Version def aux past end of section\n"));
252b5132 12730
c9f02c3e
MR
12731 /* PR 17531:
12732 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12733 if (ent.vd_next < sizeof (*edef)
12734 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12735 {
12736 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12737 cnt = section->sh_info;
12738 break;
12739 }
452bf675 12740 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12741 break;
12742
252b5132
RH
12743 idx += ent.vd_next;
12744 }
dd24e3da 12745
54806181
AM
12746 if (cnt < section->sh_info)
12747 printf (_(" Version definition past end of section\n"));
252b5132
RH
12748
12749 free (edefs);
12750 }
12751 break;
103f02d3 12752
252b5132
RH
12753 case SHT_GNU_verneed:
12754 {
2cf0635d 12755 Elf_External_Verneed * eneed;
26c527e6
AM
12756 size_t idx;
12757 size_t cnt;
2cf0635d 12758 char * endbuf;
252b5132 12759
015dc7e1 12760 found = true;
252b5132 12761
ca0e11aa
NC
12762 if (filedata->is_separate)
12763 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12764 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12765 section->sh_info),
12766 filedata->file_name,
12767 printable_section_name (filedata, section),
12768 section->sh_info);
12769 else
12770 printf (ngettext ("\nVersion needs section '%s' "
12771 "contains %u entry:\n",
12772 "\nVersion needs section '%s' "
12773 "contains %u entries:\n",
12774 section->sh_info),
12775 printable_section_name (filedata, section),
12776 section->sh_info);
047c3dbf 12777
625d49fc 12778 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12779 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12780 section->sh_offset, section->sh_link,
b6ac461a 12781 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12782
dda8d76d 12783 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12784 section->sh_offset, 1,
12785 section->sh_size,
9cf03b7e 12786 _("Version Needs section"));
a6e9f9df
AM
12787 if (!eneed)
12788 break;
59245841 12789 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12790
12791 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12792 {
2cf0635d 12793 Elf_External_Verneed * entry;
b34976b6 12794 Elf_Internal_Verneed ent;
26c527e6 12795 size_t isum;
b34976b6 12796 int j;
2cf0635d 12797 char * vstart;
252b5132
RH
12798
12799 vstart = ((char *) eneed) + idx;
54806181
AM
12800 if (vstart + sizeof (*entry) > endbuf)
12801 break;
252b5132
RH
12802
12803 entry = (Elf_External_Verneed *) vstart;
12804
12805 ent.vn_version = BYTE_GET (entry->vn_version);
12806 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12807 ent.vn_file = BYTE_GET (entry->vn_file);
12808 ent.vn_aux = BYTE_GET (entry->vn_aux);
12809 ent.vn_next = BYTE_GET (entry->vn_next);
12810
26c527e6 12811 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12812
84714f86 12813 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12814 printf (_(" File: %s"),
84714f86 12815 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12816 else
12817 printf (_(" File: %lx"), ent.vn_file);
12818
12819 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12820
dd24e3da 12821 /* Check for overflow. */
7e26601c 12822 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12823 break;
252b5132
RH
12824 vstart += ent.vn_aux;
12825
12826 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12827 {
2cf0635d 12828 Elf_External_Vernaux * eaux;
b34976b6 12829 Elf_Internal_Vernaux aux;
252b5132 12830
54806181
AM
12831 if (vstart + sizeof (*eaux) > endbuf)
12832 break;
252b5132
RH
12833 eaux = (Elf_External_Vernaux *) vstart;
12834
12835 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12836 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12837 aux.vna_other = BYTE_GET (eaux->vna_other);
12838 aux.vna_name = BYTE_GET (eaux->vna_name);
12839 aux.vna_next = BYTE_GET (eaux->vna_next);
12840
84714f86 12841 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12842 printf (_(" %#06zx: Name: %s"),
84714f86 12843 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12844 else
26c527e6 12845 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12846 isum, aux.vna_name);
12847
12848 printf (_(" Flags: %s Version: %d\n"),
12849 get_ver_flags (aux.vna_flags), aux.vna_other);
12850
1445030f
AM
12851 if (aux.vna_next < sizeof (*eaux)
12852 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12853 {
12854 warn (_("Invalid vna_next field of %lx\n"),
12855 aux.vna_next);
12856 j = ent.vn_cnt;
12857 break;
12858 }
1445030f
AM
12859 /* Check for overflow. */
12860 if (aux.vna_next > (size_t) (endbuf - vstart))
12861 break;
252b5132
RH
12862 isum += aux.vna_next;
12863 vstart += aux.vna_next;
12864 }
9cf03b7e 12865
54806181 12866 if (j < ent.vn_cnt)
f9a6a8f0 12867 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12868
1445030f
AM
12869 if (ent.vn_next < sizeof (*entry)
12870 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12871 {
452bf675 12872 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12873 cnt = section->sh_info;
12874 break;
12875 }
1445030f
AM
12876 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12877 break;
252b5132
RH
12878 idx += ent.vn_next;
12879 }
9cf03b7e 12880
54806181 12881 if (cnt < section->sh_info)
9cf03b7e 12882 warn (_("Missing Version Needs information\n"));
103f02d3 12883
252b5132
RH
12884 free (eneed);
12885 }
12886 break;
12887
12888 case SHT_GNU_versym:
12889 {
2cf0635d 12890 Elf_Internal_Shdr * link_section;
26c527e6 12891 uint64_t total;
8b73c356 12892 unsigned int cnt;
2cf0635d
NC
12893 unsigned char * edata;
12894 unsigned short * data;
12895 char * strtab;
12896 Elf_Internal_Sym * symbols;
12897 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12898 uint64_t num_syms;
12899 uint64_t off;
252b5132 12900
dda8d76d 12901 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12902 break;
12903
dda8d76d 12904 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12905 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12906
dda8d76d 12907 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12908 break;
12909
015dc7e1 12910 found = true;
252b5132 12911
4de91c10 12912 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12913 if (symbols == NULL)
12914 break;
252b5132 12915
dda8d76d 12916 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12917
dda8d76d 12918 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12919 string_sec->sh_size,
12920 _("version string table"));
a6e9f9df 12921 if (!strtab)
0429c154
MS
12922 {
12923 free (symbols);
12924 break;
12925 }
252b5132 12926
ca0e11aa 12927 if (filedata->is_separate)
26c527e6
AM
12928 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12929 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12930 total),
12931 filedata->file_name,
12932 printable_section_name (filedata, section),
26c527e6 12933 total);
ca0e11aa
NC
12934 else
12935 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12936 "contains %" PRIu64 " entry:\n",
ca0e11aa 12937 "\nVersion symbols section '%s' "
26c527e6 12938 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12939 total),
12940 printable_section_name (filedata, section),
26c527e6 12941 total);
252b5132 12942
625d49fc 12943 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12944 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12945 section->sh_offset, section->sh_link,
dda8d76d 12946 printable_section_name (filedata, link_section));
252b5132 12947
dda8d76d 12948 off = offset_from_vma (filedata,
978c4450 12949 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12950 total * sizeof (short));
95099889
AM
12951 edata = (unsigned char *) get_data (NULL, filedata, off,
12952 sizeof (short), total,
12953 _("version symbol data"));
a6e9f9df
AM
12954 if (!edata)
12955 {
12956 free (strtab);
0429c154 12957 free (symbols);
a6e9f9df
AM
12958 break;
12959 }
252b5132 12960
3f5e193b 12961 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12962
12963 for (cnt = total; cnt --;)
b34976b6
AM
12964 data[cnt] = byte_get (edata + cnt * sizeof (short),
12965 sizeof (short));
252b5132
RH
12966
12967 free (edata);
12968
12969 for (cnt = 0; cnt < total; cnt += 4)
12970 {
12971 int j, nn;
ab273396
AM
12972 char *name;
12973 char *invalid = _("*invalid*");
252b5132
RH
12974
12975 printf (" %03x:", cnt);
12976
12977 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12978 switch (data[cnt + j])
252b5132
RH
12979 {
12980 case 0:
12981 fputs (_(" 0 (*local*) "), stdout);
12982 break;
12983
12984 case 1:
12985 fputs (_(" 1 (*global*) "), stdout);
12986 break;
12987
12988 default:
c244d050
NC
12989 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12990 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12991
dd24e3da 12992 /* If this index value is greater than the size of the symbols
ba5cdace 12993 array, break to avoid an out-of-bounds read. */
26c527e6 12994 if (cnt + j >= num_syms)
dd24e3da
NC
12995 {
12996 warn (_("invalid index into symbol array\n"));
12997 break;
12998 }
12999
ab273396 13000 name = NULL;
978c4450 13001 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13002 {
b34976b6 13003 Elf_Internal_Verneed ivn;
26c527e6 13004 uint64_t offset;
252b5132 13005
d93f0186 13006 offset = offset_from_vma
978c4450
AM
13007 (filedata,
13008 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13009 sizeof (Elf_External_Verneed));
252b5132 13010
b34976b6 13011 do
252b5132 13012 {
b34976b6
AM
13013 Elf_Internal_Vernaux ivna;
13014 Elf_External_Verneed evn;
13015 Elf_External_Vernaux evna;
26c527e6 13016 uint64_t a_off;
252b5132 13017
dda8d76d 13018 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13019 _("version need")) == NULL)
13020 break;
0b4362b0 13021
252b5132
RH
13022 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13023 ivn.vn_next = BYTE_GET (evn.vn_next);
13024
13025 a_off = offset + ivn.vn_aux;
13026
13027 do
13028 {
dda8d76d 13029 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13030 1, _("version need aux (2)")) == NULL)
13031 {
13032 ivna.vna_next = 0;
13033 ivna.vna_other = 0;
13034 }
13035 else
13036 {
13037 ivna.vna_next = BYTE_GET (evna.vna_next);
13038 ivna.vna_other = BYTE_GET (evna.vna_other);
13039 }
252b5132
RH
13040
13041 a_off += ivna.vna_next;
13042 }
b34976b6 13043 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13044 && ivna.vna_next != 0);
13045
b34976b6 13046 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13047 {
13048 ivna.vna_name = BYTE_GET (evna.vna_name);
13049
54806181 13050 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13051 name = invalid;
54806181
AM
13052 else
13053 name = strtab + ivna.vna_name;
252b5132
RH
13054 break;
13055 }
13056
13057 offset += ivn.vn_next;
13058 }
13059 while (ivn.vn_next);
13060 }
00d93f34 13061
ab273396 13062 if (data[cnt + j] != 0x8001
978c4450 13063 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13064 {
b34976b6
AM
13065 Elf_Internal_Verdef ivd;
13066 Elf_External_Verdef evd;
26c527e6 13067 uint64_t offset;
252b5132 13068
d93f0186 13069 offset = offset_from_vma
978c4450
AM
13070 (filedata,
13071 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13072 sizeof evd);
252b5132
RH
13073
13074 do
13075 {
dda8d76d 13076 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13077 _("version def")) == NULL)
13078 {
13079 ivd.vd_next = 0;
948f632f 13080 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13081 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13082 break;
59245841
NC
13083 }
13084 else
13085 {
13086 ivd.vd_next = BYTE_GET (evd.vd_next);
13087 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13088 }
252b5132
RH
13089
13090 offset += ivd.vd_next;
13091 }
c244d050 13092 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13093 && ivd.vd_next != 0);
13094
c244d050 13095 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13096 {
b34976b6
AM
13097 Elf_External_Verdaux evda;
13098 Elf_Internal_Verdaux ivda;
252b5132
RH
13099
13100 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13101
dda8d76d 13102 if (get_data (&evda, filedata,
59245841
NC
13103 offset - ivd.vd_next + ivd.vd_aux,
13104 sizeof (evda), 1,
13105 _("version def aux")) == NULL)
13106 break;
252b5132
RH
13107
13108 ivda.vda_name = BYTE_GET (evda.vda_name);
13109
54806181 13110 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13111 name = invalid;
13112 else if (name != NULL && name != invalid)
13113 name = _("*both*");
54806181
AM
13114 else
13115 name = strtab + ivda.vda_name;
252b5132
RH
13116 }
13117 }
ab273396
AM
13118 if (name != NULL)
13119 nn += printf ("(%s%-*s",
13120 name,
13121 12 - (int) strlen (name),
13122 ")");
252b5132
RH
13123
13124 if (nn < 18)
13125 printf ("%*c", 18 - nn, ' ');
13126 }
13127
13128 putchar ('\n');
13129 }
13130
13131 free (data);
13132 free (strtab);
13133 free (symbols);
13134 }
13135 break;
103f02d3 13136
252b5132
RH
13137 default:
13138 break;
13139 }
13140 }
13141
13142 if (! found)
ca0e11aa
NC
13143 {
13144 if (filedata->is_separate)
13145 printf (_("\nNo version information found in linked file '%s'.\n"),
13146 filedata->file_name);
13147 else
13148 printf (_("\nNo version information found in this file.\n"));
13149 }
252b5132 13150
015dc7e1 13151 return true;
252b5132
RH
13152}
13153
d1133906 13154static const char *
dda8d76d 13155get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13156{
89246a0e 13157 static char buff[64];
252b5132
RH
13158
13159 switch (binding)
13160 {
b34976b6
AM
13161 case STB_LOCAL: return "LOCAL";
13162 case STB_GLOBAL: return "GLOBAL";
13163 case STB_WEAK: return "WEAK";
252b5132
RH
13164 default:
13165 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13166 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13167 binding);
252b5132 13168 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13169 {
13170 if (binding == STB_GNU_UNIQUE
df3a023b 13171 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13172 return "UNIQUE";
13173 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13174 }
252b5132 13175 else
e9e44622 13176 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13177 return buff;
13178 }
13179}
13180
d1133906 13181static const char *
dda8d76d 13182get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13183{
89246a0e 13184 static char buff[64];
252b5132
RH
13185
13186 switch (type)
13187 {
b34976b6
AM
13188 case STT_NOTYPE: return "NOTYPE";
13189 case STT_OBJECT: return "OBJECT";
13190 case STT_FUNC: return "FUNC";
13191 case STT_SECTION: return "SECTION";
13192 case STT_FILE: return "FILE";
13193 case STT_COMMON: return "COMMON";
13194 case STT_TLS: return "TLS";
15ab5209
DB
13195 case STT_RELC: return "RELC";
13196 case STT_SRELC: return "SRELC";
252b5132
RH
13197 default:
13198 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13199 {
dda8d76d 13200 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13201 return "THUMB_FUNC";
103f02d3 13202
dda8d76d 13203 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13204 return "REGISTER";
13205
dda8d76d 13206 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13207 return "PARISC_MILLI";
13208
e9e44622 13209 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13210 }
252b5132 13211 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13212 {
dda8d76d 13213 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13214 {
13215 if (type == STT_HP_OPAQUE)
13216 return "HP_OPAQUE";
13217 if (type == STT_HP_STUB)
13218 return "HP_STUB";
13219 }
13220
8654c01f
ML
13221 if (type == STT_GNU_IFUNC
13222 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13223 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13224 return "IFUNC";
13225
e9e44622 13226 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13227 }
252b5132 13228 else
e9e44622 13229 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13230 return buff;
13231 }
13232}
13233
d1133906 13234static const char *
d3ba0551 13235get_symbol_visibility (unsigned int visibility)
d1133906
NC
13236{
13237 switch (visibility)
13238 {
b34976b6
AM
13239 case STV_DEFAULT: return "DEFAULT";
13240 case STV_INTERNAL: return "INTERNAL";
13241 case STV_HIDDEN: return "HIDDEN";
d1133906 13242 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13243 default:
27a45f42 13244 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13245 return _("<unknown>");
d1133906
NC
13246 }
13247}
13248
2057d69d
CZ
13249static const char *
13250get_alpha_symbol_other (unsigned int other)
9abca702 13251{
2057d69d
CZ
13252 switch (other)
13253 {
13254 case STO_ALPHA_NOPV: return "NOPV";
13255 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13256 default:
27a45f42 13257 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13258 return _("<unknown>");
9abca702 13259 }
2057d69d
CZ
13260}
13261
fd85a6a1
NC
13262static const char *
13263get_solaris_symbol_visibility (unsigned int visibility)
13264{
13265 switch (visibility)
13266 {
13267 case 4: return "EXPORTED";
13268 case 5: return "SINGLETON";
13269 case 6: return "ELIMINATE";
13270 default: return get_symbol_visibility (visibility);
13271 }
13272}
13273
2301ed1c
SN
13274static const char *
13275get_aarch64_symbol_other (unsigned int other)
13276{
13277 static char buf[32];
13278
13279 if (other & STO_AARCH64_VARIANT_PCS)
13280 {
13281 other &= ~STO_AARCH64_VARIANT_PCS;
13282 if (other == 0)
13283 return "VARIANT_PCS";
13284 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13285 return buf;
13286 }
13287 return NULL;
13288}
13289
5e2b0d47
NC
13290static const char *
13291get_mips_symbol_other (unsigned int other)
13292{
13293 switch (other)
13294 {
32ec8896
NC
13295 case STO_OPTIONAL: return "OPTIONAL";
13296 case STO_MIPS_PLT: return "MIPS PLT";
13297 case STO_MIPS_PIC: return "MIPS PIC";
13298 case STO_MICROMIPS: return "MICROMIPS";
13299 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13300 case STO_MIPS16: return "MIPS16";
13301 default: return NULL;
5e2b0d47
NC
13302 }
13303}
13304
28f997cf 13305static const char *
dda8d76d 13306get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13307{
dda8d76d 13308 if (is_ia64_vms (filedata))
28f997cf
TG
13309 {
13310 static char res[32];
13311
13312 res[0] = 0;
13313
13314 /* Function types is for images and .STB files only. */
dda8d76d 13315 switch (filedata->file_header.e_type)
28f997cf
TG
13316 {
13317 case ET_DYN:
13318 case ET_EXEC:
13319 switch (VMS_ST_FUNC_TYPE (other))
13320 {
13321 case VMS_SFT_CODE_ADDR:
13322 strcat (res, " CA");
13323 break;
13324 case VMS_SFT_SYMV_IDX:
13325 strcat (res, " VEC");
13326 break;
13327 case VMS_SFT_FD:
13328 strcat (res, " FD");
13329 break;
13330 case VMS_SFT_RESERVE:
13331 strcat (res, " RSV");
13332 break;
13333 default:
bee0ee85
NC
13334 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13335 VMS_ST_FUNC_TYPE (other));
13336 strcat (res, " <unknown>");
13337 break;
28f997cf
TG
13338 }
13339 break;
13340 default:
13341 break;
13342 }
13343 switch (VMS_ST_LINKAGE (other))
13344 {
13345 case VMS_STL_IGNORE:
13346 strcat (res, " IGN");
13347 break;
13348 case VMS_STL_RESERVE:
13349 strcat (res, " RSV");
13350 break;
13351 case VMS_STL_STD:
13352 strcat (res, " STD");
13353 break;
13354 case VMS_STL_LNK:
13355 strcat (res, " LNK");
13356 break;
13357 default:
bee0ee85
NC
13358 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13359 VMS_ST_LINKAGE (other));
13360 strcat (res, " <unknown>");
13361 break;
28f997cf
TG
13362 }
13363
13364 if (res[0] != 0)
13365 return res + 1;
13366 else
13367 return res;
13368 }
13369 return NULL;
13370}
13371
6911b7dc
AM
13372static const char *
13373get_ppc64_symbol_other (unsigned int other)
13374{
14732552
AM
13375 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13376 return NULL;
13377
13378 other >>= STO_PPC64_LOCAL_BIT;
13379 if (other <= 6)
6911b7dc 13380 {
89246a0e 13381 static char buf[64];
14732552
AM
13382 if (other >= 2)
13383 other = ppc64_decode_local_entry (other);
13384 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13385 return buf;
13386 }
13387 return NULL;
13388}
13389
8155b853
NC
13390static const char *
13391get_riscv_symbol_other (unsigned int other)
13392{
13393 static char buf[32];
13394 buf[0] = 0;
13395
13396 if (other & STO_RISCV_VARIANT_CC)
13397 {
13398 strcat (buf, _(" VARIANT_CC"));
13399 other &= ~STO_RISCV_VARIANT_CC;
13400 }
13401
13402 if (other != 0)
13403 snprintf (buf, sizeof buf, " %x", other);
13404
13405
13406 if (buf[0] != 0)
13407 return buf + 1;
13408 else
13409 return buf;
13410}
13411
5e2b0d47 13412static const char *
dda8d76d 13413get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13414{
13415 const char * result = NULL;
89246a0e 13416 static char buff [64];
5e2b0d47
NC
13417
13418 if (other == 0)
13419 return "";
13420
dda8d76d 13421 switch (filedata->file_header.e_machine)
5e2b0d47 13422 {
2057d69d
CZ
13423 case EM_ALPHA:
13424 result = get_alpha_symbol_other (other);
13425 break;
2301ed1c
SN
13426 case EM_AARCH64:
13427 result = get_aarch64_symbol_other (other);
13428 break;
5e2b0d47
NC
13429 case EM_MIPS:
13430 result = get_mips_symbol_other (other);
28f997cf
TG
13431 break;
13432 case EM_IA_64:
dda8d76d 13433 result = get_ia64_symbol_other (filedata, other);
28f997cf 13434 break;
6911b7dc
AM
13435 case EM_PPC64:
13436 result = get_ppc64_symbol_other (other);
13437 break;
8155b853
NC
13438 case EM_RISCV:
13439 result = get_riscv_symbol_other (other);
13440 break;
5e2b0d47 13441 default:
fd85a6a1 13442 result = NULL;
5e2b0d47
NC
13443 break;
13444 }
13445
13446 if (result)
13447 return result;
13448
13449 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13450 return buff;
13451}
13452
bb4d2ac2 13453static const char *
26c527e6
AM
13454get_symbol_version_string (Filedata *filedata,
13455 bool is_dynsym,
13456 const char *strtab,
13457 size_t strtab_size,
13458 unsigned int si,
13459 Elf_Internal_Sym *psym,
13460 enum versioned_symbol_info *sym_info,
13461 unsigned short *vna_other)
bb4d2ac2 13462{
ab273396
AM
13463 unsigned char data[2];
13464 unsigned short vers_data;
26c527e6 13465 uint64_t offset;
7a815dd5 13466 unsigned short max_vd_ndx;
bb4d2ac2 13467
ab273396 13468 if (!is_dynsym
978c4450 13469 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13470 return NULL;
bb4d2ac2 13471
978c4450
AM
13472 offset = offset_from_vma (filedata,
13473 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13474 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13475
dda8d76d 13476 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13477 sizeof (data), 1, _("version data")) == NULL)
13478 return NULL;
13479
13480 vers_data = byte_get (data, 2);
bb4d2ac2 13481
1f6f5dba 13482 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13483 return NULL;
bb4d2ac2 13484
0b8b7609 13485 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13486 max_vd_ndx = 0;
13487
ab273396
AM
13488 /* Usually we'd only see verdef for defined symbols, and verneed for
13489 undefined symbols. However, symbols defined by the linker in
13490 .dynbss for variables copied from a shared library in order to
13491 avoid text relocations are defined yet have verneed. We could
13492 use a heuristic to detect the special case, for example, check
13493 for verneed first on symbols defined in SHT_NOBITS sections, but
13494 it is simpler and more reliable to just look for both verdef and
13495 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13496
ab273396
AM
13497 if (psym->st_shndx != SHN_UNDEF
13498 && vers_data != 0x8001
978c4450 13499 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13500 {
13501 Elf_Internal_Verdef ivd;
13502 Elf_Internal_Verdaux ivda;
13503 Elf_External_Verdaux evda;
26c527e6 13504 uint64_t off;
bb4d2ac2 13505
dda8d76d 13506 off = offset_from_vma (filedata,
978c4450 13507 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13508 sizeof (Elf_External_Verdef));
13509
13510 do
bb4d2ac2 13511 {
ab273396
AM
13512 Elf_External_Verdef evd;
13513
dda8d76d 13514 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13515 _("version def")) == NULL)
13516 {
13517 ivd.vd_ndx = 0;
13518 ivd.vd_aux = 0;
13519 ivd.vd_next = 0;
1f6f5dba 13520 ivd.vd_flags = 0;
ab273396
AM
13521 }
13522 else
bb4d2ac2 13523 {
ab273396
AM
13524 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13525 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13526 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13527 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13528 }
bb4d2ac2 13529
7a815dd5
L
13530 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13531 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13532
ab273396
AM
13533 off += ivd.vd_next;
13534 }
13535 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13536
ab273396
AM
13537 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13538 {
9abca702 13539 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13540 return NULL;
13541
ab273396
AM
13542 off -= ivd.vd_next;
13543 off += ivd.vd_aux;
bb4d2ac2 13544
dda8d76d 13545 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13546 _("version def aux")) != NULL)
13547 {
13548 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13549
ab273396 13550 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13551 return (ivda.vda_name < strtab_size
13552 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13553 }
13554 }
13555 }
bb4d2ac2 13556
978c4450 13557 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13558 {
13559 Elf_External_Verneed evn;
13560 Elf_Internal_Verneed ivn;
13561 Elf_Internal_Vernaux ivna;
bb4d2ac2 13562
dda8d76d 13563 offset = offset_from_vma (filedata,
978c4450 13564 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13565 sizeof evn);
13566 do
13567 {
26c527e6 13568 uint64_t vna_off;
bb4d2ac2 13569
dda8d76d 13570 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13571 _("version need")) == NULL)
13572 {
13573 ivna.vna_next = 0;
13574 ivna.vna_other = 0;
13575 ivna.vna_name = 0;
13576 break;
13577 }
bb4d2ac2 13578
ab273396
AM
13579 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13580 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13581
ab273396 13582 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13583
ab273396
AM
13584 do
13585 {
13586 Elf_External_Vernaux evna;
bb4d2ac2 13587
dda8d76d 13588 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13589 _("version need aux (3)")) == NULL)
bb4d2ac2 13590 {
ab273396
AM
13591 ivna.vna_next = 0;
13592 ivna.vna_other = 0;
13593 ivna.vna_name = 0;
bb4d2ac2 13594 }
bb4d2ac2 13595 else
bb4d2ac2 13596 {
ab273396
AM
13597 ivna.vna_other = BYTE_GET (evna.vna_other);
13598 ivna.vna_next = BYTE_GET (evna.vna_next);
13599 ivna.vna_name = BYTE_GET (evna.vna_name);
13600 }
bb4d2ac2 13601
ab273396
AM
13602 vna_off += ivna.vna_next;
13603 }
13604 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13605
ab273396
AM
13606 if (ivna.vna_other == vers_data)
13607 break;
bb4d2ac2 13608
ab273396
AM
13609 offset += ivn.vn_next;
13610 }
13611 while (ivn.vn_next != 0);
bb4d2ac2 13612
ab273396
AM
13613 if (ivna.vna_other == vers_data)
13614 {
13615 *sym_info = symbol_undefined;
13616 *vna_other = ivna.vna_other;
13617 return (ivna.vna_name < strtab_size
13618 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13619 }
7a815dd5
L
13620 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13621 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13622 return _("<corrupt>");
bb4d2ac2 13623 }
ab273396 13624 return NULL;
bb4d2ac2
L
13625}
13626
047c3dbf
NL
13627/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13628
13629static unsigned int
b6ac461a 13630print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13631{
13632 switch (base)
13633 {
13634 case 8:
13635 return print_vma (vma, OCTAL_5);
13636
13637 case 10:
13638 return print_vma (vma, UNSIGNED_5);
13639
13640 case 16:
13641 return print_vma (vma, PREFIX_HEX_5);
13642
13643 case 0:
13644 default:
13645 return print_vma (vma, DEC_5);
13646 }
13647}
13648
b6ac461a
NC
13649/* Print information on a single symbol. */
13650
10ca4b04 13651static void
b6ac461a
NC
13652print_symbol (Filedata * filedata,
13653 uint64_t symbol_index,
13654 Elf_Internal_Sym * symtab,
13655 Elf_Internal_Shdr * section,
13656 char * strtab,
13657 size_t strtab_size)
252b5132 13658{
10ca4b04
L
13659 const char *version_string;
13660 enum versioned_symbol_info sym_info;
13661 unsigned short vna_other;
23356397 13662 const char * sstr;
b6ac461a 13663 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 13664
b6ac461a
NC
13665 /* FIXME: We should have a table of field widths,
13666 rather than using hard coded constants. */
13667 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
13668 print_vma (psym->st_value, LONG_HEX);
13669 putchar (' ');
b6ac461a 13670 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13671 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13672 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13673 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13674 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13675 else
252b5132 13676 {
10ca4b04 13677 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13678
10ca4b04 13679 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 13680
10ca4b04 13681 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
13682 FIXME: Displaying this information here disrupts the layout
13683 of the table being generated. */
10ca4b04
L
13684 if (psym->st_other ^ vis)
13685 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13686 }
0942c7ab 13687
b6ac461a
NC
13688 bool is_special;
13689
13690 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13691
13692 /* Print the symbol's section index. If the index is special
13693 then print the index's name rather than its number. */
13694 if (is_special)
13695 {
13696 int printed;
13697
13698 /* Special case: If there are no section headers, and the printable
13699 name is "<section 0x...." then just display the section number
13700 as a decimal. This happens when objcopy --strip -section-headers
13701 is used. */
13702 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13703 printed = printf (" %4d ", psym->st_shndx);
13704 else
13705 printed = printf (" %4s ", sstr);
13706
13707 if (extra_sym_info && printed < 16)
13708 printf ("%*s", 16 - printed, "");
13709 }
13710 else
13711 {
13712 printf (" %4u ", psym->st_shndx);
13713
13714 if (extra_sym_info)
13715 {
13716 /* Display the section name referenced by the section index. */
13717 int printed = printf ("(%s) ", sstr);
13718 if (printed < 10)
13719 printf ("%*s", 10 - printed, "");
13720 }
13721 }
13722
13723 /* Get the symbol's name. For section symbols without a
13724 specific name use the (already computed) section name. */
23356397 13725 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 13726 && section_index_real (filedata, psym->st_shndx)
23356397
NC
13727 && psym->st_name == 0)
13728 {
b6ac461a 13729 ;
23356397
NC
13730 }
13731 else
13732 {
b6ac461a
NC
13733 bool is_valid;
13734
84714f86 13735 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13736 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13737 }
10ca4b04
L
13738
13739 version_string
13740 = get_symbol_version_string (filedata,
13741 (section == NULL
13742 || section->sh_type == SHT_DYNSYM),
b6ac461a 13743 strtab, strtab_size, symbol_index,
10ca4b04 13744 psym, &sym_info, &vna_other);
b9e920ec 13745
0942c7ab
NC
13746 int len_avail = 21;
13747 if (! do_wide && version_string != NULL)
13748 {
ddb43bab 13749 char buffer[16];
0942c7ab 13750
ddb43bab 13751 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13752
13753 if (sym_info == symbol_undefined)
13754 len_avail -= sprintf (buffer," (%d)", vna_other);
13755 else if (sym_info != symbol_hidden)
13756 len_avail -= 1;
13757 }
13758
b6ac461a 13759 print_symbol_name (len_avail, sstr);
b9e920ec 13760
10ca4b04
L
13761 if (version_string)
13762 {
13763 if (sym_info == symbol_undefined)
13764 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13765 else
10ca4b04
L
13766 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13767 version_string);
13768 }
6bd1a22c 13769
10ca4b04 13770 putchar ('\n');
6bd1a22c 13771
10ca4b04
L
13772 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13773 && section != NULL
b6ac461a 13774 && symbol_index >= section->sh_info
10ca4b04
L
13775 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13776 && filedata->file_header.e_machine != EM_MIPS
13777 /* Solaris binaries have been found to violate this requirement as
13778 well. Not sure if this is a bug or an ABI requirement. */
13779 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13780 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 13781 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 13782}
f16a9783 13783
0f03783c
NC
13784static const char *
13785get_lto_kind (unsigned int kind)
13786{
13787 switch (kind)
13788 {
13789 case 0: return "DEF";
13790 case 1: return "WEAKDEF";
13791 case 2: return "UNDEF";
13792 case 3: return "WEAKUNDEF";
13793 case 4: return "COMMON";
13794 default:
13795 break;
13796 }
13797
13798 static char buffer[30];
13799 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13800 sprintf (buffer, "<unknown: %u>", kind);
13801 return buffer;
13802}
13803
13804static const char *
13805get_lto_visibility (unsigned int visibility)
13806{
13807 switch (visibility)
13808 {
13809 case 0: return "DEFAULT";
13810 case 1: return "PROTECTED";
13811 case 2: return "INTERNAL";
13812 case 3: return "HIDDEN";
13813 default:
13814 break;
13815 }
13816
13817 static char buffer[30];
13818 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13819 sprintf (buffer, "<unknown: %u>", visibility);
13820 return buffer;
13821}
13822
13823static const char *
13824get_lto_sym_type (unsigned int sym_type)
13825{
13826 switch (sym_type)
13827 {
13828 case 0: return "UNKNOWN";
13829 case 1: return "FUNCTION";
13830 case 2: return "VARIABLE";
13831 default:
13832 break;
13833 }
13834
13835 static char buffer[30];
13836 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13837 sprintf (buffer, "<unknown: %u>", sym_type);
13838 return buffer;
13839}
13840
13841/* Display an LTO format symbol table.
13842 FIXME: The format of LTO symbol tables is not formalized.
13843 So this code could need changing in the future. */
13844
015dc7e1 13845static bool
0f03783c
NC
13846display_lto_symtab (Filedata * filedata,
13847 Elf_Internal_Shdr * section)
13848{
13849 if (section->sh_size == 0)
13850 {
ca0e11aa
NC
13851 if (filedata->is_separate)
13852 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13853 printable_section_name (filedata, section),
13854 filedata->file_name);
13855 else
13856 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13857 printable_section_name (filedata, section));
047c3dbf 13858
015dc7e1 13859 return true;
0f03783c
NC
13860 }
13861
13862 if (section->sh_size > filedata->file_size)
13863 {
26c527e6 13864 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13865 printable_section_name (filedata, section),
26c527e6 13866 section->sh_size);
015dc7e1 13867 return false;
0f03783c
NC
13868 }
13869
13870 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13871 section->sh_size, 1, _("LTO symbols"));
13872 if (alloced_data == NULL)
015dc7e1 13873 return false;
0f03783c
NC
13874
13875 /* Look for extended data for the symbol table. */
765a0c0a 13876 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
13877 void * ext_data_orig = NULL;
13878 char * ext_data = NULL;
13879 char * ext_data_end = NULL;
13880 char * ext_name = NULL;
13881
13882 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13883 (section_name (filedata, section)
13884 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13885 && ext_name != NULL /* Paranoia. */
13886 && (ext = find_section (filedata, ext_name)) != NULL)
13887 {
13888 if (ext->sh_size < 3)
13889 error (_("LTO Symbol extension table '%s' is empty!\n"),
13890 printable_section_name (filedata, ext));
13891 else
13892 {
13893 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13894 ext->sh_size, 1,
13895 _("LTO ext symbol data"));
13896 if (ext_data != NULL)
13897 {
13898 ext_data_end = ext_data + ext->sh_size;
13899 if (* ext_data++ != 1)
13900 error (_("Unexpected version number in symbol extension table\n"));
13901 }
13902 }
13903 }
b9e920ec 13904
0f03783c
NC
13905 const unsigned char * data = (const unsigned char *) alloced_data;
13906 const unsigned char * end = data + section->sh_size;
13907
ca0e11aa
NC
13908 if (filedata->is_separate)
13909 printf (_("\nIn linked file '%s': "), filedata->file_name);
13910 else
13911 printf ("\n");
13912
0f03783c
NC
13913 if (ext_data_orig != NULL)
13914 {
13915 if (do_wide)
ca0e11aa 13916 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13917 printable_section_name (filedata, section),
13918 printable_section_name (filedata, ext));
13919 else
13920 {
ca0e11aa 13921 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13922 printable_section_name (filedata, section));
13923 printf (_(" and extension table '%s' contain:\n"),
13924 printable_section_name (filedata, ext));
13925 }
13926 }
13927 else
ca0e11aa 13928 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13929 printable_section_name (filedata, section));
b9e920ec 13930
0f03783c 13931 /* FIXME: Add a wide version. */
b9e920ec 13932 if (ext_data_orig != NULL)
0f03783c
NC
13933 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13934 else
13935 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13936
13937 /* FIXME: We do not handle style prefixes. */
13938
13939 while (data < end)
13940 {
13941 const unsigned char * sym_name = data;
13942 data += strnlen ((const char *) sym_name, end - data) + 1;
13943 if (data >= end)
13944 goto fail;
13945
13946 const unsigned char * comdat_key = data;
13947 data += strnlen ((const char *) comdat_key, end - data) + 1;
13948 if (data >= end)
13949 goto fail;
13950
13951 if (data + 2 + 8 + 4 > end)
13952 goto fail;
13953
13954 unsigned int kind = *data++;
13955 unsigned int visibility = *data++;
13956
928c411d 13957 uint64_t size = byte_get (data, 8);
0f03783c
NC
13958 data += 8;
13959
928c411d 13960 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13961 data += 4;
13962
13963 if (ext_data != NULL)
13964 {
13965 if (ext_data < (ext_data_end - 1))
13966 {
13967 unsigned int sym_type = * ext_data ++;
13968 unsigned int sec_kind = * ext_data ++;
13969
31e5a3a3 13970 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13971 * comdat_key == 0 ? "-" : (char *) comdat_key,
13972 get_lto_kind (kind),
13973 get_lto_visibility (visibility),
31e5a3a3
AM
13974 size,
13975 slot,
0f03783c 13976 get_lto_sym_type (sym_type),
31e5a3a3 13977 sec_kind);
b6ac461a 13978 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
13979 }
13980 else
13981 {
13982 error (_("Ran out of LTO symbol extension data\n"));
13983 ext_data = NULL;
13984 /* FIXME: return FAIL result ? */
13985 }
13986 }
13987 else
13988 {
31e5a3a3 13989 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
13990 * comdat_key == 0 ? "-" : (char *) comdat_key,
13991 get_lto_kind (kind),
13992 get_lto_visibility (visibility),
31e5a3a3
AM
13993 size,
13994 slot);
b6ac461a 13995 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
13996 }
13997 putchar ('\n');
13998 }
13999
14000 if (ext_data != NULL && ext_data < ext_data_end)
14001 {
14002 error (_("Data remains in the LTO symbol extension table\n"));
14003 goto fail;
14004 }
14005
14006 free (alloced_data);
14007 free (ext_data_orig);
14008 free (ext_name);
015dc7e1 14009 return true;
b9e920ec 14010
0f03783c
NC
14011 fail:
14012 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14013 free (alloced_data);
14014 free (ext_data_orig);
14015 free (ext_name);
015dc7e1 14016 return false;
0f03783c
NC
14017}
14018
14019/* Display LTO symbol tables. */
14020
015dc7e1 14021static bool
0f03783c
NC
14022process_lto_symbol_tables (Filedata * filedata)
14023{
14024 Elf_Internal_Shdr * section;
14025 unsigned int i;
015dc7e1 14026 bool res = true;
0f03783c
NC
14027
14028 if (!do_lto_syms)
015dc7e1 14029 return true;
0f03783c
NC
14030
14031 if (filedata->section_headers == NULL)
015dc7e1 14032 return true;
0f03783c
NC
14033
14034 for (i = 0, section = filedata->section_headers;
14035 i < filedata->file_header.e_shnum;
14036 i++, section++)
84714f86
AM
14037 if (section_name_valid (filedata, section)
14038 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14039 res &= display_lto_symtab (filedata, section);
14040
b9e920ec 14041 return res;
0f03783c
NC
14042}
14043
b6ac461a
NC
14044static void
14045print_symbol_table_heading (void)
14046{
14047 /* FIXME: We should store the size of each field in the display in a table and
14048 then use the values inside print_symbol(), instead of that function using
14049 hard coded constants. */
14050 if (is_32bit_elf)
14051 {
14052 if (extra_sym_info)
14053 {
14054 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14055 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14056 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14057 }
14058 else if (do_wide)
14059 {
14060 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14061 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14062 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14063 }
14064 else
14065 {
14066 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14067 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14068 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14069 }
14070 }
14071 else
14072 {
14073 if (extra_sym_info)
14074 {
14075 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14076 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14077 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14078
14079 }
14080 else if (do_wide)
14081 {
14082 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14083 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14084 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14085 }
14086 else
14087 {
14088 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14089 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14090 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14091 }
14092 }
14093}
14094
10ca4b04 14095/* Dump the symbol table. */
0f03783c 14096
015dc7e1 14097static bool
10ca4b04
L
14098process_symbol_table (Filedata * filedata)
14099{
14100 Elf_Internal_Shdr * section;
f16a9783 14101
10ca4b04 14102 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14103 return true;
6bd1a22c 14104
978c4450 14105 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14106 && do_syms
14107 && do_using_dynamic
978c4450
AM
14108 && filedata->dynamic_strings != NULL
14109 && filedata->dynamic_symbols != NULL)
6bd1a22c 14110 {
26c527e6 14111 uint64_t si;
6bd1a22c 14112
ca0e11aa
NC
14113 if (filedata->is_separate)
14114 {
26c527e6
AM
14115 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14116 " contains %" PRIu64 " entry:\n",
14117 "\nIn linked file '%s' the dynamic symbol table"
14118 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14119 filedata->num_dynamic_syms),
14120 filedata->file_name,
14121 filedata->num_dynamic_syms);
14122 }
14123 else
14124 {
26c527e6
AM
14125 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14126 " entry:\n",
14127 "\nSymbol table for image contains %" PRIu64
14128 " entries:\n",
ca0e11aa
NC
14129 filedata->num_dynamic_syms),
14130 filedata->num_dynamic_syms);
14131 }
b6ac461a
NC
14132
14133 print_symbol_table_heading ();
6bd1a22c 14134
978c4450 14135 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14136 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14137 filedata->dynamic_strings,
14138 filedata->dynamic_strings_length);
252b5132 14139 }
8b73c356 14140 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14141 && filedata->section_headers != NULL)
252b5132 14142 {
b34976b6 14143 unsigned int i;
252b5132 14144
dda8d76d
NC
14145 for (i = 0, section = filedata->section_headers;
14146 i < filedata->file_header.e_shnum;
252b5132
RH
14147 i++, section++)
14148 {
2cf0635d 14149 char * strtab = NULL;
26c527e6 14150 uint64_t strtab_size = 0;
2cf0635d 14151 Elf_Internal_Sym * symtab;
26c527e6 14152 uint64_t si, num_syms;
252b5132 14153
2c610e4b
L
14154 if ((section->sh_type != SHT_SYMTAB
14155 && section->sh_type != SHT_DYNSYM)
14156 || (!do_syms
14157 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14158 continue;
14159
dd24e3da
NC
14160 if (section->sh_entsize == 0)
14161 {
14162 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 14163 printable_section_name (filedata, section));
dd24e3da
NC
14164 continue;
14165 }
14166
d3a49aa8 14167 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
14168
14169 if (filedata->is_separate)
26c527e6
AM
14170 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14171 " contains %" PRIu64 " entry:\n",
14172 "\nIn linked file '%s' symbol section '%s'"
14173 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14174 num_syms),
14175 filedata->file_name,
14176 printable_section_name (filedata, section),
14177 num_syms);
14178 else
26c527e6
AM
14179 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14180 " entry:\n",
14181 "\nSymbol table '%s' contains %" PRIu64
14182 " entries:\n",
ca0e11aa
NC
14183 num_syms),
14184 printable_section_name (filedata, section),
14185 num_syms);
dd24e3da 14186
b6ac461a 14187 print_symbol_table_heading ();
252b5132 14188
4de91c10 14189 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
14190 if (symtab == NULL)
14191 continue;
14192
dda8d76d 14193 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 14194 {
dda8d76d
NC
14195 strtab = filedata->string_table;
14196 strtab_size = filedata->string_table_length;
c256ffe7 14197 }
dda8d76d 14198 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 14199 {
2cf0635d 14200 Elf_Internal_Shdr * string_sec;
252b5132 14201
dda8d76d 14202 string_sec = filedata->section_headers + section->sh_link;
252b5132 14203
dda8d76d 14204 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
14205 1, string_sec->sh_size,
14206 _("string table"));
c256ffe7 14207 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
14208 }
14209
10ca4b04 14210 for (si = 0; si < num_syms; si++)
b6ac461a
NC
14211 print_symbol (filedata, si, symtab, section,
14212 strtab, strtab_size);
252b5132
RH
14213
14214 free (symtab);
dda8d76d 14215 if (strtab != filedata->string_table)
252b5132
RH
14216 free (strtab);
14217 }
14218 }
14219 else if (do_syms)
14220 printf
14221 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14222
978c4450 14223 if (do_histogram && filedata->buckets != NULL)
252b5132 14224 {
26c527e6
AM
14225 uint64_t *lengths;
14226 uint64_t *counts;
14227 uint64_t hn;
625d49fc 14228 uint64_t si;
26c527e6
AM
14229 uint64_t maxlength = 0;
14230 uint64_t nzero_counts = 0;
14231 uint64_t nsyms = 0;
6bd6a03d 14232 char *visited;
252b5132 14233
d3a49aa8 14234 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14235 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14236 "\nHistogram for bucket list length "
26c527e6
AM
14237 "(total of %" PRIu64 " buckets):\n",
14238 filedata->nbuckets),
14239 filedata->nbuckets);
252b5132 14240
26c527e6 14241 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14242 if (lengths == NULL)
14243 {
8b73c356 14244 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14245 goto err_out;
252b5132 14246 }
978c4450
AM
14247 visited = xcmalloc (filedata->nchains, 1);
14248 memset (visited, 0, filedata->nchains);
8b73c356
NC
14249
14250 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14251 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14252 {
978c4450 14253 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14254 {
b34976b6 14255 ++nsyms;
252b5132 14256 if (maxlength < ++lengths[hn])
b34976b6 14257 ++maxlength;
978c4450 14258 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14259 {
14260 error (_("histogram chain is corrupt\n"));
14261 break;
14262 }
14263 visited[si] = 1;
252b5132
RH
14264 }
14265 }
6bd6a03d 14266 free (visited);
252b5132 14267
26c527e6 14268 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14269 if (counts == NULL)
14270 {
b2e951ec 14271 free (lengths);
8b73c356 14272 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14273 goto err_out;
252b5132
RH
14274 }
14275
978c4450 14276 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14277 ++counts[lengths[hn]];
252b5132 14278
978c4450 14279 if (filedata->nbuckets > 0)
252b5132 14280 {
26c527e6
AM
14281 uint64_t i;
14282 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14283 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14284 for (i = 1; i <= maxlength; ++i)
103f02d3 14285 {
66543521 14286 nzero_counts += counts[i] * i;
26c527e6 14287 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14288 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14289 (nzero_counts * 100.0) / nsyms);
14290 }
252b5132
RH
14291 }
14292
14293 free (counts);
14294 free (lengths);
14295 }
14296
978c4450
AM
14297 free (filedata->buckets);
14298 filedata->buckets = NULL;
14299 filedata->nbuckets = 0;
14300 free (filedata->chains);
14301 filedata->chains = NULL;
252b5132 14302
978c4450 14303 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14304 {
26c527e6
AM
14305 uint64_t *lengths;
14306 uint64_t *counts;
14307 uint64_t hn;
14308 uint64_t maxlength = 0;
14309 uint64_t nzero_counts = 0;
14310 uint64_t nsyms = 0;
fdc90cb4 14311
f16a9783 14312 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14313 "(total of %" PRIu64 " bucket):\n",
f16a9783 14314 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14315 "(total of %" PRIu64 " buckets):\n",
14316 filedata->ngnubuckets),
978c4450 14317 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14318 filedata->ngnubuckets);
8b73c356 14319
26c527e6 14320 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14321 if (lengths == NULL)
14322 {
8b73c356 14323 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14324 goto err_out;
fdc90cb4
JJ
14325 }
14326
fdc90cb4
JJ
14327 printf (_(" Length Number %% of total Coverage\n"));
14328
978c4450
AM
14329 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14330 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14331 {
625d49fc 14332 uint64_t off, length = 1;
fdc90cb4 14333
978c4450 14334 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14335 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14336 off < filedata->ngnuchains
14337 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14338 ++off)
fdc90cb4
JJ
14339 ++length;
14340 lengths[hn] = length;
14341 if (length > maxlength)
14342 maxlength = length;
14343 nsyms += length;
14344 }
14345
26c527e6 14346 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14347 if (counts == NULL)
14348 {
b2e951ec 14349 free (lengths);
8b73c356 14350 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14351 goto err_out;
fdc90cb4
JJ
14352 }
14353
978c4450 14354 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14355 ++counts[lengths[hn]];
14356
978c4450 14357 if (filedata->ngnubuckets > 0)
fdc90cb4 14358 {
26c527e6
AM
14359 uint64_t j;
14360 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14361 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14362 for (j = 1; j <= maxlength; ++j)
14363 {
14364 nzero_counts += counts[j] * j;
26c527e6 14365 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14366 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14367 (nzero_counts * 100.0) / nsyms);
14368 }
14369 }
14370
14371 free (counts);
14372 free (lengths);
fdc90cb4 14373 }
978c4450
AM
14374 free (filedata->gnubuckets);
14375 filedata->gnubuckets = NULL;
14376 filedata->ngnubuckets = 0;
14377 free (filedata->gnuchains);
14378 filedata->gnuchains = NULL;
14379 filedata->ngnuchains = 0;
14380 free (filedata->mipsxlat);
14381 filedata->mipsxlat = NULL;
015dc7e1 14382 return true;
fd486f32
AM
14383
14384 err_out:
978c4450
AM
14385 free (filedata->gnubuckets);
14386 filedata->gnubuckets = NULL;
14387 filedata->ngnubuckets = 0;
14388 free (filedata->gnuchains);
14389 filedata->gnuchains = NULL;
14390 filedata->ngnuchains = 0;
14391 free (filedata->mipsxlat);
14392 filedata->mipsxlat = NULL;
14393 free (filedata->buckets);
14394 filedata->buckets = NULL;
14395 filedata->nbuckets = 0;
14396 free (filedata->chains);
14397 filedata->chains = NULL;
015dc7e1 14398 return false;
252b5132
RH
14399}
14400
015dc7e1 14401static bool
ca0e11aa 14402process_syminfo (Filedata * filedata)
252b5132 14403{
b4c96d0d 14404 unsigned int i;
252b5132 14405
978c4450 14406 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14407 || !do_dynamic)
14408 /* No syminfo, this is ok. */
015dc7e1 14409 return true;
252b5132
RH
14410
14411 /* There better should be a dynamic symbol section. */
978c4450 14412 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14413 return false;
252b5132 14414
ca0e11aa 14415 if (filedata->is_separate)
26c527e6
AM
14416 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14417 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14418 filedata->dynamic_syminfo_nent),
14419 filedata->file_name,
14420 filedata->dynamic_syminfo_offset,
14421 filedata->dynamic_syminfo_nent);
14422 else
26c527e6
AM
14423 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14424 " contains %d entry:\n",
14425 "\nDynamic info segment at offset %#" PRIx64
14426 " contains %d entries:\n",
978c4450 14427 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14428 filedata->dynamic_syminfo_offset,
14429 filedata->dynamic_syminfo_nent);
252b5132
RH
14430
14431 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14432 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14433 {
978c4450 14434 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14435
31104126 14436 printf ("%4d: ", i);
978c4450 14437 if (i >= filedata->num_dynamic_syms)
4082ef84 14438 printf (_("<corrupt index>"));
84714f86 14439 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14440 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14441 filedata->dynamic_symbols[i].st_name));
d79b3d50 14442 else
978c4450 14443 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14444 putchar (' ');
252b5132 14445
978c4450 14446 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14447 {
14448 case SYMINFO_BT_SELF:
14449 fputs ("SELF ", stdout);
14450 break;
14451 case SYMINFO_BT_PARENT:
14452 fputs ("PARENT ", stdout);
14453 break;
14454 default:
978c4450
AM
14455 if (filedata->dynamic_syminfo[i].si_boundto > 0
14456 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14457 && valid_dynamic_name (filedata,
978c4450 14458 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14459 {
b6ac461a 14460 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 14461 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14462 putchar (' ' );
14463 }
252b5132 14464 else
978c4450 14465 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14466 break;
14467 }
14468
14469 if (flags & SYMINFO_FLG_DIRECT)
14470 printf (" DIRECT");
14471 if (flags & SYMINFO_FLG_PASSTHRU)
14472 printf (" PASSTHRU");
14473 if (flags & SYMINFO_FLG_COPY)
14474 printf (" COPY");
14475 if (flags & SYMINFO_FLG_LAZYLOAD)
14476 printf (" LAZYLOAD");
14477
14478 puts ("");
14479 }
14480
015dc7e1 14481 return true;
252b5132
RH
14482}
14483
75802ccb
CE
14484/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14485 is contained by the region START .. END. The types of ADDR, START
14486 and END should all be the same. Note both ADDR + NELEM and END
14487 point to just beyond the end of the regions that are being tested. */
14488#define IN_RANGE(START,END,ADDR,NELEM) \
14489 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14490
cf13d699
NC
14491/* Check to see if the given reloc needs to be handled in a target specific
14492 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14493 FALSE.
14494
14495 If called with reloc == NULL, then this is a signal that reloc processing
14496 for the current section has finished, and any saved state should be
14497 discarded. */
09c11c86 14498
015dc7e1 14499static bool
26c527e6
AM
14500target_specific_reloc_handling (Filedata *filedata,
14501 Elf_Internal_Rela *reloc,
14502 unsigned char *start,
14503 unsigned char *end,
14504 Elf_Internal_Sym *symtab,
14505 uint64_t num_syms)
252b5132 14506{
f84ce13b 14507 unsigned int reloc_type = 0;
26c527e6 14508 uint64_t sym_index = 0;
f84ce13b
NC
14509
14510 if (reloc)
14511 {
dda8d76d 14512 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14513 sym_index = get_reloc_symindex (reloc->r_info);
14514 }
252b5132 14515
dda8d76d 14516 switch (filedata->file_header.e_machine)
252b5132 14517 {
76244462 14518 case EM_LOONGARCH:
14519 {
14520 switch (reloc_type)
14521 {
14522 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14523 at assembly time. */
14524 case 107: /* R_LARCH_ADD_ULEB128. */
14525 case 108: /* R_LARCH_SUB_ULEB128. */
14526 {
d3f34076 14527 uint64_t value = 0;
76244462 14528 unsigned int reloc_size = 0;
14529 int leb_ret = 0;
14530
89c70cd3
AM
14531 if (reloc->r_offset < (size_t) (end - start))
14532 value = read_leb128 (start + reloc->r_offset, end, false,
14533 &reloc_size, &leb_ret);
76244462 14534 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14535 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14536 "ULEB128 value\n"),
14537 (long) reloc->r_offset);
14538
74a965d8
AM
14539 else if (sym_index >= num_syms)
14540 error (_("%s reloc contains invalid symbol index "
14541 "%" PRIu64 "\n"),
14542 (reloc_type == 107
14543 ? "R_LARCH_ADD_ULEB128"
14544 : "R_LARCH_SUB_ULEB128"),
14545 sym_index);
14546 else
76244462 14547 {
74a965d8
AM
14548 if (reloc_type == 107)
14549 value += reloc->r_addend + symtab[sym_index].st_value;
14550 else
14551 value -= reloc->r_addend + symtab[sym_index].st_value;
14552
14553 /* Write uleb128 value to p. */
14554 bfd_byte *p = start + reloc->r_offset;
14555 do
14556 {
14557 bfd_byte c = value & 0x7f;
14558 value >>= 7;
14559 if (--reloc_size != 0)
14560 c |= 0x80;
14561 *p++ = c;
14562 }
14563 while (reloc_size);
76244462 14564 }
76244462 14565
14566 return true;
14567 }
14568 }
14569 break;
14570 }
14571
13761a11
NC
14572 case EM_MSP430:
14573 case EM_MSP430_OLD:
14574 {
14575 static Elf_Internal_Sym * saved_sym = NULL;
14576
f84ce13b
NC
14577 if (reloc == NULL)
14578 {
14579 saved_sym = NULL;
015dc7e1 14580 return true;
f84ce13b
NC
14581 }
14582
13761a11
NC
14583 switch (reloc_type)
14584 {
14585 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14586 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14587 if (uses_msp430x_relocs (filedata))
13761a11 14588 break;
1a0670f3 14589 /* Fall through. */
13761a11 14590 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14591 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14592 /* PR 21139. */
14593 if (sym_index >= num_syms)
74a965d8
AM
14594 error (_("%s reloc contains invalid symbol index "
14595 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14596 else
14597 saved_sym = symtab + sym_index;
015dc7e1 14598 return true;
13761a11
NC
14599
14600 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14601 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14602 goto handle_sym_diff;
0b4362b0 14603
13761a11
NC
14604 case 5: /* R_MSP430_16_BYTE */
14605 case 9: /* R_MSP430_8 */
7d81bc93 14606 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14607 if (uses_msp430x_relocs (filedata))
13761a11
NC
14608 break;
14609 goto handle_sym_diff;
14610
14611 case 2: /* R_MSP430_ABS16 */
14612 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14613 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14614 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14615 break;
14616 goto handle_sym_diff;
0b4362b0 14617
13761a11
NC
14618 handle_sym_diff:
14619 if (saved_sym != NULL)
14620 {
625d49fc 14621 uint64_t value;
5a805384 14622 unsigned int reloc_size = 0;
7d81bc93
JL
14623 int leb_ret = 0;
14624 switch (reloc_type)
14625 {
14626 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14627 reloc_size = 4;
14628 break;
14629 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14630 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14631 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14632 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14633 &reloc_size, &leb_ret);
7d81bc93
JL
14634 break;
14635 default:
14636 reloc_size = 2;
14637 break;
14638 }
13761a11 14639
5a805384 14640 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14641 error (_("MSP430 ULEB128 field at %#" PRIx64
14642 " contains invalid ULEB128 value\n"),
14643 reloc->r_offset);
7d81bc93 14644 else if (sym_index >= num_syms)
74a965d8
AM
14645 error (_("%s reloc contains invalid symbol index "
14646 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14647 else
f84ce13b
NC
14648 {
14649 value = reloc->r_addend + (symtab[sym_index].st_value
14650 - saved_sym->st_value);
14651
b32e566b 14652 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14653 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14654 else
14655 /* PR 21137 */
26c527e6
AM
14656 error (_("MSP430 sym diff reloc contains invalid offset: "
14657 "%#" PRIx64 "\n"),
14658 reloc->r_offset);
f84ce13b 14659 }
13761a11
NC
14660
14661 saved_sym = NULL;
015dc7e1 14662 return true;
13761a11
NC
14663 }
14664 break;
14665
14666 default:
14667 if (saved_sym != NULL)
071436c6 14668 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14669 break;
14670 }
14671 break;
14672 }
14673
cf13d699
NC
14674 case EM_MN10300:
14675 case EM_CYGNUS_MN10300:
14676 {
14677 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14678
f84ce13b
NC
14679 if (reloc == NULL)
14680 {
14681 saved_sym = NULL;
015dc7e1 14682 return true;
f84ce13b
NC
14683 }
14684
cf13d699
NC
14685 switch (reloc_type)
14686 {
14687 case 34: /* R_MN10300_ALIGN */
015dc7e1 14688 return true;
cf13d699 14689 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14690 if (sym_index >= num_syms)
74a965d8
AM
14691 error (_("%s reloc contains invalid symbol index "
14692 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14693 else
14694 saved_sym = symtab + sym_index;
015dc7e1 14695 return true;
f84ce13b 14696
cf13d699
NC
14697 case 1: /* R_MN10300_32 */
14698 case 2: /* R_MN10300_16 */
14699 if (saved_sym != NULL)
14700 {
03f7786e 14701 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14702 uint64_t value;
252b5132 14703
f84ce13b 14704 if (sym_index >= num_syms)
74a965d8
AM
14705 error (_("%s reloc contains invalid symbol index "
14706 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14707 else
f84ce13b
NC
14708 {
14709 value = reloc->r_addend + (symtab[sym_index].st_value
14710 - saved_sym->st_value);
14711
b32e566b 14712 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14713 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14714 else
26c527e6
AM
14715 error (_("MN10300 sym diff reloc contains invalid offset:"
14716 " %#" PRIx64 "\n"),
14717 reloc->r_offset);
f84ce13b 14718 }
252b5132 14719
cf13d699 14720 saved_sym = NULL;
015dc7e1 14721 return true;
cf13d699
NC
14722 }
14723 break;
14724 default:
14725 if (saved_sym != NULL)
071436c6 14726 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14727 break;
14728 }
14729 break;
14730 }
6ff71e76
NC
14731
14732 case EM_RL78:
14733 {
625d49fc
AM
14734 static uint64_t saved_sym1 = 0;
14735 static uint64_t saved_sym2 = 0;
14736 static uint64_t value;
6ff71e76 14737
f84ce13b
NC
14738 if (reloc == NULL)
14739 {
14740 saved_sym1 = saved_sym2 = 0;
015dc7e1 14741 return true;
f84ce13b
NC
14742 }
14743
6ff71e76
NC
14744 switch (reloc_type)
14745 {
14746 case 0x80: /* R_RL78_SYM. */
14747 saved_sym1 = saved_sym2;
f84ce13b 14748 if (sym_index >= num_syms)
74a965d8
AM
14749 error (_("%s reloc contains invalid symbol index "
14750 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14751 else
14752 {
14753 saved_sym2 = symtab[sym_index].st_value;
14754 saved_sym2 += reloc->r_addend;
14755 }
015dc7e1 14756 return true;
6ff71e76
NC
14757
14758 case 0x83: /* R_RL78_OPsub. */
14759 value = saved_sym1 - saved_sym2;
14760 saved_sym2 = saved_sym1 = 0;
015dc7e1 14761 return true;
6ff71e76
NC
14762 break;
14763
14764 case 0x41: /* R_RL78_ABS32. */
b32e566b 14765 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14766 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14767 else
26c527e6
AM
14768 error (_("RL78 sym diff reloc contains invalid offset: "
14769 "%#" PRIx64 "\n"),
14770 reloc->r_offset);
6ff71e76 14771 value = 0;
015dc7e1 14772 return true;
6ff71e76
NC
14773
14774 case 0x43: /* R_RL78_ABS16. */
b32e566b 14775 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14776 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14777 else
26c527e6
AM
14778 error (_("RL78 sym diff reloc contains invalid offset: "
14779 "%#" PRIx64 "\n"),
14780 reloc->r_offset);
6ff71e76 14781 value = 0;
015dc7e1 14782 return true;
6ff71e76
NC
14783
14784 default:
14785 break;
14786 }
14787 break;
14788 }
252b5132
RH
14789 }
14790
015dc7e1 14791 return false;
252b5132
RH
14792}
14793
aca88567
NC
14794/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14795 DWARF debug sections. This is a target specific test. Note - we do not
14796 go through the whole including-target-headers-multiple-times route, (as
14797 we have already done with <elf/h8.h>) because this would become very
14798 messy and even then this function would have to contain target specific
14799 information (the names of the relocs instead of their numeric values).
14800 FIXME: This is not the correct way to solve this problem. The proper way
14801 is to have target specific reloc sizing and typing functions created by
14802 the reloc-macros.h header, in the same way that it already creates the
14803 reloc naming functions. */
14804
015dc7e1 14805static bool
dda8d76d 14806is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14807{
d347c9df 14808 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14809 switch (filedata->file_header.e_machine)
aca88567 14810 {
41e92641 14811 case EM_386:
22abe556 14812 case EM_IAMCU:
41e92641 14813 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14814 case EM_68K:
14815 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14816 case EM_860:
14817 return reloc_type == 1; /* R_860_32. */
14818 case EM_960:
14819 return reloc_type == 2; /* R_960_32. */
a06ea964 14820 case EM_AARCH64:
9282b95a
JW
14821 return (reloc_type == 258
14822 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14823 case EM_BPF:
14824 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14825 case EM_ADAPTEVA_EPIPHANY:
14826 return reloc_type == 3;
aca88567 14827 case EM_ALPHA:
137b6b5f 14828 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14829 case EM_ARC:
14830 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14831 case EM_ARC_COMPACT:
14832 case EM_ARC_COMPACT2:
b5c37946
SJ
14833 case EM_ARC_COMPACT3:
14834 case EM_ARC_COMPACT3_64:
886a2506 14835 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14836 case EM_ARM:
14837 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14838 case EM_AVR_OLD:
aca88567
NC
14839 case EM_AVR:
14840 return reloc_type == 1;
14841 case EM_BLACKFIN:
14842 return reloc_type == 0x12; /* R_byte4_data. */
14843 case EM_CRIS:
14844 return reloc_type == 3; /* R_CRIS_32. */
14845 case EM_CR16:
14846 return reloc_type == 3; /* R_CR16_NUM32. */
14847 case EM_CRX:
14848 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14849 case EM_CSKY:
14850 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14851 case EM_CYGNUS_FRV:
14852 return reloc_type == 1;
41e92641
NC
14853 case EM_CYGNUS_D10V:
14854 case EM_D10V:
14855 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14856 case EM_CYGNUS_D30V:
14857 case EM_D30V:
14858 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14859 case EM_DLX:
14860 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14861 case EM_CYGNUS_FR30:
14862 case EM_FR30:
14863 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14864 case EM_FT32:
14865 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14866 case EM_H8S:
14867 case EM_H8_300:
14868 case EM_H8_300H:
14869 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14870 case EM_IA_64:
262cdac7
AM
14871 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14872 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14873 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14874 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14875 case EM_IP2K_OLD:
14876 case EM_IP2K:
14877 return reloc_type == 2; /* R_IP2K_32. */
14878 case EM_IQ2000:
14879 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
14880 case EM_KVX:
14881 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
14882 case EM_LATTICEMICO32:
14883 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14884 case EM_LOONGARCH:
14885 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14886 case EM_M32C_OLD:
aca88567
NC
14887 case EM_M32C:
14888 return reloc_type == 3; /* R_M32C_32. */
14889 case EM_M32R:
14890 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14891 case EM_68HC11:
14892 case EM_68HC12:
14893 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14894 case EM_S12Z:
2849d19f
JD
14895 return reloc_type == 7 || /* R_S12Z_EXT32 */
14896 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14897 case EM_MCORE:
14898 return reloc_type == 1; /* R_MCORE_ADDR32. */
14899 case EM_CYGNUS_MEP:
14900 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14901 case EM_METAG:
14902 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14903 case EM_MICROBLAZE:
14904 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14905 case EM_MIPS:
14906 return reloc_type == 2; /* R_MIPS_32. */
14907 case EM_MMIX:
14908 return reloc_type == 4; /* R_MMIX_32. */
14909 case EM_CYGNUS_MN10200:
14910 case EM_MN10200:
14911 return reloc_type == 1; /* R_MN10200_32. */
14912 case EM_CYGNUS_MN10300:
14913 case EM_MN10300:
14914 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14915 case EM_MOXIE:
14916 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14917 case EM_MSP430_OLD:
14918 case EM_MSP430:
13761a11 14919 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14920 case EM_MT:
14921 return reloc_type == 2; /* R_MT_32. */
35c08157 14922 case EM_NDS32:
81c5e376 14923 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14924 case EM_ALTERA_NIOS2:
36591ba1 14925 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14926 case EM_NIOS32:
14927 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14928 case EM_OR1K:
14929 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14930 case EM_PARISC:
9abca702 14931 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14932 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14933 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14934 case EM_PJ:
14935 case EM_PJ_OLD:
14936 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14937 case EM_PPC64:
14938 return reloc_type == 1; /* R_PPC64_ADDR32. */
14939 case EM_PPC:
14940 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14941 case EM_TI_PRU:
14942 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14943 case EM_RISCV:
14944 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14945 case EM_RL78:
14946 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14947 case EM_RX:
14948 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14949 case EM_S370:
14950 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14951 case EM_S390_OLD:
14952 case EM_S390:
14953 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14954 case EM_SCORE:
14955 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14956 case EM_SH:
14957 return reloc_type == 1; /* R_SH_DIR32. */
14958 case EM_SPARC32PLUS:
14959 case EM_SPARCV9:
14960 case EM_SPARC:
14961 return reloc_type == 3 /* R_SPARC_32. */
14962 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14963 case EM_SPU:
14964 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14965 case EM_TI_C6000:
14966 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14967 case EM_TILEGX:
14968 return reloc_type == 2; /* R_TILEGX_32. */
14969 case EM_TILEPRO:
14970 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14971 case EM_CYGNUS_V850:
14972 case EM_V850:
14973 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14974 case EM_V800:
14975 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14976 case EM_VAX:
14977 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14978 case EM_VISIUM:
14979 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14980 case EM_WEBASSEMBLY:
14981 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14982 case EM_X86_64:
8a9036a4 14983 case EM_L1OM:
7a9068fe 14984 case EM_K1OM:
aca88567 14985 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14986 case EM_XGATE:
14987 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14988 case EM_XSTORMY16:
14989 return reloc_type == 1; /* R_XSTROMY16_32. */
14990 case EM_XTENSA_OLD:
14991 case EM_XTENSA:
14992 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14993 case EM_Z80:
14994 return reloc_type == 6; /* R_Z80_32. */
aca88567 14995 default:
bee0ee85
NC
14996 {
14997 static unsigned int prev_warn = 0;
14998
14999 /* Avoid repeating the same warning multiple times. */
dda8d76d 15000 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15001 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15002 filedata->file_header.e_machine);
15003 prev_warn = filedata->file_header.e_machine;
015dc7e1 15004 return false;
bee0ee85 15005 }
aca88567
NC
15006 }
15007}
15008
15009/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15010 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15011
015dc7e1 15012static bool
dda8d76d 15013is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15014{
dda8d76d 15015 switch (filedata->file_header.e_machine)
d347c9df 15016 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15017 {
41e92641 15018 case EM_386:
22abe556 15019 case EM_IAMCU:
3e0873ac 15020 return reloc_type == 2; /* R_386_PC32. */
aca88567 15021 case EM_68K:
3e0873ac 15022 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15023 case EM_AARCH64:
15024 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15025 case EM_ADAPTEVA_EPIPHANY:
15026 return reloc_type == 6;
aca88567
NC
15027 case EM_ALPHA:
15028 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15029 case EM_ARC_COMPACT:
15030 case EM_ARC_COMPACT2:
b5c37946
SJ
15031 case EM_ARC_COMPACT3:
15032 case EM_ARC_COMPACT3_64:
726c18e1 15033 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15034 case EM_ARM:
3e0873ac 15035 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15036 case EM_AVR_OLD:
15037 case EM_AVR:
15038 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15039 case EM_LOONGARCH:
15040 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15041 case EM_MICROBLAZE:
15042 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15043 case EM_OR1K:
15044 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15045 case EM_PARISC:
85acf597 15046 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15047 case EM_PPC:
15048 return reloc_type == 26; /* R_PPC_REL32. */
15049 case EM_PPC64:
3e0873ac 15050 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15051 case EM_RISCV:
15052 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15053 case EM_S390_OLD:
15054 case EM_S390:
3e0873ac 15055 return reloc_type == 5; /* R_390_PC32. */
aca88567 15056 case EM_SH:
3e0873ac 15057 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15058 case EM_SPARC32PLUS:
15059 case EM_SPARCV9:
15060 case EM_SPARC:
3e0873ac 15061 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15062 case EM_SPU:
15063 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15064 case EM_TILEGX:
15065 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15066 case EM_TILEPRO:
15067 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15068 case EM_VISIUM:
15069 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15070 case EM_X86_64:
8a9036a4 15071 case EM_L1OM:
7a9068fe 15072 case EM_K1OM:
3e0873ac 15073 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15074 case EM_VAX:
15075 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15076 case EM_XTENSA_OLD:
15077 case EM_XTENSA:
15078 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15079 case EM_KVX:
15080 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15081 default:
15082 /* Do not abort or issue an error message here. Not all targets use
15083 pc-relative 32-bit relocs in their DWARF debug information and we
15084 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15085 more helpful warning message will be generated by apply_relocations
15086 anyway, so just return. */
015dc7e1 15087 return false;
aca88567
NC
15088 }
15089}
15090
15091/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15092 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15093
015dc7e1 15094static bool
dda8d76d 15095is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15096{
dda8d76d 15097 switch (filedata->file_header.e_machine)
aca88567 15098 {
a06ea964
NC
15099 case EM_AARCH64:
15100 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15101 case EM_ARC_COMPACT3_64:
15102 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15103 case EM_ALPHA:
15104 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15105 case EM_IA_64:
262cdac7
AM
15106 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15107 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15108 case EM_LOONGARCH:
15109 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15110 case EM_PARISC:
15111 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15112 case EM_PPC64:
15113 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15114 case EM_RISCV:
15115 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15116 case EM_SPARC32PLUS:
15117 case EM_SPARCV9:
15118 case EM_SPARC:
714da62f
NC
15119 return reloc_type == 32 /* R_SPARC_64. */
15120 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15121 case EM_X86_64:
8a9036a4 15122 case EM_L1OM:
7a9068fe 15123 case EM_K1OM:
aca88567 15124 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15125 case EM_S390_OLD:
15126 case EM_S390:
aa137e4d
NC
15127 return reloc_type == 22; /* R_S390_64. */
15128 case EM_TILEGX:
15129 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15130 case EM_MIPS:
aa137e4d 15131 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15132 case EM_KVX:
15133 return reloc_type == 3; /* R_KVX_64 */
aca88567 15134 default:
015dc7e1 15135 return false;
aca88567
NC
15136 }
15137}
15138
85acf597
RH
15139/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15140 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15141
015dc7e1 15142static bool
dda8d76d 15143is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15144{
dda8d76d 15145 switch (filedata->file_header.e_machine)
85acf597 15146 {
a06ea964
NC
15147 case EM_AARCH64:
15148 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15149 case EM_ALPHA:
aa137e4d 15150 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15151 case EM_IA_64:
262cdac7
AM
15152 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15153 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15154 case EM_PARISC:
aa137e4d 15155 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15156 case EM_PPC64:
aa137e4d 15157 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15158 case EM_SPARC32PLUS:
15159 case EM_SPARCV9:
15160 case EM_SPARC:
aa137e4d 15161 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15162 case EM_X86_64:
8a9036a4 15163 case EM_L1OM:
7a9068fe 15164 case EM_K1OM:
aa137e4d 15165 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15166 case EM_S390_OLD:
15167 case EM_S390:
aa137e4d
NC
15168 return reloc_type == 23; /* R_S390_PC64. */
15169 case EM_TILEGX:
15170 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15171 default:
015dc7e1 15172 return false;
85acf597
RH
15173 }
15174}
15175
4dc3c23d
AM
15176/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15177 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15178
015dc7e1 15179static bool
dda8d76d 15180is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15181{
dda8d76d 15182 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15183 {
15184 case EM_CYGNUS_MN10200:
15185 case EM_MN10200:
15186 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15187 case EM_FT32:
15188 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15189 case EM_Z80:
15190 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15191 default:
015dc7e1 15192 return false;
4dc3c23d
AM
15193 }
15194}
15195
aca88567
NC
15196/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15197 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15198
015dc7e1 15199static bool
dda8d76d 15200is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15201{
d347c9df 15202 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15203 switch (filedata->file_header.e_machine)
4b78141a 15204 {
886a2506
NC
15205 case EM_ARC:
15206 case EM_ARC_COMPACT:
15207 case EM_ARC_COMPACT2:
b5c37946
SJ
15208 case EM_ARC_COMPACT3:
15209 case EM_ARC_COMPACT3_64:
886a2506 15210 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15211 case EM_ADAPTEVA_EPIPHANY:
15212 return reloc_type == 5;
aca88567
NC
15213 case EM_AVR_OLD:
15214 case EM_AVR:
15215 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15216 case EM_CYGNUS_D10V:
15217 case EM_D10V:
15218 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15219 case EM_FT32:
15220 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15221 case EM_H8S:
15222 case EM_H8_300:
15223 case EM_H8_300H:
aca88567
NC
15224 return reloc_type == R_H8_DIR16;
15225 case EM_IP2K_OLD:
15226 case EM_IP2K:
15227 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15228 case EM_M32C_OLD:
f4236fe4
DD
15229 case EM_M32C:
15230 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15231 case EM_CYGNUS_MN10200:
15232 case EM_MN10200:
15233 return reloc_type == 2; /* R_MN10200_16. */
15234 case EM_CYGNUS_MN10300:
15235 case EM_MN10300:
15236 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15237 case EM_KVX:
15238 return reloc_type == 1; /* R_KVX_16 */
aca88567 15239 case EM_MSP430:
dda8d76d 15240 if (uses_msp430x_relocs (filedata))
13761a11 15241 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15242 /* Fall through. */
78c8d46c 15243 case EM_MSP430_OLD:
aca88567 15244 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15245 case EM_NDS32:
81c5e376 15246 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15247 case EM_ALTERA_NIOS2:
36591ba1 15248 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15249 case EM_NIOS32:
15250 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15251 case EM_OR1K:
15252 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15253 case EM_RISCV:
15254 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15255 case EM_TI_PRU:
15256 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15257 case EM_TI_C6000:
15258 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15259 case EM_VISIUM:
15260 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15261 case EM_XGATE:
15262 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15263 case EM_Z80:
15264 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15265 default:
015dc7e1 15266 return false;
4b78141a
NC
15267 }
15268}
15269
39e07931
AS
15270/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15271 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15272
015dc7e1 15273static bool
39e07931
AS
15274is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15275{
15276 switch (filedata->file_header.e_machine)
15277 {
15278 case EM_RISCV:
15279 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15280 case EM_Z80:
15281 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15282 case EM_MICROBLAZE:
15283 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15284 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15285 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15286 default:
015dc7e1 15287 return false;
39e07931
AS
15288 }
15289}
15290
15291/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15292 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15293
015dc7e1 15294static bool
39e07931
AS
15295is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15296{
15297 switch (filedata->file_header.e_machine)
15298 {
15299 case EM_RISCV:
15300 return reloc_type == 53; /* R_RISCV_SET6. */
15301 default:
015dc7e1 15302 return false;
39e07931
AS
15303 }
15304}
15305
03336641
JW
15306/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15307 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15308
015dc7e1 15309static bool
03336641
JW
15310is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15311{
15312 /* Please keep this table alpha-sorted for ease of visual lookup. */
15313 switch (filedata->file_header.e_machine)
15314 {
76244462 15315 case EM_LOONGARCH:
15316 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15317 case EM_RISCV:
15318 return reloc_type == 35; /* R_RISCV_ADD32. */
15319 default:
015dc7e1 15320 return false;
03336641
JW
15321 }
15322}
15323
15324/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15325 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15326
015dc7e1 15327static bool
03336641
JW
15328is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15329{
15330 /* Please keep this table alpha-sorted for ease of visual lookup. */
15331 switch (filedata->file_header.e_machine)
15332 {
76244462 15333 case EM_LOONGARCH:
15334 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15335 case EM_RISCV:
15336 return reloc_type == 39; /* R_RISCV_SUB32. */
15337 default:
015dc7e1 15338 return false;
03336641
JW
15339 }
15340}
15341
15342/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15343 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15344
015dc7e1 15345static bool
03336641
JW
15346is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15347{
15348 /* Please keep this table alpha-sorted for ease of visual lookup. */
15349 switch (filedata->file_header.e_machine)
15350 {
76244462 15351 case EM_LOONGARCH:
15352 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15353 case EM_RISCV:
15354 return reloc_type == 36; /* R_RISCV_ADD64. */
15355 default:
015dc7e1 15356 return false;
03336641
JW
15357 }
15358}
15359
15360/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15361 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15362
015dc7e1 15363static bool
03336641
JW
15364is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15365{
15366 /* Please keep this table alpha-sorted for ease of visual lookup. */
15367 switch (filedata->file_header.e_machine)
15368 {
76244462 15369 case EM_LOONGARCH:
15370 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15371 case EM_RISCV:
15372 return reloc_type == 40; /* R_RISCV_SUB64. */
15373 default:
015dc7e1 15374 return false;
03336641
JW
15375 }
15376}
15377
15378/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15379 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15380
015dc7e1 15381static bool
03336641
JW
15382is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15383{
15384 /* Please keep this table alpha-sorted for ease of visual lookup. */
15385 switch (filedata->file_header.e_machine)
15386 {
76244462 15387 case EM_LOONGARCH:
15388 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15389 case EM_RISCV:
15390 return reloc_type == 34; /* R_RISCV_ADD16. */
15391 default:
015dc7e1 15392 return false;
03336641
JW
15393 }
15394}
15395
15396/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15397 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15398
015dc7e1 15399static bool
03336641
JW
15400is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15401{
15402 /* Please keep this table alpha-sorted for ease of visual lookup. */
15403 switch (filedata->file_header.e_machine)
15404 {
76244462 15405 case EM_LOONGARCH:
15406 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15407 case EM_RISCV:
15408 return reloc_type == 38; /* R_RISCV_SUB16. */
15409 default:
015dc7e1 15410 return false;
03336641
JW
15411 }
15412}
15413
15414/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15415 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15416
015dc7e1 15417static bool
03336641
JW
15418is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15419{
15420 /* Please keep this table alpha-sorted for ease of visual lookup. */
15421 switch (filedata->file_header.e_machine)
15422 {
76244462 15423 case EM_LOONGARCH:
15424 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15425 case EM_RISCV:
15426 return reloc_type == 33; /* R_RISCV_ADD8. */
15427 default:
015dc7e1 15428 return false;
03336641
JW
15429 }
15430}
15431
15432/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15433 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15434
015dc7e1 15435static bool
03336641
JW
15436is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15437{
15438 /* Please keep this table alpha-sorted for ease of visual lookup. */
15439 switch (filedata->file_header.e_machine)
15440 {
76244462 15441 case EM_LOONGARCH:
15442 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15443 case EM_RISCV:
15444 return reloc_type == 37; /* R_RISCV_SUB8. */
15445 default:
015dc7e1 15446 return false;
03336641
JW
15447 }
15448}
15449
76244462 15450/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15451 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15452
15453static bool
15454is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15455{
15456 switch (filedata->file_header.e_machine)
15457 {
15458 case EM_LOONGARCH:
15459 return reloc_type == 105; /* R_LARCH_ADD6. */
15460 default:
15461 return false;
15462 }
15463}
15464
39e07931
AS
15465/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15466 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15467
015dc7e1 15468static bool
39e07931
AS
15469is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15470{
15471 switch (filedata->file_header.e_machine)
15472 {
76244462 15473 case EM_LOONGARCH:
15474 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15475 case EM_RISCV:
15476 return reloc_type == 52; /* R_RISCV_SUB6. */
15477 default:
015dc7e1 15478 return false;
39e07931
AS
15479 }
15480}
15481
2a7b2e88
JK
15482/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15483 relocation entries (possibly formerly used for SHT_GROUP sections). */
15484
015dc7e1 15485static bool
dda8d76d 15486is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15487{
dda8d76d 15488 switch (filedata->file_header.e_machine)
2a7b2e88 15489 {
cb8f3167 15490 case EM_386: /* R_386_NONE. */
d347c9df 15491 case EM_68K: /* R_68K_NONE. */
cfb8c092 15492 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15493 case EM_ALPHA: /* R_ALPHA_NONE. */
15494 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15495 case EM_ARC: /* R_ARC_NONE. */
886a2506 15496 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15497 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15498 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15499 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15500 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15501 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15502 case EM_FT32: /* R_FT32_NONE. */
15503 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15504 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15505 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15506 case EM_L1OM: /* R_X86_64_NONE. */
15507 case EM_M32R: /* R_M32R_NONE. */
15508 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15509 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15510 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15511 case EM_NIOS32: /* R_NIOS_NONE. */
15512 case EM_OR1K: /* R_OR1K_NONE. */
15513 case EM_PARISC: /* R_PARISC_NONE. */
15514 case EM_PPC64: /* R_PPC64_NONE. */
15515 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15516 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15517 case EM_S390: /* R_390_NONE. */
15518 case EM_S390_OLD:
15519 case EM_SH: /* R_SH_NONE. */
15520 case EM_SPARC32PLUS:
15521 case EM_SPARC: /* R_SPARC_NONE. */
15522 case EM_SPARCV9:
aa137e4d
NC
15523 case EM_TILEGX: /* R_TILEGX_NONE. */
15524 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15525 case EM_TI_C6000:/* R_C6000_NONE. */
15526 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15527 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15528 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15529 return reloc_type == 0;
d347c9df 15530
a06ea964
NC
15531 case EM_AARCH64:
15532 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15533 case EM_AVR_OLD:
15534 case EM_AVR:
15535 return (reloc_type == 0 /* R_AVR_NONE. */
15536 || reloc_type == 30 /* R_AVR_DIFF8. */
15537 || reloc_type == 31 /* R_AVR_DIFF16. */
15538 || reloc_type == 32 /* R_AVR_DIFF32. */);
15539 case EM_METAG:
15540 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15541 case EM_NDS32:
81c5e376
AM
15542 return (reloc_type == 0 /* R_NDS32_NONE. */
15543 || reloc_type == 205 /* R_NDS32_DIFF8. */
15544 || reloc_type == 206 /* R_NDS32_DIFF16. */
15545 || reloc_type == 207 /* R_NDS32_DIFF32. */
15546 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15547 case EM_TI_PRU:
15548 return (reloc_type == 0 /* R_PRU_NONE. */
15549 || reloc_type == 65 /* R_PRU_DIFF8. */
15550 || reloc_type == 66 /* R_PRU_DIFF16. */
15551 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15552 case EM_XTENSA_OLD:
15553 case EM_XTENSA:
4dc3c23d
AM
15554 return (reloc_type == 0 /* R_XTENSA_NONE. */
15555 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15556 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15557 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15558 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15559 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15560 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15561 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15562 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15563 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15564 }
015dc7e1 15565 return false;
2a7b2e88
JK
15566}
15567
d1c4b12b
NC
15568/* Returns TRUE if there is a relocation against
15569 section NAME at OFFSET bytes. */
15570
015dc7e1 15571bool
31e5a3a3 15572reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15573{
15574 Elf_Internal_Rela * relocs;
15575 Elf_Internal_Rela * rp;
15576
15577 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15578 return false;
d1c4b12b
NC
15579
15580 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15581
15582 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15583 if (rp->r_offset == offset)
015dc7e1 15584 return true;
d1c4b12b 15585
015dc7e1 15586 return false;
d1c4b12b
NC
15587}
15588
cf13d699 15589/* Apply relocations to a section.
32ec8896
NC
15590 Returns TRUE upon success, FALSE otherwise.
15591 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15592 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15593 will be set to the number of relocs loaded.
15594
cf13d699 15595 Note: So far support has been added only for those relocations
32ec8896
NC
15596 which can be found in debug sections. FIXME: Add support for
15597 more relocations ? */
1b315056 15598
015dc7e1 15599static bool
be7d229a
AM
15600apply_relocations (Filedata *filedata,
15601 const Elf_Internal_Shdr *section,
15602 unsigned char *start,
15603 size_t size,
15604 void **relocs_return,
26c527e6 15605 uint64_t *num_relocs_return)
1b315056 15606{
cf13d699 15607 Elf_Internal_Shdr * relsec;
0d2a7a93 15608 unsigned char * end = start + size;
cb8f3167 15609
d1c4b12b
NC
15610 if (relocs_return != NULL)
15611 {
15612 * (Elf_Internal_Rela **) relocs_return = NULL;
15613 * num_relocs_return = 0;
15614 }
15615
dda8d76d 15616 if (filedata->file_header.e_type != ET_REL)
32ec8896 15617 /* No relocs to apply. */
015dc7e1 15618 return true;
1b315056 15619
cf13d699 15620 /* Find the reloc section associated with the section. */
dda8d76d
NC
15621 for (relsec = filedata->section_headers;
15622 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15623 ++relsec)
252b5132 15624 {
015dc7e1 15625 bool is_rela;
26c527e6 15626 uint64_t num_relocs;
2cf0635d
NC
15627 Elf_Internal_Rela * relocs;
15628 Elf_Internal_Rela * rp;
15629 Elf_Internal_Shdr * symsec;
15630 Elf_Internal_Sym * symtab;
26c527e6 15631 uint64_t num_syms;
2cf0635d 15632 Elf_Internal_Sym * sym;
252b5132 15633
41e92641 15634 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15635 || relsec->sh_info >= filedata->file_header.e_shnum
15636 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15637 || relsec->sh_size == 0
dda8d76d 15638 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15639 continue;
428409d5 15640
a788aedd
AM
15641 symsec = filedata->section_headers + relsec->sh_link;
15642 if (symsec->sh_type != SHT_SYMTAB
15643 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15644 return false;
a788aedd 15645
41e92641
NC
15646 is_rela = relsec->sh_type == SHT_RELA;
15647
15648 if (is_rela)
15649 {
dda8d76d 15650 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15651 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15652 return false;
41e92641
NC
15653 }
15654 else
15655 {
dda8d76d 15656 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15657 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15658 return false;
41e92641
NC
15659 }
15660
15661 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15662 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15663 is_rela = false;
428409d5 15664
4de91c10 15665 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15666
41e92641 15667 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15668 {
625d49fc 15669 uint64_t addend;
015dc7e1
AM
15670 unsigned int reloc_type;
15671 unsigned int reloc_size;
15672 bool reloc_inplace = false;
15673 bool reloc_subtract = false;
15674 unsigned char *rloc;
26c527e6 15675 uint64_t sym_index;
4b78141a 15676
dda8d76d 15677 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15678
dda8d76d 15679 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15680 continue;
dda8d76d 15681 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15682 continue;
dda8d76d
NC
15683 else if (is_32bit_abs_reloc (filedata, reloc_type)
15684 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15685 reloc_size = 4;
dda8d76d
NC
15686 else if (is_64bit_abs_reloc (filedata, reloc_type)
15687 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15688 reloc_size = 8;
dda8d76d 15689 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15690 reloc_size = 3;
dda8d76d 15691 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15692 reloc_size = 2;
39e07931
AS
15693 else if (is_8bit_abs_reloc (filedata, reloc_type)
15694 || is_6bit_abs_reloc (filedata, reloc_type))
15695 reloc_size = 1;
03336641
JW
15696 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15697 reloc_type))
15698 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15699 {
15700 reloc_size = 4;
015dc7e1 15701 reloc_inplace = true;
03336641
JW
15702 }
15703 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15704 reloc_type))
15705 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15706 {
15707 reloc_size = 8;
015dc7e1 15708 reloc_inplace = true;
03336641
JW
15709 }
15710 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15711 reloc_type))
15712 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15713 {
15714 reloc_size = 2;
015dc7e1 15715 reloc_inplace = true;
03336641
JW
15716 }
15717 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15718 reloc_type))
15719 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15720 {
15721 reloc_size = 1;
015dc7e1 15722 reloc_inplace = true;
03336641 15723 }
39e07931 15724 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15725 reloc_type))
15726 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15727 {
15728 reloc_size = 1;
015dc7e1 15729 reloc_inplace = true;
39e07931 15730 }
aca88567 15731 else
4b78141a 15732 {
bee0ee85 15733 static unsigned int prev_reloc = 0;
dda8d76d 15734
bee0ee85
NC
15735 if (reloc_type != prev_reloc)
15736 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15737 reloc_type, printable_section_name (filedata, section));
bee0ee85 15738 prev_reloc = reloc_type;
4b78141a
NC
15739 continue;
15740 }
103f02d3 15741
91d6fa6a 15742 rloc = start + rp->r_offset;
75802ccb 15743 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15744 {
26c527e6
AM
15745 warn (_("skipping invalid relocation offset %#" PRIx64
15746 " in section %s\n"),
15747 rp->r_offset,
dda8d76d 15748 printable_section_name (filedata, section));
700dd8b7
L
15749 continue;
15750 }
103f02d3 15751
26c527e6 15752 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15753 if (sym_index >= num_syms)
15754 {
26c527e6
AM
15755 warn (_("skipping invalid relocation symbol index %#" PRIx64
15756 " in section %s\n"),
dda8d76d 15757 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15758 continue;
15759 }
15760 sym = symtab + sym_index;
41e92641
NC
15761
15762 /* If the reloc has a symbol associated with it,
55f25fc3
L
15763 make sure that it is of an appropriate type.
15764
15765 Relocations against symbols without type can happen.
15766 Gcc -feliminate-dwarf2-dups may generate symbols
15767 without type for debug info.
15768
15769 Icc generates relocations against function symbols
15770 instead of local labels.
15771
15772 Relocations against object symbols can happen, eg when
15773 referencing a global array. For an example of this see
15774 the _clz.o binary in libgcc.a. */
aca88567 15775 if (sym != symtab
b8871f35 15776 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15777 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15778 {
26c527e6 15779 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15780 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15781 printable_section_name (filedata, relsec),
26c527e6 15782 rp - relocs);
aca88567 15783 continue;
5b18a4bc 15784 }
252b5132 15785
4dc3c23d
AM
15786 addend = 0;
15787 if (is_rela)
15788 addend += rp->r_addend;
c47320c3
AM
15789 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15790 partial_inplace. */
4dc3c23d 15791 if (!is_rela
dda8d76d 15792 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15793 && reloc_type == 1)
dda8d76d
NC
15794 || ((filedata->file_header.e_machine == EM_PJ
15795 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15796 && reloc_type == 1)
dda8d76d
NC
15797 || ((filedata->file_header.e_machine == EM_D30V
15798 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15799 && reloc_type == 12)
15800 || reloc_inplace)
39e07931
AS
15801 {
15802 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15803 addend += byte_get (rloc, reloc_size) & 0x3f;
15804 else
15805 addend += byte_get (rloc, reloc_size);
15806 }
cb8f3167 15807
dda8d76d
NC
15808 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15809 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15810 {
15811 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15812 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15813 addend -= 8;
91d6fa6a 15814 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15815 reloc_size);
15816 }
39e07931 15817 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15818 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15819 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15820 {
15821 if (reloc_subtract)
15822 addend -= sym->st_value;
15823 else
15824 addend += sym->st_value;
15825 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15826 byte_put (rloc, addend, reloc_size);
15827 }
03336641
JW
15828 else if (reloc_subtract)
15829 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15830 else
91d6fa6a 15831 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15832 }
252b5132 15833
5b18a4bc 15834 free (symtab);
f84ce13b
NC
15835 /* Let the target specific reloc processing code know that
15836 we have finished with these relocs. */
dda8d76d 15837 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15838
15839 if (relocs_return)
15840 {
15841 * (Elf_Internal_Rela **) relocs_return = relocs;
15842 * num_relocs_return = num_relocs;
15843 }
15844 else
15845 free (relocs);
15846
5b18a4bc
NC
15847 break;
15848 }
32ec8896 15849
015dc7e1 15850 return true;
5b18a4bc 15851}
103f02d3 15852
cf13d699 15853#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15854static bool
dda8d76d 15855disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15856{
dda8d76d 15857 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15858
74e1a04b 15859 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15860
015dc7e1 15861 return true;
cf13d699
NC
15862}
15863#endif
15864
15865/* Reads in the contents of SECTION from FILE, returning a pointer
15866 to a malloc'ed buffer or NULL if something went wrong. */
15867
15868static char *
dda8d76d 15869get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15870{
be7d229a 15871 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15872
15873 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15874 {
c6b78c96 15875 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15876 printable_section_name (filedata, section));
cf13d699
NC
15877 return NULL;
15878 }
15879
dda8d76d 15880 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15881 _("section contents"));
cf13d699
NC
15882}
15883
1f5a3546 15884/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15885
015dc7e1 15886static bool
45f5fe46
NC
15887uncompress_section_contents (bool is_zstd,
15888 unsigned char ** buffer,
15889 uint64_t uncompressed_size,
15890 uint64_t * size,
15891 uint64_t file_size)
0e602686 15892{
31e5a3a3
AM
15893 uint64_t compressed_size = *size;
15894 unsigned char *compressed_buffer = *buffer;
45f5fe46 15895 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15896 z_stream strm;
15897 int rc;
15898
45f5fe46
NC
15899 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15900 upper limit of ~10x compression. Any compression larger than that is
15901 thought to be due to fuzzing of the compression header. */
15902 if (uncompressed_size > file_size * 10)
15903 {
15904 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15905 uncompressed_size);
15906 goto fail;
15907 }
15908
15909 uncompressed_buffer = xmalloc (uncompressed_size);
15910
1f5a3546
FS
15911 if (is_zstd)
15912 {
15913#ifdef HAVE_ZSTD
15914 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15915 compressed_buffer, compressed_size);
15916 if (ZSTD_isError (ret))
15917 goto fail;
15918#endif
15919 }
15920 else
15921 {
15922 /* It is possible the section consists of several compressed
15923 buffers concatenated together, so we uncompress in a loop. */
15924 /* PR 18313: The state field in the z_stream structure is supposed
15925 to be invisible to the user (ie us), but some compilers will
15926 still complain about it being used without initialisation. So
15927 we first zero the entire z_stream structure and then set the fields
15928 that we need. */
15929 memset (&strm, 0, sizeof strm);
15930 strm.avail_in = compressed_size;
15931 strm.next_in = (Bytef *)compressed_buffer;
15932 strm.avail_out = uncompressed_size;
15933
15934 rc = inflateInit (&strm);
15935 while (strm.avail_in > 0)
15936 {
15937 if (rc != Z_OK)
15938 break;
15939 strm.next_out = ((Bytef *)uncompressed_buffer
15940 + (uncompressed_size - strm.avail_out));
15941 rc = inflate (&strm, Z_FINISH);
15942 if (rc != Z_STREAM_END)
15943 break;
15944 rc = inflateReset (&strm);
15945 }
15946 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15947 goto fail;
15948 }
0e602686
NC
15949
15950 *buffer = uncompressed_buffer;
15951 *size = uncompressed_size;
015dc7e1 15952 return true;
0e602686
NC
15953
15954 fail:
15955 free (uncompressed_buffer);
15956 /* Indicate decompression failure. */
15957 *buffer = NULL;
015dc7e1 15958 return false;
0e602686 15959}
dd24e3da 15960
015dc7e1 15961static bool
dda8d76d 15962dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15963{
015dc7e1 15964 Elf_Internal_Shdr *relsec;
be7d229a 15965 uint64_t num_bytes;
015dc7e1
AM
15966 unsigned char *data;
15967 unsigned char *end;
15968 unsigned char *real_start;
15969 unsigned char *start;
15970 bool some_strings_shown;
cf13d699 15971
dda8d76d 15972 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15973 if (start == NULL)
c6b78c96 15974 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15975 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15976
0e602686 15977 num_bytes = section->sh_size;
cf13d699 15978
835f2fae
NC
15979 if (filedata->is_separate)
15980 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15981 printable_section_name (filedata, section),
15982 filedata->file_name);
15983 else
15984 printf (_("\nString dump of section '%s':\n"),
15985 printable_section_name (filedata, section));
cf13d699 15986
0e602686
NC
15987 if (decompress_dumps)
15988 {
31e5a3a3
AM
15989 uint64_t new_size = num_bytes;
15990 uint64_t uncompressed_size = 0;
1f5a3546 15991 bool is_zstd = false;
0e602686
NC
15992
15993 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15994 {
15995 Elf_Internal_Chdr chdr;
15996 unsigned int compression_header_size
ebdf1ebf
NC
15997 = get_compression_header (& chdr, (unsigned char *) start,
15998 num_bytes);
5844b465
NC
15999 if (compression_header_size == 0)
16000 /* An error message will have already been generated
16001 by get_compression_header. */
16002 goto error_out;
0e602686 16003
89dbeac7 16004 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16005 ;
16006#ifdef HAVE_ZSTD
89dbeac7 16007 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16008 is_zstd = true;
16009#endif
16010 else
0e602686 16011 {
813dabb9 16012 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16013 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16014 goto error_out;
813dabb9 16015 }
813dabb9
L
16016 uncompressed_size = chdr.ch_size;
16017 start += compression_header_size;
16018 new_size -= compression_header_size;
0e602686
NC
16019 }
16020 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16021 {
16022 /* Read the zlib header. In this case, it should be "ZLIB"
16023 followed by the uncompressed section size, 8 bytes in
16024 big-endian order. */
16025 uncompressed_size = start[4]; uncompressed_size <<= 8;
16026 uncompressed_size += start[5]; uncompressed_size <<= 8;
16027 uncompressed_size += start[6]; uncompressed_size <<= 8;
16028 uncompressed_size += start[7]; uncompressed_size <<= 8;
16029 uncompressed_size += start[8]; uncompressed_size <<= 8;
16030 uncompressed_size += start[9]; uncompressed_size <<= 8;
16031 uncompressed_size += start[10]; uncompressed_size <<= 8;
16032 uncompressed_size += start[11];
16033 start += 12;
16034 new_size -= 12;
16035 }
16036
1835f746
NC
16037 if (uncompressed_size)
16038 {
1f5a3546 16039 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16040 &new_size, filedata->file_size))
1835f746
NC
16041 num_bytes = new_size;
16042 else
16043 {
16044 error (_("Unable to decompress section %s\n"),
dda8d76d 16045 printable_section_name (filedata, section));
f761cb13 16046 goto error_out;
1835f746
NC
16047 }
16048 }
bc303e5d
NC
16049 else
16050 start = real_start;
0e602686 16051 }
fd8008d8 16052
cf13d699
NC
16053 /* If the section being dumped has relocations against it the user might
16054 be expecting these relocations to have been applied. Check for this
16055 case and issue a warning message in order to avoid confusion.
16056 FIXME: Maybe we ought to have an option that dumps a section with
16057 relocs applied ? */
dda8d76d
NC
16058 for (relsec = filedata->section_headers;
16059 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16060 ++relsec)
16061 {
16062 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16063 || relsec->sh_info >= filedata->file_header.e_shnum
16064 || filedata->section_headers + relsec->sh_info != section
cf13d699 16065 || relsec->sh_size == 0
dda8d76d 16066 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16067 continue;
16068
16069 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16070 break;
16071 }
16072
cf13d699
NC
16073 data = start;
16074 end = start + num_bytes;
015dc7e1 16075 some_strings_shown = false;
cf13d699 16076
ba3265d0
NC
16077#ifdef HAVE_MBSTATE_T
16078 mbstate_t state;
16079 /* Initialise the multibyte conversion state. */
16080 memset (& state, 0, sizeof (state));
16081#endif
16082
015dc7e1 16083 bool continuing = false;
ba3265d0 16084
cf13d699
NC
16085 while (data < end)
16086 {
16087 while (!ISPRINT (* data))
16088 if (++ data >= end)
16089 break;
16090
16091 if (data < end)
16092 {
071436c6
NC
16093 size_t maxlen = end - data;
16094
ba3265d0
NC
16095 if (continuing)
16096 {
16097 printf (" ");
015dc7e1 16098 continuing = false;
ba3265d0
NC
16099 }
16100 else
16101 {
26c527e6 16102 printf (" [%6tx] ", data - start);
ba3265d0
NC
16103 }
16104
4082ef84
NC
16105 if (maxlen > 0)
16106 {
f3da8a96 16107 char c = 0;
ba3265d0
NC
16108
16109 while (maxlen)
16110 {
16111 c = *data++;
16112
16113 if (c == 0)
16114 break;
16115
16116 /* PR 25543: Treat new-lines as string-ending characters. */
16117 if (c == '\n')
16118 {
16119 printf ("\\n\n");
16120 if (*data != 0)
015dc7e1 16121 continuing = true;
ba3265d0
NC
16122 break;
16123 }
16124
16125 /* Do not print control characters directly as they can affect terminal
16126 settings. Such characters usually appear in the names generated
16127 by the assembler for local labels. */
16128 if (ISCNTRL (c))
16129 {
16130 printf ("^%c", c + 0x40);
16131 }
16132 else if (ISPRINT (c))
16133 {
16134 putchar (c);
16135 }
16136 else
16137 {
16138 size_t n;
16139#ifdef HAVE_MBSTATE_T
16140 wchar_t w;
16141#endif
16142 /* Let printf do the hard work of displaying multibyte characters. */
16143 printf ("%.1s", data - 1);
16144#ifdef HAVE_MBSTATE_T
16145 /* Try to find out how many bytes made up the character that was
16146 just printed. Advance the symbol pointer past the bytes that
16147 were displayed. */
16148 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16149#else
16150 n = 1;
16151#endif
16152 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16153 data += (n - 1);
16154 }
16155 }
16156
16157 if (c != '\n')
16158 putchar ('\n');
4082ef84
NC
16159 }
16160 else
16161 {
16162 printf (_("<corrupt>\n"));
16163 data = end;
16164 }
015dc7e1 16165 some_strings_shown = true;
cf13d699
NC
16166 }
16167 }
16168
16169 if (! some_strings_shown)
16170 printf (_(" No strings found in this section."));
16171
0e602686 16172 free (real_start);
cf13d699
NC
16173
16174 putchar ('\n');
015dc7e1 16175 return true;
f761cb13
AM
16176
16177error_out:
16178 free (real_start);
015dc7e1 16179 return false;
cf13d699
NC
16180}
16181
015dc7e1
AM
16182static bool
16183dump_section_as_bytes (Elf_Internal_Shdr *section,
16184 Filedata *filedata,
16185 bool relocate)
cf13d699 16186{
be7d229a
AM
16187 Elf_Internal_Shdr *relsec;
16188 size_t bytes;
16189 uint64_t section_size;
625d49fc 16190 uint64_t addr;
be7d229a
AM
16191 unsigned char *data;
16192 unsigned char *real_start;
16193 unsigned char *start;
0e602686 16194
dda8d76d 16195 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16196 if (start == NULL)
c6b78c96 16197 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16198 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16199
0e602686 16200 section_size = section->sh_size;
cf13d699 16201
835f2fae
NC
16202 if (filedata->is_separate)
16203 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16204 printable_section_name (filedata, section),
16205 filedata->file_name);
16206 else
16207 printf (_("\nHex dump of section '%s':\n"),
16208 printable_section_name (filedata, section));
cf13d699 16209
0e602686
NC
16210 if (decompress_dumps)
16211 {
31e5a3a3
AM
16212 uint64_t new_size = section_size;
16213 uint64_t uncompressed_size = 0;
1f5a3546 16214 bool is_zstd = false;
0e602686
NC
16215
16216 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16217 {
16218 Elf_Internal_Chdr chdr;
16219 unsigned int compression_header_size
ebdf1ebf 16220 = get_compression_header (& chdr, start, section_size);
0e602686 16221
5844b465
NC
16222 if (compression_header_size == 0)
16223 /* An error message will have already been generated
16224 by get_compression_header. */
16225 goto error_out;
16226
89dbeac7 16227 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16228 ;
16229#ifdef HAVE_ZSTD
89dbeac7 16230 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16231 is_zstd = true;
16232#endif
16233 else
0e602686 16234 {
813dabb9 16235 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16236 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16237 goto error_out;
0e602686 16238 }
813dabb9
L
16239 uncompressed_size = chdr.ch_size;
16240 start += compression_header_size;
16241 new_size -= compression_header_size;
0e602686
NC
16242 }
16243 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16244 {
16245 /* Read the zlib header. In this case, it should be "ZLIB"
16246 followed by the uncompressed section size, 8 bytes in
16247 big-endian order. */
16248 uncompressed_size = start[4]; uncompressed_size <<= 8;
16249 uncompressed_size += start[5]; uncompressed_size <<= 8;
16250 uncompressed_size += start[6]; uncompressed_size <<= 8;
16251 uncompressed_size += start[7]; uncompressed_size <<= 8;
16252 uncompressed_size += start[8]; uncompressed_size <<= 8;
16253 uncompressed_size += start[9]; uncompressed_size <<= 8;
16254 uncompressed_size += start[10]; uncompressed_size <<= 8;
16255 uncompressed_size += start[11];
16256 start += 12;
16257 new_size -= 12;
16258 }
16259
f055032e
NC
16260 if (uncompressed_size)
16261 {
1f5a3546 16262 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16263 &new_size, filedata->file_size))
bc303e5d
NC
16264 {
16265 section_size = new_size;
16266 }
f055032e
NC
16267 else
16268 {
16269 error (_("Unable to decompress section %s\n"),
dda8d76d 16270 printable_section_name (filedata, section));
bc303e5d 16271 /* FIXME: Print the section anyway ? */
f761cb13 16272 goto error_out;
f055032e
NC
16273 }
16274 }
bc303e5d
NC
16275 else
16276 start = real_start;
0e602686 16277 }
14ae95f2 16278
cf13d699
NC
16279 if (relocate)
16280 {
dda8d76d 16281 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 16282 goto error_out;
cf13d699
NC
16283 }
16284 else
16285 {
16286 /* If the section being dumped has relocations against it the user might
16287 be expecting these relocations to have been applied. Check for this
16288 case and issue a warning message in order to avoid confusion.
16289 FIXME: Maybe we ought to have an option that dumps a section with
16290 relocs applied ? */
dda8d76d
NC
16291 for (relsec = filedata->section_headers;
16292 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16293 ++relsec)
16294 {
16295 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16296 || relsec->sh_info >= filedata->file_header.e_shnum
16297 || filedata->section_headers + relsec->sh_info != section
cf13d699 16298 || relsec->sh_size == 0
dda8d76d 16299 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16300 continue;
16301
16302 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16303 break;
16304 }
16305 }
16306
16307 addr = section->sh_addr;
0e602686 16308 bytes = section_size;
cf13d699
NC
16309 data = start;
16310
16311 while (bytes)
16312 {
16313 int j;
16314 int k;
16315 int lbytes;
16316
16317 lbytes = (bytes > 16 ? 16 : bytes);
16318
26c527e6 16319 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16320
16321 for (j = 0; j < 16; j++)
16322 {
16323 if (j < lbytes)
16324 printf ("%2.2x", data[j]);
16325 else
16326 printf (" ");
16327
16328 if ((j & 3) == 3)
16329 printf (" ");
16330 }
16331
16332 for (j = 0; j < lbytes; j++)
16333 {
16334 k = data[j];
16335 if (k >= ' ' && k < 0x7f)
16336 printf ("%c", k);
16337 else
16338 printf (".");
16339 }
16340
16341 putchar ('\n');
16342
16343 data += lbytes;
16344 addr += lbytes;
16345 bytes -= lbytes;
16346 }
16347
0e602686 16348 free (real_start);
cf13d699
NC
16349
16350 putchar ('\n');
015dc7e1 16351 return true;
f761cb13
AM
16352
16353 error_out:
16354 free (real_start);
015dc7e1 16355 return false;
cf13d699
NC
16356}
16357
094e34f2 16358#ifdef ENABLE_LIBCTF
7d9813f1
NA
16359static ctf_sect_t *
16360shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16361{
b6ac461a 16362 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16363 buf->cts_size = shdr->sh_size;
16364 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16365
16366 return buf;
16367}
16368
16369/* Formatting callback function passed to ctf_dump. Returns either the pointer
16370 it is passed, or a pointer to newly-allocated storage, in which case
16371 dump_ctf() will free it when it no longer needs it. */
16372
2f6ecaed
NA
16373static char *
16374dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16375 char *s, void *arg)
7d9813f1 16376{
3e50a591 16377 const char *blanks = arg;
7d9813f1
NA
16378 char *new_s;
16379
3e50a591 16380 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16381 return s;
16382 return new_s;
16383}
16384
926c9e76
NA
16385/* Dump CTF errors/warnings. */
16386static void
139633c3 16387dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16388{
16389 ctf_next_t *it = NULL;
16390 char *errtext;
16391 int is_warning;
16392 int err;
16393
16394 /* Dump accumulated errors and warnings. */
16395 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16396 {
5e9b84f7 16397 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16398 errtext);
16399 free (errtext);
16400 }
16401 if (err != ECTF_NEXT_END)
16402 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16403}
16404
2f6ecaed
NA
16405/* Dump one CTF archive member. */
16406
80b56fad
NA
16407static void
16408dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16409 size_t member)
2f6ecaed 16410{
2f6ecaed
NA
16411 const char *things[] = {"Header", "Labels", "Data objects",
16412 "Function objects", "Variables", "Types", "Strings",
16413 ""};
16414 const char **thing;
16415 size_t i;
16416
80b56fad
NA
16417 /* Don't print out the name of the default-named archive member if it appears
16418 first in the list. The name .ctf appears everywhere, even for things that
16419 aren't really archives, so printing it out is liable to be confusing; also,
16420 the common case by far is for only one archive member to exist, and hiding
16421 it in that case seems worthwhile. */
2f6ecaed 16422
80b56fad
NA
16423 if (strcmp (name, ".ctf") != 0 || member != 0)
16424 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16425
80b56fad
NA
16426 if (ctf_parent_name (ctf) != NULL)
16427 ctf_import (ctf, parent);
2f6ecaed
NA
16428
16429 for (i = 0, thing = things; *thing[0]; thing++, i++)
16430 {
16431 ctf_dump_state_t *s = NULL;
16432 char *item;
16433
16434 printf ("\n %s:\n", *thing);
16435 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16436 (void *) " ")) != NULL)
16437 {
16438 printf ("%s\n", item);
16439 free (item);
16440 }
16441
16442 if (ctf_errno (ctf))
16443 {
16444 error (_("Iteration failed: %s, %s\n"), *thing,
16445 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16446 break;
2f6ecaed
NA
16447 }
16448 }
8b37e7b6 16449
926c9e76 16450 dump_ctf_errs (ctf);
2f6ecaed
NA
16451}
16452
015dc7e1 16453static bool
7d9813f1
NA
16454dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16455{
7d9813f1
NA
16456 Elf_Internal_Shdr * symtab_sec = NULL;
16457 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16458 void * data = NULL;
16459 void * symdata = NULL;
16460 void * strdata = NULL;
80b56fad 16461 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16462 ctf_sect_t * symsectp = NULL;
16463 ctf_sect_t * strsectp = NULL;
2f6ecaed 16464 ctf_archive_t * ctfa = NULL;
139633c3 16465 ctf_dict_t * parent = NULL;
80b56fad 16466 ctf_dict_t * fp;
7d9813f1 16467
80b56fad
NA
16468 ctf_next_t *i = NULL;
16469 const char *name;
16470 size_t member = 0;
7d9813f1 16471 int err;
015dc7e1 16472 bool ret = false;
7d9813f1
NA
16473
16474 shdr_to_ctf_sect (&ctfsect, section, filedata);
16475 data = get_section_contents (section, filedata);
16476 ctfsect.cts_data = data;
16477
616febde 16478 if (!dump_ctf_symtab_name)
3d16b64e 16479 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16480
16481 if (!dump_ctf_strtab_name)
3d16b64e 16482 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16483
16484 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16485 {
16486 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16487 {
16488 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16489 goto fail;
16490 }
16491 if ((symdata = (void *) get_data (NULL, filedata,
16492 symtab_sec->sh_offset, 1,
16493 symtab_sec->sh_size,
16494 _("symbols"))) == NULL)
16495 goto fail;
16496 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16497 symsect.cts_data = symdata;
16498 }
835f2fae 16499
df16e041 16500 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16501 {
16502 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16503 {
16504 error (_("No string table section named %s\n"),
16505 dump_ctf_strtab_name);
16506 goto fail;
16507 }
16508 if ((strdata = (void *) get_data (NULL, filedata,
16509 strtab_sec->sh_offset, 1,
16510 strtab_sec->sh_size,
16511 _("strings"))) == NULL)
16512 goto fail;
16513 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16514 strsect.cts_data = strdata;
16515 }
835f2fae 16516
2f6ecaed
NA
16517 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16518 libctf papers over the difference, so we can pretend it is always an
80b56fad 16519 archive. */
7d9813f1 16520
2f6ecaed 16521 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16522 {
926c9e76 16523 dump_ctf_errs (NULL);
7d9813f1
NA
16524 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16525 goto fail;
16526 }
16527
96c61be5
NA
16528 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16529 != ELFDATA2MSB);
16530
80b56fad
NA
16531 /* Preload the parent dict, since it will need to be imported into every
16532 child in turn. */
16533 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16534 {
926c9e76 16535 dump_ctf_errs (NULL);
2f6ecaed
NA
16536 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16537 goto fail;
7d9813f1
NA
16538 }
16539
015dc7e1 16540 ret = true;
7d9813f1 16541
835f2fae
NC
16542 if (filedata->is_separate)
16543 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16544 printable_section_name (filedata, section),
16545 filedata->file_name);
16546 else
16547 printf (_("\nDump of CTF section '%s':\n"),
16548 printable_section_name (filedata, section));
7d9813f1 16549
80b56fad
NA
16550 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16551 dump_ctf_archive_member (fp, name, parent, member++);
16552 if (err != ECTF_NEXT_END)
16553 {
16554 dump_ctf_errs (NULL);
16555 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16556 ret = false;
16557 }
7d9813f1
NA
16558
16559 fail:
139633c3 16560 ctf_dict_close (parent);
2f6ecaed 16561 ctf_close (ctfa);
7d9813f1
NA
16562 free (data);
16563 free (symdata);
16564 free (strdata);
16565 return ret;
16566}
094e34f2 16567#endif
7d9813f1 16568
42b6953b
IB
16569static bool
16570dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16571{
16572 void * data = NULL;
16573 sframe_decoder_ctx *sfd_ctx = NULL;
16574 const char *print_name = printable_section_name (filedata, section);
16575
16576 bool ret = true;
16577 size_t sf_size;
16578 int err = 0;
16579
16580 if (strcmp (print_name, "") == 0)
16581 {
16582 error (_("Section name must be provided \n"));
16583 ret = false;
16584 return ret;
16585 }
16586
16587 data = get_section_contents (section, filedata);
16588 sf_size = section->sh_size;
16589 /* Decode the contents of the section. */
16590 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16591 if (!sfd_ctx)
16592 {
16593 ret = false;
16594 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16595 goto fail;
16596 }
16597
16598 printf (_("Contents of the SFrame section %s:"), print_name);
16599 /* Dump the contents as text. */
16600 dump_sframe (sfd_ctx, section->sh_addr);
16601
16602 fail:
16603 free (data);
16604 return ret;
16605}
16606
015dc7e1 16607static bool
dda8d76d
NC
16608load_specific_debug_section (enum dwarf_section_display_enum debug,
16609 const Elf_Internal_Shdr * sec,
16610 void * data)
1007acb3 16611{
2cf0635d 16612 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16613 char buf [64];
dda8d76d 16614 Filedata * filedata = (Filedata *) data;
9abca702 16615
19e6b90e 16616 if (section->start != NULL)
dda8d76d
NC
16617 {
16618 /* If it is already loaded, do nothing. */
16619 if (streq (section->filename, filedata->file_name))
015dc7e1 16620 return true;
dda8d76d
NC
16621 free (section->start);
16622 }
1007acb3 16623
19e6b90e
L
16624 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16625 section->address = sec->sh_addr;
dda8d76d
NC
16626 section->filename = filedata->file_name;
16627 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16628 sec->sh_offset, 1,
16629 sec->sh_size, buf);
59245841
NC
16630 if (section->start == NULL)
16631 section->size = 0;
16632 else
16633 {
77115a4a 16634 unsigned char *start = section->start;
31e5a3a3
AM
16635 uint64_t size = sec->sh_size;
16636 uint64_t uncompressed_size = 0;
1f5a3546 16637 bool is_zstd = false;
77115a4a
L
16638
16639 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16640 {
16641 Elf_Internal_Chdr chdr;
d8024a91
NC
16642 unsigned int compression_header_size;
16643
f53be977
L
16644 if (size < (is_32bit_elf
16645 ? sizeof (Elf32_External_Chdr)
16646 : sizeof (Elf64_External_Chdr)))
d8024a91 16647 {
55be8fd0 16648 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16649 section->name);
015dc7e1 16650 return false;
d8024a91
NC
16651 }
16652
ebdf1ebf 16653 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16654 if (compression_header_size == 0)
16655 /* An error message will have already been generated
16656 by get_compression_header. */
015dc7e1 16657 return false;
d8024a91 16658
89dbeac7 16659 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16660 ;
16661#ifdef HAVE_ZSTD
89dbeac7 16662 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16663 is_zstd = true;
16664#endif
16665 else
813dabb9
L
16666 {
16667 warn (_("section '%s' has unsupported compress type: %d\n"),
16668 section->name, chdr.ch_type);
015dc7e1 16669 return false;
813dabb9 16670 }
dab394de 16671 uncompressed_size = chdr.ch_size;
77115a4a
L
16672 start += compression_header_size;
16673 size -= compression_header_size;
16674 }
dab394de
L
16675 else if (size > 12 && streq ((char *) start, "ZLIB"))
16676 {
16677 /* Read the zlib header. In this case, it should be "ZLIB"
16678 followed by the uncompressed section size, 8 bytes in
16679 big-endian order. */
16680 uncompressed_size = start[4]; uncompressed_size <<= 8;
16681 uncompressed_size += start[5]; uncompressed_size <<= 8;
16682 uncompressed_size += start[6]; uncompressed_size <<= 8;
16683 uncompressed_size += start[7]; uncompressed_size <<= 8;
16684 uncompressed_size += start[8]; uncompressed_size <<= 8;
16685 uncompressed_size += start[9]; uncompressed_size <<= 8;
16686 uncompressed_size += start[10]; uncompressed_size <<= 8;
16687 uncompressed_size += start[11];
16688 start += 12;
16689 size -= 12;
16690 }
16691
1835f746 16692 if (uncompressed_size)
77115a4a 16693 {
1f5a3546 16694 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16695 &size, filedata->file_size))
1835f746
NC
16696 {
16697 /* Free the compressed buffer, update the section buffer
16698 and the section size if uncompress is successful. */
16699 free (section->start);
16700 section->start = start;
16701 }
16702 else
16703 {
16704 error (_("Unable to decompress section %s\n"),
dda8d76d 16705 printable_section_name (filedata, sec));
015dc7e1 16706 return false;
1835f746 16707 }
77115a4a 16708 }
bc303e5d 16709
77115a4a 16710 section->size = size;
59245841 16711 }
4a114e3e 16712
1b315056 16713 if (section->start == NULL)
015dc7e1 16714 return false;
1b315056 16715
19e6b90e 16716 if (debug_displays [debug].relocate)
32ec8896 16717 {
dda8d76d 16718 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16719 & section->reloc_info, & section->num_relocs))
015dc7e1 16720 return false;
32ec8896 16721 }
d1c4b12b
NC
16722 else
16723 {
16724 section->reloc_info = NULL;
16725 section->num_relocs = 0;
16726 }
1007acb3 16727
015dc7e1 16728 return true;
1007acb3
L
16729}
16730
301a9420
AM
16731#if HAVE_LIBDEBUGINFOD
16732/* Return a hex string representation of the build-id. */
16733unsigned char *
16734get_build_id (void * data)
16735{
ca0e11aa 16736 Filedata * filedata = (Filedata *) data;
301a9420 16737 Elf_Internal_Shdr * shdr;
26c527e6 16738 size_t i;
301a9420 16739
55be8fd0
NC
16740 /* Iterate through notes to find note.gnu.build-id.
16741 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16742 for (i = 0, shdr = filedata->section_headers;
16743 i < filedata->file_header.e_shnum && shdr != NULL;
16744 i++, shdr++)
16745 {
16746 if (shdr->sh_type != SHT_NOTE)
16747 continue;
16748
16749 char * next;
16750 char * end;
16751 size_t data_remaining;
16752 size_t min_notesz;
16753 Elf_External_Note * enote;
16754 Elf_Internal_Note inote;
16755
625d49fc
AM
16756 uint64_t offset = shdr->sh_offset;
16757 uint64_t align = shdr->sh_addralign;
16758 uint64_t length = shdr->sh_size;
301a9420
AM
16759
16760 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16761 if (enote == NULL)
16762 continue;
16763
16764 if (align < 4)
16765 align = 4;
16766 else if (align != 4 && align != 8)
f761cb13
AM
16767 {
16768 free (enote);
16769 continue;
16770 }
301a9420
AM
16771
16772 end = (char *) enote + length;
16773 data_remaining = end - (char *) enote;
16774
16775 if (!is_ia64_vms (filedata))
16776 {
16777 min_notesz = offsetof (Elf_External_Note, name);
16778 if (data_remaining < min_notesz)
16779 {
55be8fd0
NC
16780 warn (_("\
16781malformed note encountered in section %s whilst scanning for build-id note\n"),
16782 printable_section_name (filedata, shdr));
f761cb13 16783 free (enote);
55be8fd0 16784 continue;
301a9420
AM
16785 }
16786 data_remaining -= min_notesz;
16787
16788 inote.type = BYTE_GET (enote->type);
16789 inote.namesz = BYTE_GET (enote->namesz);
16790 inote.namedata = enote->name;
16791 inote.descsz = BYTE_GET (enote->descsz);
16792 inote.descdata = ((char *) enote
16793 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16794 inote.descpos = offset + (inote.descdata - (char *) enote);
16795 next = ((char *) enote
16796 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16797 }
16798 else
16799 {
16800 Elf64_External_VMS_Note *vms_enote;
16801
16802 /* PR binutils/15191
16803 Make sure that there is enough data to read. */
16804 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16805 if (data_remaining < min_notesz)
16806 {
55be8fd0
NC
16807 warn (_("\
16808malformed note encountered in section %s whilst scanning for build-id note\n"),
16809 printable_section_name (filedata, shdr));
f761cb13 16810 free (enote);
55be8fd0 16811 continue;
301a9420
AM
16812 }
16813 data_remaining -= min_notesz;
16814
16815 vms_enote = (Elf64_External_VMS_Note *) enote;
16816 inote.type = BYTE_GET (vms_enote->type);
16817 inote.namesz = BYTE_GET (vms_enote->namesz);
16818 inote.namedata = vms_enote->name;
16819 inote.descsz = BYTE_GET (vms_enote->descsz);
16820 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16821 inote.descpos = offset + (inote.descdata - (char *) enote);
16822 next = inote.descdata + align_power (inote.descsz, 3);
16823 }
16824
16825 /* Skip malformed notes. */
16826 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16827 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16828 || (size_t) (next - inote.descdata) < inote.descsz
16829 || ((size_t) (next - inote.descdata)
16830 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16831 {
55be8fd0
NC
16832 warn (_("\
16833malformed note encountered in section %s whilst scanning for build-id note\n"),
16834 printable_section_name (filedata, shdr));
f761cb13 16835 free (enote);
301a9420
AM
16836 continue;
16837 }
16838
16839 /* Check if this is the build-id note. If so then convert the build-id
16840 bytes to a hex string. */
16841 if (inote.namesz > 0
24d127aa 16842 && startswith (inote.namedata, "GNU")
301a9420
AM
16843 && inote.type == NT_GNU_BUILD_ID)
16844 {
26c527e6 16845 size_t j;
301a9420
AM
16846 char * build_id;
16847
16848 build_id = malloc (inote.descsz * 2 + 1);
16849 if (build_id == NULL)
f761cb13
AM
16850 {
16851 free (enote);
16852 return NULL;
16853 }
301a9420
AM
16854
16855 for (j = 0; j < inote.descsz; ++j)
16856 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16857 build_id[inote.descsz * 2] = '\0';
f761cb13 16858 free (enote);
301a9420 16859
55be8fd0 16860 return (unsigned char *) build_id;
301a9420 16861 }
f761cb13 16862 free (enote);
301a9420
AM
16863 }
16864
16865 return NULL;
16866}
16867#endif /* HAVE_LIBDEBUGINFOD */
16868
657d0d47
CC
16869/* If this is not NULL, load_debug_section will only look for sections
16870 within the list of sections given here. */
32ec8896 16871static unsigned int * section_subset = NULL;
657d0d47 16872
015dc7e1 16873bool
dda8d76d 16874load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16875{
2cf0635d
NC
16876 struct dwarf_section * section = &debug_displays [debug].section;
16877 Elf_Internal_Shdr * sec;
dda8d76d
NC
16878 Filedata * filedata = (Filedata *) data;
16879
e1dbfc17
L
16880 if (!dump_any_debugging)
16881 return false;
16882
f425ec66
NC
16883 /* Without section headers we cannot find any sections. */
16884 if (filedata->section_headers == NULL)
015dc7e1 16885 return false;
f425ec66 16886
9c1ce108
AM
16887 if (filedata->string_table == NULL
16888 && filedata->file_header.e_shstrndx != SHN_UNDEF
16889 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16890 {
16891 Elf_Internal_Shdr * strs;
16892
16893 /* Read in the string table, so that we have section names to scan. */
16894 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16895
4dff97b2 16896 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16897 {
9c1ce108
AM
16898 filedata->string_table
16899 = (char *) get_data (NULL, filedata, strs->sh_offset,
16900 1, strs->sh_size, _("string table"));
dda8d76d 16901
9c1ce108
AM
16902 filedata->string_table_length
16903 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16904 }
16905 }
d966045b
DJ
16906
16907 /* Locate the debug section. */
dda8d76d 16908 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16909 if (sec != NULL)
16910 section->name = section->uncompressed_name;
16911 else
16912 {
dda8d76d 16913 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16914 if (sec != NULL)
16915 section->name = section->compressed_name;
16916 }
16917 if (sec == NULL)
015dc7e1 16918 return false;
d966045b 16919
657d0d47
CC
16920 /* If we're loading from a subset of sections, and we've loaded
16921 a section matching this name before, it's likely that it's a
16922 different one. */
16923 if (section_subset != NULL)
16924 free_debug_section (debug);
16925
dda8d76d 16926 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16927}
16928
19e6b90e
L
16929void
16930free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16931{
2cf0635d 16932 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16933
19e6b90e
L
16934 if (section->start == NULL)
16935 return;
1007acb3 16936
19e6b90e
L
16937 free ((char *) section->start);
16938 section->start = NULL;
16939 section->address = 0;
16940 section->size = 0;
a788aedd 16941
9db70fc3
AM
16942 free (section->reloc_info);
16943 section->reloc_info = NULL;
16944 section->num_relocs = 0;
1007acb3
L
16945}
16946
015dc7e1 16947static bool
dda8d76d 16948display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16949{
84714f86
AM
16950 const char *name = (section_name_valid (filedata, section)
16951 ? section_name (filedata, section) : "");
16952 const char *print_name = printable_section_name (filedata, section);
be7d229a 16953 uint64_t length;
015dc7e1 16954 bool result = true;
3f5e193b 16955 int i;
1007acb3 16956
19e6b90e
L
16957 length = section->sh_size;
16958 if (length == 0)
1007acb3 16959 {
74e1a04b 16960 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16961 return true;
1007acb3 16962 }
5dff79d8
NC
16963 if (section->sh_type == SHT_NOBITS)
16964 {
16965 /* There is no point in dumping the contents of a debugging section
16966 which has the NOBITS type - the bits in the file will be random.
16967 This can happen when a file containing a .eh_frame section is
16968 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16969 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16970 print_name);
015dc7e1 16971 return false;
5dff79d8 16972 }
1007acb3 16973
24d127aa 16974 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16975 name = ".debug_info";
1007acb3 16976
19e6b90e
L
16977 /* See if we know how to display the contents of this section. */
16978 for (i = 0; i < max; i++)
d85bf2ba
NC
16979 {
16980 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16981 struct dwarf_section_display * display = debug_displays + i;
16982 struct dwarf_section * sec = & display->section;
d966045b 16983
d85bf2ba 16984 if (streq (sec->uncompressed_name, name)
24d127aa 16985 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16986 || streq (sec->compressed_name, name))
16987 {
015dc7e1 16988 bool secondary = (section != find_section (filedata, name));
1007acb3 16989
d85bf2ba
NC
16990 if (secondary)
16991 free_debug_section (id);
dda8d76d 16992
24d127aa 16993 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16994 sec->name = name;
16995 else if (streq (sec->uncompressed_name, name))
16996 sec->name = sec->uncompressed_name;
16997 else
16998 sec->name = sec->compressed_name;
657d0d47 16999
d85bf2ba
NC
17000 if (load_specific_debug_section (id, section, filedata))
17001 {
17002 /* If this debug section is part of a CU/TU set in a .dwp file,
17003 restrict load_debug_section to the sections in that set. */
17004 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 17005
d85bf2ba 17006 result &= display->display (sec, filedata);
657d0d47 17007
d85bf2ba 17008 section_subset = NULL;
1007acb3 17009
44266f36 17010 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
17011 free_debug_section (id);
17012 }
17013 break;
17014 }
17015 }
1007acb3 17016
19e6b90e 17017 if (i == max)
1007acb3 17018 {
74e1a04b 17019 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 17020 result = false;
1007acb3
L
17021 }
17022
19e6b90e 17023 return result;
5b18a4bc 17024}
103f02d3 17025
aef1f6d0
DJ
17026/* Set DUMP_SECTS for all sections where dumps were requested
17027 based on section name. */
17028
17029static void
dda8d76d 17030initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17031{
2cf0635d 17032 struct dump_list_entry * cur;
aef1f6d0
DJ
17033
17034 for (cur = dump_sects_byname; cur; cur = cur->next)
17035 {
17036 unsigned int i;
015dc7e1 17037 bool any = false;
aef1f6d0 17038
dda8d76d 17039 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17040 if (section_name_valid (filedata, filedata->section_headers + i)
17041 && streq (section_name (filedata, filedata->section_headers + i),
17042 cur->name))
aef1f6d0 17043 {
6431e409 17044 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17045 any = true;
aef1f6d0
DJ
17046 }
17047
835f2fae
NC
17048 if (!any && !filedata->is_separate)
17049 warn (_("Section '%s' was not dumped because it does not exist\n"),
17050 cur->name);
aef1f6d0
DJ
17051 }
17052}
17053
015dc7e1 17054static bool
dda8d76d 17055process_section_contents (Filedata * filedata)
5b18a4bc 17056{
2cf0635d 17057 Elf_Internal_Shdr * section;
19e6b90e 17058 unsigned int i;
015dc7e1 17059 bool res = true;
103f02d3 17060
19e6b90e 17061 if (! do_dump)
015dc7e1 17062 return true;
103f02d3 17063
dda8d76d 17064 initialise_dumps_byname (filedata);
aef1f6d0 17065
dda8d76d 17066 for (i = 0, section = filedata->section_headers;
6431e409 17067 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17068 i++, section++)
17069 {
6431e409 17070 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17071
d6bfbc39
NC
17072 if (filedata->is_separate && ! process_links)
17073 dump &= DEBUG_DUMP;
047c3dbf 17074
19e6b90e 17075#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17076 if (dump & DISASS_DUMP)
17077 {
17078 if (! disassemble_section (section, filedata))
015dc7e1 17079 res = false;
dda8d76d 17080 }
19e6b90e 17081#endif
dda8d76d 17082 if (dump & HEX_DUMP)
32ec8896 17083 {
015dc7e1
AM
17084 if (! dump_section_as_bytes (section, filedata, false))
17085 res = false;
32ec8896 17086 }
103f02d3 17087
dda8d76d 17088 if (dump & RELOC_DUMP)
32ec8896 17089 {
015dc7e1
AM
17090 if (! dump_section_as_bytes (section, filedata, true))
17091 res = false;
32ec8896 17092 }
09c11c86 17093
dda8d76d 17094 if (dump & STRING_DUMP)
32ec8896 17095 {
dda8d76d 17096 if (! dump_section_as_strings (section, filedata))
015dc7e1 17097 res = false;
32ec8896 17098 }
cf13d699 17099
dda8d76d 17100 if (dump & DEBUG_DUMP)
32ec8896 17101 {
dda8d76d 17102 if (! display_debug_section (i, section, filedata))
015dc7e1 17103 res = false;
32ec8896 17104 }
7d9813f1 17105
094e34f2 17106#ifdef ENABLE_LIBCTF
7d9813f1
NA
17107 if (dump & CTF_DUMP)
17108 {
17109 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17110 res = false;
7d9813f1 17111 }
094e34f2 17112#endif
42b6953b
IB
17113 if (dump & SFRAME_DUMP)
17114 {
17115 if (! dump_section_as_sframe (section, filedata))
17116 res = false;
17117 }
5b18a4bc 17118 }
103f02d3 17119
835f2fae 17120 if (! filedata->is_separate)
0ee3043f 17121 {
835f2fae
NC
17122 /* Check to see if the user requested a
17123 dump of a section that does not exist. */
17124 for (; i < filedata->dump.num_dump_sects; i++)
17125 if (filedata->dump.dump_sects[i])
17126 {
ca0e11aa 17127 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17128 res = false;
835f2fae 17129 }
0ee3043f 17130 }
32ec8896
NC
17131
17132 return res;
5b18a4bc 17133}
103f02d3 17134
5b18a4bc 17135static void
19e6b90e 17136process_mips_fpe_exception (int mask)
5b18a4bc 17137{
19e6b90e
L
17138 if (mask)
17139 {
015dc7e1 17140 bool first = true;
32ec8896 17141
19e6b90e 17142 if (mask & OEX_FPU_INEX)
015dc7e1 17143 fputs ("INEX", stdout), first = false;
19e6b90e 17144 if (mask & OEX_FPU_UFLO)
015dc7e1 17145 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17146 if (mask & OEX_FPU_OFLO)
015dc7e1 17147 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17148 if (mask & OEX_FPU_DIV0)
015dc7e1 17149 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17150 if (mask & OEX_FPU_INVAL)
17151 printf ("%sINVAL", first ? "" : "|");
17152 }
5b18a4bc 17153 else
19e6b90e 17154 fputs ("0", stdout);
5b18a4bc 17155}
103f02d3 17156
f6f0e17b
NC
17157/* Display's the value of TAG at location P. If TAG is
17158 greater than 0 it is assumed to be an unknown tag, and
17159 a message is printed to this effect. Otherwise it is
17160 assumed that a message has already been printed.
17161
17162 If the bottom bit of TAG is set it assumed to have a
17163 string value, otherwise it is assumed to have an integer
17164 value.
17165
17166 Returns an updated P pointing to the first unread byte
17167 beyond the end of TAG's value.
17168
17169 Reads at or beyond END will not be made. */
17170
17171static unsigned char *
60abdbed 17172display_tag_value (signed int tag,
f6f0e17b
NC
17173 unsigned char * p,
17174 const unsigned char * const end)
17175{
26c527e6 17176 uint64_t val;
f6f0e17b
NC
17177
17178 if (tag > 0)
17179 printf (" Tag_unknown_%d: ", tag);
17180
17181 if (p >= end)
17182 {
4082ef84 17183 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17184 }
17185 else if (tag & 1)
17186 {
071436c6
NC
17187 /* PR 17531 file: 027-19978-0.004. */
17188 size_t maxlen = (end - p) - 1;
17189
17190 putchar ('"');
4082ef84
NC
17191 if (maxlen > 0)
17192 {
b6ac461a 17193 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17194 p += strnlen ((char *) p, maxlen) + 1;
17195 }
17196 else
17197 {
17198 printf (_("<corrupt string tag>"));
17199 p = (unsigned char *) end;
17200 }
071436c6 17201 printf ("\"\n");
f6f0e17b
NC
17202 }
17203 else
17204 {
cd30bcef 17205 READ_ULEB (val, p, end);
26c527e6 17206 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17207 }
17208
4082ef84 17209 assert (p <= end);
f6f0e17b
NC
17210 return p;
17211}
17212
53a346d8
CZ
17213/* ARC ABI attributes section. */
17214
17215static unsigned char *
17216display_arc_attribute (unsigned char * p,
17217 const unsigned char * const end)
17218{
17219 unsigned int tag;
53a346d8
CZ
17220 unsigned int val;
17221
cd30bcef 17222 READ_ULEB (tag, p, end);
53a346d8
CZ
17223
17224 switch (tag)
17225 {
17226 case Tag_ARC_PCS_config:
cd30bcef 17227 READ_ULEB (val, p, end);
53a346d8
CZ
17228 printf (" Tag_ARC_PCS_config: ");
17229 switch (val)
17230 {
17231 case 0:
17232 printf (_("Absent/Non standard\n"));
17233 break;
17234 case 1:
17235 printf (_("Bare metal/mwdt\n"));
17236 break;
17237 case 2:
17238 printf (_("Bare metal/newlib\n"));
17239 break;
17240 case 3:
17241 printf (_("Linux/uclibc\n"));
17242 break;
17243 case 4:
17244 printf (_("Linux/glibc\n"));
17245 break;
17246 default:
17247 printf (_("Unknown\n"));
17248 break;
17249 }
17250 break;
17251
17252 case Tag_ARC_CPU_base:
cd30bcef 17253 READ_ULEB (val, p, end);
53a346d8
CZ
17254 printf (" Tag_ARC_CPU_base: ");
17255 switch (val)
17256 {
17257 default:
17258 case TAG_CPU_NONE:
17259 printf (_("Absent\n"));
17260 break;
17261 case TAG_CPU_ARC6xx:
17262 printf ("ARC6xx\n");
17263 break;
17264 case TAG_CPU_ARC7xx:
17265 printf ("ARC7xx\n");
17266 break;
17267 case TAG_CPU_ARCEM:
17268 printf ("ARCEM\n");
17269 break;
17270 case TAG_CPU_ARCHS:
17271 printf ("ARCHS\n");
17272 break;
17273 }
17274 break;
17275
17276 case Tag_ARC_CPU_variation:
cd30bcef 17277 READ_ULEB (val, p, end);
53a346d8
CZ
17278 printf (" Tag_ARC_CPU_variation: ");
17279 switch (val)
17280 {
17281 default:
17282 if (val > 0 && val < 16)
53a346d8 17283 printf ("Core%d\n", val);
d8cbc93b
JL
17284 else
17285 printf ("Unknown\n");
17286 break;
17287
53a346d8
CZ
17288 case 0:
17289 printf (_("Absent\n"));
17290 break;
17291 }
17292 break;
17293
17294 case Tag_ARC_CPU_name:
17295 printf (" Tag_ARC_CPU_name: ");
17296 p = display_tag_value (-1, p, end);
17297 break;
17298
17299 case Tag_ARC_ABI_rf16:
cd30bcef 17300 READ_ULEB (val, p, end);
53a346d8
CZ
17301 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17302 break;
17303
17304 case Tag_ARC_ABI_osver:
cd30bcef 17305 READ_ULEB (val, p, end);
53a346d8
CZ
17306 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17307 break;
17308
17309 case Tag_ARC_ABI_pic:
17310 case Tag_ARC_ABI_sda:
cd30bcef 17311 READ_ULEB (val, p, end);
53a346d8
CZ
17312 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17313 : " Tag_ARC_ABI_pic: ");
17314 switch (val)
17315 {
17316 case 0:
17317 printf (_("Absent\n"));
17318 break;
17319 case 1:
17320 printf ("MWDT\n");
17321 break;
17322 case 2:
17323 printf ("GNU\n");
17324 break;
17325 default:
17326 printf (_("Unknown\n"));
17327 break;
17328 }
17329 break;
17330
17331 case Tag_ARC_ABI_tls:
cd30bcef 17332 READ_ULEB (val, p, end);
53a346d8
CZ
17333 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17334 break;
17335
17336 case Tag_ARC_ABI_enumsize:
cd30bcef 17337 READ_ULEB (val, p, end);
53a346d8
CZ
17338 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17339 _("smallest"));
17340 break;
17341
17342 case Tag_ARC_ABI_exceptions:
cd30bcef 17343 READ_ULEB (val, p, end);
53a346d8
CZ
17344 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17345 : _("default"));
17346 break;
17347
17348 case Tag_ARC_ABI_double_size:
cd30bcef 17349 READ_ULEB (val, p, end);
53a346d8
CZ
17350 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17351 break;
17352
17353 case Tag_ARC_ISA_config:
17354 printf (" Tag_ARC_ISA_config: ");
17355 p = display_tag_value (-1, p, end);
17356 break;
17357
17358 case Tag_ARC_ISA_apex:
17359 printf (" Tag_ARC_ISA_apex: ");
17360 p = display_tag_value (-1, p, end);
17361 break;
17362
17363 case Tag_ARC_ISA_mpy_option:
cd30bcef 17364 READ_ULEB (val, p, end);
53a346d8
CZ
17365 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17366 break;
17367
db1e1b45 17368 case Tag_ARC_ATR_version:
cd30bcef 17369 READ_ULEB (val, p, end);
db1e1b45 17370 printf (" Tag_ARC_ATR_version: %d\n", val);
17371 break;
17372
53a346d8
CZ
17373 default:
17374 return display_tag_value (tag & 1, p, end);
17375 }
17376
17377 return p;
17378}
17379
11c1ff18
PB
17380/* ARM EABI attributes section. */
17381typedef struct
17382{
70e99720 17383 unsigned int tag;
2cf0635d 17384 const char * name;
11c1ff18 17385 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17386 unsigned int type;
288f0ba2 17387 const char *const *table;
11c1ff18
PB
17388} arm_attr_public_tag;
17389
288f0ba2 17390static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17391 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17392 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17393 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17394 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17395static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17396static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17397 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17398static const char *const arm_attr_tag_FP_arch[] =
bca38921 17399 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17400 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17401static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17402static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17403 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17404 "NEON for ARMv8.1"};
288f0ba2 17405static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17406 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17407 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17408static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17409 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17410static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17411 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17412static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17413 {"Absolute", "PC-relative", "None"};
288f0ba2 17414static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17415 {"None", "direct", "GOT-indirect"};
288f0ba2 17416static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17417 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17418static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17419static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17420 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17421static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17422static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17423static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17424 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17425static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17426 {"Unused", "small", "int", "forced to int"};
288f0ba2 17427static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17428 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17429static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17430 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17431static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17432 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17433static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17434 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17435 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17436static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17437 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17438 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17439static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17440static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17441 {"Not Allowed", "Allowed"};
288f0ba2 17442static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17443 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17444static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17445 {"Follow architecture", "Allowed"};
288f0ba2 17446static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17447 {"Not Allowed", "Allowed"};
288f0ba2 17448static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17449 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17450 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17451static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17452static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17453 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17454 "TrustZone and Virtualization Extensions"};
288f0ba2 17455static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17456 {"Not Allowed", "Allowed"};
11c1ff18 17457
288f0ba2 17458static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17459 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17460
99db83d0
AC
17461static const char * arm_attr_tag_PAC_extension[] =
17462 {"No PAC/AUT instructions",
17463 "PAC/AUT instructions permitted in the NOP space",
17464 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17465
4b535030
AC
17466static const char * arm_attr_tag_BTI_extension[] =
17467 {"BTI instructions not permitted",
17468 "BTI instructions permitted in the NOP space",
17469 "BTI instructions permitted in the NOP and in the non-NOP space"};
17470
b81ee92f
AC
17471static const char * arm_attr_tag_BTI_use[] =
17472 {"Compiled without branch target enforcement",
17473 "Compiled with branch target enforcement"};
17474
c9fed665
AC
17475static const char * arm_attr_tag_PACRET_use[] =
17476 {"Compiled without return address signing and authentication",
17477 "Compiled with return address signing and authentication"};
17478
11c1ff18
PB
17479#define LOOKUP(id, name) \
17480 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17481static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17482{
17483 {4, "CPU_raw_name", 1, NULL},
17484 {5, "CPU_name", 1, NULL},
17485 LOOKUP(6, CPU_arch),
17486 {7, "CPU_arch_profile", 0, NULL},
17487 LOOKUP(8, ARM_ISA_use),
17488 LOOKUP(9, THUMB_ISA_use),
75375b3e 17489 LOOKUP(10, FP_arch),
11c1ff18 17490 LOOKUP(11, WMMX_arch),
f5f53991
AS
17491 LOOKUP(12, Advanced_SIMD_arch),
17492 LOOKUP(13, PCS_config),
11c1ff18
PB
17493 LOOKUP(14, ABI_PCS_R9_use),
17494 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17495 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17496 LOOKUP(17, ABI_PCS_GOT_use),
17497 LOOKUP(18, ABI_PCS_wchar_t),
17498 LOOKUP(19, ABI_FP_rounding),
17499 LOOKUP(20, ABI_FP_denormal),
17500 LOOKUP(21, ABI_FP_exceptions),
17501 LOOKUP(22, ABI_FP_user_exceptions),
17502 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17503 {24, "ABI_align_needed", 0, NULL},
17504 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17505 LOOKUP(26, ABI_enum_size),
17506 LOOKUP(27, ABI_HardFP_use),
17507 LOOKUP(28, ABI_VFP_args),
17508 LOOKUP(29, ABI_WMMX_args),
17509 LOOKUP(30, ABI_optimization_goals),
17510 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17511 {32, "compatibility", 0, NULL},
f5f53991 17512 LOOKUP(34, CPU_unaligned_access),
75375b3e 17513 LOOKUP(36, FP_HP_extension),
8e79c3df 17514 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17515 LOOKUP(42, MPextension_use),
17516 LOOKUP(44, DIV_use),
15afaa63 17517 LOOKUP(46, DSP_extension),
a7ad558c 17518 LOOKUP(48, MVE_arch),
99db83d0 17519 LOOKUP(50, PAC_extension),
4b535030 17520 LOOKUP(52, BTI_extension),
b81ee92f 17521 LOOKUP(74, BTI_use),
c9fed665 17522 LOOKUP(76, PACRET_use),
f5f53991
AS
17523 {64, "nodefaults", 0, NULL},
17524 {65, "also_compatible_with", 0, NULL},
17525 LOOKUP(66, T2EE_use),
17526 {67, "conformance", 1, NULL},
17527 LOOKUP(68, Virtualization_use),
cd21e546 17528 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17529};
17530#undef LOOKUP
17531
11c1ff18 17532static unsigned char *
f6f0e17b
NC
17533display_arm_attribute (unsigned char * p,
17534 const unsigned char * const end)
11c1ff18 17535{
70e99720 17536 unsigned int tag;
70e99720 17537 unsigned int val;
2cf0635d 17538 arm_attr_public_tag * attr;
11c1ff18 17539 unsigned i;
70e99720 17540 unsigned int type;
11c1ff18 17541
cd30bcef 17542 READ_ULEB (tag, p, end);
11c1ff18 17543 attr = NULL;
2cf0635d 17544 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17545 {
17546 if (arm_attr_public_tags[i].tag == tag)
17547 {
17548 attr = &arm_attr_public_tags[i];
17549 break;
17550 }
17551 }
17552
17553 if (attr)
17554 {
17555 printf (" Tag_%s: ", attr->name);
17556 switch (attr->type)
17557 {
17558 case 0:
17559 switch (tag)
17560 {
17561 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17562 READ_ULEB (val, p, end);
11c1ff18
PB
17563 switch (val)
17564 {
2b692964
NC
17565 case 0: printf (_("None\n")); break;
17566 case 'A': printf (_("Application\n")); break;
17567 case 'R': printf (_("Realtime\n")); break;
17568 case 'M': printf (_("Microcontroller\n")); break;
17569 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17570 default: printf ("??? (%d)\n", val); break;
17571 }
17572 break;
17573
75375b3e 17574 case 24: /* Tag_align_needed. */
cd30bcef 17575 READ_ULEB (val, p, end);
75375b3e
MGD
17576 switch (val)
17577 {
2b692964
NC
17578 case 0: printf (_("None\n")); break;
17579 case 1: printf (_("8-byte\n")); break;
17580 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17581 case 3: printf ("??? 3\n"); break;
17582 default:
17583 if (val <= 12)
dd24e3da 17584 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17585 1 << val);
17586 else
17587 printf ("??? (%d)\n", val);
17588 break;
17589 }
17590 break;
17591
17592 case 25: /* Tag_align_preserved. */
cd30bcef 17593 READ_ULEB (val, p, end);
75375b3e
MGD
17594 switch (val)
17595 {
2b692964
NC
17596 case 0: printf (_("None\n")); break;
17597 case 1: printf (_("8-byte, except leaf SP\n")); break;
17598 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17599 case 3: printf ("??? 3\n"); break;
17600 default:
17601 if (val <= 12)
dd24e3da 17602 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17603 1 << val);
17604 else
17605 printf ("??? (%d)\n", val);
17606 break;
17607 }
17608 break;
17609
11c1ff18 17610 case 32: /* Tag_compatibility. */
071436c6 17611 {
cd30bcef 17612 READ_ULEB (val, p, end);
071436c6 17613 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17614 if (p < end - 1)
17615 {
17616 size_t maxlen = (end - p) - 1;
17617
b6ac461a 17618 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17619 p += strnlen ((char *) p, maxlen) + 1;
17620 }
17621 else
17622 {
17623 printf (_("<corrupt>"));
17624 p = (unsigned char *) end;
17625 }
071436c6 17626 putchar ('\n');
071436c6 17627 }
11c1ff18
PB
17628 break;
17629
f5f53991 17630 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17631 /* PR 17531: file: 001-505008-0.01. */
17632 if (p < end)
17633 p++;
2b692964 17634 printf (_("True\n"));
f5f53991
AS
17635 break;
17636
17637 case 65: /* Tag_also_compatible_with. */
cd30bcef 17638 READ_ULEB (val, p, end);
f5f53991
AS
17639 if (val == 6 /* Tag_CPU_arch. */)
17640 {
cd30bcef 17641 READ_ULEB (val, p, end);
071436c6 17642 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17643 printf ("??? (%d)\n", val);
17644 else
17645 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17646 }
17647 else
17648 printf ("???\n");
071436c6
NC
17649 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17650 ;
f5f53991
AS
17651 break;
17652
11c1ff18 17653 default:
bee0ee85
NC
17654 printf (_("<unknown: %d>\n"), tag);
17655 break;
11c1ff18
PB
17656 }
17657 return p;
17658
17659 case 1:
f6f0e17b 17660 return display_tag_value (-1, p, end);
11c1ff18 17661 case 2:
f6f0e17b 17662 return display_tag_value (0, p, end);
11c1ff18
PB
17663
17664 default:
17665 assert (attr->type & 0x80);
cd30bcef 17666 READ_ULEB (val, p, end);
11c1ff18
PB
17667 type = attr->type & 0x7f;
17668 if (val >= type)
17669 printf ("??? (%d)\n", val);
17670 else
17671 printf ("%s\n", attr->table[val]);
17672 return p;
17673 }
17674 }
11c1ff18 17675
f6f0e17b 17676 return display_tag_value (tag, p, end);
11c1ff18
PB
17677}
17678
104d59d1 17679static unsigned char *
60bca95a 17680display_gnu_attribute (unsigned char * p,
60abdbed 17681 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17682 const unsigned char * const end)
104d59d1 17683{
cd30bcef 17684 unsigned int tag;
60abdbed 17685 unsigned int val;
104d59d1 17686
cd30bcef 17687 READ_ULEB (tag, p, end);
104d59d1
JM
17688
17689 /* Tag_compatibility is the only generic GNU attribute defined at
17690 present. */
17691 if (tag == 32)
17692 {
cd30bcef 17693 READ_ULEB (val, p, end);
071436c6
NC
17694
17695 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17696 if (p == end)
17697 {
071436c6 17698 printf (_("<corrupt>\n"));
f6f0e17b
NC
17699 warn (_("corrupt vendor attribute\n"));
17700 }
17701 else
17702 {
4082ef84
NC
17703 if (p < end - 1)
17704 {
17705 size_t maxlen = (end - p) - 1;
071436c6 17706
b6ac461a 17707 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17708 p += strnlen ((char *) p, maxlen) + 1;
17709 }
17710 else
17711 {
17712 printf (_("<corrupt>"));
17713 p = (unsigned char *) end;
17714 }
071436c6 17715 putchar ('\n');
f6f0e17b 17716 }
104d59d1
JM
17717 return p;
17718 }
17719
17720 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17721 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17722
f6f0e17b 17723 return display_tag_value (tag, p, end);
104d59d1
JM
17724}
17725
85f7484a
PB
17726static unsigned char *
17727display_m68k_gnu_attribute (unsigned char * p,
17728 unsigned int tag,
17729 const unsigned char * const end)
17730{
17731 unsigned int val;
17732
17733 if (tag == Tag_GNU_M68K_ABI_FP)
17734 {
17735 printf (" Tag_GNU_M68K_ABI_FP: ");
17736 if (p == end)
17737 {
17738 printf (_("<corrupt>\n"));
17739 return p;
17740 }
17741 READ_ULEB (val, p, end);
17742
17743 if (val > 3)
17744 printf ("(%#x), ", val);
17745
17746 switch (val & 3)
17747 {
17748 case 0:
17749 printf (_("unspecified hard/soft float\n"));
17750 break;
17751 case 1:
17752 printf (_("hard float\n"));
17753 break;
17754 case 2:
17755 printf (_("soft float\n"));
17756 break;
17757 }
17758 return p;
17759 }
17760
17761 return display_tag_value (tag & 1, p, end);
17762}
17763
34c8bcba 17764static unsigned char *
f6f0e17b 17765display_power_gnu_attribute (unsigned char * p,
60abdbed 17766 unsigned int tag,
f6f0e17b 17767 const unsigned char * const end)
34c8bcba 17768{
005d79fd 17769 unsigned int val;
34c8bcba
JM
17770
17771 if (tag == Tag_GNU_Power_ABI_FP)
17772 {
34c8bcba 17773 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17774 if (p == end)
005d79fd
AM
17775 {
17776 printf (_("<corrupt>\n"));
17777 return p;
17778 }
cd30bcef 17779 READ_ULEB (val, p, end);
60bca95a 17780
005d79fd
AM
17781 if (val > 15)
17782 printf ("(%#x), ", val);
17783
17784 switch (val & 3)
34c8bcba
JM
17785 {
17786 case 0:
005d79fd 17787 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17788 break;
17789 case 1:
005d79fd 17790 printf (_("hard float, "));
34c8bcba
JM
17791 break;
17792 case 2:
005d79fd 17793 printf (_("soft float, "));
34c8bcba 17794 break;
3c7b9897 17795 case 3:
005d79fd 17796 printf (_("single-precision hard float, "));
3c7b9897 17797 break;
005d79fd
AM
17798 }
17799
17800 switch (val & 0xC)
17801 {
17802 case 0:
17803 printf (_("unspecified long double\n"));
17804 break;
17805 case 4:
17806 printf (_("128-bit IBM long double\n"));
17807 break;
17808 case 8:
17809 printf (_("64-bit long double\n"));
17810 break;
17811 case 12:
17812 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17813 break;
17814 }
17815 return p;
005d79fd 17816 }
34c8bcba 17817
c6e65352
DJ
17818 if (tag == Tag_GNU_Power_ABI_Vector)
17819 {
c6e65352 17820 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17821 if (p == end)
005d79fd
AM
17822 {
17823 printf (_("<corrupt>\n"));
17824 return p;
17825 }
cd30bcef 17826 READ_ULEB (val, p, end);
005d79fd
AM
17827
17828 if (val > 3)
17829 printf ("(%#x), ", val);
17830
17831 switch (val & 3)
c6e65352
DJ
17832 {
17833 case 0:
005d79fd 17834 printf (_("unspecified\n"));
c6e65352
DJ
17835 break;
17836 case 1:
005d79fd 17837 printf (_("generic\n"));
c6e65352
DJ
17838 break;
17839 case 2:
17840 printf ("AltiVec\n");
17841 break;
17842 case 3:
17843 printf ("SPE\n");
17844 break;
c6e65352
DJ
17845 }
17846 return p;
005d79fd 17847 }
c6e65352 17848
f82e0623
NF
17849 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17850 {
005d79fd 17851 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17852 if (p == end)
f6f0e17b 17853 {
005d79fd 17854 printf (_("<corrupt>\n"));
f6f0e17b
NC
17855 return p;
17856 }
cd30bcef 17857 READ_ULEB (val, p, end);
0b4362b0 17858
005d79fd
AM
17859 if (val > 2)
17860 printf ("(%#x), ", val);
17861
17862 switch (val & 3)
17863 {
17864 case 0:
17865 printf (_("unspecified\n"));
17866 break;
17867 case 1:
17868 printf ("r3/r4\n");
17869 break;
17870 case 2:
17871 printf (_("memory\n"));
17872 break;
17873 case 3:
17874 printf ("???\n");
17875 break;
17876 }
f82e0623
NF
17877 return p;
17878 }
17879
f6f0e17b 17880 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17881}
17882
643f7afb
AK
17883static unsigned char *
17884display_s390_gnu_attribute (unsigned char * p,
60abdbed 17885 unsigned int tag,
643f7afb
AK
17886 const unsigned char * const end)
17887{
cd30bcef 17888 unsigned int val;
643f7afb
AK
17889
17890 if (tag == Tag_GNU_S390_ABI_Vector)
17891 {
643f7afb 17892 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17893 READ_ULEB (val, p, end);
643f7afb
AK
17894
17895 switch (val)
17896 {
17897 case 0:
17898 printf (_("any\n"));
17899 break;
17900 case 1:
17901 printf (_("software\n"));
17902 break;
17903 case 2:
17904 printf (_("hardware\n"));
17905 break;
17906 default:
17907 printf ("??? (%d)\n", val);
17908 break;
17909 }
17910 return p;
17911 }
17912
17913 return display_tag_value (tag & 1, p, end);
17914}
17915
9e8c70f9 17916static void
60abdbed 17917display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17918{
17919 if (mask)
17920 {
015dc7e1 17921 bool first = true;
071436c6 17922
9e8c70f9 17923 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17924 fputs ("mul32", stdout), first = false;
9e8c70f9 17925 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17926 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17927 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17928 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17929 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17930 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17931 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17932 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17933 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17934 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17935 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17936 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17937 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17938 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17939 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17940 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17941 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17942 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17943 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17944 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17945 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17946 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17947 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17948 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17949 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17950 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17951 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17952 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17953 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17954 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17955 }
17956 else
071436c6
NC
17957 fputc ('0', stdout);
17958 fputc ('\n', stdout);
9e8c70f9
DM
17959}
17960
3d68f91c 17961static void
60abdbed 17962display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17963{
17964 if (mask)
17965 {
015dc7e1 17966 bool first = true;
071436c6 17967
3d68f91c 17968 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17969 fputs ("fjathplus", stdout), first = false;
3d68f91c 17970 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17971 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17972 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17973 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17974 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17975 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17976 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17977 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17978 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17979 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17980 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17981 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17982 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17983 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17984 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17985 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17986 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17987 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17988 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17989 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17990 }
17991 else
071436c6
NC
17992 fputc ('0', stdout);
17993 fputc ('\n', stdout);
3d68f91c
JM
17994}
17995
9e8c70f9 17996static unsigned char *
f6f0e17b 17997display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17998 unsigned int tag,
f6f0e17b 17999 const unsigned char * const end)
9e8c70f9 18000{
cd30bcef 18001 unsigned int val;
3d68f91c 18002
9e8c70f9
DM
18003 if (tag == Tag_GNU_Sparc_HWCAPS)
18004 {
cd30bcef 18005 READ_ULEB (val, p, end);
9e8c70f9 18006 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
18007 display_sparc_hwcaps (val);
18008 return p;
3d68f91c
JM
18009 }
18010 if (tag == Tag_GNU_Sparc_HWCAPS2)
18011 {
cd30bcef 18012 READ_ULEB (val, p, end);
3d68f91c
JM
18013 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18014 display_sparc_hwcaps2 (val);
18015 return p;
18016 }
9e8c70f9 18017
f6f0e17b 18018 return display_tag_value (tag, p, end);
9e8c70f9
DM
18019}
18020
351cdf24 18021static void
32ec8896 18022print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18023{
18024 switch (val)
18025 {
18026 case Val_GNU_MIPS_ABI_FP_ANY:
18027 printf (_("Hard or soft float\n"));
18028 break;
18029 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18030 printf (_("Hard float (double precision)\n"));
18031 break;
18032 case Val_GNU_MIPS_ABI_FP_SINGLE:
18033 printf (_("Hard float (single precision)\n"));
18034 break;
18035 case Val_GNU_MIPS_ABI_FP_SOFT:
18036 printf (_("Soft float\n"));
18037 break;
18038 case Val_GNU_MIPS_ABI_FP_OLD_64:
18039 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18040 break;
18041 case Val_GNU_MIPS_ABI_FP_XX:
18042 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18043 break;
18044 case Val_GNU_MIPS_ABI_FP_64:
18045 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18046 break;
18047 case Val_GNU_MIPS_ABI_FP_64A:
18048 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18049 break;
3350cc01
CM
18050 case Val_GNU_MIPS_ABI_FP_NAN2008:
18051 printf (_("NaN 2008 compatibility\n"));
18052 break;
351cdf24
MF
18053 default:
18054 printf ("??? (%d)\n", val);
18055 break;
18056 }
18057}
18058
2cf19d5c 18059static unsigned char *
f6f0e17b 18060display_mips_gnu_attribute (unsigned char * p,
60abdbed 18061 unsigned int tag,
f6f0e17b 18062 const unsigned char * const end)
2cf19d5c 18063{
2cf19d5c
JM
18064 if (tag == Tag_GNU_MIPS_ABI_FP)
18065 {
32ec8896 18066 unsigned int val;
f6f0e17b 18067
2cf19d5c 18068 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18069 READ_ULEB (val, p, end);
351cdf24 18070 print_mips_fp_abi_value (val);
2cf19d5c
JM
18071 return p;
18072 }
18073
a9f58168
CF
18074 if (tag == Tag_GNU_MIPS_ABI_MSA)
18075 {
32ec8896 18076 unsigned int val;
a9f58168 18077
a9f58168 18078 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18079 READ_ULEB (val, p, end);
a9f58168
CF
18080
18081 switch (val)
18082 {
18083 case Val_GNU_MIPS_ABI_MSA_ANY:
18084 printf (_("Any MSA or not\n"));
18085 break;
18086 case Val_GNU_MIPS_ABI_MSA_128:
18087 printf (_("128-bit MSA\n"));
18088 break;
18089 default:
18090 printf ("??? (%d)\n", val);
18091 break;
18092 }
18093 return p;
18094 }
18095
f6f0e17b 18096 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18097}
18098
59e6276b 18099static unsigned char *
f6f0e17b
NC
18100display_tic6x_attribute (unsigned char * p,
18101 const unsigned char * const end)
59e6276b 18102{
60abdbed 18103 unsigned int tag;
cd30bcef 18104 unsigned int val;
59e6276b 18105
cd30bcef 18106 READ_ULEB (tag, p, end);
59e6276b
JM
18107
18108 switch (tag)
18109 {
75fa6dc1 18110 case Tag_ISA:
75fa6dc1 18111 printf (" Tag_ISA: ");
cd30bcef 18112 READ_ULEB (val, p, end);
59e6276b
JM
18113
18114 switch (val)
18115 {
75fa6dc1 18116 case C6XABI_Tag_ISA_none:
59e6276b
JM
18117 printf (_("None\n"));
18118 break;
75fa6dc1 18119 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18120 printf ("C62x\n");
18121 break;
75fa6dc1 18122 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18123 printf ("C67x\n");
18124 break;
75fa6dc1 18125 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18126 printf ("C67x+\n");
18127 break;
75fa6dc1 18128 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18129 printf ("C64x\n");
18130 break;
75fa6dc1 18131 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18132 printf ("C64x+\n");
18133 break;
75fa6dc1 18134 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18135 printf ("C674x\n");
18136 break;
18137 default:
18138 printf ("??? (%d)\n", val);
18139 break;
18140 }
18141 return p;
18142
87779176 18143 case Tag_ABI_wchar_t:
87779176 18144 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18145 READ_ULEB (val, p, end);
87779176
JM
18146 switch (val)
18147 {
18148 case 0:
18149 printf (_("Not used\n"));
18150 break;
18151 case 1:
18152 printf (_("2 bytes\n"));
18153 break;
18154 case 2:
18155 printf (_("4 bytes\n"));
18156 break;
18157 default:
18158 printf ("??? (%d)\n", val);
18159 break;
18160 }
18161 return p;
18162
18163 case Tag_ABI_stack_align_needed:
87779176 18164 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18165 READ_ULEB (val, p, end);
87779176
JM
18166 switch (val)
18167 {
18168 case 0:
18169 printf (_("8-byte\n"));
18170 break;
18171 case 1:
18172 printf (_("16-byte\n"));
18173 break;
18174 default:
18175 printf ("??? (%d)\n", val);
18176 break;
18177 }
18178 return p;
18179
18180 case Tag_ABI_stack_align_preserved:
cd30bcef 18181 READ_ULEB (val, p, end);
87779176
JM
18182 printf (" Tag_ABI_stack_align_preserved: ");
18183 switch (val)
18184 {
18185 case 0:
18186 printf (_("8-byte\n"));
18187 break;
18188 case 1:
18189 printf (_("16-byte\n"));
18190 break;
18191 default:
18192 printf ("??? (%d)\n", val);
18193 break;
18194 }
18195 return p;
18196
b5593623 18197 case Tag_ABI_DSBT:
cd30bcef 18198 READ_ULEB (val, p, end);
b5593623
JM
18199 printf (" Tag_ABI_DSBT: ");
18200 switch (val)
18201 {
18202 case 0:
18203 printf (_("DSBT addressing not used\n"));
18204 break;
18205 case 1:
18206 printf (_("DSBT addressing used\n"));
18207 break;
18208 default:
18209 printf ("??? (%d)\n", val);
18210 break;
18211 }
18212 return p;
18213
87779176 18214 case Tag_ABI_PID:
cd30bcef 18215 READ_ULEB (val, p, end);
87779176
JM
18216 printf (" Tag_ABI_PID: ");
18217 switch (val)
18218 {
18219 case 0:
18220 printf (_("Data addressing position-dependent\n"));
18221 break;
18222 case 1:
18223 printf (_("Data addressing position-independent, GOT near DP\n"));
18224 break;
18225 case 2:
18226 printf (_("Data addressing position-independent, GOT far from DP\n"));
18227 break;
18228 default:
18229 printf ("??? (%d)\n", val);
18230 break;
18231 }
18232 return p;
18233
18234 case Tag_ABI_PIC:
cd30bcef 18235 READ_ULEB (val, p, end);
87779176
JM
18236 printf (" Tag_ABI_PIC: ");
18237 switch (val)
18238 {
18239 case 0:
18240 printf (_("Code addressing position-dependent\n"));
18241 break;
18242 case 1:
18243 printf (_("Code addressing position-independent\n"));
18244 break;
18245 default:
18246 printf ("??? (%d)\n", val);
18247 break;
18248 }
18249 return p;
18250
18251 case Tag_ABI_array_object_alignment:
cd30bcef 18252 READ_ULEB (val, p, end);
87779176
JM
18253 printf (" Tag_ABI_array_object_alignment: ");
18254 switch (val)
18255 {
18256 case 0:
18257 printf (_("8-byte\n"));
18258 break;
18259 case 1:
18260 printf (_("4-byte\n"));
18261 break;
18262 case 2:
18263 printf (_("16-byte\n"));
18264 break;
18265 default:
18266 printf ("??? (%d)\n", val);
18267 break;
18268 }
18269 return p;
18270
18271 case Tag_ABI_array_object_align_expected:
cd30bcef 18272 READ_ULEB (val, p, end);
87779176
JM
18273 printf (" Tag_ABI_array_object_align_expected: ");
18274 switch (val)
18275 {
18276 case 0:
18277 printf (_("8-byte\n"));
18278 break;
18279 case 1:
18280 printf (_("4-byte\n"));
18281 break;
18282 case 2:
18283 printf (_("16-byte\n"));
18284 break;
18285 default:
18286 printf ("??? (%d)\n", val);
18287 break;
18288 }
18289 return p;
18290
3cbd1c06 18291 case Tag_ABI_compatibility:
071436c6 18292 {
cd30bcef 18293 READ_ULEB (val, p, end);
071436c6 18294 printf (" Tag_ABI_compatibility: ");
071436c6 18295 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18296 if (p < end - 1)
18297 {
18298 size_t maxlen = (end - p) - 1;
18299
b6ac461a 18300 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18301 p += strnlen ((char *) p, maxlen) + 1;
18302 }
18303 else
18304 {
18305 printf (_("<corrupt>"));
18306 p = (unsigned char *) end;
18307 }
071436c6 18308 putchar ('\n');
071436c6
NC
18309 return p;
18310 }
87779176
JM
18311
18312 case Tag_ABI_conformance:
071436c6 18313 {
4082ef84
NC
18314 printf (" Tag_ABI_conformance: \"");
18315 if (p < end - 1)
18316 {
18317 size_t maxlen = (end - p) - 1;
071436c6 18318
b6ac461a 18319 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18320 p += strnlen ((char *) p, maxlen) + 1;
18321 }
18322 else
18323 {
18324 printf (_("<corrupt>"));
18325 p = (unsigned char *) end;
18326 }
071436c6 18327 printf ("\"\n");
071436c6
NC
18328 return p;
18329 }
59e6276b
JM
18330 }
18331
f6f0e17b
NC
18332 return display_tag_value (tag, p, end);
18333}
59e6276b 18334
f6f0e17b 18335static void
60abdbed 18336display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18337{
26c527e6 18338 uint64_t addr = 0;
f6f0e17b
NC
18339 size_t bytes = end - p;
18340
feceaa59 18341 assert (end >= p);
f6f0e17b 18342 while (bytes)
87779176 18343 {
f6f0e17b
NC
18344 int j;
18345 int k;
18346 int lbytes = (bytes > 16 ? 16 : bytes);
18347
26c527e6 18348 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18349
18350 for (j = 0; j < 16; j++)
18351 {
18352 if (j < lbytes)
18353 printf ("%2.2x", p[j]);
18354 else
18355 printf (" ");
18356
18357 if ((j & 3) == 3)
18358 printf (" ");
18359 }
18360
18361 for (j = 0; j < lbytes; j++)
18362 {
18363 k = p[j];
18364 if (k >= ' ' && k < 0x7f)
18365 printf ("%c", k);
18366 else
18367 printf (".");
18368 }
18369
18370 putchar ('\n');
18371
18372 p += lbytes;
18373 bytes -= lbytes;
18374 addr += lbytes;
87779176 18375 }
59e6276b 18376
f6f0e17b 18377 putchar ('\n');
59e6276b
JM
18378}
18379
13761a11 18380static unsigned char *
b0191216 18381display_msp430_attribute (unsigned char * p,
26c527e6 18382 const unsigned char * const end)
13761a11 18383{
26c527e6
AM
18384 uint64_t val;
18385 uint64_t tag;
13761a11 18386
cd30bcef 18387 READ_ULEB (tag, p, end);
0b4362b0 18388
13761a11
NC
18389 switch (tag)
18390 {
18391 case OFBA_MSPABI_Tag_ISA:
13761a11 18392 printf (" Tag_ISA: ");
cd30bcef 18393 READ_ULEB (val, p, end);
13761a11
NC
18394 switch (val)
18395 {
18396 case 0: printf (_("None\n")); break;
18397 case 1: printf (_("MSP430\n")); break;
18398 case 2: printf (_("MSP430X\n")); break;
26c527e6 18399 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18400 }
18401 break;
18402
18403 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18404 printf (" Tag_Code_Model: ");
cd30bcef 18405 READ_ULEB (val, p, end);
13761a11
NC
18406 switch (val)
18407 {
18408 case 0: printf (_("None\n")); break;
18409 case 1: printf (_("Small\n")); break;
18410 case 2: printf (_("Large\n")); break;
26c527e6 18411 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18412 }
18413 break;
18414
18415 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18416 printf (" Tag_Data_Model: ");
cd30bcef 18417 READ_ULEB (val, p, end);
13761a11
NC
18418 switch (val)
18419 {
18420 case 0: printf (_("None\n")); break;
18421 case 1: printf (_("Small\n")); break;
18422 case 2: printf (_("Large\n")); break;
18423 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18424 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18425 }
18426 break;
18427
18428 default:
26c527e6 18429 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18430
18431 if (tag & 1)
18432 {
071436c6 18433 putchar ('"');
4082ef84
NC
18434 if (p < end - 1)
18435 {
18436 size_t maxlen = (end - p) - 1;
18437
b6ac461a 18438 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18439 p += strnlen ((char *) p, maxlen) + 1;
18440 }
18441 else
18442 {
18443 printf (_("<corrupt>"));
18444 p = (unsigned char *) end;
18445 }
071436c6 18446 printf ("\"\n");
13761a11
NC
18447 }
18448 else
18449 {
cd30bcef 18450 READ_ULEB (val, p, end);
26c527e6 18451 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18452 }
18453 break;
18454 }
18455
4082ef84 18456 assert (p <= end);
13761a11
NC
18457 return p;
18458}
18459
c0ea7c52
JL
18460static unsigned char *
18461display_msp430_gnu_attribute (unsigned char * p,
18462 unsigned int tag,
18463 const unsigned char * const end)
18464{
18465 if (tag == Tag_GNU_MSP430_Data_Region)
18466 {
26c527e6 18467 uint64_t val;
c0ea7c52 18468
c0ea7c52 18469 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18470 READ_ULEB (val, p, end);
c0ea7c52
JL
18471
18472 switch (val)
18473 {
18474 case Val_GNU_MSP430_Data_Region_Any:
18475 printf (_("Any Region\n"));
18476 break;
18477 case Val_GNU_MSP430_Data_Region_Lower:
18478 printf (_("Lower Region Only\n"));
18479 break;
18480 default:
26c527e6 18481 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18482 }
18483 return p;
18484 }
18485 return display_tag_value (tag & 1, p, end);
18486}
18487
2dc8dd17
JW
18488struct riscv_attr_tag_t {
18489 const char *name;
cd30bcef 18490 unsigned int tag;
2dc8dd17
JW
18491};
18492
18493static struct riscv_attr_tag_t riscv_attr_tag[] =
18494{
18495#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18496 T(arch),
18497 T(priv_spec),
18498 T(priv_spec_minor),
18499 T(priv_spec_revision),
18500 T(unaligned_access),
18501 T(stack_align),
18502#undef T
18503};
18504
18505static unsigned char *
18506display_riscv_attribute (unsigned char *p,
18507 const unsigned char * const end)
18508{
26c527e6
AM
18509 uint64_t val;
18510 uint64_t tag;
2dc8dd17
JW
18511 struct riscv_attr_tag_t *attr = NULL;
18512 unsigned i;
18513
cd30bcef 18514 READ_ULEB (tag, p, end);
2dc8dd17
JW
18515
18516 /* Find the name of attribute. */
18517 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18518 {
18519 if (riscv_attr_tag[i].tag == tag)
18520 {
18521 attr = &riscv_attr_tag[i];
18522 break;
18523 }
18524 }
18525
18526 if (attr)
18527 printf (" %s: ", attr->name);
18528 else
18529 return display_tag_value (tag, p, end);
18530
18531 switch (tag)
18532 {
18533 case Tag_RISCV_priv_spec:
18534 case Tag_RISCV_priv_spec_minor:
18535 case Tag_RISCV_priv_spec_revision:
cd30bcef 18536 READ_ULEB (val, p, end);
26c527e6 18537 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18538 break;
18539 case Tag_RISCV_unaligned_access:
cd30bcef 18540 READ_ULEB (val, p, end);
2dc8dd17
JW
18541 switch (val)
18542 {
18543 case 0:
18544 printf (_("No unaligned access\n"));
18545 break;
18546 case 1:
18547 printf (_("Unaligned access\n"));
18548 break;
18549 }
18550 break;
18551 case Tag_RISCV_stack_align:
cd30bcef 18552 READ_ULEB (val, p, end);
26c527e6 18553 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18554 break;
18555 case Tag_RISCV_arch:
18556 p = display_tag_value (-1, p, end);
18557 break;
18558 default:
18559 return display_tag_value (tag, p, end);
18560 }
18561
18562 return p;
18563}
18564
0861f561
CQ
18565static unsigned char *
18566display_csky_attribute (unsigned char * p,
18567 const unsigned char * const end)
18568{
26c527e6
AM
18569 uint64_t tag;
18570 uint64_t val;
0861f561
CQ
18571 READ_ULEB (tag, p, end);
18572
18573 if (tag >= Tag_CSKY_MAX)
18574 {
18575 return display_tag_value (-1, p, end);
18576 }
18577
18578 switch (tag)
18579 {
18580 case Tag_CSKY_ARCH_NAME:
18581 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18582 return display_tag_value (-1, p, end);
18583 case Tag_CSKY_CPU_NAME:
18584 printf (" Tag_CSKY_CPU_NAME:\t\t");
18585 return display_tag_value (-1, p, end);
18586
18587 case Tag_CSKY_ISA_FLAGS:
18588 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18589 return display_tag_value (0, p, end);
18590 case Tag_CSKY_ISA_EXT_FLAGS:
18591 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18592 return display_tag_value (0, p, end);
18593
18594 case Tag_CSKY_DSP_VERSION:
18595 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18596 READ_ULEB (val, p, end);
18597 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18598 printf ("DSP Extension\n");
18599 else if (val == VAL_CSKY_DSP_VERSION_2)
18600 printf ("DSP 2.0\n");
18601 break;
18602
18603 case Tag_CSKY_VDSP_VERSION:
18604 printf (" Tag_CSKY_VDSP_VERSION:\t");
18605 READ_ULEB (val, p, end);
26c527e6 18606 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18607 break;
18608
18609 case Tag_CSKY_FPU_VERSION:
18610 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18611 READ_ULEB (val, p, end);
18612 if (val == VAL_CSKY_FPU_VERSION_1)
18613 printf ("ABIV1 FPU Version 1\n");
18614 else if (val == VAL_CSKY_FPU_VERSION_2)
18615 printf ("FPU Version 2\n");
18616 break;
18617
18618 case Tag_CSKY_FPU_ABI:
18619 printf (" Tag_CSKY_FPU_ABI:\t\t");
18620 READ_ULEB (val, p, end);
18621 if (val == VAL_CSKY_FPU_ABI_HARD)
18622 printf ("Hard\n");
18623 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18624 printf ("SoftFP\n");
18625 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18626 printf ("Soft\n");
18627 break;
18628 case Tag_CSKY_FPU_ROUNDING:
18629 READ_ULEB (val, p, end);
f253158f
NC
18630 if (val == 1)
18631 {
18632 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18633 printf ("Needed\n");
18634 }
0861f561
CQ
18635 break;
18636 case Tag_CSKY_FPU_DENORMAL:
18637 READ_ULEB (val, p, end);
f253158f
NC
18638 if (val == 1)
18639 {
18640 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18641 printf ("Needed\n");
18642 }
0861f561
CQ
18643 break;
18644 case Tag_CSKY_FPU_Exception:
18645 READ_ULEB (val, p, end);
f253158f
NC
18646 if (val == 1)
18647 {
18648 printf (" Tag_CSKY_FPU_Exception:\t");
18649 printf ("Needed\n");
18650 }
0861f561
CQ
18651 break;
18652 case Tag_CSKY_FPU_NUMBER_MODULE:
18653 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18654 return display_tag_value (-1, p, end);
18655 case Tag_CSKY_FPU_HARDFP:
18656 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18657 READ_ULEB (val, p, end);
18658 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18659 printf (" Half");
18660 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18661 printf (" Single");
18662 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18663 printf (" Double");
18664 printf ("\n");
18665 break;
18666 default:
18667 return display_tag_value (tag, p, end);
18668 }
18669 return p;
18670}
18671
015dc7e1 18672static bool
dda8d76d 18673process_attributes (Filedata * filedata,
60bca95a 18674 const char * public_name,
104d59d1 18675 unsigned int proc_type,
f6f0e17b 18676 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18677 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18678{
2cf0635d 18679 Elf_Internal_Shdr * sect;
11c1ff18 18680 unsigned i;
015dc7e1 18681 bool res = true;
11c1ff18
PB
18682
18683 /* Find the section header so that we get the size. */
dda8d76d
NC
18684 for (i = 0, sect = filedata->section_headers;
18685 i < filedata->file_header.e_shnum;
11c1ff18
PB
18686 i++, sect++)
18687 {
071436c6
NC
18688 unsigned char * contents;
18689 unsigned char * p;
18690
104d59d1 18691 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18692 continue;
18693
dda8d76d 18694 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18695 sect->sh_size, _("attributes"));
60bca95a 18696 if (contents == NULL)
32ec8896 18697 {
015dc7e1 18698 res = false;
32ec8896
NC
18699 continue;
18700 }
60bca95a 18701
11c1ff18 18702 p = contents;
60abdbed
NC
18703 /* The first character is the version of the attributes.
18704 Currently only version 1, (aka 'A') is recognised here. */
18705 if (*p != 'A')
32ec8896
NC
18706 {
18707 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18708 res = false;
32ec8896 18709 }
60abdbed 18710 else
11c1ff18 18711 {
625d49fc 18712 uint64_t section_len;
071436c6
NC
18713
18714 section_len = sect->sh_size - 1;
11c1ff18 18715 p++;
60bca95a 18716
071436c6 18717 while (section_len > 0)
11c1ff18 18718 {
625d49fc 18719 uint64_t attr_len;
e9847026 18720 unsigned int namelen;
015dc7e1
AM
18721 bool public_section;
18722 bool gnu_section;
11c1ff18 18723
071436c6 18724 if (section_len <= 4)
e0a31db1
NC
18725 {
18726 error (_("Tag section ends prematurely\n"));
015dc7e1 18727 res = false;
e0a31db1
NC
18728 break;
18729 }
071436c6 18730 attr_len = byte_get (p, 4);
11c1ff18 18731 p += 4;
60bca95a 18732
071436c6 18733 if (attr_len > section_len)
11c1ff18 18734 {
071436c6
NC
18735 error (_("Bad attribute length (%u > %u)\n"),
18736 (unsigned) attr_len, (unsigned) section_len);
18737 attr_len = section_len;
015dc7e1 18738 res = false;
11c1ff18 18739 }
74e1a04b 18740 /* PR 17531: file: 001-101425-0.004 */
071436c6 18741 else if (attr_len < 5)
74e1a04b 18742 {
071436c6 18743 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18744 res = false;
74e1a04b
NC
18745 break;
18746 }
e9847026 18747
071436c6
NC
18748 section_len -= attr_len;
18749 attr_len -= 4;
18750
18751 namelen = strnlen ((char *) p, attr_len) + 1;
18752 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18753 {
18754 error (_("Corrupt attribute section name\n"));
015dc7e1 18755 res = false;
e9847026
NC
18756 break;
18757 }
18758
071436c6 18759 printf (_("Attribute Section: "));
b6ac461a 18760 print_symbol_name (INT_MAX, (const char *) p);
071436c6 18761 putchar ('\n');
60bca95a
NC
18762
18763 if (public_name && streq ((char *) p, public_name))
015dc7e1 18764 public_section = true;
11c1ff18 18765 else
015dc7e1 18766 public_section = false;
60bca95a
NC
18767
18768 if (streq ((char *) p, "gnu"))
015dc7e1 18769 gnu_section = true;
104d59d1 18770 else
015dc7e1 18771 gnu_section = false;
60bca95a 18772
11c1ff18 18773 p += namelen;
071436c6 18774 attr_len -= namelen;
e0a31db1 18775
071436c6 18776 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18777 {
e0a31db1 18778 int tag;
cd30bcef 18779 unsigned int val;
625d49fc 18780 uint64_t size;
071436c6 18781 unsigned char * end;
60bca95a 18782
e0a31db1 18783 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18784 if (attr_len < 6)
e0a31db1
NC
18785 {
18786 error (_("Unused bytes at end of section\n"));
015dc7e1 18787 res = false;
e0a31db1
NC
18788 section_len = 0;
18789 break;
18790 }
18791
18792 tag = *(p++);
11c1ff18 18793 size = byte_get (p, 4);
071436c6 18794 if (size > attr_len)
11c1ff18 18795 {
e9847026 18796 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18797 (unsigned) size, (unsigned) attr_len);
015dc7e1 18798 res = false;
071436c6 18799 size = attr_len;
11c1ff18 18800 }
e0a31db1
NC
18801 /* PR binutils/17531: Safe handling of corrupt files. */
18802 if (size < 6)
18803 {
18804 error (_("Bad subsection length (%u < 6)\n"),
18805 (unsigned) size);
015dc7e1 18806 res = false;
e0a31db1
NC
18807 section_len = 0;
18808 break;
18809 }
60bca95a 18810
071436c6 18811 attr_len -= size;
11c1ff18 18812 end = p + size - 1;
071436c6 18813 assert (end <= contents + sect->sh_size);
11c1ff18 18814 p += 4;
60bca95a 18815
11c1ff18
PB
18816 switch (tag)
18817 {
18818 case 1:
2b692964 18819 printf (_("File Attributes\n"));
11c1ff18
PB
18820 break;
18821 case 2:
2b692964 18822 printf (_("Section Attributes:"));
11c1ff18
PB
18823 goto do_numlist;
18824 case 3:
2b692964 18825 printf (_("Symbol Attributes:"));
1a0670f3 18826 /* Fall through. */
11c1ff18
PB
18827 do_numlist:
18828 for (;;)
18829 {
cd30bcef 18830 READ_ULEB (val, p, end);
11c1ff18
PB
18831 if (val == 0)
18832 break;
18833 printf (" %d", val);
18834 }
18835 printf ("\n");
18836 break;
18837 default:
2b692964 18838 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18839 public_section = false;
11c1ff18
PB
18840 break;
18841 }
60bca95a 18842
071436c6 18843 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18844 {
18845 while (p < end)
f6f0e17b 18846 p = display_pub_attribute (p, end);
60abdbed 18847 assert (p == end);
104d59d1 18848 }
071436c6 18849 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18850 {
18851 while (p < end)
18852 p = display_gnu_attribute (p,
f6f0e17b
NC
18853 display_proc_gnu_attribute,
18854 end);
60abdbed 18855 assert (p == end);
11c1ff18 18856 }
071436c6 18857 else if (p < end)
11c1ff18 18858 {
071436c6 18859 printf (_(" Unknown attribute:\n"));
f6f0e17b 18860 display_raw_attribute (p, end);
11c1ff18
PB
18861 p = end;
18862 }
071436c6
NC
18863 else
18864 attr_len = 0;
11c1ff18
PB
18865 }
18866 }
18867 }
d70c5fc7 18868
60bca95a 18869 free (contents);
11c1ff18 18870 }
32ec8896
NC
18871
18872 return res;
11c1ff18
PB
18873}
18874
ccb4c951
RS
18875/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18876 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18877 and return the VMA of the next entry, or -1 if there was a problem.
18878 Does not read from DATA_END or beyond. */
ccb4c951 18879
625d49fc
AM
18880static uint64_t
18881print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18882 unsigned char * data_end)
ccb4c951
RS
18883{
18884 printf (" ");
18885 print_vma (addr, LONG_HEX);
18886 printf (" ");
18887 if (addr < pltgot + 0xfff0)
18888 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18889 else
18890 printf ("%10s", "");
18891 printf (" ");
18892 if (data == NULL)
2b692964 18893 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18894 else
18895 {
625d49fc 18896 uint64_t entry;
82b1b41b 18897 unsigned char * from = data + addr - pltgot;
ccb4c951 18898
82b1b41b
NC
18899 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18900 {
18901 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18902 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18903 return (uint64_t) -1;
82b1b41b
NC
18904 }
18905 else
18906 {
18907 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18908 print_vma (entry, LONG_HEX);
18909 }
ccb4c951
RS
18910 }
18911 return addr + (is_32bit_elf ? 4 : 8);
18912}
18913
861fb55a
DJ
18914/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18915 PLTGOT. Print the Address and Initial fields of an entry at VMA
18916 ADDR and return the VMA of the next entry. */
18917
625d49fc
AM
18918static uint64_t
18919print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18920{
18921 printf (" ");
18922 print_vma (addr, LONG_HEX);
18923 printf (" ");
18924 if (data == NULL)
2b692964 18925 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18926 else
18927 {
625d49fc 18928 uint64_t entry;
861fb55a
DJ
18929
18930 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18931 print_vma (entry, LONG_HEX);
18932 }
18933 return addr + (is_32bit_elf ? 4 : 8);
18934}
18935
351cdf24
MF
18936static void
18937print_mips_ases (unsigned int mask)
18938{
18939 if (mask & AFL_ASE_DSP)
18940 fputs ("\n\tDSP ASE", stdout);
18941 if (mask & AFL_ASE_DSPR2)
18942 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18943 if (mask & AFL_ASE_DSPR3)
18944 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18945 if (mask & AFL_ASE_EVA)
18946 fputs ("\n\tEnhanced VA Scheme", stdout);
18947 if (mask & AFL_ASE_MCU)
18948 fputs ("\n\tMCU (MicroController) ASE", stdout);
18949 if (mask & AFL_ASE_MDMX)
18950 fputs ("\n\tMDMX ASE", stdout);
18951 if (mask & AFL_ASE_MIPS3D)
18952 fputs ("\n\tMIPS-3D ASE", stdout);
18953 if (mask & AFL_ASE_MT)
18954 fputs ("\n\tMT ASE", stdout);
18955 if (mask & AFL_ASE_SMARTMIPS)
18956 fputs ("\n\tSmartMIPS ASE", stdout);
18957 if (mask & AFL_ASE_VIRT)
18958 fputs ("\n\tVZ ASE", stdout);
18959 if (mask & AFL_ASE_MSA)
18960 fputs ("\n\tMSA ASE", stdout);
18961 if (mask & AFL_ASE_MIPS16)
18962 fputs ("\n\tMIPS16 ASE", stdout);
18963 if (mask & AFL_ASE_MICROMIPS)
18964 fputs ("\n\tMICROMIPS ASE", stdout);
18965 if (mask & AFL_ASE_XPA)
18966 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18967 if (mask & AFL_ASE_MIPS16E2)
18968 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18969 if (mask & AFL_ASE_CRC)
18970 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18971 if (mask & AFL_ASE_GINV)
18972 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18973 if (mask & AFL_ASE_LOONGSON_MMI)
18974 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18975 if (mask & AFL_ASE_LOONGSON_CAM)
18976 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18977 if (mask & AFL_ASE_LOONGSON_EXT)
18978 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18979 if (mask & AFL_ASE_LOONGSON_EXT2)
18980 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18981 if (mask == 0)
18982 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18983 else if ((mask & ~AFL_ASE_MASK) != 0)
18984 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18985}
18986
18987static void
18988print_mips_isa_ext (unsigned int isa_ext)
18989{
18990 switch (isa_ext)
18991 {
18992 case 0:
18993 fputs (_("None"), stdout);
18994 break;
18995 case AFL_EXT_XLR:
18996 fputs ("RMI XLR", stdout);
18997 break;
2c629856
N
18998 case AFL_EXT_OCTEON3:
18999 fputs ("Cavium Networks Octeon3", stdout);
19000 break;
351cdf24
MF
19001 case AFL_EXT_OCTEON2:
19002 fputs ("Cavium Networks Octeon2", stdout);
19003 break;
19004 case AFL_EXT_OCTEONP:
19005 fputs ("Cavium Networks OcteonP", stdout);
19006 break;
351cdf24
MF
19007 case AFL_EXT_OCTEON:
19008 fputs ("Cavium Networks Octeon", stdout);
19009 break;
19010 case AFL_EXT_5900:
19011 fputs ("Toshiba R5900", stdout);
19012 break;
19013 case AFL_EXT_4650:
19014 fputs ("MIPS R4650", stdout);
19015 break;
19016 case AFL_EXT_4010:
19017 fputs ("LSI R4010", stdout);
19018 break;
19019 case AFL_EXT_4100:
19020 fputs ("NEC VR4100", stdout);
19021 break;
19022 case AFL_EXT_3900:
19023 fputs ("Toshiba R3900", stdout);
19024 break;
19025 case AFL_EXT_10000:
19026 fputs ("MIPS R10000", stdout);
19027 break;
19028 case AFL_EXT_SB1:
19029 fputs ("Broadcom SB-1", stdout);
19030 break;
19031 case AFL_EXT_4111:
19032 fputs ("NEC VR4111/VR4181", stdout);
19033 break;
19034 case AFL_EXT_4120:
19035 fputs ("NEC VR4120", stdout);
19036 break;
19037 case AFL_EXT_5400:
19038 fputs ("NEC VR5400", stdout);
19039 break;
19040 case AFL_EXT_5500:
19041 fputs ("NEC VR5500", stdout);
19042 break;
19043 case AFL_EXT_LOONGSON_2E:
19044 fputs ("ST Microelectronics Loongson 2E", stdout);
19045 break;
19046 case AFL_EXT_LOONGSON_2F:
19047 fputs ("ST Microelectronics Loongson 2F", stdout);
19048 break;
38bf472a
MR
19049 case AFL_EXT_INTERAPTIV_MR2:
19050 fputs ("Imagination interAptiv MR2", stdout);
19051 break;
351cdf24 19052 default:
00ac7aa0 19053 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19054 }
19055}
19056
32ec8896 19057static signed int
351cdf24
MF
19058get_mips_reg_size (int reg_size)
19059{
19060 return (reg_size == AFL_REG_NONE) ? 0
19061 : (reg_size == AFL_REG_32) ? 32
19062 : (reg_size == AFL_REG_64) ? 64
19063 : (reg_size == AFL_REG_128) ? 128
19064 : -1;
19065}
19066
015dc7e1 19067static bool
dda8d76d 19068process_mips_specific (Filedata * filedata)
5b18a4bc 19069{
2cf0635d 19070 Elf_Internal_Dyn * entry;
351cdf24 19071 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19072 size_t liblist_offset = 0;
19073 size_t liblistno = 0;
19074 size_t conflictsno = 0;
19075 size_t options_offset = 0;
19076 size_t conflicts_offset = 0;
861fb55a
DJ
19077 size_t pltrelsz = 0;
19078 size_t pltrel = 0;
625d49fc
AM
19079 uint64_t pltgot = 0;
19080 uint64_t mips_pltgot = 0;
19081 uint64_t jmprel = 0;
19082 uint64_t local_gotno = 0;
19083 uint64_t gotsym = 0;
19084 uint64_t symtabno = 0;
015dc7e1 19085 bool res = true;
103f02d3 19086
dda8d76d 19087 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19088 display_mips_gnu_attribute))
015dc7e1 19089 res = false;
2cf19d5c 19090
dda8d76d 19091 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19092
19093 if (sect != NULL)
19094 {
19095 Elf_External_ABIFlags_v0 *abiflags_ext;
19096 Elf_Internal_ABIFlags_v0 abiflags_in;
19097
19098 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19099 {
19100 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19101 res = false;
32ec8896 19102 }
351cdf24
MF
19103 else
19104 {
dda8d76d 19105 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19106 sect->sh_size, _("MIPS ABI Flags section"));
19107 if (abiflags_ext)
19108 {
19109 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19110 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19111 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19112 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19113 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19114 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19115 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19116 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19117 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19118 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19119 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19120
19121 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19122 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19123 if (abiflags_in.isa_rev > 1)
19124 printf ("r%d", abiflags_in.isa_rev);
19125 printf ("\nGPR size: %d",
19126 get_mips_reg_size (abiflags_in.gpr_size));
19127 printf ("\nCPR1 size: %d",
19128 get_mips_reg_size (abiflags_in.cpr1_size));
19129 printf ("\nCPR2 size: %d",
19130 get_mips_reg_size (abiflags_in.cpr2_size));
19131 fputs ("\nFP ABI: ", stdout);
19132 print_mips_fp_abi_value (abiflags_in.fp_abi);
19133 fputs ("ISA Extension: ", stdout);
19134 print_mips_isa_ext (abiflags_in.isa_ext);
19135 fputs ("\nASEs:", stdout);
19136 print_mips_ases (abiflags_in.ases);
19137 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19138 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19139 fputc ('\n', stdout);
19140 free (abiflags_ext);
19141 }
19142 }
19143 }
19144
19e6b90e 19145 /* We have a lot of special sections. Thanks SGI! */
978c4450 19146 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19147 {
19148 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19149 sect = find_section (filedata, ".got");
bbdd9a68
MR
19150 if (sect != NULL)
19151 {
19152 unsigned char *data_end;
19153 unsigned char *data;
625d49fc 19154 uint64_t ent, end;
bbdd9a68
MR
19155 int addr_size;
19156
19157 pltgot = sect->sh_addr;
19158
19159 ent = pltgot;
19160 addr_size = (is_32bit_elf ? 4 : 8);
19161 end = pltgot + sect->sh_size;
19162
dda8d76d 19163 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19164 end - pltgot, 1,
19165 _("Global Offset Table data"));
19166 /* PR 12855: Null data is handled gracefully throughout. */
19167 data_end = data + (end - pltgot);
19168
19169 printf (_("\nStatic GOT:\n"));
19170 printf (_(" Canonical gp value: "));
19171 print_vma (ent + 0x7ff0, LONG_HEX);
19172 printf ("\n\n");
19173
19174 /* In a dynamic binary GOT[0] is reserved for the dynamic
19175 loader to store the lazy resolver pointer, however in
19176 a static binary it may well have been omitted and GOT
19177 reduced to a table of addresses.
19178 PR 21344: Check for the entry being fully available
19179 before fetching it. */
19180 if (data
19181 && data + ent - pltgot + addr_size <= data_end
19182 && byte_get (data + ent - pltgot, addr_size) == 0)
19183 {
19184 printf (_(" Reserved entries:\n"));
19185 printf (_(" %*s %10s %*s\n"),
19186 addr_size * 2, _("Address"), _("Access"),
19187 addr_size * 2, _("Value"));
19188 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19189 printf ("\n");
625d49fc 19190 if (ent == (uint64_t) -1)
bbdd9a68
MR
19191 goto sgot_print_fail;
19192
19193 /* Check for the MSB of GOT[1] being set, identifying a
19194 GNU object. This entry will be used by some runtime
19195 loaders, to store the module pointer. Otherwise this
19196 is an ordinary local entry.
19197 PR 21344: Check for the entry being fully available
19198 before fetching it. */
19199 if (data
19200 && data + ent - pltgot + addr_size <= data_end
19201 && (byte_get (data + ent - pltgot, addr_size)
19202 >> (addr_size * 8 - 1)) != 0)
19203 {
19204 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19205 printf ("\n");
625d49fc 19206 if (ent == (uint64_t) -1)
bbdd9a68
MR
19207 goto sgot_print_fail;
19208 }
19209 printf ("\n");
19210 }
19211
f17e9d8a 19212 if (data != NULL && ent < end)
bbdd9a68
MR
19213 {
19214 printf (_(" Local entries:\n"));
19215 printf (" %*s %10s %*s\n",
19216 addr_size * 2, _("Address"), _("Access"),
19217 addr_size * 2, _("Value"));
19218 while (ent < end)
19219 {
19220 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19221 printf ("\n");
625d49fc 19222 if (ent == (uint64_t) -1)
bbdd9a68
MR
19223 goto sgot_print_fail;
19224 }
19225 printf ("\n");
19226 }
19227
19228 sgot_print_fail:
9db70fc3 19229 free (data);
bbdd9a68
MR
19230 }
19231 return res;
19232 }
252b5132 19233
978c4450 19234 for (entry = filedata->dynamic_section;
071436c6 19235 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19236 (entry < filedata->dynamic_section + filedata->dynamic_nent
19237 && entry->d_tag != DT_NULL);
071436c6 19238 ++entry)
252b5132
RH
19239 switch (entry->d_tag)
19240 {
19241 case DT_MIPS_LIBLIST:
d93f0186 19242 liblist_offset
dda8d76d 19243 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19244 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19245 break;
19246 case DT_MIPS_LIBLISTNO:
19247 liblistno = entry->d_un.d_val;
19248 break;
19249 case DT_MIPS_OPTIONS:
dda8d76d 19250 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19251 break;
19252 case DT_MIPS_CONFLICT:
d93f0186 19253 conflicts_offset
dda8d76d 19254 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19255 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19256 break;
19257 case DT_MIPS_CONFLICTNO:
19258 conflictsno = entry->d_un.d_val;
19259 break;
ccb4c951 19260 case DT_PLTGOT:
861fb55a
DJ
19261 pltgot = entry->d_un.d_ptr;
19262 break;
ccb4c951
RS
19263 case DT_MIPS_LOCAL_GOTNO:
19264 local_gotno = entry->d_un.d_val;
19265 break;
19266 case DT_MIPS_GOTSYM:
19267 gotsym = entry->d_un.d_val;
19268 break;
19269 case DT_MIPS_SYMTABNO:
19270 symtabno = entry->d_un.d_val;
19271 break;
861fb55a
DJ
19272 case DT_MIPS_PLTGOT:
19273 mips_pltgot = entry->d_un.d_ptr;
19274 break;
19275 case DT_PLTREL:
19276 pltrel = entry->d_un.d_val;
19277 break;
19278 case DT_PLTRELSZ:
19279 pltrelsz = entry->d_un.d_val;
19280 break;
19281 case DT_JMPREL:
19282 jmprel = entry->d_un.d_ptr;
19283 break;
252b5132
RH
19284 default:
19285 break;
19286 }
19287
19288 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19289 {
2cf0635d 19290 Elf32_External_Lib * elib;
252b5132
RH
19291 size_t cnt;
19292
dda8d76d 19293 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19294 sizeof (Elf32_External_Lib),
19295 liblistno,
19296 _("liblist section data"));
a6e9f9df 19297 if (elib)
252b5132 19298 {
26c527e6
AM
19299 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19300 "\nSection '.liblist' contains %zu entries:\n",
19301 liblistno),
19302 liblistno);
2b692964 19303 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19304 stdout);
19305
19306 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19307 {
a6e9f9df 19308 Elf32_Lib liblist;
91d6fa6a 19309 time_t atime;
d5b07ef4 19310 char timebuf[128];
2cf0635d 19311 struct tm * tmp;
a6e9f9df
AM
19312
19313 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19314 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19315 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19316 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19317 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19318
91d6fa6a 19319 tmp = gmtime (&atime);
e9e44622
JJ
19320 snprintf (timebuf, sizeof (timebuf),
19321 "%04u-%02u-%02uT%02u:%02u:%02u",
19322 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19323 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19324
26c527e6 19325 printf ("%3zu: ", cnt);
84714f86 19326 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19327 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19328 else
2b692964 19329 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19330 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19331 liblist.l_version);
a6e9f9df
AM
19332
19333 if (liblist.l_flags == 0)
2b692964 19334 puts (_(" NONE"));
a6e9f9df
AM
19335 else
19336 {
19337 static const struct
252b5132 19338 {
2cf0635d 19339 const char * name;
a6e9f9df 19340 int bit;
252b5132 19341 }
a6e9f9df
AM
19342 l_flags_vals[] =
19343 {
19344 { " EXACT_MATCH", LL_EXACT_MATCH },
19345 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19346 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19347 { " EXPORTS", LL_EXPORTS },
19348 { " DELAY_LOAD", LL_DELAY_LOAD },
19349 { " DELTA", LL_DELTA }
19350 };
19351 int flags = liblist.l_flags;
19352 size_t fcnt;
19353
60bca95a 19354 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19355 if ((flags & l_flags_vals[fcnt].bit) != 0)
19356 {
19357 fputs (l_flags_vals[fcnt].name, stdout);
19358 flags ^= l_flags_vals[fcnt].bit;
19359 }
19360 if (flags != 0)
19361 printf (" %#x", (unsigned int) flags);
252b5132 19362
a6e9f9df
AM
19363 puts ("");
19364 }
252b5132 19365 }
252b5132 19366
a6e9f9df
AM
19367 free (elib);
19368 }
32ec8896 19369 else
015dc7e1 19370 res = false;
252b5132
RH
19371 }
19372
19373 if (options_offset != 0)
19374 {
2cf0635d 19375 Elf_External_Options * eopt;
252b5132
RH
19376 size_t offset;
19377 int cnt;
19378
19379 /* Find the section header so that we get the size. */
dda8d76d 19380 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19381 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19382 if (sect == NULL)
19383 {
19384 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19385 return false;
071436c6 19386 }
7fc0c668
NC
19387 /* PR 24243 */
19388 if (sect->sh_size < sizeof (* eopt))
19389 {
19390 error (_("The MIPS options section is too small.\n"));
015dc7e1 19391 return false;
7fc0c668 19392 }
252b5132 19393
dda8d76d 19394 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19395 sect->sh_size, _("options"));
a6e9f9df 19396 if (eopt)
252b5132 19397 {
fd17d1e6 19398 Elf_Internal_Options option;
76da6bbe 19399
a6e9f9df 19400 offset = cnt = 0;
82b1b41b 19401 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19402 {
2cf0635d 19403 Elf_External_Options * eoption;
fd17d1e6 19404 unsigned int optsize;
252b5132 19405
a6e9f9df 19406 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19407
fd17d1e6 19408 optsize = BYTE_GET (eoption->size);
76da6bbe 19409
82b1b41b 19410 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19411 if (optsize < sizeof (* eopt)
19412 || optsize > sect->sh_size - offset)
82b1b41b 19413 {
645f43a8 19414 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19415 optsize);
645f43a8 19416 free (eopt);
015dc7e1 19417 return false;
82b1b41b 19418 }
fd17d1e6 19419 offset += optsize;
a6e9f9df
AM
19420 ++cnt;
19421 }
252b5132 19422
d3a49aa8
AM
19423 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19424 "\nSection '%s' contains %d entries:\n",
19425 cnt),
dda8d76d 19426 printable_section_name (filedata, sect), cnt);
76da6bbe 19427
82b1b41b 19428 offset = 0;
a6e9f9df 19429 while (cnt-- > 0)
252b5132 19430 {
a6e9f9df 19431 size_t len;
fd17d1e6
AM
19432 Elf_External_Options * eoption;
19433
19434 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19435
19436 option.kind = BYTE_GET (eoption->kind);
19437 option.size = BYTE_GET (eoption->size);
19438 option.section = BYTE_GET (eoption->section);
19439 option.info = BYTE_GET (eoption->info);
a6e9f9df 19440
fd17d1e6 19441 switch (option.kind)
252b5132 19442 {
a6e9f9df
AM
19443 case ODK_NULL:
19444 /* This shouldn't happen. */
d0c4e780 19445 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19446 option.section, option.info);
a6e9f9df 19447 break;
2e6be59c 19448
a6e9f9df
AM
19449 case ODK_REGINFO:
19450 printf (" REGINFO ");
dda8d76d 19451 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19452 {
2cf0635d 19453 Elf32_External_RegInfo * ereg;
b34976b6 19454 Elf32_RegInfo reginfo;
a6e9f9df 19455
2e6be59c 19456 /* 32bit form. */
fd17d1e6
AM
19457 if (option.size < (sizeof (Elf_External_Options)
19458 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19459 {
19460 printf (_("<corrupt>\n"));
19461 error (_("Truncated MIPS REGINFO option\n"));
19462 cnt = 0;
19463 break;
19464 }
19465
fd17d1e6 19466 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19467
a6e9f9df
AM
19468 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19469 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19470 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19471 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19472 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19473 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19474
d0c4e780
AM
19475 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19476 reginfo.ri_gprmask, reginfo.ri_gp_value);
19477 printf (" "
19478 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19479 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19480 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19481 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19482 }
19483 else
19484 {
19485 /* 64 bit form. */
2cf0635d 19486 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19487 Elf64_Internal_RegInfo reginfo;
19488
fd17d1e6
AM
19489 if (option.size < (sizeof (Elf_External_Options)
19490 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19491 {
19492 printf (_("<corrupt>\n"));
19493 error (_("Truncated MIPS REGINFO option\n"));
19494 cnt = 0;
19495 break;
19496 }
19497
fd17d1e6 19498 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19499 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19500 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19501 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19502 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19503 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19504 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19505
d0c4e780
AM
19506 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19507 reginfo.ri_gprmask, reginfo.ri_gp_value);
19508 printf (" "
19509 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19510 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19511 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19512 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19513 }
fd17d1e6 19514 offset += option.size;
a6e9f9df 19515 continue;
2e6be59c 19516
a6e9f9df
AM
19517 case ODK_EXCEPTIONS:
19518 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19519 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19520 fputs (") fpe_max(", stdout);
fd17d1e6 19521 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19522 fputs (")", stdout);
19523
fd17d1e6 19524 if (option.info & OEX_PAGE0)
a6e9f9df 19525 fputs (" PAGE0", stdout);
fd17d1e6 19526 if (option.info & OEX_SMM)
a6e9f9df 19527 fputs (" SMM", stdout);
fd17d1e6 19528 if (option.info & OEX_FPDBUG)
a6e9f9df 19529 fputs (" FPDBUG", stdout);
fd17d1e6 19530 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19531 fputs (" DISMISS", stdout);
19532 break;
2e6be59c 19533
a6e9f9df
AM
19534 case ODK_PAD:
19535 fputs (" PAD ", stdout);
fd17d1e6 19536 if (option.info & OPAD_PREFIX)
a6e9f9df 19537 fputs (" PREFIX", stdout);
fd17d1e6 19538 if (option.info & OPAD_POSTFIX)
a6e9f9df 19539 fputs (" POSTFIX", stdout);
fd17d1e6 19540 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19541 fputs (" SYMBOL", stdout);
19542 break;
2e6be59c 19543
a6e9f9df
AM
19544 case ODK_HWPATCH:
19545 fputs (" HWPATCH ", stdout);
fd17d1e6 19546 if (option.info & OHW_R4KEOP)
a6e9f9df 19547 fputs (" R4KEOP", stdout);
fd17d1e6 19548 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19549 fputs (" R8KPFETCH", stdout);
fd17d1e6 19550 if (option.info & OHW_R5KEOP)
a6e9f9df 19551 fputs (" R5KEOP", stdout);
fd17d1e6 19552 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19553 fputs (" R5KCVTL", stdout);
19554 break;
2e6be59c 19555
a6e9f9df
AM
19556 case ODK_FILL:
19557 fputs (" FILL ", stdout);
19558 /* XXX Print content of info word? */
19559 break;
2e6be59c 19560
a6e9f9df
AM
19561 case ODK_TAGS:
19562 fputs (" TAGS ", stdout);
19563 /* XXX Print content of info word? */
19564 break;
2e6be59c 19565
a6e9f9df
AM
19566 case ODK_HWAND:
19567 fputs (" HWAND ", stdout);
fd17d1e6 19568 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19569 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19570 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19571 fputs (" R4KEOP_CLEAN", stdout);
19572 break;
2e6be59c 19573
a6e9f9df
AM
19574 case ODK_HWOR:
19575 fputs (" HWOR ", stdout);
fd17d1e6 19576 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19577 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19578 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19579 fputs (" R4KEOP_CLEAN", stdout);
19580 break;
2e6be59c 19581
a6e9f9df 19582 case ODK_GP_GROUP:
d0c4e780 19583 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19584 option.info & OGP_GROUP,
19585 (option.info & OGP_SELF) >> 16);
a6e9f9df 19586 break;
2e6be59c 19587
a6e9f9df 19588 case ODK_IDENT:
d0c4e780 19589 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19590 option.info & OGP_GROUP,
19591 (option.info & OGP_SELF) >> 16);
a6e9f9df 19592 break;
2e6be59c 19593
a6e9f9df
AM
19594 default:
19595 /* This shouldn't happen. */
d0c4e780 19596 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19597 option.kind, option.section, option.info);
a6e9f9df 19598 break;
252b5132 19599 }
a6e9f9df 19600
2cf0635d 19601 len = sizeof (* eopt);
fd17d1e6 19602 while (len < option.size)
82b1b41b 19603 {
fd17d1e6 19604 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19605
82b1b41b
NC
19606 if (ISPRINT (datum))
19607 printf ("%c", datum);
19608 else
19609 printf ("\\%03o", datum);
19610 len ++;
19611 }
a6e9f9df 19612 fputs ("\n", stdout);
82b1b41b 19613
fd17d1e6 19614 offset += option.size;
252b5132 19615 }
a6e9f9df 19616 free (eopt);
252b5132 19617 }
32ec8896 19618 else
015dc7e1 19619 res = false;
252b5132
RH
19620 }
19621
19622 if (conflicts_offset != 0 && conflictsno != 0)
19623 {
2cf0635d 19624 Elf32_Conflict * iconf;
252b5132
RH
19625 size_t cnt;
19626
978c4450 19627 if (filedata->dynamic_symbols == NULL)
252b5132 19628 {
591a748a 19629 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19630 return false;
252b5132
RH
19631 }
19632
7296a62a
NC
19633 /* PR 21345 - print a slightly more helpful error message
19634 if we are sure that the cmalloc will fail. */
645f43a8 19635 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19636 {
26c527e6
AM
19637 error (_("Overlarge number of conflicts detected: %zx\n"),
19638 conflictsno);
015dc7e1 19639 return false;
7296a62a
NC
19640 }
19641
3f5e193b 19642 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19643 if (iconf == NULL)
19644 {
8b73c356 19645 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19646 return false;
252b5132
RH
19647 }
19648
9ea033b2 19649 if (is_32bit_elf)
252b5132 19650 {
2cf0635d 19651 Elf32_External_Conflict * econf32;
a6e9f9df 19652
3f5e193b 19653 econf32 = (Elf32_External_Conflict *)
95099889
AM
19654 get_data (NULL, filedata, conflicts_offset,
19655 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19656 if (!econf32)
5a814d6d
AM
19657 {
19658 free (iconf);
015dc7e1 19659 return false;
5a814d6d 19660 }
252b5132
RH
19661
19662 for (cnt = 0; cnt < conflictsno; ++cnt)
19663 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19664
19665 free (econf32);
252b5132
RH
19666 }
19667 else
19668 {
2cf0635d 19669 Elf64_External_Conflict * econf64;
a6e9f9df 19670
3f5e193b 19671 econf64 = (Elf64_External_Conflict *)
95099889
AM
19672 get_data (NULL, filedata, conflicts_offset,
19673 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19674 if (!econf64)
5a814d6d
AM
19675 {
19676 free (iconf);
015dc7e1 19677 return false;
5a814d6d 19678 }
252b5132
RH
19679
19680 for (cnt = 0; cnt < conflictsno; ++cnt)
19681 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19682
19683 free (econf64);
252b5132
RH
19684 }
19685
26c527e6
AM
19686 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19687 "\nSection '.conflict' contains %zu entries:\n",
19688 conflictsno),
19689 conflictsno);
252b5132
RH
19690 puts (_(" Num: Index Value Name"));
19691
19692 for (cnt = 0; cnt < conflictsno; ++cnt)
19693 {
26c527e6 19694 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19695
978c4450 19696 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19697 printf (_("<corrupt symbol index>"));
d79b3d50 19698 else
e0a31db1
NC
19699 {
19700 Elf_Internal_Sym * psym;
19701
978c4450 19702 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19703 print_vma (psym->st_value, FULL_HEX);
19704 putchar (' ');
84714f86 19705 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19706 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19707 else
19708 printf (_("<corrupt: %14ld>"), psym->st_name);
19709 }
31104126 19710 putchar ('\n');
252b5132
RH
19711 }
19712
252b5132
RH
19713 free (iconf);
19714 }
19715
ccb4c951
RS
19716 if (pltgot != 0 && local_gotno != 0)
19717 {
625d49fc 19718 uint64_t ent, local_end, global_end;
bbeee7ea 19719 size_t i, offset;
2cf0635d 19720 unsigned char * data;
82b1b41b 19721 unsigned char * data_end;
bbeee7ea 19722 int addr_size;
ccb4c951 19723
91d6fa6a 19724 ent = pltgot;
ccb4c951
RS
19725 addr_size = (is_32bit_elf ? 4 : 8);
19726 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19727
74e1a04b
NC
19728 /* PR binutils/17533 file: 012-111227-0.004 */
19729 if (symtabno < gotsym)
19730 {
26c527e6
AM
19731 error (_("The GOT symbol offset (%" PRIu64
19732 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19733 gotsym, symtabno);
015dc7e1 19734 return false;
74e1a04b 19735 }
82b1b41b 19736
74e1a04b 19737 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19738 /* PR 17531: file: 54c91a34. */
19739 if (global_end < local_end)
19740 {
26c527e6 19741 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19742 return false;
82b1b41b 19743 }
948f632f 19744
dda8d76d
NC
19745 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19746 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19747 global_end - pltgot, 1,
19748 _("Global Offset Table data"));
919383ac 19749 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19750 data_end = data + (global_end - pltgot);
59245841 19751
ccb4c951
RS
19752 printf (_("\nPrimary GOT:\n"));
19753 printf (_(" Canonical gp value: "));
19754 print_vma (pltgot + 0x7ff0, LONG_HEX);
19755 printf ("\n\n");
19756
19757 printf (_(" Reserved entries:\n"));
19758 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19759 addr_size * 2, _("Address"), _("Access"),
19760 addr_size * 2, _("Initial"));
82b1b41b 19761 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19762 printf (_(" Lazy resolver\n"));
625d49fc 19763 if (ent == (uint64_t) -1)
82b1b41b 19764 goto got_print_fail;
75ec1fdb 19765
c4ab9505
MR
19766 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19767 This entry will be used by some runtime loaders, to store the
19768 module pointer. Otherwise this is an ordinary local entry.
19769 PR 21344: Check for the entry being fully available before
19770 fetching it. */
19771 if (data
19772 && data + ent - pltgot + addr_size <= data_end
19773 && (byte_get (data + ent - pltgot, addr_size)
19774 >> (addr_size * 8 - 1)) != 0)
19775 {
19776 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19777 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19778 if (ent == (uint64_t) -1)
c4ab9505 19779 goto got_print_fail;
ccb4c951
RS
19780 }
19781 printf ("\n");
19782
f17e9d8a 19783 if (data != NULL && ent < local_end)
ccb4c951
RS
19784 {
19785 printf (_(" Local entries:\n"));
cc5914eb 19786 printf (" %*s %10s %*s\n",
2b692964
NC
19787 addr_size * 2, _("Address"), _("Access"),
19788 addr_size * 2, _("Initial"));
91d6fa6a 19789 while (ent < local_end)
ccb4c951 19790 {
82b1b41b 19791 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19792 printf ("\n");
625d49fc 19793 if (ent == (uint64_t) -1)
82b1b41b 19794 goto got_print_fail;
ccb4c951
RS
19795 }
19796 printf ("\n");
19797 }
19798
f17e9d8a 19799 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19800 {
19801 int sym_width;
19802
19803 printf (_(" Global entries:\n"));
cc5914eb 19804 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19805 addr_size * 2, _("Address"),
19806 _("Access"),
2b692964 19807 addr_size * 2, _("Initial"),
9cf03b7e
NC
19808 addr_size * 2, _("Sym.Val."),
19809 _("Type"),
19810 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19811 _("Ndx"), _("Name"));
0b4362b0 19812
ccb4c951 19813 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19814
ccb4c951
RS
19815 for (i = gotsym; i < symtabno; i++)
19816 {
82b1b41b 19817 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19818 printf (" ");
e0a31db1 19819
978c4450 19820 if (filedata->dynamic_symbols == NULL)
e0a31db1 19821 printf (_("<no dynamic symbols>"));
978c4450 19822 else if (i < filedata->num_dynamic_syms)
e0a31db1 19823 {
978c4450 19824 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19825
19826 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
19827 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
19828
19829 bool is_special;
19830 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
19831 if (is_special)
19832 printf ("%3s ", s);
19833 else
19834 printf ("%3u ", psym->st_shndx);
e0a31db1 19835
84714f86 19836 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19837 print_symbol_name (sym_width,
84714f86 19838 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19839 else
19840 printf (_("<corrupt: %14ld>"), psym->st_name);
19841 }
ccb4c951 19842 else
26c527e6
AM
19843 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19844 i);
e0a31db1 19845
ccb4c951 19846 printf ("\n");
625d49fc 19847 if (ent == (uint64_t) -1)
82b1b41b 19848 break;
ccb4c951
RS
19849 }
19850 printf ("\n");
19851 }
19852
82b1b41b 19853 got_print_fail:
9db70fc3 19854 free (data);
ccb4c951
RS
19855 }
19856
861fb55a
DJ
19857 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19858 {
625d49fc 19859 uint64_t ent, end;
26c527e6
AM
19860 uint64_t offset, rel_offset;
19861 uint64_t count, i;
2cf0635d 19862 unsigned char * data;
861fb55a 19863 int addr_size, sym_width;
2cf0635d 19864 Elf_Internal_Rela * rels;
861fb55a 19865
dda8d76d 19866 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19867 if (pltrel == DT_RELA)
19868 {
dda8d76d 19869 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19870 return false;
861fb55a
DJ
19871 }
19872 else
19873 {
dda8d76d 19874 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19875 return false;
861fb55a
DJ
19876 }
19877
91d6fa6a 19878 ent = mips_pltgot;
861fb55a
DJ
19879 addr_size = (is_32bit_elf ? 4 : 8);
19880 end = mips_pltgot + (2 + count) * addr_size;
19881
dda8d76d
NC
19882 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19883 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19884 1, _("Procedure Linkage Table data"));
59245841 19885 if (data == NULL)
288f0ba2
AM
19886 {
19887 free (rels);
015dc7e1 19888 return false;
288f0ba2 19889 }
59245841 19890
9cf03b7e 19891 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19892 printf (_(" Reserved entries:\n"));
19893 printf (_(" %*s %*s Purpose\n"),
2b692964 19894 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19895 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19896 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19897 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19898 printf (_(" Module pointer\n"));
861fb55a
DJ
19899 printf ("\n");
19900
19901 printf (_(" Entries:\n"));
cc5914eb 19902 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19903 addr_size * 2, _("Address"),
19904 addr_size * 2, _("Initial"),
19905 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19906 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19907 for (i = 0; i < count; i++)
19908 {
26c527e6 19909 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19910
91d6fa6a 19911 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19912 printf (" ");
e0a31db1 19913
978c4450 19914 if (idx >= filedata->num_dynamic_syms)
26c527e6 19915 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19916 else
e0a31db1 19917 {
978c4450 19918 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19919
19920 print_vma (psym->st_value, LONG_HEX);
19921 printf (" %-7s %3s ",
dda8d76d 19922 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 19923 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 19924 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19925 print_symbol_name (sym_width,
84714f86 19926 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19927 else
19928 printf (_("<corrupt: %14ld>"), psym->st_name);
19929 }
861fb55a
DJ
19930 printf ("\n");
19931 }
19932 printf ("\n");
19933
9db70fc3 19934 free (data);
861fb55a
DJ
19935 free (rels);
19936 }
19937
32ec8896 19938 return res;
252b5132
RH
19939}
19940
015dc7e1 19941static bool
dda8d76d 19942process_nds32_specific (Filedata * filedata)
35c08157
KLC
19943{
19944 Elf_Internal_Shdr *sect = NULL;
19945
dda8d76d 19946 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19947 if (sect != NULL && sect->sh_size >= 4)
35c08157 19948 {
9c7b8e9b
AM
19949 unsigned char *buf;
19950 unsigned int flag;
35c08157
KLC
19951
19952 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19953 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19954 _("NDS32 elf flags section"));
35c08157 19955
9c7b8e9b 19956 if (buf == NULL)
015dc7e1 19957 return false;
32ec8896 19958
9c7b8e9b
AM
19959 flag = byte_get (buf, 4);
19960 free (buf);
19961 switch (flag & 0x3)
35c08157
KLC
19962 {
19963 case 0:
19964 printf ("(VEC_SIZE):\tNo entry.\n");
19965 break;
19966 case 1:
19967 printf ("(VEC_SIZE):\t4 bytes\n");
19968 break;
19969 case 2:
19970 printf ("(VEC_SIZE):\t16 bytes\n");
19971 break;
19972 case 3:
19973 printf ("(VEC_SIZE):\treserved\n");
19974 break;
19975 }
19976 }
19977
015dc7e1 19978 return true;
35c08157
KLC
19979}
19980
015dc7e1 19981static bool
dda8d76d 19982process_gnu_liblist (Filedata * filedata)
047b2264 19983{
2cf0635d
NC
19984 Elf_Internal_Shdr * section;
19985 Elf_Internal_Shdr * string_sec;
19986 Elf32_External_Lib * elib;
19987 char * strtab;
c256ffe7 19988 size_t strtab_size;
047b2264 19989 size_t cnt;
26c527e6 19990 uint64_t num_liblist;
047b2264 19991 unsigned i;
015dc7e1 19992 bool res = true;
047b2264
JJ
19993
19994 if (! do_arch)
015dc7e1 19995 return true;
047b2264 19996
dda8d76d
NC
19997 for (i = 0, section = filedata->section_headers;
19998 i < filedata->file_header.e_shnum;
b34976b6 19999 i++, section++)
047b2264
JJ
20000 {
20001 switch (section->sh_type)
20002 {
20003 case SHT_GNU_LIBLIST:
dda8d76d 20004 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
20005 break;
20006
3f5e193b 20007 elib = (Elf32_External_Lib *)
dda8d76d 20008 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 20009 _("liblist section data"));
047b2264
JJ
20010
20011 if (elib == NULL)
32ec8896 20012 {
015dc7e1 20013 res = false;
32ec8896
NC
20014 break;
20015 }
047b2264 20016
dda8d76d
NC
20017 string_sec = filedata->section_headers + section->sh_link;
20018 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
20019 string_sec->sh_size,
20020 _("liblist string table"));
047b2264
JJ
20021 if (strtab == NULL
20022 || section->sh_entsize != sizeof (Elf32_External_Lib))
20023 {
20024 free (elib);
2842702f 20025 free (strtab);
015dc7e1 20026 res = false;
047b2264
JJ
20027 break;
20028 }
59245841 20029 strtab_size = string_sec->sh_size;
047b2264 20030
d3a49aa8 20031 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20032 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20033 " entries:\n",
20034 "\nLibrary list section '%s' contains %" PRIu64
20035 " entries:\n",
d3a49aa8 20036 num_liblist),
dda8d76d 20037 printable_section_name (filedata, section),
d3a49aa8 20038 num_liblist);
047b2264 20039
2b692964 20040 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20041
20042 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20043 ++cnt)
20044 {
20045 Elf32_Lib liblist;
91d6fa6a 20046 time_t atime;
d5b07ef4 20047 char timebuf[128];
2cf0635d 20048 struct tm * tmp;
047b2264
JJ
20049
20050 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20051 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20052 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20053 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20054 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20055
91d6fa6a 20056 tmp = gmtime (&atime);
e9e44622
JJ
20057 snprintf (timebuf, sizeof (timebuf),
20058 "%04u-%02u-%02uT%02u:%02u:%02u",
20059 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20060 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20061
26c527e6 20062 printf ("%3zu: ", cnt);
047b2264 20063 if (do_wide)
c256ffe7 20064 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20065 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20066 else
c256ffe7 20067 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20068 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20069 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20070 liblist.l_version, liblist.l_flags);
20071 }
20072
20073 free (elib);
2842702f 20074 free (strtab);
047b2264
JJ
20075 }
20076 }
20077
32ec8896 20078 return res;
047b2264
JJ
20079}
20080
9437c45b 20081static const char *
dda8d76d 20082get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20083{
20084 static char buff[64];
103f02d3 20085
dda8d76d 20086 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20087 switch (e_type)
20088 {
57346661 20089 case NT_AUXV:
1ec5cd37 20090 return _("NT_AUXV (auxiliary vector)");
57346661 20091 case NT_PRSTATUS:
1ec5cd37 20092 return _("NT_PRSTATUS (prstatus structure)");
57346661 20093 case NT_FPREGSET:
1ec5cd37 20094 return _("NT_FPREGSET (floating point registers)");
57346661 20095 case NT_PRPSINFO:
1ec5cd37 20096 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20097 case NT_TASKSTRUCT:
1ec5cd37 20098 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20099 case NT_GDB_TDESC:
20100 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20101 case NT_PRXFPREG:
1ec5cd37 20102 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20103 case NT_PPC_VMX:
20104 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20105 case NT_PPC_VSX:
20106 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20107 case NT_PPC_TAR:
20108 return _("NT_PPC_TAR (ppc TAR register)");
20109 case NT_PPC_PPR:
20110 return _("NT_PPC_PPR (ppc PPR register)");
20111 case NT_PPC_DSCR:
20112 return _("NT_PPC_DSCR (ppc DSCR register)");
20113 case NT_PPC_EBB:
20114 return _("NT_PPC_EBB (ppc EBB registers)");
20115 case NT_PPC_PMU:
20116 return _("NT_PPC_PMU (ppc PMU registers)");
20117 case NT_PPC_TM_CGPR:
20118 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20119 case NT_PPC_TM_CFPR:
20120 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20121 case NT_PPC_TM_CVMX:
20122 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20123 case NT_PPC_TM_CVSX:
3fd21718 20124 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20125 case NT_PPC_TM_SPR:
20126 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20127 case NT_PPC_TM_CTAR:
20128 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20129 case NT_PPC_TM_CPPR:
20130 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20131 case NT_PPC_TM_CDSCR:
20132 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20133 case NT_386_TLS:
20134 return _("NT_386_TLS (x86 TLS information)");
20135 case NT_386_IOPERM:
20136 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20137 case NT_X86_XSTATE:
20138 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20139 case NT_X86_CET:
20140 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
20141 case NT_S390_HIGH_GPRS:
20142 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20143 case NT_S390_TIMER:
20144 return _("NT_S390_TIMER (s390 timer register)");
20145 case NT_S390_TODCMP:
20146 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20147 case NT_S390_TODPREG:
20148 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20149 case NT_S390_CTRS:
20150 return _("NT_S390_CTRS (s390 control registers)");
20151 case NT_S390_PREFIX:
20152 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20153 case NT_S390_LAST_BREAK:
20154 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20155 case NT_S390_SYSTEM_CALL:
20156 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20157 case NT_S390_TDB:
20158 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20159 case NT_S390_VXRS_LOW:
20160 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20161 case NT_S390_VXRS_HIGH:
20162 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20163 case NT_S390_GS_CB:
20164 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20165 case NT_S390_GS_BC:
20166 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20167 case NT_ARM_VFP:
20168 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20169 case NT_ARM_TLS:
20170 return _("NT_ARM_TLS (AArch TLS registers)");
20171 case NT_ARM_HW_BREAK:
20172 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20173 case NT_ARM_HW_WATCH:
20174 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20175 case NT_ARM_SYSTEM_CALL:
20176 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20177 case NT_ARM_SVE:
20178 return _("NT_ARM_SVE (AArch SVE registers)");
20179 case NT_ARM_PAC_MASK:
20180 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20181 case NT_ARM_PACA_KEYS:
20182 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20183 case NT_ARM_PACG_KEYS:
20184 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20185 case NT_ARM_TAGGED_ADDR_CTRL:
20186 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20187 case NT_ARM_SSVE:
20188 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20189 case NT_ARM_ZA:
20190 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20191 case NT_ARM_ZT:
20192 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20193 case NT_ARM_PAC_ENABLED_KEYS:
20194 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20195 case NT_ARC_V2:
20196 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20197 case NT_RISCV_CSR:
20198 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20199 case NT_PSTATUS:
1ec5cd37 20200 return _("NT_PSTATUS (pstatus structure)");
57346661 20201 case NT_FPREGS:
1ec5cd37 20202 return _("NT_FPREGS (floating point registers)");
57346661 20203 case NT_PSINFO:
1ec5cd37 20204 return _("NT_PSINFO (psinfo structure)");
57346661 20205 case NT_LWPSTATUS:
1ec5cd37 20206 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20207 case NT_LWPSINFO:
1ec5cd37 20208 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20209 case NT_WIN32PSTATUS:
1ec5cd37 20210 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20211 case NT_SIGINFO:
20212 return _("NT_SIGINFO (siginfo_t data)");
20213 case NT_FILE:
20214 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20215 default:
20216 break;
20217 }
20218 else
20219 switch (e_type)
20220 {
20221 case NT_VERSION:
20222 return _("NT_VERSION (version)");
20223 case NT_ARCH:
20224 return _("NT_ARCH (architecture)");
9ef920e9 20225 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20226 return _("OPEN");
9ef920e9 20227 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20228 return _("func");
c8795e1f
NC
20229 case NT_GO_BUILDID:
20230 return _("GO BUILDID");
3ac925fc
LB
20231 case FDO_PACKAGING_METADATA:
20232 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20233 default:
20234 break;
20235 }
20236
e9e44622 20237 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20238 return buff;
779fe533
NC
20239}
20240
015dc7e1 20241static bool
9ece1fa9
TT
20242print_core_note (Elf_Internal_Note *pnote)
20243{
20244 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20245 uint64_t count, page_size;
9ece1fa9
TT
20246 unsigned char *descdata, *filenames, *descend;
20247
20248 if (pnote->type != NT_FILE)
04ac15ab
AS
20249 {
20250 if (do_wide)
20251 printf ("\n");
015dc7e1 20252 return true;
04ac15ab 20253 }
9ece1fa9 20254
9ece1fa9
TT
20255 if (!is_32bit_elf)
20256 {
20257 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20258 /* Still "successful". */
015dc7e1 20259 return true;
9ece1fa9 20260 }
9ece1fa9
TT
20261
20262 if (pnote->descsz < 2 * addr_size)
20263 {
32ec8896 20264 error (_(" Malformed note - too short for header\n"));
015dc7e1 20265 return false;
9ece1fa9
TT
20266 }
20267
20268 descdata = (unsigned char *) pnote->descdata;
20269 descend = descdata + pnote->descsz;
20270
20271 if (descdata[pnote->descsz - 1] != '\0')
20272 {
32ec8896 20273 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20274 return false;
9ece1fa9
TT
20275 }
20276
20277 count = byte_get (descdata, addr_size);
20278 descdata += addr_size;
20279
20280 page_size = byte_get (descdata, addr_size);
20281 descdata += addr_size;
20282
625d49fc 20283 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20284 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20285 {
32ec8896 20286 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20287 return false;
9ece1fa9
TT
20288 }
20289
20290 printf (_(" Page size: "));
20291 print_vma (page_size, DEC);
20292 printf ("\n");
20293
20294 printf (_(" %*s%*s%*s\n"),
20295 (int) (2 + 2 * addr_size), _("Start"),
20296 (int) (4 + 2 * addr_size), _("End"),
20297 (int) (4 + 2 * addr_size), _("Page Offset"));
20298 filenames = descdata + count * 3 * addr_size;
595712bb 20299 while (count-- > 0)
9ece1fa9 20300 {
625d49fc 20301 uint64_t start, end, file_ofs;
9ece1fa9
TT
20302
20303 if (filenames == descend)
20304 {
32ec8896 20305 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20306 return false;
9ece1fa9
TT
20307 }
20308
20309 start = byte_get (descdata, addr_size);
20310 descdata += addr_size;
20311 end = byte_get (descdata, addr_size);
20312 descdata += addr_size;
20313 file_ofs = byte_get (descdata, addr_size);
20314 descdata += addr_size;
20315
20316 printf (" ");
20317 print_vma (start, FULL_HEX);
20318 printf (" ");
20319 print_vma (end, FULL_HEX);
20320 printf (" ");
20321 print_vma (file_ofs, FULL_HEX);
20322 printf ("\n %s\n", filenames);
20323
20324 filenames += 1 + strlen ((char *) filenames);
20325 }
20326
015dc7e1 20327 return true;
9ece1fa9
TT
20328}
20329
1118d252
RM
20330static const char *
20331get_gnu_elf_note_type (unsigned e_type)
20332{
1449284b 20333 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20334 switch (e_type)
20335 {
20336 case NT_GNU_ABI_TAG:
20337 return _("NT_GNU_ABI_TAG (ABI version tag)");
20338 case NT_GNU_HWCAP:
20339 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20340 case NT_GNU_BUILD_ID:
20341 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20342 case NT_GNU_GOLD_VERSION:
20343 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20344 case NT_GNU_PROPERTY_TYPE_0:
20345 return _("NT_GNU_PROPERTY_TYPE_0");
20346 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20347 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20348 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20349 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20350 default:
1449284b
NC
20351 {
20352 static char buff[64];
1118d252 20353
1449284b
NC
20354 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20355 return buff;
20356 }
20357 }
1118d252
RM
20358}
20359
a9eafb08
L
20360static void
20361decode_x86_compat_isa (unsigned int bitmask)
20362{
20363 while (bitmask)
20364 {
20365 unsigned int bit = bitmask & (- bitmask);
20366
20367 bitmask &= ~ bit;
20368 switch (bit)
20369 {
20370 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20371 printf ("i486");
20372 break;
20373 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20374 printf ("586");
20375 break;
20376 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20377 printf ("686");
20378 break;
20379 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20380 printf ("SSE");
20381 break;
20382 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20383 printf ("SSE2");
20384 break;
20385 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20386 printf ("SSE3");
20387 break;
20388 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20389 printf ("SSSE3");
20390 break;
20391 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20392 printf ("SSE4_1");
20393 break;
20394 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20395 printf ("SSE4_2");
20396 break;
20397 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20398 printf ("AVX");
20399 break;
20400 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20401 printf ("AVX2");
20402 break;
20403 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20404 printf ("AVX512F");
20405 break;
20406 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20407 printf ("AVX512CD");
20408 break;
20409 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20410 printf ("AVX512ER");
20411 break;
20412 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20413 printf ("AVX512PF");
20414 break;
20415 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20416 printf ("AVX512VL");
20417 break;
20418 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20419 printf ("AVX512DQ");
20420 break;
20421 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20422 printf ("AVX512BW");
20423 break;
65b3d26e
L
20424 default:
20425 printf (_("<unknown: %x>"), bit);
20426 break;
a9eafb08
L
20427 }
20428 if (bitmask)
20429 printf (", ");
20430 }
20431}
20432
9ef920e9 20433static void
32930e4e 20434decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20435{
0a59decb 20436 if (!bitmask)
90c745dc
L
20437 {
20438 printf (_("<None>"));
20439 return;
20440 }
90c745dc 20441
9ef920e9
NC
20442 while (bitmask)
20443 {
1fc87489 20444 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20445
20446 bitmask &= ~ bit;
20447 switch (bit)
20448 {
32930e4e 20449 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20450 printf ("CMOV");
20451 break;
32930e4e 20452 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20453 printf ("SSE");
20454 break;
32930e4e 20455 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20456 printf ("SSE2");
20457 break;
32930e4e 20458 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20459 printf ("SSE3");
20460 break;
32930e4e 20461 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20462 printf ("SSSE3");
20463 break;
32930e4e 20464 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20465 printf ("SSE4_1");
20466 break;
32930e4e 20467 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20468 printf ("SSE4_2");
20469 break;
32930e4e 20470 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20471 printf ("AVX");
20472 break;
32930e4e 20473 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20474 printf ("AVX2");
20475 break;
32930e4e 20476 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20477 printf ("FMA");
20478 break;
32930e4e 20479 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20480 printf ("AVX512F");
20481 break;
32930e4e 20482 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20483 printf ("AVX512CD");
20484 break;
32930e4e 20485 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20486 printf ("AVX512ER");
20487 break;
32930e4e 20488 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20489 printf ("AVX512PF");
20490 break;
32930e4e 20491 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20492 printf ("AVX512VL");
20493 break;
32930e4e 20494 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20495 printf ("AVX512DQ");
20496 break;
32930e4e 20497 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20498 printf ("AVX512BW");
20499 break;
32930e4e 20500 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20501 printf ("AVX512_4FMAPS");
20502 break;
32930e4e 20503 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20504 printf ("AVX512_4VNNIW");
20505 break;
32930e4e 20506 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20507 printf ("AVX512_BITALG");
20508 break;
32930e4e 20509 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20510 printf ("AVX512_IFMA");
20511 break;
32930e4e 20512 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20513 printf ("AVX512_VBMI");
20514 break;
32930e4e 20515 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20516 printf ("AVX512_VBMI2");
20517 break;
32930e4e 20518 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20519 printf ("AVX512_VNNI");
20520 break;
32930e4e 20521 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20522 printf ("AVX512_BF16");
20523 break;
65b3d26e
L
20524 default:
20525 printf (_("<unknown: %x>"), bit);
20526 break;
9ef920e9
NC
20527 }
20528 if (bitmask)
20529 printf (", ");
20530 }
20531}
20532
28cdbb18
SM
20533static const char *
20534get_amdgpu_elf_note_type (unsigned int e_type)
20535{
20536 switch (e_type)
20537 {
20538 case NT_AMDGPU_METADATA:
20539 return _("NT_AMDGPU_METADATA (code object metadata)");
20540 default:
20541 {
20542 static char buf[64];
20543 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20544 return buf;
20545 }
20546 }
20547}
20548
32930e4e
L
20549static void
20550decode_x86_isa (unsigned int bitmask)
20551{
32930e4e
L
20552 while (bitmask)
20553 {
20554 unsigned int bit = bitmask & (- bitmask);
20555
20556 bitmask &= ~ bit;
20557 switch (bit)
20558 {
b0ab0693
L
20559 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20560 printf ("x86-64-baseline");
20561 break;
32930e4e
L
20562 case GNU_PROPERTY_X86_ISA_1_V2:
20563 printf ("x86-64-v2");
20564 break;
20565 case GNU_PROPERTY_X86_ISA_1_V3:
20566 printf ("x86-64-v3");
20567 break;
20568 case GNU_PROPERTY_X86_ISA_1_V4:
20569 printf ("x86-64-v4");
20570 break;
20571 default:
20572 printf (_("<unknown: %x>"), bit);
20573 break;
20574 }
20575 if (bitmask)
20576 printf (", ");
20577 }
20578}
20579
ee2fdd6f 20580static void
a9eafb08 20581decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20582{
0a59decb 20583 if (!bitmask)
90c745dc
L
20584 {
20585 printf (_("<None>"));
20586 return;
20587 }
90c745dc 20588
ee2fdd6f
L
20589 while (bitmask)
20590 {
20591 unsigned int bit = bitmask & (- bitmask);
20592
20593 bitmask &= ~ bit;
20594 switch (bit)
20595 {
20596 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20597 printf ("IBT");
ee2fdd6f 20598 break;
48580982 20599 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20600 printf ("SHSTK");
48580982 20601 break;
279d901e
L
20602 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20603 printf ("LAM_U48");
20604 break;
20605 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20606 printf ("LAM_U57");
20607 break;
ee2fdd6f
L
20608 default:
20609 printf (_("<unknown: %x>"), bit);
20610 break;
20611 }
20612 if (bitmask)
20613 printf (", ");
20614 }
20615}
20616
a9eafb08
L
20617static void
20618decode_x86_feature_2 (unsigned int bitmask)
20619{
0a59decb 20620 if (!bitmask)
90c745dc
L
20621 {
20622 printf (_("<None>"));
20623 return;
20624 }
90c745dc 20625
a9eafb08
L
20626 while (bitmask)
20627 {
20628 unsigned int bit = bitmask & (- bitmask);
20629
20630 bitmask &= ~ bit;
20631 switch (bit)
20632 {
20633 case GNU_PROPERTY_X86_FEATURE_2_X86:
20634 printf ("x86");
20635 break;
20636 case GNU_PROPERTY_X86_FEATURE_2_X87:
20637 printf ("x87");
20638 break;
20639 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20640 printf ("MMX");
20641 break;
20642 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20643 printf ("XMM");
20644 break;
20645 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20646 printf ("YMM");
20647 break;
20648 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20649 printf ("ZMM");
20650 break;
a308b89d
L
20651 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20652 printf ("TMM");
20653 break;
32930e4e
L
20654 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20655 printf ("MASK");
20656 break;
a9eafb08
L
20657 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20658 printf ("FXSR");
20659 break;
20660 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20661 printf ("XSAVE");
20662 break;
20663 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20664 printf ("XSAVEOPT");
20665 break;
20666 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20667 printf ("XSAVEC");
20668 break;
65b3d26e
L
20669 default:
20670 printf (_("<unknown: %x>"), bit);
20671 break;
a9eafb08
L
20672 }
20673 if (bitmask)
20674 printf (", ");
20675 }
20676}
20677
cd702818
SD
20678static void
20679decode_aarch64_feature_1_and (unsigned int bitmask)
20680{
20681 while (bitmask)
20682 {
20683 unsigned int bit = bitmask & (- bitmask);
20684
20685 bitmask &= ~ bit;
20686 switch (bit)
20687 {
20688 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20689 printf ("BTI");
20690 break;
20691
20692 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20693 printf ("PAC");
20694 break;
20695
20696 default:
20697 printf (_("<unknown: %x>"), bit);
20698 break;
20699 }
20700 if (bitmask)
20701 printf (", ");
20702 }
20703}
20704
6320fd00
L
20705static void
20706decode_1_needed (unsigned int bitmask)
20707{
20708 while (bitmask)
20709 {
20710 unsigned int bit = bitmask & (- bitmask);
20711
20712 bitmask &= ~ bit;
20713 switch (bit)
20714 {
20715 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20716 printf ("indirect external access");
20717 break;
20718 default:
20719 printf (_("<unknown: %x>"), bit);
20720 break;
20721 }
20722 if (bitmask)
20723 printf (", ");
20724 }
20725}
20726
9ef920e9 20727static void
dda8d76d 20728print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20729{
20730 unsigned char * ptr = (unsigned char *) pnote->descdata;
20731 unsigned char * ptr_end = ptr + pnote->descsz;
20732 unsigned int size = is_32bit_elf ? 4 : 8;
20733
20734 printf (_(" Properties: "));
20735
1fc87489 20736 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20737 {
20738 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20739 return;
20740 }
20741
6ab2c4ed 20742 while (ptr < ptr_end)
9ef920e9 20743 {
1fc87489 20744 unsigned int j;
6ab2c4ed
MC
20745 unsigned int type;
20746 unsigned int datasz;
20747
20748 if ((size_t) (ptr_end - ptr) < 8)
20749 {
20750 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20751 break;
20752 }
20753
20754 type = byte_get (ptr, 4);
20755 datasz = byte_get (ptr + 4, 4);
9ef920e9 20756
1fc87489 20757 ptr += 8;
9ef920e9 20758
6ab2c4ed 20759 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20760 {
1fc87489
L
20761 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20762 type, datasz);
9ef920e9 20763 break;
1fc87489 20764 }
9ef920e9 20765
1fc87489
L
20766 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20767 {
dda8d76d
NC
20768 if (filedata->file_header.e_machine == EM_X86_64
20769 || filedata->file_header.e_machine == EM_IAMCU
20770 || filedata->file_header.e_machine == EM_386)
1fc87489 20771 {
aa7bca9b
L
20772 unsigned int bitmask;
20773
20774 if (datasz == 4)
0a59decb 20775 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20776 else
20777 bitmask = 0;
20778
1fc87489
L
20779 switch (type)
20780 {
20781 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20782 if (datasz != 4)
aa7bca9b
L
20783 printf (_("x86 ISA used: <corrupt length: %#x> "),
20784 datasz);
1fc87489 20785 else
aa7bca9b
L
20786 {
20787 printf ("x86 ISA used: ");
20788 decode_x86_isa (bitmask);
20789 }
1fc87489 20790 goto next;
9ef920e9 20791
1fc87489 20792 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20793 if (datasz != 4)
aa7bca9b
L
20794 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20795 datasz);
1fc87489 20796 else
aa7bca9b
L
20797 {
20798 printf ("x86 ISA needed: ");
20799 decode_x86_isa (bitmask);
20800 }
1fc87489 20801 goto next;
9ef920e9 20802
ee2fdd6f 20803 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20804 if (datasz != 4)
aa7bca9b
L
20805 printf (_("x86 feature: <corrupt length: %#x> "),
20806 datasz);
ee2fdd6f 20807 else
aa7bca9b
L
20808 {
20809 printf ("x86 feature: ");
a9eafb08
L
20810 decode_x86_feature_1 (bitmask);
20811 }
20812 goto next;
20813
20814 case GNU_PROPERTY_X86_FEATURE_2_USED:
20815 if (datasz != 4)
20816 printf (_("x86 feature used: <corrupt length: %#x> "),
20817 datasz);
20818 else
20819 {
20820 printf ("x86 feature used: ");
20821 decode_x86_feature_2 (bitmask);
20822 }
20823 goto next;
20824
20825 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20826 if (datasz != 4)
20827 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20828 else
20829 {
20830 printf ("x86 feature needed: ");
20831 decode_x86_feature_2 (bitmask);
20832 }
20833 goto next;
20834
20835 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20836 if (datasz != 4)
20837 printf (_("x86 ISA used: <corrupt length: %#x> "),
20838 datasz);
20839 else
20840 {
20841 printf ("x86 ISA used: ");
20842 decode_x86_compat_isa (bitmask);
20843 }
20844 goto next;
20845
20846 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20847 if (datasz != 4)
20848 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20849 datasz);
20850 else
20851 {
20852 printf ("x86 ISA needed: ");
20853 decode_x86_compat_isa (bitmask);
aa7bca9b 20854 }
ee2fdd6f
L
20855 goto next;
20856
32930e4e
L
20857 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20858 if (datasz != 4)
20859 printf (_("x86 ISA used: <corrupt length: %#x> "),
20860 datasz);
20861 else
20862 {
20863 printf ("x86 ISA used: ");
20864 decode_x86_compat_2_isa (bitmask);
20865 }
20866 goto next;
20867
20868 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20869 if (datasz != 4)
20870 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20871 datasz);
20872 else
20873 {
20874 printf ("x86 ISA needed: ");
20875 decode_x86_compat_2_isa (bitmask);
20876 }
20877 goto next;
20878
1fc87489
L
20879 default:
20880 break;
20881 }
20882 }
cd702818
SD
20883 else if (filedata->file_header.e_machine == EM_AARCH64)
20884 {
20885 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20886 {
20887 printf ("AArch64 feature: ");
20888 if (datasz != 4)
20889 printf (_("<corrupt length: %#x> "), datasz);
20890 else
20891 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20892 goto next;
20893 }
20894 }
1fc87489
L
20895 }
20896 else
20897 {
20898 switch (type)
9ef920e9 20899 {
1fc87489
L
20900 case GNU_PROPERTY_STACK_SIZE:
20901 printf (_("stack size: "));
20902 if (datasz != size)
20903 printf (_("<corrupt length: %#x> "), datasz);
20904 else
26c527e6 20905 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20906 goto next;
20907
20908 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20909 printf ("no copy on protected ");
20910 if (datasz)
20911 printf (_("<corrupt length: %#x> "), datasz);
20912 goto next;
20913
20914 default:
5a767724
L
20915 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20916 && type <= GNU_PROPERTY_UINT32_AND_HI)
20917 || (type >= GNU_PROPERTY_UINT32_OR_LO
20918 && type <= GNU_PROPERTY_UINT32_OR_HI))
20919 {
6320fd00
L
20920 switch (type)
20921 {
20922 case GNU_PROPERTY_1_NEEDED:
20923 if (datasz != 4)
20924 printf (_("1_needed: <corrupt length: %#x> "),
20925 datasz);
20926 else
20927 {
20928 unsigned int bitmask = byte_get (ptr, 4);
20929 printf ("1_needed: ");
20930 decode_1_needed (bitmask);
20931 }
20932 goto next;
20933
20934 default:
20935 break;
20936 }
5a767724
L
20937 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20938 printf (_("UINT32_AND (%#x): "), type);
20939 else
20940 printf (_("UINT32_OR (%#x): "), type);
20941 if (datasz != 4)
20942 printf (_("<corrupt length: %#x> "), datasz);
20943 else
20944 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20945 goto next;
20946 }
9ef920e9
NC
20947 break;
20948 }
9ef920e9
NC
20949 }
20950
1fc87489
L
20951 if (type < GNU_PROPERTY_LOPROC)
20952 printf (_("<unknown type %#x data: "), type);
20953 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20954 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20955 else
20956 printf (_("<application-specific type %#x data: "), type);
20957 for (j = 0; j < datasz; ++j)
20958 printf ("%02x ", ptr[j] & 0xff);
20959 printf (">");
20960
dc1e8a47 20961 next:
9ef920e9 20962 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20963 if (ptr == ptr_end)
20964 break;
1fc87489 20965
6ab2c4ed
MC
20966 if (do_wide)
20967 printf (", ");
20968 else
20969 printf ("\n\t");
9ef920e9
NC
20970 }
20971
20972 printf ("\n");
20973}
20974
015dc7e1 20975static bool
dda8d76d 20976print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20977{
1449284b 20978 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20979 switch (pnote->type)
20980 {
20981 case NT_GNU_BUILD_ID:
20982 {
26c527e6 20983 size_t i;
664f90a3
TT
20984
20985 printf (_(" Build ID: "));
20986 for (i = 0; i < pnote->descsz; ++i)
20987 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20988 printf ("\n");
664f90a3
TT
20989 }
20990 break;
20991
20992 case NT_GNU_ABI_TAG:
20993 {
26c527e6 20994 unsigned int os, major, minor, subminor;
664f90a3
TT
20995 const char *osname;
20996
3102e897
NC
20997 /* PR 17531: file: 030-599401-0.004. */
20998 if (pnote->descsz < 16)
20999 {
21000 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21001 break;
21002 }
21003
664f90a3
TT
21004 os = byte_get ((unsigned char *) pnote->descdata, 4);
21005 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21006 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21007 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21008
21009 switch (os)
21010 {
21011 case GNU_ABI_TAG_LINUX:
21012 osname = "Linux";
21013 break;
21014 case GNU_ABI_TAG_HURD:
21015 osname = "Hurd";
21016 break;
21017 case GNU_ABI_TAG_SOLARIS:
21018 osname = "Solaris";
21019 break;
21020 case GNU_ABI_TAG_FREEBSD:
21021 osname = "FreeBSD";
21022 break;
21023 case GNU_ABI_TAG_NETBSD:
21024 osname = "NetBSD";
21025 break;
14ae95f2
RM
21026 case GNU_ABI_TAG_SYLLABLE:
21027 osname = "Syllable";
21028 break;
21029 case GNU_ABI_TAG_NACL:
21030 osname = "NaCl";
21031 break;
664f90a3
TT
21032 default:
21033 osname = "Unknown";
21034 break;
21035 }
21036
26c527e6 21037 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21038 major, minor, subminor);
21039 }
21040 break;
926c5385
CC
21041
21042 case NT_GNU_GOLD_VERSION:
21043 {
26c527e6 21044 size_t i;
926c5385
CC
21045
21046 printf (_(" Version: "));
21047 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21048 printf ("%c", pnote->descdata[i]);
21049 printf ("\n");
21050 }
21051 break;
1449284b
NC
21052
21053 case NT_GNU_HWCAP:
21054 {
26c527e6 21055 unsigned int num_entries, mask;
1449284b
NC
21056
21057 /* Hardware capabilities information. Word 0 is the number of entries.
21058 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21059 is a series of entries, where each entry is a single byte followed
21060 by a nul terminated string. The byte gives the bit number to test
21061 if enabled in the bitmask. */
21062 printf (_(" Hardware Capabilities: "));
21063 if (pnote->descsz < 8)
21064 {
32ec8896 21065 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21066 return false;
1449284b
NC
21067 }
21068 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21069 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21070 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21071 /* FIXME: Add code to display the entries... */
21072 }
21073 break;
21074
9ef920e9 21075 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21076 print_gnu_property_note (filedata, pnote);
9ef920e9 21077 break;
9abca702 21078
1449284b
NC
21079 default:
21080 /* Handle unrecognised types. An error message should have already been
21081 created by get_gnu_elf_note_type(), so all that we need to do is to
21082 display the data. */
21083 {
26c527e6 21084 size_t i;
1449284b
NC
21085
21086 printf (_(" Description data: "));
21087 for (i = 0; i < pnote->descsz; ++i)
21088 printf ("%02x ", pnote->descdata[i] & 0xff);
21089 printf ("\n");
21090 }
21091 break;
664f90a3
TT
21092 }
21093
015dc7e1 21094 return true;
664f90a3
TT
21095}
21096
685080f2
NC
21097static const char *
21098get_v850_elf_note_type (enum v850_notes n_type)
21099{
21100 static char buff[64];
21101
21102 switch (n_type)
21103 {
21104 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21105 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21106 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21107 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21108 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21109 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21110 default:
21111 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21112 return buff;
21113 }
21114}
21115
015dc7e1 21116static bool
685080f2
NC
21117print_v850_note (Elf_Internal_Note * pnote)
21118{
21119 unsigned int val;
21120
21121 if (pnote->descsz != 4)
015dc7e1 21122 return false;
32ec8896 21123
685080f2
NC
21124 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21125
21126 if (val == 0)
21127 {
21128 printf (_("not set\n"));
015dc7e1 21129 return true;
685080f2
NC
21130 }
21131
21132 switch (pnote->type)
21133 {
21134 case V850_NOTE_ALIGNMENT:
21135 switch (val)
21136 {
015dc7e1
AM
21137 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21138 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21139 }
21140 break;
14ae95f2 21141
685080f2
NC
21142 case V850_NOTE_DATA_SIZE:
21143 switch (val)
21144 {
015dc7e1
AM
21145 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21146 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21147 }
21148 break;
14ae95f2 21149
685080f2
NC
21150 case V850_NOTE_FPU_INFO:
21151 switch (val)
21152 {
015dc7e1
AM
21153 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21154 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21155 }
21156 break;
14ae95f2 21157
685080f2
NC
21158 case V850_NOTE_MMU_INFO:
21159 case V850_NOTE_CACHE_INFO:
21160 case V850_NOTE_SIMD_INFO:
21161 if (val == EF_RH850_SIMD)
21162 {
21163 printf (_("yes\n"));
015dc7e1 21164 return true;
685080f2
NC
21165 }
21166 break;
21167
21168 default:
21169 /* An 'unknown note type' message will already have been displayed. */
21170 break;
21171 }
21172
21173 printf (_("unknown value: %x\n"), val);
015dc7e1 21174 return false;
685080f2
NC
21175}
21176
015dc7e1 21177static bool
c6056a74
SF
21178process_netbsd_elf_note (Elf_Internal_Note * pnote)
21179{
21180 unsigned int version;
21181
21182 switch (pnote->type)
21183 {
21184 case NT_NETBSD_IDENT:
b966f55f
AM
21185 if (pnote->descsz < 1)
21186 break;
c6056a74
SF
21187 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21188 if ((version / 10000) % 100)
b966f55f 21189 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21190 version, version / 100000000, (version / 1000000) % 100,
21191 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21192 'A' + (version / 10000) % 26);
c6056a74
SF
21193 else
21194 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21195 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21196 (version / 100) % 100);
015dc7e1 21197 return true;
c6056a74
SF
21198
21199 case NT_NETBSD_MARCH:
9abca702 21200 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21201 pnote->descdata);
015dc7e1 21202 return true;
c6056a74 21203
9abca702 21204 case NT_NETBSD_PAX:
b966f55f
AM
21205 if (pnote->descsz < 1)
21206 break;
9abca702
CZ
21207 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21208 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21209 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21210 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21211 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21212 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21213 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21214 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21215 return true;
c6056a74 21216 }
b966f55f
AM
21217
21218 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21219 pnote->descsz, pnote->type);
015dc7e1 21220 return false;
c6056a74
SF
21221}
21222
f4ddf30f 21223static const char *
dda8d76d 21224get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21225{
f4ddf30f
JB
21226 switch (e_type)
21227 {
21228 case NT_FREEBSD_THRMISC:
21229 return _("NT_THRMISC (thrmisc structure)");
21230 case NT_FREEBSD_PROCSTAT_PROC:
21231 return _("NT_PROCSTAT_PROC (proc data)");
21232 case NT_FREEBSD_PROCSTAT_FILES:
21233 return _("NT_PROCSTAT_FILES (files data)");
21234 case NT_FREEBSD_PROCSTAT_VMMAP:
21235 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21236 case NT_FREEBSD_PROCSTAT_GROUPS:
21237 return _("NT_PROCSTAT_GROUPS (groups data)");
21238 case NT_FREEBSD_PROCSTAT_UMASK:
21239 return _("NT_PROCSTAT_UMASK (umask data)");
21240 case NT_FREEBSD_PROCSTAT_RLIMIT:
21241 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21242 case NT_FREEBSD_PROCSTAT_OSREL:
21243 return _("NT_PROCSTAT_OSREL (osreldate data)");
21244 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21245 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21246 case NT_FREEBSD_PROCSTAT_AUXV:
21247 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21248 case NT_FREEBSD_PTLWPINFO:
21249 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21250 case NT_FREEBSD_X86_SEGBASES:
21251 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21252 }
dda8d76d 21253 return get_note_type (filedata, e_type);
f4ddf30f
JB
21254}
21255
9437c45b 21256static const char *
dda8d76d 21257get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21258{
21259 static char buff[64];
21260
540e6170
CZ
21261 switch (e_type)
21262 {
21263 case NT_NETBSDCORE_PROCINFO:
21264 /* NetBSD core "procinfo" structure. */
21265 return _("NetBSD procinfo structure");
9437c45b 21266
540e6170
CZ
21267 case NT_NETBSDCORE_AUXV:
21268 return _("NetBSD ELF auxiliary vector data");
9437c45b 21269
06d949ec
KR
21270 case NT_NETBSDCORE_LWPSTATUS:
21271 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21272
540e6170 21273 default:
06d949ec 21274 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21275 defined for NetBSD core files. If the note type is less
21276 than the start of the machine-dependent note types, we don't
21277 understand it. */
21278
21279 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21280 {
21281 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21282 return buff;
21283 }
21284 break;
9437c45b
JT
21285 }
21286
dda8d76d 21287 switch (filedata->file_header.e_machine)
9437c45b
JT
21288 {
21289 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21290 and PT_GETFPREGS == mach+2. */
21291
21292 case EM_OLD_ALPHA:
21293 case EM_ALPHA:
21294 case EM_SPARC:
21295 case EM_SPARC32PLUS:
21296 case EM_SPARCV9:
21297 switch (e_type)
21298 {
2b692964 21299 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21300 return _("PT_GETREGS (reg structure)");
2b692964 21301 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21302 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21303 default:
21304 break;
21305 }
21306 break;
21307
c0d38b0e
CZ
21308 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21309 There's also old PT___GETREGS40 == mach + 1 for old reg
21310 structure which lacks GBR. */
21311 case EM_SH:
21312 switch (e_type)
21313 {
21314 case NT_NETBSDCORE_FIRSTMACH + 1:
21315 return _("PT___GETREGS40 (old reg structure)");
21316 case NT_NETBSDCORE_FIRSTMACH + 3:
21317 return _("PT_GETREGS (reg structure)");
21318 case NT_NETBSDCORE_FIRSTMACH + 5:
21319 return _("PT_GETFPREGS (fpreg structure)");
21320 default:
21321 break;
21322 }
21323 break;
21324
9437c45b
JT
21325 /* On all other arch's, PT_GETREGS == mach+1 and
21326 PT_GETFPREGS == mach+3. */
21327 default:
21328 switch (e_type)
21329 {
2b692964 21330 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21331 return _("PT_GETREGS (reg structure)");
2b692964 21332 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21333 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21334 default:
21335 break;
21336 }
21337 }
21338
9cf03b7e 21339 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21340 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21341 return buff;
21342}
21343
98ca73af
FC
21344static const char *
21345get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21346{
21347 switch (e_type)
21348 {
21349 case NT_OPENBSD_PROCINFO:
21350 return _("OpenBSD procinfo structure");
21351 case NT_OPENBSD_AUXV:
21352 return _("OpenBSD ELF auxiliary vector data");
21353 case NT_OPENBSD_REGS:
21354 return _("OpenBSD regular registers");
21355 case NT_OPENBSD_FPREGS:
21356 return _("OpenBSD floating point registers");
21357 case NT_OPENBSD_WCOOKIE:
21358 return _("OpenBSD window cookie");
21359 }
21360
21361 return get_note_type (filedata, e_type);
21362}
21363
e263a66b
CC
21364static const char *
21365get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21366{
21367 switch (e_type)
21368 {
21369 case QNT_DEBUG_FULLPATH:
21370 return _("QNX debug fullpath");
21371 case QNT_DEBUG_RELOC:
21372 return _("QNX debug relocation");
21373 case QNT_STACK:
21374 return _("QNX stack");
21375 case QNT_GENERATOR:
21376 return _("QNX generator");
21377 case QNT_DEFAULT_LIB:
21378 return _("QNX default library");
21379 case QNT_CORE_SYSINFO:
21380 return _("QNX core sysinfo");
21381 case QNT_CORE_INFO:
21382 return _("QNX core info");
21383 case QNT_CORE_STATUS:
21384 return _("QNX core status");
21385 case QNT_CORE_GREG:
21386 return _("QNX general registers");
21387 case QNT_CORE_FPREG:
21388 return _("QNX floating point registers");
21389 case QNT_LINK_MAP:
21390 return _("QNX link map");
21391 }
21392
21393 return get_note_type (filedata, e_type);
21394}
21395
70616151
TT
21396static const char *
21397get_stapsdt_note_type (unsigned e_type)
21398{
21399 static char buff[64];
21400
21401 switch (e_type)
21402 {
21403 case NT_STAPSDT:
21404 return _("NT_STAPSDT (SystemTap probe descriptors)");
21405
21406 default:
21407 break;
21408 }
21409
21410 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21411 return buff;
21412}
21413
015dc7e1 21414static bool
c6a9fc58
TT
21415print_stapsdt_note (Elf_Internal_Note *pnote)
21416{
3ca60c57 21417 size_t len, maxlen;
26c527e6 21418 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21419 char *data = pnote->descdata;
21420 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21421 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21422 char *provider, *probe, *arg_fmt;
21423
3ca60c57
NC
21424 if (pnote->descsz < (addr_size * 3))
21425 goto stapdt_note_too_small;
21426
c6a9fc58
TT
21427 pc = byte_get ((unsigned char *) data, addr_size);
21428 data += addr_size;
3ca60c57 21429
c6a9fc58
TT
21430 base_addr = byte_get ((unsigned char *) data, addr_size);
21431 data += addr_size;
3ca60c57 21432
c6a9fc58
TT
21433 semaphore = byte_get ((unsigned char *) data, addr_size);
21434 data += addr_size;
21435
3ca60c57
NC
21436 if (data >= data_end)
21437 goto stapdt_note_too_small;
21438 maxlen = data_end - data;
21439 len = strnlen (data, maxlen);
21440 if (len < maxlen)
21441 {
21442 provider = data;
21443 data += len + 1;
21444 }
21445 else
21446 goto stapdt_note_too_small;
21447
21448 if (data >= data_end)
21449 goto stapdt_note_too_small;
21450 maxlen = data_end - data;
21451 len = strnlen (data, maxlen);
21452 if (len < maxlen)
21453 {
21454 probe = data;
21455 data += len + 1;
21456 }
21457 else
21458 goto stapdt_note_too_small;
9abca702 21459
3ca60c57
NC
21460 if (data >= data_end)
21461 goto stapdt_note_too_small;
21462 maxlen = data_end - data;
21463 len = strnlen (data, maxlen);
21464 if (len < maxlen)
21465 {
21466 arg_fmt = data;
21467 data += len + 1;
21468 }
21469 else
21470 goto stapdt_note_too_small;
c6a9fc58
TT
21471
21472 printf (_(" Provider: %s\n"), provider);
21473 printf (_(" Name: %s\n"), probe);
21474 printf (_(" Location: "));
21475 print_vma (pc, FULL_HEX);
21476 printf (_(", Base: "));
21477 print_vma (base_addr, FULL_HEX);
21478 printf (_(", Semaphore: "));
21479 print_vma (semaphore, FULL_HEX);
9cf03b7e 21480 printf ("\n");
c6a9fc58
TT
21481 printf (_(" Arguments: %s\n"), arg_fmt);
21482
21483 return data == data_end;
3ca60c57
NC
21484
21485 stapdt_note_too_small:
21486 printf (_(" <corrupt - note is too small>\n"));
21487 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21488 return false;
c6a9fc58
TT
21489}
21490
e5382207
LB
21491static bool
21492print_fdo_note (Elf_Internal_Note * pnote)
21493{
21494 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21495 {
21496 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21497 return true;
21498 }
21499 return false;
21500}
21501
00e98fc7
TG
21502static const char *
21503get_ia64_vms_note_type (unsigned e_type)
21504{
21505 static char buff[64];
21506
21507 switch (e_type)
21508 {
21509 case NT_VMS_MHD:
21510 return _("NT_VMS_MHD (module header)");
21511 case NT_VMS_LNM:
21512 return _("NT_VMS_LNM (language name)");
21513 case NT_VMS_SRC:
21514 return _("NT_VMS_SRC (source files)");
21515 case NT_VMS_TITLE:
9cf03b7e 21516 return "NT_VMS_TITLE";
00e98fc7
TG
21517 case NT_VMS_EIDC:
21518 return _("NT_VMS_EIDC (consistency check)");
21519 case NT_VMS_FPMODE:
21520 return _("NT_VMS_FPMODE (FP mode)");
21521 case NT_VMS_LINKTIME:
9cf03b7e 21522 return "NT_VMS_LINKTIME";
00e98fc7
TG
21523 case NT_VMS_IMGNAM:
21524 return _("NT_VMS_IMGNAM (image name)");
21525 case NT_VMS_IMGID:
21526 return _("NT_VMS_IMGID (image id)");
21527 case NT_VMS_LINKID:
21528 return _("NT_VMS_LINKID (link id)");
21529 case NT_VMS_IMGBID:
21530 return _("NT_VMS_IMGBID (build id)");
21531 case NT_VMS_GSTNAM:
21532 return _("NT_VMS_GSTNAM (sym table name)");
21533 case NT_VMS_ORIG_DYN:
9cf03b7e 21534 return "NT_VMS_ORIG_DYN";
00e98fc7 21535 case NT_VMS_PATCHTIME:
9cf03b7e 21536 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21537 default:
21538 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21539 return buff;
21540 }
21541}
21542
015dc7e1 21543static bool
00e98fc7
TG
21544print_ia64_vms_note (Elf_Internal_Note * pnote)
21545{
26c527e6 21546 unsigned int maxlen = pnote->descsz;
8d18bf79 21547
26c527e6 21548 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21549 goto desc_size_fail;
21550
00e98fc7
TG
21551 switch (pnote->type)
21552 {
21553 case NT_VMS_MHD:
8d18bf79
NC
21554 if (maxlen <= 36)
21555 goto desc_size_fail;
21556
26c527e6 21557 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21558
21559 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21560 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21561 if (l + 34 < maxlen)
21562 {
21563 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21564 if (l + 35 < maxlen)
21565 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21566 else
21567 printf (_(" Module version : <missing>\n"));
21568 }
00e98fc7 21569 else
8d18bf79
NC
21570 {
21571 printf (_(" Module name : <missing>\n"));
21572 printf (_(" Module version : <missing>\n"));
21573 }
00e98fc7 21574 break;
8d18bf79 21575
00e98fc7 21576 case NT_VMS_LNM:
8d18bf79 21577 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21578 break;
8d18bf79 21579
00e98fc7 21580 case NT_VMS_FPMODE:
9cf03b7e 21581 printf (_(" Floating Point mode: "));
8d18bf79
NC
21582 if (maxlen < 8)
21583 goto desc_size_fail;
21584 /* FIXME: Generate an error if descsz > 8 ? */
21585
b8281767 21586 printf ("0x%016" PRIx64 "\n",
625d49fc 21587 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21588 break;
8d18bf79 21589
00e98fc7
TG
21590 case NT_VMS_LINKTIME:
21591 printf (_(" Link time: "));
8d18bf79
NC
21592 if (maxlen < 8)
21593 goto desc_size_fail;
21594 /* FIXME: Generate an error if descsz > 8 ? */
21595
0e3c1eeb 21596 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21597 printf ("\n");
21598 break;
8d18bf79 21599
00e98fc7
TG
21600 case NT_VMS_PATCHTIME:
21601 printf (_(" Patch time: "));
8d18bf79
NC
21602 if (maxlen < 8)
21603 goto desc_size_fail;
21604 /* FIXME: Generate an error if descsz > 8 ? */
21605
0e3c1eeb 21606 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21607 printf ("\n");
21608 break;
8d18bf79 21609
00e98fc7 21610 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21611 if (maxlen < 34)
21612 goto desc_size_fail;
21613
00e98fc7 21614 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21615 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21616 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21617 printf (_(" Last modified : "));
0e3c1eeb 21618 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21619 printf (_("\n Link flags : "));
b8281767 21620 printf ("0x%016" PRIx64 "\n",
625d49fc 21621 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21622 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21623 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21624 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21625 break;
8d18bf79 21626
00e98fc7 21627 case NT_VMS_IMGNAM:
8d18bf79 21628 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21629 break;
8d18bf79 21630
00e98fc7 21631 case NT_VMS_GSTNAM:
8d18bf79 21632 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21633 break;
8d18bf79 21634
00e98fc7 21635 case NT_VMS_IMGID:
8d18bf79 21636 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21637 break;
8d18bf79 21638
00e98fc7 21639 case NT_VMS_LINKID:
8d18bf79 21640 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21641 break;
8d18bf79 21642
00e98fc7 21643 default:
015dc7e1 21644 return false;
00e98fc7 21645 }
8d18bf79 21646
015dc7e1 21647 return true;
8d18bf79
NC
21648
21649 desc_size_fail:
21650 printf (_(" <corrupt - data size is too small>\n"));
21651 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21652 return false;
00e98fc7
TG
21653}
21654
fd486f32
AM
21655struct build_attr_cache {
21656 Filedata *filedata;
21657 char *strtab;
26c527e6 21658 uint64_t strtablen;
fd486f32 21659 Elf_Internal_Sym *symtab;
26c527e6 21660 uint64_t nsyms;
fd486f32
AM
21661} ba_cache;
21662
6f156d7a
NC
21663/* Find the symbol associated with a build attribute that is attached
21664 to address OFFSET. If PNAME is non-NULL then store the name of
21665 the symbol (if found) in the provided pointer, Returns NULL if a
21666 symbol could not be found. */
c799a79d 21667
6f156d7a 21668static Elf_Internal_Sym *
015dc7e1 21669get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21670 uint64_t offset,
015dc7e1
AM
21671 bool is_open_attr,
21672 const char **pname)
9ef920e9 21673{
fd486f32
AM
21674 Elf_Internal_Sym *saved_sym = NULL;
21675 Elf_Internal_Sym *sym;
9ef920e9 21676
dda8d76d 21677 if (filedata->section_headers != NULL
fd486f32 21678 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21679 {
c799a79d 21680 Elf_Internal_Shdr * symsec;
9ef920e9 21681
fd486f32
AM
21682 free (ba_cache.strtab);
21683 ba_cache.strtab = NULL;
21684 free (ba_cache.symtab);
21685 ba_cache.symtab = NULL;
21686
c799a79d 21687 /* Load the symbol and string sections. */
dda8d76d
NC
21688 for (symsec = filedata->section_headers;
21689 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21690 symsec ++)
9ef920e9 21691 {
28d13567
AM
21692 if (symsec->sh_type == SHT_SYMTAB
21693 && get_symtab (filedata, symsec,
21694 &ba_cache.symtab, &ba_cache.nsyms,
21695 &ba_cache.strtab, &ba_cache.strtablen))
21696 break;
9ef920e9 21697 }
fd486f32 21698 ba_cache.filedata = filedata;
9ef920e9
NC
21699 }
21700
fd486f32 21701 if (ba_cache.symtab == NULL)
6f156d7a 21702 return NULL;
9ef920e9 21703
c799a79d 21704 /* Find a symbol whose value matches offset. */
fd486f32 21705 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21706 if (sym->st_value == offset)
21707 {
fd486f32 21708 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21709 /* Huh ? This should not happen. */
21710 continue;
9ef920e9 21711
fd486f32 21712 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21713 continue;
9ef920e9 21714
9b9b1092 21715 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21716 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21717 if (ba_cache.strtab[sym->st_name] == '$'
21718 && ba_cache.strtab[sym->st_name + 1] != 0
21719 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21720 continue;
21721
c799a79d
NC
21722 if (is_open_attr)
21723 {
21724 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21725 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21726 FUNC symbols entirely. */
21727 switch (ELF_ST_TYPE (sym->st_info))
21728 {
c799a79d 21729 case STT_OBJECT:
6f156d7a 21730 case STT_FILE:
c799a79d 21731 saved_sym = sym;
6f156d7a
NC
21732 if (sym->st_size)
21733 {
21734 /* If the symbol has a size associated
21735 with it then we can stop searching. */
fd486f32 21736 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21737 }
c799a79d 21738 continue;
9ef920e9 21739
c799a79d
NC
21740 case STT_FUNC:
21741 /* Ignore function symbols. */
21742 continue;
21743
21744 default:
21745 break;
21746 }
21747
21748 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21749 {
c799a79d
NC
21750 case STB_GLOBAL:
21751 if (saved_sym == NULL
21752 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21753 saved_sym = sym;
21754 break;
c871dade 21755
c799a79d
NC
21756 case STB_LOCAL:
21757 if (saved_sym == NULL)
21758 saved_sym = sym;
21759 break;
21760
21761 default:
9ef920e9
NC
21762 break;
21763 }
21764 }
c799a79d
NC
21765 else
21766 {
21767 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21768 continue;
21769
21770 saved_sym = sym;
21771 break;
21772 }
21773 }
21774
6f156d7a 21775 if (saved_sym && pname)
fd486f32 21776 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21777
21778 return saved_sym;
c799a79d
NC
21779}
21780
d20e98ab
NC
21781/* Returns true iff addr1 and addr2 are in the same section. */
21782
015dc7e1 21783static bool
26c527e6 21784same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21785{
21786 Elf_Internal_Shdr * a1;
21787 Elf_Internal_Shdr * a2;
21788
21789 a1 = find_section_by_address (filedata, addr1);
21790 a2 = find_section_by_address (filedata, addr2);
9abca702 21791
d20e98ab
NC
21792 return a1 == a2 && a1 != NULL;
21793}
21794
015dc7e1 21795static bool
dda8d76d
NC
21796print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21797 Filedata * filedata)
c799a79d 21798{
26c527e6
AM
21799 static uint64_t global_offset = 0;
21800 static uint64_t global_end = 0;
21801 static uint64_t func_offset = 0;
21802 static uint64_t func_end = 0;
c871dade 21803
015dc7e1
AM
21804 Elf_Internal_Sym *sym;
21805 const char *name;
26c527e6
AM
21806 uint64_t start;
21807 uint64_t end;
015dc7e1 21808 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21809
21810 switch (pnote->descsz)
c799a79d 21811 {
6f156d7a
NC
21812 case 0:
21813 /* A zero-length description means that the range of
21814 the previous note of the same type should be used. */
c799a79d 21815 if (is_open_attr)
c871dade 21816 {
6f156d7a 21817 if (global_end > global_offset)
26c527e6
AM
21818 printf (_(" Applies to region from %#" PRIx64
21819 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21820 else
26c527e6
AM
21821 printf (_(" Applies to region from %#" PRIx64
21822 "\n"), global_offset);
c799a79d
NC
21823 }
21824 else
21825 {
6f156d7a 21826 if (func_end > func_offset)
26c527e6
AM
21827 printf (_(" Applies to region from %#" PRIx64
21828 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21829 else
26c527e6
AM
21830 printf (_(" Applies to region from %#" PRIx64
21831 "\n"), func_offset);
c871dade 21832 }
015dc7e1 21833 return true;
9ef920e9 21834
6f156d7a
NC
21835 case 4:
21836 start = byte_get ((unsigned char *) pnote->descdata, 4);
21837 end = 0;
21838 break;
21839
21840 case 8:
c74147bb
NC
21841 start = byte_get ((unsigned char *) pnote->descdata, 4);
21842 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21843 break;
21844
21845 case 16:
21846 start = byte_get ((unsigned char *) pnote->descdata, 8);
21847 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21848 break;
9abca702 21849
6f156d7a 21850 default:
c799a79d
NC
21851 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21852 printf (_(" <invalid descsz>"));
015dc7e1 21853 return false;
c799a79d
NC
21854 }
21855
6f156d7a
NC
21856 name = NULL;
21857 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21858 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21859 in order to avoid them being confused with the start address of the
21860 first function in the file... */
21861 if (sym == NULL && is_open_attr)
21862 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21863 & name);
6f156d7a
NC
21864
21865 if (end == 0 && sym != NULL && sym->st_size > 0)
21866 end = start + sym->st_size;
c799a79d
NC
21867
21868 if (is_open_attr)
21869 {
d20e98ab
NC
21870 /* FIXME: Need to properly allow for section alignment.
21871 16 is just the alignment used on x86_64. */
21872 if (global_end > 0
21873 && start > BFD_ALIGN (global_end, 16)
21874 /* Build notes are not guaranteed to be organised in order of
21875 increasing address, but we should find the all of the notes
21876 for one section in the same place. */
21877 && same_section (filedata, start, global_end))
26c527e6
AM
21878 warn (_("Gap in build notes detected from %#" PRIx64
21879 " to %#" PRIx64 "\n"),
6f156d7a
NC
21880 global_end + 1, start - 1);
21881
26c527e6 21882 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21883 global_offset = start;
21884
21885 if (end)
21886 {
26c527e6 21887 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21888 global_end = end;
21889 }
c799a79d
NC
21890 }
21891 else
21892 {
26c527e6 21893 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21894 func_offset = start;
21895
21896 if (end)
21897 {
26c527e6 21898 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21899 func_end = end;
21900 }
c799a79d
NC
21901 }
21902
6f156d7a
NC
21903 if (sym && name)
21904 printf (_(" (%s)"), name);
21905
21906 printf ("\n");
015dc7e1 21907 return true;
9ef920e9
NC
21908}
21909
015dc7e1 21910static bool
9ef920e9
NC
21911print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21912{
1d15e434
NC
21913 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21914 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21915 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21916 char name_type;
21917 char name_attribute;
1d15e434 21918 const char * expected_types;
9ef920e9
NC
21919 const char * name = pnote->namedata;
21920 const char * text;
88305e1b 21921 signed int left;
9ef920e9
NC
21922
21923 if (name == NULL || pnote->namesz < 2)
21924 {
21925 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21926 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21927 return false;
9ef920e9
NC
21928 }
21929
6f156d7a
NC
21930 if (do_wide)
21931 left = 28;
21932 else
21933 left = 20;
88305e1b
NC
21934
21935 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21936 if (name[0] == 'G' && name[1] == 'A')
21937 {
6f156d7a
NC
21938 if (pnote->namesz < 4)
21939 {
21940 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21941 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21942 return false;
6f156d7a
NC
21943 }
21944
88305e1b
NC
21945 printf ("GA");
21946 name += 2;
21947 left -= 2;
21948 }
21949
9ef920e9
NC
21950 switch ((name_type = * name))
21951 {
21952 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21953 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21954 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21955 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21956 printf ("%c", * name);
88305e1b 21957 left --;
9ef920e9
NC
21958 break;
21959 default:
21960 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 21961 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 21962 return false;
9ef920e9
NC
21963 }
21964
9ef920e9
NC
21965 ++ name;
21966 text = NULL;
21967
21968 switch ((name_attribute = * name))
21969 {
21970 case GNU_BUILD_ATTRIBUTE_VERSION:
21971 text = _("<version>");
1d15e434 21972 expected_types = string_expected;
9ef920e9
NC
21973 ++ name;
21974 break;
21975 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21976 text = _("<stack prot>");
75d7d298 21977 expected_types = "!+*";
9ef920e9
NC
21978 ++ name;
21979 break;
21980 case GNU_BUILD_ATTRIBUTE_RELRO:
21981 text = _("<relro>");
1d15e434 21982 expected_types = bool_expected;
9ef920e9
NC
21983 ++ name;
21984 break;
21985 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21986 text = _("<stack size>");
1d15e434 21987 expected_types = number_expected;
9ef920e9
NC
21988 ++ name;
21989 break;
21990 case GNU_BUILD_ATTRIBUTE_TOOL:
21991 text = _("<tool>");
1d15e434 21992 expected_types = string_expected;
9ef920e9
NC
21993 ++ name;
21994 break;
21995 case GNU_BUILD_ATTRIBUTE_ABI:
21996 text = _("<ABI>");
21997 expected_types = "$*";
21998 ++ name;
21999 break;
22000 case GNU_BUILD_ATTRIBUTE_PIC:
22001 text = _("<PIC>");
1d15e434 22002 expected_types = number_expected;
9ef920e9
NC
22003 ++ name;
22004 break;
a8be5506
NC
22005 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22006 text = _("<short enum>");
1d15e434 22007 expected_types = bool_expected;
a8be5506
NC
22008 ++ name;
22009 break;
9ef920e9
NC
22010 default:
22011 if (ISPRINT (* name))
22012 {
22013 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22014
22015 if (len > left && ! do_wide)
22016 len = left;
75d7d298 22017 printf ("%.*s:", len, name);
9ef920e9 22018 left -= len;
0dd6ae21 22019 name += len;
9ef920e9
NC
22020 }
22021 else
22022 {
3e6b6445 22023 static char tmpbuf [128];
88305e1b 22024
3e6b6445
NC
22025 error (_("unrecognised byte in name field: %d\n"), * name);
22026 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22027 text = tmpbuf;
22028 name ++;
9ef920e9
NC
22029 }
22030 expected_types = "*$!+";
22031 break;
22032 }
22033
22034 if (text)
88305e1b 22035 left -= printf ("%s", text);
9ef920e9
NC
22036
22037 if (strchr (expected_types, name_type) == NULL)
75d7d298 22038 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22039
26c527e6 22040 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22041 {
26c527e6
AM
22042 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22043 pnote->namesz,
22044 name - pnote->namedata);
015dc7e1 22045 return false;
9ef920e9
NC
22046 }
22047
22048 if (left < 1 && ! do_wide)
015dc7e1 22049 return true;
9ef920e9
NC
22050
22051 switch (name_type)
22052 {
22053 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22054 {
26c527e6
AM
22055 unsigned int bytes;
22056 uint64_t val = 0;
22057 unsigned int shift = 0;
22058 char *decoded = NULL;
ddef72cd 22059
b06b2c92
NC
22060 bytes = pnote->namesz - (name - pnote->namedata);
22061 if (bytes > 0)
22062 /* The -1 is because the name field is always 0 terminated, and we
22063 want to be able to ensure that the shift in the while loop below
22064 will not overflow. */
22065 -- bytes;
22066
ddef72cd
NC
22067 if (bytes > sizeof (val))
22068 {
3e6b6445
NC
22069 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22070 bytes);
22071 bytes = sizeof (val);
ddef72cd 22072 }
3e6b6445
NC
22073 /* We do not bother to warn if bytes == 0 as this can
22074 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22075
22076 while (bytes --)
22077 {
26c527e6 22078 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22079
22080 val |= byte << shift;
9ef920e9
NC
22081 shift += 8;
22082 }
22083
75d7d298 22084 switch (name_attribute)
9ef920e9 22085 {
75d7d298 22086 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22087 switch (val)
22088 {
75d7d298
NC
22089 case 0: decoded = "static"; break;
22090 case 1: decoded = "pic"; break;
22091 case 2: decoded = "PIC"; break;
22092 case 3: decoded = "pie"; break;
22093 case 4: decoded = "PIE"; break;
22094 default: break;
9ef920e9 22095 }
75d7d298
NC
22096 break;
22097 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22098 switch (val)
9ef920e9 22099 {
75d7d298
NC
22100 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22101 case 0: decoded = "off"; break;
22102 case 1: decoded = "on"; break;
22103 case 2: decoded = "all"; break;
22104 case 3: decoded = "strong"; break;
22105 case 4: decoded = "explicit"; break;
22106 default: break;
9ef920e9 22107 }
75d7d298
NC
22108 break;
22109 default:
22110 break;
9ef920e9
NC
22111 }
22112
75d7d298 22113 if (decoded != NULL)
3e6b6445 22114 {
b6ac461a 22115 print_symbol_name (-left, decoded);
3e6b6445
NC
22116 left = 0;
22117 }
22118 else if (val == 0)
22119 {
22120 printf ("0x0");
22121 left -= 3;
22122 }
9ef920e9 22123 else
75d7d298
NC
22124 {
22125 if (do_wide)
26c527e6 22126 left -= printf ("0x%" PRIx64, val);
75d7d298 22127 else
26c527e6 22128 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22129 }
9ef920e9
NC
22130 }
22131 break;
22132 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22133 left -= print_symbol_name (- left, name);
9ef920e9
NC
22134 break;
22135 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22136 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22137 break;
22138 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22139 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22140 break;
22141 }
22142
22143 if (do_wide && left > 0)
22144 printf ("%-*s", left, " ");
9abca702 22145
015dc7e1 22146 return true;
9ef920e9
NC
22147}
22148
2952f10c
SM
22149/* Print the contents of PNOTE as hex. */
22150
22151static void
22152print_note_contents_hex (Elf_Internal_Note *pnote)
22153{
22154 if (pnote->descsz)
22155 {
26c527e6 22156 size_t i;
2952f10c
SM
22157
22158 printf (_(" description data: "));
22159 for (i = 0; i < pnote->descsz; i++)
22160 printf ("%02x ", pnote->descdata[i] & 0xff);
22161 if (!do_wide)
22162 printf ("\n");
22163 }
22164
22165 if (do_wide)
22166 printf ("\n");
22167}
22168
22169#if defined HAVE_MSGPACK
22170
22171static void
22172print_indents (int n)
22173{
22174 printf (" ");
22175
22176 for (int i = 0; i < n; i++)
22177 printf (" ");
22178}
22179
22180/* Print OBJ in human-readable form. */
22181
22182static void
22183dump_msgpack_obj (const msgpack_object *obj, int indent)
22184{
22185 switch (obj->type)
22186 {
22187 case MSGPACK_OBJECT_NIL:
22188 printf ("(nil)");
22189 break;
22190
22191 case MSGPACK_OBJECT_BOOLEAN:
22192 printf ("%s", obj->via.boolean ? "true" : "false");
22193 break;
22194
22195 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22196 printf ("%" PRIu64, obj->via.u64);
22197 break;
22198
22199 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22200 printf ("%" PRIi64, obj->via.i64);
22201 break;
22202
22203 case MSGPACK_OBJECT_FLOAT32:
22204 case MSGPACK_OBJECT_FLOAT64:
22205 printf ("%f", obj->via.f64);
22206 break;
22207
22208 case MSGPACK_OBJECT_STR:
22209 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22210 break;
22211
22212 case MSGPACK_OBJECT_ARRAY:
22213 {
22214 const msgpack_object_array *array = &obj->via.array;
22215
22216 printf ("[\n");
22217 ++indent;
22218
22219 for (uint32_t i = 0; i < array->size; ++i)
22220 {
22221 const msgpack_object *item = &array->ptr[i];
22222
22223 print_indents (indent);
22224 dump_msgpack_obj (item, indent);
22225 printf (",\n");
22226 }
22227
22228 --indent;
22229 print_indents (indent);
22230 printf ("]");
22231 break;
22232 }
22233 break;
22234
22235 case MSGPACK_OBJECT_MAP:
22236 {
22237 const msgpack_object_map *map = &obj->via.map;
22238
22239 printf ("{\n");
22240 ++indent;
22241
22242 for (uint32_t i = 0; i < map->size; ++i)
22243 {
22244 const msgpack_object_kv *kv = &map->ptr[i];
22245 const msgpack_object *key = &kv->key;
22246 const msgpack_object *val = &kv->val;
22247
22248 print_indents (indent);
22249 dump_msgpack_obj (key, indent);
22250 printf (": ");
22251 dump_msgpack_obj (val, indent);
22252
22253 printf (",\n");
22254 }
22255
22256 --indent;
22257 print_indents (indent);
22258 printf ("}");
22259
22260 break;
22261 }
22262
22263 case MSGPACK_OBJECT_BIN:
22264 printf ("(bin)");
22265 break;
22266
22267 case MSGPACK_OBJECT_EXT:
22268 printf ("(ext)");
22269 break;
22270 }
22271}
22272
22273static void
22274dump_msgpack (const msgpack_unpacked *msg)
22275{
22276 print_indents (0);
22277 dump_msgpack_obj (&msg->data, 0);
22278 printf ("\n");
22279}
22280
22281#endif /* defined HAVE_MSGPACK */
22282
22283static bool
22284print_amdgpu_note (Elf_Internal_Note *pnote)
22285{
22286#if defined HAVE_MSGPACK
22287 /* If msgpack is available, decode and dump the note's content. */
22288 bool ret;
22289 msgpack_unpacked msg;
22290 msgpack_unpack_return msgpack_ret;
22291
22292 assert (pnote->type == NT_AMDGPU_METADATA);
22293
22294 msgpack_unpacked_init (&msg);
22295 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22296 NULL);
22297
22298 switch (msgpack_ret)
22299 {
22300 case MSGPACK_UNPACK_SUCCESS:
22301 dump_msgpack (&msg);
22302 ret = true;
22303 break;
22304
22305 default:
22306 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22307 ret = false;
22308 break;
22309 }
22310
22311 msgpack_unpacked_destroy (&msg);
22312 return ret;
22313#else
22314 /* msgpack is not available, dump contents as hex. */
22315 print_note_contents_hex (pnote);
22316 return true;
22317#endif
22318}
22319
e263a66b
CC
22320static bool
22321print_qnx_note (Elf_Internal_Note *pnote)
22322{
22323 switch (pnote->type)
22324 {
22325 case QNT_STACK:
22326 if (pnote->descsz != 12)
22327 goto desc_size_fail;
22328
22329 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22330 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22331 printf (_(" Stack allocated: %" PRIx32 "\n"),
22332 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22333 printf (_(" Executable: %s\n"),
22334 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22335 break;
22336
22337 default:
22338 print_note_contents_hex(pnote);
22339 }
22340 return true;
22341
22342desc_size_fail:
22343 printf (_(" <corrupt - data size is too small>\n"));
22344 error (_("corrupt QNX note: data size is too small\n"));
22345 return false;
22346}
22347
22348
6d118b09
NC
22349/* Note that by the ELF standard, the name field is already null byte
22350 terminated, and namesz includes the terminating null byte.
22351 I.E. the value of namesz for the name "FSF" is 4.
22352
e3c8793a 22353 If the value of namesz is zero, there is no name present. */
9ef920e9 22354
015dc7e1 22355static bool
9ef920e9 22356process_note (Elf_Internal_Note * pnote,
dda8d76d 22357 Filedata * filedata)
779fe533 22358{
2cf0635d
NC
22359 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22360 const char * nt;
9437c45b
JT
22361
22362 if (pnote->namesz == 0)
1ec5cd37
NC
22363 /* If there is no note name, then use the default set of
22364 note type strings. */
dda8d76d 22365 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22366
24d127aa 22367 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22368 /* GNU-specific object file notes. */
22369 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22370
28cdbb18
SM
22371 else if (startswith (pnote->namedata, "AMDGPU"))
22372 /* AMDGPU-specific object file notes. */
22373 nt = get_amdgpu_elf_note_type (pnote->type);
22374
24d127aa 22375 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22376 /* FreeBSD-specific core file notes. */
dda8d76d 22377 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22378
24d127aa 22379 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22380 /* NetBSD-specific core file notes. */
dda8d76d 22381 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22382
24d127aa 22383 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22384 /* NetBSD-specific core file notes. */
22385 return process_netbsd_elf_note (pnote);
22386
24d127aa 22387 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22388 /* NetBSD-specific core file notes. */
22389 return process_netbsd_elf_note (pnote);
22390
98ca73af
FC
22391 else if (startswith (pnote->namedata, "OpenBSD"))
22392 /* OpenBSD-specific core file notes. */
22393 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22394
e263a66b
CC
22395 else if (startswith (pnote->namedata, "QNX"))
22396 /* QNX-specific core file notes. */
22397 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22398
e9b095a5 22399 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22400 {
22401 /* SPU-specific core file notes. */
22402 nt = pnote->namedata + 4;
22403 name = "SPU";
22404 }
22405
24d127aa 22406 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22407 /* VMS/ia64-specific file notes. */
22408 nt = get_ia64_vms_note_type (pnote->type);
22409
24d127aa 22410 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22411 nt = get_stapsdt_note_type (pnote->type);
22412
9437c45b 22413 else
1ec5cd37
NC
22414 /* Don't recognize this note name; just use the default set of
22415 note type strings. */
dda8d76d 22416 nt = get_note_type (filedata, pnote->type);
9437c45b 22417
1449284b 22418 printf (" ");
9ef920e9 22419
24d127aa 22420 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22421 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22422 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22423 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22424 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22425 print_gnu_build_attribute_name (pnote);
22426 else
b6ac461a 22427 print_symbol_name (-20, name);
9ef920e9
NC
22428
22429 if (do_wide)
22430 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22431 else
22432 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22433
24d127aa 22434 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22435 return print_ia64_vms_note (pnote);
24d127aa 22436 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22437 return print_gnu_note (filedata, pnote);
24d127aa 22438 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22439 return print_stapsdt_note (pnote);
24d127aa 22440 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22441 return print_core_note (pnote);
e5382207
LB
22442 else if (startswith (pnote->namedata, "FDO"))
22443 return print_fdo_note (pnote);
24d127aa 22444 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22445 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22446 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22447 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22448 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22449 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22450 else if (startswith (pnote->namedata, "AMDGPU")
22451 && pnote->type == NT_AMDGPU_METADATA)
22452 return print_amdgpu_note (pnote);
e263a66b
CC
22453 else if (startswith (pnote->namedata, "QNX"))
22454 return print_qnx_note (pnote);
779fe533 22455
2952f10c 22456 print_note_contents_hex (pnote);
015dc7e1 22457 return true;
1449284b 22458}
6d118b09 22459
015dc7e1 22460static bool
dda8d76d
NC
22461process_notes_at (Filedata * filedata,
22462 Elf_Internal_Shdr * section,
625d49fc
AM
22463 uint64_t offset,
22464 uint64_t length,
22465 uint64_t align)
779fe533 22466{
015dc7e1
AM
22467 Elf_External_Note *pnotes;
22468 Elf_External_Note *external;
22469 char *end;
22470 bool res = true;
103f02d3 22471
779fe533 22472 if (length <= 0)
015dc7e1 22473 return false;
103f02d3 22474
1449284b
NC
22475 if (section)
22476 {
dda8d76d 22477 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22478 if (pnotes)
32ec8896 22479 {
dda8d76d 22480 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22481 {
22482 free (pnotes);
015dc7e1 22483 return false;
f761cb13 22484 }
32ec8896 22485 }
1449284b
NC
22486 }
22487 else
82ed9683 22488 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22489 _("notes"));
4dff97b2 22490
dd24e3da 22491 if (pnotes == NULL)
015dc7e1 22492 return false;
779fe533 22493
103f02d3 22494 external = pnotes;
103f02d3 22495
ca0e11aa
NC
22496 if (filedata->is_separate)
22497 printf (_("In linked file '%s': "), filedata->file_name);
22498 else
22499 printf ("\n");
1449284b 22500 if (section)
ca0e11aa 22501 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22502 else
26c527e6
AM
22503 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22504 " with length 0x%08" PRIx64 ":\n"),
22505 offset, length);
1449284b 22506
82ed9683
L
22507 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22508 specifies that notes should be aligned to 4 bytes in 32-bit
22509 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22510 we also support 4 byte alignment in 64-bit objects. If section
22511 alignment is less than 4, we treate alignment as 4 bytes. */
22512 if (align < 4)
22513 align = 4;
22514 else if (align != 4 && align != 8)
22515 {
26c527e6
AM
22516 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22517 align);
a788aedd 22518 free (pnotes);
015dc7e1 22519 return false;
82ed9683
L
22520 }
22521
dbe15e4e 22522 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22523
c8071705
NC
22524 end = (char *) pnotes + length;
22525 while ((char *) external < end)
779fe533 22526 {
b34976b6 22527 Elf_Internal_Note inote;
15b42fb0 22528 size_t min_notesz;
4dff97b2 22529 char * next;
2cf0635d 22530 char * temp = NULL;
c8071705 22531 size_t data_remaining = end - (char *) external;
6d118b09 22532
dda8d76d 22533 if (!is_ia64_vms (filedata))
15b42fb0 22534 {
9dd3a467
NC
22535 /* PR binutils/15191
22536 Make sure that there is enough data to read. */
15b42fb0
AM
22537 min_notesz = offsetof (Elf_External_Note, name);
22538 if (data_remaining < min_notesz)
9dd3a467 22539 {
26c527e6 22540 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22541 "not enough for a full note\n",
26c527e6 22542 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22543 "not enough for a full note\n",
22544 data_remaining),
26c527e6 22545 data_remaining);
9dd3a467
NC
22546 break;
22547 }
5396a86e
AM
22548 data_remaining -= min_notesz;
22549
15b42fb0
AM
22550 inote.type = BYTE_GET (external->type);
22551 inote.namesz = BYTE_GET (external->namesz);
22552 inote.namedata = external->name;
22553 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22554 inote.descdata = ((char *) external
4dff97b2 22555 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22556 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22557 next = ((char *) external
4dff97b2 22558 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22559 }
00e98fc7 22560 else
15b42fb0
AM
22561 {
22562 Elf64_External_VMS_Note *vms_external;
00e98fc7 22563
9dd3a467
NC
22564 /* PR binutils/15191
22565 Make sure that there is enough data to read. */
15b42fb0
AM
22566 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22567 if (data_remaining < min_notesz)
9dd3a467 22568 {
26c527e6 22569 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22570 "not enough for a full note\n",
26c527e6 22571 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22572 "not enough for a full note\n",
22573 data_remaining),
26c527e6 22574 data_remaining);
9dd3a467
NC
22575 break;
22576 }
5396a86e 22577 data_remaining -= min_notesz;
3e55a963 22578
15b42fb0
AM
22579 vms_external = (Elf64_External_VMS_Note *) external;
22580 inote.type = BYTE_GET (vms_external->type);
22581 inote.namesz = BYTE_GET (vms_external->namesz);
22582 inote.namedata = vms_external->name;
22583 inote.descsz = BYTE_GET (vms_external->descsz);
22584 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22585 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22586 next = inote.descdata + align_power (inote.descsz, 3);
22587 }
22588
5396a86e
AM
22589 /* PR 17531: file: 3443835e. */
22590 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22591 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22592 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22593 || (size_t) (next - inote.descdata) < inote.descsz
22594 || ((size_t) (next - inote.descdata)
22595 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22596 {
26c527e6
AM
22597 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22598 (char *) external - (char *) pnotes);
22599 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22600 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22601 break;
22602 }
22603
15b42fb0 22604 external = (Elf_External_Note *) next;
dd24e3da 22605
6d118b09
NC
22606 /* Verify that name is null terminated. It appears that at least
22607 one version of Linux (RedHat 6.0) generates corefiles that don't
22608 comply with the ELF spec by failing to include the null byte in
22609 namesz. */
18344509 22610 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22611 {
5396a86e 22612 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22613 {
5396a86e
AM
22614 temp = (char *) malloc (inote.namesz + 1);
22615 if (temp == NULL)
22616 {
22617 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22618 res = false;
5396a86e
AM
22619 break;
22620 }
76da6bbe 22621
5396a86e
AM
22622 memcpy (temp, inote.namedata, inote.namesz);
22623 inote.namedata = temp;
22624 }
22625 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22626 }
22627
dda8d76d 22628 if (! process_note (& inote, filedata))
015dc7e1 22629 res = false;
103f02d3 22630
9db70fc3
AM
22631 free (temp);
22632 temp = NULL;
779fe533
NC
22633 }
22634
22635 free (pnotes);
103f02d3 22636
779fe533
NC
22637 return res;
22638}
22639
015dc7e1 22640static bool
dda8d76d 22641process_corefile_note_segments (Filedata * filedata)
779fe533 22642{
015dc7e1 22643 Elf_Internal_Phdr *segment;
b34976b6 22644 unsigned int i;
015dc7e1 22645 bool res = true;
103f02d3 22646
dda8d76d 22647 if (! get_program_headers (filedata))
015dc7e1 22648 return true;
103f02d3 22649
dda8d76d
NC
22650 for (i = 0, segment = filedata->program_headers;
22651 i < filedata->file_header.e_phnum;
b34976b6 22652 i++, segment++)
779fe533
NC
22653 {
22654 if (segment->p_type == PT_NOTE)
625d49fc
AM
22655 if (! process_notes_at (filedata, NULL, segment->p_offset,
22656 segment->p_filesz, segment->p_align))
015dc7e1 22657 res = false;
779fe533 22658 }
103f02d3 22659
779fe533
NC
22660 return res;
22661}
22662
015dc7e1 22663static bool
625d49fc 22664process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22665{
22666 Elf_External_Note * pnotes;
22667 Elf_External_Note * external;
c8071705 22668 char * end;
015dc7e1 22669 bool res = true;
685080f2
NC
22670
22671 if (length <= 0)
015dc7e1 22672 return false;
685080f2 22673
dda8d76d 22674 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22675 _("v850 notes"));
22676 if (pnotes == NULL)
015dc7e1 22677 return false;
685080f2
NC
22678
22679 external = pnotes;
c8071705 22680 end = (char*) pnotes + length;
685080f2 22681
26c527e6
AM
22682 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22683 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22684 offset, length);
685080f2 22685
c8071705 22686 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22687 {
22688 Elf_External_Note * next;
22689 Elf_Internal_Note inote;
22690
22691 inote.type = BYTE_GET (external->type);
22692 inote.namesz = BYTE_GET (external->namesz);
22693 inote.namedata = external->name;
22694 inote.descsz = BYTE_GET (external->descsz);
22695 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22696 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22697
c8071705
NC
22698 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22699 {
22700 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22701 inote.descdata = inote.namedata;
22702 inote.namesz = 0;
22703 }
22704
685080f2
NC
22705 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22706
c8071705 22707 if ( ((char *) next > end)
685080f2
NC
22708 || ((char *) next < (char *) pnotes))
22709 {
26c527e6
AM
22710 warn (_("corrupt descsz found in note at offset %#tx\n"),
22711 (char *) external - (char *) pnotes);
22712 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22713 inote.type, inote.namesz, inote.descsz);
22714 break;
22715 }
22716
22717 external = next;
22718
22719 /* Prevent out-of-bounds indexing. */
c8071705 22720 if ( inote.namedata + inote.namesz > end
685080f2
NC
22721 || inote.namedata + inote.namesz < inote.namedata)
22722 {
26c527e6
AM
22723 warn (_("corrupt namesz found in note at offset %#zx\n"),
22724 (char *) external - (char *) pnotes);
22725 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22726 inote.type, inote.namesz, inote.descsz);
22727 break;
22728 }
22729
22730 printf (" %s: ", get_v850_elf_note_type (inote.type));
22731
22732 if (! print_v850_note (& inote))
22733 {
015dc7e1 22734 res = false;
26c527e6 22735 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22736 inote.namesz, inote.descsz);
22737 }
22738 }
22739
22740 free (pnotes);
22741
22742 return res;
22743}
22744
015dc7e1 22745static bool
dda8d76d 22746process_note_sections (Filedata * filedata)
1ec5cd37 22747{
015dc7e1 22748 Elf_Internal_Shdr *section;
26c527e6 22749 size_t i;
32ec8896 22750 unsigned int n = 0;
015dc7e1 22751 bool res = true;
1ec5cd37 22752
dda8d76d
NC
22753 for (i = 0, section = filedata->section_headers;
22754 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22755 i++, section++)
685080f2
NC
22756 {
22757 if (section->sh_type == SHT_NOTE)
22758 {
625d49fc
AM
22759 if (! process_notes_at (filedata, section, section->sh_offset,
22760 section->sh_size, section->sh_addralign))
015dc7e1 22761 res = false;
685080f2
NC
22762 n++;
22763 }
22764
dda8d76d
NC
22765 if (( filedata->file_header.e_machine == EM_V800
22766 || filedata->file_header.e_machine == EM_V850
22767 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22768 && section->sh_type == SHT_RENESAS_INFO)
22769 {
625d49fc
AM
22770 if (! process_v850_notes (filedata, section->sh_offset,
22771 section->sh_size))
015dc7e1 22772 res = false;
685080f2
NC
22773 n++;
22774 }
22775 }
df565f32
NC
22776
22777 if (n == 0)
22778 /* Try processing NOTE segments instead. */
dda8d76d 22779 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22780
22781 return res;
22782}
22783
015dc7e1 22784static bool
dda8d76d 22785process_notes (Filedata * filedata)
779fe533
NC
22786{
22787 /* If we have not been asked to display the notes then do nothing. */
22788 if (! do_notes)
015dc7e1 22789 return true;
103f02d3 22790
dda8d76d
NC
22791 if (filedata->file_header.e_type != ET_CORE)
22792 return process_note_sections (filedata);
103f02d3 22793
779fe533 22794 /* No program headers means no NOTE segment. */
dda8d76d
NC
22795 if (filedata->file_header.e_phnum > 0)
22796 return process_corefile_note_segments (filedata);
779fe533 22797
ca0e11aa
NC
22798 if (filedata->is_separate)
22799 printf (_("No notes found in linked file '%s'.\n"),
22800 filedata->file_name);
22801 else
22802 printf (_("No notes found file.\n"));
22803
015dc7e1 22804 return true;
779fe533
NC
22805}
22806
60abdbed
NC
22807static unsigned char *
22808display_public_gnu_attributes (unsigned char * start,
22809 const unsigned char * const end)
22810{
22811 printf (_(" Unknown GNU attribute: %s\n"), start);
22812
22813 start += strnlen ((char *) start, end - start);
22814 display_raw_attribute (start, end);
22815
22816 return (unsigned char *) end;
22817}
22818
22819static unsigned char *
22820display_generic_attribute (unsigned char * start,
22821 unsigned int tag,
22822 const unsigned char * const end)
22823{
22824 if (tag == 0)
22825 return (unsigned char *) end;
22826
22827 return display_tag_value (tag, start, end);
22828}
22829
015dc7e1 22830static bool
dda8d76d 22831process_arch_specific (Filedata * filedata)
252b5132 22832{
a952a375 22833 if (! do_arch)
015dc7e1 22834 return true;
a952a375 22835
dda8d76d 22836 switch (filedata->file_header.e_machine)
252b5132 22837 {
53a346d8
CZ
22838 case EM_ARC:
22839 case EM_ARC_COMPACT:
22840 case EM_ARC_COMPACT2:
b5c37946
SJ
22841 case EM_ARC_COMPACT3:
22842 case EM_ARC_COMPACT3_64:
dda8d76d 22843 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22844 display_arc_attribute,
22845 display_generic_attribute);
11c1ff18 22846 case EM_ARM:
dda8d76d 22847 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22848 display_arm_attribute,
22849 display_generic_attribute);
22850
252b5132 22851 case EM_MIPS:
4fe85591 22852 case EM_MIPS_RS3_LE:
dda8d76d 22853 return process_mips_specific (filedata);
60abdbed
NC
22854
22855 case EM_MSP430:
dda8d76d 22856 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22857 display_msp430_attribute,
c0ea7c52 22858 display_msp430_gnu_attribute);
60abdbed 22859
2dc8dd17
JW
22860 case EM_RISCV:
22861 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22862 display_riscv_attribute,
22863 display_generic_attribute);
22864
35c08157 22865 case EM_NDS32:
dda8d76d 22866 return process_nds32_specific (filedata);
60abdbed 22867
85f7484a
PB
22868 case EM_68K:
22869 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22870 display_m68k_gnu_attribute);
22871
34c8bcba 22872 case EM_PPC:
b82317dd 22873 case EM_PPC64:
dda8d76d 22874 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22875 display_power_gnu_attribute);
22876
643f7afb
AK
22877 case EM_S390:
22878 case EM_S390_OLD:
dda8d76d 22879 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22880 display_s390_gnu_attribute);
22881
9e8c70f9
DM
22882 case EM_SPARC:
22883 case EM_SPARC32PLUS:
22884 case EM_SPARCV9:
dda8d76d 22885 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22886 display_sparc_gnu_attribute);
22887
59e6276b 22888 case EM_TI_C6000:
dda8d76d 22889 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22890 display_tic6x_attribute,
22891 display_generic_attribute);
22892
0861f561
CQ
22893 case EM_CSKY:
22894 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22895 display_csky_attribute, NULL);
22896
252b5132 22897 default:
dda8d76d 22898 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22899 display_public_gnu_attributes,
22900 display_generic_attribute);
252b5132 22901 }
252b5132
RH
22902}
22903
015dc7e1 22904static bool
dda8d76d 22905get_file_header (Filedata * filedata)
252b5132 22906{
9ea033b2 22907 /* Read in the identity array. */
dda8d76d 22908 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22909 return false;
252b5132 22910
9ea033b2 22911 /* Determine how to read the rest of the header. */
dda8d76d 22912 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22913 {
1a0670f3
AM
22914 default:
22915 case ELFDATANONE:
adab8cdc
AO
22916 case ELFDATA2LSB:
22917 byte_get = byte_get_little_endian;
22918 byte_put = byte_put_little_endian;
22919 break;
22920 case ELFDATA2MSB:
22921 byte_get = byte_get_big_endian;
22922 byte_put = byte_put_big_endian;
22923 break;
9ea033b2
NC
22924 }
22925
22926 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22927 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22928
22929 /* Read in the rest of the header. */
22930 if (is_32bit_elf)
22931 {
22932 Elf32_External_Ehdr ehdr32;
252b5132 22933
dda8d76d 22934 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22935 return false;
103f02d3 22936
dda8d76d
NC
22937 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22938 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22939 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22940 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22941 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22942 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22943 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22944 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22945 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22946 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22947 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22948 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22949 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22950 }
252b5132 22951 else
9ea033b2
NC
22952 {
22953 Elf64_External_Ehdr ehdr64;
a952a375 22954
dda8d76d 22955 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22956 return false;
103f02d3 22957
dda8d76d
NC
22958 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22959 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22960 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22961 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22962 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22963 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22964 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22965 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22966 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22967 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22968 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22969 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22970 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22971 }
252b5132 22972
015dc7e1 22973 return true;
252b5132
RH
22974}
22975
13acb58d
AM
22976static void
22977free_filedata (Filedata *filedata)
22978{
22979 free (filedata->program_interpreter);
13acb58d 22980 free (filedata->program_headers);
13acb58d 22981 free (filedata->section_headers);
13acb58d 22982 free (filedata->string_table);
13acb58d 22983 free (filedata->dump.dump_sects);
13acb58d 22984 free (filedata->dynamic_strings);
13acb58d 22985 free (filedata->dynamic_symbols);
13acb58d 22986 free (filedata->dynamic_syminfo);
13acb58d 22987 free (filedata->dynamic_section);
13acb58d
AM
22988
22989 while (filedata->symtab_shndx_list != NULL)
22990 {
22991 elf_section_list *next = filedata->symtab_shndx_list->next;
22992 free (filedata->symtab_shndx_list);
22993 filedata->symtab_shndx_list = next;
22994 }
22995
22996 free (filedata->section_headers_groups);
13acb58d
AM
22997
22998 if (filedata->section_groups)
22999 {
23000 size_t i;
23001 struct group_list * g;
23002 struct group_list * next;
23003
23004 for (i = 0; i < filedata->group_count; i++)
23005 {
23006 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23007 {
23008 next = g->next;
23009 free (g);
23010 }
23011 }
23012
23013 free (filedata->section_groups);
13acb58d 23014 }
066f8fbe
AM
23015 memset (&filedata->section_headers, 0,
23016 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
23017}
23018
dda8d76d
NC
23019static void
23020close_file (Filedata * filedata)
23021{
23022 if (filedata)
23023 {
23024 if (filedata->handle)
23025 fclose (filedata->handle);
23026 free (filedata);
23027 }
23028}
23029
23030void
23031close_debug_file (void * data)
23032{
13acb58d 23033 free_filedata ((Filedata *) data);
dda8d76d
NC
23034 close_file ((Filedata *) data);
23035}
23036
23037static Filedata *
015dc7e1 23038open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23039{
23040 struct stat statbuf;
23041 Filedata * filedata = NULL;
23042
23043 if (stat (pathname, & statbuf) < 0
23044 || ! S_ISREG (statbuf.st_mode))
23045 goto fail;
23046
23047 filedata = calloc (1, sizeof * filedata);
23048 if (filedata == NULL)
23049 goto fail;
23050
23051 filedata->handle = fopen (pathname, "rb");
23052 if (filedata->handle == NULL)
23053 goto fail;
23054
be7d229a 23055 filedata->file_size = statbuf.st_size;
dda8d76d 23056 filedata->file_name = pathname;
ca0e11aa 23057 filedata->is_separate = is_separate;
dda8d76d
NC
23058
23059 if (! get_file_header (filedata))
23060 goto fail;
23061
4de91c10
AM
23062 if (!get_section_headers (filedata, false))
23063 goto fail;
dda8d76d
NC
23064
23065 return filedata;
23066
23067 fail:
23068 if (filedata)
23069 {
23070 if (filedata->handle)
23071 fclose (filedata->handle);
23072 free (filedata);
23073 }
23074 return NULL;
23075}
23076
23077void *
23078open_debug_file (const char * pathname)
23079{
015dc7e1 23080 return open_file (pathname, true);
dda8d76d
NC
23081}
23082
835f2fae
NC
23083static void
23084initialise_dump_sects (Filedata * filedata)
23085{
23086 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23087 Note we do this even if cmdline_dump_sects is empty because we
23088 must make sure that the dump_sets array is zeroed out before each
23089 object file is processed. */
23090 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23091 memset (filedata->dump.dump_sects, 0,
23092 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23093
23094 if (cmdline.num_dump_sects > 0)
23095 {
23096 if (filedata->dump.num_dump_sects == 0)
23097 /* A sneaky way of allocating the dump_sects array. */
23098 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23099
23100 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23101 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23102 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23103 }
23104}
23105
94585d6d
NC
23106static bool
23107might_need_separate_debug_info (Filedata * filedata)
23108{
23109 /* Debuginfo files do not need further separate file loading. */
23110 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23111 return false;
23112
23113 /* Since do_follow_links might be enabled by default, only treat it as an
23114 indication that separate files should be loaded if setting it was a
23115 deliberate user action. */
23116 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23117 return true;
23118
23119 if (process_links || do_syms || do_unwind
23120 || dump_any_debugging || do_dump || do_debugging)
23121 return true;
23122
23123 return false;
23124}
23125
fb52b2f4
NC
23126/* Process one ELF object file according to the command line options.
23127 This file may actually be stored in an archive. The file is
32ec8896
NC
23128 positioned at the start of the ELF object. Returns TRUE if no
23129 problems were encountered, FALSE otherwise. */
fb52b2f4 23130
015dc7e1 23131static bool
dda8d76d 23132process_object (Filedata * filedata)
252b5132 23133{
015dc7e1 23134 bool have_separate_files;
252b5132 23135 unsigned int i;
015dc7e1 23136 bool res;
252b5132 23137
dda8d76d 23138 if (! get_file_header (filedata))
252b5132 23139 {
dda8d76d 23140 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23141 return false;
252b5132
RH
23142 }
23143
23144 /* Initialise per file variables. */
978c4450
AM
23145 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23146 filedata->version_info[i] = 0;
252b5132 23147
978c4450
AM
23148 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23149 filedata->dynamic_info[i] = 0;
23150 filedata->dynamic_info_DT_GNU_HASH = 0;
23151 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23152
23153 /* Process the file. */
23154 if (show_name)
dda8d76d 23155 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23156
835f2fae 23157 initialise_dump_sects (filedata);
d70c5fc7 23158
4de91c10
AM
23159 /* There may be some extensions in the first section header. Don't
23160 bomb if we can't read it. */
23161 get_section_headers (filedata, true);
23162
dda8d76d 23163 if (! process_file_header (filedata))
4de91c10
AM
23164 {
23165 res = false;
23166 goto out;
23167 }
252b5132 23168
e331b18d
AM
23169 /* Throw away the single section header read above, so that we
23170 re-read the entire set. */
23171 free (filedata->section_headers);
23172 filedata->section_headers = NULL;
23173
dda8d76d 23174 if (! process_section_headers (filedata))
2f62977e 23175 {
32ec8896 23176 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23177 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23178
2f62977e 23179 if (! do_using_dynamic)
015dc7e1 23180 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23181 }
252b5132 23182
dda8d76d 23183 if (! process_section_groups (filedata))
32ec8896 23184 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23185 do_unwind = false;
d1f5c6e3 23186
93df3340
AM
23187 process_program_headers (filedata);
23188
23189 res = process_dynamic_section (filedata);
252b5132 23190
dda8d76d 23191 if (! process_relocs (filedata))
015dc7e1 23192 res = false;
252b5132 23193
dda8d76d 23194 if (! process_unwind (filedata))
015dc7e1 23195 res = false;
4d6ed7c8 23196
dda8d76d 23197 if (! process_symbol_table (filedata))
015dc7e1 23198 res = false;
252b5132 23199
0f03783c 23200 if (! process_lto_symbol_tables (filedata))
015dc7e1 23201 res = false;
b9e920ec 23202
dda8d76d 23203 if (! process_syminfo (filedata))
015dc7e1 23204 res = false;
252b5132 23205
dda8d76d 23206 if (! process_version_sections (filedata))
015dc7e1 23207 res = false;
252b5132 23208
94585d6d 23209 if (might_need_separate_debug_info (filedata))
24841daa 23210 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23211 else
015dc7e1 23212 have_separate_files = false;
dda8d76d
NC
23213
23214 if (! process_section_contents (filedata))
015dc7e1 23215 res = false;
f5842774 23216
24841daa 23217 if (have_separate_files)
dda8d76d 23218 {
24841daa
NC
23219 separate_info * d;
23220
23221 for (d = first_separate_info; d != NULL; d = d->next)
23222 {
835f2fae
NC
23223 initialise_dump_sects (d->handle);
23224
ca0e11aa 23225 if (process_links && ! process_file_header (d->handle))
015dc7e1 23226 res = false;
ca0e11aa 23227 else if (! process_section_headers (d->handle))
015dc7e1 23228 res = false;
d6bfbc39 23229 else if (! process_section_contents (d->handle))
015dc7e1 23230 res = false;
ca0e11aa
NC
23231 else if (process_links)
23232 {
ca0e11aa 23233 if (! process_section_groups (d->handle))
015dc7e1 23234 res = false;
93df3340 23235 process_program_headers (d->handle);
ca0e11aa 23236 if (! process_dynamic_section (d->handle))
015dc7e1 23237 res = false;
ca0e11aa 23238 if (! process_relocs (d->handle))
015dc7e1 23239 res = false;
ca0e11aa 23240 if (! process_unwind (d->handle))
015dc7e1 23241 res = false;
ca0e11aa 23242 if (! process_symbol_table (d->handle))
015dc7e1 23243 res = false;
ca0e11aa 23244 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23245 res = false;
ca0e11aa 23246 if (! process_syminfo (d->handle))
015dc7e1 23247 res = false;
ca0e11aa 23248 if (! process_version_sections (d->handle))
015dc7e1 23249 res = false;
ca0e11aa 23250 if (! process_notes (d->handle))
015dc7e1 23251 res = false;
ca0e11aa 23252 }
24841daa
NC
23253 }
23254
23255 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23256 }
23257
23258 if (! process_notes (filedata))
015dc7e1 23259 res = false;
103f02d3 23260
dda8d76d 23261 if (! process_gnu_liblist (filedata))
015dc7e1 23262 res = false;
047b2264 23263
dda8d76d 23264 if (! process_arch_specific (filedata))
015dc7e1 23265 res = false;
252b5132 23266
4de91c10 23267 out:
13acb58d 23268 free_filedata (filedata);
e4b17d5c 23269
19e6b90e 23270 free_debug_memory ();
18bd398b 23271
32ec8896 23272 return res;
252b5132
RH
23273}
23274
2cf0635d 23275/* Process an ELF archive.
32ec8896
NC
23276 On entry the file is positioned just after the ARMAG string.
23277 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23278
015dc7e1
AM
23279static bool
23280process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23281{
23282 struct archive_info arch;
23283 struct archive_info nested_arch;
23284 size_t got;
015dc7e1 23285 bool ret = true;
2cf0635d 23286
015dc7e1 23287 show_name = true;
2cf0635d
NC
23288
23289 /* The ARCH structure is used to hold information about this archive. */
23290 arch.file_name = NULL;
23291 arch.file = NULL;
23292 arch.index_array = NULL;
23293 arch.sym_table = NULL;
23294 arch.longnames = NULL;
23295
23296 /* The NESTED_ARCH structure is used as a single-item cache of information
23297 about a nested archive (when members of a thin archive reside within
23298 another regular archive file). */
23299 nested_arch.file_name = NULL;
23300 nested_arch.file = NULL;
23301 nested_arch.index_array = NULL;
23302 nested_arch.sym_table = NULL;
23303 nested_arch.longnames = NULL;
23304
dda8d76d 23305 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23306 filedata->file_size, is_thin_archive,
23307 do_archive_index) != 0)
2cf0635d 23308 {
015dc7e1 23309 ret = false;
2cf0635d 23310 goto out;
4145f1d5 23311 }
fb52b2f4 23312
4145f1d5
NC
23313 if (do_archive_index)
23314 {
2cf0635d 23315 if (arch.sym_table == NULL)
1cb7d8b1
AM
23316 error (_("%s: unable to dump the index as none was found\n"),
23317 filedata->file_name);
4145f1d5
NC
23318 else
23319 {
26c527e6
AM
23320 uint64_t i, l;
23321 uint64_t current_pos;
4145f1d5 23322
26c527e6
AM
23323 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23324 " %#" PRIx64 " bytes in the symbol table)\n"),
23325 filedata->file_name, arch.index_num,
1cb7d8b1 23326 arch.sym_size);
dda8d76d
NC
23327
23328 current_pos = ftell (filedata->handle);
4145f1d5 23329
2cf0635d 23330 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23331 {
1cb7d8b1
AM
23332 if (i == 0
23333 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23334 {
23335 char * member_name
23336 = get_archive_member_name_at (&arch, arch.index_array[i],
23337 &nested_arch);
2cf0635d 23338
1cb7d8b1
AM
23339 if (member_name != NULL)
23340 {
23341 char * qualified_name
23342 = make_qualified_name (&arch, &nested_arch,
23343 member_name);
2cf0635d 23344
1cb7d8b1
AM
23345 if (qualified_name != NULL)
23346 {
23347 printf (_("Contents of binary %s at offset "),
23348 qualified_name);
c2a7d3f5
NC
23349 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23350 putchar ('\n');
1cb7d8b1
AM
23351 free (qualified_name);
23352 }
fd486f32 23353 free (member_name);
4145f1d5
NC
23354 }
23355 }
2cf0635d
NC
23356
23357 if (l >= arch.sym_size)
4145f1d5 23358 {
1cb7d8b1
AM
23359 error (_("%s: end of the symbol table reached "
23360 "before the end of the index\n"),
dda8d76d 23361 filedata->file_name);
015dc7e1 23362 ret = false;
cb8f3167 23363 break;
4145f1d5 23364 }
591f7597 23365 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23366 printf ("\t%.*s\n",
23367 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23368 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23369 }
23370
67ce483b 23371 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23372 l = (l + 7) & ~ 7;
23373 else
23374 l += l & 1;
23375
2cf0635d 23376 if (l < arch.sym_size)
32ec8896 23377 {
26c527e6 23378 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23379 "but without corresponding entries in "
23380 "the index table\n",
26c527e6 23381 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23382 "but without corresponding entries in "
23383 "the index table\n",
23384 arch.sym_size - l),
dda8d76d 23385 filedata->file_name, arch.sym_size - l);
015dc7e1 23386 ret = false;
32ec8896 23387 }
4145f1d5 23388
63cf857e 23389 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23390 {
1cb7d8b1
AM
23391 error (_("%s: failed to seek back to start of object files "
23392 "in the archive\n"),
dda8d76d 23393 filedata->file_name);
015dc7e1 23394 ret = false;
2cf0635d 23395 goto out;
4145f1d5 23396 }
fb52b2f4 23397 }
4145f1d5
NC
23398
23399 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23400 && !do_segments && !do_header && !do_dump && !do_version
23401 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23402 && !do_section_groups && !do_dyn_syms)
2cf0635d 23403 {
015dc7e1 23404 ret = true; /* Archive index only. */
2cf0635d
NC
23405 goto out;
23406 }
fb52b2f4
NC
23407 }
23408
fb52b2f4
NC
23409 while (1)
23410 {
2cf0635d
NC
23411 char * name;
23412 size_t namelen;
23413 char * qualified_name;
23414
23415 /* Read the next archive header. */
63cf857e 23416 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23417 {
23418 error (_("%s: failed to seek to next archive header\n"),
23419 arch.file_name);
015dc7e1 23420 ret = false;
1cb7d8b1
AM
23421 break;
23422 }
dda8d76d 23423 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23424 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23425 {
23426 if (got == 0)
2cf0635d 23427 break;
28e817cc
NC
23428 /* PR 24049 - we cannot use filedata->file_name as this will
23429 have already been freed. */
23430 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23431
015dc7e1 23432 ret = false;
1cb7d8b1
AM
23433 break;
23434 }
2cf0635d 23435 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23436 {
23437 error (_("%s: did not find a valid archive header\n"),
23438 arch.file_name);
015dc7e1 23439 ret = false;
1cb7d8b1
AM
23440 break;
23441 }
2cf0635d
NC
23442
23443 arch.next_arhdr_offset += sizeof arch.arhdr;
23444
978c4450 23445 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23446
23447 name = get_archive_member_name (&arch, &nested_arch);
23448 if (name == NULL)
fb52b2f4 23449 {
28e817cc 23450 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23451 ret = false;
d989285c 23452 break;
fb52b2f4 23453 }
2cf0635d 23454 namelen = strlen (name);
fb52b2f4 23455
2cf0635d
NC
23456 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23457 if (qualified_name == NULL)
fb52b2f4 23458 {
28e817cc 23459 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23460 free (name);
015dc7e1 23461 ret = false;
d989285c 23462 break;
fb52b2f4
NC
23463 }
23464
2cf0635d 23465 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23466 {
23467 /* This is a proxy for an external member of a thin archive. */
23468 Filedata * member_filedata;
23469 char * member_file_name = adjust_relative_path
dda8d76d 23470 (filedata->file_name, name, namelen);
32ec8896 23471
fd486f32 23472 free (name);
1cb7d8b1
AM
23473 if (member_file_name == NULL)
23474 {
fd486f32 23475 free (qualified_name);
015dc7e1 23476 ret = false;
1cb7d8b1
AM
23477 break;
23478 }
2cf0635d 23479
015dc7e1 23480 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23481 if (member_filedata == NULL)
23482 {
23483 error (_("Input file '%s' is not readable.\n"), member_file_name);
23484 free (member_file_name);
fd486f32 23485 free (qualified_name);
015dc7e1 23486 ret = false;
1cb7d8b1
AM
23487 break;
23488 }
2cf0635d 23489
978c4450 23490 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23491 member_filedata->file_name = qualified_name;
2cf0635d 23492
75a2da57
AH
23493 /* The call to process_object() expects the file to be at the beginning. */
23494 rewind (member_filedata->handle);
23495
1cb7d8b1 23496 if (! process_object (member_filedata))
015dc7e1 23497 ret = false;
2cf0635d 23498
1cb7d8b1
AM
23499 close_file (member_filedata);
23500 free (member_file_name);
1cb7d8b1 23501 }
2cf0635d 23502 else if (is_thin_archive)
1cb7d8b1
AM
23503 {
23504 Filedata thin_filedata;
eb02c04d 23505
1cb7d8b1 23506 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23507
a043396b
NC
23508 /* PR 15140: Allow for corrupt thin archives. */
23509 if (nested_arch.file == NULL)
23510 {
23511 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23512 qualified_name, name);
fd486f32
AM
23513 free (qualified_name);
23514 free (name);
015dc7e1 23515 ret = false;
a043396b
NC
23516 break;
23517 }
fd486f32 23518 free (name);
a043396b 23519
1cb7d8b1 23520 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23521 filedata->archive_file_offset
23522 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23523
1cb7d8b1
AM
23524 /* The nested archive file will have been opened and setup by
23525 get_archive_member_name. */
63cf857e
AM
23526 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23527 SEEK_SET) != 0)
1cb7d8b1
AM
23528 {
23529 error (_("%s: failed to seek to archive member.\n"),
23530 nested_arch.file_name);
fd486f32 23531 free (qualified_name);
015dc7e1 23532 ret = false;
1cb7d8b1
AM
23533 break;
23534 }
2cf0635d 23535
dda8d76d
NC
23536 thin_filedata.handle = nested_arch.file;
23537 thin_filedata.file_name = qualified_name;
9abca702 23538
1cb7d8b1 23539 if (! process_object (& thin_filedata))
015dc7e1 23540 ret = false;
1cb7d8b1 23541 }
2cf0635d 23542 else
1cb7d8b1 23543 {
fd486f32 23544 free (name);
978c4450 23545 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23546 filedata->file_name = qualified_name;
1cb7d8b1 23547 if (! process_object (filedata))
015dc7e1 23548 ret = false;
237877b8 23549 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23550 /* Stop looping with "negative" archive_file_size. */
978c4450 23551 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23552 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23553 }
fb52b2f4 23554
2cf0635d 23555 free (qualified_name);
fb52b2f4
NC
23556 }
23557
4145f1d5 23558 out:
2cf0635d
NC
23559 if (nested_arch.file != NULL)
23560 fclose (nested_arch.file);
23561 release_archive (&nested_arch);
23562 release_archive (&arch);
fb52b2f4 23563
d989285c 23564 return ret;
fb52b2f4
NC
23565}
23566
015dc7e1 23567static bool
2cf0635d 23568process_file (char * file_name)
fb52b2f4 23569{
dda8d76d 23570 Filedata * filedata = NULL;
fb52b2f4
NC
23571 struct stat statbuf;
23572 char armag[SARMAG];
015dc7e1 23573 bool ret = true;
fb52b2f4
NC
23574
23575 if (stat (file_name, &statbuf) < 0)
23576 {
f24ddbdd
NC
23577 if (errno == ENOENT)
23578 error (_("'%s': No such file\n"), file_name);
23579 else
23580 error (_("Could not locate '%s'. System error message: %s\n"),
23581 file_name, strerror (errno));
015dc7e1 23582 return false;
f24ddbdd
NC
23583 }
23584
23585 if (! S_ISREG (statbuf.st_mode))
23586 {
23587 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23588 return false;
fb52b2f4
NC
23589 }
23590
dda8d76d
NC
23591 filedata = calloc (1, sizeof * filedata);
23592 if (filedata == NULL)
23593 {
23594 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23595 return false;
dda8d76d
NC
23596 }
23597
23598 filedata->file_name = file_name;
23599 filedata->handle = fopen (file_name, "rb");
23600 if (filedata->handle == NULL)
fb52b2f4 23601 {
f24ddbdd 23602 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23603 free (filedata);
015dc7e1 23604 return false;
fb52b2f4
NC
23605 }
23606
dda8d76d 23607 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23608 {
4145f1d5 23609 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23610 fclose (filedata->handle);
23611 free (filedata);
015dc7e1 23612 return false;
fb52b2f4
NC
23613 }
23614
be7d229a 23615 filedata->file_size = statbuf.st_size;
015dc7e1 23616 filedata->is_separate = false;
f54498b4 23617
fb52b2f4 23618 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23619 {
015dc7e1
AM
23620 if (! process_archive (filedata, false))
23621 ret = false;
32ec8896 23622 }
2cf0635d 23623 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23624 {
015dc7e1
AM
23625 if ( ! process_archive (filedata, true))
23626 ret = false;
32ec8896 23627 }
fb52b2f4
NC
23628 else
23629 {
1b513401 23630 if (do_archive_index && !check_all)
4145f1d5
NC
23631 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23632 file_name);
23633
dda8d76d 23634 rewind (filedata->handle);
978c4450 23635 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23636
dda8d76d 23637 if (! process_object (filedata))
015dc7e1 23638 ret = false;
fb52b2f4
NC
23639 }
23640
dda8d76d 23641 fclose (filedata->handle);
8fb879cd
AM
23642 free (filedata->section_headers);
23643 free (filedata->program_headers);
23644 free (filedata->string_table);
6431e409 23645 free (filedata->dump.dump_sects);
dda8d76d 23646 free (filedata);
32ec8896 23647
fd486f32 23648 free (ba_cache.strtab);
1bd6175a 23649 ba_cache.strtab = NULL;
fd486f32 23650 free (ba_cache.symtab);
1bd6175a 23651 ba_cache.symtab = NULL;
fd486f32
AM
23652 ba_cache.filedata = NULL;
23653
fb52b2f4
NC
23654 return ret;
23655}
23656
252b5132
RH
23657#ifdef SUPPORT_DISASSEMBLY
23658/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23659 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23660 symbols. */
252b5132
RH
23661
23662void
2cf0635d 23663print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23664{
23665 fprintf (outfile,"0x%8.8x", addr);
23666}
23667
e3c8793a 23668/* Needed by the i386 disassembler. */
dda8d76d 23669
252b5132
RH
23670void
23671db_task_printsym (unsigned int addr)
23672{
23673 print_address (addr, stderr);
23674}
23675#endif
23676
23677int
2cf0635d 23678main (int argc, char ** argv)
252b5132 23679{
ff78d6d6
L
23680 int err;
23681
87b9f255 23682#ifdef HAVE_LC_MESSAGES
252b5132 23683 setlocale (LC_MESSAGES, "");
3882b010 23684#endif
3882b010 23685 setlocale (LC_CTYPE, "");
252b5132
RH
23686 bindtextdomain (PACKAGE, LOCALEDIR);
23687 textdomain (PACKAGE);
23688
869b9d07
MM
23689 expandargv (&argc, &argv);
23690
dda8d76d 23691 parse_args (& cmdline, argc, argv);
59f14fc0 23692
18bd398b 23693 if (optind < (argc - 1))
1b513401
NC
23694 /* When displaying information for more than one file,
23695 prefix the information with the file name. */
015dc7e1 23696 show_name = true;
5656ba2c
L
23697 else if (optind >= argc)
23698 {
1b513401 23699 /* Ensure that the warning is always displayed. */
015dc7e1 23700 do_checks = true;
1b513401 23701
5656ba2c
L
23702 warn (_("Nothing to do.\n"));
23703 usage (stderr);
23704 }
18bd398b 23705
015dc7e1 23706 err = false;
252b5132 23707 while (optind < argc)
32ec8896 23708 if (! process_file (argv[optind++]))
015dc7e1 23709 err = true;
252b5132 23710
9db70fc3 23711 free (cmdline.dump_sects);
252b5132 23712
7d9813f1
NA
23713 free (dump_ctf_symtab_name);
23714 free (dump_ctf_strtab_name);
23715 free (dump_ctf_parent_name);
23716
32ec8896 23717 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23718}