]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Fix: Segmentation fault caused by npd in objdump
[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
252b5132 2525static const char *
dda8d76d 2526get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2527{
e9e44622 2528 static char buff[64];
252b5132
RH
2529
2530 switch (type)
2531 {
2532 case DT_NULL: return "NULL";
2533 case DT_NEEDED: return "NEEDED";
2534 case DT_PLTRELSZ: return "PLTRELSZ";
2535 case DT_PLTGOT: return "PLTGOT";
2536 case DT_HASH: return "HASH";
2537 case DT_STRTAB: return "STRTAB";
2538 case DT_SYMTAB: return "SYMTAB";
2539 case DT_RELA: return "RELA";
2540 case DT_RELASZ: return "RELASZ";
2541 case DT_RELAENT: return "RELAENT";
2542 case DT_STRSZ: return "STRSZ";
2543 case DT_SYMENT: return "SYMENT";
2544 case DT_INIT: return "INIT";
2545 case DT_FINI: return "FINI";
2546 case DT_SONAME: return "SONAME";
2547 case DT_RPATH: return "RPATH";
2548 case DT_SYMBOLIC: return "SYMBOLIC";
2549 case DT_REL: return "REL";
2550 case DT_RELSZ: return "RELSZ";
2551 case DT_RELENT: return "RELENT";
dd207c13
FS
2552 case DT_RELR: return "RELR";
2553 case DT_RELRSZ: return "RELRSZ";
2554 case DT_RELRENT: return "RELRENT";
252b5132
RH
2555 case DT_PLTREL: return "PLTREL";
2556 case DT_DEBUG: return "DEBUG";
2557 case DT_TEXTREL: return "TEXTREL";
2558 case DT_JMPREL: return "JMPREL";
2559 case DT_BIND_NOW: return "BIND_NOW";
2560 case DT_INIT_ARRAY: return "INIT_ARRAY";
2561 case DT_FINI_ARRAY: return "FINI_ARRAY";
2562 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2563 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2564 case DT_RUNPATH: return "RUNPATH";
2565 case DT_FLAGS: return "FLAGS";
2d0e6f43 2566
d1133906
NC
2567 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2568 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2569 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2570
05107a46 2571 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2572 case DT_PLTPADSZ: return "PLTPADSZ";
2573 case DT_MOVEENT: return "MOVEENT";
2574 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2575 case DT_FEATURE: return "FEATURE";
252b5132
RH
2576 case DT_POSFLAG_1: return "POSFLAG_1";
2577 case DT_SYMINSZ: return "SYMINSZ";
2578 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2579
252b5132 2580 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2581 case DT_CONFIG: return "CONFIG";
2582 case DT_DEPAUDIT: return "DEPAUDIT";
2583 case DT_AUDIT: return "AUDIT";
2584 case DT_PLTPAD: return "PLTPAD";
2585 case DT_MOVETAB: return "MOVETAB";
252b5132 2586 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2587
252b5132 2588 case DT_VERSYM: return "VERSYM";
103f02d3 2589
67a4f2b7
AO
2590 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2591 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2592 case DT_RELACOUNT: return "RELACOUNT";
2593 case DT_RELCOUNT: return "RELCOUNT";
2594 case DT_FLAGS_1: return "FLAGS_1";
2595 case DT_VERDEF: return "VERDEF";
2596 case DT_VERDEFNUM: return "VERDEFNUM";
2597 case DT_VERNEED: return "VERNEED";
2598 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2599
019148e4 2600 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2601 case DT_USED: return "USED";
2602 case DT_FILTER: return "FILTER";
103f02d3 2603
047b2264
JJ
2604 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2605 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2606 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2607 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2608 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2609 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2610 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2611
252b5132
RH
2612 default:
2613 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2614 {
2cf0635d 2615 const char * result;
103f02d3 2616
dda8d76d 2617 switch (filedata->file_header.e_machine)
252b5132 2618 {
37c18eed
SD
2619 case EM_AARCH64:
2620 result = get_aarch64_dynamic_type (type);
2621 break;
252b5132 2622 case EM_MIPS:
4fe85591 2623 case EM_MIPS_RS3_LE:
252b5132
RH
2624 result = get_mips_dynamic_type (type);
2625 break;
9a097730
RH
2626 case EM_SPARCV9:
2627 result = get_sparc64_dynamic_type (type);
2628 break;
7490d522
AM
2629 case EM_PPC:
2630 result = get_ppc_dynamic_type (type);
2631 break;
f1cb7e17
AM
2632 case EM_PPC64:
2633 result = get_ppc64_dynamic_type (type);
2634 break;
ecc51f48
NC
2635 case EM_IA_64:
2636 result = get_ia64_dynamic_type (type);
2637 break;
fabcb361
RH
2638 case EM_ALPHA:
2639 result = get_alpha_dynamic_type (type);
2640 break;
1c0d3aa6
NC
2641 case EM_SCORE:
2642 result = get_score_dynamic_type (type);
2643 break;
40b36596
JM
2644 case EM_TI_C6000:
2645 result = get_tic6x_dynamic_type (type);
2646 break;
36591ba1
SL
2647 case EM_ALTERA_NIOS2:
2648 result = get_nios2_dynamic_type (type);
2649 break;
8155b853
NC
2650 case EM_RISCV:
2651 result = get_riscv_dynamic_type (type);
2652 break;
252b5132 2653 default:
dda8d76d 2654 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2655 result = get_solaris_dynamic_type (type);
2656 else
2657 result = NULL;
252b5132
RH
2658 break;
2659 }
2660
2661 if (result != NULL)
2662 return result;
2663
e9e44622 2664 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2665 }
eec8f817 2666 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2667 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2668 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2669 {
2cf0635d 2670 const char * result;
103f02d3 2671
dda8d76d 2672 switch (filedata->file_header.e_machine)
103f02d3
UD
2673 {
2674 case EM_PARISC:
2675 result = get_parisc_dynamic_type (type);
2676 break;
148b93f2
NC
2677 case EM_IA_64:
2678 result = get_ia64_dynamic_type (type);
2679 break;
103f02d3 2680 default:
dda8d76d 2681 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2682 result = get_solaris_dynamic_type (type);
2683 else
2684 result = NULL;
103f02d3
UD
2685 break;
2686 }
2687
2688 if (result != NULL)
2689 return result;
2690
e9e44622
JJ
2691 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2692 type);
103f02d3 2693 }
252b5132 2694 else
e9e44622 2695 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2696
252b5132
RH
2697 return buff;
2698 }
2699}
2700
93df3340
AM
2701static bool get_program_headers (Filedata *);
2702static bool get_dynamic_section (Filedata *);
2703
2704static void
2705locate_dynamic_section (Filedata *filedata)
2706{
26c527e6 2707 uint64_t dynamic_addr = 0;
be7d229a 2708 uint64_t dynamic_size = 0;
93df3340
AM
2709
2710 if (filedata->file_header.e_phnum != 0
2711 && get_program_headers (filedata))
2712 {
2713 Elf_Internal_Phdr *segment;
2714 unsigned int i;
2715
2716 for (i = 0, segment = filedata->program_headers;
2717 i < filedata->file_header.e_phnum;
2718 i++, segment++)
2719 {
2720 if (segment->p_type == PT_DYNAMIC)
2721 {
2722 dynamic_addr = segment->p_offset;
2723 dynamic_size = segment->p_filesz;
2724
2725 if (filedata->section_headers != NULL)
2726 {
2727 Elf_Internal_Shdr *sec;
2728
2729 sec = find_section (filedata, ".dynamic");
2730 if (sec != NULL)
2731 {
2732 if (sec->sh_size == 0
2733 || sec->sh_type == SHT_NOBITS)
2734 {
2735 dynamic_addr = 0;
2736 dynamic_size = 0;
2737 }
2738 else
2739 {
2740 dynamic_addr = sec->sh_offset;
2741 dynamic_size = sec->sh_size;
2742 }
2743 }
2744 }
2745
2746 if (dynamic_addr > filedata->file_size
2747 || (dynamic_size > filedata->file_size - dynamic_addr))
2748 {
2749 dynamic_addr = 0;
2750 dynamic_size = 0;
2751 }
2752 break;
2753 }
2754 }
2755 }
2756 filedata->dynamic_addr = dynamic_addr;
2757 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2758}
2759
2760static bool
2761is_pie (Filedata *filedata)
2762{
2763 Elf_Internal_Dyn *entry;
2764
2765 if (filedata->dynamic_size == 0)
2766 locate_dynamic_section (filedata);
2767 if (filedata->dynamic_size <= 1)
2768 return false;
2769
2770 if (!get_dynamic_section (filedata))
2771 return false;
2772
2773 for (entry = filedata->dynamic_section;
2774 entry < filedata->dynamic_section + filedata->dynamic_nent;
2775 entry++)
2776 {
2777 if (entry->d_tag == DT_FLAGS_1)
2778 {
2779 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2780 return true;
2781 break;
2782 }
2783 }
2784 return false;
2785}
2786
252b5132 2787static char *
93df3340 2788get_file_type (Filedata *filedata)
252b5132 2789{
93df3340 2790 unsigned e_type = filedata->file_header.e_type;
89246a0e 2791 static char buff[64];
252b5132
RH
2792
2793 switch (e_type)
2794 {
32ec8896
NC
2795 case ET_NONE: return _("NONE (None)");
2796 case ET_REL: return _("REL (Relocatable file)");
2797 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2798 case ET_DYN:
2799 if (is_pie (filedata))
2800 return _("DYN (Position-Independent Executable file)");
2801 else
2802 return _("DYN (Shared object file)");
32ec8896 2803 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2804
2805 default:
2806 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2807 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2808 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2809 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2810 else
e9e44622 2811 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2812 return buff;
2813 }
2814}
2815
2816static char *
d3ba0551 2817get_machine_name (unsigned e_machine)
252b5132 2818{
b34976b6 2819 static char buff[64]; /* XXX */
252b5132
RH
2820
2821 switch (e_machine)
2822 {
55e22ca8
NC
2823 /* Please keep this switch table sorted by increasing EM_ value. */
2824 /* 0 */
c45021f2
NC
2825 case EM_NONE: return _("None");
2826 case EM_M32: return "WE32100";
2827 case EM_SPARC: return "Sparc";
2828 case EM_386: return "Intel 80386";
2829 case EM_68K: return "MC68000";
2830 case EM_88K: return "MC88000";
22abe556 2831 case EM_IAMCU: return "Intel MCU";
fb70ec17 2832 case EM_860: return "Intel 80860";
c45021f2
NC
2833 case EM_MIPS: return "MIPS R3000";
2834 case EM_S370: return "IBM System/370";
55e22ca8 2835 /* 10 */
7036c0e1 2836 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2837 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2838 case EM_PARISC: return "HPPA";
55e22ca8 2839 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2840 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2841 case EM_960: return "Intel 80960";
c45021f2 2842 case EM_PPC: return "PowerPC";
55e22ca8 2843 /* 20 */
285d1771 2844 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2845 case EM_S390_OLD:
2846 case EM_S390: return "IBM S/390";
2847 case EM_SPU: return "SPU";
2848 /* 30 */
2849 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2850 case EM_FR20: return "Fujitsu FR20";
2851 case EM_RH32: return "TRW RH32";
b34976b6 2852 case EM_MCORE: return "MCORE";
55e22ca8 2853 /* 40 */
7036c0e1
AJ
2854 case EM_ARM: return "ARM";
2855 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2856 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2857 case EM_SPARCV9: return "Sparc v9";
2858 case EM_TRICORE: return "Siemens Tricore";
584da044 2859 case EM_ARC: return "ARC";
c2dcd04e
NC
2860 case EM_H8_300: return "Renesas H8/300";
2861 case EM_H8_300H: return "Renesas H8/300H";
2862 case EM_H8S: return "Renesas H8S";
2863 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2864 /* 50 */
30800947 2865 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2866 case EM_MIPS_X: return "Stanford MIPS-X";
2867 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2868 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2869 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2870 case EM_PCP: return "Siemens PCP";
2871 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 2872 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
2873 case EM_STARCORE: return "Motorola Star*Core processor";
2874 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2875 /* 60 */
7036c0e1
AJ
2876 case EM_ST100: return "STMicroelectronics ST100 processor";
2877 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2878 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2879 case EM_PDSP: return "Sony DSP processor";
2880 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2881 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2882 case EM_FX66: return "Siemens FX66 microcontroller";
2883 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2884 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2885 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2886 /* 70 */
7036c0e1
AJ
2887 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2888 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2889 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2890 case EM_SVX: return "Silicon Graphics SVx";
2891 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2892 case EM_VAX: return "Digital VAX";
1b61cf92 2893 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2894 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2895 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2896 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2897 /* 80 */
b34976b6 2898 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2899 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2900 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2901 case EM_AVR_OLD:
2902 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2903 case EM_CYGNUS_FR30:
2904 case EM_FR30: return "Fujitsu FR30";
2905 case EM_CYGNUS_D10V:
2906 case EM_D10V: return "d10v";
2907 case EM_CYGNUS_D30V:
2908 case EM_D30V: return "d30v";
2909 case EM_CYGNUS_V850:
2910 case EM_V850: return "Renesas V850";
2911 case EM_CYGNUS_M32R:
2912 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2913 case EM_CYGNUS_MN10300:
2914 case EM_MN10300: return "mn10300";
2915 /* 90 */
2916 case EM_CYGNUS_MN10200:
2917 case EM_MN10200: return "mn10200";
2918 case EM_PJ: return "picoJava";
73589c9d 2919 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2920 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2921 case EM_XTENSA_OLD:
2922 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2923 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2924 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2925 case EM_NS32K: return "National Semiconductor 32000 series";
2926 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2927 case EM_SNP1K: return "Trebia SNP 1000 processor";
2928 /* 100 */
9abca702 2929 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2930 case EM_IP2K_OLD:
2931 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2932 case EM_MAX: return "MAX Processor";
2933 case EM_CR: return "National Semiconductor CompactRISC";
2934 case EM_F2MC16: return "Fujitsu F2MC16";
2935 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2936 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2937 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2938 case EM_SEP: return "Sharp embedded microprocessor";
2939 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2940 /* 110 */
11636f9e
JM
2941 case EM_UNICORE: return "Unicore";
2942 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2943 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2944 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2945 case EM_CRX: return "National Semiconductor CRX microprocessor";
2946 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2947 case EM_C166:
d70c5fc7 2948 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2949 case EM_M16C: return "Renesas M16C series microprocessors";
2950 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2951 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2952 /* 120 */
2953 case EM_M32C: return "Renesas M32c";
2954 /* 130 */
11636f9e
JM
2955 case EM_TSK3000: return "Altium TSK3000 core";
2956 case EM_RS08: return "Freescale RS08 embedded processor";
2957 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2958 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2959 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2960 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2961 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2962 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2963 /* 140 */
11636f9e
JM
2964 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2965 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2966 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2967 case EM_TI_PRU: return "TI PRU I/O processor";
2968 /* 160 */
11636f9e
JM
2969 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2970 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2971 case EM_R32C: return "Renesas R32C series microprocessors";
2972 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2973 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2974 case EM_8051: return "Intel 8051 and variants";
2975 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2976 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2977 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2978 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2979 /* 170 */
11636f9e
JM
2980 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2981 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2982 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2983 case EM_RX: return "Renesas RX";
a3c62988 2984 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2985 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2986 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2987 case EM_CR16:
2988 case EM_MICROBLAZE:
2989 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2990 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2991 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2992 /* 180 */
2993 case EM_L1OM: return "Intel L1OM";
2994 case EM_K1OM: return "Intel K1OM";
2995 case EM_INTEL182: return "Intel (reserved)";
2996 case EM_AARCH64: return "AArch64";
2997 case EM_ARM184: return "ARM (reserved)";
2998 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2999 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3000 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3001 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3002 /* 190 */
11636f9e 3003 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3004 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3005 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3006 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3007 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3008 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3009 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3010 case EM_RL78: return "Renesas RL78";
6d913794 3011 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3012 case EM_78K0R: return "Renesas 78K0R";
3013 /* 200 */
6d913794 3014 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3015 case EM_BA1: return "Beyond BA1 CPU architecture";
3016 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3017 case EM_XCORE: return "XMOS xCORE processor family";
3018 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3019 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3020 /* 210 */
6d913794
NC
3021 case EM_KM32: return "KM211 KM32 32-bit processor";
3022 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3023 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3024 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3025 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3026 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3027 case EM_COGE: return "Cognitive Smart Memory Processor";
3028 case EM_COOL: return "Bluechip Systems CoolEngine";
3029 case EM_NORC: return "Nanoradio Optimized RISC";
3030 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3031 /* 220 */
15f205b1 3032 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3033 case EM_VISIUM: return "CDS VISIUMcore processor";
3034 case EM_FT32: return "FTDI Chip FT32";
3035 case EM_MOXIE: return "Moxie";
3036 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3037 /* 230 (all reserved) */
3038 /* 240 */
55e22ca8
NC
3039 case EM_RISCV: return "RISC-V";
3040 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3041 case EM_CEVA: return "CEVA Processor Architecture Family";
3042 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3043 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3044 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3045 case EM_IMG1: return "Imagination Technologies";
3046 /* 250 */
fe944acf 3047 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3048 case EM_VE: return "NEC Vector Engine";
3049 case EM_CSKY: return "C-SKY";
b5c37946 3050 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3051 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3052 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3053 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3054 case EM_65816: return "WDC 65816/65C816";
01a8c731 3055 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3056 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3057
3058 /* Large numbers... */
3059 case EM_MT: return "Morpho Techologies MT processor";
3060 case EM_ALPHA: return "Alpha";
3061 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3062 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3063 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3064 case EM_IQ2000: return "Vitesse IQ2000";
3065 case EM_M32C_OLD:
3066 case EM_NIOS32: return "Altera Nios";
3067 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3068 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3069 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3070 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3071
252b5132 3072 default:
35d9dd2f 3073 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3074 return buff;
3075 }
3076}
3077
f8c4789c
AM
3078static char *
3079decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3080{
3081 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3082 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3083 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3084 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3085 architectures.
3086
3087 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3088 but also sets a specific architecture type in the e_flags field.
3089
3090 However, when decoding the flags we don't worry if we see an
3091 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3092 ARCEM architecture type. */
3093
3094 switch (e_flags & EF_ARC_MACH_MSK)
3095 {
3096 /* We only expect these to occur for EM_ARC_COMPACT2. */
3097 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3098 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3099 break;
3100 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3101 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3102 break;
3103
3104 /* We only expect these to occur for EM_ARC_COMPACT. */
3105 case E_ARC_MACH_ARC600:
f8c4789c 3106 out = stpcpy (out, ", ARC600");
a9522a21
AB
3107 break;
3108 case E_ARC_MACH_ARC601:
f8c4789c 3109 out = stpcpy (out, ", ARC601");
a9522a21
AB
3110 break;
3111 case E_ARC_MACH_ARC700:
f8c4789c 3112 out = stpcpy (out, ", ARC700");
a9522a21
AB
3113 break;
3114
3115 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3116 new ELF with new architecture being read by an old version of
3117 readelf, or (c) An ELF built with non-GNU compiler that does not
3118 set the architecture in the e_flags. */
3119 default:
3120 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3121 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3122 else
f8c4789c 3123 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3124 break;
3125 }
3126
3127 switch (e_flags & EF_ARC_OSABI_MSK)
3128 {
3129 case E_ARC_OSABI_ORIG:
f8c4789c 3130 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3131 break;
3132 case E_ARC_OSABI_V2:
f8c4789c 3133 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3134 break;
3135 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3136 case E_ARC_OSABI_V3:
f8c4789c 3137 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3138 break;
53a346d8 3139 case E_ARC_OSABI_V4:
f8c4789c 3140 out = stpcpy (out, ", v4 ABI");
53a346d8 3141 break;
a9522a21 3142 default:
f8c4789c 3143 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3144 break;
3145 }
f8c4789c 3146 return out;
a9522a21
AB
3147}
3148
f8c4789c
AM
3149static char *
3150decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3151{
3152 unsigned eabi;
015dc7e1 3153 bool unknown = false;
f3485b74
NC
3154
3155 eabi = EF_ARM_EABI_VERSION (e_flags);
3156 e_flags &= ~ EF_ARM_EABIMASK;
3157
3158 /* Handle "generic" ARM flags. */
3159 if (e_flags & EF_ARM_RELEXEC)
3160 {
f8c4789c 3161 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3162 e_flags &= ~ EF_ARM_RELEXEC;
3163 }
76da6bbe 3164
18a20338
CL
3165 if (e_flags & EF_ARM_PIC)
3166 {
f8c4789c 3167 out = stpcpy (out, ", position independent");
18a20338
CL
3168 e_flags &= ~ EF_ARM_PIC;
3169 }
3170
f3485b74
NC
3171 /* Now handle EABI specific flags. */
3172 switch (eabi)
3173 {
3174 default:
f8c4789c 3175 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3176 if (e_flags)
015dc7e1 3177 unknown = true;
f3485b74
NC
3178 break;
3179
3180 case EF_ARM_EABI_VER1:
f8c4789c 3181 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3182 while (e_flags)
3183 {
3184 unsigned flag;
76da6bbe 3185
f3485b74
NC
3186 /* Process flags one bit at a time. */
3187 flag = e_flags & - e_flags;
3188 e_flags &= ~ flag;
76da6bbe 3189
f3485b74
NC
3190 switch (flag)
3191 {
a5bcd848 3192 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3193 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3194 break;
76da6bbe 3195
f3485b74 3196 default:
015dc7e1 3197 unknown = true;
f3485b74
NC
3198 break;
3199 }
3200 }
3201 break;
76da6bbe 3202
a5bcd848 3203 case EF_ARM_EABI_VER2:
f8c4789c 3204 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3205 while (e_flags)
3206 {
3207 unsigned flag;
3208
3209 /* Process flags one bit at a time. */
3210 flag = e_flags & - e_flags;
3211 e_flags &= ~ flag;
3212
3213 switch (flag)
3214 {
3215 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3216 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3217 break;
3218
3219 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3220 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3221 break;
3222
3223 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3224 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3225 break;
3226
3227 default:
015dc7e1 3228 unknown = true;
a5bcd848
PB
3229 break;
3230 }
3231 }
3232 break;
3233
d507cf36 3234 case EF_ARM_EABI_VER3:
f8c4789c 3235 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3236 break;
3237
3238 case EF_ARM_EABI_VER4:
f8c4789c 3239 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3240 while (e_flags)
3241 {
3242 unsigned flag;
3243
3244 /* Process flags one bit at a time. */
3245 flag = e_flags & - e_flags;
3246 e_flags &= ~ flag;
3247
3248 switch (flag)
3249 {
3250 case EF_ARM_BE8:
f8c4789c 3251 out = stpcpy (out, ", BE8");
3bfcb652
NC
3252 break;
3253
3254 case EF_ARM_LE8:
f8c4789c 3255 out = stpcpy (out, ", LE8");
3bfcb652
NC
3256 break;
3257
3258 default:
015dc7e1 3259 unknown = true;
3bfcb652
NC
3260 break;
3261 }
3bfcb652
NC
3262 }
3263 break;
3a4a14e9
PB
3264
3265 case EF_ARM_EABI_VER5:
f8c4789c 3266 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3267 while (e_flags)
3268 {
3269 unsigned flag;
3270
3271 /* Process flags one bit at a time. */
3272 flag = e_flags & - e_flags;
3273 e_flags &= ~ flag;
3274
3275 switch (flag)
3276 {
3277 case EF_ARM_BE8:
f8c4789c 3278 out = stpcpy (out, ", BE8");
d507cf36
PB
3279 break;
3280
3281 case EF_ARM_LE8:
f8c4789c 3282 out = stpcpy (out, ", LE8");
d507cf36
PB
3283 break;
3284
3bfcb652 3285 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3286 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3287 break;
3288
3289 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3290 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3291 break;
3292
d507cf36 3293 default:
015dc7e1 3294 unknown = true;
d507cf36
PB
3295 break;
3296 }
3297 }
3298 break;
3299
f3485b74 3300 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3301 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3302 while (e_flags)
3303 {
3304 unsigned flag;
76da6bbe 3305
f3485b74
NC
3306 /* Process flags one bit at a time. */
3307 flag = e_flags & - e_flags;
3308 e_flags &= ~ flag;
76da6bbe 3309
f3485b74
NC
3310 switch (flag)
3311 {
a5bcd848 3312 case EF_ARM_INTERWORK:
f8c4789c 3313 out = stpcpy (out, ", interworking enabled");
f3485b74 3314 break;
76da6bbe 3315
a5bcd848 3316 case EF_ARM_APCS_26:
f8c4789c 3317 out = stpcpy (out, ", uses APCS/26");
f3485b74 3318 break;
76da6bbe 3319
a5bcd848 3320 case EF_ARM_APCS_FLOAT:
f8c4789c 3321 out = stpcpy (out, ", uses APCS/float");
f3485b74 3322 break;
76da6bbe 3323
a5bcd848 3324 case EF_ARM_PIC:
f8c4789c 3325 out = stpcpy (out, ", position independent");
f3485b74 3326 break;
76da6bbe 3327
a5bcd848 3328 case EF_ARM_ALIGN8:
f8c4789c 3329 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3330 break;
76da6bbe 3331
a5bcd848 3332 case EF_ARM_NEW_ABI:
f8c4789c 3333 out = stpcpy (out, ", uses new ABI");
f3485b74 3334 break;
76da6bbe 3335
a5bcd848 3336 case EF_ARM_OLD_ABI:
f8c4789c 3337 out = stpcpy (out, ", uses old ABI");
f3485b74 3338 break;
76da6bbe 3339
a5bcd848 3340 case EF_ARM_SOFT_FLOAT:
f8c4789c 3341 out = stpcpy (out, ", software FP");
f3485b74 3342 break;
76da6bbe 3343
90e01f86 3344 case EF_ARM_VFP_FLOAT:
f8c4789c 3345 out = stpcpy (out, ", VFP");
90e01f86
ILT
3346 break;
3347
fde78edd 3348 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3349 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3350 break;
3351
f3485b74 3352 default:
015dc7e1 3353 unknown = true;
f3485b74
NC
3354 break;
3355 }
3356 }
3357 }
f3485b74
NC
3358
3359 if (unknown)
f8c4789c
AM
3360 out = stpcpy (out,_(", <unknown>"));
3361 return out;
f3485b74
NC
3362}
3363
f8c4789c
AM
3364static char *
3365decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3366{
343433df
AB
3367 switch (e_flags & EF_AVR_MACH)
3368 {
3369 case E_AVR_MACH_AVR1:
f8c4789c 3370 out = stpcpy (out, ", avr:1");
343433df
AB
3371 break;
3372 case E_AVR_MACH_AVR2:
f8c4789c 3373 out = stpcpy (out, ", avr:2");
343433df
AB
3374 break;
3375 case E_AVR_MACH_AVR25:
f8c4789c 3376 out = stpcpy (out, ", avr:25");
343433df
AB
3377 break;
3378 case E_AVR_MACH_AVR3:
f8c4789c 3379 out = stpcpy (out, ", avr:3");
343433df
AB
3380 break;
3381 case E_AVR_MACH_AVR31:
f8c4789c 3382 out = stpcpy (out, ", avr:31");
343433df
AB
3383 break;
3384 case E_AVR_MACH_AVR35:
f8c4789c 3385 out = stpcpy (out, ", avr:35");
343433df
AB
3386 break;
3387 case E_AVR_MACH_AVR4:
f8c4789c 3388 out = stpcpy (out, ", avr:4");
343433df
AB
3389 break;
3390 case E_AVR_MACH_AVR5:
f8c4789c 3391 out = stpcpy (out, ", avr:5");
343433df
AB
3392 break;
3393 case E_AVR_MACH_AVR51:
f8c4789c 3394 out = stpcpy (out, ", avr:51");
343433df
AB
3395 break;
3396 case E_AVR_MACH_AVR6:
f8c4789c 3397 out = stpcpy (out, ", avr:6");
343433df
AB
3398 break;
3399 case E_AVR_MACH_AVRTINY:
f8c4789c 3400 out = stpcpy (out, ", avr:100");
343433df
AB
3401 break;
3402 case E_AVR_MACH_XMEGA1:
f8c4789c 3403 out = stpcpy (out, ", avr:101");
343433df
AB
3404 break;
3405 case E_AVR_MACH_XMEGA2:
f8c4789c 3406 out = stpcpy (out, ", avr:102");
343433df
AB
3407 break;
3408 case E_AVR_MACH_XMEGA3:
f8c4789c 3409 out = stpcpy (out, ", avr:103");
343433df
AB
3410 break;
3411 case E_AVR_MACH_XMEGA4:
f8c4789c 3412 out = stpcpy (out, ", avr:104");
343433df
AB
3413 break;
3414 case E_AVR_MACH_XMEGA5:
f8c4789c 3415 out = stpcpy (out, ", avr:105");
343433df
AB
3416 break;
3417 case E_AVR_MACH_XMEGA6:
f8c4789c 3418 out = stpcpy (out, ", avr:106");
343433df
AB
3419 break;
3420 case E_AVR_MACH_XMEGA7:
f8c4789c 3421 out = stpcpy (out, ", avr:107");
343433df
AB
3422 break;
3423 default:
f8c4789c 3424 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3425 break;
3426 }
3427
343433df 3428 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3429 out = stpcpy (out, ", link-relax");
3430 return out;
343433df
AB
3431}
3432
f8c4789c
AM
3433static char *
3434decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3435{
3436 if (e_flags & EF_BFIN_PIC)
3437 out = stpcpy (out, ", PIC");
3438
3439 if (e_flags & EF_BFIN_FDPIC)
3440 out = stpcpy (out, ", FDPIC");
3441
3442 if (e_flags & EF_BFIN_CODE_IN_L1)
3443 out = stpcpy (out, ", code in L1");
3444
3445 if (e_flags & EF_BFIN_DATA_IN_L1)
3446 out = stpcpy (out, ", data in L1");
3447 return out;
3448}
3449
3450static char *
3451decode_FRV_machine_flags (char *out, unsigned e_flags)
3452{
3453 switch (e_flags & EF_FRV_CPU_MASK)
3454 {
3455 case EF_FRV_CPU_GENERIC:
3456 break;
3457
3458 default:
3459 out = stpcpy (out, ", fr???");
3460 break;
3461
3462 case EF_FRV_CPU_FR300:
3463 out = stpcpy (out, ", fr300");
3464 break;
3465
3466 case EF_FRV_CPU_FR400:
3467 out = stpcpy (out, ", fr400");
3468 break;
3469 case EF_FRV_CPU_FR405:
3470 out = stpcpy (out, ", fr405");
3471 break;
3472
3473 case EF_FRV_CPU_FR450:
3474 out = stpcpy (out, ", fr450");
3475 break;
3476
3477 case EF_FRV_CPU_FR500:
3478 out = stpcpy (out, ", fr500");
3479 break;
3480 case EF_FRV_CPU_FR550:
3481 out = stpcpy (out, ", fr550");
3482 break;
3483
3484 case EF_FRV_CPU_SIMPLE:
3485 out = stpcpy (out, ", simple");
3486 break;
3487 case EF_FRV_CPU_TOMCAT:
3488 out = stpcpy (out, ", tomcat");
3489 break;
3490 }
3491 return out;
3492}
3493
3494static char *
3495decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3496{
3497 if ((e_flags & EF_IA_64_ABI64))
3498 out = stpcpy (out, ", 64-bit");
3499 else
3500 out = stpcpy (out, ", 32-bit");
3501 if ((e_flags & EF_IA_64_REDUCEDFP))
3502 out = stpcpy (out, ", reduced fp model");
3503 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3504 out = stpcpy (out, ", no function descriptors, constant gp");
3505 else if ((e_flags & EF_IA_64_CONS_GP))
3506 out = stpcpy (out, ", constant gp");
3507 if ((e_flags & EF_IA_64_ABSOLUTE))
3508 out = stpcpy (out, ", absolute");
3509 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3510 {
3511 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3512 out = stpcpy (out, ", vms_linkages");
3513 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3514 {
3515 case EF_IA_64_VMS_COMCOD_SUCCESS:
3516 break;
3517 case EF_IA_64_VMS_COMCOD_WARNING:
3518 out = stpcpy (out, ", warning");
3519 break;
3520 case EF_IA_64_VMS_COMCOD_ERROR:
3521 out = stpcpy (out, ", error");
3522 break;
3523 case EF_IA_64_VMS_COMCOD_ABORT:
3524 out = stpcpy (out, ", abort");
3525 break;
3526 default:
3527 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3528 e_flags & EF_IA_64_VMS_COMCOD);
3529 out = stpcpy (out, ", <unknown>");
3530 }
3531 }
3532 return out;
3533}
3534
3535static char *
3536decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3537{
3538 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3539 out = stpcpy (out, ", SOFT-FLOAT");
3540 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3541 out = stpcpy (out, ", SINGLE-FLOAT");
3542 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3543 out = stpcpy (out, ", DOUBLE-FLOAT");
3544
3545 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3546 out = stpcpy (out, ", OBJ-v0");
3547 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3548 out = stpcpy (out, ", OBJ-v1");
3549 return out;
3550}
3551
3552static char *
3553decode_M68K_machine_flags (char *out, unsigned int e_flags)
3554{
3555 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3556 out = stpcpy (out, ", m68000");
3557 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3558 out = stpcpy (out, ", cpu32");
3559 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3560 out = stpcpy (out, ", fido_a");
3561 else
3562 {
3563 char const *isa = _("unknown");
3564 char const *mac = _("unknown mac");
3565 char const *additional = NULL;
3566
3567 switch (e_flags & EF_M68K_CF_ISA_MASK)
3568 {
3569 case EF_M68K_CF_ISA_A_NODIV:
3570 isa = "A";
3571 additional = ", nodiv";
3572 break;
3573 case EF_M68K_CF_ISA_A:
3574 isa = "A";
3575 break;
3576 case EF_M68K_CF_ISA_A_PLUS:
3577 isa = "A+";
3578 break;
3579 case EF_M68K_CF_ISA_B_NOUSP:
3580 isa = "B";
3581 additional = ", nousp";
3582 break;
3583 case EF_M68K_CF_ISA_B:
3584 isa = "B";
3585 break;
3586 case EF_M68K_CF_ISA_C:
3587 isa = "C";
3588 break;
3589 case EF_M68K_CF_ISA_C_NODIV:
3590 isa = "C";
3591 additional = ", nodiv";
3592 break;
3593 }
3594 out = stpcpy (out, ", cf, isa ");
3595 out = stpcpy (out, isa);
3596 if (additional)
3597 out = stpcpy (out, additional);
3598 if (e_flags & EF_M68K_CF_FLOAT)
3599 out = stpcpy (out, ", float");
3600 switch (e_flags & EF_M68K_CF_MAC_MASK)
3601 {
3602 case 0:
3603 mac = NULL;
3604 break;
3605 case EF_M68K_CF_MAC:
3606 mac = "mac";
3607 break;
3608 case EF_M68K_CF_EMAC:
3609 mac = "emac";
3610 break;
3611 case EF_M68K_CF_EMAC_B:
3612 mac = "emac_b";
3613 break;
3614 }
3615 if (mac)
3616 {
3617 out = stpcpy (out, ", ");
3618 out = stpcpy (out, mac);
3619 }
3620 }
3621 return out;
3622}
3623
3624static char *
3625decode_MeP_machine_flags (char *out, unsigned int e_flags)
3626{
3627 switch (e_flags & EF_MEP_CPU_MASK)
3628 {
3629 case EF_MEP_CPU_MEP:
3630 out = stpcpy (out, ", generic MeP");
3631 break;
3632 case EF_MEP_CPU_C2:
3633 out = stpcpy (out, ", MeP C2");
3634 break;
3635 case EF_MEP_CPU_C3:
3636 out = stpcpy (out, ", MeP C3");
3637 break;
3638 case EF_MEP_CPU_C4:
3639 out = stpcpy (out, ", MeP C4");
3640 break;
3641 case EF_MEP_CPU_C5:
3642 out = stpcpy (out, ", MeP C5");
3643 break;
3644 case EF_MEP_CPU_H1:
3645 out = stpcpy (out, ", MeP H1");
3646 break;
3647 default:
3648 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3649 break;
3650 }
3651
3652 switch (e_flags & EF_MEP_COP_MASK)
3653 {
3654 case EF_MEP_COP_NONE:
3655 break;
3656 case EF_MEP_COP_AVC:
3657 out = stpcpy (out, ", AVC coprocessor");
3658 break;
3659 case EF_MEP_COP_AVC2:
3660 out = stpcpy (out, ", AVC2 coprocessor");
3661 break;
3662 case EF_MEP_COP_FMAX:
3663 out = stpcpy (out, ", FMAX coprocessor");
3664 break;
3665 case EF_MEP_COP_IVC2:
3666 out = stpcpy (out, ", IVC2 coprocessor");
3667 break;
3668 default:
3669 out = stpcpy (out, _("<unknown MeP copro type>"));
3670 break;
3671 }
3672
3673 if (e_flags & EF_MEP_LIBRARY)
3674 out = stpcpy (out, ", Built for Library");
3675
3676 if (e_flags & EF_MEP_INDEX_MASK)
3677 out += sprintf (out, ", Configuration Index: %#x",
3678 e_flags & EF_MEP_INDEX_MASK);
3679
3680 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3681 out += sprintf (out, _(", unknown flags bits: %#x"),
3682 e_flags & ~ EF_MEP_ALL_FLAGS);
3683 return out;
3684}
3685
3686static char *
3687decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3688{
3689 if (e_flags & EF_MIPS_NOREORDER)
3690 out = stpcpy (out, ", noreorder");
3691
3692 if (e_flags & EF_MIPS_PIC)
3693 out = stpcpy (out, ", pic");
3694
3695 if (e_flags & EF_MIPS_CPIC)
3696 out = stpcpy (out, ", cpic");
3697
3698 if (e_flags & EF_MIPS_UCODE)
3699 out = stpcpy (out, ", ugen_reserved");
3700
3701 if (e_flags & EF_MIPS_ABI2)
3702 out = stpcpy (out, ", abi2");
3703
3704 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3705 out = stpcpy (out, ", odk first");
3706
3707 if (e_flags & EF_MIPS_32BITMODE)
3708 out = stpcpy (out, ", 32bitmode");
3709
3710 if (e_flags & EF_MIPS_NAN2008)
3711 out = stpcpy (out, ", nan2008");
3712
3713 if (e_flags & EF_MIPS_FP64)
3714 out = stpcpy (out, ", fp64");
3715
3716 switch ((e_flags & EF_MIPS_MACH))
3717 {
3718 case E_MIPS_MACH_3900:
3719 out = stpcpy (out, ", 3900");
3720 break;
3721 case E_MIPS_MACH_4010:
3722 out = stpcpy (out, ", 4010");
3723 break;
3724 case E_MIPS_MACH_4100:
3725 out = stpcpy (out, ", 4100");
3726 break;
3727 case E_MIPS_MACH_4111:
3728 out = stpcpy (out, ", 4111");
3729 break;
3730 case E_MIPS_MACH_4120:
3731 out = stpcpy (out, ", 4120");
3732 break;
3733 case E_MIPS_MACH_4650:
3734 out = stpcpy (out, ", 4650");
3735 break;
3736 case E_MIPS_MACH_5400:
3737 out = stpcpy (out, ", 5400");
3738 break;
3739 case E_MIPS_MACH_5500:
3740 out = stpcpy (out, ", 5500");
3741 break;
3742 case E_MIPS_MACH_5900:
3743 out = stpcpy (out, ", 5900");
3744 break;
3745 case E_MIPS_MACH_SB1:
3746 out = stpcpy (out, ", sb1");
3747 break;
3748 case E_MIPS_MACH_9000:
3749 out = stpcpy (out, ", 9000");
3750 break;
3751 case E_MIPS_MACH_LS2E:
3752 out = stpcpy (out, ", loongson-2e");
3753 break;
3754 case E_MIPS_MACH_LS2F:
3755 out = stpcpy (out, ", loongson-2f");
3756 break;
3757 case E_MIPS_MACH_GS464:
3758 out = stpcpy (out, ", gs464");
3759 break;
3760 case E_MIPS_MACH_GS464E:
3761 out = stpcpy (out, ", gs464e");
3762 break;
3763 case E_MIPS_MACH_GS264E:
3764 out = stpcpy (out, ", gs264e");
3765 break;
3766 case E_MIPS_MACH_OCTEON:
3767 out = stpcpy (out, ", octeon");
3768 break;
3769 case E_MIPS_MACH_OCTEON2:
3770 out = stpcpy (out, ", octeon2");
3771 break;
3772 case E_MIPS_MACH_OCTEON3:
3773 out = stpcpy (out, ", octeon3");
3774 break;
3775 case E_MIPS_MACH_XLR:
3776 out = stpcpy (out, ", xlr");
3777 break;
3778 case E_MIPS_MACH_IAMR2:
3779 out = stpcpy (out, ", interaptiv-mr2");
3780 break;
3781 case E_MIPS_MACH_ALLEGREX:
3782 out = stpcpy (out, ", allegrex");
3783 break;
3784 case 0:
3785 /* We simply ignore the field in this case to avoid confusion:
3786 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3787 extension. */
3788 break;
3789 default:
3790 out = stpcpy (out, _(", unknown CPU"));
3791 break;
3792 }
3793
3794 switch ((e_flags & EF_MIPS_ABI))
3795 {
3796 case E_MIPS_ABI_O32:
3797 out = stpcpy (out, ", o32");
3798 break;
3799 case E_MIPS_ABI_O64:
3800 out = stpcpy (out, ", o64");
3801 break;
3802 case E_MIPS_ABI_EABI32:
3803 out = stpcpy (out, ", eabi32");
3804 break;
3805 case E_MIPS_ABI_EABI64:
3806 out = stpcpy (out, ", eabi64");
3807 break;
3808 case 0:
3809 /* We simply ignore the field in this case to avoid confusion:
3810 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3811 This means it is likely to be an o32 file, but not for
3812 sure. */
3813 break;
3814 default:
3815 out = stpcpy (out, _(", unknown ABI"));
3816 break;
3817 }
3818
3819 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3820 out = stpcpy (out, ", mdmx");
3821
3822 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3823 out = stpcpy (out, ", mips16");
3824
3825 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3826 out = stpcpy (out, ", micromips");
3827
3828 switch ((e_flags & EF_MIPS_ARCH))
3829 {
3830 case E_MIPS_ARCH_1:
3831 out = stpcpy (out, ", mips1");
3832 break;
3833 case E_MIPS_ARCH_2:
3834 out = stpcpy (out, ", mips2");
3835 break;
3836 case E_MIPS_ARCH_3:
3837 out = stpcpy (out, ", mips3");
3838 break;
3839 case E_MIPS_ARCH_4:
3840 out = stpcpy (out, ", mips4");
3841 break;
3842 case E_MIPS_ARCH_5:
3843 out = stpcpy (out, ", mips5");
3844 break;
3845 case E_MIPS_ARCH_32:
3846 out = stpcpy (out, ", mips32");
3847 break;
3848 case E_MIPS_ARCH_32R2:
3849 out = stpcpy (out, ", mips32r2");
3850 break;
3851 case E_MIPS_ARCH_32R6:
3852 out = stpcpy (out, ", mips32r6");
3853 break;
3854 case E_MIPS_ARCH_64:
3855 out = stpcpy (out, ", mips64");
3856 break;
3857 case E_MIPS_ARCH_64R2:
3858 out = stpcpy (out, ", mips64r2");
3859 break;
3860 case E_MIPS_ARCH_64R6:
3861 out = stpcpy (out, ", mips64r6");
3862 break;
3863 default:
3864 out = stpcpy (out, _(", unknown ISA"));
3865 break;
3866 }
3867 return out;
3868}
3869
3870static char *
3871decode_MSP430_machine_flags (char *out, unsigned e_flags)
3872{
3873 out = stpcpy (out, _(": architecture variant: "));
3874 switch (e_flags & EF_MSP430_MACH)
3875 {
3876 case E_MSP430_MACH_MSP430x11:
3877 out = stpcpy (out, "MSP430x11");
3878 break;
3879 case E_MSP430_MACH_MSP430x11x1:
3880 out = stpcpy (out, "MSP430x11x1 ");
3881 break;
3882 case E_MSP430_MACH_MSP430x12:
3883 out = stpcpy (out, "MSP430x12");
3884 break;
3885 case E_MSP430_MACH_MSP430x13:
3886 out = stpcpy (out, "MSP430x13");
3887 break;
3888 case E_MSP430_MACH_MSP430x14:
3889 out = stpcpy (out, "MSP430x14");
3890 break;
3891 case E_MSP430_MACH_MSP430x15:
3892 out = stpcpy (out, "MSP430x15");
3893 break;
3894 case E_MSP430_MACH_MSP430x16:
3895 out = stpcpy (out, "MSP430x16");
3896 break;
3897 case E_MSP430_MACH_MSP430x31:
3898 out = stpcpy (out, "MSP430x31");
3899 break;
3900 case E_MSP430_MACH_MSP430x32:
3901 out = stpcpy (out, "MSP430x32");
3902 break;
3903 case E_MSP430_MACH_MSP430x33:
3904 out = stpcpy (out, "MSP430x33");
3905 break;
3906 case E_MSP430_MACH_MSP430x41:
3907 out = stpcpy (out, "MSP430x41");
3908 break;
3909 case E_MSP430_MACH_MSP430x42:
3910 out = stpcpy (out, "MSP430x42");
3911 break;
3912 case E_MSP430_MACH_MSP430x43:
3913 out = stpcpy (out, "MSP430x43");
3914 break;
3915 case E_MSP430_MACH_MSP430x44:
3916 out = stpcpy (out, "MSP430x44");
3917 break;
3918 case E_MSP430_MACH_MSP430X :
3919 out = stpcpy (out, "MSP430X");
3920 break;
3921 default:
3922 out = stpcpy (out, _(": unknown"));
3923 break;
3924 }
3925
3926 if (e_flags & ~ EF_MSP430_MACH)
3927 out = stpcpy (out, _(": unknown extra flag bits also present"));
3928 return out;
3929}
3930
3931static char *
3932decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
3933{
3934 unsigned abi;
3935 unsigned arch;
3936 unsigned config;
3937 unsigned version;
015dc7e1 3938 bool has_fpu = false;
35c08157
KLC
3939
3940 static const char *ABI_STRINGS[] =
3941 {
3942 "ABI v0", /* use r5 as return register; only used in N1213HC */
3943 "ABI v1", /* use r0 as return register */
3944 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3945 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3946 "AABI",
3947 "ABI2 FP+"
35c08157
KLC
3948 };
3949 static const char *VER_STRINGS[] =
3950 {
3951 "Andes ELF V1.3 or older",
3952 "Andes ELF V1.3.1",
3953 "Andes ELF V1.4"
3954 };
3955 static const char *ARCH_STRINGS[] =
3956 {
3957 "",
3958 "Andes Star v1.0",
3959 "Andes Star v2.0",
3960 "Andes Star v3.0",
3961 "Andes Star v3.0m"
3962 };
3963
3964 abi = EF_NDS_ABI & e_flags;
3965 arch = EF_NDS_ARCH & e_flags;
3966 config = EF_NDS_INST & e_flags;
3967 version = EF_NDS32_ELF_VERSION & e_flags;
3968
35c08157
KLC
3969 switch (abi)
3970 {
3971 case E_NDS_ABI_V0:
3972 case E_NDS_ABI_V1:
3973 case E_NDS_ABI_V2:
3974 case E_NDS_ABI_V2FP:
3975 case E_NDS_ABI_AABI:
40c7a7cb 3976 case E_NDS_ABI_V2FP_PLUS:
35c08157 3977 /* In case there are holes in the array. */
f8c4789c 3978 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
3979 break;
3980
3981 default:
f8c4789c 3982 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
3983 break;
3984 }
3985
3986 switch (version)
3987 {
3988 case E_NDS32_ELF_VER_1_2:
3989 case E_NDS32_ELF_VER_1_3:
3990 case E_NDS32_ELF_VER_1_4:
f8c4789c 3991 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
3992 break;
3993
3994 default:
f8c4789c 3995 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
3996 break;
3997 }
3998
3999 if (E_NDS_ABI_V0 == abi)
4000 {
4001 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4002 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4003 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4004 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4005 return out;
35c08157
KLC
4006 }
4007
4008 switch (arch)
4009 {
4010 case E_NDS_ARCH_STAR_V1_0:
4011 case E_NDS_ARCH_STAR_V2_0:
4012 case E_NDS_ARCH_STAR_V3_0:
4013 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4014 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4015 break;
4016
4017 default:
f8c4789c 4018 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4019 /* ARCH version determines how the e_flags are interpreted.
4020 If it is unknown, we cannot proceed. */
f8c4789c 4021 return out;
35c08157
KLC
4022 }
4023
4024 /* Newer ABI; Now handle architecture specific flags. */
4025 if (arch == E_NDS_ARCH_STAR_V1_0)
4026 {
4027 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4028 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4029
4030 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4031 out = stpcpy (out, ", MAC");
35c08157
KLC
4032
4033 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4034 out = stpcpy (out, ", DIV");
35c08157
KLC
4035
4036 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4037 out = stpcpy (out, ", 16b");
35c08157
KLC
4038 }
4039 else
4040 {
4041 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4042 {
4043 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4044 out = stpcpy (out, ", [B8]");
35c08157 4045 else
f8c4789c 4046 out = stpcpy (out, ", EX9");
35c08157
KLC
4047 }
4048
4049 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4050 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4051
4052 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4053 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4054
4055 if (config & E_NDS32_HAS_16BIT_INST)
4056 {
4057 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4058 out = stpcpy (out, ", 16b");
35c08157 4059 else
f8c4789c 4060 out = stpcpy (out, ", IFC");
35c08157
KLC
4061 }
4062 }
4063
4064 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4065 out = stpcpy (out, ", PERF1");
35c08157
KLC
4066
4067 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4068 out = stpcpy (out, ", PERF2");
35c08157
KLC
4069
4070 if (config & E_NDS32_HAS_FPU_INST)
4071 {
015dc7e1 4072 has_fpu = true;
f8c4789c 4073 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4074 }
4075
4076 if (config & E_NDS32_HAS_FPU_DP_INST)
4077 {
015dc7e1 4078 has_fpu = true;
f8c4789c 4079 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4080 }
4081
4082 if (config & E_NDS32_HAS_FPU_MAC_INST)
4083 {
015dc7e1 4084 has_fpu = true;
f8c4789c 4085 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4086 }
4087
4088 if (has_fpu)
4089 {
4090 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4091 {
4092 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4093 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4094 break;
4095 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4096 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4097 break;
4098 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4099 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4100 break;
4101 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4102 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4103 break;
4104 }
4105 }
4106
4107 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4108 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4109
4110 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4111 out = stpcpy (out, ", STR");
35c08157
KLC
4112
4113 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4114 out = stpcpy (out, ", 16REG");
35c08157
KLC
4115
4116 if (config & E_NDS32_HAS_VIDEO_INST)
4117 {
4118 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4119 out = stpcpy (out, ", VIDEO");
35c08157 4120 else
f8c4789c 4121 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4122 }
4123
4124 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4125 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4126
4127 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4128 out = stpcpy (out, ", L2C");
4129
4130 return out;
35c08157
KLC
4131}
4132
f8c4789c
AM
4133static char *
4134decode_PARISC_machine_flags (char *out, unsigned e_flags)
4135{
4136 switch (e_flags & EF_PARISC_ARCH)
4137 {
4138 case EFA_PARISC_1_0:
4139 out = stpcpy (out, ", PA-RISC 1.0");
4140 break;
4141 case EFA_PARISC_1_1:
4142 out = stpcpy (out, ", PA-RISC 1.1");
4143 break;
4144 case EFA_PARISC_2_0:
4145 out = stpcpy (out, ", PA-RISC 2.0");
4146 break;
4147 default:
4148 break;
4149 }
4150 if (e_flags & EF_PARISC_TRAPNIL)
4151 out = stpcpy (out, ", trapnil");
4152 if (e_flags & EF_PARISC_EXT)
4153 out = stpcpy (out, ", ext");
4154 if (e_flags & EF_PARISC_LSB)
4155 out = stpcpy (out, ", lsb");
4156 if (e_flags & EF_PARISC_WIDE)
4157 out = stpcpy (out, ", wide");
4158 if (e_flags & EF_PARISC_NO_KABP)
4159 out = stpcpy (out, ", no kabp");
4160 if (e_flags & EF_PARISC_LAZYSWAP)
4161 out = stpcpy (out, ", lazyswap");
4162 return out;
4163}
4164
4165static char *
4166decode_RISCV_machine_flags (char *out, unsigned e_flags)
4167{
4168 if (e_flags & EF_RISCV_RVC)
4169 out = stpcpy (out, ", RVC");
4170
4171 if (e_flags & EF_RISCV_RVE)
4172 out = stpcpy (out, ", RVE");
4173
4174 if (e_flags & EF_RISCV_TSO)
4175 out = stpcpy (out, ", TSO");
4176
4177 switch (e_flags & EF_RISCV_FLOAT_ABI)
4178 {
4179 case EF_RISCV_FLOAT_ABI_SOFT:
4180 out = stpcpy (out, ", soft-float ABI");
4181 break;
4182
4183 case EF_RISCV_FLOAT_ABI_SINGLE:
4184 out = stpcpy (out, ", single-float ABI");
4185 break;
4186
4187 case EF_RISCV_FLOAT_ABI_DOUBLE:
4188 out = stpcpy (out, ", double-float ABI");
4189 break;
4190
4191 case EF_RISCV_FLOAT_ABI_QUAD:
4192 out = stpcpy (out, ", quad-float ABI");
4193 break;
4194 }
4195 return out;
4196}
4197
4198static char *
4199decode_RL78_machine_flags (char *out, unsigned e_flags)
4200{
4201 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4202 {
4203 case E_FLAG_RL78_ANY_CPU:
4204 break;
4205 case E_FLAG_RL78_G10:
4206 out = stpcpy (out, ", G10");
4207 break;
4208 case E_FLAG_RL78_G13:
4209 out = stpcpy (out, ", G13");
4210 break;
4211 case E_FLAG_RL78_G14:
4212 out = stpcpy (out, ", G14");
4213 break;
4214 }
4215 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4216 out = stpcpy (out, ", 64-bit doubles");
4217 return out;
4218}
4219
4220static char *
4221decode_RX_machine_flags (char *out, unsigned e_flags)
4222{
4223 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4224 out = stpcpy (out, ", 64-bit doubles");
4225 if (e_flags & E_FLAG_RX_DSP)
4226 out = stpcpy (out, ", dsp");
4227 if (e_flags & E_FLAG_RX_PID)
4228 out = stpcpy (out, ", pid");
4229 if (e_flags & E_FLAG_RX_ABI)
4230 out = stpcpy (out, ", RX ABI");
4231 if (e_flags & E_FLAG_RX_SINSNS_SET)
4232 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4233 ? ", uses String instructions"
4234 : ", bans String instructions"));
4235 if (e_flags & E_FLAG_RX_V2)
4236 out = stpcpy (out, ", V2");
4237 if (e_flags & E_FLAG_RX_V3)
4238 out = stpcpy (out, ", V3");
4239 return out;
4240}
4241
4242static char *
4243decode_SH_machine_flags (char *out, unsigned e_flags)
4244{
4245 switch ((e_flags & EF_SH_MACH_MASK))
4246 {
4247 case EF_SH1:
4248 out = stpcpy (out, ", sh1");
4249 break;
4250 case EF_SH2:
4251 out = stpcpy (out, ", sh2");
4252 break;
4253 case EF_SH3:
4254 out = stpcpy (out, ", sh3");
4255 break;
4256 case EF_SH_DSP:
4257 out = stpcpy (out, ", sh-dsp");
4258 break;
4259 case EF_SH3_DSP:
4260 out = stpcpy (out, ", sh3-dsp");
4261 break;
4262 case EF_SH4AL_DSP:
4263 out = stpcpy (out, ", sh4al-dsp");
4264 break;
4265 case EF_SH3E:
4266 out = stpcpy (out, ", sh3e");
4267 break;
4268 case EF_SH4:
4269 out = stpcpy (out, ", sh4");
4270 break;
4271 case EF_SH5:
4272 out = stpcpy (out, ", sh5");
4273 break;
4274 case EF_SH2E:
4275 out = stpcpy (out, ", sh2e");
4276 break;
4277 case EF_SH4A:
4278 out = stpcpy (out, ", sh4a");
4279 break;
4280 case EF_SH2A:
4281 out = stpcpy (out, ", sh2a");
4282 break;
4283 case EF_SH4_NOFPU:
4284 out = stpcpy (out, ", sh4-nofpu");
4285 break;
4286 case EF_SH4A_NOFPU:
4287 out = stpcpy (out, ", sh4a-nofpu");
4288 break;
4289 case EF_SH2A_NOFPU:
4290 out = stpcpy (out, ", sh2a-nofpu");
4291 break;
4292 case EF_SH3_NOMMU:
4293 out = stpcpy (out, ", sh3-nommu");
4294 break;
4295 case EF_SH4_NOMMU_NOFPU:
4296 out = stpcpy (out, ", sh4-nommu-nofpu");
4297 break;
4298 case EF_SH2A_SH4_NOFPU:
4299 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4300 break;
4301 case EF_SH2A_SH3_NOFPU:
4302 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4303 break;
4304 case EF_SH2A_SH4:
4305 out = stpcpy (out, ", sh2a-or-sh4");
4306 break;
4307 case EF_SH2A_SH3E:
4308 out = stpcpy (out, ", sh2a-or-sh3e");
4309 break;
4310 default:
4311 out = stpcpy (out, _(", unknown ISA"));
4312 break;
4313 }
4314
4315 if (e_flags & EF_SH_PIC)
4316 out = stpcpy (out, ", pic");
4317
4318 if (e_flags & EF_SH_FDPIC)
4319 out = stpcpy (out, ", fdpic");
4320 return out;
4321}
4322
4323static char *
4324decode_SPARC_machine_flags (char *out, unsigned e_flags)
4325{
4326 if (e_flags & EF_SPARC_32PLUS)
4327 out = stpcpy (out, ", v8+");
4328
4329 if (e_flags & EF_SPARC_SUN_US1)
4330 out = stpcpy (out, ", ultrasparcI");
4331
4332 if (e_flags & EF_SPARC_SUN_US3)
4333 out = stpcpy (out, ", ultrasparcIII");
4334
4335 if (e_flags & EF_SPARC_HAL_R1)
4336 out = stpcpy (out, ", halr1");
4337
4338 if (e_flags & EF_SPARC_LEDATA)
4339 out = stpcpy (out, ", ledata");
4340
4341 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4342 out = stpcpy (out, ", tso");
4343
4344 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4345 out = stpcpy (out, ", pso");
4346
4347 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4348 out = stpcpy (out, ", rmo");
4349 return out;
4350}
4351
4352static char *
4353decode_V800_machine_flags (char *out, unsigned int e_flags)
4354{
4355 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4356 out = stpcpy (out, ", RH850 ABI");
4357
4358 if (e_flags & EF_V800_850E3)
4359 out = stpcpy (out, ", V3 architecture");
4360
4361 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4362 out = stpcpy (out, ", FPU not used");
4363
4364 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4365 out = stpcpy (out, ", regmode: COMMON");
4366
4367 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4368 out = stpcpy (out, ", r4 not used");
4369
4370 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4371 out = stpcpy (out, ", r30 not used");
4372
4373 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4374 out = stpcpy (out, ", r5 not used");
4375
4376 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4377 out = stpcpy (out, ", r2 not used");
4378
4379 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4380 {
4381 switch (e_flags & - e_flags)
4382 {
4383 case EF_RH850_FPU_DOUBLE:
4384 out = stpcpy (out, ", double precision FPU");
4385 break;
4386 case EF_RH850_FPU_SINGLE:
4387 out = stpcpy (out, ", single precision FPU");
4388 break;
4389 case EF_RH850_REGMODE22:
4390 out = stpcpy (out, ", regmode:22");
4391 break;
4392 case EF_RH850_REGMODE32:
4393 out = stpcpy (out, ", regmode:23");
4394 break;
4395 case EF_RH850_GP_FIX:
4396 out = stpcpy (out, ", r4 fixed");
4397 break;
4398 case EF_RH850_GP_NOFIX:
4399 out = stpcpy (out, ", r4 free");
4400 break;
4401 case EF_RH850_EP_FIX:
4402 out = stpcpy (out, ", r30 fixed");
4403 break;
4404 case EF_RH850_EP_NOFIX:
4405 out = stpcpy (out, ", r30 free");
4406 break;
4407 case EF_RH850_TP_FIX:
4408 out = stpcpy (out, ", r5 fixed");
4409 break;
4410 case EF_RH850_TP_NOFIX:
4411 out = stpcpy (out, ", r5 free");
4412 break;
4413 case EF_RH850_REG2_RESERVE:
4414 out = stpcpy (out, ", r2 fixed");
4415 break;
4416 case EF_RH850_REG2_NORESERVE:
4417 out = stpcpy (out, ", r2 free");
4418 break;
4419 default:
4420 break;
4421 }
4422 }
4423 return out;
4424}
4425
4426static char *
4427decode_V850_machine_flags (char *out, unsigned int e_flags)
4428{
4429 switch (e_flags & EF_V850_ARCH)
4430 {
4431 case E_V850E3V5_ARCH:
4432 out = stpcpy (out, ", v850e3v5");
4433 break;
4434 case E_V850E2V3_ARCH:
4435 out = stpcpy (out, ", v850e2v3");
4436 break;
4437 case E_V850E2_ARCH:
4438 out = stpcpy (out, ", v850e2");
4439 break;
4440 case E_V850E1_ARCH:
4441 out = stpcpy (out, ", v850e1");
4442 break;
4443 case E_V850E_ARCH:
4444 out = stpcpy (out, ", v850e");
4445 break;
4446 case E_V850_ARCH:
4447 out = stpcpy (out, ", v850");
4448 break;
4449 default:
4450 out = stpcpy (out, _(", unknown v850 architecture variant"));
4451 break;
4452 }
4453 return out;
4454}
4455
4456static char *
4457decode_Z80_machine_flags (char *out, unsigned int e_flags)
4458{
4459 switch (e_flags & EF_Z80_MACH_MSK)
4460 {
4461 case EF_Z80_MACH_Z80:
4462 out = stpcpy (out, ", Z80");
4463 break;
4464 case EF_Z80_MACH_Z180:
4465 out = stpcpy (out, ", Z180");
4466 break;
4467 case EF_Z80_MACH_R800:
4468 out = stpcpy (out, ", R800");
4469 break;
4470 case EF_Z80_MACH_EZ80_Z80:
4471 out = stpcpy (out, ", EZ80");
4472 break;
4473 case EF_Z80_MACH_EZ80_ADL:
4474 out = stpcpy (out, ", EZ80, ADL");
4475 break;
4476 case EF_Z80_MACH_GBZ80:
4477 out = stpcpy (out, ", GBZ80");
4478 break;
4479 case EF_Z80_MACH_Z80N:
4480 out = stpcpy (out, ", Z80N");
4481 break;
4482 default:
4483 out = stpcpy (out, _(", unknown"));
4484 break;
4485 }
4486 return out;
4487}
4488
4489static char *
4490decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4491{
4492 unsigned char *e_ident = filedata->file_header.e_ident;
4493 unsigned char osabi = e_ident[EI_OSABI];
4494 unsigned char abiversion = e_ident[EI_ABIVERSION];
4495 unsigned int mach;
4496
4497 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4498 it has been deprecated for a while.
4499
4500 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4501 of writing, they use the same flags as HSA v3, so the code below uses that
4502 assumption. */
4503 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4504 return out;
c077c580
SM
4505
4506 mach = e_flags & EF_AMDGPU_MACH;
4507 switch (mach)
4508 {
4509#define AMDGPU_CASE(code, string) \
f8c4789c 4510 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4511 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4512 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4513 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4514 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4515 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4516 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4517 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4518 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4519 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4520 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4521 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4522 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4523 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4524 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4525 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4526 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4527 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4528 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4529 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4530 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4531 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4532 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4533 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4534 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4535 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
4536 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4537 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4538 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4539 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4540 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4541 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4542 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4543 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4544 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4545 default:
f8c4789c 4546 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4547 break;
4548#undef AMDGPU_CASE
4549 }
4550
c077c580
SM
4551 e_flags &= ~EF_AMDGPU_MACH;
4552
4553 if ((osabi == ELFOSABI_AMDGPU_HSA
4554 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4555 || osabi != ELFOSABI_AMDGPU_HSA)
4556 {
4557 /* For HSA v3 and other OS ABIs. */
4558 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4559 {
f8c4789c 4560 out = stpcpy (out, ", xnack on");
c077c580
SM
4561 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4562 }
4563
4564 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4565 {
f8c4789c 4566 out = stpcpy (out, ", sramecc on");
c077c580
SM
4567 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4568 }
4569 }
4570 else
4571 {
4572 /* For HSA v4+. */
4573 int xnack, sramecc;
4574
4575 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4576 switch (xnack)
4577 {
4578 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4579 break;
4580
4581 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4582 out = stpcpy (out, ", xnack any");
c077c580
SM
4583 break;
4584
4585 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4586 out = stpcpy (out, ", xnack off");
c077c580
SM
4587 break;
4588
4589 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4590 out = stpcpy (out, ", xnack on");
c077c580
SM
4591 break;
4592
4593 default:
f8c4789c 4594 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4595 break;
4596 }
4597
c077c580
SM
4598 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4599
4600 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4601 switch (sramecc)
4602 {
4603 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4604 break;
4605
4606 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4607 out = stpcpy (out, ", sramecc any");
c077c580
SM
4608 break;
4609
4610 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4611 out = stpcpy (out, ", sramecc off");
c077c580
SM
4612 break;
4613
4614 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4615 out = stpcpy (out, ", sramecc on");
c077c580
SM
4616 break;
4617
4618 default:
f8c4789c 4619 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4620 break;
4621 }
4622
c077c580
SM
4623 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4624 }
4625
4626 if (e_flags != 0)
f8c4789c
AM
4627 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4628 return out;
c077c580
SM
4629}
4630
252b5132 4631static char *
dda8d76d 4632get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4633{
b34976b6 4634 static char buf[1024];
f8c4789c 4635 char *out = buf;
252b5132
RH
4636
4637 buf[0] = '\0';
76da6bbe 4638
252b5132
RH
4639 if (e_flags)
4640 {
4641 switch (e_machine)
4642 {
4643 default:
4644 break;
4645
b5c37946 4646 case EM_ARC_COMPACT3:
f8c4789c 4647 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4648 break;
4649
4650 case EM_ARC_COMPACT3_64:
f8c4789c 4651 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4652 break;
4653
886a2506 4654 case EM_ARC_COMPACT2:
886a2506 4655 case EM_ARC_COMPACT:
f8c4789c
AM
4656 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4657 break;
886a2506 4658
f3485b74 4659 case EM_ARM:
f8c4789c 4660 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4661 break;
76da6bbe 4662
f8c4789c
AM
4663 case EM_AVR:
4664 out = decode_AVR_machine_flags (out, e_flags);
4665 break;
343433df 4666
781303ce 4667 case EM_BLACKFIN:
f8c4789c 4668 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4669 break;
4670
ec2dfb42 4671 case EM_CYGNUS_FRV:
f8c4789c 4672 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4673 break;
ec2dfb42 4674
53c7db4b 4675 case EM_68K:
f8c4789c 4676 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4677 break;
33c63f9d 4678
c077c580 4679 case EM_AMDGPU:
f8c4789c 4680 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4681 break;
4682
153a2776 4683 case EM_CYGNUS_MEP:
f8c4789c 4684 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4685 break;
4686
252b5132
RH
4687 case EM_PPC:
4688 if (e_flags & EF_PPC_EMB)
f8c4789c 4689 out = stpcpy (out, ", emb");
252b5132
RH
4690
4691 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4692 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4693
4694 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4695 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4696 break;
4697
ee67d69a
AM
4698 case EM_PPC64:
4699 if (e_flags & EF_PPC64_ABI)
f8c4789c 4700 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4701 break;
4702
708e2187 4703 case EM_V800:
f8c4789c 4704 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4705 break;
4706
2b0337b0 4707 case EM_V850:
252b5132 4708 case EM_CYGNUS_V850:
f8c4789c 4709 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4710 break;
4711
2b0337b0 4712 case EM_M32R:
252b5132
RH
4713 case EM_CYGNUS_M32R:
4714 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4715 out = stpcpy (out, ", m32r");
252b5132
RH
4716 break;
4717
4718 case EM_MIPS:
4fe85591 4719 case EM_MIPS_RS3_LE:
f8c4789c 4720 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4721 break;
351b4b40 4722
35c08157 4723 case EM_NDS32:
f8c4789c 4724 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4725 break;
4726
fe944acf
FT
4727 case EM_NFP:
4728 switch (EF_NFP_MACH (e_flags))
4729 {
4730 case E_NFP_MACH_3200:
f8c4789c 4731 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4732 break;
4733 case E_NFP_MACH_6000:
f8c4789c 4734 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4735 break;
4736 }
4737 break;
4738
e23eba97 4739 case EM_RISCV:
f8c4789c 4740 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4741 break;
4742
ccde1100 4743 case EM_SH:
f8c4789c 4744 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4745 break;
948f632f 4746
f8c4789c
AM
4747 case EM_OR1K:
4748 if (e_flags & EF_OR1K_NODELAY)
4749 out = stpcpy (out, ", no delay");
4750 break;
57346661 4751
f8c4789c
AM
4752 case EM_BPF:
4753 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4754 break;
b5c37946 4755
351b4b40 4756 case EM_SPARCV9:
f8c4789c 4757 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4758 break;
7d466069 4759
103f02d3 4760 case EM_PARISC:
f8c4789c 4761 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4762 break;
76da6bbe 4763
7d466069 4764 case EM_PJ:
2b0337b0 4765 case EM_PJ_OLD:
7d466069 4766 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4767 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4768
4769 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4770 out = stpcpy (out, ", gnu calling convention");
7d466069 4771 break;
4d6ed7c8
NC
4772
4773 case EM_IA_64:
f8c4789c 4774 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4775 break;
179d3252
JT
4776
4777 case EM_VAX:
4778 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4779 out = stpcpy (out, ", non-PIC");
179d3252 4780 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4781 out = stpcpy (out, ", D-Float");
179d3252 4782 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4783 out = stpcpy (out, ", G-Float");
179d3252 4784 break;
c7927a3c 4785
f8c4789c 4786 case EM_VISIUM:
619ed720 4787 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4788 out = stpcpy (out, ", mcm");
619ed720 4789 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4790 out = stpcpy (out, ", mcm24");
619ed720 4791 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4792 out = stpcpy (out, ", gr6");
619ed720
EB
4793 break;
4794
4046d87a 4795 case EM_RL78:
f8c4789c 4796 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4797 break;
0b4362b0 4798
c7927a3c 4799 case EM_RX:
f8c4789c 4800 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4801 break;
55786da2
AK
4802
4803 case EM_S390:
4804 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4805 out = stpcpy (out, ", highgprs");
d4cb0ea0 4806 break;
40b36596
JM
4807
4808 case EM_TI_C6000:
4809 if ((e_flags & EF_C6000_REL))
f8c4789c 4810 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4811 break;
13761a11 4812
6e712424
PI
4813 case EM_KVX:
4814 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4815 strcat (buf, ", Kalray VLIW kv3-1");
4816 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4817 strcat (buf, ", Kalray VLIW kv3-2");
4818 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4819 strcat (buf, ", Kalray VLIW kv4-1");
4820 else
4821 strcat (buf, ", unknown KVX MPPA");
4822 break;
4823
13761a11 4824 case EM_MSP430:
f8c4789c 4825 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4826 break;
4827
4828 case EM_Z80:
f8c4789c 4829 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4830 break;
c4a7e6b5 4831
f8c4789c
AM
4832 case EM_LOONGARCH:
4833 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4834 break;
252b5132
RH
4835 }
4836 }
4837
4838 return buf;
4839}
4840
252b5132 4841static const char *
dda8d76d 4842get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4843{
4844 static char buff[32];
4845
4846 switch (osabi)
4847 {
4848 case ELFOSABI_NONE: return "UNIX - System V";
4849 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4850 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4851 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4852 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4853 case ELFOSABI_AIX: return "UNIX - AIX";
4854 case ELFOSABI_IRIX: return "UNIX - IRIX";
4855 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4856 case ELFOSABI_TRU64: return "UNIX - TRU64";
4857 case ELFOSABI_MODESTO: return "Novell - Modesto";
4858 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4859 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4860 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4861 case ELFOSABI_AROS: return "AROS";
11636f9e 4862 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4863 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4864 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4865 default:
40b36596 4866 if (osabi >= 64)
dda8d76d 4867 switch (filedata->file_header.e_machine)
40b36596 4868 {
37870be8
SM
4869 case EM_AMDGPU:
4870 switch (osabi)
4871 {
4872 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4873 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4874 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4875 default:
4876 break;
4877 }
4878 break;
4879
40b36596
JM
4880 case EM_ARM:
4881 switch (osabi)
4882 {
4883 case ELFOSABI_ARM: return "ARM";
18a20338 4884 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4885 default:
4886 break;
4887 }
4888 break;
4889
4890 case EM_MSP430:
4891 case EM_MSP430_OLD:
619ed720 4892 case EM_VISIUM:
40b36596
JM
4893 switch (osabi)
4894 {
4895 case ELFOSABI_STANDALONE: return _("Standalone App");
4896 default:
4897 break;
4898 }
4899 break;
4900
4901 case EM_TI_C6000:
4902 switch (osabi)
4903 {
4904 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4905 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4906 default:
4907 break;
4908 }
4909 break;
4910
4911 default:
4912 break;
4913 }
e9e44622 4914 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4915 return buff;
4916 }
4917}
4918
a06ea964
NC
4919static const char *
4920get_aarch64_segment_type (unsigned long type)
4921{
4922 switch (type)
4923 {
32ec8896 4924 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 4925 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 4926 default: return NULL;
a06ea964 4927 }
a06ea964
NC
4928}
4929
b294bdf8
MM
4930static const char *
4931get_arm_segment_type (unsigned long type)
4932{
4933 switch (type)
4934 {
32ec8896
NC
4935 case PT_ARM_EXIDX: return "EXIDX";
4936 default: return NULL;
b294bdf8 4937 }
b294bdf8
MM
4938}
4939
b4cbbe8f
AK
4940static const char *
4941get_s390_segment_type (unsigned long type)
4942{
4943 switch (type)
4944 {
4945 case PT_S390_PGSTE: return "S390_PGSTE";
4946 default: return NULL;
4947 }
4948}
4949
d3ba0551
AM
4950static const char *
4951get_mips_segment_type (unsigned long type)
252b5132
RH
4952{
4953 switch (type)
4954 {
32ec8896
NC
4955 case PT_MIPS_REGINFO: return "REGINFO";
4956 case PT_MIPS_RTPROC: return "RTPROC";
4957 case PT_MIPS_OPTIONS: return "OPTIONS";
4958 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4959 default: return NULL;
252b5132 4960 }
252b5132
RH
4961}
4962
103f02d3 4963static const char *
d3ba0551 4964get_parisc_segment_type (unsigned long type)
103f02d3
UD
4965{
4966 switch (type)
4967 {
103f02d3
UD
4968 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4969 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4970 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4971 default: return NULL;
103f02d3 4972 }
103f02d3
UD
4973}
4974
4d6ed7c8 4975static const char *
d3ba0551 4976get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4977{
4978 switch (type)
4979 {
4980 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4981 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4982 default: return NULL;
4d6ed7c8 4983 }
4d6ed7c8
NC
4984}
4985
40b36596
JM
4986static const char *
4987get_tic6x_segment_type (unsigned long type)
4988{
4989 switch (type)
4990 {
32ec8896
NC
4991 case PT_C6000_PHATTR: return "C6000_PHATTR";
4992 default: return NULL;
40b36596 4993 }
40b36596
JM
4994}
4995
fbc95f1e
KC
4996static const char *
4997get_riscv_segment_type (unsigned long type)
4998{
4999 switch (type)
5000 {
5001 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5002 default: return NULL;
5003 }
5004}
5005
df3a023b
AM
5006static const char *
5007get_hpux_segment_type (unsigned long type, unsigned e_machine)
5008{
5009 if (e_machine == EM_PARISC)
5010 switch (type)
5011 {
5012 case PT_HP_TLS: return "HP_TLS";
5013 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5014 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5015 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5016 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5017 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5018 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5019 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5020 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5021 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5022 case PT_HP_PARALLEL: return "HP_PARALLEL";
5023 case PT_HP_FASTBIND: return "HP_FASTBIND";
5024 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5025 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5026 case PT_HP_STACK: return "HP_STACK";
5027 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5028 default: return NULL;
5029 }
5030
5031 if (e_machine == EM_IA_64)
5032 switch (type)
5033 {
5034 case PT_HP_TLS: return "HP_TLS";
5035 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5036 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5037 case PT_IA_64_HP_STACK: return "HP_STACK";
5038 default: return NULL;
5039 }
5040
5041 return NULL;
5042}
5043
5522f910
NC
5044static const char *
5045get_solaris_segment_type (unsigned long type)
5046{
5047 switch (type)
5048 {
5049 case 0x6464e550: return "PT_SUNW_UNWIND";
5050 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5051 case 0x6ffffff7: return "PT_LOSUNW";
5052 case 0x6ffffffa: return "PT_SUNWBSS";
5053 case 0x6ffffffb: return "PT_SUNWSTACK";
5054 case 0x6ffffffc: return "PT_SUNWDTRACE";
5055 case 0x6ffffffd: return "PT_SUNWCAP";
5056 case 0x6fffffff: return "PT_HISUNW";
32ec8896 5057 default: return NULL;
5522f910
NC
5058 }
5059}
5060
252b5132 5061static const char *
dda8d76d 5062get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5063{
b34976b6 5064 static char buff[32];
252b5132
RH
5065
5066 switch (p_type)
5067 {
b34976b6
AM
5068 case PT_NULL: return "NULL";
5069 case PT_LOAD: return "LOAD";
252b5132 5070 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5071 case PT_INTERP: return "INTERP";
5072 case PT_NOTE: return "NOTE";
5073 case PT_SHLIB: return "SHLIB";
5074 case PT_PHDR: return "PHDR";
13ae64f3 5075 case PT_TLS: return "TLS";
32ec8896 5076 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5077 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5078 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5079 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5080 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5081
80251d41 5082 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5083 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5084 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
73b22419 5085 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
3eba3ef3 5086 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5087
252b5132 5088 default:
df3a023b 5089 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5090 {
2cf0635d 5091 const char * result;
103f02d3 5092
dda8d76d 5093 switch (filedata->file_header.e_machine)
252b5132 5094 {
a06ea964
NC
5095 case EM_AARCH64:
5096 result = get_aarch64_segment_type (p_type);
5097 break;
b294bdf8
MM
5098 case EM_ARM:
5099 result = get_arm_segment_type (p_type);
5100 break;
252b5132 5101 case EM_MIPS:
4fe85591 5102 case EM_MIPS_RS3_LE:
252b5132
RH
5103 result = get_mips_segment_type (p_type);
5104 break;
103f02d3
UD
5105 case EM_PARISC:
5106 result = get_parisc_segment_type (p_type);
5107 break;
4d6ed7c8
NC
5108 case EM_IA_64:
5109 result = get_ia64_segment_type (p_type);
5110 break;
40b36596
JM
5111 case EM_TI_C6000:
5112 result = get_tic6x_segment_type (p_type);
5113 break;
b4cbbe8f
AK
5114 case EM_S390:
5115 case EM_S390_OLD:
5116 result = get_s390_segment_type (p_type);
5117 break;
fbc95f1e
KC
5118 case EM_RISCV:
5119 result = get_riscv_segment_type (p_type);
5120 break;
252b5132
RH
5121 default:
5122 result = NULL;
5123 break;
5124 }
103f02d3 5125
252b5132
RH
5126 if (result != NULL)
5127 return result;
103f02d3 5128
1a9ccd70 5129 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5130 }
5131 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5132 {
df3a023b 5133 const char * result = NULL;
103f02d3 5134
df3a023b 5135 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5136 {
df3a023b
AM
5137 case ELFOSABI_GNU:
5138 case ELFOSABI_FREEBSD:
5139 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5140 {
5141 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5142 result = buff;
5143 }
103f02d3 5144 break;
df3a023b
AM
5145 case ELFOSABI_HPUX:
5146 result = get_hpux_segment_type (p_type,
5147 filedata->file_header.e_machine);
5148 break;
5149 case ELFOSABI_SOLARIS:
5150 result = get_solaris_segment_type (p_type);
00428cca 5151 break;
103f02d3 5152 default:
103f02d3
UD
5153 break;
5154 }
103f02d3
UD
5155 if (result != NULL)
5156 return result;
5157
1a9ccd70 5158 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5159 }
252b5132 5160 else
e9e44622 5161 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5162
5163 return buff;
5164 }
5165}
5166
53a346d8
CZ
5167static const char *
5168get_arc_section_type_name (unsigned int sh_type)
5169{
5170 switch (sh_type)
5171 {
5172 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5173 default:
5174 break;
5175 }
5176 return NULL;
5177}
5178
252b5132 5179static const char *
d3ba0551 5180get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5181{
5182 switch (sh_type)
5183 {
b34976b6
AM
5184 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5185 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5186 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5187 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5188 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5189 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5190 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5191 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5192 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5193 case SHT_MIPS_RELD: return "MIPS_RELD";
5194 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5195 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5196 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5197 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5198 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5199 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5200 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5201 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5202 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5203 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5204 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5205 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5206 case SHT_MIPS_LINE: return "MIPS_LINE";
5207 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5208 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5209 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5210 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5211 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5212 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5213 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5214 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5215 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5216 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5217 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5218 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5219 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5220 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5221 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5222 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5223 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5224 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5225 default:
5226 break;
5227 }
5228 return NULL;
5229}
5230
103f02d3 5231static const char *
d3ba0551 5232get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5233{
5234 switch (sh_type)
5235 {
5236 case SHT_PARISC_EXT: return "PARISC_EXT";
5237 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5238 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5239 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5240 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5241 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5242 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5243 default: return NULL;
103f02d3 5244 }
103f02d3
UD
5245}
5246
4d6ed7c8 5247static const char *
dda8d76d 5248get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5249{
18bd398b 5250 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5251 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5252 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5253
4d6ed7c8
NC
5254 switch (sh_type)
5255 {
148b93f2
NC
5256 case SHT_IA_64_EXT: return "IA_64_EXT";
5257 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5258 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5259 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5260 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5261 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5262 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5263 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5264 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5265 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5266 default:
5267 break;
5268 }
5269 return NULL;
5270}
5271
d2b2c203
DJ
5272static const char *
5273get_x86_64_section_type_name (unsigned int sh_type)
5274{
5275 switch (sh_type)
5276 {
5277 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5278 default: return NULL;
d2b2c203 5279 }
d2b2c203
DJ
5280}
5281
a06ea964
NC
5282static const char *
5283get_aarch64_section_type_name (unsigned int sh_type)
5284{
5285 switch (sh_type)
5286 {
32ec8896
NC
5287 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5288 default: return NULL;
a06ea964 5289 }
a06ea964
NC
5290}
5291
40a18ebd
NC
5292static const char *
5293get_arm_section_type_name (unsigned int sh_type)
5294{
5295 switch (sh_type)
5296 {
7f6fed87
NC
5297 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5298 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5299 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5300 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5301 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5302 default: return NULL;
40a18ebd 5303 }
40a18ebd
NC
5304}
5305
40b36596
JM
5306static const char *
5307get_tic6x_section_type_name (unsigned int sh_type)
5308{
5309 switch (sh_type)
5310 {
32ec8896
NC
5311 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5312 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5313 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5314 case SHT_TI_ICODE: return "TI_ICODE";
5315 case SHT_TI_XREF: return "TI_XREF";
5316 case SHT_TI_HANDLER: return "TI_HANDLER";
5317 case SHT_TI_INITINFO: return "TI_INITINFO";
5318 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5319 default: return NULL;
40b36596 5320 }
40b36596
JM
5321}
5322
13761a11 5323static const char *
b0191216 5324get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5325{
5326 switch (sh_type)
5327 {
32ec8896
NC
5328 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5329 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5330 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5331 default: return NULL;
13761a11
NC
5332 }
5333}
5334
fe944acf
FT
5335static const char *
5336get_nfp_section_type_name (unsigned int sh_type)
5337{
5338 switch (sh_type)
5339 {
5340 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5341 case SHT_NFP_INITREG: return "NFP_INITREG";
5342 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5343 default: return NULL;
5344 }
5345}
5346
685080f2
NC
5347static const char *
5348get_v850_section_type_name (unsigned int sh_type)
5349{
5350 switch (sh_type)
5351 {
32ec8896
NC
5352 case SHT_V850_SCOMMON: return "V850 Small Common";
5353 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5354 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5355 case SHT_RENESAS_IOP: return "RENESAS IOP";
5356 case SHT_RENESAS_INFO: return "RENESAS INFO";
5357 default: return NULL;
685080f2
NC
5358 }
5359}
5360
2dc8dd17
JW
5361static const char *
5362get_riscv_section_type_name (unsigned int sh_type)
5363{
5364 switch (sh_type)
5365 {
5366 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5367 default: return NULL;
5368 }
5369}
5370
0861f561
CQ
5371static const char *
5372get_csky_section_type_name (unsigned int sh_type)
5373{
5374 switch (sh_type)
5375 {
5376 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5377 default: return NULL;
5378 }
5379}
5380
252b5132 5381static const char *
dda8d76d 5382get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5383{
b34976b6 5384 static char buff[32];
9fb71ee4 5385 const char * result;
252b5132
RH
5386
5387 switch (sh_type)
5388 {
5389 case SHT_NULL: return "NULL";
5390 case SHT_PROGBITS: return "PROGBITS";
5391 case SHT_SYMTAB: return "SYMTAB";
5392 case SHT_STRTAB: return "STRTAB";
5393 case SHT_RELA: return "RELA";
dd207c13 5394 case SHT_RELR: return "RELR";
252b5132
RH
5395 case SHT_HASH: return "HASH";
5396 case SHT_DYNAMIC: return "DYNAMIC";
5397 case SHT_NOTE: return "NOTE";
5398 case SHT_NOBITS: return "NOBITS";
5399 case SHT_REL: return "REL";
5400 case SHT_SHLIB: return "SHLIB";
5401 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
5402 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5403 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5404 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 5405 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 5406 case SHT_GROUP: return "GROUP";
67ce483b 5407 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
5408 case SHT_GNU_verdef: return "VERDEF";
5409 case SHT_GNU_verneed: return "VERNEED";
5410 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
5411 case 0x6ffffff0: return "VERSYM";
5412 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5413 case 0x7ffffffd: return "AUXILIARY";
5414 case 0x7fffffff: return "FILTER";
047b2264 5415 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
5416
5417 default:
5418 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5419 {
dda8d76d 5420 switch (filedata->file_header.e_machine)
252b5132 5421 {
53a346d8
CZ
5422 case EM_ARC:
5423 case EM_ARC_COMPACT:
5424 case EM_ARC_COMPACT2:
b5c37946
SJ
5425 case EM_ARC_COMPACT3:
5426 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5427 result = get_arc_section_type_name (sh_type);
5428 break;
252b5132 5429 case EM_MIPS:
4fe85591 5430 case EM_MIPS_RS3_LE:
252b5132
RH
5431 result = get_mips_section_type_name (sh_type);
5432 break;
103f02d3
UD
5433 case EM_PARISC:
5434 result = get_parisc_section_type_name (sh_type);
5435 break;
4d6ed7c8 5436 case EM_IA_64:
dda8d76d 5437 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5438 break;
d2b2c203 5439 case EM_X86_64:
8a9036a4 5440 case EM_L1OM:
7a9068fe 5441 case EM_K1OM:
d2b2c203
DJ
5442 result = get_x86_64_section_type_name (sh_type);
5443 break;
a06ea964
NC
5444 case EM_AARCH64:
5445 result = get_aarch64_section_type_name (sh_type);
5446 break;
40a18ebd
NC
5447 case EM_ARM:
5448 result = get_arm_section_type_name (sh_type);
5449 break;
40b36596
JM
5450 case EM_TI_C6000:
5451 result = get_tic6x_section_type_name (sh_type);
5452 break;
13761a11 5453 case EM_MSP430:
b0191216 5454 result = get_msp430_section_type_name (sh_type);
13761a11 5455 break;
fe944acf
FT
5456 case EM_NFP:
5457 result = get_nfp_section_type_name (sh_type);
5458 break;
685080f2
NC
5459 case EM_V800:
5460 case EM_V850:
5461 case EM_CYGNUS_V850:
5462 result = get_v850_section_type_name (sh_type);
5463 break;
2dc8dd17
JW
5464 case EM_RISCV:
5465 result = get_riscv_section_type_name (sh_type);
5466 break;
0861f561
CQ
5467 case EM_CSKY:
5468 result = get_csky_section_type_name (sh_type);
5469 break;
252b5132
RH
5470 default:
5471 result = NULL;
5472 break;
5473 }
5474
5475 if (result != NULL)
5476 return result;
5477
9fb71ee4 5478 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5479 }
5480 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5481 {
dda8d76d 5482 switch (filedata->file_header.e_machine)
148b93f2
NC
5483 {
5484 case EM_IA_64:
dda8d76d 5485 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5486 break;
5487 default:
dda8d76d 5488 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5489 result = get_solaris_section_type (sh_type);
5490 else
1b4b80bf
NC
5491 {
5492 switch (sh_type)
5493 {
5494 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5495 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5496 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5497 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5498 default:
5499 result = NULL;
5500 break;
5501 }
5502 }
148b93f2
NC
5503 break;
5504 }
5505
5506 if (result != NULL)
5507 return result;
5508
9fb71ee4 5509 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5510 }
252b5132 5511 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5512 {
dda8d76d 5513 switch (filedata->file_header.e_machine)
685080f2
NC
5514 {
5515 case EM_V800:
5516 case EM_V850:
5517 case EM_CYGNUS_V850:
9fb71ee4 5518 result = get_v850_section_type_name (sh_type);
a9fb83be 5519 break;
685080f2 5520 default:
9fb71ee4 5521 result = NULL;
685080f2
NC
5522 break;
5523 }
5524
9fb71ee4
NC
5525 if (result != NULL)
5526 return result;
5527
5528 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5529 }
252b5132 5530 else
a7dbfd1c
NC
5531 /* This message is probably going to be displayed in a 15
5532 character wide field, so put the hex value first. */
5533 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5534
252b5132
RH
5535 return buff;
5536 }
5537}
5538
79bc120c
NC
5539enum long_option_values
5540{
5541 OPTION_DEBUG_DUMP = 512,
5542 OPTION_DYN_SYMS,
0f03783c 5543 OPTION_LTO_SYMS,
79bc120c
NC
5544 OPTION_DWARF_DEPTH,
5545 OPTION_DWARF_START,
5546 OPTION_DWARF_CHECK,
5547 OPTION_CTF_DUMP,
5548 OPTION_CTF_PARENT,
5549 OPTION_CTF_SYMBOLS,
5550 OPTION_CTF_STRINGS,
42b6953b 5551 OPTION_SFRAME_DUMP,
79bc120c
NC
5552 OPTION_WITH_SYMBOL_VERSIONS,
5553 OPTION_RECURSE_LIMIT,
5554 OPTION_NO_RECURSE_LIMIT,
047c3dbf 5555 OPTION_NO_DEMANGLING,
b6ac461a 5556 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 5557 OPTION_SYM_BASE
79bc120c 5558};
2979dc34 5559
85b1c36d 5560static struct option options[] =
252b5132 5561{
79bc120c
NC
5562 /* Note - This table is alpha-sorted on the 'val'
5563 field in order to make adding new options easier. */
5564 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5565 {"all", no_argument, 0, 'a'},
79bc120c
NC
5566 {"demangle", optional_argument, 0, 'C'},
5567 {"archive-index", no_argument, 0, 'c'},
5568 {"use-dynamic", no_argument, 0, 'D'},
5569 {"dynamic", no_argument, 0, 'd'},
b34976b6 5570 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5571 {"section-groups", no_argument, 0, 'g'},
5572 {"help", no_argument, 0, 'H'},
5573 {"file-header", no_argument, 0, 'h'},
b34976b6 5574 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
5575 {"lint", no_argument, 0, 'L'},
5576 {"enable-checks", no_argument, 0, 'L'},
5577 {"program-headers", no_argument, 0, 'l'},
b34976b6 5578 {"segments", no_argument, 0, 'l'},
595cf52e 5579 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5580 {"notes", no_argument, 0, 'n'},
ca0e11aa 5581 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5582 {"string-dump", required_argument, 0, 'p'},
5583 {"relocated-dump", required_argument, 0, 'R'},
5584 {"relocs", no_argument, 0, 'r'},
5585 {"section-headers", no_argument, 0, 'S'},
5586 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5587 {"symbols", no_argument, 0, 's'},
5588 {"syms", no_argument, 0, 's'},
79bc120c
NC
5589 {"silent-truncation",no_argument, 0, 'T'},
5590 {"section-details", no_argument, 0, 't'},
b3aa80b4 5591 {"unicode", required_argument, NULL, 'U'},
09c11c86 5592 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5593 {"version-info", no_argument, 0, 'V'},
5594 {"version", no_argument, 0, 'v'},
5595 {"wide", no_argument, 0, 'W'},
b6ac461a 5596 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 5597 {"hex-dump", required_argument, 0, 'x'},
0e602686 5598 {"decompress", no_argument, 0, 'z'},
252b5132 5599
79bc120c 5600 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 5601 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
5602 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5603 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5604 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5605 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5606 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5607 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5608 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5609 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5610 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5611#ifdef ENABLE_LIBCTF
d344b407 5612 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5613 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5614 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5615 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5616#endif
42b6953b 5617 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5618 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5619
b34976b6 5620 {0, no_argument, 0, 0}
252b5132
RH
5621};
5622
5623static void
2cf0635d 5624usage (FILE * stream)
252b5132 5625{
92f01d61
JM
5626 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5627 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5628 fprintf (stream, _(" Options are:\n"));
5629 fprintf (stream, _("\
5630 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5631 fprintf (stream, _("\
5632 -h --file-header Display the ELF file header\n"));
5633 fprintf (stream, _("\
5634 -l --program-headers Display the program headers\n"));
5635 fprintf (stream, _("\
5636 --segments An alias for --program-headers\n"));
5637 fprintf (stream, _("\
5638 -S --section-headers Display the sections' header\n"));
5639 fprintf (stream, _("\
5640 --sections An alias for --section-headers\n"));
5641 fprintf (stream, _("\
5642 -g --section-groups Display the section groups\n"));
5643 fprintf (stream, _("\
5644 -t --section-details Display the section details\n"));
5645 fprintf (stream, _("\
5646 -e --headers Equivalent to: -h -l -S\n"));
5647 fprintf (stream, _("\
5648 -s --syms Display the symbol table\n"));
5649 fprintf (stream, _("\
5650 --symbols An alias for --syms\n"));
5651 fprintf (stream, _("\
5652 --dyn-syms Display the dynamic symbol table\n"));
5653 fprintf (stream, _("\
5654 --lto-syms Display LTO symbol tables\n"));
5655 fprintf (stream, _("\
047c3dbf
NL
5656 --sym-base=[0|8|10|16] \n\
5657 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5658 mixed (the default), octal, decimal, hexadecimal.\n"));
5659 fprintf (stream, _("\
0d646226
AM
5660 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5661 display_demangler_styles (stream, _("\
5662 STYLE can be "));
d6249f5f
AM
5663 fprintf (stream, _("\
5664 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5665 fprintf (stream, _("\
5666 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5667 fprintf (stream, _("\
5668 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5669 fprintf (stream, _("\
5670 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5671 Display unicode characters as determined by the current locale\n\
5672 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5673 escape sequences, or treat them as invalid and display as\n\
5674 \"{hex sequences}\"\n"));
d6249f5f 5675 fprintf (stream, _("\
b6ac461a
NC
5676 -X --extra-sym-info Display extra information when showing symbols\n"));
5677 fprintf (stream, _("\
5678 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5679 fprintf (stream, _("\
5680 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
5681 fprintf (stream, _("\
5682 -r --relocs Display the relocations (if present)\n"));
5683 fprintf (stream, _("\
5684 -u --unwind Display the unwind info (if present)\n"));
5685 fprintf (stream, _("\
5686 -d --dynamic Display the dynamic section (if present)\n"));
5687 fprintf (stream, _("\
5688 -V --version-info Display the version sections (if present)\n"));
5689 fprintf (stream, _("\
5690 -A --arch-specific Display architecture specific information (if any)\n"));
5691 fprintf (stream, _("\
5692 -c --archive-index Display the symbol/file index in an archive\n"));
5693 fprintf (stream, _("\
5694 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5695 fprintf (stream, _("\
5696 -L --lint|--enable-checks\n\
5697 Display warning messages for possible problems\n"));
5698 fprintf (stream, _("\
09c11c86 5699 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5700 Dump the contents of section <number|name> as bytes\n"));
5701 fprintf (stream, _("\
09c11c86 5702 -p --string-dump=<number|name>\n\
d6249f5f
AM
5703 Dump the contents of section <number|name> as strings\n"));
5704 fprintf (stream, _("\
cf13d699 5705 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5706 Dump the relocated contents of section <number|name>\n"));
5707 fprintf (stream, _("\
5708 -z --decompress Decompress section before dumping it\n"));
5709 fprintf (stream, _("\
5710 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5711 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5712 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5713 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5714 U/=trace_info]\n\
5715 Display the contents of DWARF debug sections\n"));
5716 fprintf (stream, _("\
5717 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5718 debuginfo files\n"));
5719 fprintf (stream, _("\
5720 -P --process-links Display the contents of non-debug sections in separate\n\
5721 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5722#if DEFAULT_FOR_FOLLOW_LINKS
5723 fprintf (stream, _("\
d6249f5f
AM
5724 -wK --debug-dump=follow-links\n\
5725 Follow links to separate debug info files (default)\n"));
5726 fprintf (stream, _("\
5727 -wN --debug-dump=no-follow-links\n\
5728 Do not follow links to separate debug info files\n"));
c46b7066
NC
5729#else
5730 fprintf (stream, _("\
d6249f5f
AM
5731 -wK --debug-dump=follow-links\n\
5732 Follow links to separate debug info files\n"));
5733 fprintf (stream, _("\
5734 -wN --debug-dump=no-follow-links\n\
5735 Do not follow links to separate debug info files\n\
5736 (default)\n"));
bed566bb
NC
5737#endif
5738#if HAVE_LIBDEBUGINFOD
5739 fprintf (stream, _("\
5740 -wD --debug-dump=use-debuginfod\n\
5741 When following links, also query debuginfod servers (default)\n"));
5742 fprintf (stream, _("\
5743 -wE --debug-dump=do-not-use-debuginfod\n\
5744 When following links, do not query debuginfod servers\n"));
c46b7066 5745#endif
fd2f0033 5746 fprintf (stream, _("\
d6249f5f
AM
5747 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5748 fprintf (stream, _("\
5749 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5750#ifdef ENABLE_LIBCTF
7d9813f1 5751 fprintf (stream, _("\
d6249f5f
AM
5752 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5753 fprintf (stream, _("\
80b56fad 5754 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5755 fprintf (stream, _("\
7d9813f1 5756 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5757 Use section <number|name> as the CTF external symtab\n"));
5758 fprintf (stream, _("\
7d9813f1 5759 --ctf-strings=<number|name>\n\
d6249f5f 5760 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5761#endif
42b6953b
IB
5762 fprintf (stream, _("\
5763 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5764
252b5132 5765#ifdef SUPPORT_DISASSEMBLY
92f01d61 5766 fprintf (stream, _("\
09c11c86
NC
5767 -i --instruction-dump=<number|name>\n\
5768 Disassemble the contents of section <number|name>\n"));
252b5132 5769#endif
92f01d61 5770 fprintf (stream, _("\
d6249f5f
AM
5771 -I --histogram Display histogram of bucket list lengths\n"));
5772 fprintf (stream, _("\
5773 -W --wide Allow output width to exceed 80 characters\n"));
5774 fprintf (stream, _("\
5775 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5776 fprintf (stream, _("\
5777 @<file> Read options from <file>\n"));
5778 fprintf (stream, _("\
5779 -H --help Display this information\n"));
5780 fprintf (stream, _("\
8b53311e 5781 -v --version Display the version number of readelf\n"));
1118d252 5782
92f01d61
JM
5783 if (REPORT_BUGS_TO[0] && stream == stdout)
5784 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5785
92f01d61 5786 exit (stream == stdout ? 0 : 1);
252b5132
RH
5787}
5788
18bd398b
NC
5789/* Record the fact that the user wants the contents of section number
5790 SECTION to be displayed using the method(s) encoded as flags bits
5791 in TYPE. Note, TYPE can be zero if we are creating the array for
5792 the first time. */
5793
252b5132 5794static void
6431e409
AM
5795request_dump_bynumber (struct dump_data *dumpdata,
5796 unsigned int section, dump_type type)
252b5132 5797{
6431e409 5798 if (section >= dumpdata->num_dump_sects)
252b5132 5799 {
2cf0635d 5800 dump_type * new_dump_sects;
252b5132 5801
3f5e193b 5802 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5803 sizeof (* new_dump_sects));
252b5132
RH
5804
5805 if (new_dump_sects == NULL)
591a748a 5806 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5807 else
5808 {
6431e409 5809 if (dumpdata->dump_sects)
21b65bac
NC
5810 {
5811 /* Copy current flag settings. */
6431e409
AM
5812 memcpy (new_dump_sects, dumpdata->dump_sects,
5813 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5814
6431e409 5815 free (dumpdata->dump_sects);
21b65bac 5816 }
252b5132 5817
6431e409
AM
5818 dumpdata->dump_sects = new_dump_sects;
5819 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5820 }
5821 }
5822
6431e409
AM
5823 if (dumpdata->dump_sects)
5824 dumpdata->dump_sects[section] |= type;
252b5132
RH
5825}
5826
aef1f6d0
DJ
5827/* Request a dump by section name. */
5828
5829static void
2cf0635d 5830request_dump_byname (const char * section, dump_type type)
aef1f6d0 5831{
2cf0635d 5832 struct dump_list_entry * new_request;
aef1f6d0 5833
3f5e193b
NC
5834 new_request = (struct dump_list_entry *)
5835 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5836 if (!new_request)
591a748a 5837 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5838
5839 new_request->name = strdup (section);
5840 if (!new_request->name)
591a748a 5841 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5842
5843 new_request->type = type;
5844
5845 new_request->next = dump_sects_byname;
5846 dump_sects_byname = new_request;
5847}
5848
cf13d699 5849static inline void
6431e409 5850request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5851{
5852 int section;
5853 char * cp;
5854
015dc7e1 5855 do_dump = true;
cf13d699
NC
5856 section = strtoul (optarg, & cp, 0);
5857
5858 if (! *cp && section >= 0)
6431e409 5859 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5860 else
5861 request_dump_byname (optarg, type);
5862}
5863
252b5132 5864static void
6431e409 5865parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5866{
5867 int c;
5868
5869 if (argc < 2)
92f01d61 5870 usage (stderr);
252b5132
RH
5871
5872 while ((c = getopt_long
b6ac461a 5873 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5874 {
252b5132
RH
5875 switch (c)
5876 {
5877 case 0:
5878 /* Long options. */
5879 break;
5880 case 'H':
92f01d61 5881 usage (stdout);
252b5132
RH
5882 break;
5883
5884 case 'a':
015dc7e1
AM
5885 do_syms = true;
5886 do_reloc = true;
5887 do_unwind = true;
5888 do_dynamic = true;
5889 do_header = true;
5890 do_sections = true;
5891 do_section_groups = true;
5892 do_segments = true;
5893 do_version = true;
5894 do_histogram = true;
5895 do_arch = true;
5896 do_notes = true;
252b5132 5897 break;
79bc120c 5898
f5842774 5899 case 'g':
015dc7e1 5900 do_section_groups = true;
f5842774 5901 break;
5477e8a0 5902 case 't':
595cf52e 5903 case 'N':
015dc7e1
AM
5904 do_sections = true;
5905 do_section_details = true;
595cf52e 5906 break;
252b5132 5907 case 'e':
015dc7e1
AM
5908 do_header = true;
5909 do_sections = true;
5910 do_segments = true;
252b5132 5911 break;
a952a375 5912 case 'A':
015dc7e1 5913 do_arch = true;
a952a375 5914 break;
252b5132 5915 case 'D':
015dc7e1 5916 do_using_dynamic = true;
252b5132
RH
5917 break;
5918 case 'r':
015dc7e1 5919 do_reloc = true;
252b5132 5920 break;
4d6ed7c8 5921 case 'u':
015dc7e1 5922 do_unwind = true;
4d6ed7c8 5923 break;
252b5132 5924 case 'h':
015dc7e1 5925 do_header = true;
252b5132
RH
5926 break;
5927 case 'l':
015dc7e1 5928 do_segments = true;
252b5132
RH
5929 break;
5930 case 's':
015dc7e1 5931 do_syms = true;
252b5132
RH
5932 break;
5933 case 'S':
015dc7e1 5934 do_sections = true;
252b5132
RH
5935 break;
5936 case 'd':
015dc7e1 5937 do_dynamic = true;
252b5132 5938 break;
a952a375 5939 case 'I':
015dc7e1 5940 do_histogram = true;
a952a375 5941 break;
779fe533 5942 case 'n':
015dc7e1 5943 do_notes = true;
779fe533 5944 break;
4145f1d5 5945 case 'c':
015dc7e1 5946 do_archive_index = true;
4145f1d5 5947 break;
1b513401 5948 case 'L':
015dc7e1 5949 do_checks = true;
1b513401 5950 break;
ca0e11aa 5951 case 'P':
015dc7e1
AM
5952 process_links = true;
5953 do_follow_links = true;
e1dbfc17 5954 dump_any_debugging = true;
ca0e11aa 5955 break;
252b5132 5956 case 'x':
6431e409 5957 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5958 break;
09c11c86 5959 case 'p':
6431e409 5960 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5961 break;
5962 case 'R':
6431e409 5963 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5964 break;
0e602686 5965 case 'z':
015dc7e1 5966 decompress_dumps = true;
0e602686 5967 break;
252b5132 5968 case 'w':
0f03783c 5969 if (optarg == NULL)
613ff48b 5970 {
015dc7e1 5971 do_debugging = true;
94585d6d
NC
5972 do_dump = true;
5973 dump_any_debugging = true;
613ff48b
CC
5974 dwarf_select_sections_all ();
5975 }
252b5132
RH
5976 else
5977 {
015dc7e1 5978 do_debugging = false;
94585d6d
NC
5979 if (dwarf_select_sections_by_letters (optarg))
5980 {
5981 do_dump = true;
5982 dump_any_debugging = true;
5983 }
252b5132
RH
5984 }
5985 break;
2979dc34 5986 case OPTION_DEBUG_DUMP:
0f03783c 5987 if (optarg == NULL)
d6249f5f 5988 {
94585d6d 5989 do_dump = true;
d6249f5f 5990 do_debugging = true;
94585d6d 5991 dump_any_debugging = true;
d6249f5f
AM
5992 dwarf_select_sections_all ();
5993 }
2979dc34
JJ
5994 else
5995 {
015dc7e1 5996 do_debugging = false;
94585d6d
NC
5997 if (dwarf_select_sections_by_names (optarg))
5998 {
5999 do_dump = true;
6000 dump_any_debugging = true;
6001 }
2979dc34
JJ
6002 }
6003 break;
fd2f0033
TT
6004 case OPTION_DWARF_DEPTH:
6005 {
6006 char *cp;
6007
6008 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6009 }
6010 break;
6011 case OPTION_DWARF_START:
6012 {
6013 char *cp;
6014
6015 dwarf_start_die = strtoul (optarg, & cp, 0);
6016 }
6017 break;
4723351a 6018 case OPTION_DWARF_CHECK:
015dc7e1 6019 dwarf_check = true;
4723351a 6020 break;
7d9813f1 6021 case OPTION_CTF_DUMP:
015dc7e1 6022 do_ctf = true;
6431e409 6023 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6024 break;
6025 case OPTION_CTF_SYMBOLS:
df16e041 6026 free (dump_ctf_symtab_name);
7d9813f1
NA
6027 dump_ctf_symtab_name = strdup (optarg);
6028 break;
6029 case OPTION_CTF_STRINGS:
df16e041 6030 free (dump_ctf_strtab_name);
7d9813f1
NA
6031 dump_ctf_strtab_name = strdup (optarg);
6032 break;
6033 case OPTION_CTF_PARENT:
df16e041 6034 free (dump_ctf_parent_name);
7d9813f1
NA
6035 dump_ctf_parent_name = strdup (optarg);
6036 break;
42b6953b
IB
6037 case OPTION_SFRAME_DUMP:
6038 do_sframe = true;
6039 /* Providing section name is optional. request_dump (), however,
6040 thrives on non NULL optarg. Handle it explicitly here. */
6041 if (optarg != NULL)
6042 request_dump (dumpdata, SFRAME_DUMP);
6043 else
6044 {
6045 do_dump = true;
6046 const char *sframe_sec_name = strdup (".sframe");
6047 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6048 }
6049 break;
2c610e4b 6050 case OPTION_DYN_SYMS:
015dc7e1 6051 do_dyn_syms = true;
2c610e4b 6052 break;
0f03783c 6053 case OPTION_LTO_SYMS:
015dc7e1 6054 do_lto_syms = true;
0f03783c 6055 break;
b6ac461a
NC
6056 case 'X':
6057 extra_sym_info = true;
6058 break;
6059 case OPTION_NO_EXTRA_SYM_INFO:
6060 extra_sym_info = false;
6061 break;
6062
252b5132
RH
6063#ifdef SUPPORT_DISASSEMBLY
6064 case 'i':
6431e409 6065 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6066 break;
252b5132
RH
6067#endif
6068 case 'v':
6069 print_version (program_name);
6070 break;
6071 case 'V':
015dc7e1 6072 do_version = true;
252b5132 6073 break;
d974e256 6074 case 'W':
015dc7e1 6075 do_wide = true;
d974e256 6076 break;
0942c7ab 6077 case 'T':
015dc7e1 6078 do_not_show_symbol_truncation = true;
0942c7ab 6079 break;
79bc120c 6080 case 'C':
015dc7e1 6081 do_demangle = true;
79bc120c
NC
6082 if (optarg != NULL)
6083 {
6084 enum demangling_styles style;
6085
6086 style = cplus_demangle_name_to_style (optarg);
6087 if (style == unknown_demangling)
6088 error (_("unknown demangling style `%s'"), optarg);
6089
6090 cplus_demangle_set_style (style);
6091 }
6092 break;
6093 case OPTION_NO_DEMANGLING:
015dc7e1 6094 do_demangle = false;
79bc120c
NC
6095 break;
6096 case OPTION_RECURSE_LIMIT:
6097 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6098 break;
6099 case OPTION_NO_RECURSE_LIMIT:
6100 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6101 break;
6102 case OPTION_WITH_SYMBOL_VERSIONS:
6103 /* Ignored for backward compatibility. */
6104 break;
b9e920ec 6105
b3aa80b4
NC
6106 case 'U':
6107 if (optarg == NULL)
6108 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6109 else if (streq (optarg, "default") || streq (optarg, "d"))
6110 unicode_display = unicode_default;
6111 else if (streq (optarg, "locale") || streq (optarg, "l"))
6112 unicode_display = unicode_locale;
6113 else if (streq (optarg, "escape") || streq (optarg, "e"))
6114 unicode_display = unicode_escape;
6115 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6116 unicode_display = unicode_invalid;
6117 else if (streq (optarg, "hex") || streq (optarg, "x"))
6118 unicode_display = unicode_hex;
6119 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6120 unicode_display = unicode_highlight;
6121 else
6122 error (_("invalid argument to -U/--unicode: %s"), optarg);
6123 break;
6124
047c3dbf
NL
6125 case OPTION_SYM_BASE:
6126 sym_base = 0;
6127 if (optarg != NULL)
6128 {
6129 sym_base = strtoul (optarg, NULL, 0);
6130 switch (sym_base)
6131 {
6132 case 0:
6133 case 8:
6134 case 10:
6135 case 16:
6136 break;
6137
6138 default:
6139 sym_base = 0;
6140 break;
6141 }
6142 }
6143 break;
6144
252b5132 6145 default:
252b5132
RH
6146 /* xgettext:c-format */
6147 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6148 /* Fall through. */
252b5132 6149 case '?':
92f01d61 6150 usage (stderr);
252b5132
RH
6151 }
6152 }
6153
4d6ed7c8 6154 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6155 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6156 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6157 && !do_section_groups && !do_archive_index
0f03783c 6158 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6159 {
6160 if (do_checks)
6161 {
015dc7e1
AM
6162 check_all = true;
6163 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6164 do_segments = do_header = do_dump = do_version = true;
6165 do_histogram = do_debugging = do_arch = do_notes = true;
6166 do_section_groups = do_archive_index = do_dyn_syms = true;
6167 do_lto_syms = true;
1b513401
NC
6168 }
6169 else
6170 usage (stderr);
6171 }
252b5132
RH
6172}
6173
6174static const char *
d3ba0551 6175get_elf_class (unsigned int elf_class)
252b5132 6176{
b34976b6 6177 static char buff[32];
103f02d3 6178
252b5132
RH
6179 switch (elf_class)
6180 {
6181 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6182 case ELFCLASS32: return "ELF32";
6183 case ELFCLASS64: return "ELF64";
ab5e7794 6184 default:
e9e44622 6185 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6186 return buff;
252b5132
RH
6187 }
6188}
6189
6190static const char *
d3ba0551 6191get_data_encoding (unsigned int encoding)
252b5132 6192{
b34976b6 6193 static char buff[32];
103f02d3 6194
252b5132
RH
6195 switch (encoding)
6196 {
6197 case ELFDATANONE: return _("none");
33c63f9d
CM
6198 case ELFDATA2LSB: return _("2's complement, little endian");
6199 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6200 default:
e9e44622 6201 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6202 return buff;
252b5132
RH
6203 }
6204}
6205
521f7268
NC
6206static bool
6207check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6208{
6209 if (header->e_ident[EI_MAG0] == ELFMAG0
6210 && header->e_ident[EI_MAG1] == ELFMAG1
6211 && header->e_ident[EI_MAG2] == ELFMAG2
6212 && header->e_ident[EI_MAG3] == ELFMAG3)
6213 return true;
6214
6215 /* Some compilers produce object files that are not in the ELF file format.
6216 As an aid to users of readelf, try to identify these cases and suggest
6217 alternative tools.
6218
6219 FIXME: It is not clear if all four bytes are used as constant magic
6220 valus by all compilers. It may be necessary to recode this function if
6221 different tools use different length sequences. */
6222
6223 static struct
6224 {
6225 unsigned char magic[4];
6226 const char * obj_message;
6227 const char * ar_message;
6228 }
6229 known_magic[] =
6230 {
6231 { { 'B', 'C', 0xc0, 0xde },
6232 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6233 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6234 },
6235 { { 'g', 'o', ' ', 'o' },
6236 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6237 NULL
6238 }
6239 };
6240 int i;
6241
6242 for (i = ARRAY_SIZE (known_magic); i--;)
6243 {
6244 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6245 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6246 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6247 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6248 {
6249 /* Some compiler's analyzer tools do not handle archives,
6250 so we provide two different kinds of error message. */
6251 if (filedata->archive_file_size > 0
6252 && known_magic[i].ar_message != NULL)
b3ea2010 6253 error ("%s", known_magic[i].ar_message);
521f7268 6254 else
b3ea2010 6255 error ("%s", known_magic[i].obj_message);
521f7268
NC
6256 return false;
6257 }
6258 }
6259
6260 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6261 return false;
6262}
6263
dda8d76d 6264/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6265
015dc7e1 6266static bool
dda8d76d 6267process_file_header (Filedata * filedata)
252b5132 6268{
dda8d76d
NC
6269 Elf_Internal_Ehdr * header = & filedata->file_header;
6270
521f7268
NC
6271 if (! check_magic_number (filedata, header))
6272 return false;
252b5132 6273
ca0e11aa
NC
6274 if (! filedata->is_separate)
6275 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6276
252b5132
RH
6277 if (do_header)
6278 {
32ec8896 6279 unsigned i;
252b5132 6280
ca0e11aa
NC
6281 if (filedata->is_separate)
6282 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6283 else
6284 printf (_("ELF Header:\n"));
252b5132 6285 printf (_(" Magic: "));
b34976b6 6286 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6287 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6288 printf ("\n");
6289 printf (_(" Class: %s\n"),
dda8d76d 6290 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6291 printf (_(" Data: %s\n"),
dda8d76d 6292 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6293 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6294 header->e_ident[EI_VERSION],
6295 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6296 ? _(" (current)")
dda8d76d 6297 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6298 ? _(" <unknown>")
789be9f7 6299 : "")));
252b5132 6300 printf (_(" OS/ABI: %s\n"),
dda8d76d 6301 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6302 printf (_(" ABI Version: %d\n"),
dda8d76d 6303 header->e_ident[EI_ABIVERSION]);
252b5132 6304 printf (_(" Type: %s\n"),
93df3340 6305 get_file_type (filedata));
252b5132 6306 printf (_(" Machine: %s\n"),
dda8d76d 6307 get_machine_name (header->e_machine));
252b5132 6308 printf (_(" Version: 0x%lx\n"),
e8a64888 6309 header->e_version);
76da6bbe 6310
f7a99963 6311 printf (_(" Entry point address: "));
e8a64888 6312 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6313 printf (_("\n Start of program headers: "));
e8a64888 6314 print_vma (header->e_phoff, DEC);
f7a99963 6315 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6316 print_vma (header->e_shoff, DEC);
f7a99963 6317 printf (_(" (bytes into file)\n"));
76da6bbe 6318
252b5132 6319 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6320 header->e_flags,
dda8d76d 6321 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6322 printf (_(" Size of this header: %u (bytes)\n"),
6323 header->e_ehsize);
6324 printf (_(" Size of program headers: %u (bytes)\n"),
6325 header->e_phentsize);
6326 printf (_(" Number of program headers: %u"),
6327 header->e_phnum);
dda8d76d
NC
6328 if (filedata->section_headers != NULL
6329 && header->e_phnum == PN_XNUM
6330 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6331 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6332 putc ('\n', stdout);
e8a64888
AM
6333 printf (_(" Size of section headers: %u (bytes)\n"),
6334 header->e_shentsize);
6335 printf (_(" Number of section headers: %u"),
6336 header->e_shnum);
dda8d76d 6337 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6338 {
6339 header->e_shnum = filedata->section_headers[0].sh_size;
6340 printf (" (%u)", header->e_shnum);
6341 }
560f3c1c 6342 putc ('\n', stdout);
e8a64888
AM
6343 printf (_(" Section header string table index: %u"),
6344 header->e_shstrndx);
dda8d76d
NC
6345 if (filedata->section_headers != NULL
6346 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6347 {
6348 header->e_shstrndx = filedata->section_headers[0].sh_link;
6349 printf (" (%u)", header->e_shstrndx);
6350 }
6351 if (header->e_shstrndx != SHN_UNDEF
6352 && header->e_shstrndx >= header->e_shnum)
6353 {
6354 header->e_shstrndx = SHN_UNDEF;
6355 printf (_(" <corrupt: out of range>"));
6356 }
560f3c1c
AM
6357 putc ('\n', stdout);
6358 }
6359
dda8d76d 6360 if (filedata->section_headers != NULL)
560f3c1c 6361 {
dda8d76d
NC
6362 if (header->e_phnum == PN_XNUM
6363 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6364 {
6365 /* Throw away any cached read of PN_XNUM headers. */
6366 free (filedata->program_headers);
6367 filedata->program_headers = NULL;
6368 header->e_phnum = filedata->section_headers[0].sh_info;
6369 }
dda8d76d
NC
6370 if (header->e_shnum == SHN_UNDEF)
6371 header->e_shnum = filedata->section_headers[0].sh_size;
6372 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6373 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6374 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6375 header->e_shstrndx = SHN_UNDEF;
252b5132 6376 }
103f02d3 6377
015dc7e1 6378 return true;
9ea033b2
NC
6379}
6380
dda8d76d
NC
6381/* Read in the program headers from FILEDATA and store them in PHEADERS.
6382 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6383
015dc7e1 6384static bool
dda8d76d 6385get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6386{
2cf0635d
NC
6387 Elf32_External_Phdr * phdrs;
6388 Elf32_External_Phdr * external;
6389 Elf_Internal_Phdr * internal;
b34976b6 6390 unsigned int i;
dda8d76d
NC
6391 unsigned int size = filedata->file_header.e_phentsize;
6392 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6393
6394 /* PR binutils/17531: Cope with unexpected section header sizes. */
6395 if (size == 0 || num == 0)
015dc7e1 6396 return false;
e0a31db1
NC
6397 if (size < sizeof * phdrs)
6398 {
6399 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6400 return false;
e0a31db1
NC
6401 }
6402 if (size > sizeof * phdrs)
6403 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6404
dda8d76d 6405 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6406 size, num, _("program headers"));
6407 if (phdrs == NULL)
015dc7e1 6408 return false;
9ea033b2 6409
91d6fa6a 6410 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6411 i < filedata->file_header.e_phnum;
b34976b6 6412 i++, internal++, external++)
252b5132 6413 {
9ea033b2
NC
6414 internal->p_type = BYTE_GET (external->p_type);
6415 internal->p_offset = BYTE_GET (external->p_offset);
6416 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6417 internal->p_paddr = BYTE_GET (external->p_paddr);
6418 internal->p_filesz = BYTE_GET (external->p_filesz);
6419 internal->p_memsz = BYTE_GET (external->p_memsz);
6420 internal->p_flags = BYTE_GET (external->p_flags);
6421 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6422 }
6423
9ea033b2 6424 free (phdrs);
015dc7e1 6425 return true;
252b5132
RH
6426}
6427
dda8d76d
NC
6428/* Read in the program headers from FILEDATA and store them in PHEADERS.
6429 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6430
015dc7e1 6431static bool
dda8d76d 6432get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6433{
2cf0635d
NC
6434 Elf64_External_Phdr * phdrs;
6435 Elf64_External_Phdr * external;
6436 Elf_Internal_Phdr * internal;
b34976b6 6437 unsigned int i;
dda8d76d
NC
6438 unsigned int size = filedata->file_header.e_phentsize;
6439 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6440
6441 /* PR binutils/17531: Cope with unexpected section header sizes. */
6442 if (size == 0 || num == 0)
015dc7e1 6443 return false;
e0a31db1
NC
6444 if (size < sizeof * phdrs)
6445 {
6446 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6447 return false;
e0a31db1
NC
6448 }
6449 if (size > sizeof * phdrs)
6450 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6451
dda8d76d 6452 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6453 size, num, _("program headers"));
a6e9f9df 6454 if (!phdrs)
015dc7e1 6455 return false;
9ea033b2 6456
91d6fa6a 6457 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6458 i < filedata->file_header.e_phnum;
b34976b6 6459 i++, internal++, external++)
9ea033b2
NC
6460 {
6461 internal->p_type = BYTE_GET (external->p_type);
6462 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6463 internal->p_offset = BYTE_GET (external->p_offset);
6464 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6465 internal->p_paddr = BYTE_GET (external->p_paddr);
6466 internal->p_filesz = BYTE_GET (external->p_filesz);
6467 internal->p_memsz = BYTE_GET (external->p_memsz);
6468 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6469 }
6470
6471 free (phdrs);
015dc7e1 6472 return true;
9ea033b2 6473}
252b5132 6474
32ec8896 6475/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6476
015dc7e1 6477static bool
dda8d76d 6478get_program_headers (Filedata * filedata)
d93f0186 6479{
2cf0635d 6480 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6481
6482 /* Check cache of prior read. */
dda8d76d 6483 if (filedata->program_headers != NULL)
015dc7e1 6484 return true;
d93f0186 6485
82156ab7
NC
6486 /* Be kind to memory checkers by looking for
6487 e_phnum values which we know must be invalid. */
dda8d76d 6488 if (filedata->file_header.e_phnum
82156ab7 6489 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6490 >= filedata->file_size)
82156ab7
NC
6491 {
6492 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6493 filedata->file_header.e_phnum);
015dc7e1 6494 return false;
82156ab7 6495 }
d93f0186 6496
dda8d76d 6497 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6498 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6499 if (phdrs == NULL)
6500 {
8b73c356 6501 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6502 filedata->file_header.e_phnum);
015dc7e1 6503 return false;
d93f0186
NC
6504 }
6505
6506 if (is_32bit_elf
dda8d76d
NC
6507 ? get_32bit_program_headers (filedata, phdrs)
6508 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6509 {
dda8d76d 6510 filedata->program_headers = phdrs;
015dc7e1 6511 return true;
d93f0186
NC
6512 }
6513
6514 free (phdrs);
015dc7e1 6515 return false;
d93f0186
NC
6516}
6517
93df3340 6518/* Print program header info and locate dynamic section. */
2f62977e 6519
93df3340 6520static void
dda8d76d 6521process_program_headers (Filedata * filedata)
252b5132 6522{
2cf0635d 6523 Elf_Internal_Phdr * segment;
b34976b6 6524 unsigned int i;
1a9ccd70 6525 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6526
dda8d76d 6527 if (filedata->file_header.e_phnum == 0)
252b5132 6528 {
82f2dbf7 6529 /* PR binutils/12467. */
dda8d76d 6530 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6531 warn (_("possibly corrupt ELF header - it has a non-zero program"
6532 " header offset, but no program headers\n"));
82f2dbf7 6533 else if (do_segments)
ca0e11aa
NC
6534 {
6535 if (filedata->is_separate)
6536 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6537 filedata->file_name);
6538 else
6539 printf (_("\nThere are no program headers in this file.\n"));
6540 }
93df3340 6541 goto no_headers;
252b5132
RH
6542 }
6543
6544 if (do_segments && !do_header)
6545 {
ca0e11aa
NC
6546 if (filedata->is_separate)
6547 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6548 filedata->file_name, get_file_type (filedata));
ca0e11aa 6549 else
93df3340 6550 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6551 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6552 filedata->file_header.e_entry);
b8281767
AM
6553 printf (ngettext ("There is %d program header,"
6554 " starting at offset %" PRIu64 "\n",
6555 "There are %d program headers,"
6556 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6557 filedata->file_header.e_phnum),
6558 filedata->file_header.e_phnum,
625d49fc 6559 filedata->file_header.e_phoff);
252b5132
RH
6560 }
6561
dda8d76d 6562 if (! get_program_headers (filedata))
93df3340 6563 goto no_headers;
103f02d3 6564
252b5132
RH
6565 if (do_segments)
6566 {
dda8d76d 6567 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6568 printf (_("\nProgram Headers:\n"));
6569 else
6570 printf (_("\nProgram Headers:\n"));
76da6bbe 6571
f7a99963
NC
6572 if (is_32bit_elf)
6573 printf
6574 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6575 else if (do_wide)
6576 printf
6577 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6578 else
6579 {
6580 printf
6581 (_(" Type Offset VirtAddr PhysAddr\n"));
6582 printf
6583 (_(" FileSiz MemSiz Flags Align\n"));
6584 }
252b5132
RH
6585 }
6586
26c527e6 6587 uint64_t dynamic_addr = 0;
be7d229a 6588 uint64_t dynamic_size = 0;
dda8d76d
NC
6589 for (i = 0, segment = filedata->program_headers;
6590 i < filedata->file_header.e_phnum;
b34976b6 6591 i++, segment++)
252b5132
RH
6592 {
6593 if (do_segments)
6594 {
dda8d76d 6595 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6596
6597 if (is_32bit_elf)
6598 {
6599 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6600 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6601 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6602 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6603 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6604 printf ("%c%c%c ",
6605 (segment->p_flags & PF_R ? 'R' : ' '),
6606 (segment->p_flags & PF_W ? 'W' : ' '),
6607 (segment->p_flags & PF_X ? 'E' : ' '));
6608 printf ("%#lx", (unsigned long) segment->p_align);
6609 }
d974e256
JJ
6610 else if (do_wide)
6611 {
6612 if ((unsigned long) segment->p_offset == segment->p_offset)
6613 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6614 else
6615 {
6616 print_vma (segment->p_offset, FULL_HEX);
6617 putchar (' ');
6618 }
6619
6620 print_vma (segment->p_vaddr, FULL_HEX);
6621 putchar (' ');
6622 print_vma (segment->p_paddr, FULL_HEX);
6623 putchar (' ');
6624
6625 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6626 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6627 else
6628 {
6629 print_vma (segment->p_filesz, FULL_HEX);
6630 putchar (' ');
6631 }
6632
6633 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6634 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6635 else
6636 {
f48e6c45 6637 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6638 }
6639
6640 printf (" %c%c%c ",
6641 (segment->p_flags & PF_R ? 'R' : ' '),
6642 (segment->p_flags & PF_W ? 'W' : ' '),
6643 (segment->p_flags & PF_X ? 'E' : ' '));
6644
6645 if ((unsigned long) segment->p_align == segment->p_align)
6646 printf ("%#lx", (unsigned long) segment->p_align);
6647 else
6648 {
6649 print_vma (segment->p_align, PREFIX_HEX);
6650 }
6651 }
f7a99963
NC
6652 else
6653 {
6654 print_vma (segment->p_offset, FULL_HEX);
6655 putchar (' ');
6656 print_vma (segment->p_vaddr, FULL_HEX);
6657 putchar (' ');
6658 print_vma (segment->p_paddr, FULL_HEX);
6659 printf ("\n ");
6660 print_vma (segment->p_filesz, FULL_HEX);
6661 putchar (' ');
6662 print_vma (segment->p_memsz, FULL_HEX);
6663 printf (" %c%c%c ",
6664 (segment->p_flags & PF_R ? 'R' : ' '),
6665 (segment->p_flags & PF_W ? 'W' : ' '),
6666 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6667 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6668 }
252b5132 6669
1a9ccd70
NC
6670 putc ('\n', stdout);
6671 }
f54498b4 6672
252b5132
RH
6673 switch (segment->p_type)
6674 {
1a9ccd70 6675 case PT_LOAD:
502d895c
NC
6676#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6677 required by the ELF standard, several programs, including the Linux
6678 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6679 if (previous_load
6680 && previous_load->p_vaddr > segment->p_vaddr)
6681 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6682#endif
1a9ccd70
NC
6683 if (segment->p_memsz < segment->p_filesz)
6684 error (_("the segment's file size is larger than its memory size\n"));
6685 previous_load = segment;
6686 break;
6687
6688 case PT_PHDR:
6689 /* PR 20815 - Verify that the program header is loaded into memory. */
6690 if (i > 0 && previous_load != NULL)
6691 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6692 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6693 {
6694 unsigned int j;
6695
dda8d76d 6696 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6697 {
6698 Elf_Internal_Phdr *load = filedata->program_headers + j;
6699 if (load->p_type == PT_LOAD
6700 && load->p_offset <= segment->p_offset
6701 && (load->p_offset + load->p_filesz
6702 >= segment->p_offset + segment->p_filesz)
6703 && load->p_vaddr <= segment->p_vaddr
6704 && (load->p_vaddr + load->p_filesz
6705 >= segment->p_vaddr + segment->p_filesz))
6706 break;
6707 }
dda8d76d 6708 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6709 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6710 }
6711 break;
6712
252b5132 6713 case PT_DYNAMIC:
93df3340 6714 if (dynamic_addr)
252b5132
RH
6715 error (_("more than one dynamic segment\n"));
6716
20737c13
AM
6717 /* By default, assume that the .dynamic section is the first
6718 section in the DYNAMIC segment. */
93df3340
AM
6719 dynamic_addr = segment->p_offset;
6720 dynamic_size = segment->p_filesz;
20737c13 6721
b2d38a17
NC
6722 /* Try to locate the .dynamic section. If there is
6723 a section header table, we can easily locate it. */
dda8d76d 6724 if (filedata->section_headers != NULL)
b2d38a17 6725 {
2cf0635d 6726 Elf_Internal_Shdr * sec;
b2d38a17 6727
dda8d76d 6728 sec = find_section (filedata, ".dynamic");
89fac5e3 6729 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6730 {
93df3340
AM
6731 /* A corresponding .dynamic section is expected, but on
6732 IA-64/OpenVMS it is OK for it to be missing. */
6733 if (!is_ia64_vms (filedata))
6734 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6735 break;
6736 }
6737
42bb2e33 6738 if (sec->sh_type == SHT_NOBITS)
20737c13 6739 {
93df3340
AM
6740 dynamic_addr = 0;
6741 dynamic_size = 0;
20737c13
AM
6742 break;
6743 }
42bb2e33 6744
93df3340
AM
6745 dynamic_addr = sec->sh_offset;
6746 dynamic_size = sec->sh_size;
b2d38a17 6747
8ac10c5b
L
6748 /* The PT_DYNAMIC segment, which is used by the run-time
6749 loader, should exactly match the .dynamic section. */
6750 if (do_checks
93df3340
AM
6751 && (dynamic_addr != segment->p_offset
6752 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6753 warn (_("\
6754the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6755 }
39e224f6
MW
6756
6757 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6758 segment. Check this after matching against the section headers
6759 so we don't warn on debuginfo file (which have NOBITS .dynamic
6760 sections). */
93df3340
AM
6761 if (dynamic_addr > filedata->file_size
6762 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6763 {
6764 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6765 dynamic_addr = 0;
6766 dynamic_size = 0;
39e224f6 6767 }
252b5132
RH
6768 break;
6769
6770 case PT_INTERP:
13acb58d
AM
6771 if (segment->p_offset >= filedata->file_size
6772 || segment->p_filesz > filedata->file_size - segment->p_offset
6773 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6774 || fseek64 (filedata->handle,
6775 filedata->archive_file_offset + segment->p_offset,
6776 SEEK_SET))
252b5132
RH
6777 error (_("Unable to find program interpreter name\n"));
6778 else
6779 {
13acb58d
AM
6780 size_t len = segment->p_filesz;
6781 free (filedata->program_interpreter);
6782 filedata->program_interpreter = xmalloc (len + 1);
6783 len = fread (filedata->program_interpreter, 1, len,
6784 filedata->handle);
6785 filedata->program_interpreter[len] = 0;
252b5132
RH
6786
6787 if (do_segments)
f54498b4 6788 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6789 filedata->program_interpreter);
252b5132
RH
6790 }
6791 break;
6792 }
252b5132
RH
6793 }
6794
dda8d76d
NC
6795 if (do_segments
6796 && filedata->section_headers != NULL
6797 && filedata->string_table != NULL)
252b5132
RH
6798 {
6799 printf (_("\n Section to Segment mapping:\n"));
6800 printf (_(" Segment Sections...\n"));
6801
dda8d76d 6802 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6803 {
9ad5cbcf 6804 unsigned int j;
2cf0635d 6805 Elf_Internal_Shdr * section;
252b5132 6806
dda8d76d
NC
6807 segment = filedata->program_headers + i;
6808 section = filedata->section_headers + 1;
252b5132
RH
6809
6810 printf (" %2.2d ", i);
6811
dda8d76d 6812 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6813 {
f4638467
AM
6814 if (!ELF_TBSS_SPECIAL (section, segment)
6815 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6816 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6817 }
6818
6819 putc ('\n',stdout);
6820 }
6821 }
6822
93df3340
AM
6823 filedata->dynamic_addr = dynamic_addr;
6824 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6825 return;
6826
6827 no_headers:
6828 filedata->dynamic_addr = 0;
6829 filedata->dynamic_size = 1;
252b5132
RH
6830}
6831
6832
d93f0186
NC
6833/* Find the file offset corresponding to VMA by using the program headers. */
6834
26c527e6 6835static int64_t
625d49fc 6836offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 6837{
2cf0635d 6838 Elf_Internal_Phdr * seg;
d93f0186 6839
dda8d76d 6840 if (! get_program_headers (filedata))
d93f0186
NC
6841 {
6842 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6843 return (long) vma;
6844 }
6845
dda8d76d
NC
6846 for (seg = filedata->program_headers;
6847 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6848 ++seg)
6849 {
6850 if (seg->p_type != PT_LOAD)
6851 continue;
6852
6853 if (vma >= (seg->p_vaddr & -seg->p_align)
6854 && vma + size <= seg->p_vaddr + seg->p_filesz)
6855 return vma - seg->p_vaddr + seg->p_offset;
6856 }
6857
26c527e6
AM
6858 warn (_("Virtual address %#" PRIx64
6859 " not located in any PT_LOAD segment.\n"), vma);
6860 return vma;
d93f0186
NC
6861}
6862
6863
dda8d76d
NC
6864/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6865 If PROBE is true, this is just a probe and we do not generate any error
6866 messages if the load fails. */
049b0c3a 6867
015dc7e1
AM
6868static bool
6869get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6870{
2cf0635d
NC
6871 Elf32_External_Shdr * shdrs;
6872 Elf_Internal_Shdr * internal;
dda8d76d
NC
6873 unsigned int i;
6874 unsigned int size = filedata->file_header.e_shentsize;
6875 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6876
6877 /* PR binutils/17531: Cope with unexpected section header sizes. */
6878 if (size == 0 || num == 0)
015dc7e1 6879 return false;
907b52f4
NC
6880
6881 /* The section header cannot be at the start of the file - that is
6882 where the ELF file header is located. A file with absolutely no
6883 sections in it will use a shoff of 0. */
6884 if (filedata->file_header.e_shoff == 0)
6885 return false;
6886
049b0c3a
NC
6887 if (size < sizeof * shdrs)
6888 {
6889 if (! probe)
6890 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6891 return false;
049b0c3a
NC
6892 }
6893 if (!probe && size > sizeof * shdrs)
6894 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6895
dda8d76d 6896 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6897 size, num,
6898 probe ? NULL : _("section headers"));
6899 if (shdrs == NULL)
015dc7e1 6900 return false;
252b5132 6901
dda8d76d
NC
6902 filedata->section_headers = (Elf_Internal_Shdr *)
6903 cmalloc (num, sizeof (Elf_Internal_Shdr));
6904 if (filedata->section_headers == NULL)
252b5132 6905 {
049b0c3a 6906 if (!probe)
8b73c356 6907 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6908 free (shdrs);
015dc7e1 6909 return false;
252b5132
RH
6910 }
6911
dda8d76d 6912 for (i = 0, internal = filedata->section_headers;
560f3c1c 6913 i < num;
b34976b6 6914 i++, internal++)
252b5132
RH
6915 {
6916 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6917 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6918 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6919 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6920 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6921 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6922 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6923 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6924 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6925 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6926 if (!probe && internal->sh_link > num)
6927 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6928 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6929 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6930 }
6931
6932 free (shdrs);
015dc7e1 6933 return true;
252b5132
RH
6934}
6935
dda8d76d
NC
6936/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6937
015dc7e1
AM
6938static bool
6939get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6940{
dda8d76d
NC
6941 Elf64_External_Shdr * shdrs;
6942 Elf_Internal_Shdr * internal;
6943 unsigned int i;
6944 unsigned int size = filedata->file_header.e_shentsize;
6945 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6946
6947 /* PR binutils/17531: Cope with unexpected section header sizes. */
6948 if (size == 0 || num == 0)
015dc7e1 6949 return false;
dda8d76d 6950
907b52f4
NC
6951 /* The section header cannot be at the start of the file - that is
6952 where the ELF file header is located. A file with absolutely no
6953 sections in it will use a shoff of 0. */
6954 if (filedata->file_header.e_shoff == 0)
6955 return false;
6956
049b0c3a
NC
6957 if (size < sizeof * shdrs)
6958 {
6959 if (! probe)
6960 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6961 return false;
049b0c3a 6962 }
dda8d76d 6963
049b0c3a
NC
6964 if (! probe && size > sizeof * shdrs)
6965 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6966
dda8d76d
NC
6967 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6968 filedata->file_header.e_shoff,
049b0c3a
NC
6969 size, num,
6970 probe ? NULL : _("section headers"));
6971 if (shdrs == NULL)
015dc7e1 6972 return false;
9ea033b2 6973
dda8d76d
NC
6974 filedata->section_headers = (Elf_Internal_Shdr *)
6975 cmalloc (num, sizeof (Elf_Internal_Shdr));
6976 if (filedata->section_headers == NULL)
9ea033b2 6977 {
049b0c3a 6978 if (! probe)
8b73c356 6979 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6980 free (shdrs);
015dc7e1 6981 return false;
9ea033b2
NC
6982 }
6983
dda8d76d 6984 for (i = 0, internal = filedata->section_headers;
560f3c1c 6985 i < num;
b34976b6 6986 i++, internal++)
9ea033b2
NC
6987 {
6988 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6989 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6990 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6991 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6992 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6993 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6994 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6995 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6996 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6997 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6998 if (!probe && internal->sh_link > num)
6999 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7000 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7001 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7002 }
7003
7004 free (shdrs);
015dc7e1 7005 return true;
9ea033b2
NC
7006}
7007
4de91c10
AM
7008static bool
7009get_section_headers (Filedata *filedata, bool probe)
7010{
7011 if (filedata->section_headers != NULL)
7012 return true;
7013
4de91c10
AM
7014 if (is_32bit_elf)
7015 return get_32bit_section_headers (filedata, probe);
7016 else
7017 return get_64bit_section_headers (filedata, probe);
7018}
7019
252b5132 7020static Elf_Internal_Sym *
26c527e6
AM
7021get_32bit_elf_symbols (Filedata *filedata,
7022 Elf_Internal_Shdr *section,
7023 uint64_t *num_syms_return)
252b5132 7024{
26c527e6 7025 uint64_t number = 0;
dd24e3da 7026 Elf32_External_Sym * esyms = NULL;
ba5cdace 7027 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7028 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7029 Elf_Internal_Sym * psym;
b34976b6 7030 unsigned int j;
e3d39609 7031 elf_section_list * entry;
252b5132 7032
c9c1d674
EG
7033 if (section->sh_size == 0)
7034 {
7035 if (num_syms_return != NULL)
7036 * num_syms_return = 0;
7037 return NULL;
7038 }
7039
dd24e3da 7040 /* Run some sanity checks first. */
c9c1d674 7041 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7042 {
26c527e6 7043 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7044 printable_section_name (filedata, section),
26c527e6 7045 section->sh_entsize);
ba5cdace 7046 goto exit_point;
dd24e3da
NC
7047 }
7048
dda8d76d 7049 if (section->sh_size > filedata->file_size)
f54498b4 7050 {
26c527e6 7051 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7052 printable_section_name (filedata, section),
26c527e6 7053 section->sh_size);
f54498b4
NC
7054 goto exit_point;
7055 }
7056
dd24e3da
NC
7057 number = section->sh_size / section->sh_entsize;
7058
7059 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7060 {
26c527e6
AM
7061 error (_("Size (%#" PRIx64 ") of section %s "
7062 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7063 section->sh_size,
dda8d76d 7064 printable_section_name (filedata, section),
26c527e6 7065 section->sh_entsize);
ba5cdace 7066 goto exit_point;
dd24e3da
NC
7067 }
7068
dda8d76d 7069 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7070 section->sh_size, _("symbols"));
dd24e3da 7071 if (esyms == NULL)
ba5cdace 7072 goto exit_point;
252b5132 7073
e3d39609 7074 shndx = NULL;
978c4450 7075 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7076 {
26c527e6 7077 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7078 continue;
7079
7080 if (shndx != NULL)
7081 {
7082 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7083 free (shndx);
7084 }
7085
7086 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7087 entry->hdr->sh_offset,
7088 1, entry->hdr->sh_size,
7089 _("symbol table section indices"));
7090 if (shndx == NULL)
7091 goto exit_point;
7092
7093 /* PR17531: file: heap-buffer-overflow */
7094 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7095 {
26c527e6 7096 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7097 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7098 entry->hdr->sh_size,
7099 section->sh_size);
e3d39609 7100 goto exit_point;
c9c1d674 7101 }
e3d39609 7102 }
9ad5cbcf 7103
3f5e193b 7104 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7105
7106 if (isyms == NULL)
7107 {
26c527e6 7108 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7109 goto exit_point;
252b5132
RH
7110 }
7111
dd24e3da 7112 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7113 {
7114 psym->st_name = BYTE_GET (esyms[j].st_name);
7115 psym->st_value = BYTE_GET (esyms[j].st_value);
7116 psym->st_size = BYTE_GET (esyms[j].st_size);
7117 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7118 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7119 psym->st_shndx
7120 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7121 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7122 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7123 psym->st_info = BYTE_GET (esyms[j].st_info);
7124 psym->st_other = BYTE_GET (esyms[j].st_other);
7125 }
7126
dd24e3da 7127 exit_point:
e3d39609
NC
7128 free (shndx);
7129 free (esyms);
252b5132 7130
ba5cdace
NC
7131 if (num_syms_return != NULL)
7132 * num_syms_return = isyms == NULL ? 0 : number;
7133
252b5132
RH
7134 return isyms;
7135}
7136
9ea033b2 7137static Elf_Internal_Sym *
26c527e6
AM
7138get_64bit_elf_symbols (Filedata *filedata,
7139 Elf_Internal_Shdr *section,
7140 uint64_t *num_syms_return)
9ea033b2 7141{
26c527e6 7142 uint64_t number = 0;
ba5cdace
NC
7143 Elf64_External_Sym * esyms = NULL;
7144 Elf_External_Sym_Shndx * shndx = NULL;
7145 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7146 Elf_Internal_Sym * psym;
b34976b6 7147 unsigned int j;
e3d39609 7148 elf_section_list * entry;
9ea033b2 7149
c9c1d674
EG
7150 if (section->sh_size == 0)
7151 {
7152 if (num_syms_return != NULL)
7153 * num_syms_return = 0;
7154 return NULL;
7155 }
7156
dd24e3da 7157 /* Run some sanity checks first. */
c9c1d674 7158 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7159 {
26c527e6 7160 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7161 printable_section_name (filedata, section),
26c527e6 7162 section->sh_entsize);
ba5cdace 7163 goto exit_point;
dd24e3da
NC
7164 }
7165
dda8d76d 7166 if (section->sh_size > filedata->file_size)
f54498b4 7167 {
26c527e6 7168 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7169 printable_section_name (filedata, section),
26c527e6 7170 section->sh_size);
f54498b4
NC
7171 goto exit_point;
7172 }
7173
dd24e3da
NC
7174 number = section->sh_size / section->sh_entsize;
7175
7176 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7177 {
26c527e6
AM
7178 error (_("Size (%#" PRIx64 ") of section %s "
7179 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7180 section->sh_size,
dda8d76d 7181 printable_section_name (filedata, section),
26c527e6 7182 section->sh_entsize);
ba5cdace 7183 goto exit_point;
dd24e3da
NC
7184 }
7185
dda8d76d 7186 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7187 section->sh_size, _("symbols"));
a6e9f9df 7188 if (!esyms)
ba5cdace 7189 goto exit_point;
9ea033b2 7190
e3d39609 7191 shndx = NULL;
978c4450 7192 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7193 {
26c527e6 7194 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7195 continue;
7196
7197 if (shndx != NULL)
7198 {
7199 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7200 free (shndx);
c9c1d674 7201 }
e3d39609
NC
7202
7203 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7204 entry->hdr->sh_offset,
7205 1, entry->hdr->sh_size,
7206 _("symbol table section indices"));
7207 if (shndx == NULL)
7208 goto exit_point;
7209
7210 /* PR17531: file: heap-buffer-overflow */
7211 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7212 {
26c527e6 7213 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7214 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7215 entry->hdr->sh_size,
7216 section->sh_size);
e3d39609
NC
7217 goto exit_point;
7218 }
7219 }
9ad5cbcf 7220
3f5e193b 7221 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7222
7223 if (isyms == NULL)
7224 {
26c527e6 7225 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7226 goto exit_point;
9ea033b2
NC
7227 }
7228
ba5cdace 7229 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7230 {
7231 psym->st_name = BYTE_GET (esyms[j].st_name);
7232 psym->st_info = BYTE_GET (esyms[j].st_info);
7233 psym->st_other = BYTE_GET (esyms[j].st_other);
7234 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7235
4fbb74a6 7236 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7237 psym->st_shndx
7238 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7239 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7240 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7241
66543521
AM
7242 psym->st_value = BYTE_GET (esyms[j].st_value);
7243 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7244 }
7245
ba5cdace 7246 exit_point:
e3d39609
NC
7247 free (shndx);
7248 free (esyms);
ba5cdace
NC
7249
7250 if (num_syms_return != NULL)
7251 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7252
7253 return isyms;
7254}
7255
4de91c10
AM
7256static Elf_Internal_Sym *
7257get_elf_symbols (Filedata *filedata,
7258 Elf_Internal_Shdr *section,
26c527e6 7259 uint64_t *num_syms_return)
4de91c10
AM
7260{
7261 if (is_32bit_elf)
7262 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7263 else
7264 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7265}
7266
d1133906 7267static const char *
625d49fc 7268get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7269{
5477e8a0 7270 static char buff[1024];
2cf0635d 7271 char * p = buff;
32ec8896
NC
7272 unsigned int field_size = is_32bit_elf ? 8 : 16;
7273 signed int sindex;
7274 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7275 uint64_t os_flags = 0;
7276 uint64_t proc_flags = 0;
7277 uint64_t unknown_flags = 0;
148b93f2 7278 static const struct
5477e8a0 7279 {
2cf0635d 7280 const char * str;
32ec8896 7281 unsigned int len;
5477e8a0
L
7282 }
7283 flags [] =
7284 {
cfcac11d
NC
7285 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7286 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7287 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7288 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7289 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7290 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7291 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7292 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7293 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7294 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7295 /* IA-64 specific. */
7296 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7297 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7298 /* IA-64 OpenVMS specific. */
7299 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7300 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7301 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7302 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7303 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7304 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7305 /* Generic. */
cfcac11d 7306 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7307 /* SPARC specific. */
77115a4a 7308 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7309 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7310 /* ARM specific. */
7311 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7312 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7313 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7314 /* GNU specific. */
7315 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7316 /* VLE specific. */
7317 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7318 /* GNU specific. */
7319 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7320 };
7321
7322 if (do_section_details)
f8c4789c
AM
7323 p += sprintf (p, "[%*.*lx]: ",
7324 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7325
d1133906
NC
7326 while (sh_flags)
7327 {
625d49fc 7328 uint64_t flag;
d1133906
NC
7329
7330 flag = sh_flags & - sh_flags;
7331 sh_flags &= ~ flag;
76da6bbe 7332
5477e8a0 7333 if (do_section_details)
d1133906 7334 {
5477e8a0
L
7335 switch (flag)
7336 {
91d6fa6a
NC
7337 case SHF_WRITE: sindex = 0; break;
7338 case SHF_ALLOC: sindex = 1; break;
7339 case SHF_EXECINSTR: sindex = 2; break;
7340 case SHF_MERGE: sindex = 3; break;
7341 case SHF_STRINGS: sindex = 4; break;
7342 case SHF_INFO_LINK: sindex = 5; break;
7343 case SHF_LINK_ORDER: sindex = 6; break;
7344 case SHF_OS_NONCONFORMING: sindex = 7; break;
7345 case SHF_GROUP: sindex = 8; break;
7346 case SHF_TLS: sindex = 9; break;
18ae9cc1 7347 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7348 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7349
5477e8a0 7350 default:
91d6fa6a 7351 sindex = -1;
dda8d76d 7352 switch (filedata->file_header.e_machine)
148b93f2 7353 {
cfcac11d 7354 case EM_IA_64:
148b93f2 7355 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7356 sindex = 10;
148b93f2 7357 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7358 sindex = 11;
dda8d76d 7359 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7360 switch (flag)
7361 {
91d6fa6a
NC
7362 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7363 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7364 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7365 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7366 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7367 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7368 default: break;
7369 }
cfcac11d
NC
7370 break;
7371
caa83f8b 7372 case EM_386:
22abe556 7373 case EM_IAMCU:
caa83f8b 7374 case EM_X86_64:
7f502d6c 7375 case EM_L1OM:
7a9068fe 7376 case EM_K1OM:
cfcac11d
NC
7377 case EM_OLD_SPARCV9:
7378 case EM_SPARC32PLUS:
7379 case EM_SPARCV9:
7380 case EM_SPARC:
18ae9cc1 7381 if (flag == SHF_ORDERED)
91d6fa6a 7382 sindex = 19;
cfcac11d 7383 break;
ac4c9b04
MG
7384
7385 case EM_ARM:
7386 switch (flag)
7387 {
7388 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7389 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7390 case SHF_COMDEF: sindex = 23; break;
7391 default: break;
7392 }
7393 break;
83eef883
AFB
7394 case EM_PPC:
7395 if (flag == SHF_PPC_VLE)
7396 sindex = 25;
7397 break;
99fabbc9
JL
7398 default:
7399 break;
7400 }
ac4c9b04 7401
99fabbc9
JL
7402 switch (filedata->file_header.e_ident[EI_OSABI])
7403 {
7404 case ELFOSABI_GNU:
7405 case ELFOSABI_FREEBSD:
7406 if (flag == SHF_GNU_RETAIN)
7407 sindex = 26;
7408 /* Fall through */
7409 case ELFOSABI_NONE:
7410 if (flag == SHF_GNU_MBIND)
7411 /* We should not recognize SHF_GNU_MBIND for
7412 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7413 not set the EI_OSABI header byte. */
7414 sindex = 24;
7415 break;
cfcac11d
NC
7416 default:
7417 break;
148b93f2 7418 }
99fabbc9 7419 break;
5477e8a0
L
7420 }
7421
91d6fa6a 7422 if (sindex != -1)
5477e8a0 7423 {
8d5ff12c
L
7424 if (p != buff + field_size + 4)
7425 {
7426 if (size < (10 + 2))
bee0ee85
NC
7427 {
7428 warn (_("Internal error: not enough buffer room for section flag info"));
7429 return _("<unknown>");
7430 }
8d5ff12c
L
7431 size -= 2;
7432 *p++ = ',';
7433 *p++ = ' ';
7434 }
7435
91d6fa6a
NC
7436 size -= flags [sindex].len;
7437 p = stpcpy (p, flags [sindex].str);
5477e8a0 7438 }
3b22753a 7439 else if (flag & SHF_MASKOS)
8d5ff12c 7440 os_flags |= flag;
d1133906 7441 else if (flag & SHF_MASKPROC)
8d5ff12c 7442 proc_flags |= flag;
d1133906 7443 else
8d5ff12c 7444 unknown_flags |= flag;
5477e8a0
L
7445 }
7446 else
7447 {
7448 switch (flag)
7449 {
7450 case SHF_WRITE: *p = 'W'; break;
7451 case SHF_ALLOC: *p = 'A'; break;
7452 case SHF_EXECINSTR: *p = 'X'; break;
7453 case SHF_MERGE: *p = 'M'; break;
7454 case SHF_STRINGS: *p = 'S'; break;
7455 case SHF_INFO_LINK: *p = 'I'; break;
7456 case SHF_LINK_ORDER: *p = 'L'; break;
7457 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7458 case SHF_GROUP: *p = 'G'; break;
7459 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7460 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7461 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7462
7463 default:
dda8d76d
NC
7464 if ((filedata->file_header.e_machine == EM_X86_64
7465 || filedata->file_header.e_machine == EM_L1OM
7466 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7467 && flag == SHF_X86_64_LARGE)
7468 *p = 'l';
dda8d76d 7469 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7470 && flag == SHF_ARM_PURECODE)
99fabbc9 7471 *p = 'y';
dda8d76d 7472 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7473 && flag == SHF_PPC_VLE)
99fabbc9 7474 *p = 'v';
5477e8a0
L
7475 else if (flag & SHF_MASKOS)
7476 {
99fabbc9
JL
7477 switch (filedata->file_header.e_ident[EI_OSABI])
7478 {
7479 case ELFOSABI_GNU:
7480 case ELFOSABI_FREEBSD:
7481 if (flag == SHF_GNU_RETAIN)
7482 {
7483 *p = 'R';
7484 break;
7485 }
7486 /* Fall through */
7487 case ELFOSABI_NONE:
7488 if (flag == SHF_GNU_MBIND)
7489 {
7490 /* We should not recognize SHF_GNU_MBIND for
7491 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7492 not set the EI_OSABI header byte. */
7493 *p = 'D';
7494 break;
7495 }
7496 /* Fall through */
7497 default:
7498 *p = 'o';
7499 sh_flags &= ~SHF_MASKOS;
7500 break;
7501 }
5477e8a0
L
7502 }
7503 else if (flag & SHF_MASKPROC)
7504 {
7505 *p = 'p';
7506 sh_flags &= ~ SHF_MASKPROC;
7507 }
7508 else
7509 *p = 'x';
7510 break;
7511 }
7512 p++;
d1133906
NC
7513 }
7514 }
76da6bbe 7515
8d5ff12c
L
7516 if (do_section_details)
7517 {
7518 if (os_flags)
7519 {
8d5ff12c
L
7520 if (p != buff + field_size + 4)
7521 {
f8c4789c 7522 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7523 {
7524 warn (_("Internal error: not enough buffer room for section flag info"));
7525 return _("<unknown>");
7526 }
8d5ff12c
L
7527 size -= 2;
7528 *p++ = ',';
7529 *p++ = ' ';
7530 }
f8c4789c
AM
7531 size -= 5 + field_size;
7532 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7533 (unsigned long) os_flags);
8d5ff12c
L
7534 }
7535 if (proc_flags)
7536 {
8d5ff12c
L
7537 if (p != buff + field_size + 4)
7538 {
f8c4789c 7539 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7540 {
7541 warn (_("Internal error: not enough buffer room for section flag info"));
7542 return _("<unknown>");
7543 }
8d5ff12c
L
7544 size -= 2;
7545 *p++ = ',';
7546 *p++ = ' ';
7547 }
f8c4789c
AM
7548 size -= 7 + field_size;
7549 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7550 (unsigned long) proc_flags);
8d5ff12c
L
7551 }
7552 if (unknown_flags)
7553 {
8d5ff12c
L
7554 if (p != buff + field_size + 4)
7555 {
f8c4789c 7556 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7557 {
7558 warn (_("Internal error: not enough buffer room for section flag info"));
7559 return _("<unknown>");
7560 }
8d5ff12c
L
7561 size -= 2;
7562 *p++ = ',';
7563 *p++ = ' ';
7564 }
f8c4789c
AM
7565 size -= 10 + field_size;
7566 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7567 (unsigned long) unknown_flags);
8d5ff12c
L
7568 }
7569 }
7570
e9e44622 7571 *p = '\0';
d1133906
NC
7572 return buff;
7573}
7574
5844b465 7575static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7576get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7577 uint64_t size)
77115a4a
L
7578{
7579 if (is_32bit_elf)
7580 {
7581 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7582
ebdf1ebf
NC
7583 if (size < sizeof (* echdr))
7584 {
7585 error (_("Compressed section is too small even for a compression header\n"));
7586 return 0;
7587 }
7588
77115a4a
L
7589 chdr->ch_type = BYTE_GET (echdr->ch_type);
7590 chdr->ch_size = BYTE_GET (echdr->ch_size);
7591 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7592 return sizeof (*echdr);
7593 }
7594 else
7595 {
7596 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7597
ebdf1ebf
NC
7598 if (size < sizeof (* echdr))
7599 {
7600 error (_("Compressed section is too small even for a compression header\n"));
7601 return 0;
7602 }
7603
77115a4a
L
7604 chdr->ch_type = BYTE_GET (echdr->ch_type);
7605 chdr->ch_size = BYTE_GET (echdr->ch_size);
7606 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7607 return sizeof (*echdr);
7608 }
7609}
7610
015dc7e1 7611static bool
dda8d76d 7612process_section_headers (Filedata * filedata)
252b5132 7613{
2cf0635d 7614 Elf_Internal_Shdr * section;
b34976b6 7615 unsigned int i;
252b5132 7616
dda8d76d 7617 if (filedata->file_header.e_shnum == 0)
252b5132 7618 {
82f2dbf7 7619 /* PR binutils/12467. */
dda8d76d 7620 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7621 {
7622 warn (_("possibly corrupt ELF file header - it has a non-zero"
7623 " section header offset, but no section headers\n"));
015dc7e1 7624 return false;
32ec8896 7625 }
82f2dbf7 7626 else if (do_sections)
252b5132
RH
7627 printf (_("\nThere are no sections in this file.\n"));
7628
015dc7e1 7629 return true;
252b5132
RH
7630 }
7631
7632 if (do_sections && !do_header)
ca0e11aa
NC
7633 {
7634 if (filedata->is_separate && process_links)
7635 printf (_("In linked file '%s': "), filedata->file_name);
7636 if (! filedata->is_separate || process_links)
7637 printf (ngettext ("There is %d section header, "
26c527e6 7638 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7639 "There are %d section headers, "
26c527e6 7640 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7641 filedata->file_header.e_shnum),
7642 filedata->file_header.e_shnum,
26c527e6 7643 filedata->file_header.e_shoff);
ca0e11aa 7644 }
252b5132 7645
4de91c10
AM
7646 if (!get_section_headers (filedata, false))
7647 return false;
252b5132
RH
7648
7649 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7650 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7651 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7652 {
dda8d76d 7653 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7654
c256ffe7
JJ
7655 if (section->sh_size != 0)
7656 {
dda8d76d
NC
7657 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7658 1, section->sh_size,
7659 _("string table"));
0de14b54 7660
dda8d76d 7661 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7662 }
252b5132
RH
7663 }
7664
7665 /* Scan the sections for the dynamic symbol table
e3c8793a 7666 and dynamic string table and debug sections. */
89fac5e3 7667 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7668 switch (filedata->file_header.e_machine)
89fac5e3
RS
7669 {
7670 case EM_MIPS:
7671 case EM_MIPS_RS3_LE:
7672 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7673 FDE addresses. However, the ABI also has a semi-official ILP32
7674 variant for which the normal FDE address size rules apply.
7675
7676 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7677 section, where XX is the size of longs in bits. Unfortunately,
7678 earlier compilers provided no way of distinguishing ILP32 objects
7679 from LP64 objects, so if there's any doubt, we should assume that
7680 the official LP64 form is being used. */
dda8d76d
NC
7681 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
7682 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7683 eh_addr_size = 8;
7684 break;
0f56a26a
DD
7685
7686 case EM_H8_300:
7687 case EM_H8_300H:
dda8d76d 7688 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7689 {
7690 case E_H8_MACH_H8300:
7691 case E_H8_MACH_H8300HN:
7692 case E_H8_MACH_H8300SN:
7693 case E_H8_MACH_H8300SXN:
7694 eh_addr_size = 2;
7695 break;
7696 case E_H8_MACH_H8300H:
7697 case E_H8_MACH_H8300S:
7698 case E_H8_MACH_H8300SX:
7699 eh_addr_size = 4;
7700 break;
7701 }
f4236fe4
DD
7702 break;
7703
ff7eeb89 7704 case EM_M32C_OLD:
f4236fe4 7705 case EM_M32C:
dda8d76d 7706 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7707 {
7708 case EF_M32C_CPU_M16C:
7709 eh_addr_size = 2;
7710 break;
7711 }
7712 break;
89fac5e3
RS
7713 }
7714
76ca31c0
NC
7715#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7716 do \
7717 { \
be7d229a 7718 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7719 if (section->sh_entsize != expected_entsize) \
9dd3a467 7720 { \
f493c217 7721 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7722 i, section->sh_entsize); \
f493c217 7723 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7724 expected_entsize); \
9dd3a467 7725 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7726 } \
7727 } \
08d8fa11 7728 while (0)
9dd3a467
NC
7729
7730#define CHECK_ENTSIZE(section, i, type) \
1b513401 7731 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7732 sizeof (Elf64_External_##type))
7733
dda8d76d
NC
7734 for (i = 0, section = filedata->section_headers;
7735 i < filedata->file_header.e_shnum;
b34976b6 7736 i++, section++)
252b5132 7737 {
b6ac461a 7738 const char *name = printable_section_name (filedata, section);
252b5132 7739
1b513401
NC
7740 /* Run some sanity checks on the headers and
7741 possibly fill in some file data as well. */
7742 switch (section->sh_type)
252b5132 7743 {
1b513401 7744 case SHT_DYNSYM:
978c4450 7745 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7746 {
7747 error (_("File contains multiple dynamic symbol tables\n"));
7748 continue;
7749 }
7750
08d8fa11 7751 CHECK_ENTSIZE (section, i, Sym);
978c4450 7752 filedata->dynamic_symbols
4de91c10 7753 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7754 filedata->dynamic_symtab_section = section;
1b513401
NC
7755 break;
7756
7757 case SHT_STRTAB:
7758 if (streq (name, ".dynstr"))
252b5132 7759 {
1b513401
NC
7760 if (filedata->dynamic_strings != NULL)
7761 {
7762 error (_("File contains multiple dynamic string tables\n"));
7763 continue;
7764 }
7765
7766 filedata->dynamic_strings
7767 = (char *) get_data (NULL, filedata, section->sh_offset,
7768 1, section->sh_size, _("dynamic strings"));
7769 filedata->dynamic_strings_length
7770 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7771 filedata->dynamic_strtab_section = section;
252b5132 7772 }
1b513401
NC
7773 break;
7774
7775 case SHT_SYMTAB_SHNDX:
7776 {
7777 elf_section_list * entry = xmalloc (sizeof * entry);
7778
7779 entry->hdr = section;
7780 entry->next = filedata->symtab_shndx_list;
7781 filedata->symtab_shndx_list = entry;
7782 }
7783 break;
7784
7785 case SHT_SYMTAB:
7786 CHECK_ENTSIZE (section, i, Sym);
7787 break;
7788
7789 case SHT_GROUP:
7790 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7791 break;
252b5132 7792
1b513401
NC
7793 case SHT_REL:
7794 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7795 if (do_checks && section->sh_size == 0)
1b513401
NC
7796 warn (_("Section '%s': zero-sized relocation section\n"), name);
7797 break;
7798
7799 case SHT_RELA:
7800 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7801 if (do_checks && section->sh_size == 0)
1b513401
NC
7802 warn (_("Section '%s': zero-sized relocation section\n"), name);
7803 break;
7804
682351b9
AM
7805 case SHT_RELR:
7806 CHECK_ENTSIZE (section, i, Relr);
7807 break;
7808
1b513401
NC
7809 case SHT_NOTE:
7810 case SHT_PROGBITS:
546cb2d8
NC
7811 /* Having a zero sized section is not illegal according to the
7812 ELF standard, but it might be an indication that something
7813 is wrong. So issue a warning if we are running in lint mode. */
7814 if (do_checks && section->sh_size == 0)
1b513401
NC
7815 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7816 break;
7817
7818 default:
7819 break;
7820 }
7821
7822 if ((do_debugging || do_debug_info || do_debug_abbrevs
7823 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7824 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7825 || do_debug_str || do_debug_str_offsets || do_debug_loc
7826 || do_debug_ranges
1b513401 7827 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7828 && (startswith (name, ".debug_")
7829 || startswith (name, ".zdebug_")))
252b5132 7830 {
1b315056
CS
7831 if (name[1] == 'z')
7832 name += sizeof (".zdebug_") - 1;
7833 else
7834 name += sizeof (".debug_") - 1;
252b5132
RH
7835
7836 if (do_debugging
24d127aa
ML
7837 || (do_debug_info && startswith (name, "info"))
7838 || (do_debug_info && startswith (name, "types"))
7839 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7840 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7841 || (do_debug_lines && startswith (name, "line."))
7842 || (do_debug_pubnames && startswith (name, "pubnames"))
7843 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7844 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7845 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7846 || (do_debug_aranges && startswith (name, "aranges"))
7847 || (do_debug_ranges && startswith (name, "ranges"))
7848 || (do_debug_ranges && startswith (name, "rnglists"))
7849 || (do_debug_frames && startswith (name, "frame"))
7850 || (do_debug_macinfo && startswith (name, "macinfo"))
7851 || (do_debug_macinfo && startswith (name, "macro"))
7852 || (do_debug_str && startswith (name, "str"))
7853 || (do_debug_links && startswith (name, "sup"))
7854 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7855 || (do_debug_loc && startswith (name, "loc"))
7856 || (do_debug_loc && startswith (name, "loclists"))
7857 || (do_debug_addr && startswith (name, "addr"))
7858 || (do_debug_cu_index && startswith (name, "cu_index"))
7859 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7860 )
6431e409 7861 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7862 }
a262ae96 7863 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7864 else if ((do_debugging || do_debug_info)
24d127aa 7865 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7866 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7867 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7868 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7869 else if (do_gdb_index && (streq (name, ".gdb_index")
7870 || streq (name, ".debug_names")))
6431e409 7871 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7872 /* Trace sections for Itanium VMS. */
7873 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7874 || do_trace_aranges)
24d127aa 7875 && startswith (name, ".trace_"))
6f875884
TG
7876 {
7877 name += sizeof (".trace_") - 1;
7878
7879 if (do_debugging
7880 || (do_trace_info && streq (name, "info"))
7881 || (do_trace_abbrevs && streq (name, "abbrev"))
7882 || (do_trace_aranges && streq (name, "aranges"))
7883 )
6431e409 7884 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7885 }
dda8d76d 7886 else if ((do_debugging || do_debug_links)
24d127aa
ML
7887 && (startswith (name, ".gnu_debuglink")
7888 || startswith (name, ".gnu_debugaltlink")))
6431e409 7889 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7890 }
7891
7892 if (! do_sections)
015dc7e1 7893 return true;
252b5132 7894
ca0e11aa 7895 if (filedata->is_separate && ! process_links)
015dc7e1 7896 return true;
ca0e11aa
NC
7897
7898 if (filedata->is_separate)
7899 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7900 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7901 printf (_("\nSection Headers:\n"));
7902 else
7903 printf (_("\nSection Header:\n"));
76da6bbe 7904
f7a99963 7905 if (is_32bit_elf)
595cf52e 7906 {
5477e8a0 7907 if (do_section_details)
595cf52e
L
7908 {
7909 printf (_(" [Nr] Name\n"));
5477e8a0 7910 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7911 }
7912 else
7913 printf
7914 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7915 }
d974e256 7916 else if (do_wide)
595cf52e 7917 {
5477e8a0 7918 if (do_section_details)
595cf52e
L
7919 {
7920 printf (_(" [Nr] Name\n"));
5477e8a0 7921 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7922 }
7923 else
7924 printf
7925 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7926 }
f7a99963
NC
7927 else
7928 {
5477e8a0 7929 if (do_section_details)
595cf52e
L
7930 {
7931 printf (_(" [Nr] Name\n"));
5477e8a0
L
7932 printf (_(" Type Address Offset Link\n"));
7933 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7934 }
7935 else
7936 {
7937 printf (_(" [Nr] Name Type Address Offset\n"));
7938 printf (_(" Size EntSize Flags Link Info Align\n"));
7939 }
f7a99963 7940 }
252b5132 7941
5477e8a0
L
7942 if (do_section_details)
7943 printf (_(" Flags\n"));
7944
dda8d76d
NC
7945 for (i = 0, section = filedata->section_headers;
7946 i < filedata->file_header.e_shnum;
b34976b6 7947 i++, section++)
252b5132 7948 {
dd905818
NC
7949 /* Run some sanity checks on the section header. */
7950
7951 /* Check the sh_link field. */
7952 switch (section->sh_type)
7953 {
285e3f99
AM
7954 case SHT_REL:
7955 case SHT_RELA:
7956 if (section->sh_link == 0
7957 && (filedata->file_header.e_type == ET_EXEC
7958 || filedata->file_header.e_type == ET_DYN))
7959 /* A dynamic relocation section where all entries use a
7960 zero symbol index need not specify a symtab section. */
7961 break;
7962 /* Fall through. */
dd905818
NC
7963 case SHT_SYMTAB_SHNDX:
7964 case SHT_GROUP:
7965 case SHT_HASH:
7966 case SHT_GNU_HASH:
7967 case SHT_GNU_versym:
285e3f99 7968 if (section->sh_link == 0
dda8d76d
NC
7969 || section->sh_link >= filedata->file_header.e_shnum
7970 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7971 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7972 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7973 i, section->sh_link);
7974 break;
7975
7976 case SHT_DYNAMIC:
7977 case SHT_SYMTAB:
7978 case SHT_DYNSYM:
7979 case SHT_GNU_verneed:
7980 case SHT_GNU_verdef:
7981 case SHT_GNU_LIBLIST:
285e3f99 7982 if (section->sh_link == 0
dda8d76d
NC
7983 || section->sh_link >= filedata->file_header.e_shnum
7984 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7985 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7986 i, section->sh_link);
7987 break;
7988
7989 case SHT_INIT_ARRAY:
7990 case SHT_FINI_ARRAY:
7991 case SHT_PREINIT_ARRAY:
7992 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7993 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7994 i, section->sh_link);
7995 break;
7996
7997 default:
7998 /* FIXME: Add support for target specific section types. */
7999#if 0 /* Currently we do not check other section types as there are too
8000 many special cases. Stab sections for example have a type
8001 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8002 section. */
8003 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8004 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8005 i, section->sh_link);
8006#endif
8007 break;
8008 }
8009
8010 /* Check the sh_info field. */
8011 switch (section->sh_type)
8012 {
8013 case SHT_REL:
8014 case SHT_RELA:
285e3f99
AM
8015 if (section->sh_info == 0
8016 && (filedata->file_header.e_type == ET_EXEC
8017 || filedata->file_header.e_type == ET_DYN))
8018 /* Dynamic relocations apply to segments, so they do not
8019 need to specify the section they relocate. */
8020 break;
8021 if (section->sh_info == 0
dda8d76d
NC
8022 || section->sh_info >= filedata->file_header.e_shnum
8023 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8024 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8025 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8026 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8027 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8028 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8029 /* FIXME: Are other section types valid ? */
dda8d76d 8030 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8031 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8032 i, section->sh_info);
dd905818
NC
8033 break;
8034
8035 case SHT_DYNAMIC:
8036 case SHT_HASH:
8037 case SHT_SYMTAB_SHNDX:
8038 case SHT_INIT_ARRAY:
8039 case SHT_FINI_ARRAY:
8040 case SHT_PREINIT_ARRAY:
8041 if (section->sh_info != 0)
8042 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8043 i, section->sh_info);
8044 break;
8045
8046 case SHT_GROUP:
8047 case SHT_SYMTAB:
8048 case SHT_DYNSYM:
8049 /* A symbol index - we assume that it is valid. */
8050 break;
8051
8052 default:
8053 /* FIXME: Add support for target specific section types. */
8054 if (section->sh_type == SHT_NOBITS)
8055 /* NOBITS section headers with non-zero sh_info fields can be
8056 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8057 information. The stripped sections have their headers
8058 preserved but their types set to SHT_NOBITS. So do not check
8059 this type of section. */
dd905818
NC
8060 ;
8061 else if (section->sh_flags & SHF_INFO_LINK)
8062 {
dda8d76d 8063 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8064 warn (_("[%2u]: Expected link to another section in info field"), i);
8065 }
a91e1603
L
8066 else if (section->sh_type < SHT_LOOS
8067 && (section->sh_flags & SHF_GNU_MBIND) == 0
8068 && section->sh_info != 0)
dd905818
NC
8069 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8070 i, section->sh_info);
8071 break;
8072 }
8073
3e6b6445 8074 /* Check the sh_size field. */
dda8d76d 8075 if (section->sh_size > filedata->file_size
3e6b6445
NC
8076 && section->sh_type != SHT_NOBITS
8077 && section->sh_type != SHT_NULL
8078 && section->sh_type < SHT_LOOS)
8079 warn (_("Size of section %u is larger than the entire file!\n"), i);
8080
7bfd842d 8081 printf (" [%2u] ", i);
5477e8a0 8082 if (do_section_details)
dda8d76d 8083 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8084 else
b6ac461a 8085 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8086
ea52a088 8087 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8088 get_section_type_name (filedata, section->sh_type));
0b4362b0 8089
f7a99963
NC
8090 if (is_32bit_elf)
8091 {
cfcac11d
NC
8092 const char * link_too_big = NULL;
8093
f7a99963 8094 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8095
f7a99963
NC
8096 printf ( " %6.6lx %6.6lx %2.2lx",
8097 (unsigned long) section->sh_offset,
8098 (unsigned long) section->sh_size,
8099 (unsigned long) section->sh_entsize);
d1133906 8100
5477e8a0
L
8101 if (do_section_details)
8102 fputs (" ", stdout);
8103 else
dda8d76d 8104 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8105
dda8d76d 8106 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8107 {
8108 link_too_big = "";
8109 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8110 an error but it can have special values in Solaris binaries. */
dda8d76d 8111 switch (filedata->file_header.e_machine)
cfcac11d 8112 {
caa83f8b 8113 case EM_386:
22abe556 8114 case EM_IAMCU:
caa83f8b 8115 case EM_X86_64:
7f502d6c 8116 case EM_L1OM:
7a9068fe 8117 case EM_K1OM:
cfcac11d
NC
8118 case EM_OLD_SPARCV9:
8119 case EM_SPARC32PLUS:
8120 case EM_SPARCV9:
8121 case EM_SPARC:
8122 if (section->sh_link == (SHN_BEFORE & 0xffff))
8123 link_too_big = "BEFORE";
8124 else if (section->sh_link == (SHN_AFTER & 0xffff))
8125 link_too_big = "AFTER";
8126 break;
8127 default:
8128 break;
8129 }
8130 }
8131
8132 if (do_section_details)
8133 {
8134 if (link_too_big != NULL && * link_too_big)
8135 printf ("<%s> ", link_too_big);
8136 else
8137 printf ("%2u ", section->sh_link);
8138 printf ("%3u %2lu\n", section->sh_info,
8139 (unsigned long) section->sh_addralign);
8140 }
8141 else
8142 printf ("%2u %3u %2lu\n",
8143 section->sh_link,
8144 section->sh_info,
8145 (unsigned long) section->sh_addralign);
8146
8147 if (link_too_big && ! * link_too_big)
8148 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8149 i, section->sh_link);
f7a99963 8150 }
d974e256
JJ
8151 else if (do_wide)
8152 {
8153 print_vma (section->sh_addr, LONG_HEX);
8154
8155 if ((long) section->sh_offset == section->sh_offset)
8156 printf (" %6.6lx", (unsigned long) section->sh_offset);
8157 else
8158 {
8159 putchar (' ');
8160 print_vma (section->sh_offset, LONG_HEX);
8161 }
8162
8163 if ((unsigned long) section->sh_size == section->sh_size)
8164 printf (" %6.6lx", (unsigned long) section->sh_size);
8165 else
8166 {
8167 putchar (' ');
8168 print_vma (section->sh_size, LONG_HEX);
8169 }
8170
8171 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8172 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8173 else
8174 {
8175 putchar (' ');
8176 print_vma (section->sh_entsize, LONG_HEX);
8177 }
8178
5477e8a0
L
8179 if (do_section_details)
8180 fputs (" ", stdout);
8181 else
dda8d76d 8182 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8183
72de5009 8184 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8185
8186 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8187 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8188 else
8189 {
8190 print_vma (section->sh_addralign, DEC);
8191 putchar ('\n');
8192 }
8193 }
5477e8a0 8194 else if (do_section_details)
595cf52e 8195 {
55cc53e9 8196 putchar (' ');
595cf52e
L
8197 print_vma (section->sh_addr, LONG_HEX);
8198 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8199 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8200 else
8201 {
8202 printf (" ");
8203 print_vma (section->sh_offset, LONG_HEX);
8204 }
72de5009 8205 printf (" %u\n ", section->sh_link);
595cf52e 8206 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8207 putchar (' ');
595cf52e
L
8208 print_vma (section->sh_entsize, LONG_HEX);
8209
72de5009
AM
8210 printf (" %-16u %lu\n",
8211 section->sh_info,
595cf52e
L
8212 (unsigned long) section->sh_addralign);
8213 }
f7a99963
NC
8214 else
8215 {
8216 putchar (' ');
8217 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8218 if ((long) section->sh_offset == section->sh_offset)
8219 printf (" %8.8lx", (unsigned long) section->sh_offset);
8220 else
8221 {
8222 printf (" ");
8223 print_vma (section->sh_offset, LONG_HEX);
8224 }
f7a99963
NC
8225 printf ("\n ");
8226 print_vma (section->sh_size, LONG_HEX);
8227 printf (" ");
8228 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8229
dda8d76d 8230 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8231
72de5009
AM
8232 printf (" %2u %3u %lu\n",
8233 section->sh_link,
8234 section->sh_info,
f7a99963
NC
8235 (unsigned long) section->sh_addralign);
8236 }
5477e8a0
L
8237
8238 if (do_section_details)
77115a4a 8239 {
dda8d76d 8240 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8241 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8242 {
8243 /* Minimum section size is 12 bytes for 32-bit compression
8244 header + 12 bytes for compressed data header. */
8245 unsigned char buf[24];
d8024a91 8246
77115a4a 8247 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8248 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8249 sizeof (buf), _("compression header")))
8250 {
8251 Elf_Internal_Chdr chdr;
d8024a91 8252
5844b465
NC
8253 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8254 printf (_(" [<corrupt>]\n"));
77115a4a 8255 else
5844b465 8256 {
89dbeac7 8257 if (chdr.ch_type == ch_compress_zlib)
5844b465 8258 printf (" ZLIB, ");
89dbeac7 8259 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8260 printf (" ZSTD, ");
5844b465
NC
8261 else
8262 printf (_(" [<unknown>: 0x%x], "),
8263 chdr.ch_type);
8264 print_vma (chdr.ch_size, LONG_HEX);
8265 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8266 }
77115a4a
L
8267 }
8268 }
8269 }
252b5132
RH
8270 }
8271
5477e8a0 8272 if (!do_section_details)
3dbcc61d 8273 {
9fb71ee4
NC
8274 /* The ordering of the letters shown here matches the ordering of the
8275 corresponding SHF_xxx values, and hence the order in which these
8276 letters will be displayed to the user. */
8277 printf (_("Key to Flags:\n\
8278 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8279 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8280 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8281 switch (filedata->file_header.e_ident[EI_OSABI])
8282 {
8283 case ELFOSABI_GNU:
8284 case ELFOSABI_FREEBSD:
8285 printf (_("R (retain), "));
8286 /* Fall through */
8287 case ELFOSABI_NONE:
8288 printf (_("D (mbind), "));
8289 break;
8290 default:
8291 break;
8292 }
dda8d76d
NC
8293 if (filedata->file_header.e_machine == EM_X86_64
8294 || filedata->file_header.e_machine == EM_L1OM
8295 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8296 printf (_("l (large), "));
dda8d76d 8297 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8298 printf (_("y (purecode), "));
dda8d76d 8299 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8300 printf (_("v (VLE), "));
9fb71ee4 8301 printf ("p (processor specific)\n");
0b4362b0 8302 }
d1133906 8303
015dc7e1 8304 return true;
252b5132
RH
8305}
8306
015dc7e1 8307static bool
28d13567 8308get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
26c527e6
AM
8309 Elf_Internal_Sym **symtab, uint64_t *nsyms,
8310 char **strtab, uint64_t *strtablen)
28d13567
AM
8311{
8312 *strtab = NULL;
8313 *strtablen = 0;
4de91c10 8314 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8315
8316 if (*symtab == NULL)
015dc7e1 8317 return false;
28d13567
AM
8318
8319 if (symsec->sh_link != 0)
8320 {
8321 Elf_Internal_Shdr *strsec;
8322
8323 if (symsec->sh_link >= filedata->file_header.e_shnum)
8324 {
8325 error (_("Bad sh_link in symbol table section\n"));
8326 free (*symtab);
8327 *symtab = NULL;
8328 *nsyms = 0;
015dc7e1 8329 return false;
28d13567
AM
8330 }
8331
8332 strsec = filedata->section_headers + symsec->sh_link;
8333
8334 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8335 1, strsec->sh_size, _("string table"));
8336 if (*strtab == NULL)
8337 {
8338 free (*symtab);
8339 *symtab = NULL;
8340 *nsyms = 0;
015dc7e1 8341 return false;
28d13567
AM
8342 }
8343 *strtablen = strsec->sh_size;
8344 }
015dc7e1 8345 return true;
28d13567
AM
8346}
8347
f5842774
L
8348static const char *
8349get_group_flags (unsigned int flags)
8350{
1449284b 8351 static char buff[128];
220453ec 8352
6d913794
NC
8353 if (flags == 0)
8354 return "";
8355 else if (flags == GRP_COMDAT)
8356 return "COMDAT ";
f5842774 8357
89246a0e
AM
8358 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8359 flags,
8360 flags & GRP_MASKOS ? _("<OS specific>") : "",
8361 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8362 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8363 ? _("<unknown>") : ""));
6d913794 8364
f5842774
L
8365 return buff;
8366}
8367
015dc7e1 8368static bool
dda8d76d 8369process_section_groups (Filedata * filedata)
f5842774 8370{
2cf0635d 8371 Elf_Internal_Shdr * section;
f5842774 8372 unsigned int i;
2cf0635d
NC
8373 struct group * group;
8374 Elf_Internal_Shdr * symtab_sec;
8375 Elf_Internal_Shdr * strtab_sec;
8376 Elf_Internal_Sym * symtab;
26c527e6 8377 uint64_t num_syms;
2cf0635d 8378 char * strtab;
c256ffe7 8379 size_t strtab_size;
d1f5c6e3
L
8380
8381 /* Don't process section groups unless needed. */
8382 if (!do_unwind && !do_section_groups)
015dc7e1 8383 return true;
f5842774 8384
dda8d76d 8385 if (filedata->file_header.e_shnum == 0)
f5842774
L
8386 {
8387 if (do_section_groups)
ca0e11aa
NC
8388 {
8389 if (filedata->is_separate)
8390 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8391 filedata->file_name);
8392 else
8393 printf (_("\nThere are no section groups in this file.\n"));
8394 }
015dc7e1 8395 return true;
f5842774
L
8396 }
8397
dda8d76d 8398 if (filedata->section_headers == NULL)
f5842774
L
8399 {
8400 error (_("Section headers are not available!\n"));
fa1908fd 8401 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8402 return false;
f5842774
L
8403 }
8404
978c4450
AM
8405 filedata->section_headers_groups
8406 = (struct group **) calloc (filedata->file_header.e_shnum,
8407 sizeof (struct group *));
e4b17d5c 8408
978c4450 8409 if (filedata->section_headers_groups == NULL)
e4b17d5c 8410 {
8b73c356 8411 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8412 filedata->file_header.e_shnum);
015dc7e1 8413 return false;
e4b17d5c
L
8414 }
8415
f5842774 8416 /* Scan the sections for the group section. */
978c4450 8417 filedata->group_count = 0;
dda8d76d
NC
8418 for (i = 0, section = filedata->section_headers;
8419 i < filedata->file_header.e_shnum;
f5842774 8420 i++, section++)
e4b17d5c 8421 if (section->sh_type == SHT_GROUP)
978c4450 8422 filedata->group_count++;
e4b17d5c 8423
978c4450 8424 if (filedata->group_count == 0)
d1f5c6e3
L
8425 {
8426 if (do_section_groups)
ca0e11aa
NC
8427 {
8428 if (filedata->is_separate)
8429 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8430 filedata->file_name);
8431 else
8432 printf (_("\nThere are no section groups in this file.\n"));
8433 }
d1f5c6e3 8434
015dc7e1 8435 return true;
d1f5c6e3
L
8436 }
8437
978c4450
AM
8438 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8439 sizeof (struct group));
e4b17d5c 8440
978c4450 8441 if (filedata->section_groups == NULL)
e4b17d5c 8442 {
26c527e6 8443 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8444 return false;
e4b17d5c
L
8445 }
8446
d1f5c6e3
L
8447 symtab_sec = NULL;
8448 strtab_sec = NULL;
8449 symtab = NULL;
ba5cdace 8450 num_syms = 0;
d1f5c6e3 8451 strtab = NULL;
c256ffe7 8452 strtab_size = 0;
ca0e11aa
NC
8453
8454 if (filedata->is_separate)
8455 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8456
978c4450 8457 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8458 i < filedata->file_header.e_shnum;
e4b17d5c 8459 i++, section++)
f5842774
L
8460 {
8461 if (section->sh_type == SHT_GROUP)
8462 {
dda8d76d 8463 const char * name = printable_section_name (filedata, section);
74e1a04b 8464 const char * group_name;
2cf0635d
NC
8465 unsigned char * start;
8466 unsigned char * indices;
f5842774 8467 unsigned int entry, j, size;
2cf0635d
NC
8468 Elf_Internal_Shdr * sec;
8469 Elf_Internal_Sym * sym;
f5842774
L
8470
8471 /* Get the symbol table. */
dda8d76d
NC
8472 if (section->sh_link >= filedata->file_header.e_shnum
8473 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8474 != SHT_SYMTAB))
f5842774
L
8475 {
8476 error (_("Bad sh_link in group section `%s'\n"), name);
8477 continue;
8478 }
d1f5c6e3
L
8479
8480 if (symtab_sec != sec)
8481 {
8482 symtab_sec = sec;
9db70fc3 8483 free (symtab);
4de91c10 8484 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8485 }
f5842774 8486
dd24e3da
NC
8487 if (symtab == NULL)
8488 {
8489 error (_("Corrupt header in group section `%s'\n"), name);
8490 continue;
8491 }
8492
ba5cdace
NC
8493 if (section->sh_info >= num_syms)
8494 {
8495 error (_("Bad sh_info in group section `%s'\n"), name);
8496 continue;
8497 }
8498
f5842774
L
8499 sym = symtab + section->sh_info;
8500
8501 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8502 {
4fbb74a6 8503 if (sym->st_shndx == 0
dda8d76d 8504 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8505 {
8506 error (_("Bad sh_info in group section `%s'\n"), name);
8507 continue;
8508 }
ba2685cc 8509
b6ac461a
NC
8510 group_name = printable_section_name (filedata,
8511 filedata->section_headers
8512 + sym->st_shndx);
c256ffe7 8513 strtab_sec = NULL;
9db70fc3 8514 free (strtab);
f5842774 8515 strtab = NULL;
c256ffe7 8516 strtab_size = 0;
f5842774
L
8517 }
8518 else
8519 {
8520 /* Get the string table. */
dda8d76d 8521 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8522 {
8523 strtab_sec = NULL;
9db70fc3 8524 free (strtab);
c256ffe7
JJ
8525 strtab = NULL;
8526 strtab_size = 0;
8527 }
8528 else if (strtab_sec
dda8d76d 8529 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8530 {
8531 strtab_sec = sec;
9db70fc3 8532 free (strtab);
071436c6 8533
dda8d76d 8534 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8535 1, strtab_sec->sh_size,
8536 _("string table"));
c256ffe7 8537 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8538 }
c256ffe7 8539 group_name = sym->st_name < strtab_size
2b692964 8540 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8541 }
8542
c9c1d674
EG
8543 /* PR 17531: file: loop. */
8544 if (section->sh_entsize > section->sh_size)
8545 {
26c527e6
AM
8546 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8547 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8548 printable_section_name (filedata, section),
26c527e6
AM
8549 section->sh_entsize,
8550 section->sh_size);
61dd8e19 8551 continue;
c9c1d674
EG
8552 }
8553
dda8d76d 8554 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8555 1, section->sh_size,
8556 _("section data"));
59245841
NC
8557 if (start == NULL)
8558 continue;
f5842774
L
8559
8560 indices = start;
8561 size = (section->sh_size / section->sh_entsize) - 1;
8562 entry = byte_get (indices, 4);
8563 indices += 4;
e4b17d5c
L
8564
8565 if (do_section_groups)
8566 {
2b692964 8567 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8568 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8569
e4b17d5c
L
8570 printf (_(" [Index] Name\n"));
8571 }
8572
8573 group->group_index = i;
8574
f5842774
L
8575 for (j = 0; j < size; j++)
8576 {
2cf0635d 8577 struct group_list * g;
e4b17d5c 8578
f5842774
L
8579 entry = byte_get (indices, 4);
8580 indices += 4;
8581
dda8d76d 8582 if (entry >= filedata->file_header.e_shnum)
391cb864 8583 {
57028622
NC
8584 static unsigned num_group_errors = 0;
8585
8586 if (num_group_errors ++ < 10)
8587 {
8588 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8589 entry, i, filedata->file_header.e_shnum - 1);
57028622 8590 if (num_group_errors == 10)
67ce483b 8591 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8592 }
391cb864
L
8593 continue;
8594 }
391cb864 8595
978c4450 8596 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8597 {
d1f5c6e3
L
8598 if (entry)
8599 {
57028622
NC
8600 static unsigned num_errs = 0;
8601
8602 if (num_errs ++ < 10)
8603 {
8604 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8605 entry, i,
978c4450 8606 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8607 if (num_errs == 10)
8608 warn (_("Further error messages about already contained group sections suppressed\n"));
8609 }
d1f5c6e3
L
8610 continue;
8611 }
8612 else
8613 {
8614 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8615 section group. We just warn it the first time
d1f5c6e3 8616 and ignore it afterwards. */
015dc7e1 8617 static bool warned = false;
d1f5c6e3
L
8618 if (!warned)
8619 {
8620 error (_("section 0 in group section [%5u]\n"),
978c4450 8621 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8622 warned = true;
d1f5c6e3
L
8623 }
8624 }
e4b17d5c
L
8625 }
8626
978c4450 8627 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8628
8629 if (do_section_groups)
8630 {
dda8d76d
NC
8631 sec = filedata->section_headers + entry;
8632 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8633 }
8634
3f5e193b 8635 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8636 g->section_index = entry;
8637 g->next = group->root;
8638 group->root = g;
f5842774
L
8639 }
8640
9db70fc3 8641 free (start);
e4b17d5c
L
8642
8643 group++;
f5842774
L
8644 }
8645 }
8646
9db70fc3
AM
8647 free (symtab);
8648 free (strtab);
015dc7e1 8649 return true;
f5842774
L
8650}
8651
28f997cf
TG
8652/* Data used to display dynamic fixups. */
8653
8654struct ia64_vms_dynfixup
8655{
625d49fc
AM
8656 uint64_t needed_ident; /* Library ident number. */
8657 uint64_t needed; /* Index in the dstrtab of the library name. */
8658 uint64_t fixup_needed; /* Index of the library. */
8659 uint64_t fixup_rela_cnt; /* Number of fixups. */
8660 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8661};
8662
8663/* Data used to display dynamic relocations. */
8664
8665struct ia64_vms_dynimgrela
8666{
625d49fc
AM
8667 uint64_t img_rela_cnt; /* Number of relocations. */
8668 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8669};
8670
8671/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8672 library). */
8673
015dc7e1 8674static bool
dda8d76d
NC
8675dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8676 struct ia64_vms_dynfixup * fixup,
8677 const char * strtab,
8678 unsigned int strtab_sz)
28f997cf 8679{
32ec8896 8680 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8681 size_t i;
32ec8896 8682 const char * lib_name;
28f997cf 8683
978c4450
AM
8684 imfs = get_data (NULL, filedata,
8685 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8686 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8687 _("dynamic section image fixups"));
8688 if (!imfs)
015dc7e1 8689 return false;
28f997cf
TG
8690
8691 if (fixup->needed < strtab_sz)
8692 lib_name = strtab + fixup->needed;
8693 else
8694 {
26c527e6
AM
8695 warn (_("corrupt library name index of %#" PRIx64
8696 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8697 lib_name = "???";
8698 }
736990c4 8699
26c527e6
AM
8700 printf (_("\nImage fixups for needed library #%" PRId64
8701 ": %s - ident: %" PRIx64 "\n"),
8702 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8703 printf
8704 (_("Seg Offset Type SymVec DataType\n"));
8705
26c527e6 8706 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8707 {
8708 unsigned int type;
8709 const char *rtype;
8710
8711 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8712 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8713 type = BYTE_GET (imfs [i].type);
8714 rtype = elf_ia64_reloc_type (type);
8715 if (rtype == NULL)
f493c217 8716 printf ("0x%08x ", type);
28f997cf 8717 else
f493c217 8718 printf ("%-32s ", rtype);
28f997cf
TG
8719 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8720 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8721 }
8722
8723 free (imfs);
015dc7e1 8724 return true;
28f997cf
TG
8725}
8726
8727/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8728
015dc7e1 8729static bool
dda8d76d 8730dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8731{
8732 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8733 size_t i;
28f997cf 8734
978c4450
AM
8735 imrs = get_data (NULL, filedata,
8736 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8737 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8738 _("dynamic section image relocations"));
28f997cf 8739 if (!imrs)
015dc7e1 8740 return false;
28f997cf
TG
8741
8742 printf (_("\nImage relocs\n"));
8743 printf
8744 (_("Seg Offset Type Addend Seg Sym Off\n"));
8745
26c527e6 8746 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8747 {
8748 unsigned int type;
8749 const char *rtype;
8750
8751 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8752 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8753 type = BYTE_GET (imrs [i].type);
8754 rtype = elf_ia64_reloc_type (type);
8755 if (rtype == NULL)
8756 printf ("0x%08x ", type);
8757 else
8758 printf ("%-31s ", rtype);
8759 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8760 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8761 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8762 }
8763
8764 free (imrs);
015dc7e1 8765 return true;
28f997cf
TG
8766}
8767
8768/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8769
015dc7e1 8770static bool
dda8d76d 8771process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8772{
8773 struct ia64_vms_dynfixup fixup;
8774 struct ia64_vms_dynimgrela imgrela;
8775 Elf_Internal_Dyn *entry;
625d49fc
AM
8776 uint64_t strtab_off = 0;
8777 uint64_t strtab_sz = 0;
28f997cf 8778 char *strtab = NULL;
015dc7e1 8779 bool res = true;
28f997cf
TG
8780
8781 memset (&fixup, 0, sizeof (fixup));
8782 memset (&imgrela, 0, sizeof (imgrela));
8783
8784 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8785 for (entry = filedata->dynamic_section;
8786 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8787 entry++)
8788 {
8789 switch (entry->d_tag)
8790 {
8791 case DT_IA_64_VMS_STRTAB_OFFSET:
8792 strtab_off = entry->d_un.d_val;
8793 break;
8794 case DT_STRSZ:
8795 strtab_sz = entry->d_un.d_val;
8796 if (strtab == NULL)
978c4450
AM
8797 strtab = get_data (NULL, filedata,
8798 filedata->dynamic_addr + strtab_off,
28f997cf 8799 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8800 if (strtab == NULL)
8801 strtab_sz = 0;
28f997cf
TG
8802 break;
8803
8804 case DT_IA_64_VMS_NEEDED_IDENT:
8805 fixup.needed_ident = entry->d_un.d_val;
8806 break;
8807 case DT_NEEDED:
8808 fixup.needed = entry->d_un.d_val;
8809 break;
8810 case DT_IA_64_VMS_FIXUP_NEEDED:
8811 fixup.fixup_needed = entry->d_un.d_val;
8812 break;
8813 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8814 fixup.fixup_rela_cnt = entry->d_un.d_val;
8815 break;
8816 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8817 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8818 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8819 res = false;
28f997cf 8820 break;
28f997cf
TG
8821 case DT_IA_64_VMS_IMG_RELA_CNT:
8822 imgrela.img_rela_cnt = entry->d_un.d_val;
8823 break;
8824 case DT_IA_64_VMS_IMG_RELA_OFF:
8825 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8826 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8827 res = false;
28f997cf
TG
8828 break;
8829
8830 default:
8831 break;
8832 }
8833 }
8834
9db70fc3 8835 free (strtab);
28f997cf
TG
8836
8837 return res;
8838}
8839
85b1c36d 8840static struct
566b0d53 8841{
2cf0635d 8842 const char * name;
566b0d53
L
8843 int reloc;
8844 int size;
a7fd1186 8845 relocation_type rel_type;
32ec8896
NC
8846}
8847 dynamic_relocations [] =
566b0d53 8848{
a7fd1186
FS
8849 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8850 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8851 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8852 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8853};
8854
252b5132 8855/* Process the reloc section. */
18bd398b 8856
015dc7e1 8857static bool
dda8d76d 8858process_relocs (Filedata * filedata)
252b5132 8859{
26c527e6
AM
8860 uint64_t rel_size;
8861 uint64_t rel_offset;
252b5132 8862
252b5132 8863 if (!do_reloc)
015dc7e1 8864 return true;
252b5132
RH
8865
8866 if (do_using_dynamic)
8867 {
a7fd1186 8868 relocation_type rel_type;
2cf0635d 8869 const char * name;
015dc7e1 8870 bool has_dynamic_reloc;
566b0d53 8871 unsigned int i;
0de14b54 8872
015dc7e1 8873 has_dynamic_reloc = false;
252b5132 8874
566b0d53 8875 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8876 {
a7fd1186 8877 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8878 name = dynamic_relocations [i].name;
978c4450
AM
8879 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8880 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8881
32ec8896 8882 if (rel_size)
015dc7e1 8883 has_dynamic_reloc = true;
566b0d53 8884
a7fd1186 8885 if (rel_type == reltype_unknown)
aa903cfb 8886 {
566b0d53 8887 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8888 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8889 {
8890 case DT_REL:
a7fd1186 8891 rel_type = reltype_rel;
566b0d53
L
8892 break;
8893 case DT_RELA:
a7fd1186 8894 rel_type = reltype_rela;
566b0d53
L
8895 break;
8896 }
aa903cfb 8897 }
252b5132 8898
566b0d53
L
8899 if (rel_size)
8900 {
ca0e11aa
NC
8901 if (filedata->is_separate)
8902 printf
26c527e6
AM
8903 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
8904 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
8905 filedata->file_name, name, rel_offset, rel_size);
8906 else
8907 printf
26c527e6
AM
8908 (_("\n'%s' relocation section at offset %#" PRIx64
8909 " contains %" PRId64 " bytes:\n"),
ca0e11aa 8910 name, rel_offset, rel_size);
252b5132 8911
dda8d76d
NC
8912 dump_relocations (filedata,
8913 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8914 rel_size,
978c4450
AM
8915 filedata->dynamic_symbols,
8916 filedata->num_dynamic_syms,
8917 filedata->dynamic_strings,
8918 filedata->dynamic_strings_length,
a7fd1186 8919 rel_type, true /* is_dynamic */);
566b0d53 8920 }
252b5132 8921 }
566b0d53 8922
dda8d76d
NC
8923 if (is_ia64_vms (filedata))
8924 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8925 has_dynamic_reloc = true;
28f997cf 8926
566b0d53 8927 if (! has_dynamic_reloc)
ca0e11aa
NC
8928 {
8929 if (filedata->is_separate)
8930 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8931 filedata->file_name);
8932 else
8933 printf (_("\nThere are no dynamic relocations in this file.\n"));
8934 }
252b5132
RH
8935 }
8936 else
8937 {
2cf0635d 8938 Elf_Internal_Shdr * section;
26c527e6 8939 size_t i;
015dc7e1 8940 bool found = false;
252b5132 8941
dda8d76d
NC
8942 for (i = 0, section = filedata->section_headers;
8943 i < filedata->file_header.e_shnum;
b34976b6 8944 i++, section++)
252b5132
RH
8945 {
8946 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8947 && section->sh_type != SHT_REL
8948 && section->sh_type != SHT_RELR)
252b5132
RH
8949 continue;
8950
8951 rel_offset = section->sh_offset;
8952 rel_size = section->sh_size;
8953
8954 if (rel_size)
8955 {
a7fd1186 8956 relocation_type rel_type;
26c527e6 8957 uint64_t num_rela;
103f02d3 8958
ca0e11aa
NC
8959 if (filedata->is_separate)
8960 printf (_("\nIn linked file '%s' relocation section "),
8961 filedata->file_name);
8962 else
8963 printf (_("\nRelocation section "));
252b5132 8964
dda8d76d 8965 if (filedata->string_table == NULL)
19936277 8966 printf ("%d", section->sh_name);
252b5132 8967 else
dda8d76d 8968 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8969
d3a49aa8 8970 num_rela = rel_size / section->sh_entsize;
26c527e6
AM
8971 printf (ngettext (" at offset %#" PRIx64
8972 " contains %" PRIu64 " entry:\n",
8973 " at offset %#" PRIx64
8974 " contains %" PRId64 " entries:\n",
d3a49aa8
AM
8975 num_rela),
8976 rel_offset, num_rela);
252b5132 8977
a7fd1186
FS
8978 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8979 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8980
4fbb74a6 8981 if (section->sh_link != 0
dda8d76d 8982 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8983 {
26c527e6
AM
8984 Elf_Internal_Shdr *symsec;
8985 Elf_Internal_Sym *symtab;
8986 uint64_t nsyms;
8987 uint64_t strtablen = 0;
8988 char *strtab = NULL;
57346661 8989
dda8d76d 8990 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8991 if (symsec->sh_type != SHT_SYMTAB
8992 && symsec->sh_type != SHT_DYNSYM)
8993 continue;
8994
28d13567
AM
8995 if (!get_symtab (filedata, symsec,
8996 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8997 continue;
252b5132 8998
dda8d76d 8999 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 9000 symtab, nsyms, strtab, strtablen,
a7fd1186 9001 rel_type,
bb4d2ac2 9002 symsec->sh_type == SHT_DYNSYM);
9db70fc3 9003 free (strtab);
d79b3d50
NC
9004 free (symtab);
9005 }
9006 else
dda8d76d 9007 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 9008 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 9009
015dc7e1 9010 found = true;
252b5132
RH
9011 }
9012 }
9013
9014 if (! found)
45ac8f4f
NC
9015 {
9016 /* Users sometimes forget the -D option, so try to be helpful. */
9017 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9018 {
978c4450 9019 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9020 {
ca0e11aa
NC
9021 if (filedata->is_separate)
9022 printf (_("\nThere are no static relocations in linked file '%s'."),
9023 filedata->file_name);
9024 else
9025 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9026 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9027
9028 break;
9029 }
9030 }
9031 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9032 {
9033 if (filedata->is_separate)
9034 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9035 filedata->file_name);
9036 else
9037 printf (_("\nThere are no relocations in this file.\n"));
9038 }
45ac8f4f 9039 }
252b5132
RH
9040 }
9041
015dc7e1 9042 return true;
252b5132
RH
9043}
9044
4d6ed7c8
NC
9045/* An absolute address consists of a section and an offset. If the
9046 section is NULL, the offset itself is the address, otherwise, the
9047 address equals to LOAD_ADDRESS(section) + offset. */
9048
9049struct absaddr
948f632f
DA
9050{
9051 unsigned short section;
625d49fc 9052 uint64_t offset;
948f632f 9053};
4d6ed7c8 9054
948f632f
DA
9055/* Find the nearest symbol at or below ADDR. Returns the symbol
9056 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9057
4d6ed7c8 9058static void
26c527e6
AM
9059find_symbol_for_address (Filedata *filedata,
9060 Elf_Internal_Sym *symtab,
9061 uint64_t nsyms,
9062 const char *strtab,
9063 uint64_t strtab_size,
9064 struct absaddr addr,
9065 const char **symname,
9066 uint64_t *offset)
4d6ed7c8 9067{
625d49fc 9068 uint64_t dist = 0x100000;
2cf0635d 9069 Elf_Internal_Sym * sym;
948f632f
DA
9070 Elf_Internal_Sym * beg;
9071 Elf_Internal_Sym * end;
2cf0635d 9072 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9073
0b6ae522 9074 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9075 beg = symtab;
9076 end = symtab + nsyms;
0b6ae522 9077
948f632f 9078 while (beg < end)
4d6ed7c8 9079 {
625d49fc 9080 uint64_t value;
948f632f
DA
9081
9082 sym = beg + (end - beg) / 2;
0b6ae522 9083
948f632f 9084 value = sym->st_value;
0b6ae522
DJ
9085 REMOVE_ARCH_BITS (value);
9086
948f632f 9087 if (sym->st_name != 0
4d6ed7c8 9088 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9089 && addr.offset >= value
9090 && addr.offset - value < dist)
4d6ed7c8
NC
9091 {
9092 best = sym;
0b6ae522 9093 dist = addr.offset - value;
4d6ed7c8
NC
9094 if (!dist)
9095 break;
9096 }
948f632f
DA
9097
9098 if (addr.offset < value)
9099 end = sym;
9100 else
9101 beg = sym + 1;
4d6ed7c8 9102 }
1b31d05e 9103
4d6ed7c8
NC
9104 if (best)
9105 {
57346661 9106 *symname = (best->st_name >= strtab_size
2b692964 9107 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9108 *offset = dist;
9109 return;
9110 }
1b31d05e 9111
4d6ed7c8
NC
9112 *symname = NULL;
9113 *offset = addr.offset;
9114}
9115
32ec8896 9116static /* signed */ int
948f632f
DA
9117symcmp (const void *p, const void *q)
9118{
9119 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
9120 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
9121
9122 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
9123}
9124
9125/* Process the unwind section. */
9126
9127#include "unwind-ia64.h"
9128
9129struct ia64_unw_table_entry
9130{
9131 struct absaddr start;
9132 struct absaddr end;
9133 struct absaddr info;
9134};
9135
9136struct ia64_unw_aux_info
9137{
32ec8896 9138 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9139 uint64_t table_len; /* Length of unwind table. */
32ec8896 9140 unsigned char * info; /* Unwind info. */
26c527e6 9141 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9142 uint64_t info_addr; /* Starting address of unwind info. */
9143 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9144 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9145 uint64_t nsyms; /* Number of symbols. */
32ec8896 9146 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9147 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9148 char * strtab; /* The string table. */
26c527e6 9149 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9150};
9151
015dc7e1 9152static bool
dda8d76d 9153dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9154{
2cf0635d 9155 struct ia64_unw_table_entry * tp;
26c527e6 9156 size_t j, nfuns;
4d6ed7c8 9157 int in_body;
015dc7e1 9158 bool res = true;
7036c0e1 9159
948f632f
DA
9160 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9161 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9162 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9163 aux->funtab[nfuns++] = aux->symtab[j];
9164 aux->nfuns = nfuns;
9165 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9166
4d6ed7c8
NC
9167 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9168 {
625d49fc
AM
9169 uint64_t stamp;
9170 uint64_t offset;
2cf0635d
NC
9171 const unsigned char * dp;
9172 const unsigned char * head;
53774b7e 9173 const unsigned char * end;
2cf0635d 9174 const char * procname;
4d6ed7c8 9175
dda8d76d 9176 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9177 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9178
9179 fputs ("\n<", stdout);
9180
9181 if (procname)
9182 {
9183 fputs (procname, stdout);
9184
9185 if (offset)
26c527e6 9186 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9187 }
9188
9189 fputs (">: [", stdout);
9190 print_vma (tp->start.offset, PREFIX_HEX);
9191 fputc ('-', stdout);
9192 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9193 printf ("], info at +0x%" PRIx64 "\n",
9194 tp->info.offset - aux->seg_base);
4d6ed7c8 9195
53774b7e
NC
9196 /* PR 17531: file: 86232b32. */
9197 if (aux->info == NULL)
9198 continue;
9199
97c0a079
AM
9200 offset = tp->info.offset;
9201 if (tp->info.section)
9202 {
9203 if (tp->info.section >= filedata->file_header.e_shnum)
9204 {
26c527e6
AM
9205 warn (_("Invalid section %u in table entry %td\n"),
9206 tp->info.section, tp - aux->table);
015dc7e1 9207 res = false;
97c0a079
AM
9208 continue;
9209 }
9210 offset += filedata->section_headers[tp->info.section].sh_addr;
9211 }
9212 offset -= aux->info_addr;
53774b7e 9213 /* PR 17531: file: 0997b4d1. */
90679903
AM
9214 if (offset >= aux->info_size
9215 || aux->info_size - offset < 8)
53774b7e 9216 {
26c527e6
AM
9217 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9218 tp->info.offset, tp - aux->table);
015dc7e1 9219 res = false;
53774b7e
NC
9220 continue;
9221 }
9222
97c0a079 9223 head = aux->info + offset;
a4a00738 9224 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9225
86f55779 9226 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9227 (unsigned) UNW_VER (stamp),
9228 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9229 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9230 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9231 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9232
9233 if (UNW_VER (stamp) != 1)
9234 {
2b692964 9235 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9236 continue;
9237 }
9238
9239 in_body = 0;
53774b7e
NC
9240 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9241 /* PR 17531: file: 16ceda89. */
9242 if (end > aux->info + aux->info_size)
9243 end = aux->info + aux->info_size;
9244 for (dp = head + 8; dp < end;)
b4477bc8 9245 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9246 }
948f632f
DA
9247
9248 free (aux->funtab);
32ec8896
NC
9249
9250 return res;
4d6ed7c8
NC
9251}
9252
015dc7e1 9253static bool
dda8d76d
NC
9254slurp_ia64_unwind_table (Filedata * filedata,
9255 struct ia64_unw_aux_info * aux,
9256 Elf_Internal_Shdr * sec)
4d6ed7c8 9257{
26c527e6 9258 uint64_t size, nrelas, i;
2cf0635d
NC
9259 Elf_Internal_Phdr * seg;
9260 struct ia64_unw_table_entry * tep;
9261 Elf_Internal_Shdr * relsec;
9262 Elf_Internal_Rela * rela;
9263 Elf_Internal_Rela * rp;
9264 unsigned char * table;
9265 unsigned char * tp;
9266 Elf_Internal_Sym * sym;
9267 const char * relname;
4d6ed7c8 9268
53774b7e
NC
9269 aux->table_len = 0;
9270
4d6ed7c8
NC
9271 /* First, find the starting address of the segment that includes
9272 this section: */
9273
dda8d76d 9274 if (filedata->file_header.e_phnum)
4d6ed7c8 9275 {
dda8d76d 9276 if (! get_program_headers (filedata))
015dc7e1 9277 return false;
4d6ed7c8 9278
dda8d76d
NC
9279 for (seg = filedata->program_headers;
9280 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9281 ++seg)
4d6ed7c8
NC
9282 {
9283 if (seg->p_type != PT_LOAD)
9284 continue;
9285
9286 if (sec->sh_addr >= seg->p_vaddr
9287 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9288 {
9289 aux->seg_base = seg->p_vaddr;
9290 break;
9291 }
9292 }
4d6ed7c8
NC
9293 }
9294
9295 /* Second, build the unwind table from the contents of the unwind section: */
9296 size = sec->sh_size;
dda8d76d 9297 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9298 _("unwind table"));
a6e9f9df 9299 if (!table)
015dc7e1 9300 return false;
4d6ed7c8 9301
53774b7e 9302 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9303 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9304 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9305 tep = aux->table;
53774b7e
NC
9306
9307 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9308 {
9309 tep->start.section = SHN_UNDEF;
9310 tep->end.section = SHN_UNDEF;
9311 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9312 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9313 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9314 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9315 tep->start.offset += aux->seg_base;
9316 tep->end.offset += aux->seg_base;
9317 tep->info.offset += aux->seg_base;
9318 }
9319 free (table);
9320
41e92641 9321 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9322 for (relsec = filedata->section_headers;
9323 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9324 ++relsec)
9325 {
9326 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9327 || relsec->sh_info >= filedata->file_header.e_shnum
9328 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9329 continue;
9330
dda8d76d 9331 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9332 & rela, & nrelas))
53774b7e
NC
9333 {
9334 free (aux->table);
9335 aux->table = NULL;
9336 aux->table_len = 0;
015dc7e1 9337 return false;
53774b7e 9338 }
4d6ed7c8
NC
9339
9340 for (rp = rela; rp < rela + nrelas; ++rp)
9341 {
4770fb94 9342 unsigned int sym_ndx;
726bd37d
AM
9343 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9344 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9345
82b1b41b
NC
9346 /* PR 17531: file: 9fa67536. */
9347 if (relname == NULL)
9348 {
726bd37d 9349 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9350 continue;
9351 }
948f632f 9352
24d127aa 9353 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9354 {
82b1b41b 9355 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9356 continue;
9357 }
9358
89fac5e3 9359 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9360
53774b7e
NC
9361 /* PR 17531: file: 5bc8d9bf. */
9362 if (i >= aux->table_len)
9363 {
26c527e6
AM
9364 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9365 i);
53774b7e
NC
9366 continue;
9367 }
9368
4770fb94
AM
9369 sym_ndx = get_reloc_symindex (rp->r_info);
9370 if (sym_ndx >= aux->nsyms)
9371 {
9372 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9373 sym_ndx);
9374 continue;
9375 }
9376 sym = aux->symtab + sym_ndx;
9377
53774b7e 9378 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9379 {
9380 case 0:
9381 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9382 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9383 break;
9384 case 1:
9385 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9386 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9387 break;
9388 case 2:
9389 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9390 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9391 break;
9392 default:
9393 break;
9394 }
9395 }
9396
9397 free (rela);
9398 }
9399
015dc7e1 9400 return true;
4d6ed7c8
NC
9401}
9402
015dc7e1 9403static bool
dda8d76d 9404ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9405{
2cf0635d
NC
9406 Elf_Internal_Shdr * sec;
9407 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9408 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9409 struct ia64_unw_aux_info aux;
015dc7e1 9410 bool res = true;
f1467e33 9411
4d6ed7c8
NC
9412 memset (& aux, 0, sizeof (aux));
9413
dda8d76d 9414 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9415 {
28d13567 9416 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9417 {
28d13567 9418 if (aux.symtab)
4082ef84 9419 {
28d13567
AM
9420 error (_("Multiple symbol tables encountered\n"));
9421 free (aux.symtab);
9422 aux.symtab = NULL;
4082ef84 9423 free (aux.strtab);
28d13567 9424 aux.strtab = NULL;
4082ef84 9425 }
28d13567
AM
9426 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9427 &aux.strtab, &aux.strtab_size))
015dc7e1 9428 return false;
4d6ed7c8
NC
9429 }
9430 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9431 unwcount++;
9432 }
9433
9434 if (!unwcount)
9435 printf (_("\nThere are no unwind sections in this file.\n"));
9436
9437 while (unwcount-- > 0)
9438 {
84714f86 9439 const char *suffix;
579f31ac
JJ
9440 size_t len, len2;
9441
dda8d76d
NC
9442 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9443 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9444 if (sec->sh_type == SHT_IA_64_UNWIND)
9445 {
9446 unwsec = sec;
9447 break;
9448 }
4082ef84
NC
9449 /* We have already counted the number of SHT_IA64_UNWIND
9450 sections so the loop above should never fail. */
9451 assert (unwsec != NULL);
579f31ac
JJ
9452
9453 unwstart = i + 1;
9454 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9455
e4b17d5c
L
9456 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9457 {
9458 /* We need to find which section group it is in. */
4082ef84 9459 struct group_list * g;
e4b17d5c 9460
978c4450
AM
9461 if (filedata->section_headers_groups == NULL
9462 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9463 i = filedata->file_header.e_shnum;
4082ef84 9464 else
e4b17d5c 9465 {
978c4450 9466 g = filedata->section_headers_groups[i]->root;
18bd398b 9467
4082ef84
NC
9468 for (; g != NULL; g = g->next)
9469 {
dda8d76d 9470 sec = filedata->section_headers + g->section_index;
e4b17d5c 9471
84714f86
AM
9472 if (section_name_valid (filedata, sec)
9473 && streq (section_name (filedata, sec),
9474 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9475 break;
9476 }
9477
9478 if (g == NULL)
dda8d76d 9479 i = filedata->file_header.e_shnum;
4082ef84 9480 }
e4b17d5c 9481 }
84714f86
AM
9482 else if (section_name_valid (filedata, unwsec)
9483 && startswith (section_name (filedata, unwsec),
e9b095a5 9484 ELF_STRING_ia64_unwind_once))
579f31ac 9485 {
18bd398b 9486 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9487 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9488 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9489 for (i = 0, sec = filedata->section_headers;
9490 i < filedata->file_header.e_shnum;
579f31ac 9491 ++i, ++sec)
84714f86
AM
9492 if (section_name_valid (filedata, sec)
9493 && startswith (section_name (filedata, sec),
e9b095a5 9494 ELF_STRING_ia64_unwind_info_once)
84714f86 9495 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9496 break;
9497 }
9498 else
9499 {
9500 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9501 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9502 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9503 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9504 suffix = "";
84714f86
AM
9505 if (section_name_valid (filedata, unwsec)
9506 && startswith (section_name (filedata, unwsec),
9507 ELF_STRING_ia64_unwind))
9508 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9509 for (i = 0, sec = filedata->section_headers;
9510 i < filedata->file_header.e_shnum;
579f31ac 9511 ++i, ++sec)
84714f86
AM
9512 if (section_name_valid (filedata, sec)
9513 && startswith (section_name (filedata, sec),
9514 ELF_STRING_ia64_unwind_info)
9515 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9516 break;
9517 }
9518
dda8d76d 9519 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9520 {
9521 printf (_("\nCould not find unwind info section for "));
9522
dda8d76d 9523 if (filedata->string_table == NULL)
579f31ac
JJ
9524 printf ("%d", unwsec->sh_name);
9525 else
dda8d76d 9526 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9527 }
9528 else
4d6ed7c8 9529 {
4d6ed7c8 9530 aux.info_addr = sec->sh_addr;
dda8d76d 9531 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9532 sec->sh_size,
9533 _("unwind info"));
59245841 9534 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9535
579f31ac 9536 printf (_("\nUnwind section "));
4d6ed7c8 9537
dda8d76d 9538 if (filedata->string_table == NULL)
579f31ac
JJ
9539 printf ("%d", unwsec->sh_name);
9540 else
dda8d76d 9541 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9542
26c527e6
AM
9543 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9544 unwsec->sh_offset,
9545 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9546
dda8d76d 9547 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9548 && aux.table_len > 0)
dda8d76d 9549 dump_ia64_unwind (filedata, & aux);
579f31ac 9550
9db70fc3
AM
9551 free ((char *) aux.table);
9552 free ((char *) aux.info);
579f31ac
JJ
9553 aux.table = NULL;
9554 aux.info = NULL;
9555 }
4d6ed7c8 9556 }
4d6ed7c8 9557
9db70fc3
AM
9558 free (aux.symtab);
9559 free ((char *) aux.strtab);
32ec8896
NC
9560
9561 return res;
4d6ed7c8
NC
9562}
9563
3f5e193b 9564struct hppa_unw_table_entry
32ec8896
NC
9565{
9566 struct absaddr start;
9567 struct absaddr end;
9568 unsigned int Cannot_unwind:1; /* 0 */
9569 unsigned int Millicode:1; /* 1 */
9570 unsigned int Millicode_save_sr0:1; /* 2 */
9571 unsigned int Region_description:2; /* 3..4 */
9572 unsigned int reserved1:1; /* 5 */
9573 unsigned int Entry_SR:1; /* 6 */
9574 unsigned int Entry_FR:4; /* Number saved 7..10 */
9575 unsigned int Entry_GR:5; /* Number saved 11..15 */
9576 unsigned int Args_stored:1; /* 16 */
9577 unsigned int Variable_Frame:1; /* 17 */
9578 unsigned int Separate_Package_Body:1; /* 18 */
9579 unsigned int Frame_Extension_Millicode:1; /* 19 */
9580 unsigned int Stack_Overflow_Check:1; /* 20 */
9581 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9582 unsigned int Ada_Region:1; /* 22 */
9583 unsigned int cxx_info:1; /* 23 */
9584 unsigned int cxx_try_catch:1; /* 24 */
9585 unsigned int sched_entry_seq:1; /* 25 */
9586 unsigned int reserved2:1; /* 26 */
9587 unsigned int Save_SP:1; /* 27 */
9588 unsigned int Save_RP:1; /* 28 */
9589 unsigned int Save_MRP_in_frame:1; /* 29 */
9590 unsigned int extn_ptr_defined:1; /* 30 */
9591 unsigned int Cleanup_defined:1; /* 31 */
9592
9593 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9594 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9595 unsigned int Large_frame:1; /* 2 */
9596 unsigned int Pseudo_SP_Set:1; /* 3 */
9597 unsigned int reserved4:1; /* 4 */
9598 unsigned int Total_frame_size:27; /* 5..31 */
9599};
3f5e193b 9600
57346661 9601struct hppa_unw_aux_info
948f632f 9602{
32ec8896 9603 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9604 uint64_t table_len; /* Length of unwind table. */
625d49fc 9605 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9606 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9607 uint64_t nsyms; /* Number of symbols. */
32ec8896 9608 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9609 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9610 char * strtab; /* The string table. */
26c527e6 9611 uint64_t strtab_size; /* Size of string table. */
948f632f 9612};
57346661 9613
015dc7e1 9614static bool
dda8d76d 9615dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9616{
2cf0635d 9617 struct hppa_unw_table_entry * tp;
26c527e6 9618 uint64_t j, nfuns;
015dc7e1 9619 bool res = true;
948f632f
DA
9620
9621 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9622 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9623 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9624 aux->funtab[nfuns++] = aux->symtab[j];
9625 aux->nfuns = nfuns;
9626 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9627
57346661
AM
9628 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9629 {
625d49fc 9630 uint64_t offset;
2cf0635d 9631 const char * procname;
57346661 9632
dda8d76d 9633 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9634 aux->strtab_size, tp->start, &procname,
9635 &offset);
9636
9637 fputs ("\n<", stdout);
9638
9639 if (procname)
9640 {
9641 fputs (procname, stdout);
9642
9643 if (offset)
26c527e6 9644 printf ("+%" PRIx64, offset);
57346661
AM
9645 }
9646
9647 fputs (">: [", stdout);
9648 print_vma (tp->start.offset, PREFIX_HEX);
9649 fputc ('-', stdout);
9650 print_vma (tp->end.offset, PREFIX_HEX);
9651 printf ("]\n\t");
9652
18bd398b
NC
9653#define PF(_m) if (tp->_m) printf (#_m " ");
9654#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9655 PF(Cannot_unwind);
9656 PF(Millicode);
9657 PF(Millicode_save_sr0);
18bd398b 9658 /* PV(Region_description); */
57346661
AM
9659 PF(Entry_SR);
9660 PV(Entry_FR);
9661 PV(Entry_GR);
9662 PF(Args_stored);
9663 PF(Variable_Frame);
9664 PF(Separate_Package_Body);
9665 PF(Frame_Extension_Millicode);
9666 PF(Stack_Overflow_Check);
9667 PF(Two_Instruction_SP_Increment);
9668 PF(Ada_Region);
9669 PF(cxx_info);
9670 PF(cxx_try_catch);
9671 PF(sched_entry_seq);
9672 PF(Save_SP);
9673 PF(Save_RP);
9674 PF(Save_MRP_in_frame);
9675 PF(extn_ptr_defined);
9676 PF(Cleanup_defined);
9677 PF(MPE_XL_interrupt_marker);
9678 PF(HP_UX_interrupt_marker);
9679 PF(Large_frame);
9680 PF(Pseudo_SP_Set);
9681 PV(Total_frame_size);
9682#undef PF
9683#undef PV
9684 }
9685
18bd398b 9686 printf ("\n");
948f632f
DA
9687
9688 free (aux->funtab);
32ec8896
NC
9689
9690 return res;
57346661
AM
9691}
9692
015dc7e1 9693static bool
dda8d76d
NC
9694slurp_hppa_unwind_table (Filedata * filedata,
9695 struct hppa_unw_aux_info * aux,
9696 Elf_Internal_Shdr * sec)
57346661 9697{
26c527e6 9698 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9699 Elf_Internal_Phdr * seg;
9700 struct hppa_unw_table_entry * tep;
9701 Elf_Internal_Shdr * relsec;
9702 Elf_Internal_Rela * rela;
9703 Elf_Internal_Rela * rp;
9704 unsigned char * table;
9705 unsigned char * tp;
9706 Elf_Internal_Sym * sym;
9707 const char * relname;
57346661 9708
57346661
AM
9709 /* First, find the starting address of the segment that includes
9710 this section. */
dda8d76d 9711 if (filedata->file_header.e_phnum)
57346661 9712 {
dda8d76d 9713 if (! get_program_headers (filedata))
015dc7e1 9714 return false;
57346661 9715
dda8d76d
NC
9716 for (seg = filedata->program_headers;
9717 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9718 ++seg)
9719 {
9720 if (seg->p_type != PT_LOAD)
9721 continue;
9722
9723 if (sec->sh_addr >= seg->p_vaddr
9724 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9725 {
9726 aux->seg_base = seg->p_vaddr;
9727 break;
9728 }
9729 }
9730 }
9731
9732 /* Second, build the unwind table from the contents of the unwind
9733 section. */
9734 size = sec->sh_size;
dda8d76d 9735 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9736 _("unwind table"));
57346661 9737 if (!table)
015dc7e1 9738 return false;
57346661 9739
1c0751b2
DA
9740 unw_ent_size = 16;
9741 nentries = size / unw_ent_size;
9742 size = unw_ent_size * nentries;
57346661 9743
e3fdc001 9744 aux->table_len = nentries;
3f5e193b
NC
9745 tep = aux->table = (struct hppa_unw_table_entry *)
9746 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9747
1c0751b2 9748 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9749 {
9750 unsigned int tmp1, tmp2;
9751
9752 tep->start.section = SHN_UNDEF;
9753 tep->end.section = SHN_UNDEF;
9754
1c0751b2
DA
9755 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9756 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9757 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9758 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9759
9760 tep->start.offset += aux->seg_base;
9761 tep->end.offset += aux->seg_base;
57346661
AM
9762
9763 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9764 tep->Millicode = (tmp1 >> 30) & 0x1;
9765 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9766 tep->Region_description = (tmp1 >> 27) & 0x3;
9767 tep->reserved1 = (tmp1 >> 26) & 0x1;
9768 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9769 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9770 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9771 tep->Args_stored = (tmp1 >> 15) & 0x1;
9772 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9773 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9774 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9775 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9776 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9777 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9778 tep->cxx_info = (tmp1 >> 8) & 0x1;
9779 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9780 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9781 tep->reserved2 = (tmp1 >> 5) & 0x1;
9782 tep->Save_SP = (tmp1 >> 4) & 0x1;
9783 tep->Save_RP = (tmp1 >> 3) & 0x1;
9784 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9785 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9786 tep->Cleanup_defined = tmp1 & 0x1;
9787
9788 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9789 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9790 tep->Large_frame = (tmp2 >> 29) & 0x1;
9791 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9792 tep->reserved4 = (tmp2 >> 27) & 0x1;
9793 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9794 }
9795 free (table);
9796
9797 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9798 for (relsec = filedata->section_headers;
9799 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9800 ++relsec)
9801 {
9802 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9803 || relsec->sh_info >= filedata->file_header.e_shnum
9804 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9805 continue;
9806
dda8d76d 9807 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9808 & rela, & nrelas))
015dc7e1 9809 return false;
57346661
AM
9810
9811 for (rp = rela; rp < rela + nrelas; ++rp)
9812 {
4770fb94 9813 unsigned int sym_ndx;
726bd37d
AM
9814 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9815 relname = elf_hppa_reloc_type (r_type);
57346661 9816
726bd37d
AM
9817 if (relname == NULL)
9818 {
9819 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9820 continue;
9821 }
9822
57346661 9823 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9824 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9825 {
726bd37d 9826 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9827 continue;
9828 }
9829
9830 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9831 if (i >= aux->table_len)
9832 {
26c527e6
AM
9833 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9834 i);
726bd37d
AM
9835 continue;
9836 }
57346661 9837
4770fb94
AM
9838 sym_ndx = get_reloc_symindex (rp->r_info);
9839 if (sym_ndx >= aux->nsyms)
9840 {
9841 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9842 sym_ndx);
9843 continue;
9844 }
9845 sym = aux->symtab + sym_ndx;
9846
43f6cd05 9847 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9848 {
9849 case 0:
9850 aux->table[i].start.section = sym->st_shndx;
1e456d54 9851 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9852 break;
9853 case 1:
9854 aux->table[i].end.section = sym->st_shndx;
1e456d54 9855 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9856 break;
9857 default:
9858 break;
9859 }
9860 }
9861
9862 free (rela);
9863 }
9864
015dc7e1 9865 return true;
57346661
AM
9866}
9867
015dc7e1 9868static bool
dda8d76d 9869hppa_process_unwind (Filedata * filedata)
57346661 9870{
57346661 9871 struct hppa_unw_aux_info aux;
2cf0635d 9872 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9873 Elf_Internal_Shdr * sec;
26c527e6 9874 size_t i;
015dc7e1 9875 bool res = true;
57346661 9876
dda8d76d 9877 if (filedata->string_table == NULL)
015dc7e1 9878 return false;
1b31d05e
NC
9879
9880 memset (& aux, 0, sizeof (aux));
57346661 9881
dda8d76d 9882 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9883 {
28d13567 9884 if (sec->sh_type == SHT_SYMTAB)
57346661 9885 {
28d13567 9886 if (aux.symtab)
4082ef84 9887 {
28d13567
AM
9888 error (_("Multiple symbol tables encountered\n"));
9889 free (aux.symtab);
9890 aux.symtab = NULL;
4082ef84 9891 free (aux.strtab);
28d13567 9892 aux.strtab = NULL;
4082ef84 9893 }
28d13567
AM
9894 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9895 &aux.strtab, &aux.strtab_size))
015dc7e1 9896 return false;
57346661 9897 }
84714f86
AM
9898 else if (section_name_valid (filedata, sec)
9899 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9900 unwsec = sec;
9901 }
9902
9903 if (!unwsec)
9904 printf (_("\nThere are no unwind sections in this file.\n"));
9905
dda8d76d 9906 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9907 {
84714f86
AM
9908 if (section_name_valid (filedata, sec)
9909 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9910 {
26c527e6 9911 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 9912
26c527e6
AM
9913 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
9914 "contains %" PRIu64 " entry:\n",
9915 "\nUnwind section '%s' at offset %#" PRIx64 " "
9916 "contains %" PRIu64 " entries:\n",
d3a49aa8 9917 num_unwind),
dda8d76d 9918 printable_section_name (filedata, sec),
26c527e6 9919 sec->sh_offset,
d3a49aa8 9920 num_unwind);
57346661 9921
dda8d76d 9922 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9923 res = false;
66b09c7e
S
9924
9925 if (res && aux.table_len > 0)
32ec8896 9926 {
dda8d76d 9927 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9928 res = false;
32ec8896 9929 }
57346661 9930
9db70fc3 9931 free ((char *) aux.table);
57346661
AM
9932 aux.table = NULL;
9933 }
9934 }
9935
9db70fc3
AM
9936 free (aux.symtab);
9937 free ((char *) aux.strtab);
32ec8896
NC
9938
9939 return res;
57346661
AM
9940}
9941
0b6ae522
DJ
9942struct arm_section
9943{
a734115a
NC
9944 unsigned char * data; /* The unwind data. */
9945 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9946 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 9947 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
9948 unsigned int rel_type; /* REL or RELA ? */
9949 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9950};
9951
9952struct arm_unw_aux_info
9953{
dda8d76d 9954 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 9955 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 9956 uint64_t nsyms; /* Number of symbols. */
948f632f 9957 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9958 uint64_t nfuns; /* Number of these symbols. */
a734115a 9959 char * strtab; /* The file's string table. */
26c527e6 9960 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
9961};
9962
9963static const char *
dda8d76d
NC
9964arm_print_vma_and_name (Filedata * filedata,
9965 struct arm_unw_aux_info * aux,
625d49fc 9966 uint64_t fn,
dda8d76d 9967 struct absaddr addr)
0b6ae522
DJ
9968{
9969 const char *procname;
625d49fc 9970 uint64_t sym_offset;
0b6ae522
DJ
9971
9972 if (addr.section == SHN_UNDEF)
9973 addr.offset = fn;
9974
dda8d76d 9975 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9976 aux->strtab_size, addr, &procname,
9977 &sym_offset);
9978
9979 print_vma (fn, PREFIX_HEX);
9980
9981 if (procname)
9982 {
9983 fputs (" <", stdout);
9984 fputs (procname, stdout);
9985
9986 if (sym_offset)
26c527e6 9987 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
9988 fputc ('>', stdout);
9989 }
9990
9991 return procname;
9992}
9993
9994static void
9995arm_free_section (struct arm_section *arm_sec)
9996{
9db70fc3
AM
9997 free (arm_sec->data);
9998 free (arm_sec->rela);
0b6ae522
DJ
9999}
10000
a734115a
NC
10001/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10002 cached section and install SEC instead.
10003 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10004 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10005 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10006 relocation's offset in ADDR.
1b31d05e
NC
10007 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10008 into the string table of the symbol associated with the reloc. If no
10009 reloc was applied store -1 there.
10010 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10011
015dc7e1 10012static bool
dda8d76d
NC
10013get_unwind_section_word (Filedata * filedata,
10014 struct arm_unw_aux_info * aux,
1b31d05e
NC
10015 struct arm_section * arm_sec,
10016 Elf_Internal_Shdr * sec,
625d49fc 10017 uint64_t word_offset,
1b31d05e
NC
10018 unsigned int * wordp,
10019 struct absaddr * addr,
625d49fc 10020 uint64_t * sym_name)
0b6ae522
DJ
10021{
10022 Elf_Internal_Rela *rp;
10023 Elf_Internal_Sym *sym;
10024 const char * relname;
10025 unsigned int word;
015dc7e1 10026 bool wrapped;
0b6ae522 10027
e0a31db1 10028 if (sec == NULL || arm_sec == NULL)
015dc7e1 10029 return false;
e0a31db1 10030
0b6ae522
DJ
10031 addr->section = SHN_UNDEF;
10032 addr->offset = 0;
10033
1b31d05e 10034 if (sym_name != NULL)
625d49fc 10035 *sym_name = (uint64_t) -1;
1b31d05e 10036
a734115a 10037 /* If necessary, update the section cache. */
0b6ae522
DJ
10038 if (sec != arm_sec->sec)
10039 {
10040 Elf_Internal_Shdr *relsec;
10041
10042 arm_free_section (arm_sec);
10043
10044 arm_sec->sec = sec;
dda8d76d 10045 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10046 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10047 arm_sec->rela = NULL;
10048 arm_sec->nrelas = 0;
10049
dda8d76d
NC
10050 for (relsec = filedata->section_headers;
10051 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10052 ++relsec)
10053 {
dda8d76d
NC
10054 if (relsec->sh_info >= filedata->file_header.e_shnum
10055 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10056 /* PR 15745: Check the section type as well. */
10057 || (relsec->sh_type != SHT_REL
10058 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10059 continue;
10060
a734115a 10061 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10062 if (relsec->sh_type == SHT_REL)
10063 {
dda8d76d 10064 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10065 relsec->sh_size,
10066 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10067 return false;
0b6ae522 10068 }
1ae40aa4 10069 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10070 {
dda8d76d 10071 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10072 relsec->sh_size,
10073 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10074 return false;
0b6ae522 10075 }
1ae40aa4 10076 break;
0b6ae522
DJ
10077 }
10078
10079 arm_sec->next_rela = arm_sec->rela;
10080 }
10081
a734115a 10082 /* If there is no unwind data we can do nothing. */
0b6ae522 10083 if (arm_sec->data == NULL)
015dc7e1 10084 return false;
0b6ae522 10085
e0a31db1 10086 /* If the offset is invalid then fail. */
f32ba729
NC
10087 if (/* PR 21343 *//* PR 18879 */
10088 sec->sh_size < 4
625d49fc 10089 || word_offset > sec->sh_size - 4)
015dc7e1 10090 return false;
e0a31db1 10091
a734115a 10092 /* Get the word at the required offset. */
0b6ae522
DJ
10093 word = byte_get (arm_sec->data + word_offset, 4);
10094
0eff7165
NC
10095 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10096 if (arm_sec->rela == NULL)
10097 {
10098 * wordp = word;
015dc7e1 10099 return true;
0eff7165
NC
10100 }
10101
a734115a 10102 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10103 wrapped = false;
0b6ae522
DJ
10104 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10105 {
625d49fc 10106 uint64_t prelval, offset;
0b6ae522
DJ
10107
10108 if (rp->r_offset > word_offset && !wrapped)
10109 {
10110 rp = arm_sec->rela;
015dc7e1 10111 wrapped = true;
0b6ae522
DJ
10112 }
10113 if (rp->r_offset > word_offset)
10114 break;
10115
10116 if (rp->r_offset & 3)
10117 {
26c527e6
AM
10118 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10119 rp->r_offset);
0b6ae522
DJ
10120 continue;
10121 }
10122
10123 if (rp->r_offset < word_offset)
10124 continue;
10125
74e1a04b
NC
10126 /* PR 17531: file: 027-161405-0.004 */
10127 if (aux->symtab == NULL)
10128 continue;
10129
0b6ae522
DJ
10130 if (arm_sec->rel_type == SHT_REL)
10131 {
10132 offset = word & 0x7fffffff;
10133 if (offset & 0x40000000)
625d49fc 10134 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10135 }
a734115a 10136 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10137 offset = rp->r_addend;
a734115a 10138 else
74e1a04b
NC
10139 {
10140 error (_("Unknown section relocation type %d encountered\n"),
10141 arm_sec->rel_type);
10142 break;
10143 }
0b6ae522 10144
071436c6
NC
10145 /* PR 17531 file: 027-1241568-0.004. */
10146 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10147 {
26c527e6
AM
10148 error (_("Bad symbol index in unwind relocation "
10149 "(%" PRIu64 " > %" PRIu64 ")\n"),
10150 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10151 break;
10152 }
10153
10154 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10155 offset += sym->st_value;
10156 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10157
a734115a 10158 /* Check that we are processing the expected reloc type. */
dda8d76d 10159 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10160 {
10161 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10162 if (relname == NULL)
10163 {
10164 warn (_("Skipping unknown ARM relocation type: %d\n"),
10165 (int) ELF32_R_TYPE (rp->r_info));
10166 continue;
10167 }
a734115a
NC
10168
10169 if (streq (relname, "R_ARM_NONE"))
10170 continue;
0b4362b0 10171
a734115a
NC
10172 if (! streq (relname, "R_ARM_PREL31"))
10173 {
071436c6 10174 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10175 continue;
10176 }
10177 }
dda8d76d 10178 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10179 {
10180 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10181 if (relname == NULL)
10182 {
10183 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10184 (int) ELF32_R_TYPE (rp->r_info));
10185 continue;
10186 }
0b4362b0 10187
a734115a
NC
10188 if (streq (relname, "R_C6000_NONE"))
10189 continue;
10190
10191 if (! streq (relname, "R_C6000_PREL31"))
10192 {
071436c6 10193 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10194 continue;
10195 }
10196
10197 prelval >>= 1;
10198 }
10199 else
74e1a04b
NC
10200 {
10201 /* This function currently only supports ARM and TI unwinders. */
10202 warn (_("Only TI and ARM unwinders are currently supported\n"));
10203 break;
10204 }
fa197c1c 10205
625d49fc 10206 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10207 addr->section = sym->st_shndx;
10208 addr->offset = offset;
74e1a04b 10209
1b31d05e
NC
10210 if (sym_name)
10211 * sym_name = sym->st_name;
0b6ae522
DJ
10212 break;
10213 }
10214
10215 *wordp = word;
10216 arm_sec->next_rela = rp;
10217
015dc7e1 10218 return true;
0b6ae522
DJ
10219}
10220
a734115a
NC
10221static const char *tic6x_unwind_regnames[16] =
10222{
0b4362b0
RM
10223 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10224 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10225 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10226};
fa197c1c 10227
0b6ae522 10228static void
fa197c1c 10229decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10230{
fa197c1c
PB
10231 int i;
10232
10233 for (i = 12; mask; mask >>= 1, i--)
10234 {
10235 if (mask & 1)
10236 {
10237 fputs (tic6x_unwind_regnames[i], stdout);
10238 if (mask > 1)
10239 fputs (", ", stdout);
10240 }
10241 }
10242}
0b6ae522
DJ
10243
10244#define ADVANCE \
10245 if (remaining == 0 && more_words) \
10246 { \
10247 data_offset += 4; \
dda8d76d 10248 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10249 data_offset, & word, & addr, NULL)) \
015dc7e1 10250 return false; \
0b6ae522
DJ
10251 remaining = 4; \
10252 more_words--; \
10253 } \
10254
10255#define GET_OP(OP) \
10256 ADVANCE; \
10257 if (remaining) \
10258 { \
10259 remaining--; \
10260 (OP) = word >> 24; \
10261 word <<= 8; \
10262 } \
10263 else \
10264 { \
2b692964 10265 printf (_("[Truncated opcode]\n")); \
015dc7e1 10266 return false; \
0b6ae522 10267 } \
cc5914eb 10268 printf ("0x%02x ", OP)
0b6ae522 10269
015dc7e1 10270static bool
dda8d76d
NC
10271decode_arm_unwind_bytecode (Filedata * filedata,
10272 struct arm_unw_aux_info * aux,
948f632f
DA
10273 unsigned int word,
10274 unsigned int remaining,
10275 unsigned int more_words,
625d49fc 10276 uint64_t data_offset,
948f632f
DA
10277 Elf_Internal_Shdr * data_sec,
10278 struct arm_section * data_arm_sec)
fa197c1c
PB
10279{
10280 struct absaddr addr;
015dc7e1 10281 bool res = true;
0b6ae522
DJ
10282
10283 /* Decode the unwinding instructions. */
10284 while (1)
10285 {
10286 unsigned int op, op2;
10287
10288 ADVANCE;
10289 if (remaining == 0)
10290 break;
10291 remaining--;
10292 op = word >> 24;
10293 word <<= 8;
10294
cc5914eb 10295 printf (" 0x%02x ", op);
0b6ae522
DJ
10296
10297 if ((op & 0xc0) == 0x00)
10298 {
10299 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10300
cc5914eb 10301 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10302 }
10303 else if ((op & 0xc0) == 0x40)
10304 {
10305 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10306
cc5914eb 10307 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10308 }
10309 else if ((op & 0xf0) == 0x80)
10310 {
10311 GET_OP (op2);
10312 if (op == 0x80 && op2 == 0)
10313 printf (_("Refuse to unwind"));
10314 else
10315 {
10316 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10317 bool first = true;
0b6ae522 10318 int i;
2b692964 10319
0b6ae522
DJ
10320 printf ("pop {");
10321 for (i = 0; i < 12; i++)
10322 if (mask & (1 << i))
10323 {
10324 if (first)
015dc7e1 10325 first = false;
0b6ae522
DJ
10326 else
10327 printf (", ");
10328 printf ("r%d", 4 + i);
10329 }
10330 printf ("}");
10331 }
10332 }
10333 else if ((op & 0xf0) == 0x90)
10334 {
10335 if (op == 0x9d || op == 0x9f)
10336 printf (_(" [Reserved]"));
10337 else
cc5914eb 10338 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10339 }
10340 else if ((op & 0xf0) == 0xa0)
10341 {
10342 int end = 4 + (op & 0x07);
015dc7e1 10343 bool first = true;
0b6ae522 10344 int i;
61865e30 10345
0b6ae522
DJ
10346 printf (" pop {");
10347 for (i = 4; i <= end; i++)
10348 {
10349 if (first)
015dc7e1 10350 first = false;
0b6ae522
DJ
10351 else
10352 printf (", ");
10353 printf ("r%d", i);
10354 }
10355 if (op & 0x08)
10356 {
1b31d05e 10357 if (!first)
0b6ae522
DJ
10358 printf (", ");
10359 printf ("r14");
10360 }
10361 printf ("}");
10362 }
10363 else if (op == 0xb0)
10364 printf (_(" finish"));
10365 else if (op == 0xb1)
10366 {
10367 GET_OP (op2);
10368 if (op2 == 0 || (op2 & 0xf0) != 0)
10369 printf (_("[Spare]"));
10370 else
10371 {
10372 unsigned int mask = op2 & 0x0f;
015dc7e1 10373 bool first = true;
0b6ae522 10374 int i;
61865e30 10375
0b6ae522
DJ
10376 printf ("pop {");
10377 for (i = 0; i < 12; i++)
10378 if (mask & (1 << i))
10379 {
10380 if (first)
015dc7e1 10381 first = false;
0b6ae522
DJ
10382 else
10383 printf (", ");
10384 printf ("r%d", i);
10385 }
10386 printf ("}");
10387 }
10388 }
10389 else if (op == 0xb2)
10390 {
b115cf96 10391 unsigned char buf[9];
0b6ae522 10392 unsigned int i, len;
26c527e6 10393 uint64_t offset;
61865e30 10394
b115cf96 10395 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10396 {
10397 GET_OP (buf[i]);
10398 if ((buf[i] & 0x80) == 0)
10399 break;
10400 }
4082ef84 10401 if (i == sizeof (buf))
32ec8896 10402 {
27a45f42 10403 error (_("corrupt change to vsp\n"));
015dc7e1 10404 res = false;
32ec8896 10405 }
4082ef84
NC
10406 else
10407 {
015dc7e1 10408 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10409 assert (len == i + 1);
10410 offset = offset * 4 + 0x204;
26c527e6 10411 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10412 }
0b6ae522 10413 }
61865e30 10414 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10415 {
61865e30
NC
10416 unsigned int first, last;
10417
10418 GET_OP (op2);
10419 first = op2 >> 4;
10420 last = op2 & 0x0f;
10421 if (op == 0xc8)
10422 first = first + 16;
10423 printf ("pop {D%d", first);
10424 if (last)
10425 printf ("-D%d", first + last);
10426 printf ("}");
10427 }
09854a88
TB
10428 else if (op == 0xb4)
10429 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10430 else if (op == 0xb5)
10431 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10432 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10433 {
10434 unsigned int count = op & 0x07;
10435
10436 printf ("pop {D8");
10437 if (count)
10438 printf ("-D%d", 8 + count);
10439 printf ("}");
10440 }
10441 else if (op >= 0xc0 && op <= 0xc5)
10442 {
10443 unsigned int count = op & 0x07;
10444
10445 printf (" pop {wR10");
10446 if (count)
10447 printf ("-wR%d", 10 + count);
10448 printf ("}");
10449 }
10450 else if (op == 0xc6)
10451 {
10452 unsigned int first, last;
10453
10454 GET_OP (op2);
10455 first = op2 >> 4;
10456 last = op2 & 0x0f;
10457 printf ("pop {wR%d", first);
10458 if (last)
10459 printf ("-wR%d", first + last);
10460 printf ("}");
10461 }
10462 else if (op == 0xc7)
10463 {
10464 GET_OP (op2);
10465 if (op2 == 0 || (op2 & 0xf0) != 0)
10466 printf (_("[Spare]"));
0b6ae522
DJ
10467 else
10468 {
61865e30 10469 unsigned int mask = op2 & 0x0f;
015dc7e1 10470 bool first = true;
61865e30
NC
10471 int i;
10472
10473 printf ("pop {");
10474 for (i = 0; i < 4; i++)
10475 if (mask & (1 << i))
10476 {
10477 if (first)
015dc7e1 10478 first = false;
61865e30
NC
10479 else
10480 printf (", ");
10481 printf ("wCGR%d", i);
10482 }
10483 printf ("}");
0b6ae522
DJ
10484 }
10485 }
61865e30 10486 else
32ec8896
NC
10487 {
10488 printf (_(" [unsupported opcode]"));
015dc7e1 10489 res = false;
32ec8896
NC
10490 }
10491
0b6ae522
DJ
10492 printf ("\n");
10493 }
32ec8896
NC
10494
10495 return res;
fa197c1c
PB
10496}
10497
015dc7e1 10498static bool
dda8d76d
NC
10499decode_tic6x_unwind_bytecode (Filedata * filedata,
10500 struct arm_unw_aux_info * aux,
948f632f
DA
10501 unsigned int word,
10502 unsigned int remaining,
10503 unsigned int more_words,
625d49fc 10504 uint64_t data_offset,
948f632f
DA
10505 Elf_Internal_Shdr * data_sec,
10506 struct arm_section * data_arm_sec)
fa197c1c
PB
10507{
10508 struct absaddr addr;
10509
10510 /* Decode the unwinding instructions. */
10511 while (1)
10512 {
10513 unsigned int op, op2;
10514
10515 ADVANCE;
10516 if (remaining == 0)
10517 break;
10518 remaining--;
10519 op = word >> 24;
10520 word <<= 8;
10521
9cf03b7e 10522 printf (" 0x%02x ", op);
fa197c1c
PB
10523
10524 if ((op & 0xc0) == 0x00)
10525 {
10526 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10527 printf (" sp = sp + %d", offset);
fa197c1c
PB
10528 }
10529 else if ((op & 0xc0) == 0x80)
10530 {
10531 GET_OP (op2);
10532 if (op == 0x80 && op2 == 0)
10533 printf (_("Refuse to unwind"));
10534 else
10535 {
10536 unsigned int mask = ((op & 0x1f) << 8) | op2;
10537 if (op & 0x20)
10538 printf ("pop compact {");
10539 else
10540 printf ("pop {");
10541
10542 decode_tic6x_unwind_regmask (mask);
10543 printf("}");
10544 }
10545 }
10546 else if ((op & 0xf0) == 0xc0)
10547 {
10548 unsigned int reg;
10549 unsigned int nregs;
10550 unsigned int i;
10551 const char *name;
a734115a
NC
10552 struct
10553 {
32ec8896
NC
10554 unsigned int offset;
10555 unsigned int reg;
fa197c1c
PB
10556 } regpos[16];
10557
10558 /* Scan entire instruction first so that GET_OP output is not
10559 interleaved with disassembly. */
10560 nregs = 0;
10561 for (i = 0; nregs < (op & 0xf); i++)
10562 {
10563 GET_OP (op2);
10564 reg = op2 >> 4;
10565 if (reg != 0xf)
10566 {
10567 regpos[nregs].offset = i * 2;
10568 regpos[nregs].reg = reg;
10569 nregs++;
10570 }
10571
10572 reg = op2 & 0xf;
10573 if (reg != 0xf)
10574 {
10575 regpos[nregs].offset = i * 2 + 1;
10576 regpos[nregs].reg = reg;
10577 nregs++;
10578 }
10579 }
10580
10581 printf (_("pop frame {"));
18344509 10582 if (nregs == 0)
fa197c1c 10583 {
18344509
NC
10584 printf (_("*corrupt* - no registers specified"));
10585 }
10586 else
10587 {
10588 reg = nregs - 1;
10589 for (i = i * 2; i > 0; i--)
fa197c1c 10590 {
18344509
NC
10591 if (regpos[reg].offset == i - 1)
10592 {
10593 name = tic6x_unwind_regnames[regpos[reg].reg];
10594 if (reg > 0)
10595 reg--;
10596 }
10597 else
10598 name = _("[pad]");
fa197c1c 10599
18344509
NC
10600 fputs (name, stdout);
10601 if (i > 1)
10602 printf (", ");
10603 }
fa197c1c
PB
10604 }
10605
10606 printf ("}");
10607 }
10608 else if (op == 0xd0)
10609 printf (" MOV FP, SP");
10610 else if (op == 0xd1)
10611 printf (" __c6xabi_pop_rts");
10612 else if (op == 0xd2)
10613 {
10614 unsigned char buf[9];
10615 unsigned int i, len;
26c527e6 10616 uint64_t offset;
a734115a 10617
fa197c1c
PB
10618 for (i = 0; i < sizeof (buf); i++)
10619 {
10620 GET_OP (buf[i]);
10621 if ((buf[i] & 0x80) == 0)
10622 break;
10623 }
0eff7165
NC
10624 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10625 if (i == sizeof (buf))
10626 {
0eff7165 10627 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10628 return false;
0eff7165 10629 }
948f632f 10630
015dc7e1 10631 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10632 assert (len == i + 1);
10633 offset = offset * 8 + 0x408;
26c527e6 10634 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10635 }
10636 else if ((op & 0xf0) == 0xe0)
10637 {
10638 if ((op & 0x0f) == 7)
10639 printf (" RETURN");
10640 else
10641 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10642 }
10643 else
10644 {
10645 printf (_(" [unsupported opcode]"));
10646 }
10647 putchar ('\n');
10648 }
32ec8896 10649
015dc7e1 10650 return true;
fa197c1c
PB
10651}
10652
625d49fc
AM
10653static uint64_t
10654arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10655{
625d49fc 10656 uint64_t offset;
fa197c1c
PB
10657
10658 offset = word & 0x7fffffff;
10659 if (offset & 0x40000000)
625d49fc 10660 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10661
dda8d76d 10662 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10663 offset <<= 1;
10664
10665 return offset + where;
10666}
10667
015dc7e1 10668static bool
dda8d76d
NC
10669decode_arm_unwind (Filedata * filedata,
10670 struct arm_unw_aux_info * aux,
1b31d05e
NC
10671 unsigned int word,
10672 unsigned int remaining,
625d49fc 10673 uint64_t data_offset,
1b31d05e
NC
10674 Elf_Internal_Shdr * data_sec,
10675 struct arm_section * data_arm_sec)
fa197c1c
PB
10676{
10677 int per_index;
10678 unsigned int more_words = 0;
37e14bc3 10679 struct absaddr addr;
625d49fc 10680 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10681 bool res = true;
fa197c1c
PB
10682
10683 if (remaining == 0)
10684 {
1b31d05e
NC
10685 /* Fetch the first word.
10686 Note - when decoding an object file the address extracted
10687 here will always be 0. So we also pass in the sym_name
10688 parameter so that we can find the symbol associated with
10689 the personality routine. */
dda8d76d 10690 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10691 & word, & addr, & sym_name))
015dc7e1 10692 return false;
1b31d05e 10693
fa197c1c
PB
10694 remaining = 4;
10695 }
c93dbb25
CZ
10696 else
10697 {
10698 addr.section = SHN_UNDEF;
10699 addr.offset = 0;
10700 }
fa197c1c
PB
10701
10702 if ((word & 0x80000000) == 0)
10703 {
10704 /* Expand prel31 for personality routine. */
625d49fc 10705 uint64_t fn;
fa197c1c
PB
10706 const char *procname;
10707
dda8d76d 10708 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10709 printf (_(" Personality routine: "));
1b31d05e
NC
10710 if (fn == 0
10711 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10712 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10713 {
10714 procname = aux->strtab + sym_name;
10715 print_vma (fn, PREFIX_HEX);
10716 if (procname)
10717 {
10718 fputs (" <", stdout);
10719 fputs (procname, stdout);
10720 fputc ('>', stdout);
10721 }
10722 }
10723 else
dda8d76d 10724 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10725 fputc ('\n', stdout);
10726
10727 /* The GCC personality routines use the standard compact
10728 encoding, starting with one byte giving the number of
10729 words. */
10730 if (procname != NULL
24d127aa
ML
10731 && (startswith (procname, "__gcc_personality_v0")
10732 || startswith (procname, "__gxx_personality_v0")
10733 || startswith (procname, "__gcj_personality_v0")
10734 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10735 {
10736 remaining = 0;
10737 more_words = 1;
10738 ADVANCE;
10739 if (!remaining)
10740 {
10741 printf (_(" [Truncated data]\n"));
015dc7e1 10742 return false;
fa197c1c
PB
10743 }
10744 more_words = word >> 24;
10745 word <<= 8;
10746 remaining--;
10747 per_index = -1;
10748 }
10749 else
015dc7e1 10750 return true;
fa197c1c
PB
10751 }
10752 else
10753 {
1b31d05e 10754 /* ARM EHABI Section 6.3:
0b4362b0 10755
1b31d05e 10756 An exception-handling table entry for the compact model looks like:
0b4362b0 10757
1b31d05e
NC
10758 31 30-28 27-24 23-0
10759 -- ----- ----- ----
10760 1 0 index Data for personalityRoutine[index] */
10761
dda8d76d 10762 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10763 && (word & 0x70000000))
32ec8896
NC
10764 {
10765 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10766 res = false;
32ec8896 10767 }
1b31d05e 10768
fa197c1c 10769 per_index = (word >> 24) & 0x7f;
1b31d05e 10770 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10771 if (per_index == 0)
10772 {
10773 more_words = 0;
10774 word <<= 8;
10775 remaining--;
10776 }
10777 else if (per_index < 3)
10778 {
10779 more_words = (word >> 16) & 0xff;
10780 word <<= 16;
10781 remaining -= 2;
10782 }
10783 }
10784
dda8d76d 10785 switch (filedata->file_header.e_machine)
fa197c1c
PB
10786 {
10787 case EM_ARM:
10788 if (per_index < 3)
10789 {
dda8d76d 10790 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10791 data_offset, data_sec, data_arm_sec))
015dc7e1 10792 res = false;
fa197c1c
PB
10793 }
10794 else
1b31d05e
NC
10795 {
10796 warn (_("Unknown ARM compact model index encountered\n"));
10797 printf (_(" [reserved]\n"));
015dc7e1 10798 res = false;
1b31d05e 10799 }
fa197c1c
PB
10800 break;
10801
10802 case EM_TI_C6000:
10803 if (per_index < 3)
10804 {
dda8d76d 10805 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10806 data_offset, data_sec, data_arm_sec))
015dc7e1 10807 res = false;
fa197c1c
PB
10808 }
10809 else if (per_index < 5)
10810 {
10811 if (((word >> 17) & 0x7f) == 0x7f)
10812 printf (_(" Restore stack from frame pointer\n"));
10813 else
10814 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10815 printf (_(" Registers restored: "));
10816 if (per_index == 4)
10817 printf (" (compact) ");
10818 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10819 putchar ('\n');
10820 printf (_(" Return register: %s\n"),
10821 tic6x_unwind_regnames[word & 0xf]);
10822 }
10823 else
1b31d05e 10824 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10825 break;
10826
10827 default:
74e1a04b 10828 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10829 filedata->file_header.e_machine);
015dc7e1 10830 res = false;
fa197c1c 10831 }
0b6ae522
DJ
10832
10833 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10834
10835 return res;
0b6ae522
DJ
10836}
10837
015dc7e1 10838static bool
dda8d76d
NC
10839dump_arm_unwind (Filedata * filedata,
10840 struct arm_unw_aux_info * aux,
10841 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10842{
10843 struct arm_section exidx_arm_sec, extab_arm_sec;
10844 unsigned int i, exidx_len;
26c527e6 10845 uint64_t j, nfuns;
015dc7e1 10846 bool res = true;
0b6ae522
DJ
10847
10848 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10849 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10850 exidx_len = exidx_sec->sh_size / 8;
10851
948f632f
DA
10852 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10853 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10854 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10855 aux->funtab[nfuns++] = aux->symtab[j];
10856 aux->nfuns = nfuns;
10857 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10858
0b6ae522
DJ
10859 for (i = 0; i < exidx_len; i++)
10860 {
10861 unsigned int exidx_fn, exidx_entry;
10862 struct absaddr fn_addr, entry_addr;
625d49fc 10863 uint64_t fn;
0b6ae522
DJ
10864
10865 fputc ('\n', stdout);
10866
dda8d76d 10867 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10868 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10869 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10870 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10871 {
948f632f 10872 free (aux->funtab);
1b31d05e
NC
10873 arm_free_section (& exidx_arm_sec);
10874 arm_free_section (& extab_arm_sec);
015dc7e1 10875 return false;
0b6ae522
DJ
10876 }
10877
83c257ca
NC
10878 /* ARM EHABI, Section 5:
10879 An index table entry consists of 2 words.
10880 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10881 if (exidx_fn & 0x80000000)
32ec8896
NC
10882 {
10883 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10884 res = false;
32ec8896 10885 }
83c257ca 10886
dda8d76d 10887 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10888
dda8d76d 10889 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10890 fputs (": ", stdout);
10891
10892 if (exidx_entry == 1)
10893 {
10894 print_vma (exidx_entry, PREFIX_HEX);
10895 fputs (" [cantunwind]\n", stdout);
10896 }
10897 else if (exidx_entry & 0x80000000)
10898 {
10899 print_vma (exidx_entry, PREFIX_HEX);
10900 fputc ('\n', stdout);
dda8d76d 10901 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10902 }
10903 else
10904 {
625d49fc 10905 uint64_t table, table_offset = 0;
0b6ae522
DJ
10906 Elf_Internal_Shdr *table_sec;
10907
10908 fputs ("@", stdout);
dda8d76d 10909 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10910 print_vma (table, PREFIX_HEX);
10911 printf ("\n");
10912
10913 /* Locate the matching .ARM.extab. */
10914 if (entry_addr.section != SHN_UNDEF
dda8d76d 10915 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10916 {
dda8d76d 10917 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10918 table_offset = entry_addr.offset;
1a915552 10919 /* PR 18879 */
625d49fc 10920 if (table_offset > table_sec->sh_size)
1a915552 10921 {
26c527e6
AM
10922 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
10923 table_offset,
dda8d76d 10924 printable_section_name (filedata, table_sec));
015dc7e1 10925 res = false;
1a915552
NC
10926 continue;
10927 }
0b6ae522
DJ
10928 }
10929 else
10930 {
dda8d76d 10931 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10932 if (table_sec != NULL)
10933 table_offset = table - table_sec->sh_addr;
10934 }
32ec8896 10935
0b6ae522
DJ
10936 if (table_sec == NULL)
10937 {
26c527e6
AM
10938 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
10939 table);
015dc7e1 10940 res = false;
0b6ae522
DJ
10941 continue;
10942 }
32ec8896 10943
dda8d76d 10944 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10945 &extab_arm_sec))
015dc7e1 10946 res = false;
0b6ae522
DJ
10947 }
10948 }
10949
10950 printf ("\n");
10951
948f632f 10952 free (aux->funtab);
0b6ae522
DJ
10953 arm_free_section (&exidx_arm_sec);
10954 arm_free_section (&extab_arm_sec);
32ec8896
NC
10955
10956 return res;
0b6ae522
DJ
10957}
10958
fa197c1c 10959/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10960
015dc7e1 10961static bool
dda8d76d 10962arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10963{
10964 struct arm_unw_aux_info aux;
10965 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 10966 Elf_Internal_Shdr *sec;
26c527e6 10967 size_t i;
fa197c1c 10968 unsigned int sec_type;
015dc7e1 10969 bool res = true;
0b6ae522 10970
dda8d76d 10971 switch (filedata->file_header.e_machine)
fa197c1c
PB
10972 {
10973 case EM_ARM:
10974 sec_type = SHT_ARM_EXIDX;
10975 break;
10976
10977 case EM_TI_C6000:
10978 sec_type = SHT_C6000_UNWIND;
10979 break;
10980
0b4362b0 10981 default:
74e1a04b 10982 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10983 filedata->file_header.e_machine);
015dc7e1 10984 return false;
fa197c1c
PB
10985 }
10986
dda8d76d 10987 if (filedata->string_table == NULL)
015dc7e1 10988 return false;
1b31d05e
NC
10989
10990 memset (& aux, 0, sizeof (aux));
dda8d76d 10991 aux.filedata = filedata;
0b6ae522 10992
dda8d76d 10993 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10994 {
28d13567 10995 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10996 {
28d13567 10997 if (aux.symtab)
74e1a04b 10998 {
28d13567
AM
10999 error (_("Multiple symbol tables encountered\n"));
11000 free (aux.symtab);
11001 aux.symtab = NULL;
74e1a04b 11002 free (aux.strtab);
28d13567 11003 aux.strtab = NULL;
74e1a04b 11004 }
28d13567
AM
11005 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11006 &aux.strtab, &aux.strtab_size))
015dc7e1 11007 return false;
0b6ae522 11008 }
fa197c1c 11009 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11010 unwsec = sec;
11011 }
11012
1b31d05e 11013 if (unwsec == NULL)
0b6ae522 11014 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11015 else
dda8d76d 11016 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11017 {
11018 if (sec->sh_type == sec_type)
11019 {
26c527e6
AM
11020 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11021 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11022 "contains %" PRIu64 " entry:\n",
11023 "\nUnwind section '%s' at offset %#" PRIx64 " "
11024 "contains %" PRIu64 " entries:\n",
d3a49aa8 11025 num_unwind),
dda8d76d 11026 printable_section_name (filedata, sec),
26c527e6 11027 sec->sh_offset,
d3a49aa8 11028 num_unwind);
0b6ae522 11029
dda8d76d 11030 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11031 res = false;
1b31d05e
NC
11032 }
11033 }
0b6ae522 11034
9db70fc3
AM
11035 free (aux.symtab);
11036 free ((char *) aux.strtab);
32ec8896
NC
11037
11038 return res;
0b6ae522
DJ
11039}
11040
3ecc00ec
NC
11041static bool
11042no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11043{
11044 printf (_("No processor specific unwind information to decode\n"));
11045 return true;
11046}
11047
015dc7e1 11048static bool
dda8d76d 11049process_unwind (Filedata * filedata)
57346661 11050{
2cf0635d
NC
11051 struct unwind_handler
11052 {
32ec8896 11053 unsigned int machtype;
015dc7e1 11054 bool (* handler)(Filedata *);
2cf0635d
NC
11055 } handlers[] =
11056 {
0b6ae522 11057 { EM_ARM, arm_process_unwind },
57346661
AM
11058 { EM_IA_64, ia64_process_unwind },
11059 { EM_PARISC, hppa_process_unwind },
fa197c1c 11060 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11061 { EM_386, no_processor_specific_unwind },
11062 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11063 { 0, NULL }
57346661
AM
11064 };
11065 int i;
11066
11067 if (!do_unwind)
015dc7e1 11068 return true;
57346661
AM
11069
11070 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11071 if (filedata->file_header.e_machine == handlers[i].machtype)
11072 return handlers[i].handler (filedata);
57346661 11073
1b31d05e 11074 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11075 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11076 return true;
57346661
AM
11077}
11078
37c18eed
SD
11079static void
11080dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11081{
11082 switch (entry->d_tag)
11083 {
11084 case DT_AARCH64_BTI_PLT:
1dbade74 11085 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11086 break;
11087 default:
11088 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11089 break;
11090 }
11091 putchar ('\n');
11092}
11093
252b5132 11094static void
978c4450 11095dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11096{
11097 switch (entry->d_tag)
11098 {
11099 case DT_MIPS_FLAGS:
11100 if (entry->d_un.d_val == 0)
4b68bca3 11101 printf (_("NONE"));
252b5132
RH
11102 else
11103 {
11104 static const char * opts[] =
11105 {
11106 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11107 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11108 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11109 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11110 "RLD_ORDER_SAFE"
11111 };
11112 unsigned int cnt;
015dc7e1 11113 bool first = true;
2b692964 11114
60bca95a 11115 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11116 if (entry->d_un.d_val & (1 << cnt))
11117 {
11118 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11119 first = false;
252b5132 11120 }
252b5132
RH
11121 }
11122 break;
103f02d3 11123
252b5132 11124 case DT_MIPS_IVERSION:
84714f86 11125 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11126 printf (_("Interface Version: %s"),
84714f86 11127 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11128 else
f493c217 11129 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11130 entry->d_un.d_ptr);
252b5132 11131 break;
103f02d3 11132
252b5132
RH
11133 case DT_MIPS_TIME_STAMP:
11134 {
d5b07ef4 11135 char timebuf[128];
2cf0635d 11136 struct tm * tmp;
91d6fa6a 11137 time_t atime = entry->d_un.d_val;
82b1b41b 11138
91d6fa6a 11139 tmp = gmtime (&atime);
82b1b41b
NC
11140 /* PR 17531: file: 6accc532. */
11141 if (tmp == NULL)
11142 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11143 else
11144 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11145 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11146 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11147 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11148 }
11149 break;
103f02d3 11150
252b5132
RH
11151 case DT_MIPS_RLD_VERSION:
11152 case DT_MIPS_LOCAL_GOTNO:
11153 case DT_MIPS_CONFLICTNO:
11154 case DT_MIPS_LIBLISTNO:
11155 case DT_MIPS_SYMTABNO:
11156 case DT_MIPS_UNREFEXTNO:
11157 case DT_MIPS_HIPAGENO:
11158 case DT_MIPS_DELTA_CLASS_NO:
11159 case DT_MIPS_DELTA_INSTANCE_NO:
11160 case DT_MIPS_DELTA_RELOC_NO:
11161 case DT_MIPS_DELTA_SYM_NO:
11162 case DT_MIPS_DELTA_CLASSSYM_NO:
11163 case DT_MIPS_COMPACT_SIZE:
c69075ac 11164 print_vma (entry->d_un.d_val, DEC);
252b5132 11165 break;
103f02d3 11166
f16a9783 11167 case DT_MIPS_XHASH:
978c4450
AM
11168 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11169 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11170 /* Falls through. */
11171
103f02d3 11172 default:
4b68bca3 11173 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11174 }
4b68bca3 11175 putchar ('\n');
103f02d3
UD
11176}
11177
103f02d3 11178static void
2cf0635d 11179dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11180{
11181 switch (entry->d_tag)
11182 {
11183 case DT_HP_DLD_FLAGS:
11184 {
11185 static struct
11186 {
26c527e6 11187 unsigned int bit;
2cf0635d 11188 const char * str;
5e220199
NC
11189 }
11190 flags[] =
11191 {
11192 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11193 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11194 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11195 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11196 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11197 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11198 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11199 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11200 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11201 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11202 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11203 { DT_HP_GST, "HP_GST" },
11204 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11205 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11206 { DT_HP_NODELETE, "HP_NODELETE" },
11207 { DT_HP_GROUP, "HP_GROUP" },
11208 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11209 };
015dc7e1 11210 bool first = true;
5e220199 11211 size_t cnt;
625d49fc 11212 uint64_t val = entry->d_un.d_val;
103f02d3 11213
60bca95a 11214 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11215 if (val & flags[cnt].bit)
30800947
NC
11216 {
11217 if (! first)
11218 putchar (' ');
11219 fputs (flags[cnt].str, stdout);
015dc7e1 11220 first = false;
30800947
NC
11221 val ^= flags[cnt].bit;
11222 }
76da6bbe 11223
103f02d3 11224 if (val != 0 || first)
f7a99963
NC
11225 {
11226 if (! first)
11227 putchar (' ');
11228 print_vma (val, HEX);
11229 }
103f02d3
UD
11230 }
11231 break;
76da6bbe 11232
252b5132 11233 default:
f7a99963
NC
11234 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11235 break;
252b5132 11236 }
35b1837e 11237 putchar ('\n');
252b5132
RH
11238}
11239
28f997cf
TG
11240/* VMS vs Unix time offset and factor. */
11241
11242#define VMS_EPOCH_OFFSET 35067168000000000LL
11243#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11244#ifndef INT64_MIN
11245#define INT64_MIN (-9223372036854775807LL - 1)
11246#endif
28f997cf
TG
11247
11248/* Display a VMS time in a human readable format. */
11249
11250static void
0e3c1eeb 11251print_vms_time (int64_t vmstime)
28f997cf 11252{
dccc31de 11253 struct tm *tm = NULL;
28f997cf
TG
11254 time_t unxtime;
11255
dccc31de
AM
11256 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11257 {
11258 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11259 unxtime = vmstime;
11260 if (unxtime == vmstime)
11261 tm = gmtime (&unxtime);
11262 }
11263 if (tm != NULL)
11264 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11265 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11266 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11267}
28f997cf 11268
ecc51f48 11269static void
2cf0635d 11270dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11271{
11272 switch (entry->d_tag)
11273 {
0de14b54 11274 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11275 /* First 3 slots reserved. */
ecc51f48
NC
11276 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11277 printf (" -- ");
11278 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11279 break;
11280
28f997cf 11281 case DT_IA_64_VMS_LINKTIME:
28f997cf 11282 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11283 break;
11284
11285 case DT_IA_64_VMS_LNKFLAGS:
11286 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11287 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11288 printf (" CALL_DEBUG");
11289 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11290 printf (" NOP0BUFS");
11291 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11292 printf (" P0IMAGE");
11293 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11294 printf (" MKTHREADS");
11295 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11296 printf (" UPCALLS");
11297 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11298 printf (" IMGSTA");
11299 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11300 printf (" INITIALIZE");
11301 if (entry->d_un.d_val & VMS_LF_MAIN)
11302 printf (" MAIN");
11303 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11304 printf (" EXE_INIT");
11305 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11306 printf (" TBK_IN_IMG");
11307 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11308 printf (" DBG_IN_IMG");
11309 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11310 printf (" TBK_IN_DSF");
11311 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11312 printf (" DBG_IN_DSF");
11313 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11314 printf (" SIGNATURES");
11315 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11316 printf (" REL_SEG_OFF");
11317 break;
11318
bdf4d63a
JJ
11319 default:
11320 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11321 break;
ecc51f48 11322 }
bdf4d63a 11323 putchar ('\n');
ecc51f48
NC
11324}
11325
015dc7e1 11326static bool
dda8d76d 11327get_32bit_dynamic_section (Filedata * filedata)
252b5132 11328{
2cf0635d
NC
11329 Elf32_External_Dyn * edyn;
11330 Elf32_External_Dyn * ext;
11331 Elf_Internal_Dyn * entry;
103f02d3 11332
978c4450
AM
11333 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11334 filedata->dynamic_addr, 1,
11335 filedata->dynamic_size,
11336 _("dynamic section"));
a6e9f9df 11337 if (!edyn)
015dc7e1 11338 return false;
103f02d3 11339
071436c6
NC
11340 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11341 might not have the luxury of section headers. Look for the DT_NULL
11342 terminator to determine the number of entries. */
978c4450
AM
11343 for (ext = edyn, filedata->dynamic_nent = 0;
11344 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11345 ext++)
11346 {
978c4450 11347 filedata->dynamic_nent++;
ba2685cc
AM
11348 if (BYTE_GET (ext->d_tag) == DT_NULL)
11349 break;
11350 }
252b5132 11351
978c4450
AM
11352 filedata->dynamic_section
11353 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11354 if (filedata->dynamic_section == NULL)
252b5132 11355 {
26c527e6
AM
11356 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11357 filedata->dynamic_nent);
9ea033b2 11358 free (edyn);
015dc7e1 11359 return false;
9ea033b2 11360 }
252b5132 11361
978c4450
AM
11362 for (ext = edyn, entry = filedata->dynamic_section;
11363 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11364 ext++, entry++)
9ea033b2 11365 {
fb514b26
AM
11366 entry->d_tag = BYTE_GET (ext->d_tag);
11367 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11368 }
11369
9ea033b2
NC
11370 free (edyn);
11371
015dc7e1 11372 return true;
9ea033b2
NC
11373}
11374
015dc7e1 11375static bool
dda8d76d 11376get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11377{
2cf0635d
NC
11378 Elf64_External_Dyn * edyn;
11379 Elf64_External_Dyn * ext;
11380 Elf_Internal_Dyn * entry;
103f02d3 11381
071436c6 11382 /* Read in the data. */
978c4450
AM
11383 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11384 filedata->dynamic_addr, 1,
11385 filedata->dynamic_size,
11386 _("dynamic section"));
a6e9f9df 11387 if (!edyn)
015dc7e1 11388 return false;
103f02d3 11389
071436c6
NC
11390 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11391 might not have the luxury of section headers. Look for the DT_NULL
11392 terminator to determine the number of entries. */
978c4450 11393 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11394 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11395 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11396 ext++)
11397 {
978c4450 11398 filedata->dynamic_nent++;
66543521 11399 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11400 break;
11401 }
252b5132 11402
978c4450
AM
11403 filedata->dynamic_section
11404 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11405 if (filedata->dynamic_section == NULL)
252b5132 11406 {
26c527e6
AM
11407 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11408 filedata->dynamic_nent);
252b5132 11409 free (edyn);
015dc7e1 11410 return false;
252b5132
RH
11411 }
11412
071436c6 11413 /* Convert from external to internal formats. */
978c4450
AM
11414 for (ext = edyn, entry = filedata->dynamic_section;
11415 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11416 ext++, entry++)
252b5132 11417 {
66543521
AM
11418 entry->d_tag = BYTE_GET (ext->d_tag);
11419 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11420 }
11421
11422 free (edyn);
11423
015dc7e1 11424 return true;
9ea033b2
NC
11425}
11426
4de91c10
AM
11427static bool
11428get_dynamic_section (Filedata *filedata)
11429{
11430 if (filedata->dynamic_section)
11431 return true;
11432
11433 if (is_32bit_elf)
11434 return get_32bit_dynamic_section (filedata);
11435 else
11436 return get_64bit_dynamic_section (filedata);
11437}
11438
e9e44622 11439static void
625d49fc 11440print_dynamic_flags (uint64_t flags)
d1133906 11441{
015dc7e1 11442 bool first = true;
13ae64f3 11443
d1133906
NC
11444 while (flags)
11445 {
625d49fc 11446 uint64_t flag;
d1133906
NC
11447
11448 flag = flags & - flags;
11449 flags &= ~ flag;
11450
e9e44622 11451 if (first)
015dc7e1 11452 first = false;
e9e44622
JJ
11453 else
11454 putc (' ', stdout);
13ae64f3 11455
d1133906
NC
11456 switch (flag)
11457 {
e9e44622
JJ
11458 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11459 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11460 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11461 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11462 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11463 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11464 }
11465 }
e9e44622 11466 puts ("");
d1133906
NC
11467}
11468
625d49fc 11469static uint64_t *
be7d229a 11470get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11471{
11472 unsigned char * e_data;
625d49fc 11473 uint64_t * i_data;
10ca4b04 11474
be7d229a
AM
11475 /* If size_t is smaller than uint64_t, eg because you are building
11476 on a 32-bit host, then make sure that when number is cast to
11477 size_t no information is lost. */
11478 if ((size_t) number != number
11479 || ent_size * number / ent_size != number)
10ca4b04 11480 {
be7d229a 11481 error (_("Size overflow prevents reading %" PRIu64
b8281767 11482 " elements of size %u\n"),
be7d229a 11483 number, ent_size);
10ca4b04
L
11484 return NULL;
11485 }
11486
11487 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11488 attempting to allocate memory when the read is bound to fail. */
11489 if (ent_size * number > filedata->file_size)
11490 {
b8281767 11491 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11492 number);
10ca4b04
L
11493 return NULL;
11494 }
11495
11496 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11497 if (e_data == NULL)
11498 {
b8281767 11499 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11500 number);
10ca4b04
L
11501 return NULL;
11502 }
11503
11504 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11505 {
b8281767 11506 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11507 number * ent_size);
10ca4b04
L
11508 free (e_data);
11509 return NULL;
11510 }
11511
625d49fc 11512 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11513 if (i_data == NULL)
11514 {
b8281767 11515 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11516 number);
10ca4b04
L
11517 free (e_data);
11518 return NULL;
11519 }
11520
11521 while (number--)
11522 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11523
11524 free (e_data);
11525
11526 return i_data;
11527}
11528
26c527e6 11529static uint64_t
10ca4b04
L
11530get_num_dynamic_syms (Filedata * filedata)
11531{
26c527e6 11532 uint64_t num_of_syms = 0;
10ca4b04
L
11533
11534 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11535 return num_of_syms;
11536
978c4450 11537 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11538 {
11539 unsigned char nb[8];
11540 unsigned char nc[8];
11541 unsigned int hash_ent_size = 4;
11542
11543 if ((filedata->file_header.e_machine == EM_ALPHA
11544 || filedata->file_header.e_machine == EM_S390
11545 || filedata->file_header.e_machine == EM_S390_OLD)
11546 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11547 hash_ent_size = 8;
11548
63cf857e
AM
11549 if (fseek64 (filedata->handle,
11550 (filedata->archive_file_offset
11551 + offset_from_vma (filedata,
11552 filedata->dynamic_info[DT_HASH],
11553 sizeof nb + sizeof nc)),
11554 SEEK_SET))
10ca4b04
L
11555 {
11556 error (_("Unable to seek to start of dynamic information\n"));
11557 goto no_hash;
11558 }
11559
11560 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11561 {
11562 error (_("Failed to read in number of buckets\n"));
11563 goto no_hash;
11564 }
11565
11566 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11567 {
11568 error (_("Failed to read in number of chains\n"));
11569 goto no_hash;
11570 }
11571
978c4450
AM
11572 filedata->nbuckets = byte_get (nb, hash_ent_size);
11573 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11574
2482f306
AM
11575 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11576 {
11577 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11578 hash_ent_size);
11579 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11580 hash_ent_size);
001890e1 11581
2482f306
AM
11582 if (filedata->buckets != NULL && filedata->chains != NULL)
11583 num_of_syms = filedata->nchains;
11584 }
ceb9bf11 11585 no_hash:
10ca4b04
L
11586 if (num_of_syms == 0)
11587 {
9db70fc3
AM
11588 free (filedata->buckets);
11589 filedata->buckets = NULL;
11590 free (filedata->chains);
11591 filedata->chains = NULL;
978c4450 11592 filedata->nbuckets = 0;
10ca4b04
L
11593 }
11594 }
11595
978c4450 11596 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11597 {
11598 unsigned char nb[16];
625d49fc
AM
11599 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11600 uint64_t buckets_vma;
26c527e6 11601 uint64_t hn;
10ca4b04 11602
63cf857e
AM
11603 if (fseek64 (filedata->handle,
11604 (filedata->archive_file_offset
11605 + offset_from_vma (filedata,
11606 filedata->dynamic_info_DT_GNU_HASH,
11607 sizeof nb)),
11608 SEEK_SET))
10ca4b04
L
11609 {
11610 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11611 goto no_gnu_hash;
11612 }
11613
11614 if (fread (nb, 16, 1, filedata->handle) != 1)
11615 {
11616 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11617 goto no_gnu_hash;
11618 }
11619
978c4450
AM
11620 filedata->ngnubuckets = byte_get (nb, 4);
11621 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11622 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11623 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11624 if (is_32bit_elf)
11625 buckets_vma += bitmaskwords * 4;
11626 else
11627 buckets_vma += bitmaskwords * 8;
11628
63cf857e
AM
11629 if (fseek64 (filedata->handle,
11630 (filedata->archive_file_offset
11631 + offset_from_vma (filedata, buckets_vma, 4)),
11632 SEEK_SET))
10ca4b04
L
11633 {
11634 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11635 goto no_gnu_hash;
11636 }
11637
978c4450
AM
11638 filedata->gnubuckets
11639 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11640
978c4450 11641 if (filedata->gnubuckets == NULL)
90837ea7 11642 goto no_gnu_hash;
10ca4b04 11643
978c4450
AM
11644 for (i = 0; i < filedata->ngnubuckets; i++)
11645 if (filedata->gnubuckets[i] != 0)
10ca4b04 11646 {
978c4450 11647 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11648 goto no_gnu_hash;
10ca4b04 11649
978c4450
AM
11650 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11651 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11652 }
11653
11654 if (maxchain == 0xffffffff)
90837ea7 11655 goto no_gnu_hash;
10ca4b04 11656
978c4450 11657 maxchain -= filedata->gnusymidx;
10ca4b04 11658
63cf857e
AM
11659 if (fseek64 (filedata->handle,
11660 (filedata->archive_file_offset
11661 + offset_from_vma (filedata,
11662 buckets_vma + 4 * (filedata->ngnubuckets
11663 + maxchain),
11664 4)),
11665 SEEK_SET))
10ca4b04
L
11666 {
11667 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11668 goto no_gnu_hash;
11669 }
11670
11671 do
11672 {
11673 if (fread (nb, 4, 1, filedata->handle) != 1)
11674 {
11675 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11676 goto no_gnu_hash;
11677 }
11678
11679 if (maxchain + 1 == 0)
90837ea7 11680 goto no_gnu_hash;
10ca4b04
L
11681
11682 ++maxchain;
11683 }
11684 while ((byte_get (nb, 4) & 1) == 0);
11685
63cf857e
AM
11686 if (fseek64 (filedata->handle,
11687 (filedata->archive_file_offset
11688 + offset_from_vma (filedata, (buckets_vma
11689 + 4 * filedata->ngnubuckets),
11690 4)),
11691 SEEK_SET))
10ca4b04
L
11692 {
11693 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11694 goto no_gnu_hash;
11695 }
11696
978c4450
AM
11697 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11698 filedata->ngnuchains = maxchain;
10ca4b04 11699
978c4450 11700 if (filedata->gnuchains == NULL)
90837ea7 11701 goto no_gnu_hash;
10ca4b04 11702
978c4450 11703 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 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 + maxchain)), 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 11716 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11717 if (filedata->mipsxlat == NULL)
11718 goto no_gnu_hash;
10ca4b04
L
11719 }
11720
978c4450
AM
11721 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11722 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11723 {
625d49fc
AM
11724 uint64_t si = filedata->gnubuckets[hn];
11725 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11726
11727 do
11728 {
978c4450 11729 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11730 {
c31ab5a0
AM
11731 if (off < filedata->ngnuchains
11732 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11733 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11734 }
11735 else
11736 {
11737 if (si >= num_of_syms)
11738 num_of_syms = si + 1;
11739 }
11740 si++;
11741 }
978c4450
AM
11742 while (off < filedata->ngnuchains
11743 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11744 }
11745
90837ea7 11746 if (num_of_syms == 0)
10ca4b04 11747 {
90837ea7 11748 no_gnu_hash:
9db70fc3
AM
11749 free (filedata->mipsxlat);
11750 filedata->mipsxlat = NULL;
11751 free (filedata->gnuchains);
11752 filedata->gnuchains = NULL;
11753 free (filedata->gnubuckets);
11754 filedata->gnubuckets = NULL;
978c4450
AM
11755 filedata->ngnubuckets = 0;
11756 filedata->ngnuchains = 0;
10ca4b04
L
11757 }
11758 }
11759
11760 return num_of_syms;
11761}
11762
b2d38a17
NC
11763/* Parse and display the contents of the dynamic section. */
11764
015dc7e1 11765static bool
dda8d76d 11766process_dynamic_section (Filedata * filedata)
9ea033b2 11767{
2cf0635d 11768 Elf_Internal_Dyn * entry;
9ea033b2 11769
93df3340 11770 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11771 {
11772 if (do_dynamic)
ca0e11aa
NC
11773 {
11774 if (filedata->is_separate)
11775 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11776 filedata->file_name);
11777 else
11778 printf (_("\nThere is no dynamic section in this file.\n"));
11779 }
9ea033b2 11780
015dc7e1 11781 return true;
9ea033b2
NC
11782 }
11783
4de91c10
AM
11784 if (!get_dynamic_section (filedata))
11785 return false;
9ea033b2 11786
252b5132 11787 /* Find the appropriate symbol table. */
978c4450 11788 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11789 {
26c527e6 11790 uint64_t num_of_syms;
2482f306 11791
978c4450
AM
11792 for (entry = filedata->dynamic_section;
11793 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11794 ++entry)
10ca4b04 11795 if (entry->d_tag == DT_SYMTAB)
978c4450 11796 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11797 else if (entry->d_tag == DT_SYMENT)
978c4450 11798 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11799 else if (entry->d_tag == DT_HASH)
978c4450 11800 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11801 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11802 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11803 else if ((filedata->file_header.e_machine == EM_MIPS
11804 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11805 && entry->d_tag == DT_MIPS_XHASH)
11806 {
978c4450
AM
11807 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11808 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11809 }
252b5132 11810
2482f306
AM
11811 num_of_syms = get_num_dynamic_syms (filedata);
11812
11813 if (num_of_syms != 0
11814 && filedata->dynamic_symbols == NULL
11815 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11816 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11817 {
11818 Elf_Internal_Phdr *seg;
625d49fc 11819 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11820
2482f306
AM
11821 if (! get_program_headers (filedata))
11822 {
11823 error (_("Cannot interpret virtual addresses "
11824 "without program headers.\n"));
015dc7e1 11825 return false;
2482f306 11826 }
252b5132 11827
2482f306
AM
11828 for (seg = filedata->program_headers;
11829 seg < filedata->program_headers + filedata->file_header.e_phnum;
11830 ++seg)
11831 {
11832 if (seg->p_type != PT_LOAD)
11833 continue;
252b5132 11834
2482f306
AM
11835 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11836 {
11837 /* See PR 21379 for a reproducer. */
11838 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11839 return false;
2482f306 11840 }
252b5132 11841
2482f306
AM
11842 if (vma >= (seg->p_vaddr & -seg->p_align)
11843 && vma < seg->p_vaddr + seg->p_filesz)
11844 {
11845 /* Since we do not know how big the symbol table is,
11846 we default to reading in up to the end of PT_LOAD
11847 segment and processing that. This is overkill, I
11848 know, but it should work. */
11849 Elf_Internal_Shdr section;
11850 section.sh_offset = (vma - seg->p_vaddr
11851 + seg->p_offset);
11852 section.sh_size = (num_of_syms
11853 * filedata->dynamic_info[DT_SYMENT]);
11854 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11855
11856 if (do_checks
11857 && filedata->dynamic_symtab_section != NULL
11858 && ((filedata->dynamic_symtab_section->sh_offset
11859 != section.sh_offset)
11860 || (filedata->dynamic_symtab_section->sh_size
11861 != section.sh_size)
11862 || (filedata->dynamic_symtab_section->sh_entsize
11863 != section.sh_entsize)))
11864 warn (_("\
11865the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11866
2482f306
AM
11867 section.sh_name = filedata->string_table_length;
11868 filedata->dynamic_symbols
4de91c10 11869 = get_elf_symbols (filedata, &section,
2482f306
AM
11870 &filedata->num_dynamic_syms);
11871 if (filedata->dynamic_symbols == NULL
11872 || filedata->num_dynamic_syms != num_of_syms)
11873 {
11874 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11875 return false;
2482f306
AM
11876 }
11877 break;
11878 }
11879 }
11880 }
11881 }
252b5132
RH
11882
11883 /* Similarly find a string table. */
978c4450
AM
11884 if (filedata->dynamic_strings == NULL)
11885 for (entry = filedata->dynamic_section;
11886 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11887 ++entry)
11888 {
11889 if (entry->d_tag == DT_STRTAB)
978c4450 11890 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11891
10ca4b04 11892 if (entry->d_tag == DT_STRSZ)
978c4450 11893 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11894
978c4450
AM
11895 if (filedata->dynamic_info[DT_STRTAB]
11896 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 11897 {
26c527e6 11898 uint64_t offset;
be7d229a 11899 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11900
11901 offset = offset_from_vma (filedata,
978c4450 11902 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11903 str_tab_len);
8ac10c5b
L
11904 if (do_checks
11905 && filedata->dynamic_strtab_section
11906 && ((filedata->dynamic_strtab_section->sh_offset
11907 != (file_ptr) offset)
11908 || (filedata->dynamic_strtab_section->sh_size
11909 != str_tab_len)))
11910 warn (_("\
11911the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11912
978c4450
AM
11913 filedata->dynamic_strings
11914 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11915 _("dynamic string table"));
11916 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11917 {
11918 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11919 break;
11920 }
e3d39609 11921
978c4450 11922 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11923 break;
11924 }
11925 }
252b5132
RH
11926
11927 /* And find the syminfo section if available. */
978c4450 11928 if (filedata->dynamic_syminfo == NULL)
252b5132 11929 {
26c527e6 11930 uint64_t syminsz = 0;
252b5132 11931
978c4450
AM
11932 for (entry = filedata->dynamic_section;
11933 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11934 ++entry)
252b5132
RH
11935 {
11936 if (entry->d_tag == DT_SYMINENT)
11937 {
11938 /* Note: these braces are necessary to avoid a syntax
11939 error from the SunOS4 C compiler. */
049b0c3a
NC
11940 /* PR binutils/17531: A corrupt file can trigger this test.
11941 So do not use an assert, instead generate an error message. */
11942 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11943 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11944 (int) entry->d_un.d_val);
252b5132
RH
11945 }
11946 else if (entry->d_tag == DT_SYMINSZ)
11947 syminsz = entry->d_un.d_val;
11948 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11949 filedata->dynamic_syminfo_offset
11950 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11951 }
11952
978c4450 11953 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11954 {
2cf0635d
NC
11955 Elf_External_Syminfo * extsyminfo;
11956 Elf_External_Syminfo * extsym;
11957 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11958
11959 /* There is a syminfo section. Read the data. */
3f5e193b 11960 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11961 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11962 1, syminsz, _("symbol information"));
a6e9f9df 11963 if (!extsyminfo)
015dc7e1 11964 return false;
252b5132 11965
978c4450 11966 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11967 {
11968 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11969 free (filedata->dynamic_syminfo);
e3d39609 11970 }
978c4450
AM
11971 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11972 if (filedata->dynamic_syminfo == NULL)
252b5132 11973 {
26c527e6
AM
11974 error (_("Out of memory allocating %" PRIu64
11975 " bytes for dynamic symbol info\n"),
11976 syminsz);
015dc7e1 11977 return false;
252b5132
RH
11978 }
11979
2482f306
AM
11980 filedata->dynamic_syminfo_nent
11981 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11982 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11983 syminfo < (filedata->dynamic_syminfo
11984 + filedata->dynamic_syminfo_nent);
86dba8ee 11985 ++syminfo, ++extsym)
252b5132 11986 {
86dba8ee
AM
11987 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11988 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11989 }
11990
11991 free (extsyminfo);
11992 }
11993 }
11994
978c4450 11995 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11996 {
f253158f 11997 if (filedata->is_separate)
26c527e6
AM
11998 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
11999 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12000 filedata->dynamic_nent),
f253158f
NC
12001 filedata->file_name,
12002 filedata->dynamic_addr,
26c527e6 12003 filedata->dynamic_nent);
84a9f195 12004 else
02da71ee 12005 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12006 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12007 filedata->dynamic_nent),
84a9f195 12008 filedata->dynamic_addr,
26c527e6 12009 filedata->dynamic_nent);
ca0e11aa 12010 }
252b5132
RH
12011 if (do_dynamic)
12012 printf (_(" Tag Type Name/Value\n"));
12013
978c4450
AM
12014 for (entry = filedata->dynamic_section;
12015 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12016 entry++)
252b5132
RH
12017 {
12018 if (do_dynamic)
f7a99963 12019 {
2cf0635d 12020 const char * dtype;
e699b9ff 12021
f7a99963
NC
12022 putchar (' ');
12023 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12024 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12025 printf (" (%s)%*s", dtype,
32ec8896 12026 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12027 }
252b5132
RH
12028
12029 switch (entry->d_tag)
12030 {
d1133906
NC
12031 case DT_FLAGS:
12032 if (do_dynamic)
e9e44622 12033 print_dynamic_flags (entry->d_un.d_val);
d1133906 12034 break;
76da6bbe 12035
252b5132
RH
12036 case DT_AUXILIARY:
12037 case DT_FILTER:
019148e4
L
12038 case DT_CONFIG:
12039 case DT_DEPAUDIT:
12040 case DT_AUDIT:
252b5132
RH
12041 if (do_dynamic)
12042 {
019148e4 12043 switch (entry->d_tag)
b34976b6 12044 {
019148e4
L
12045 case DT_AUXILIARY:
12046 printf (_("Auxiliary library"));
12047 break;
12048
12049 case DT_FILTER:
12050 printf (_("Filter library"));
12051 break;
12052
b34976b6 12053 case DT_CONFIG:
019148e4
L
12054 printf (_("Configuration file"));
12055 break;
12056
12057 case DT_DEPAUDIT:
12058 printf (_("Dependency audit library"));
12059 break;
12060
12061 case DT_AUDIT:
12062 printf (_("Audit library"));
12063 break;
12064 }
252b5132 12065
84714f86 12066 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12067 printf (": [%s]\n",
84714f86 12068 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12069 else
f7a99963
NC
12070 {
12071 printf (": ");
12072 print_vma (entry->d_un.d_val, PREFIX_HEX);
12073 putchar ('\n');
12074 }
252b5132
RH
12075 }
12076 break;
12077
dcefbbbd 12078 case DT_FEATURE:
252b5132
RH
12079 if (do_dynamic)
12080 {
12081 printf (_("Flags:"));
86f55779 12082
252b5132
RH
12083 if (entry->d_un.d_val == 0)
12084 printf (_(" None\n"));
12085 else
12086 {
26c527e6 12087 uint64_t val = entry->d_un.d_val;
86f55779 12088
252b5132
RH
12089 if (val & DTF_1_PARINIT)
12090 {
12091 printf (" PARINIT");
12092 val ^= DTF_1_PARINIT;
12093 }
dcefbbbd
L
12094 if (val & DTF_1_CONFEXP)
12095 {
12096 printf (" CONFEXP");
12097 val ^= DTF_1_CONFEXP;
12098 }
252b5132 12099 if (val != 0)
26c527e6 12100 printf (" %" PRIx64, val);
252b5132
RH
12101 puts ("");
12102 }
12103 }
12104 break;
12105
12106 case DT_POSFLAG_1:
12107 if (do_dynamic)
12108 {
12109 printf (_("Flags:"));
86f55779 12110
252b5132
RH
12111 if (entry->d_un.d_val == 0)
12112 printf (_(" None\n"));
12113 else
12114 {
26c527e6 12115 uint64_t val = entry->d_un.d_val;
86f55779 12116
252b5132
RH
12117 if (val & DF_P1_LAZYLOAD)
12118 {
12119 printf (" LAZYLOAD");
12120 val ^= DF_P1_LAZYLOAD;
12121 }
12122 if (val & DF_P1_GROUPPERM)
12123 {
12124 printf (" GROUPPERM");
12125 val ^= DF_P1_GROUPPERM;
12126 }
12127 if (val != 0)
26c527e6 12128 printf (" %" PRIx64, val);
252b5132
RH
12129 puts ("");
12130 }
12131 }
12132 break;
12133
12134 case DT_FLAGS_1:
12135 if (do_dynamic)
12136 {
12137 printf (_("Flags:"));
12138 if (entry->d_un.d_val == 0)
12139 printf (_(" None\n"));
12140 else
12141 {
26c527e6 12142 uint64_t val = entry->d_un.d_val;
86f55779 12143
252b5132
RH
12144 if (val & DF_1_NOW)
12145 {
12146 printf (" NOW");
12147 val ^= DF_1_NOW;
12148 }
12149 if (val & DF_1_GLOBAL)
12150 {
12151 printf (" GLOBAL");
12152 val ^= DF_1_GLOBAL;
12153 }
12154 if (val & DF_1_GROUP)
12155 {
12156 printf (" GROUP");
12157 val ^= DF_1_GROUP;
12158 }
12159 if (val & DF_1_NODELETE)
12160 {
12161 printf (" NODELETE");
12162 val ^= DF_1_NODELETE;
12163 }
12164 if (val & DF_1_LOADFLTR)
12165 {
12166 printf (" LOADFLTR");
12167 val ^= DF_1_LOADFLTR;
12168 }
12169 if (val & DF_1_INITFIRST)
12170 {
12171 printf (" INITFIRST");
12172 val ^= DF_1_INITFIRST;
12173 }
12174 if (val & DF_1_NOOPEN)
12175 {
12176 printf (" NOOPEN");
12177 val ^= DF_1_NOOPEN;
12178 }
12179 if (val & DF_1_ORIGIN)
12180 {
12181 printf (" ORIGIN");
12182 val ^= DF_1_ORIGIN;
12183 }
12184 if (val & DF_1_DIRECT)
12185 {
12186 printf (" DIRECT");
12187 val ^= DF_1_DIRECT;
12188 }
12189 if (val & DF_1_TRANS)
12190 {
12191 printf (" TRANS");
12192 val ^= DF_1_TRANS;
12193 }
12194 if (val & DF_1_INTERPOSE)
12195 {
12196 printf (" INTERPOSE");
12197 val ^= DF_1_INTERPOSE;
12198 }
f7db6139 12199 if (val & DF_1_NODEFLIB)
dcefbbbd 12200 {
f7db6139
L
12201 printf (" NODEFLIB");
12202 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12203 }
12204 if (val & DF_1_NODUMP)
12205 {
12206 printf (" NODUMP");
12207 val ^= DF_1_NODUMP;
12208 }
34b60028 12209 if (val & DF_1_CONFALT)
dcefbbbd 12210 {
34b60028
L
12211 printf (" CONFALT");
12212 val ^= DF_1_CONFALT;
12213 }
12214 if (val & DF_1_ENDFILTEE)
12215 {
12216 printf (" ENDFILTEE");
12217 val ^= DF_1_ENDFILTEE;
12218 }
12219 if (val & DF_1_DISPRELDNE)
12220 {
12221 printf (" DISPRELDNE");
12222 val ^= DF_1_DISPRELDNE;
12223 }
12224 if (val & DF_1_DISPRELPND)
12225 {
12226 printf (" DISPRELPND");
12227 val ^= DF_1_DISPRELPND;
12228 }
12229 if (val & DF_1_NODIRECT)
12230 {
12231 printf (" NODIRECT");
12232 val ^= DF_1_NODIRECT;
12233 }
12234 if (val & DF_1_IGNMULDEF)
12235 {
12236 printf (" IGNMULDEF");
12237 val ^= DF_1_IGNMULDEF;
12238 }
12239 if (val & DF_1_NOKSYMS)
12240 {
12241 printf (" NOKSYMS");
12242 val ^= DF_1_NOKSYMS;
12243 }
12244 if (val & DF_1_NOHDR)
12245 {
12246 printf (" NOHDR");
12247 val ^= DF_1_NOHDR;
12248 }
12249 if (val & DF_1_EDITED)
12250 {
12251 printf (" EDITED");
12252 val ^= DF_1_EDITED;
12253 }
12254 if (val & DF_1_NORELOC)
12255 {
12256 printf (" NORELOC");
12257 val ^= DF_1_NORELOC;
12258 }
12259 if (val & DF_1_SYMINTPOSE)
12260 {
12261 printf (" SYMINTPOSE");
12262 val ^= DF_1_SYMINTPOSE;
12263 }
12264 if (val & DF_1_GLOBAUDIT)
12265 {
12266 printf (" GLOBAUDIT");
12267 val ^= DF_1_GLOBAUDIT;
12268 }
12269 if (val & DF_1_SINGLETON)
12270 {
12271 printf (" SINGLETON");
12272 val ^= DF_1_SINGLETON;
dcefbbbd 12273 }
5c383f02
RO
12274 if (val & DF_1_STUB)
12275 {
12276 printf (" STUB");
12277 val ^= DF_1_STUB;
12278 }
12279 if (val & DF_1_PIE)
12280 {
12281 printf (" PIE");
12282 val ^= DF_1_PIE;
12283 }
b1202ffa
L
12284 if (val & DF_1_KMOD)
12285 {
12286 printf (" KMOD");
12287 val ^= DF_1_KMOD;
12288 }
12289 if (val & DF_1_WEAKFILTER)
12290 {
12291 printf (" WEAKFILTER");
12292 val ^= DF_1_WEAKFILTER;
12293 }
12294 if (val & DF_1_NOCOMMON)
12295 {
12296 printf (" NOCOMMON");
12297 val ^= DF_1_NOCOMMON;
12298 }
252b5132 12299 if (val != 0)
26c527e6 12300 printf (" %" PRIx64, val);
252b5132
RH
12301 puts ("");
12302 }
12303 }
12304 break;
12305
12306 case DT_PLTREL:
978c4450 12307 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12308 if (do_dynamic)
dda8d76d 12309 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12310 break;
12311
12312 case DT_NULL :
12313 case DT_NEEDED :
12314 case DT_PLTGOT :
12315 case DT_HASH :
12316 case DT_STRTAB :
12317 case DT_SYMTAB :
12318 case DT_RELA :
12319 case DT_INIT :
12320 case DT_FINI :
12321 case DT_SONAME :
12322 case DT_RPATH :
12323 case DT_SYMBOLIC:
12324 case DT_REL :
a7fd1186 12325 case DT_RELR :
252b5132
RH
12326 case DT_DEBUG :
12327 case DT_TEXTREL :
12328 case DT_JMPREL :
019148e4 12329 case DT_RUNPATH :
978c4450 12330 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12331
12332 if (do_dynamic)
12333 {
84714f86 12334 const char *name;
252b5132 12335
84714f86
AM
12336 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12337 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12338 else
d79b3d50 12339 name = NULL;
252b5132
RH
12340
12341 if (name)
12342 {
12343 switch (entry->d_tag)
12344 {
12345 case DT_NEEDED:
12346 printf (_("Shared library: [%s]"), name);
12347
13acb58d
AM
12348 if (filedata->program_interpreter
12349 && streq (name, filedata->program_interpreter))
f7a99963 12350 printf (_(" program interpreter"));
252b5132
RH
12351 break;
12352
12353 case DT_SONAME:
f7a99963 12354 printf (_("Library soname: [%s]"), name);
252b5132
RH
12355 break;
12356
12357 case DT_RPATH:
f7a99963 12358 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12359 break;
12360
019148e4
L
12361 case DT_RUNPATH:
12362 printf (_("Library runpath: [%s]"), name);
12363 break;
12364
252b5132 12365 default:
f7a99963
NC
12366 print_vma (entry->d_un.d_val, PREFIX_HEX);
12367 break;
252b5132
RH
12368 }
12369 }
12370 else
f7a99963
NC
12371 print_vma (entry->d_un.d_val, PREFIX_HEX);
12372
12373 putchar ('\n');
252b5132
RH
12374 }
12375 break;
12376
12377 case DT_PLTRELSZ:
12378 case DT_RELASZ :
12379 case DT_STRSZ :
12380 case DT_RELSZ :
12381 case DT_RELAENT :
a7fd1186
FS
12382 case DT_RELRENT :
12383 case DT_RELRSZ :
252b5132
RH
12384 case DT_SYMENT :
12385 case DT_RELENT :
978c4450 12386 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12387 /* Fall through. */
252b5132
RH
12388 case DT_PLTPADSZ:
12389 case DT_MOVEENT :
12390 case DT_MOVESZ :
04d8355a 12391 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12392 case DT_INIT_ARRAYSZ:
12393 case DT_FINI_ARRAYSZ:
047b2264
JJ
12394 case DT_GNU_CONFLICTSZ:
12395 case DT_GNU_LIBLISTSZ:
252b5132 12396 if (do_dynamic)
f7a99963
NC
12397 {
12398 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12399 printf (_(" (bytes)\n"));
f7a99963 12400 }
252b5132
RH
12401 break;
12402
12403 case DT_VERDEFNUM:
12404 case DT_VERNEEDNUM:
12405 case DT_RELACOUNT:
12406 case DT_RELCOUNT:
12407 if (do_dynamic)
f7a99963
NC
12408 {
12409 print_vma (entry->d_un.d_val, UNSIGNED);
12410 putchar ('\n');
12411 }
252b5132
RH
12412 break;
12413
12414 case DT_SYMINSZ:
12415 case DT_SYMINENT:
12416 case DT_SYMINFO:
12417 case DT_USED:
12418 case DT_INIT_ARRAY:
12419 case DT_FINI_ARRAY:
12420 if (do_dynamic)
12421 {
d79b3d50 12422 if (entry->d_tag == DT_USED
84714f86 12423 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12424 {
84714f86
AM
12425 const char *name
12426 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12427
b34976b6 12428 if (*name)
252b5132
RH
12429 {
12430 printf (_("Not needed object: [%s]\n"), name);
12431 break;
12432 }
12433 }
103f02d3 12434
f7a99963
NC
12435 print_vma (entry->d_un.d_val, PREFIX_HEX);
12436 putchar ('\n');
252b5132
RH
12437 }
12438 break;
12439
12440 case DT_BIND_NOW:
12441 /* The value of this entry is ignored. */
35b1837e
AM
12442 if (do_dynamic)
12443 putchar ('\n');
252b5132 12444 break;
103f02d3 12445
047b2264
JJ
12446 case DT_GNU_PRELINKED:
12447 if (do_dynamic)
12448 {
2cf0635d 12449 struct tm * tmp;
91d6fa6a 12450 time_t atime = entry->d_un.d_val;
047b2264 12451
91d6fa6a 12452 tmp = gmtime (&atime);
071436c6
NC
12453 /* PR 17533 file: 041-1244816-0.004. */
12454 if (tmp == NULL)
26c527e6
AM
12455 printf (_("<corrupt time val: %" PRIx64),
12456 (uint64_t) atime);
071436c6
NC
12457 else
12458 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12459 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12460 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12461
12462 }
12463 break;
12464
fdc90cb4 12465 case DT_GNU_HASH:
978c4450 12466 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12467 if (do_dynamic)
12468 {
12469 print_vma (entry->d_un.d_val, PREFIX_HEX);
12470 putchar ('\n');
12471 }
12472 break;
12473
a5da3dee
VDM
12474 case DT_GNU_FLAGS_1:
12475 if (do_dynamic)
12476 {
12477 printf (_("Flags:"));
12478 if (entry->d_un.d_val == 0)
12479 printf (_(" None\n"));
12480 else
12481 {
26c527e6 12482 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12483
12484 if (val & DF_GNU_1_UNIQUE)
12485 {
12486 printf (" UNIQUE");
12487 val ^= DF_GNU_1_UNIQUE;
12488 }
12489 if (val != 0)
26c527e6 12490 printf (" %" PRIx64, val);
a5da3dee
VDM
12491 puts ("");
12492 }
12493 }
12494 break;
12495
252b5132
RH
12496 default:
12497 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12498 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12499 = entry->d_un.d_val;
252b5132
RH
12500
12501 if (do_dynamic)
12502 {
dda8d76d 12503 switch (filedata->file_header.e_machine)
252b5132 12504 {
37c18eed
SD
12505 case EM_AARCH64:
12506 dynamic_section_aarch64_val (entry);
12507 break;
252b5132 12508 case EM_MIPS:
4fe85591 12509 case EM_MIPS_RS3_LE:
978c4450 12510 dynamic_section_mips_val (filedata, entry);
252b5132 12511 break;
103f02d3 12512 case EM_PARISC:
b2d38a17 12513 dynamic_section_parisc_val (entry);
103f02d3 12514 break;
ecc51f48 12515 case EM_IA_64:
b2d38a17 12516 dynamic_section_ia64_val (entry);
ecc51f48 12517 break;
252b5132 12518 default:
f7a99963
NC
12519 print_vma (entry->d_un.d_val, PREFIX_HEX);
12520 putchar ('\n');
252b5132
RH
12521 }
12522 }
12523 break;
12524 }
12525 }
12526
015dc7e1 12527 return true;
252b5132
RH
12528}
12529
12530static char *
d3ba0551 12531get_ver_flags (unsigned int flags)
252b5132 12532{
6d4f21f6 12533 static char buff[128];
252b5132
RH
12534
12535 buff[0] = 0;
12536
12537 if (flags == 0)
12538 return _("none");
12539
12540 if (flags & VER_FLG_BASE)
7bb1ad17 12541 strcat (buff, "BASE");
252b5132
RH
12542
12543 if (flags & VER_FLG_WEAK)
12544 {
12545 if (flags & VER_FLG_BASE)
7bb1ad17 12546 strcat (buff, " | ");
252b5132 12547
7bb1ad17 12548 strcat (buff, "WEAK");
252b5132
RH
12549 }
12550
44ec90b9
RO
12551 if (flags & VER_FLG_INFO)
12552 {
12553 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12554 strcat (buff, " | ");
44ec90b9 12555
7bb1ad17 12556 strcat (buff, "INFO");
44ec90b9
RO
12557 }
12558
12559 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12560 {
12561 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12562 strcat (buff, " | ");
12563
12564 strcat (buff, _("<unknown>"));
12565 }
252b5132
RH
12566
12567 return buff;
12568}
12569
12570/* Display the contents of the version sections. */
98fb390a 12571
015dc7e1 12572static bool
dda8d76d 12573process_version_sections (Filedata * filedata)
252b5132 12574{
2cf0635d 12575 Elf_Internal_Shdr * section;
b34976b6 12576 unsigned i;
015dc7e1 12577 bool found = false;
252b5132
RH
12578
12579 if (! do_version)
015dc7e1 12580 return true;
252b5132 12581
dda8d76d
NC
12582 for (i = 0, section = filedata->section_headers;
12583 i < filedata->file_header.e_shnum;
b34976b6 12584 i++, section++)
252b5132
RH
12585 {
12586 switch (section->sh_type)
12587 {
12588 case SHT_GNU_verdef:
12589 {
2cf0635d 12590 Elf_External_Verdef * edefs;
26c527e6
AM
12591 size_t idx;
12592 size_t cnt;
2cf0635d 12593 char * endbuf;
252b5132 12594
015dc7e1 12595 found = true;
252b5132 12596
ca0e11aa
NC
12597 if (filedata->is_separate)
12598 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12599 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12600 section->sh_info),
12601 filedata->file_name,
12602 printable_section_name (filedata, section),
12603 section->sh_info);
12604 else
12605 printf (ngettext ("\nVersion definition section '%s' "
12606 "contains %u entry:\n",
12607 "\nVersion definition section '%s' "
12608 "contains %u entries:\n",
12609 section->sh_info),
12610 printable_section_name (filedata, section),
12611 section->sh_info);
047c3dbf 12612
625d49fc 12613 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12614 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12615 section->sh_offset, section->sh_link,
b6ac461a 12616 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12617
3f5e193b 12618 edefs = (Elf_External_Verdef *)
dda8d76d 12619 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12620 _("version definition section"));
a6e9f9df
AM
12621 if (!edefs)
12622 break;
59245841 12623 endbuf = (char *) edefs + section->sh_size;
252b5132 12624
1445030f 12625 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12626 {
2cf0635d
NC
12627 char * vstart;
12628 Elf_External_Verdef * edef;
b34976b6 12629 Elf_Internal_Verdef ent;
2cf0635d 12630 Elf_External_Verdaux * eaux;
b34976b6 12631 Elf_Internal_Verdaux aux;
26c527e6 12632 size_t isum;
b34976b6 12633 int j;
103f02d3 12634
252b5132 12635 vstart = ((char *) edefs) + idx;
54806181
AM
12636 if (vstart + sizeof (*edef) > endbuf)
12637 break;
252b5132
RH
12638
12639 edef = (Elf_External_Verdef *) vstart;
12640
12641 ent.vd_version = BYTE_GET (edef->vd_version);
12642 ent.vd_flags = BYTE_GET (edef->vd_flags);
12643 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12644 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12645 ent.vd_hash = BYTE_GET (edef->vd_hash);
12646 ent.vd_aux = BYTE_GET (edef->vd_aux);
12647 ent.vd_next = BYTE_GET (edef->vd_next);
12648
26c527e6 12649 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12650 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12651
12652 printf (_(" Index: %d Cnt: %d "),
12653 ent.vd_ndx, ent.vd_cnt);
12654
452bf675 12655 /* Check for overflow. */
1445030f 12656 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12657 break;
12658
252b5132
RH
12659 vstart += ent.vd_aux;
12660
1445030f
AM
12661 if (vstart + sizeof (*eaux) > endbuf)
12662 break;
252b5132
RH
12663 eaux = (Elf_External_Verdaux *) vstart;
12664
12665 aux.vda_name = BYTE_GET (eaux->vda_name);
12666 aux.vda_next = BYTE_GET (eaux->vda_next);
12667
84714f86 12668 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12669 printf (_("Name: %s\n"),
84714f86 12670 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12671 else
12672 printf (_("Name index: %ld\n"), aux.vda_name);
12673
12674 isum = idx + ent.vd_aux;
12675
b34976b6 12676 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12677 {
1445030f
AM
12678 if (aux.vda_next < sizeof (*eaux)
12679 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12680 {
12681 warn (_("Invalid vda_next field of %lx\n"),
12682 aux.vda_next);
12683 j = ent.vd_cnt;
12684 break;
12685 }
dd24e3da 12686 /* Check for overflow. */
7e26601c 12687 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12688 break;
12689
252b5132
RH
12690 isum += aux.vda_next;
12691 vstart += aux.vda_next;
12692
54806181
AM
12693 if (vstart + sizeof (*eaux) > endbuf)
12694 break;
1445030f 12695 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12696
12697 aux.vda_name = BYTE_GET (eaux->vda_name);
12698 aux.vda_next = BYTE_GET (eaux->vda_next);
12699
84714f86 12700 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12701 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12702 isum, j,
84714f86 12703 get_dynamic_name (filedata, aux.vda_name));
252b5132 12704 else
26c527e6 12705 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12706 isum, j, aux.vda_name);
12707 }
dd24e3da 12708
54806181
AM
12709 if (j < ent.vd_cnt)
12710 printf (_(" Version def aux past end of section\n"));
252b5132 12711
c9f02c3e
MR
12712 /* PR 17531:
12713 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12714 if (ent.vd_next < sizeof (*edef)
12715 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12716 {
12717 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12718 cnt = section->sh_info;
12719 break;
12720 }
452bf675 12721 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12722 break;
12723
252b5132
RH
12724 idx += ent.vd_next;
12725 }
dd24e3da 12726
54806181
AM
12727 if (cnt < section->sh_info)
12728 printf (_(" Version definition past end of section\n"));
252b5132
RH
12729
12730 free (edefs);
12731 }
12732 break;
103f02d3 12733
252b5132
RH
12734 case SHT_GNU_verneed:
12735 {
2cf0635d 12736 Elf_External_Verneed * eneed;
26c527e6
AM
12737 size_t idx;
12738 size_t cnt;
2cf0635d 12739 char * endbuf;
252b5132 12740
015dc7e1 12741 found = true;
252b5132 12742
ca0e11aa
NC
12743 if (filedata->is_separate)
12744 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12745 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12746 section->sh_info),
12747 filedata->file_name,
12748 printable_section_name (filedata, section),
12749 section->sh_info);
12750 else
12751 printf (ngettext ("\nVersion needs section '%s' "
12752 "contains %u entry:\n",
12753 "\nVersion needs section '%s' "
12754 "contains %u entries:\n",
12755 section->sh_info),
12756 printable_section_name (filedata, section),
12757 section->sh_info);
047c3dbf 12758
625d49fc 12759 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12760 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12761 section->sh_offset, section->sh_link,
b6ac461a 12762 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12763
dda8d76d 12764 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12765 section->sh_offset, 1,
12766 section->sh_size,
9cf03b7e 12767 _("Version Needs section"));
a6e9f9df
AM
12768 if (!eneed)
12769 break;
59245841 12770 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12771
12772 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12773 {
2cf0635d 12774 Elf_External_Verneed * entry;
b34976b6 12775 Elf_Internal_Verneed ent;
26c527e6 12776 size_t isum;
b34976b6 12777 int j;
2cf0635d 12778 char * vstart;
252b5132
RH
12779
12780 vstart = ((char *) eneed) + idx;
54806181
AM
12781 if (vstart + sizeof (*entry) > endbuf)
12782 break;
252b5132
RH
12783
12784 entry = (Elf_External_Verneed *) vstart;
12785
12786 ent.vn_version = BYTE_GET (entry->vn_version);
12787 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12788 ent.vn_file = BYTE_GET (entry->vn_file);
12789 ent.vn_aux = BYTE_GET (entry->vn_aux);
12790 ent.vn_next = BYTE_GET (entry->vn_next);
12791
26c527e6 12792 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12793
84714f86 12794 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12795 printf (_(" File: %s"),
84714f86 12796 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12797 else
12798 printf (_(" File: %lx"), ent.vn_file);
12799
12800 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12801
dd24e3da 12802 /* Check for overflow. */
7e26601c 12803 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12804 break;
252b5132
RH
12805 vstart += ent.vn_aux;
12806
12807 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12808 {
2cf0635d 12809 Elf_External_Vernaux * eaux;
b34976b6 12810 Elf_Internal_Vernaux aux;
252b5132 12811
54806181
AM
12812 if (vstart + sizeof (*eaux) > endbuf)
12813 break;
252b5132
RH
12814 eaux = (Elf_External_Vernaux *) vstart;
12815
12816 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12817 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12818 aux.vna_other = BYTE_GET (eaux->vna_other);
12819 aux.vna_name = BYTE_GET (eaux->vna_name);
12820 aux.vna_next = BYTE_GET (eaux->vna_next);
12821
84714f86 12822 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 12823 printf (_(" %#06zx: Name: %s"),
84714f86 12824 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12825 else
26c527e6 12826 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
12827 isum, aux.vna_name);
12828
12829 printf (_(" Flags: %s Version: %d\n"),
12830 get_ver_flags (aux.vna_flags), aux.vna_other);
12831
1445030f
AM
12832 if (aux.vna_next < sizeof (*eaux)
12833 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12834 {
12835 warn (_("Invalid vna_next field of %lx\n"),
12836 aux.vna_next);
12837 j = ent.vn_cnt;
12838 break;
12839 }
1445030f
AM
12840 /* Check for overflow. */
12841 if (aux.vna_next > (size_t) (endbuf - vstart))
12842 break;
252b5132
RH
12843 isum += aux.vna_next;
12844 vstart += aux.vna_next;
12845 }
9cf03b7e 12846
54806181 12847 if (j < ent.vn_cnt)
f9a6a8f0 12848 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12849
1445030f
AM
12850 if (ent.vn_next < sizeof (*entry)
12851 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12852 {
452bf675 12853 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12854 cnt = section->sh_info;
12855 break;
12856 }
1445030f
AM
12857 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12858 break;
252b5132
RH
12859 idx += ent.vn_next;
12860 }
9cf03b7e 12861
54806181 12862 if (cnt < section->sh_info)
9cf03b7e 12863 warn (_("Missing Version Needs information\n"));
103f02d3 12864
252b5132
RH
12865 free (eneed);
12866 }
12867 break;
12868
12869 case SHT_GNU_versym:
12870 {
2cf0635d 12871 Elf_Internal_Shdr * link_section;
26c527e6 12872 uint64_t total;
8b73c356 12873 unsigned int cnt;
2cf0635d
NC
12874 unsigned char * edata;
12875 unsigned short * data;
12876 char * strtab;
12877 Elf_Internal_Sym * symbols;
12878 Elf_Internal_Shdr * string_sec;
26c527e6
AM
12879 uint64_t num_syms;
12880 uint64_t off;
252b5132 12881
dda8d76d 12882 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12883 break;
12884
dda8d76d 12885 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12886 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12887
dda8d76d 12888 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12889 break;
12890
015dc7e1 12891 found = true;
252b5132 12892
4de91c10 12893 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12894 if (symbols == NULL)
12895 break;
252b5132 12896
dda8d76d 12897 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12898
dda8d76d 12899 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12900 string_sec->sh_size,
12901 _("version string table"));
a6e9f9df 12902 if (!strtab)
0429c154
MS
12903 {
12904 free (symbols);
12905 break;
12906 }
252b5132 12907
ca0e11aa 12908 if (filedata->is_separate)
26c527e6
AM
12909 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
12910 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12911 total),
12912 filedata->file_name,
12913 printable_section_name (filedata, section),
26c527e6 12914 total);
ca0e11aa
NC
12915 else
12916 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 12917 "contains %" PRIu64 " entry:\n",
ca0e11aa 12918 "\nVersion symbols section '%s' "
26c527e6 12919 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
12920 total),
12921 printable_section_name (filedata, section),
26c527e6 12922 total);
252b5132 12923
625d49fc 12924 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12925 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12926 section->sh_offset, section->sh_link,
dda8d76d 12927 printable_section_name (filedata, link_section));
252b5132 12928
dda8d76d 12929 off = offset_from_vma (filedata,
978c4450 12930 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12931 total * sizeof (short));
95099889
AM
12932 edata = (unsigned char *) get_data (NULL, filedata, off,
12933 sizeof (short), total,
12934 _("version symbol data"));
a6e9f9df
AM
12935 if (!edata)
12936 {
12937 free (strtab);
0429c154 12938 free (symbols);
a6e9f9df
AM
12939 break;
12940 }
252b5132 12941
3f5e193b 12942 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12943
12944 for (cnt = total; cnt --;)
b34976b6
AM
12945 data[cnt] = byte_get (edata + cnt * sizeof (short),
12946 sizeof (short));
252b5132
RH
12947
12948 free (edata);
12949
12950 for (cnt = 0; cnt < total; cnt += 4)
12951 {
12952 int j, nn;
ab273396
AM
12953 char *name;
12954 char *invalid = _("*invalid*");
252b5132
RH
12955
12956 printf (" %03x:", cnt);
12957
12958 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12959 switch (data[cnt + j])
252b5132
RH
12960 {
12961 case 0:
12962 fputs (_(" 0 (*local*) "), stdout);
12963 break;
12964
12965 case 1:
12966 fputs (_(" 1 (*global*) "), stdout);
12967 break;
12968
12969 default:
c244d050
NC
12970 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12971 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12972
dd24e3da 12973 /* If this index value is greater than the size of the symbols
ba5cdace 12974 array, break to avoid an out-of-bounds read. */
26c527e6 12975 if (cnt + j >= num_syms)
dd24e3da
NC
12976 {
12977 warn (_("invalid index into symbol array\n"));
12978 break;
12979 }
12980
ab273396 12981 name = NULL;
978c4450 12982 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12983 {
b34976b6 12984 Elf_Internal_Verneed ivn;
26c527e6 12985 uint64_t offset;
252b5132 12986
d93f0186 12987 offset = offset_from_vma
978c4450
AM
12988 (filedata,
12989 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12990 sizeof (Elf_External_Verneed));
252b5132 12991
b34976b6 12992 do
252b5132 12993 {
b34976b6
AM
12994 Elf_Internal_Vernaux ivna;
12995 Elf_External_Verneed evn;
12996 Elf_External_Vernaux evna;
26c527e6 12997 uint64_t a_off;
252b5132 12998
dda8d76d 12999 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13000 _("version need")) == NULL)
13001 break;
0b4362b0 13002
252b5132
RH
13003 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13004 ivn.vn_next = BYTE_GET (evn.vn_next);
13005
13006 a_off = offset + ivn.vn_aux;
13007
13008 do
13009 {
dda8d76d 13010 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13011 1, _("version need aux (2)")) == NULL)
13012 {
13013 ivna.vna_next = 0;
13014 ivna.vna_other = 0;
13015 }
13016 else
13017 {
13018 ivna.vna_next = BYTE_GET (evna.vna_next);
13019 ivna.vna_other = BYTE_GET (evna.vna_other);
13020 }
252b5132
RH
13021
13022 a_off += ivna.vna_next;
13023 }
b34976b6 13024 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13025 && ivna.vna_next != 0);
13026
b34976b6 13027 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13028 {
13029 ivna.vna_name = BYTE_GET (evna.vna_name);
13030
54806181 13031 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13032 name = invalid;
54806181
AM
13033 else
13034 name = strtab + ivna.vna_name;
252b5132
RH
13035 break;
13036 }
13037
13038 offset += ivn.vn_next;
13039 }
13040 while (ivn.vn_next);
13041 }
00d93f34 13042
ab273396 13043 if (data[cnt + j] != 0x8001
978c4450 13044 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13045 {
b34976b6
AM
13046 Elf_Internal_Verdef ivd;
13047 Elf_External_Verdef evd;
26c527e6 13048 uint64_t offset;
252b5132 13049
d93f0186 13050 offset = offset_from_vma
978c4450
AM
13051 (filedata,
13052 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13053 sizeof evd);
252b5132
RH
13054
13055 do
13056 {
dda8d76d 13057 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13058 _("version def")) == NULL)
13059 {
13060 ivd.vd_next = 0;
948f632f 13061 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13062 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13063 break;
59245841
NC
13064 }
13065 else
13066 {
13067 ivd.vd_next = BYTE_GET (evd.vd_next);
13068 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13069 }
252b5132
RH
13070
13071 offset += ivd.vd_next;
13072 }
c244d050 13073 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13074 && ivd.vd_next != 0);
13075
c244d050 13076 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13077 {
b34976b6
AM
13078 Elf_External_Verdaux evda;
13079 Elf_Internal_Verdaux ivda;
252b5132
RH
13080
13081 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13082
dda8d76d 13083 if (get_data (&evda, filedata,
59245841
NC
13084 offset - ivd.vd_next + ivd.vd_aux,
13085 sizeof (evda), 1,
13086 _("version def aux")) == NULL)
13087 break;
252b5132
RH
13088
13089 ivda.vda_name = BYTE_GET (evda.vda_name);
13090
54806181 13091 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13092 name = invalid;
13093 else if (name != NULL && name != invalid)
13094 name = _("*both*");
54806181
AM
13095 else
13096 name = strtab + ivda.vda_name;
252b5132
RH
13097 }
13098 }
ab273396
AM
13099 if (name != NULL)
13100 nn += printf ("(%s%-*s",
13101 name,
13102 12 - (int) strlen (name),
13103 ")");
252b5132
RH
13104
13105 if (nn < 18)
13106 printf ("%*c", 18 - nn, ' ');
13107 }
13108
13109 putchar ('\n');
13110 }
13111
13112 free (data);
13113 free (strtab);
13114 free (symbols);
13115 }
13116 break;
103f02d3 13117
252b5132
RH
13118 default:
13119 break;
13120 }
13121 }
13122
13123 if (! found)
ca0e11aa
NC
13124 {
13125 if (filedata->is_separate)
13126 printf (_("\nNo version information found in linked file '%s'.\n"),
13127 filedata->file_name);
13128 else
13129 printf (_("\nNo version information found in this file.\n"));
13130 }
252b5132 13131
015dc7e1 13132 return true;
252b5132
RH
13133}
13134
d1133906 13135static const char *
dda8d76d 13136get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13137{
89246a0e 13138 static char buff[64];
252b5132
RH
13139
13140 switch (binding)
13141 {
b34976b6
AM
13142 case STB_LOCAL: return "LOCAL";
13143 case STB_GLOBAL: return "GLOBAL";
13144 case STB_WEAK: return "WEAK";
252b5132
RH
13145 default:
13146 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13147 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13148 binding);
252b5132 13149 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13150 {
13151 if (binding == STB_GNU_UNIQUE
df3a023b 13152 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13153 return "UNIQUE";
13154 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13155 }
252b5132 13156 else
e9e44622 13157 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13158 return buff;
13159 }
13160}
13161
d1133906 13162static const char *
dda8d76d 13163get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13164{
89246a0e 13165 static char buff[64];
252b5132
RH
13166
13167 switch (type)
13168 {
b34976b6
AM
13169 case STT_NOTYPE: return "NOTYPE";
13170 case STT_OBJECT: return "OBJECT";
13171 case STT_FUNC: return "FUNC";
13172 case STT_SECTION: return "SECTION";
13173 case STT_FILE: return "FILE";
13174 case STT_COMMON: return "COMMON";
13175 case STT_TLS: return "TLS";
15ab5209
DB
13176 case STT_RELC: return "RELC";
13177 case STT_SRELC: return "SRELC";
252b5132
RH
13178 default:
13179 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13180 {
dda8d76d 13181 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13182 return "THUMB_FUNC";
103f02d3 13183
dda8d76d 13184 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13185 return "REGISTER";
13186
dda8d76d 13187 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13188 return "PARISC_MILLI";
13189
e9e44622 13190 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13191 }
252b5132 13192 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13193 {
dda8d76d 13194 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13195 {
13196 if (type == STT_HP_OPAQUE)
13197 return "HP_OPAQUE";
13198 if (type == STT_HP_STUB)
13199 return "HP_STUB";
13200 }
13201
8654c01f
ML
13202 if (type == STT_GNU_IFUNC
13203 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13204 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13205 return "IFUNC";
13206
e9e44622 13207 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13208 }
252b5132 13209 else
e9e44622 13210 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13211 return buff;
13212 }
13213}
13214
d1133906 13215static const char *
d3ba0551 13216get_symbol_visibility (unsigned int visibility)
d1133906
NC
13217{
13218 switch (visibility)
13219 {
b34976b6
AM
13220 case STV_DEFAULT: return "DEFAULT";
13221 case STV_INTERNAL: return "INTERNAL";
13222 case STV_HIDDEN: return "HIDDEN";
d1133906 13223 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13224 default:
27a45f42 13225 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13226 return _("<unknown>");
d1133906
NC
13227 }
13228}
13229
2057d69d
CZ
13230static const char *
13231get_alpha_symbol_other (unsigned int other)
9abca702 13232{
2057d69d
CZ
13233 switch (other)
13234 {
13235 case STO_ALPHA_NOPV: return "NOPV";
13236 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13237 default:
27a45f42 13238 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13239 return _("<unknown>");
9abca702 13240 }
2057d69d
CZ
13241}
13242
fd85a6a1
NC
13243static const char *
13244get_solaris_symbol_visibility (unsigned int visibility)
13245{
13246 switch (visibility)
13247 {
13248 case 4: return "EXPORTED";
13249 case 5: return "SINGLETON";
13250 case 6: return "ELIMINATE";
13251 default: return get_symbol_visibility (visibility);
13252 }
13253}
13254
2301ed1c
SN
13255static const char *
13256get_aarch64_symbol_other (unsigned int other)
13257{
13258 static char buf[32];
13259
13260 if (other & STO_AARCH64_VARIANT_PCS)
13261 {
13262 other &= ~STO_AARCH64_VARIANT_PCS;
13263 if (other == 0)
13264 return "VARIANT_PCS";
13265 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13266 return buf;
13267 }
13268 return NULL;
13269}
13270
5e2b0d47
NC
13271static const char *
13272get_mips_symbol_other (unsigned int other)
13273{
13274 switch (other)
13275 {
32ec8896
NC
13276 case STO_OPTIONAL: return "OPTIONAL";
13277 case STO_MIPS_PLT: return "MIPS PLT";
13278 case STO_MIPS_PIC: return "MIPS PIC";
13279 case STO_MICROMIPS: return "MICROMIPS";
13280 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13281 case STO_MIPS16: return "MIPS16";
13282 default: return NULL;
5e2b0d47
NC
13283 }
13284}
13285
28f997cf 13286static const char *
dda8d76d 13287get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13288{
dda8d76d 13289 if (is_ia64_vms (filedata))
28f997cf
TG
13290 {
13291 static char res[32];
13292
13293 res[0] = 0;
13294
13295 /* Function types is for images and .STB files only. */
dda8d76d 13296 switch (filedata->file_header.e_type)
28f997cf
TG
13297 {
13298 case ET_DYN:
13299 case ET_EXEC:
13300 switch (VMS_ST_FUNC_TYPE (other))
13301 {
13302 case VMS_SFT_CODE_ADDR:
13303 strcat (res, " CA");
13304 break;
13305 case VMS_SFT_SYMV_IDX:
13306 strcat (res, " VEC");
13307 break;
13308 case VMS_SFT_FD:
13309 strcat (res, " FD");
13310 break;
13311 case VMS_SFT_RESERVE:
13312 strcat (res, " RSV");
13313 break;
13314 default:
bee0ee85
NC
13315 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13316 VMS_ST_FUNC_TYPE (other));
13317 strcat (res, " <unknown>");
13318 break;
28f997cf
TG
13319 }
13320 break;
13321 default:
13322 break;
13323 }
13324 switch (VMS_ST_LINKAGE (other))
13325 {
13326 case VMS_STL_IGNORE:
13327 strcat (res, " IGN");
13328 break;
13329 case VMS_STL_RESERVE:
13330 strcat (res, " RSV");
13331 break;
13332 case VMS_STL_STD:
13333 strcat (res, " STD");
13334 break;
13335 case VMS_STL_LNK:
13336 strcat (res, " LNK");
13337 break;
13338 default:
bee0ee85
NC
13339 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13340 VMS_ST_LINKAGE (other));
13341 strcat (res, " <unknown>");
13342 break;
28f997cf
TG
13343 }
13344
13345 if (res[0] != 0)
13346 return res + 1;
13347 else
13348 return res;
13349 }
13350 return NULL;
13351}
13352
6911b7dc
AM
13353static const char *
13354get_ppc64_symbol_other (unsigned int other)
13355{
14732552
AM
13356 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13357 return NULL;
13358
13359 other >>= STO_PPC64_LOCAL_BIT;
13360 if (other <= 6)
6911b7dc 13361 {
89246a0e 13362 static char buf[64];
14732552
AM
13363 if (other >= 2)
13364 other = ppc64_decode_local_entry (other);
13365 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13366 return buf;
13367 }
13368 return NULL;
13369}
13370
8155b853
NC
13371static const char *
13372get_riscv_symbol_other (unsigned int other)
13373{
13374 static char buf[32];
13375 buf[0] = 0;
13376
13377 if (other & STO_RISCV_VARIANT_CC)
13378 {
13379 strcat (buf, _(" VARIANT_CC"));
13380 other &= ~STO_RISCV_VARIANT_CC;
13381 }
13382
13383 if (other != 0)
13384 snprintf (buf, sizeof buf, " %x", other);
13385
13386
13387 if (buf[0] != 0)
13388 return buf + 1;
13389 else
13390 return buf;
13391}
13392
5e2b0d47 13393static const char *
dda8d76d 13394get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13395{
13396 const char * result = NULL;
89246a0e 13397 static char buff [64];
5e2b0d47
NC
13398
13399 if (other == 0)
13400 return "";
13401
dda8d76d 13402 switch (filedata->file_header.e_machine)
5e2b0d47 13403 {
2057d69d
CZ
13404 case EM_ALPHA:
13405 result = get_alpha_symbol_other (other);
13406 break;
2301ed1c
SN
13407 case EM_AARCH64:
13408 result = get_aarch64_symbol_other (other);
13409 break;
5e2b0d47
NC
13410 case EM_MIPS:
13411 result = get_mips_symbol_other (other);
28f997cf
TG
13412 break;
13413 case EM_IA_64:
dda8d76d 13414 result = get_ia64_symbol_other (filedata, other);
28f997cf 13415 break;
6911b7dc
AM
13416 case EM_PPC64:
13417 result = get_ppc64_symbol_other (other);
13418 break;
8155b853
NC
13419 case EM_RISCV:
13420 result = get_riscv_symbol_other (other);
13421 break;
5e2b0d47 13422 default:
fd85a6a1 13423 result = NULL;
5e2b0d47
NC
13424 break;
13425 }
13426
13427 if (result)
13428 return result;
13429
13430 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13431 return buff;
13432}
13433
bb4d2ac2 13434static const char *
26c527e6
AM
13435get_symbol_version_string (Filedata *filedata,
13436 bool is_dynsym,
13437 const char *strtab,
13438 size_t strtab_size,
13439 unsigned int si,
13440 Elf_Internal_Sym *psym,
13441 enum versioned_symbol_info *sym_info,
13442 unsigned short *vna_other)
bb4d2ac2 13443{
ab273396
AM
13444 unsigned char data[2];
13445 unsigned short vers_data;
26c527e6 13446 uint64_t offset;
7a815dd5 13447 unsigned short max_vd_ndx;
bb4d2ac2 13448
ab273396 13449 if (!is_dynsym
978c4450 13450 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13451 return NULL;
bb4d2ac2 13452
978c4450
AM
13453 offset = offset_from_vma (filedata,
13454 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13455 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13456
dda8d76d 13457 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13458 sizeof (data), 1, _("version data")) == NULL)
13459 return NULL;
13460
13461 vers_data = byte_get (data, 2);
bb4d2ac2 13462
1f6f5dba 13463 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13464 return NULL;
bb4d2ac2 13465
0b8b7609 13466 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13467 max_vd_ndx = 0;
13468
ab273396
AM
13469 /* Usually we'd only see verdef for defined symbols, and verneed for
13470 undefined symbols. However, symbols defined by the linker in
13471 .dynbss for variables copied from a shared library in order to
13472 avoid text relocations are defined yet have verneed. We could
13473 use a heuristic to detect the special case, for example, check
13474 for verneed first on symbols defined in SHT_NOBITS sections, but
13475 it is simpler and more reliable to just look for both verdef and
13476 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13477
ab273396
AM
13478 if (psym->st_shndx != SHN_UNDEF
13479 && vers_data != 0x8001
978c4450 13480 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13481 {
13482 Elf_Internal_Verdef ivd;
13483 Elf_Internal_Verdaux ivda;
13484 Elf_External_Verdaux evda;
26c527e6 13485 uint64_t off;
bb4d2ac2 13486
dda8d76d 13487 off = offset_from_vma (filedata,
978c4450 13488 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13489 sizeof (Elf_External_Verdef));
13490
13491 do
bb4d2ac2 13492 {
ab273396
AM
13493 Elf_External_Verdef evd;
13494
dda8d76d 13495 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13496 _("version def")) == NULL)
13497 {
13498 ivd.vd_ndx = 0;
13499 ivd.vd_aux = 0;
13500 ivd.vd_next = 0;
1f6f5dba 13501 ivd.vd_flags = 0;
ab273396
AM
13502 }
13503 else
bb4d2ac2 13504 {
ab273396
AM
13505 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13506 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13507 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13508 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13509 }
bb4d2ac2 13510
7a815dd5
L
13511 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13512 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13513
ab273396
AM
13514 off += ivd.vd_next;
13515 }
13516 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13517
ab273396
AM
13518 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13519 {
9abca702 13520 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13521 return NULL;
13522
ab273396
AM
13523 off -= ivd.vd_next;
13524 off += ivd.vd_aux;
bb4d2ac2 13525
dda8d76d 13526 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13527 _("version def aux")) != NULL)
13528 {
13529 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13530
ab273396 13531 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13532 return (ivda.vda_name < strtab_size
13533 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13534 }
13535 }
13536 }
bb4d2ac2 13537
978c4450 13538 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13539 {
13540 Elf_External_Verneed evn;
13541 Elf_Internal_Verneed ivn;
13542 Elf_Internal_Vernaux ivna;
bb4d2ac2 13543
dda8d76d 13544 offset = offset_from_vma (filedata,
978c4450 13545 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13546 sizeof evn);
13547 do
13548 {
26c527e6 13549 uint64_t vna_off;
bb4d2ac2 13550
dda8d76d 13551 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13552 _("version need")) == NULL)
13553 {
13554 ivna.vna_next = 0;
13555 ivna.vna_other = 0;
13556 ivna.vna_name = 0;
13557 break;
13558 }
bb4d2ac2 13559
ab273396
AM
13560 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13561 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13562
ab273396 13563 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13564
ab273396
AM
13565 do
13566 {
13567 Elf_External_Vernaux evna;
bb4d2ac2 13568
dda8d76d 13569 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13570 _("version need aux (3)")) == NULL)
bb4d2ac2 13571 {
ab273396
AM
13572 ivna.vna_next = 0;
13573 ivna.vna_other = 0;
13574 ivna.vna_name = 0;
bb4d2ac2 13575 }
bb4d2ac2 13576 else
bb4d2ac2 13577 {
ab273396
AM
13578 ivna.vna_other = BYTE_GET (evna.vna_other);
13579 ivna.vna_next = BYTE_GET (evna.vna_next);
13580 ivna.vna_name = BYTE_GET (evna.vna_name);
13581 }
bb4d2ac2 13582
ab273396
AM
13583 vna_off += ivna.vna_next;
13584 }
13585 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13586
ab273396
AM
13587 if (ivna.vna_other == vers_data)
13588 break;
bb4d2ac2 13589
ab273396
AM
13590 offset += ivn.vn_next;
13591 }
13592 while (ivn.vn_next != 0);
bb4d2ac2 13593
ab273396
AM
13594 if (ivna.vna_other == vers_data)
13595 {
13596 *sym_info = symbol_undefined;
13597 *vna_other = ivna.vna_other;
13598 return (ivna.vna_name < strtab_size
13599 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13600 }
7a815dd5
L
13601 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13602 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13603 return _("<corrupt>");
bb4d2ac2 13604 }
ab273396 13605 return NULL;
bb4d2ac2
L
13606}
13607
047c3dbf
NL
13608/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13609
13610static unsigned int
b6ac461a 13611print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13612{
13613 switch (base)
13614 {
13615 case 8:
13616 return print_vma (vma, OCTAL_5);
13617
13618 case 10:
13619 return print_vma (vma, UNSIGNED_5);
13620
13621 case 16:
13622 return print_vma (vma, PREFIX_HEX_5);
13623
13624 case 0:
13625 default:
13626 return print_vma (vma, DEC_5);
13627 }
13628}
13629
b6ac461a
NC
13630/* Print information on a single symbol. */
13631
10ca4b04 13632static void
b6ac461a
NC
13633print_symbol (Filedata * filedata,
13634 uint64_t symbol_index,
13635 Elf_Internal_Sym * symtab,
13636 Elf_Internal_Shdr * section,
13637 char * strtab,
13638 size_t strtab_size)
252b5132 13639{
10ca4b04
L
13640 const char *version_string;
13641 enum versioned_symbol_info sym_info;
13642 unsigned short vna_other;
23356397 13643 const char * sstr;
b6ac461a 13644 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 13645
b6ac461a
NC
13646 /* FIXME: We should have a table of field widths,
13647 rather than using hard coded constants. */
13648 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
13649 print_vma (psym->st_value, LONG_HEX);
13650 putchar (' ');
b6ac461a 13651 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13652 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13653 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13654 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13655 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13656 else
252b5132 13657 {
10ca4b04 13658 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13659
10ca4b04 13660 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 13661
10ca4b04 13662 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
13663 FIXME: Displaying this information here disrupts the layout
13664 of the table being generated. */
10ca4b04
L
13665 if (psym->st_other ^ vis)
13666 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13667 }
0942c7ab 13668
b6ac461a
NC
13669 bool is_special;
13670
13671 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13672
13673 /* Print the symbol's section index. If the index is special
13674 then print the index's name rather than its number. */
13675 if (is_special)
13676 {
13677 int printed;
13678
13679 /* Special case: If there are no section headers, and the printable
13680 name is "<section 0x...." then just display the section number
13681 as a decimal. This happens when objcopy --strip -section-headers
13682 is used. */
13683 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13684 printed = printf (" %4d ", psym->st_shndx);
13685 else
13686 printed = printf (" %4s ", sstr);
13687
13688 if (extra_sym_info && printed < 16)
13689 printf ("%*s", 16 - printed, "");
13690 }
13691 else
13692 {
13693 printf (" %4u ", psym->st_shndx);
13694
13695 if (extra_sym_info)
13696 {
13697 /* Display the section name referenced by the section index. */
13698 int printed = printf ("(%s) ", sstr);
13699 if (printed < 10)
13700 printf ("%*s", 10 - printed, "");
13701 }
13702 }
13703
13704 /* Get the symbol's name. For section symbols without a
13705 specific name use the (already computed) section name. */
23356397 13706 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 13707 && section_index_real (filedata, psym->st_shndx)
23356397
NC
13708 && psym->st_name == 0)
13709 {
b6ac461a 13710 ;
23356397
NC
13711 }
13712 else
13713 {
b6ac461a
NC
13714 bool is_valid;
13715
84714f86 13716 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13717 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13718 }
10ca4b04
L
13719
13720 version_string
13721 = get_symbol_version_string (filedata,
13722 (section == NULL
13723 || section->sh_type == SHT_DYNSYM),
b6ac461a 13724 strtab, strtab_size, symbol_index,
10ca4b04 13725 psym, &sym_info, &vna_other);
b9e920ec 13726
0942c7ab
NC
13727 int len_avail = 21;
13728 if (! do_wide && version_string != NULL)
13729 {
ddb43bab 13730 char buffer[16];
0942c7ab 13731
ddb43bab 13732 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13733
13734 if (sym_info == symbol_undefined)
13735 len_avail -= sprintf (buffer," (%d)", vna_other);
13736 else if (sym_info != symbol_hidden)
13737 len_avail -= 1;
13738 }
13739
b6ac461a 13740 print_symbol_name (len_avail, sstr);
b9e920ec 13741
10ca4b04
L
13742 if (version_string)
13743 {
13744 if (sym_info == symbol_undefined)
13745 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13746 else
10ca4b04
L
13747 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13748 version_string);
13749 }
6bd1a22c 13750
10ca4b04 13751 putchar ('\n');
6bd1a22c 13752
10ca4b04
L
13753 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13754 && section != NULL
b6ac461a 13755 && symbol_index >= section->sh_info
10ca4b04
L
13756 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13757 && filedata->file_header.e_machine != EM_MIPS
13758 /* Solaris binaries have been found to violate this requirement as
13759 well. Not sure if this is a bug or an ABI requirement. */
13760 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13761 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 13762 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 13763}
f16a9783 13764
0f03783c
NC
13765static const char *
13766get_lto_kind (unsigned int kind)
13767{
13768 switch (kind)
13769 {
13770 case 0: return "DEF";
13771 case 1: return "WEAKDEF";
13772 case 2: return "UNDEF";
13773 case 3: return "WEAKUNDEF";
13774 case 4: return "COMMON";
13775 default:
13776 break;
13777 }
13778
13779 static char buffer[30];
13780 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13781 sprintf (buffer, "<unknown: %u>", kind);
13782 return buffer;
13783}
13784
13785static const char *
13786get_lto_visibility (unsigned int visibility)
13787{
13788 switch (visibility)
13789 {
13790 case 0: return "DEFAULT";
13791 case 1: return "PROTECTED";
13792 case 2: return "INTERNAL";
13793 case 3: return "HIDDEN";
13794 default:
13795 break;
13796 }
13797
13798 static char buffer[30];
13799 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13800 sprintf (buffer, "<unknown: %u>", visibility);
13801 return buffer;
13802}
13803
13804static const char *
13805get_lto_sym_type (unsigned int sym_type)
13806{
13807 switch (sym_type)
13808 {
13809 case 0: return "UNKNOWN";
13810 case 1: return "FUNCTION";
13811 case 2: return "VARIABLE";
13812 default:
13813 break;
13814 }
13815
13816 static char buffer[30];
13817 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13818 sprintf (buffer, "<unknown: %u>", sym_type);
13819 return buffer;
13820}
13821
13822/* Display an LTO format symbol table.
13823 FIXME: The format of LTO symbol tables is not formalized.
13824 So this code could need changing in the future. */
13825
015dc7e1 13826static bool
0f03783c
NC
13827display_lto_symtab (Filedata * filedata,
13828 Elf_Internal_Shdr * section)
13829{
13830 if (section->sh_size == 0)
13831 {
ca0e11aa
NC
13832 if (filedata->is_separate)
13833 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13834 printable_section_name (filedata, section),
13835 filedata->file_name);
13836 else
13837 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13838 printable_section_name (filedata, section));
047c3dbf 13839
015dc7e1 13840 return true;
0f03783c
NC
13841 }
13842
13843 if (section->sh_size > filedata->file_size)
13844 {
26c527e6 13845 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 13846 printable_section_name (filedata, section),
26c527e6 13847 section->sh_size);
015dc7e1 13848 return false;
0f03783c
NC
13849 }
13850
13851 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13852 section->sh_size, 1, _("LTO symbols"));
13853 if (alloced_data == NULL)
015dc7e1 13854 return false;
0f03783c
NC
13855
13856 /* Look for extended data for the symbol table. */
765a0c0a 13857 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
13858 void * ext_data_orig = NULL;
13859 char * ext_data = NULL;
13860 char * ext_data_end = NULL;
13861 char * ext_name = NULL;
13862
13863 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13864 (section_name (filedata, section)
13865 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13866 && ext_name != NULL /* Paranoia. */
13867 && (ext = find_section (filedata, ext_name)) != NULL)
13868 {
13869 if (ext->sh_size < 3)
13870 error (_("LTO Symbol extension table '%s' is empty!\n"),
13871 printable_section_name (filedata, ext));
13872 else
13873 {
13874 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13875 ext->sh_size, 1,
13876 _("LTO ext symbol data"));
13877 if (ext_data != NULL)
13878 {
13879 ext_data_end = ext_data + ext->sh_size;
13880 if (* ext_data++ != 1)
13881 error (_("Unexpected version number in symbol extension table\n"));
13882 }
13883 }
13884 }
b9e920ec 13885
0f03783c
NC
13886 const unsigned char * data = (const unsigned char *) alloced_data;
13887 const unsigned char * end = data + section->sh_size;
13888
ca0e11aa
NC
13889 if (filedata->is_separate)
13890 printf (_("\nIn linked file '%s': "), filedata->file_name);
13891 else
13892 printf ("\n");
13893
0f03783c
NC
13894 if (ext_data_orig != NULL)
13895 {
13896 if (do_wide)
ca0e11aa 13897 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13898 printable_section_name (filedata, section),
13899 printable_section_name (filedata, ext));
13900 else
13901 {
ca0e11aa 13902 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13903 printable_section_name (filedata, section));
13904 printf (_(" and extension table '%s' contain:\n"),
13905 printable_section_name (filedata, ext));
13906 }
13907 }
13908 else
ca0e11aa 13909 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13910 printable_section_name (filedata, section));
b9e920ec 13911
0f03783c 13912 /* FIXME: Add a wide version. */
b9e920ec 13913 if (ext_data_orig != NULL)
0f03783c
NC
13914 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13915 else
13916 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13917
13918 /* FIXME: We do not handle style prefixes. */
13919
13920 while (data < end)
13921 {
13922 const unsigned char * sym_name = data;
13923 data += strnlen ((const char *) sym_name, end - data) + 1;
13924 if (data >= end)
13925 goto fail;
13926
13927 const unsigned char * comdat_key = data;
13928 data += strnlen ((const char *) comdat_key, end - data) + 1;
13929 if (data >= end)
13930 goto fail;
13931
13932 if (data + 2 + 8 + 4 > end)
13933 goto fail;
13934
13935 unsigned int kind = *data++;
13936 unsigned int visibility = *data++;
13937
928c411d 13938 uint64_t size = byte_get (data, 8);
0f03783c
NC
13939 data += 8;
13940
928c411d 13941 uint64_t slot = byte_get (data, 4);
0f03783c
NC
13942 data += 4;
13943
13944 if (ext_data != NULL)
13945 {
13946 if (ext_data < (ext_data_end - 1))
13947 {
13948 unsigned int sym_type = * ext_data ++;
13949 unsigned int sec_kind = * ext_data ++;
13950
31e5a3a3 13951 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
13952 * comdat_key == 0 ? "-" : (char *) comdat_key,
13953 get_lto_kind (kind),
13954 get_lto_visibility (visibility),
31e5a3a3
AM
13955 size,
13956 slot,
0f03783c 13957 get_lto_sym_type (sym_type),
31e5a3a3 13958 sec_kind);
b6ac461a 13959 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
13960 }
13961 else
13962 {
13963 error (_("Ran out of LTO symbol extension data\n"));
13964 ext_data = NULL;
13965 /* FIXME: return FAIL result ? */
13966 }
13967 }
13968 else
13969 {
31e5a3a3 13970 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
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);
b6ac461a 13976 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
13977 }
13978 putchar ('\n');
13979 }
13980
13981 if (ext_data != NULL && ext_data < ext_data_end)
13982 {
13983 error (_("Data remains in the LTO symbol extension table\n"));
13984 goto fail;
13985 }
13986
13987 free (alloced_data);
13988 free (ext_data_orig);
13989 free (ext_name);
015dc7e1 13990 return true;
b9e920ec 13991
0f03783c
NC
13992 fail:
13993 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13994 free (alloced_data);
13995 free (ext_data_orig);
13996 free (ext_name);
015dc7e1 13997 return false;
0f03783c
NC
13998}
13999
14000/* Display LTO symbol tables. */
14001
015dc7e1 14002static bool
0f03783c
NC
14003process_lto_symbol_tables (Filedata * filedata)
14004{
14005 Elf_Internal_Shdr * section;
14006 unsigned int i;
015dc7e1 14007 bool res = true;
0f03783c
NC
14008
14009 if (!do_lto_syms)
015dc7e1 14010 return true;
0f03783c
NC
14011
14012 if (filedata->section_headers == NULL)
015dc7e1 14013 return true;
0f03783c
NC
14014
14015 for (i = 0, section = filedata->section_headers;
14016 i < filedata->file_header.e_shnum;
14017 i++, section++)
84714f86
AM
14018 if (section_name_valid (filedata, section)
14019 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14020 res &= display_lto_symtab (filedata, section);
14021
b9e920ec 14022 return res;
0f03783c
NC
14023}
14024
b6ac461a
NC
14025static void
14026print_symbol_table_heading (void)
14027{
14028 /* FIXME: We should store the size of each field in the display in a table and
14029 then use the values inside print_symbol(), instead of that function using
14030 hard coded constants. */
14031 if (is_32bit_elf)
14032 {
14033 if (extra_sym_info)
14034 {
14035 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14036 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14037 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14038 }
14039 else if (do_wide)
14040 {
14041 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14042 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14043 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14044 }
14045 else
14046 {
14047 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14048 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14049 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14050 }
14051 }
14052 else
14053 {
14054 if (extra_sym_info)
14055 {
14056 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14057 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14058 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14059
14060 }
14061 else if (do_wide)
14062 {
14063 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14064 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14065 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14066 }
14067 else
14068 {
14069 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14070 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14071 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14072 }
14073 }
14074}
14075
10ca4b04 14076/* Dump the symbol table. */
0f03783c 14077
015dc7e1 14078static bool
10ca4b04
L
14079process_symbol_table (Filedata * filedata)
14080{
14081 Elf_Internal_Shdr * section;
f16a9783 14082
10ca4b04 14083 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14084 return true;
6bd1a22c 14085
978c4450 14086 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14087 && do_syms
14088 && do_using_dynamic
978c4450
AM
14089 && filedata->dynamic_strings != NULL
14090 && filedata->dynamic_symbols != NULL)
6bd1a22c 14091 {
26c527e6 14092 uint64_t si;
6bd1a22c 14093
ca0e11aa
NC
14094 if (filedata->is_separate)
14095 {
26c527e6
AM
14096 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14097 " contains %" PRIu64 " entry:\n",
14098 "\nIn linked file '%s' the dynamic symbol table"
14099 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14100 filedata->num_dynamic_syms),
14101 filedata->file_name,
14102 filedata->num_dynamic_syms);
14103 }
14104 else
14105 {
26c527e6
AM
14106 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14107 " entry:\n",
14108 "\nSymbol table for image contains %" PRIu64
14109 " entries:\n",
ca0e11aa
NC
14110 filedata->num_dynamic_syms),
14111 filedata->num_dynamic_syms);
14112 }
b6ac461a
NC
14113
14114 print_symbol_table_heading ();
6bd1a22c 14115
978c4450 14116 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14117 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14118 filedata->dynamic_strings,
14119 filedata->dynamic_strings_length);
252b5132 14120 }
8b73c356 14121 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14122 && filedata->section_headers != NULL)
252b5132 14123 {
b34976b6 14124 unsigned int i;
252b5132 14125
dda8d76d
NC
14126 for (i = 0, section = filedata->section_headers;
14127 i < filedata->file_header.e_shnum;
252b5132
RH
14128 i++, section++)
14129 {
2cf0635d 14130 char * strtab = NULL;
26c527e6 14131 uint64_t strtab_size = 0;
2cf0635d 14132 Elf_Internal_Sym * symtab;
26c527e6 14133 uint64_t si, num_syms;
252b5132 14134
2c610e4b
L
14135 if ((section->sh_type != SHT_SYMTAB
14136 && section->sh_type != SHT_DYNSYM)
14137 || (!do_syms
14138 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14139 continue;
14140
dd24e3da
NC
14141 if (section->sh_entsize == 0)
14142 {
14143 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 14144 printable_section_name (filedata, section));
dd24e3da
NC
14145 continue;
14146 }
14147
d3a49aa8 14148 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
14149
14150 if (filedata->is_separate)
26c527e6
AM
14151 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14152 " contains %" PRIu64 " entry:\n",
14153 "\nIn linked file '%s' symbol section '%s'"
14154 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14155 num_syms),
14156 filedata->file_name,
14157 printable_section_name (filedata, section),
14158 num_syms);
14159 else
26c527e6
AM
14160 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14161 " entry:\n",
14162 "\nSymbol table '%s' contains %" PRIu64
14163 " entries:\n",
ca0e11aa
NC
14164 num_syms),
14165 printable_section_name (filedata, section),
14166 num_syms);
dd24e3da 14167
b6ac461a 14168 print_symbol_table_heading ();
252b5132 14169
4de91c10 14170 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
14171 if (symtab == NULL)
14172 continue;
14173
dda8d76d 14174 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 14175 {
dda8d76d
NC
14176 strtab = filedata->string_table;
14177 strtab_size = filedata->string_table_length;
c256ffe7 14178 }
dda8d76d 14179 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 14180 {
2cf0635d 14181 Elf_Internal_Shdr * string_sec;
252b5132 14182
dda8d76d 14183 string_sec = filedata->section_headers + section->sh_link;
252b5132 14184
dda8d76d 14185 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
14186 1, string_sec->sh_size,
14187 _("string table"));
c256ffe7 14188 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
14189 }
14190
10ca4b04 14191 for (si = 0; si < num_syms; si++)
b6ac461a
NC
14192 print_symbol (filedata, si, symtab, section,
14193 strtab, strtab_size);
252b5132
RH
14194
14195 free (symtab);
dda8d76d 14196 if (strtab != filedata->string_table)
252b5132
RH
14197 free (strtab);
14198 }
14199 }
14200 else if (do_syms)
14201 printf
14202 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14203
978c4450 14204 if (do_histogram && filedata->buckets != NULL)
252b5132 14205 {
26c527e6
AM
14206 uint64_t *lengths;
14207 uint64_t *counts;
14208 uint64_t hn;
625d49fc 14209 uint64_t si;
26c527e6
AM
14210 uint64_t maxlength = 0;
14211 uint64_t nzero_counts = 0;
14212 uint64_t nsyms = 0;
6bd6a03d 14213 char *visited;
252b5132 14214
d3a49aa8 14215 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14216 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14217 "\nHistogram for bucket list length "
26c527e6
AM
14218 "(total of %" PRIu64 " buckets):\n",
14219 filedata->nbuckets),
14220 filedata->nbuckets);
252b5132 14221
26c527e6 14222 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14223 if (lengths == NULL)
14224 {
8b73c356 14225 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14226 goto err_out;
252b5132 14227 }
978c4450
AM
14228 visited = xcmalloc (filedata->nchains, 1);
14229 memset (visited, 0, filedata->nchains);
8b73c356
NC
14230
14231 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14232 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14233 {
978c4450 14234 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14235 {
b34976b6 14236 ++nsyms;
252b5132 14237 if (maxlength < ++lengths[hn])
b34976b6 14238 ++maxlength;
978c4450 14239 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14240 {
14241 error (_("histogram chain is corrupt\n"));
14242 break;
14243 }
14244 visited[si] = 1;
252b5132
RH
14245 }
14246 }
6bd6a03d 14247 free (visited);
252b5132 14248
26c527e6 14249 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14250 if (counts == NULL)
14251 {
b2e951ec 14252 free (lengths);
8b73c356 14253 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14254 goto err_out;
252b5132
RH
14255 }
14256
978c4450 14257 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14258 ++counts[lengths[hn]];
252b5132 14259
978c4450 14260 if (filedata->nbuckets > 0)
252b5132 14261 {
26c527e6
AM
14262 uint64_t i;
14263 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14264 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14265 for (i = 1; i <= maxlength; ++i)
103f02d3 14266 {
66543521 14267 nzero_counts += counts[i] * i;
26c527e6 14268 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14269 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14270 (nzero_counts * 100.0) / nsyms);
14271 }
252b5132
RH
14272 }
14273
14274 free (counts);
14275 free (lengths);
14276 }
14277
978c4450
AM
14278 free (filedata->buckets);
14279 filedata->buckets = NULL;
14280 filedata->nbuckets = 0;
14281 free (filedata->chains);
14282 filedata->chains = NULL;
252b5132 14283
978c4450 14284 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14285 {
26c527e6
AM
14286 uint64_t *lengths;
14287 uint64_t *counts;
14288 uint64_t hn;
14289 uint64_t maxlength = 0;
14290 uint64_t nzero_counts = 0;
14291 uint64_t nsyms = 0;
fdc90cb4 14292
f16a9783 14293 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14294 "(total of %" PRIu64 " bucket):\n",
f16a9783 14295 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14296 "(total of %" PRIu64 " buckets):\n",
14297 filedata->ngnubuckets),
978c4450 14298 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14299 filedata->ngnubuckets);
8b73c356 14300
26c527e6 14301 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14302 if (lengths == NULL)
14303 {
8b73c356 14304 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14305 goto err_out;
fdc90cb4
JJ
14306 }
14307
fdc90cb4
JJ
14308 printf (_(" Length Number %% of total Coverage\n"));
14309
978c4450
AM
14310 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14311 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14312 {
625d49fc 14313 uint64_t off, length = 1;
fdc90cb4 14314
978c4450 14315 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14316 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14317 off < filedata->ngnuchains
14318 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14319 ++off)
fdc90cb4
JJ
14320 ++length;
14321 lengths[hn] = length;
14322 if (length > maxlength)
14323 maxlength = length;
14324 nsyms += length;
14325 }
14326
26c527e6 14327 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14328 if (counts == NULL)
14329 {
b2e951ec 14330 free (lengths);
8b73c356 14331 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14332 goto err_out;
fdc90cb4
JJ
14333 }
14334
978c4450 14335 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14336 ++counts[lengths[hn]];
14337
978c4450 14338 if (filedata->ngnubuckets > 0)
fdc90cb4 14339 {
26c527e6
AM
14340 uint64_t j;
14341 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14342 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14343 for (j = 1; j <= maxlength; ++j)
14344 {
14345 nzero_counts += counts[j] * j;
26c527e6 14346 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14347 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14348 (nzero_counts * 100.0) / nsyms);
14349 }
14350 }
14351
14352 free (counts);
14353 free (lengths);
fdc90cb4 14354 }
978c4450
AM
14355 free (filedata->gnubuckets);
14356 filedata->gnubuckets = NULL;
14357 filedata->ngnubuckets = 0;
14358 free (filedata->gnuchains);
14359 filedata->gnuchains = NULL;
14360 filedata->ngnuchains = 0;
14361 free (filedata->mipsxlat);
14362 filedata->mipsxlat = NULL;
015dc7e1 14363 return true;
fd486f32
AM
14364
14365 err_out:
978c4450
AM
14366 free (filedata->gnubuckets);
14367 filedata->gnubuckets = NULL;
14368 filedata->ngnubuckets = 0;
14369 free (filedata->gnuchains);
14370 filedata->gnuchains = NULL;
14371 filedata->ngnuchains = 0;
14372 free (filedata->mipsxlat);
14373 filedata->mipsxlat = NULL;
14374 free (filedata->buckets);
14375 filedata->buckets = NULL;
14376 filedata->nbuckets = 0;
14377 free (filedata->chains);
14378 filedata->chains = NULL;
015dc7e1 14379 return false;
252b5132
RH
14380}
14381
015dc7e1 14382static bool
ca0e11aa 14383process_syminfo (Filedata * filedata)
252b5132 14384{
b4c96d0d 14385 unsigned int i;
252b5132 14386
978c4450 14387 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14388 || !do_dynamic)
14389 /* No syminfo, this is ok. */
015dc7e1 14390 return true;
252b5132
RH
14391
14392 /* There better should be a dynamic symbol section. */
978c4450 14393 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14394 return false;
252b5132 14395
ca0e11aa 14396 if (filedata->is_separate)
26c527e6
AM
14397 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14398 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14399 filedata->dynamic_syminfo_nent),
14400 filedata->file_name,
14401 filedata->dynamic_syminfo_offset,
14402 filedata->dynamic_syminfo_nent);
14403 else
26c527e6
AM
14404 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14405 " contains %d entry:\n",
14406 "\nDynamic info segment at offset %#" PRIx64
14407 " contains %d entries:\n",
978c4450 14408 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14409 filedata->dynamic_syminfo_offset,
14410 filedata->dynamic_syminfo_nent);
252b5132
RH
14411
14412 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14413 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14414 {
978c4450 14415 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14416
31104126 14417 printf ("%4d: ", i);
978c4450 14418 if (i >= filedata->num_dynamic_syms)
4082ef84 14419 printf (_("<corrupt index>"));
84714f86 14420 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14421 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14422 filedata->dynamic_symbols[i].st_name));
d79b3d50 14423 else
978c4450 14424 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14425 putchar (' ');
252b5132 14426
978c4450 14427 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14428 {
14429 case SYMINFO_BT_SELF:
14430 fputs ("SELF ", stdout);
14431 break;
14432 case SYMINFO_BT_PARENT:
14433 fputs ("PARENT ", stdout);
14434 break;
14435 default:
978c4450
AM
14436 if (filedata->dynamic_syminfo[i].si_boundto > 0
14437 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14438 && valid_dynamic_name (filedata,
978c4450 14439 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14440 {
b6ac461a 14441 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 14442 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14443 putchar (' ' );
14444 }
252b5132 14445 else
978c4450 14446 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14447 break;
14448 }
14449
14450 if (flags & SYMINFO_FLG_DIRECT)
14451 printf (" DIRECT");
14452 if (flags & SYMINFO_FLG_PASSTHRU)
14453 printf (" PASSTHRU");
14454 if (flags & SYMINFO_FLG_COPY)
14455 printf (" COPY");
14456 if (flags & SYMINFO_FLG_LAZYLOAD)
14457 printf (" LAZYLOAD");
14458
14459 puts ("");
14460 }
14461
015dc7e1 14462 return true;
252b5132
RH
14463}
14464
75802ccb
CE
14465/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14466 is contained by the region START .. END. The types of ADDR, START
14467 and END should all be the same. Note both ADDR + NELEM and END
14468 point to just beyond the end of the regions that are being tested. */
14469#define IN_RANGE(START,END,ADDR,NELEM) \
14470 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14471
cf13d699
NC
14472/* Check to see if the given reloc needs to be handled in a target specific
14473 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14474 FALSE.
14475
14476 If called with reloc == NULL, then this is a signal that reloc processing
14477 for the current section has finished, and any saved state should be
14478 discarded. */
09c11c86 14479
015dc7e1 14480static bool
26c527e6
AM
14481target_specific_reloc_handling (Filedata *filedata,
14482 Elf_Internal_Rela *reloc,
14483 unsigned char *start,
14484 unsigned char *end,
14485 Elf_Internal_Sym *symtab,
14486 uint64_t num_syms)
252b5132 14487{
f84ce13b 14488 unsigned int reloc_type = 0;
26c527e6 14489 uint64_t sym_index = 0;
f84ce13b
NC
14490
14491 if (reloc)
14492 {
dda8d76d 14493 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14494 sym_index = get_reloc_symindex (reloc->r_info);
14495 }
252b5132 14496
dda8d76d 14497 switch (filedata->file_header.e_machine)
252b5132 14498 {
76244462 14499 case EM_LOONGARCH:
14500 {
14501 switch (reloc_type)
14502 {
14503 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14504 at assembly time. */
14505 case 107: /* R_LARCH_ADD_ULEB128. */
14506 case 108: /* R_LARCH_SUB_ULEB128. */
14507 {
d3f34076 14508 uint64_t value = 0;
76244462 14509 unsigned int reloc_size = 0;
14510 int leb_ret = 0;
14511
89c70cd3
AM
14512 if (reloc->r_offset < (size_t) (end - start))
14513 value = read_leb128 (start + reloc->r_offset, end, false,
14514 &reloc_size, &leb_ret);
76244462 14515 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14516 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14517 "ULEB128 value\n"),
14518 (long) reloc->r_offset);
14519
74a965d8
AM
14520 else if (sym_index >= num_syms)
14521 error (_("%s reloc contains invalid symbol index "
14522 "%" PRIu64 "\n"),
14523 (reloc_type == 107
14524 ? "R_LARCH_ADD_ULEB128"
14525 : "R_LARCH_SUB_ULEB128"),
14526 sym_index);
14527 else
76244462 14528 {
74a965d8
AM
14529 if (reloc_type == 107)
14530 value += reloc->r_addend + symtab[sym_index].st_value;
14531 else
14532 value -= reloc->r_addend + symtab[sym_index].st_value;
14533
14534 /* Write uleb128 value to p. */
14535 bfd_byte *p = start + reloc->r_offset;
14536 do
14537 {
14538 bfd_byte c = value & 0x7f;
14539 value >>= 7;
14540 if (--reloc_size != 0)
14541 c |= 0x80;
14542 *p++ = c;
14543 }
14544 while (reloc_size);
76244462 14545 }
76244462 14546
14547 return true;
14548 }
14549 }
14550 break;
14551 }
14552
13761a11
NC
14553 case EM_MSP430:
14554 case EM_MSP430_OLD:
14555 {
14556 static Elf_Internal_Sym * saved_sym = NULL;
14557
f84ce13b
NC
14558 if (reloc == NULL)
14559 {
14560 saved_sym = NULL;
015dc7e1 14561 return true;
f84ce13b
NC
14562 }
14563
13761a11
NC
14564 switch (reloc_type)
14565 {
14566 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14567 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14568 if (uses_msp430x_relocs (filedata))
13761a11 14569 break;
1a0670f3 14570 /* Fall through. */
13761a11 14571 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14572 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14573 /* PR 21139. */
14574 if (sym_index >= num_syms)
74a965d8
AM
14575 error (_("%s reloc contains invalid symbol index "
14576 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14577 else
14578 saved_sym = symtab + sym_index;
015dc7e1 14579 return true;
13761a11
NC
14580
14581 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14582 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14583 goto handle_sym_diff;
0b4362b0 14584
13761a11
NC
14585 case 5: /* R_MSP430_16_BYTE */
14586 case 9: /* R_MSP430_8 */
7d81bc93 14587 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14588 if (uses_msp430x_relocs (filedata))
13761a11
NC
14589 break;
14590 goto handle_sym_diff;
14591
14592 case 2: /* R_MSP430_ABS16 */
14593 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14594 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14595 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14596 break;
14597 goto handle_sym_diff;
0b4362b0 14598
13761a11
NC
14599 handle_sym_diff:
14600 if (saved_sym != NULL)
14601 {
625d49fc 14602 uint64_t value;
5a805384 14603 unsigned int reloc_size = 0;
7d81bc93
JL
14604 int leb_ret = 0;
14605 switch (reloc_type)
14606 {
14607 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14608 reloc_size = 4;
14609 break;
14610 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14611 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14612 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14613 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14614 &reloc_size, &leb_ret);
7d81bc93
JL
14615 break;
14616 default:
14617 reloc_size = 2;
14618 break;
14619 }
13761a11 14620
5a805384 14621 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14622 error (_("MSP430 ULEB128 field at %#" PRIx64
14623 " contains invalid ULEB128 value\n"),
14624 reloc->r_offset);
7d81bc93 14625 else if (sym_index >= num_syms)
74a965d8
AM
14626 error (_("%s reloc contains invalid symbol index "
14627 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14628 else
f84ce13b
NC
14629 {
14630 value = reloc->r_addend + (symtab[sym_index].st_value
14631 - saved_sym->st_value);
14632
b32e566b 14633 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14634 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14635 else
14636 /* PR 21137 */
26c527e6
AM
14637 error (_("MSP430 sym diff reloc contains invalid offset: "
14638 "%#" PRIx64 "\n"),
14639 reloc->r_offset);
f84ce13b 14640 }
13761a11
NC
14641
14642 saved_sym = NULL;
015dc7e1 14643 return true;
13761a11
NC
14644 }
14645 break;
14646
14647 default:
14648 if (saved_sym != NULL)
071436c6 14649 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14650 break;
14651 }
14652 break;
14653 }
14654
cf13d699
NC
14655 case EM_MN10300:
14656 case EM_CYGNUS_MN10300:
14657 {
14658 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14659
f84ce13b
NC
14660 if (reloc == NULL)
14661 {
14662 saved_sym = NULL;
015dc7e1 14663 return true;
f84ce13b
NC
14664 }
14665
cf13d699
NC
14666 switch (reloc_type)
14667 {
14668 case 34: /* R_MN10300_ALIGN */
015dc7e1 14669 return true;
cf13d699 14670 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14671 if (sym_index >= num_syms)
74a965d8
AM
14672 error (_("%s reloc contains invalid symbol index "
14673 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14674 else
14675 saved_sym = symtab + sym_index;
015dc7e1 14676 return true;
f84ce13b 14677
cf13d699
NC
14678 case 1: /* R_MN10300_32 */
14679 case 2: /* R_MN10300_16 */
14680 if (saved_sym != NULL)
14681 {
03f7786e 14682 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14683 uint64_t value;
252b5132 14684
f84ce13b 14685 if (sym_index >= num_syms)
74a965d8
AM
14686 error (_("%s reloc contains invalid symbol index "
14687 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14688 else
f84ce13b
NC
14689 {
14690 value = reloc->r_addend + (symtab[sym_index].st_value
14691 - saved_sym->st_value);
14692
b32e566b 14693 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14694 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14695 else
26c527e6
AM
14696 error (_("MN10300 sym diff reloc contains invalid offset:"
14697 " %#" PRIx64 "\n"),
14698 reloc->r_offset);
f84ce13b 14699 }
252b5132 14700
cf13d699 14701 saved_sym = NULL;
015dc7e1 14702 return true;
cf13d699
NC
14703 }
14704 break;
14705 default:
14706 if (saved_sym != NULL)
071436c6 14707 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14708 break;
14709 }
14710 break;
14711 }
6ff71e76
NC
14712
14713 case EM_RL78:
14714 {
625d49fc
AM
14715 static uint64_t saved_sym1 = 0;
14716 static uint64_t saved_sym2 = 0;
14717 static uint64_t value;
6ff71e76 14718
f84ce13b
NC
14719 if (reloc == NULL)
14720 {
14721 saved_sym1 = saved_sym2 = 0;
015dc7e1 14722 return true;
f84ce13b
NC
14723 }
14724
6ff71e76
NC
14725 switch (reloc_type)
14726 {
14727 case 0x80: /* R_RL78_SYM. */
14728 saved_sym1 = saved_sym2;
f84ce13b 14729 if (sym_index >= num_syms)
74a965d8
AM
14730 error (_("%s reloc contains invalid symbol index "
14731 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14732 else
14733 {
14734 saved_sym2 = symtab[sym_index].st_value;
14735 saved_sym2 += reloc->r_addend;
14736 }
015dc7e1 14737 return true;
6ff71e76
NC
14738
14739 case 0x83: /* R_RL78_OPsub. */
14740 value = saved_sym1 - saved_sym2;
14741 saved_sym2 = saved_sym1 = 0;
015dc7e1 14742 return true;
6ff71e76
NC
14743 break;
14744
14745 case 0x41: /* R_RL78_ABS32. */
b32e566b 14746 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14747 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14748 else
26c527e6
AM
14749 error (_("RL78 sym diff reloc contains invalid offset: "
14750 "%#" PRIx64 "\n"),
14751 reloc->r_offset);
6ff71e76 14752 value = 0;
015dc7e1 14753 return true;
6ff71e76
NC
14754
14755 case 0x43: /* R_RL78_ABS16. */
b32e566b 14756 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14757 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14758 else
26c527e6
AM
14759 error (_("RL78 sym diff reloc contains invalid offset: "
14760 "%#" PRIx64 "\n"),
14761 reloc->r_offset);
6ff71e76 14762 value = 0;
015dc7e1 14763 return true;
6ff71e76
NC
14764
14765 default:
14766 break;
14767 }
14768 break;
14769 }
252b5132
RH
14770 }
14771
015dc7e1 14772 return false;
252b5132
RH
14773}
14774
aca88567
NC
14775/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14776 DWARF debug sections. This is a target specific test. Note - we do not
14777 go through the whole including-target-headers-multiple-times route, (as
14778 we have already done with <elf/h8.h>) because this would become very
14779 messy and even then this function would have to contain target specific
14780 information (the names of the relocs instead of their numeric values).
14781 FIXME: This is not the correct way to solve this problem. The proper way
14782 is to have target specific reloc sizing and typing functions created by
14783 the reloc-macros.h header, in the same way that it already creates the
14784 reloc naming functions. */
14785
015dc7e1 14786static bool
dda8d76d 14787is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14788{
d347c9df 14789 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14790 switch (filedata->file_header.e_machine)
aca88567 14791 {
41e92641 14792 case EM_386:
22abe556 14793 case EM_IAMCU:
41e92641 14794 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14795 case EM_68K:
14796 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14797 case EM_860:
14798 return reloc_type == 1; /* R_860_32. */
14799 case EM_960:
14800 return reloc_type == 2; /* R_960_32. */
a06ea964 14801 case EM_AARCH64:
9282b95a
JW
14802 return (reloc_type == 258
14803 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14804 case EM_BPF:
14805 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14806 case EM_ADAPTEVA_EPIPHANY:
14807 return reloc_type == 3;
aca88567 14808 case EM_ALPHA:
137b6b5f 14809 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14810 case EM_ARC:
14811 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14812 case EM_ARC_COMPACT:
14813 case EM_ARC_COMPACT2:
b5c37946
SJ
14814 case EM_ARC_COMPACT3:
14815 case EM_ARC_COMPACT3_64:
886a2506 14816 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14817 case EM_ARM:
14818 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14819 case EM_AVR_OLD:
aca88567
NC
14820 case EM_AVR:
14821 return reloc_type == 1;
14822 case EM_BLACKFIN:
14823 return reloc_type == 0x12; /* R_byte4_data. */
14824 case EM_CRIS:
14825 return reloc_type == 3; /* R_CRIS_32. */
14826 case EM_CR16:
14827 return reloc_type == 3; /* R_CR16_NUM32. */
14828 case EM_CRX:
14829 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14830 case EM_CSKY:
14831 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14832 case EM_CYGNUS_FRV:
14833 return reloc_type == 1;
41e92641
NC
14834 case EM_CYGNUS_D10V:
14835 case EM_D10V:
14836 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14837 case EM_CYGNUS_D30V:
14838 case EM_D30V:
14839 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14840 case EM_DLX:
14841 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14842 case EM_CYGNUS_FR30:
14843 case EM_FR30:
14844 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14845 case EM_FT32:
14846 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14847 case EM_H8S:
14848 case EM_H8_300:
14849 case EM_H8_300H:
14850 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14851 case EM_IA_64:
262cdac7
AM
14852 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14853 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14854 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14855 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14856 case EM_IP2K_OLD:
14857 case EM_IP2K:
14858 return reloc_type == 2; /* R_IP2K_32. */
14859 case EM_IQ2000:
14860 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
14861 case EM_KVX:
14862 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
14863 case EM_LATTICEMICO32:
14864 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14865 case EM_LOONGARCH:
14866 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14867 case EM_M32C_OLD:
aca88567
NC
14868 case EM_M32C:
14869 return reloc_type == 3; /* R_M32C_32. */
14870 case EM_M32R:
14871 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14872 case EM_68HC11:
14873 case EM_68HC12:
14874 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14875 case EM_S12Z:
2849d19f
JD
14876 return reloc_type == 7 || /* R_S12Z_EXT32 */
14877 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14878 case EM_MCORE:
14879 return reloc_type == 1; /* R_MCORE_ADDR32. */
14880 case EM_CYGNUS_MEP:
14881 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14882 case EM_METAG:
14883 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14884 case EM_MICROBLAZE:
14885 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14886 case EM_MIPS:
14887 return reloc_type == 2; /* R_MIPS_32. */
14888 case EM_MMIX:
14889 return reloc_type == 4; /* R_MMIX_32. */
14890 case EM_CYGNUS_MN10200:
14891 case EM_MN10200:
14892 return reloc_type == 1; /* R_MN10200_32. */
14893 case EM_CYGNUS_MN10300:
14894 case EM_MN10300:
14895 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14896 case EM_MOXIE:
14897 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14898 case EM_MSP430_OLD:
14899 case EM_MSP430:
13761a11 14900 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14901 case EM_MT:
14902 return reloc_type == 2; /* R_MT_32. */
35c08157 14903 case EM_NDS32:
81c5e376 14904 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 14905 case EM_ALTERA_NIOS2:
36591ba1 14906 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14907 case EM_NIOS32:
14908 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14909 case EM_OR1K:
14910 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14911 case EM_PARISC:
9abca702 14912 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14913 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14914 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14915 case EM_PJ:
14916 case EM_PJ_OLD:
14917 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14918 case EM_PPC64:
14919 return reloc_type == 1; /* R_PPC64_ADDR32. */
14920 case EM_PPC:
14921 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14922 case EM_TI_PRU:
14923 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14924 case EM_RISCV:
14925 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14926 case EM_RL78:
14927 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14928 case EM_RX:
14929 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14930 case EM_S370:
14931 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14932 case EM_S390_OLD:
14933 case EM_S390:
14934 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14935 case EM_SCORE:
14936 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14937 case EM_SH:
14938 return reloc_type == 1; /* R_SH_DIR32. */
14939 case EM_SPARC32PLUS:
14940 case EM_SPARCV9:
14941 case EM_SPARC:
14942 return reloc_type == 3 /* R_SPARC_32. */
14943 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14944 case EM_SPU:
14945 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14946 case EM_TI_C6000:
14947 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14948 case EM_TILEGX:
14949 return reloc_type == 2; /* R_TILEGX_32. */
14950 case EM_TILEPRO:
14951 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14952 case EM_CYGNUS_V850:
14953 case EM_V850:
14954 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14955 case EM_V800:
14956 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14957 case EM_VAX:
14958 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14959 case EM_VISIUM:
14960 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14961 case EM_WEBASSEMBLY:
14962 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14963 case EM_X86_64:
8a9036a4 14964 case EM_L1OM:
7a9068fe 14965 case EM_K1OM:
aca88567 14966 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
14967 case EM_XGATE:
14968 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14969 case EM_XSTORMY16:
14970 return reloc_type == 1; /* R_XSTROMY16_32. */
14971 case EM_XTENSA_OLD:
14972 case EM_XTENSA:
14973 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14974 case EM_Z80:
14975 return reloc_type == 6; /* R_Z80_32. */
aca88567 14976 default:
bee0ee85
NC
14977 {
14978 static unsigned int prev_warn = 0;
14979
14980 /* Avoid repeating the same warning multiple times. */
dda8d76d 14981 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14982 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14983 filedata->file_header.e_machine);
14984 prev_warn = filedata->file_header.e_machine;
015dc7e1 14985 return false;
bee0ee85 14986 }
aca88567
NC
14987 }
14988}
14989
14990/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14991 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14992
015dc7e1 14993static bool
dda8d76d 14994is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14995{
dda8d76d 14996 switch (filedata->file_header.e_machine)
d347c9df 14997 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14998 {
41e92641 14999 case EM_386:
22abe556 15000 case EM_IAMCU:
3e0873ac 15001 return reloc_type == 2; /* R_386_PC32. */
aca88567 15002 case EM_68K:
3e0873ac 15003 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15004 case EM_AARCH64:
15005 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15006 case EM_ADAPTEVA_EPIPHANY:
15007 return reloc_type == 6;
aca88567
NC
15008 case EM_ALPHA:
15009 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15010 case EM_ARC_COMPACT:
15011 case EM_ARC_COMPACT2:
b5c37946
SJ
15012 case EM_ARC_COMPACT3:
15013 case EM_ARC_COMPACT3_64:
726c18e1 15014 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15015 case EM_ARM:
3e0873ac 15016 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15017 case EM_AVR_OLD:
15018 case EM_AVR:
15019 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15020 case EM_LOONGARCH:
15021 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15022 case EM_MICROBLAZE:
15023 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15024 case EM_OR1K:
15025 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15026 case EM_PARISC:
85acf597 15027 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15028 case EM_PPC:
15029 return reloc_type == 26; /* R_PPC_REL32. */
15030 case EM_PPC64:
3e0873ac 15031 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15032 case EM_RISCV:
15033 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15034 case EM_S390_OLD:
15035 case EM_S390:
3e0873ac 15036 return reloc_type == 5; /* R_390_PC32. */
aca88567 15037 case EM_SH:
3e0873ac 15038 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15039 case EM_SPARC32PLUS:
15040 case EM_SPARCV9:
15041 case EM_SPARC:
3e0873ac 15042 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15043 case EM_SPU:
15044 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15045 case EM_TILEGX:
15046 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15047 case EM_TILEPRO:
15048 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15049 case EM_VISIUM:
15050 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15051 case EM_X86_64:
8a9036a4 15052 case EM_L1OM:
7a9068fe 15053 case EM_K1OM:
3e0873ac 15054 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15055 case EM_VAX:
15056 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15057 case EM_XTENSA_OLD:
15058 case EM_XTENSA:
15059 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15060 case EM_KVX:
15061 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15062 default:
15063 /* Do not abort or issue an error message here. Not all targets use
15064 pc-relative 32-bit relocs in their DWARF debug information and we
15065 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15066 more helpful warning message will be generated by apply_relocations
15067 anyway, so just return. */
015dc7e1 15068 return false;
aca88567
NC
15069 }
15070}
15071
15072/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15073 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15074
015dc7e1 15075static bool
dda8d76d 15076is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15077{
dda8d76d 15078 switch (filedata->file_header.e_machine)
aca88567 15079 {
a06ea964
NC
15080 case EM_AARCH64:
15081 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15082 case EM_ARC_COMPACT3_64:
15083 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15084 case EM_ALPHA:
15085 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15086 case EM_IA_64:
262cdac7
AM
15087 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15088 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15089 case EM_LOONGARCH:
15090 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15091 case EM_PARISC:
15092 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15093 case EM_PPC64:
15094 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15095 case EM_RISCV:
15096 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15097 case EM_SPARC32PLUS:
15098 case EM_SPARCV9:
15099 case EM_SPARC:
714da62f
NC
15100 return reloc_type == 32 /* R_SPARC_64. */
15101 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15102 case EM_X86_64:
8a9036a4 15103 case EM_L1OM:
7a9068fe 15104 case EM_K1OM:
aca88567 15105 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15106 case EM_S390_OLD:
15107 case EM_S390:
aa137e4d
NC
15108 return reloc_type == 22; /* R_S390_64. */
15109 case EM_TILEGX:
15110 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15111 case EM_MIPS:
aa137e4d 15112 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15113 case EM_KVX:
15114 return reloc_type == 3; /* R_KVX_64 */
aca88567 15115 default:
015dc7e1 15116 return false;
aca88567
NC
15117 }
15118}
15119
85acf597
RH
15120/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15121 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15122
015dc7e1 15123static bool
dda8d76d 15124is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15125{
dda8d76d 15126 switch (filedata->file_header.e_machine)
85acf597 15127 {
a06ea964
NC
15128 case EM_AARCH64:
15129 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15130 case EM_ALPHA:
aa137e4d 15131 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15132 case EM_IA_64:
262cdac7
AM
15133 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15134 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15135 case EM_PARISC:
aa137e4d 15136 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15137 case EM_PPC64:
aa137e4d 15138 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15139 case EM_SPARC32PLUS:
15140 case EM_SPARCV9:
15141 case EM_SPARC:
aa137e4d 15142 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15143 case EM_X86_64:
8a9036a4 15144 case EM_L1OM:
7a9068fe 15145 case EM_K1OM:
aa137e4d 15146 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15147 case EM_S390_OLD:
15148 case EM_S390:
aa137e4d
NC
15149 return reloc_type == 23; /* R_S390_PC64. */
15150 case EM_TILEGX:
15151 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15152 default:
015dc7e1 15153 return false;
85acf597
RH
15154 }
15155}
15156
4dc3c23d
AM
15157/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15158 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15159
015dc7e1 15160static bool
dda8d76d 15161is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15162{
dda8d76d 15163 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15164 {
15165 case EM_CYGNUS_MN10200:
15166 case EM_MN10200:
15167 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15168 case EM_FT32:
15169 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15170 case EM_Z80:
15171 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15172 default:
015dc7e1 15173 return false;
4dc3c23d
AM
15174 }
15175}
15176
aca88567
NC
15177/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15178 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15179
015dc7e1 15180static bool
dda8d76d 15181is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15182{
d347c9df 15183 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15184 switch (filedata->file_header.e_machine)
4b78141a 15185 {
886a2506
NC
15186 case EM_ARC:
15187 case EM_ARC_COMPACT:
15188 case EM_ARC_COMPACT2:
b5c37946
SJ
15189 case EM_ARC_COMPACT3:
15190 case EM_ARC_COMPACT3_64:
886a2506 15191 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15192 case EM_ADAPTEVA_EPIPHANY:
15193 return reloc_type == 5;
aca88567
NC
15194 case EM_AVR_OLD:
15195 case EM_AVR:
15196 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15197 case EM_CYGNUS_D10V:
15198 case EM_D10V:
15199 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15200 case EM_FT32:
15201 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15202 case EM_H8S:
15203 case EM_H8_300:
15204 case EM_H8_300H:
aca88567
NC
15205 return reloc_type == R_H8_DIR16;
15206 case EM_IP2K_OLD:
15207 case EM_IP2K:
15208 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15209 case EM_M32C_OLD:
f4236fe4
DD
15210 case EM_M32C:
15211 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15212 case EM_CYGNUS_MN10200:
15213 case EM_MN10200:
15214 return reloc_type == 2; /* R_MN10200_16. */
15215 case EM_CYGNUS_MN10300:
15216 case EM_MN10300:
15217 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15218 case EM_KVX:
15219 return reloc_type == 1; /* R_KVX_16 */
aca88567 15220 case EM_MSP430:
dda8d76d 15221 if (uses_msp430x_relocs (filedata))
13761a11 15222 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15223 /* Fall through. */
78c8d46c 15224 case EM_MSP430_OLD:
aca88567 15225 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15226 case EM_NDS32:
81c5e376 15227 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15228 case EM_ALTERA_NIOS2:
36591ba1 15229 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15230 case EM_NIOS32:
15231 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15232 case EM_OR1K:
15233 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15234 case EM_RISCV:
15235 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15236 case EM_TI_PRU:
15237 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15238 case EM_TI_C6000:
15239 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15240 case EM_VISIUM:
15241 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15242 case EM_XGATE:
15243 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15244 case EM_Z80:
15245 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15246 default:
015dc7e1 15247 return false;
4b78141a
NC
15248 }
15249}
15250
39e07931
AS
15251/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15252 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15253
015dc7e1 15254static bool
39e07931
AS
15255is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15256{
15257 switch (filedata->file_header.e_machine)
15258 {
15259 case EM_RISCV:
15260 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15261 case EM_Z80:
15262 return reloc_type == 1; /* R_Z80_8. */
39e07931 15263 default:
015dc7e1 15264 return false;
39e07931
AS
15265 }
15266}
15267
15268/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15269 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15270
015dc7e1 15271static bool
39e07931
AS
15272is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15273{
15274 switch (filedata->file_header.e_machine)
15275 {
15276 case EM_RISCV:
15277 return reloc_type == 53; /* R_RISCV_SET6. */
15278 default:
015dc7e1 15279 return false;
39e07931
AS
15280 }
15281}
15282
03336641
JW
15283/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15284 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15285
015dc7e1 15286static bool
03336641
JW
15287is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15288{
15289 /* Please keep this table alpha-sorted for ease of visual lookup. */
15290 switch (filedata->file_header.e_machine)
15291 {
76244462 15292 case EM_LOONGARCH:
15293 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15294 case EM_RISCV:
15295 return reloc_type == 35; /* R_RISCV_ADD32. */
15296 default:
015dc7e1 15297 return false;
03336641
JW
15298 }
15299}
15300
15301/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15302 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15303
015dc7e1 15304static bool
03336641
JW
15305is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15306{
15307 /* Please keep this table alpha-sorted for ease of visual lookup. */
15308 switch (filedata->file_header.e_machine)
15309 {
76244462 15310 case EM_LOONGARCH:
15311 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15312 case EM_RISCV:
15313 return reloc_type == 39; /* R_RISCV_SUB32. */
15314 default:
015dc7e1 15315 return false;
03336641
JW
15316 }
15317}
15318
15319/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15320 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15321
015dc7e1 15322static bool
03336641
JW
15323is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15324{
15325 /* Please keep this table alpha-sorted for ease of visual lookup. */
15326 switch (filedata->file_header.e_machine)
15327 {
76244462 15328 case EM_LOONGARCH:
15329 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15330 case EM_RISCV:
15331 return reloc_type == 36; /* R_RISCV_ADD64. */
15332 default:
015dc7e1 15333 return false;
03336641
JW
15334 }
15335}
15336
15337/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15338 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15339
015dc7e1 15340static bool
03336641
JW
15341is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15342{
15343 /* Please keep this table alpha-sorted for ease of visual lookup. */
15344 switch (filedata->file_header.e_machine)
15345 {
76244462 15346 case EM_LOONGARCH:
15347 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15348 case EM_RISCV:
15349 return reloc_type == 40; /* R_RISCV_SUB64. */
15350 default:
015dc7e1 15351 return false;
03336641
JW
15352 }
15353}
15354
15355/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15356 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15357
015dc7e1 15358static bool
03336641
JW
15359is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15360{
15361 /* Please keep this table alpha-sorted for ease of visual lookup. */
15362 switch (filedata->file_header.e_machine)
15363 {
76244462 15364 case EM_LOONGARCH:
15365 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15366 case EM_RISCV:
15367 return reloc_type == 34; /* R_RISCV_ADD16. */
15368 default:
015dc7e1 15369 return false;
03336641
JW
15370 }
15371}
15372
15373/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15374 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15375
015dc7e1 15376static bool
03336641
JW
15377is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15378{
15379 /* Please keep this table alpha-sorted for ease of visual lookup. */
15380 switch (filedata->file_header.e_machine)
15381 {
76244462 15382 case EM_LOONGARCH:
15383 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15384 case EM_RISCV:
15385 return reloc_type == 38; /* R_RISCV_SUB16. */
15386 default:
015dc7e1 15387 return false;
03336641
JW
15388 }
15389}
15390
15391/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15392 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15393
015dc7e1 15394static bool
03336641
JW
15395is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15396{
15397 /* Please keep this table alpha-sorted for ease of visual lookup. */
15398 switch (filedata->file_header.e_machine)
15399 {
76244462 15400 case EM_LOONGARCH:
15401 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15402 case EM_RISCV:
15403 return reloc_type == 33; /* R_RISCV_ADD8. */
15404 default:
015dc7e1 15405 return false;
03336641
JW
15406 }
15407}
15408
15409/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15410 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15411
015dc7e1 15412static bool
03336641
JW
15413is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15414{
15415 /* Please keep this table alpha-sorted for ease of visual lookup. */
15416 switch (filedata->file_header.e_machine)
15417 {
76244462 15418 case EM_LOONGARCH:
15419 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15420 case EM_RISCV:
15421 return reloc_type == 37; /* R_RISCV_SUB8. */
15422 default:
015dc7e1 15423 return false;
03336641
JW
15424 }
15425}
15426
76244462 15427/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15428 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15429
15430static bool
15431is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15432{
15433 switch (filedata->file_header.e_machine)
15434 {
15435 case EM_LOONGARCH:
15436 return reloc_type == 105; /* R_LARCH_ADD6. */
15437 default:
15438 return false;
15439 }
15440}
15441
39e07931
AS
15442/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15443 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15444
015dc7e1 15445static bool
39e07931
AS
15446is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15447{
15448 switch (filedata->file_header.e_machine)
15449 {
76244462 15450 case EM_LOONGARCH:
15451 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15452 case EM_RISCV:
15453 return reloc_type == 52; /* R_RISCV_SUB6. */
15454 default:
015dc7e1 15455 return false;
39e07931
AS
15456 }
15457}
15458
2a7b2e88
JK
15459/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15460 relocation entries (possibly formerly used for SHT_GROUP sections). */
15461
015dc7e1 15462static bool
dda8d76d 15463is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15464{
dda8d76d 15465 switch (filedata->file_header.e_machine)
2a7b2e88 15466 {
cb8f3167 15467 case EM_386: /* R_386_NONE. */
d347c9df 15468 case EM_68K: /* R_68K_NONE. */
cfb8c092 15469 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15470 case EM_ALPHA: /* R_ALPHA_NONE. */
15471 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15472 case EM_ARC: /* R_ARC_NONE. */
886a2506 15473 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15474 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15475 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15476 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15477 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15478 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15479 case EM_FT32: /* R_FT32_NONE. */
15480 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15481 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15482 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15483 case EM_L1OM: /* R_X86_64_NONE. */
15484 case EM_M32R: /* R_M32R_NONE. */
15485 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15486 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15487 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15488 case EM_NIOS32: /* R_NIOS_NONE. */
15489 case EM_OR1K: /* R_OR1K_NONE. */
15490 case EM_PARISC: /* R_PARISC_NONE. */
15491 case EM_PPC64: /* R_PPC64_NONE. */
15492 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15493 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15494 case EM_S390: /* R_390_NONE. */
15495 case EM_S390_OLD:
15496 case EM_SH: /* R_SH_NONE. */
15497 case EM_SPARC32PLUS:
15498 case EM_SPARC: /* R_SPARC_NONE. */
15499 case EM_SPARCV9:
aa137e4d
NC
15500 case EM_TILEGX: /* R_TILEGX_NONE. */
15501 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15502 case EM_TI_C6000:/* R_C6000_NONE. */
15503 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15504 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15505 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15506 return reloc_type == 0;
d347c9df 15507
a06ea964
NC
15508 case EM_AARCH64:
15509 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15510 case EM_AVR_OLD:
15511 case EM_AVR:
15512 return (reloc_type == 0 /* R_AVR_NONE. */
15513 || reloc_type == 30 /* R_AVR_DIFF8. */
15514 || reloc_type == 31 /* R_AVR_DIFF16. */
15515 || reloc_type == 32 /* R_AVR_DIFF32. */);
15516 case EM_METAG:
15517 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15518 case EM_NDS32:
81c5e376
AM
15519 return (reloc_type == 0 /* R_NDS32_NONE. */
15520 || reloc_type == 205 /* R_NDS32_DIFF8. */
15521 || reloc_type == 206 /* R_NDS32_DIFF16. */
15522 || reloc_type == 207 /* R_NDS32_DIFF32. */
15523 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15524 case EM_TI_PRU:
15525 return (reloc_type == 0 /* R_PRU_NONE. */
15526 || reloc_type == 65 /* R_PRU_DIFF8. */
15527 || reloc_type == 66 /* R_PRU_DIFF16. */
15528 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15529 case EM_XTENSA_OLD:
15530 case EM_XTENSA:
4dc3c23d
AM
15531 return (reloc_type == 0 /* R_XTENSA_NONE. */
15532 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15533 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15534 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15535 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15536 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15537 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15538 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15539 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15540 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15541 }
015dc7e1 15542 return false;
2a7b2e88
JK
15543}
15544
d1c4b12b
NC
15545/* Returns TRUE if there is a relocation against
15546 section NAME at OFFSET bytes. */
15547
015dc7e1 15548bool
31e5a3a3 15549reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15550{
15551 Elf_Internal_Rela * relocs;
15552 Elf_Internal_Rela * rp;
15553
15554 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15555 return false;
d1c4b12b
NC
15556
15557 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15558
15559 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15560 if (rp->r_offset == offset)
015dc7e1 15561 return true;
d1c4b12b 15562
015dc7e1 15563 return false;
d1c4b12b
NC
15564}
15565
cf13d699 15566/* Apply relocations to a section.
32ec8896
NC
15567 Returns TRUE upon success, FALSE otherwise.
15568 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15569 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15570 will be set to the number of relocs loaded.
15571
cf13d699 15572 Note: So far support has been added only for those relocations
32ec8896
NC
15573 which can be found in debug sections. FIXME: Add support for
15574 more relocations ? */
1b315056 15575
015dc7e1 15576static bool
be7d229a
AM
15577apply_relocations (Filedata *filedata,
15578 const Elf_Internal_Shdr *section,
15579 unsigned char *start,
15580 size_t size,
15581 void **relocs_return,
26c527e6 15582 uint64_t *num_relocs_return)
1b315056 15583{
cf13d699 15584 Elf_Internal_Shdr * relsec;
0d2a7a93 15585 unsigned char * end = start + size;
cb8f3167 15586
d1c4b12b
NC
15587 if (relocs_return != NULL)
15588 {
15589 * (Elf_Internal_Rela **) relocs_return = NULL;
15590 * num_relocs_return = 0;
15591 }
15592
dda8d76d 15593 if (filedata->file_header.e_type != ET_REL)
32ec8896 15594 /* No relocs to apply. */
015dc7e1 15595 return true;
1b315056 15596
cf13d699 15597 /* Find the reloc section associated with the section. */
dda8d76d
NC
15598 for (relsec = filedata->section_headers;
15599 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15600 ++relsec)
252b5132 15601 {
015dc7e1 15602 bool is_rela;
26c527e6 15603 uint64_t num_relocs;
2cf0635d
NC
15604 Elf_Internal_Rela * relocs;
15605 Elf_Internal_Rela * rp;
15606 Elf_Internal_Shdr * symsec;
15607 Elf_Internal_Sym * symtab;
26c527e6 15608 uint64_t num_syms;
2cf0635d 15609 Elf_Internal_Sym * sym;
252b5132 15610
41e92641 15611 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15612 || relsec->sh_info >= filedata->file_header.e_shnum
15613 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15614 || relsec->sh_size == 0
dda8d76d 15615 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15616 continue;
428409d5 15617
a788aedd
AM
15618 symsec = filedata->section_headers + relsec->sh_link;
15619 if (symsec->sh_type != SHT_SYMTAB
15620 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15621 return false;
a788aedd 15622
41e92641
NC
15623 is_rela = relsec->sh_type == SHT_RELA;
15624
15625 if (is_rela)
15626 {
dda8d76d 15627 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15628 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15629 return false;
41e92641
NC
15630 }
15631 else
15632 {
dda8d76d 15633 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15634 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15635 return false;
41e92641
NC
15636 }
15637
15638 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15639 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15640 is_rela = false;
428409d5 15641
4de91c10 15642 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15643
41e92641 15644 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15645 {
625d49fc 15646 uint64_t addend;
015dc7e1
AM
15647 unsigned int reloc_type;
15648 unsigned int reloc_size;
15649 bool reloc_inplace = false;
15650 bool reloc_subtract = false;
15651 unsigned char *rloc;
26c527e6 15652 uint64_t sym_index;
4b78141a 15653
dda8d76d 15654 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15655
dda8d76d 15656 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15657 continue;
dda8d76d 15658 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15659 continue;
dda8d76d
NC
15660 else if (is_32bit_abs_reloc (filedata, reloc_type)
15661 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15662 reloc_size = 4;
dda8d76d
NC
15663 else if (is_64bit_abs_reloc (filedata, reloc_type)
15664 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15665 reloc_size = 8;
dda8d76d 15666 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15667 reloc_size = 3;
dda8d76d 15668 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15669 reloc_size = 2;
39e07931
AS
15670 else if (is_8bit_abs_reloc (filedata, reloc_type)
15671 || is_6bit_abs_reloc (filedata, reloc_type))
15672 reloc_size = 1;
03336641
JW
15673 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15674 reloc_type))
15675 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15676 {
15677 reloc_size = 4;
015dc7e1 15678 reloc_inplace = true;
03336641
JW
15679 }
15680 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15681 reloc_type))
15682 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15683 {
15684 reloc_size = 8;
015dc7e1 15685 reloc_inplace = true;
03336641
JW
15686 }
15687 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15688 reloc_type))
15689 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15690 {
15691 reloc_size = 2;
015dc7e1 15692 reloc_inplace = true;
03336641
JW
15693 }
15694 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15695 reloc_type))
15696 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15697 {
15698 reloc_size = 1;
015dc7e1 15699 reloc_inplace = true;
03336641 15700 }
39e07931 15701 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15702 reloc_type))
15703 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15704 {
15705 reloc_size = 1;
015dc7e1 15706 reloc_inplace = true;
39e07931 15707 }
aca88567 15708 else
4b78141a 15709 {
bee0ee85 15710 static unsigned int prev_reloc = 0;
dda8d76d 15711
bee0ee85
NC
15712 if (reloc_type != prev_reloc)
15713 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15714 reloc_type, printable_section_name (filedata, section));
bee0ee85 15715 prev_reloc = reloc_type;
4b78141a
NC
15716 continue;
15717 }
103f02d3 15718
91d6fa6a 15719 rloc = start + rp->r_offset;
75802ccb 15720 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15721 {
26c527e6
AM
15722 warn (_("skipping invalid relocation offset %#" PRIx64
15723 " in section %s\n"),
15724 rp->r_offset,
dda8d76d 15725 printable_section_name (filedata, section));
700dd8b7
L
15726 continue;
15727 }
103f02d3 15728
26c527e6 15729 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15730 if (sym_index >= num_syms)
15731 {
26c527e6
AM
15732 warn (_("skipping invalid relocation symbol index %#" PRIx64
15733 " in section %s\n"),
dda8d76d 15734 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15735 continue;
15736 }
15737 sym = symtab + sym_index;
41e92641
NC
15738
15739 /* If the reloc has a symbol associated with it,
55f25fc3
L
15740 make sure that it is of an appropriate type.
15741
15742 Relocations against symbols without type can happen.
15743 Gcc -feliminate-dwarf2-dups may generate symbols
15744 without type for debug info.
15745
15746 Icc generates relocations against function symbols
15747 instead of local labels.
15748
15749 Relocations against object symbols can happen, eg when
15750 referencing a global array. For an example of this see
15751 the _clz.o binary in libgcc.a. */
aca88567 15752 if (sym != symtab
b8871f35 15753 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15754 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15755 {
26c527e6 15756 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15757 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15758 printable_section_name (filedata, relsec),
26c527e6 15759 rp - relocs);
aca88567 15760 continue;
5b18a4bc 15761 }
252b5132 15762
4dc3c23d
AM
15763 addend = 0;
15764 if (is_rela)
15765 addend += rp->r_addend;
c47320c3
AM
15766 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15767 partial_inplace. */
4dc3c23d 15768 if (!is_rela
dda8d76d 15769 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15770 && reloc_type == 1)
dda8d76d
NC
15771 || ((filedata->file_header.e_machine == EM_PJ
15772 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15773 && reloc_type == 1)
dda8d76d
NC
15774 || ((filedata->file_header.e_machine == EM_D30V
15775 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15776 && reloc_type == 12)
15777 || reloc_inplace)
39e07931
AS
15778 {
15779 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15780 addend += byte_get (rloc, reloc_size) & 0x3f;
15781 else
15782 addend += byte_get (rloc, reloc_size);
15783 }
cb8f3167 15784
dda8d76d
NC
15785 if (is_32bit_pcrel_reloc (filedata, reloc_type)
15786 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
15787 {
15788 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 15789 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 15790 addend -= 8;
91d6fa6a 15791 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
15792 reloc_size);
15793 }
39e07931 15794 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 15795 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
15796 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15797 {
15798 if (reloc_subtract)
15799 addend -= sym->st_value;
15800 else
15801 addend += sym->st_value;
15802 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
15803 byte_put (rloc, addend, reloc_size);
15804 }
03336641
JW
15805 else if (reloc_subtract)
15806 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 15807 else
91d6fa6a 15808 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 15809 }
252b5132 15810
5b18a4bc 15811 free (symtab);
f84ce13b
NC
15812 /* Let the target specific reloc processing code know that
15813 we have finished with these relocs. */
dda8d76d 15814 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
15815
15816 if (relocs_return)
15817 {
15818 * (Elf_Internal_Rela **) relocs_return = relocs;
15819 * num_relocs_return = num_relocs;
15820 }
15821 else
15822 free (relocs);
15823
5b18a4bc
NC
15824 break;
15825 }
32ec8896 15826
015dc7e1 15827 return true;
5b18a4bc 15828}
103f02d3 15829
cf13d699 15830#ifdef SUPPORT_DISASSEMBLY
015dc7e1 15831static bool
dda8d76d 15832disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15833{
dda8d76d 15834 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15835
74e1a04b 15836 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15837
015dc7e1 15838 return true;
cf13d699
NC
15839}
15840#endif
15841
15842/* Reads in the contents of SECTION from FILE, returning a pointer
15843 to a malloc'ed buffer or NULL if something went wrong. */
15844
15845static char *
dda8d76d 15846get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15847{
be7d229a 15848 uint64_t num_bytes = section->sh_size;
cf13d699
NC
15849
15850 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15851 {
c6b78c96 15852 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15853 printable_section_name (filedata, section));
cf13d699
NC
15854 return NULL;
15855 }
15856
dda8d76d 15857 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15858 _("section contents"));
cf13d699
NC
15859}
15860
1f5a3546 15861/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 15862
015dc7e1 15863static bool
45f5fe46
NC
15864uncompress_section_contents (bool is_zstd,
15865 unsigned char ** buffer,
15866 uint64_t uncompressed_size,
15867 uint64_t * size,
15868 uint64_t file_size)
0e602686 15869{
31e5a3a3
AM
15870 uint64_t compressed_size = *size;
15871 unsigned char *compressed_buffer = *buffer;
45f5fe46 15872 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
15873 z_stream strm;
15874 int rc;
15875
45f5fe46
NC
15876 /* Similar to _bfd_section_size_insane() in the BFD library we expect an
15877 upper limit of ~10x compression. Any compression larger than that is
15878 thought to be due to fuzzing of the compression header. */
15879 if (uncompressed_size > file_size * 10)
15880 {
15881 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
15882 uncompressed_size);
15883 goto fail;
15884 }
15885
15886 uncompressed_buffer = xmalloc (uncompressed_size);
15887
1f5a3546
FS
15888 if (is_zstd)
15889 {
15890#ifdef HAVE_ZSTD
15891 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
15892 compressed_buffer, compressed_size);
15893 if (ZSTD_isError (ret))
15894 goto fail;
15895#endif
15896 }
15897 else
15898 {
15899 /* It is possible the section consists of several compressed
15900 buffers concatenated together, so we uncompress in a loop. */
15901 /* PR 18313: The state field in the z_stream structure is supposed
15902 to be invisible to the user (ie us), but some compilers will
15903 still complain about it being used without initialisation. So
15904 we first zero the entire z_stream structure and then set the fields
15905 that we need. */
15906 memset (&strm, 0, sizeof strm);
15907 strm.avail_in = compressed_size;
15908 strm.next_in = (Bytef *)compressed_buffer;
15909 strm.avail_out = uncompressed_size;
15910
15911 rc = inflateInit (&strm);
15912 while (strm.avail_in > 0)
15913 {
15914 if (rc != Z_OK)
15915 break;
15916 strm.next_out = ((Bytef *)uncompressed_buffer
15917 + (uncompressed_size - strm.avail_out));
15918 rc = inflate (&strm, Z_FINISH);
15919 if (rc != Z_STREAM_END)
15920 break;
15921 rc = inflateReset (&strm);
15922 }
15923 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
15924 goto fail;
15925 }
0e602686
NC
15926
15927 *buffer = uncompressed_buffer;
15928 *size = uncompressed_size;
015dc7e1 15929 return true;
0e602686
NC
15930
15931 fail:
15932 free (uncompressed_buffer);
15933 /* Indicate decompression failure. */
15934 *buffer = NULL;
015dc7e1 15935 return false;
0e602686 15936}
dd24e3da 15937
015dc7e1 15938static bool
dda8d76d 15939dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15940{
015dc7e1 15941 Elf_Internal_Shdr *relsec;
be7d229a 15942 uint64_t num_bytes;
015dc7e1
AM
15943 unsigned char *data;
15944 unsigned char *end;
15945 unsigned char *real_start;
15946 unsigned char *start;
15947 bool some_strings_shown;
cf13d699 15948
dda8d76d 15949 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15950 if (start == NULL)
c6b78c96 15951 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15952 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15953
0e602686 15954 num_bytes = section->sh_size;
cf13d699 15955
835f2fae
NC
15956 if (filedata->is_separate)
15957 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15958 printable_section_name (filedata, section),
15959 filedata->file_name);
15960 else
15961 printf (_("\nString dump of section '%s':\n"),
15962 printable_section_name (filedata, section));
cf13d699 15963
0e602686
NC
15964 if (decompress_dumps)
15965 {
31e5a3a3
AM
15966 uint64_t new_size = num_bytes;
15967 uint64_t uncompressed_size = 0;
1f5a3546 15968 bool is_zstd = false;
0e602686
NC
15969
15970 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15971 {
15972 Elf_Internal_Chdr chdr;
15973 unsigned int compression_header_size
ebdf1ebf
NC
15974 = get_compression_header (& chdr, (unsigned char *) start,
15975 num_bytes);
5844b465
NC
15976 if (compression_header_size == 0)
15977 /* An error message will have already been generated
15978 by get_compression_header. */
15979 goto error_out;
0e602686 15980
89dbeac7 15981 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
15982 ;
15983#ifdef HAVE_ZSTD
89dbeac7 15984 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
15985 is_zstd = true;
15986#endif
15987 else
0e602686 15988 {
813dabb9 15989 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15990 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15991 goto error_out;
813dabb9 15992 }
813dabb9
L
15993 uncompressed_size = chdr.ch_size;
15994 start += compression_header_size;
15995 new_size -= compression_header_size;
0e602686
NC
15996 }
15997 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15998 {
15999 /* Read the zlib header. In this case, it should be "ZLIB"
16000 followed by the uncompressed section size, 8 bytes in
16001 big-endian order. */
16002 uncompressed_size = start[4]; uncompressed_size <<= 8;
16003 uncompressed_size += start[5]; uncompressed_size <<= 8;
16004 uncompressed_size += start[6]; uncompressed_size <<= 8;
16005 uncompressed_size += start[7]; uncompressed_size <<= 8;
16006 uncompressed_size += start[8]; uncompressed_size <<= 8;
16007 uncompressed_size += start[9]; uncompressed_size <<= 8;
16008 uncompressed_size += start[10]; uncompressed_size <<= 8;
16009 uncompressed_size += start[11];
16010 start += 12;
16011 new_size -= 12;
16012 }
16013
1835f746
NC
16014 if (uncompressed_size)
16015 {
1f5a3546 16016 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16017 &new_size, filedata->file_size))
1835f746
NC
16018 num_bytes = new_size;
16019 else
16020 {
16021 error (_("Unable to decompress section %s\n"),
dda8d76d 16022 printable_section_name (filedata, section));
f761cb13 16023 goto error_out;
1835f746
NC
16024 }
16025 }
bc303e5d
NC
16026 else
16027 start = real_start;
0e602686 16028 }
fd8008d8 16029
cf13d699
NC
16030 /* If the section being dumped has relocations against it the user might
16031 be expecting these relocations to have been applied. Check for this
16032 case and issue a warning message in order to avoid confusion.
16033 FIXME: Maybe we ought to have an option that dumps a section with
16034 relocs applied ? */
dda8d76d
NC
16035 for (relsec = filedata->section_headers;
16036 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16037 ++relsec)
16038 {
16039 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16040 || relsec->sh_info >= filedata->file_header.e_shnum
16041 || filedata->section_headers + relsec->sh_info != section
cf13d699 16042 || relsec->sh_size == 0
dda8d76d 16043 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16044 continue;
16045
16046 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16047 break;
16048 }
16049
cf13d699
NC
16050 data = start;
16051 end = start + num_bytes;
015dc7e1 16052 some_strings_shown = false;
cf13d699 16053
ba3265d0
NC
16054#ifdef HAVE_MBSTATE_T
16055 mbstate_t state;
16056 /* Initialise the multibyte conversion state. */
16057 memset (& state, 0, sizeof (state));
16058#endif
16059
015dc7e1 16060 bool continuing = false;
ba3265d0 16061
cf13d699
NC
16062 while (data < end)
16063 {
16064 while (!ISPRINT (* data))
16065 if (++ data >= end)
16066 break;
16067
16068 if (data < end)
16069 {
071436c6
NC
16070 size_t maxlen = end - data;
16071
ba3265d0
NC
16072 if (continuing)
16073 {
16074 printf (" ");
015dc7e1 16075 continuing = false;
ba3265d0
NC
16076 }
16077 else
16078 {
26c527e6 16079 printf (" [%6tx] ", data - start);
ba3265d0
NC
16080 }
16081
4082ef84
NC
16082 if (maxlen > 0)
16083 {
f3da8a96 16084 char c = 0;
ba3265d0
NC
16085
16086 while (maxlen)
16087 {
16088 c = *data++;
16089
16090 if (c == 0)
16091 break;
16092
16093 /* PR 25543: Treat new-lines as string-ending characters. */
16094 if (c == '\n')
16095 {
16096 printf ("\\n\n");
16097 if (*data != 0)
015dc7e1 16098 continuing = true;
ba3265d0
NC
16099 break;
16100 }
16101
16102 /* Do not print control characters directly as they can affect terminal
16103 settings. Such characters usually appear in the names generated
16104 by the assembler for local labels. */
16105 if (ISCNTRL (c))
16106 {
16107 printf ("^%c", c + 0x40);
16108 }
16109 else if (ISPRINT (c))
16110 {
16111 putchar (c);
16112 }
16113 else
16114 {
16115 size_t n;
16116#ifdef HAVE_MBSTATE_T
16117 wchar_t w;
16118#endif
16119 /* Let printf do the hard work of displaying multibyte characters. */
16120 printf ("%.1s", data - 1);
16121#ifdef HAVE_MBSTATE_T
16122 /* Try to find out how many bytes made up the character that was
16123 just printed. Advance the symbol pointer past the bytes that
16124 were displayed. */
16125 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16126#else
16127 n = 1;
16128#endif
16129 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16130 data += (n - 1);
16131 }
16132 }
16133
16134 if (c != '\n')
16135 putchar ('\n');
4082ef84
NC
16136 }
16137 else
16138 {
16139 printf (_("<corrupt>\n"));
16140 data = end;
16141 }
015dc7e1 16142 some_strings_shown = true;
cf13d699
NC
16143 }
16144 }
16145
16146 if (! some_strings_shown)
16147 printf (_(" No strings found in this section."));
16148
0e602686 16149 free (real_start);
cf13d699
NC
16150
16151 putchar ('\n');
015dc7e1 16152 return true;
f761cb13
AM
16153
16154error_out:
16155 free (real_start);
015dc7e1 16156 return false;
cf13d699
NC
16157}
16158
015dc7e1
AM
16159static bool
16160dump_section_as_bytes (Elf_Internal_Shdr *section,
16161 Filedata *filedata,
16162 bool relocate)
cf13d699 16163{
be7d229a
AM
16164 Elf_Internal_Shdr *relsec;
16165 size_t bytes;
16166 uint64_t section_size;
625d49fc 16167 uint64_t addr;
be7d229a
AM
16168 unsigned char *data;
16169 unsigned char *real_start;
16170 unsigned char *start;
0e602686 16171
dda8d76d 16172 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16173 if (start == NULL)
c6b78c96 16174 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16175 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16176
0e602686 16177 section_size = section->sh_size;
cf13d699 16178
835f2fae
NC
16179 if (filedata->is_separate)
16180 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16181 printable_section_name (filedata, section),
16182 filedata->file_name);
16183 else
16184 printf (_("\nHex dump of section '%s':\n"),
16185 printable_section_name (filedata, section));
cf13d699 16186
0e602686
NC
16187 if (decompress_dumps)
16188 {
31e5a3a3
AM
16189 uint64_t new_size = section_size;
16190 uint64_t uncompressed_size = 0;
1f5a3546 16191 bool is_zstd = false;
0e602686
NC
16192
16193 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16194 {
16195 Elf_Internal_Chdr chdr;
16196 unsigned int compression_header_size
ebdf1ebf 16197 = get_compression_header (& chdr, start, section_size);
0e602686 16198
5844b465
NC
16199 if (compression_header_size == 0)
16200 /* An error message will have already been generated
16201 by get_compression_header. */
16202 goto error_out;
16203
89dbeac7 16204 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16205 ;
16206#ifdef HAVE_ZSTD
89dbeac7 16207 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16208 is_zstd = true;
16209#endif
16210 else
0e602686 16211 {
813dabb9 16212 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16213 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 16214 goto error_out;
0e602686 16215 }
813dabb9
L
16216 uncompressed_size = chdr.ch_size;
16217 start += compression_header_size;
16218 new_size -= compression_header_size;
0e602686
NC
16219 }
16220 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16221 {
16222 /* Read the zlib header. In this case, it should be "ZLIB"
16223 followed by the uncompressed section size, 8 bytes in
16224 big-endian order. */
16225 uncompressed_size = start[4]; uncompressed_size <<= 8;
16226 uncompressed_size += start[5]; uncompressed_size <<= 8;
16227 uncompressed_size += start[6]; uncompressed_size <<= 8;
16228 uncompressed_size += start[7]; uncompressed_size <<= 8;
16229 uncompressed_size += start[8]; uncompressed_size <<= 8;
16230 uncompressed_size += start[9]; uncompressed_size <<= 8;
16231 uncompressed_size += start[10]; uncompressed_size <<= 8;
16232 uncompressed_size += start[11];
16233 start += 12;
16234 new_size -= 12;
16235 }
16236
f055032e
NC
16237 if (uncompressed_size)
16238 {
1f5a3546 16239 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16240 &new_size, filedata->file_size))
bc303e5d
NC
16241 {
16242 section_size = new_size;
16243 }
f055032e
NC
16244 else
16245 {
16246 error (_("Unable to decompress section %s\n"),
dda8d76d 16247 printable_section_name (filedata, section));
bc303e5d 16248 /* FIXME: Print the section anyway ? */
f761cb13 16249 goto error_out;
f055032e
NC
16250 }
16251 }
bc303e5d
NC
16252 else
16253 start = real_start;
0e602686 16254 }
14ae95f2 16255
cf13d699
NC
16256 if (relocate)
16257 {
dda8d76d 16258 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 16259 goto error_out;
cf13d699
NC
16260 }
16261 else
16262 {
16263 /* If the section being dumped has relocations against it the user might
16264 be expecting these relocations to have been applied. Check for this
16265 case and issue a warning message in order to avoid confusion.
16266 FIXME: Maybe we ought to have an option that dumps a section with
16267 relocs applied ? */
dda8d76d
NC
16268 for (relsec = filedata->section_headers;
16269 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
16270 ++relsec)
16271 {
16272 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
16273 || relsec->sh_info >= filedata->file_header.e_shnum
16274 || filedata->section_headers + relsec->sh_info != section
cf13d699 16275 || relsec->sh_size == 0
dda8d76d 16276 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
16277 continue;
16278
16279 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16280 break;
16281 }
16282 }
16283
16284 addr = section->sh_addr;
0e602686 16285 bytes = section_size;
cf13d699
NC
16286 data = start;
16287
16288 while (bytes)
16289 {
16290 int j;
16291 int k;
16292 int lbytes;
16293
16294 lbytes = (bytes > 16 ? 16 : bytes);
16295
26c527e6 16296 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16297
16298 for (j = 0; j < 16; j++)
16299 {
16300 if (j < lbytes)
16301 printf ("%2.2x", data[j]);
16302 else
16303 printf (" ");
16304
16305 if ((j & 3) == 3)
16306 printf (" ");
16307 }
16308
16309 for (j = 0; j < lbytes; j++)
16310 {
16311 k = data[j];
16312 if (k >= ' ' && k < 0x7f)
16313 printf ("%c", k);
16314 else
16315 printf (".");
16316 }
16317
16318 putchar ('\n');
16319
16320 data += lbytes;
16321 addr += lbytes;
16322 bytes -= lbytes;
16323 }
16324
0e602686 16325 free (real_start);
cf13d699
NC
16326
16327 putchar ('\n');
015dc7e1 16328 return true;
f761cb13
AM
16329
16330 error_out:
16331 free (real_start);
015dc7e1 16332 return false;
cf13d699
NC
16333}
16334
094e34f2 16335#ifdef ENABLE_LIBCTF
7d9813f1
NA
16336static ctf_sect_t *
16337shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16338{
b6ac461a 16339 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16340 buf->cts_size = shdr->sh_size;
16341 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16342
16343 return buf;
16344}
16345
16346/* Formatting callback function passed to ctf_dump. Returns either the pointer
16347 it is passed, or a pointer to newly-allocated storage, in which case
16348 dump_ctf() will free it when it no longer needs it. */
16349
2f6ecaed
NA
16350static char *
16351dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16352 char *s, void *arg)
7d9813f1 16353{
3e50a591 16354 const char *blanks = arg;
7d9813f1
NA
16355 char *new_s;
16356
3e50a591 16357 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16358 return s;
16359 return new_s;
16360}
16361
926c9e76
NA
16362/* Dump CTF errors/warnings. */
16363static void
139633c3 16364dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16365{
16366 ctf_next_t *it = NULL;
16367 char *errtext;
16368 int is_warning;
16369 int err;
16370
16371 /* Dump accumulated errors and warnings. */
16372 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16373 {
5e9b84f7 16374 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16375 errtext);
16376 free (errtext);
16377 }
16378 if (err != ECTF_NEXT_END)
16379 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16380}
16381
2f6ecaed
NA
16382/* Dump one CTF archive member. */
16383
80b56fad
NA
16384static void
16385dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16386 size_t member)
2f6ecaed 16387{
2f6ecaed
NA
16388 const char *things[] = {"Header", "Labels", "Data objects",
16389 "Function objects", "Variables", "Types", "Strings",
16390 ""};
16391 const char **thing;
16392 size_t i;
16393
80b56fad
NA
16394 /* Don't print out the name of the default-named archive member if it appears
16395 first in the list. The name .ctf appears everywhere, even for things that
16396 aren't really archives, so printing it out is liable to be confusing; also,
16397 the common case by far is for only one archive member to exist, and hiding
16398 it in that case seems worthwhile. */
2f6ecaed 16399
80b56fad
NA
16400 if (strcmp (name, ".ctf") != 0 || member != 0)
16401 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16402
80b56fad
NA
16403 if (ctf_parent_name (ctf) != NULL)
16404 ctf_import (ctf, parent);
2f6ecaed
NA
16405
16406 for (i = 0, thing = things; *thing[0]; thing++, i++)
16407 {
16408 ctf_dump_state_t *s = NULL;
16409 char *item;
16410
16411 printf ("\n %s:\n", *thing);
16412 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16413 (void *) " ")) != NULL)
16414 {
16415 printf ("%s\n", item);
16416 free (item);
16417 }
16418
16419 if (ctf_errno (ctf))
16420 {
16421 error (_("Iteration failed: %s, %s\n"), *thing,
16422 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16423 break;
2f6ecaed
NA
16424 }
16425 }
8b37e7b6 16426
926c9e76 16427 dump_ctf_errs (ctf);
2f6ecaed
NA
16428}
16429
015dc7e1 16430static bool
7d9813f1
NA
16431dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16432{
7d9813f1
NA
16433 Elf_Internal_Shdr * symtab_sec = NULL;
16434 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16435 void * data = NULL;
16436 void * symdata = NULL;
16437 void * strdata = NULL;
80b56fad 16438 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16439 ctf_sect_t * symsectp = NULL;
16440 ctf_sect_t * strsectp = NULL;
2f6ecaed 16441 ctf_archive_t * ctfa = NULL;
139633c3 16442 ctf_dict_t * parent = NULL;
80b56fad 16443 ctf_dict_t * fp;
7d9813f1 16444
80b56fad
NA
16445 ctf_next_t *i = NULL;
16446 const char *name;
16447 size_t member = 0;
7d9813f1 16448 int err;
015dc7e1 16449 bool ret = false;
7d9813f1
NA
16450
16451 shdr_to_ctf_sect (&ctfsect, section, filedata);
16452 data = get_section_contents (section, filedata);
16453 ctfsect.cts_data = data;
16454
616febde 16455 if (!dump_ctf_symtab_name)
3d16b64e 16456 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16457
16458 if (!dump_ctf_strtab_name)
3d16b64e 16459 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16460
16461 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16462 {
16463 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16464 {
16465 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16466 goto fail;
16467 }
16468 if ((symdata = (void *) get_data (NULL, filedata,
16469 symtab_sec->sh_offset, 1,
16470 symtab_sec->sh_size,
16471 _("symbols"))) == NULL)
16472 goto fail;
16473 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16474 symsect.cts_data = symdata;
16475 }
835f2fae 16476
df16e041 16477 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16478 {
16479 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16480 {
16481 error (_("No string table section named %s\n"),
16482 dump_ctf_strtab_name);
16483 goto fail;
16484 }
16485 if ((strdata = (void *) get_data (NULL, filedata,
16486 strtab_sec->sh_offset, 1,
16487 strtab_sec->sh_size,
16488 _("strings"))) == NULL)
16489 goto fail;
16490 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16491 strsect.cts_data = strdata;
16492 }
835f2fae 16493
2f6ecaed
NA
16494 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16495 libctf papers over the difference, so we can pretend it is always an
80b56fad 16496 archive. */
7d9813f1 16497
2f6ecaed 16498 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16499 {
926c9e76 16500 dump_ctf_errs (NULL);
7d9813f1
NA
16501 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16502 goto fail;
16503 }
16504
96c61be5
NA
16505 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16506 != ELFDATA2MSB);
16507
80b56fad
NA
16508 /* Preload the parent dict, since it will need to be imported into every
16509 child in turn. */
16510 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16511 {
926c9e76 16512 dump_ctf_errs (NULL);
2f6ecaed
NA
16513 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16514 goto fail;
7d9813f1
NA
16515 }
16516
015dc7e1 16517 ret = true;
7d9813f1 16518
835f2fae
NC
16519 if (filedata->is_separate)
16520 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16521 printable_section_name (filedata, section),
16522 filedata->file_name);
16523 else
16524 printf (_("\nDump of CTF section '%s':\n"),
16525 printable_section_name (filedata, section));
7d9813f1 16526
80b56fad
NA
16527 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16528 dump_ctf_archive_member (fp, name, parent, member++);
16529 if (err != ECTF_NEXT_END)
16530 {
16531 dump_ctf_errs (NULL);
16532 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16533 ret = false;
16534 }
7d9813f1
NA
16535
16536 fail:
139633c3 16537 ctf_dict_close (parent);
2f6ecaed 16538 ctf_close (ctfa);
7d9813f1
NA
16539 free (data);
16540 free (symdata);
16541 free (strdata);
16542 return ret;
16543}
094e34f2 16544#endif
7d9813f1 16545
42b6953b
IB
16546static bool
16547dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16548{
16549 void * data = NULL;
16550 sframe_decoder_ctx *sfd_ctx = NULL;
16551 const char *print_name = printable_section_name (filedata, section);
16552
16553 bool ret = true;
16554 size_t sf_size;
16555 int err = 0;
16556
16557 if (strcmp (print_name, "") == 0)
16558 {
16559 error (_("Section name must be provided \n"));
16560 ret = false;
16561 return ret;
16562 }
16563
16564 data = get_section_contents (section, filedata);
16565 sf_size = section->sh_size;
16566 /* Decode the contents of the section. */
16567 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16568 if (!sfd_ctx)
16569 {
16570 ret = false;
16571 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16572 goto fail;
16573 }
16574
16575 printf (_("Contents of the SFrame section %s:"), print_name);
16576 /* Dump the contents as text. */
16577 dump_sframe (sfd_ctx, section->sh_addr);
16578
16579 fail:
16580 free (data);
16581 return ret;
16582}
16583
015dc7e1 16584static bool
dda8d76d
NC
16585load_specific_debug_section (enum dwarf_section_display_enum debug,
16586 const Elf_Internal_Shdr * sec,
16587 void * data)
1007acb3 16588{
2cf0635d 16589 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16590 char buf [64];
dda8d76d 16591 Filedata * filedata = (Filedata *) data;
9abca702 16592
19e6b90e 16593 if (section->start != NULL)
dda8d76d
NC
16594 {
16595 /* If it is already loaded, do nothing. */
16596 if (streq (section->filename, filedata->file_name))
015dc7e1 16597 return true;
dda8d76d
NC
16598 free (section->start);
16599 }
1007acb3 16600
19e6b90e
L
16601 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16602 section->address = sec->sh_addr;
dda8d76d
NC
16603 section->filename = filedata->file_name;
16604 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16605 sec->sh_offset, 1,
16606 sec->sh_size, buf);
59245841
NC
16607 if (section->start == NULL)
16608 section->size = 0;
16609 else
16610 {
77115a4a 16611 unsigned char *start = section->start;
31e5a3a3
AM
16612 uint64_t size = sec->sh_size;
16613 uint64_t uncompressed_size = 0;
1f5a3546 16614 bool is_zstd = false;
77115a4a
L
16615
16616 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16617 {
16618 Elf_Internal_Chdr chdr;
d8024a91
NC
16619 unsigned int compression_header_size;
16620
f53be977
L
16621 if (size < (is_32bit_elf
16622 ? sizeof (Elf32_External_Chdr)
16623 : sizeof (Elf64_External_Chdr)))
d8024a91 16624 {
55be8fd0 16625 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16626 section->name);
015dc7e1 16627 return false;
d8024a91
NC
16628 }
16629
ebdf1ebf 16630 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16631 if (compression_header_size == 0)
16632 /* An error message will have already been generated
16633 by get_compression_header. */
015dc7e1 16634 return false;
d8024a91 16635
89dbeac7 16636 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16637 ;
16638#ifdef HAVE_ZSTD
89dbeac7 16639 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16640 is_zstd = true;
16641#endif
16642 else
813dabb9
L
16643 {
16644 warn (_("section '%s' has unsupported compress type: %d\n"),
16645 section->name, chdr.ch_type);
015dc7e1 16646 return false;
813dabb9 16647 }
dab394de 16648 uncompressed_size = chdr.ch_size;
77115a4a
L
16649 start += compression_header_size;
16650 size -= compression_header_size;
16651 }
dab394de
L
16652 else if (size > 12 && streq ((char *) start, "ZLIB"))
16653 {
16654 /* Read the zlib header. In this case, it should be "ZLIB"
16655 followed by the uncompressed section size, 8 bytes in
16656 big-endian order. */
16657 uncompressed_size = start[4]; uncompressed_size <<= 8;
16658 uncompressed_size += start[5]; uncompressed_size <<= 8;
16659 uncompressed_size += start[6]; uncompressed_size <<= 8;
16660 uncompressed_size += start[7]; uncompressed_size <<= 8;
16661 uncompressed_size += start[8]; uncompressed_size <<= 8;
16662 uncompressed_size += start[9]; uncompressed_size <<= 8;
16663 uncompressed_size += start[10]; uncompressed_size <<= 8;
16664 uncompressed_size += start[11];
16665 start += 12;
16666 size -= 12;
16667 }
16668
1835f746 16669 if (uncompressed_size)
77115a4a 16670 {
1f5a3546 16671 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16672 &size, filedata->file_size))
1835f746
NC
16673 {
16674 /* Free the compressed buffer, update the section buffer
16675 and the section size if uncompress is successful. */
16676 free (section->start);
16677 section->start = start;
16678 }
16679 else
16680 {
16681 error (_("Unable to decompress section %s\n"),
dda8d76d 16682 printable_section_name (filedata, sec));
015dc7e1 16683 return false;
1835f746 16684 }
77115a4a 16685 }
bc303e5d 16686
77115a4a 16687 section->size = size;
59245841 16688 }
4a114e3e 16689
1b315056 16690 if (section->start == NULL)
015dc7e1 16691 return false;
1b315056 16692
19e6b90e 16693 if (debug_displays [debug].relocate)
32ec8896 16694 {
dda8d76d 16695 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16696 & section->reloc_info, & section->num_relocs))
015dc7e1 16697 return false;
32ec8896 16698 }
d1c4b12b
NC
16699 else
16700 {
16701 section->reloc_info = NULL;
16702 section->num_relocs = 0;
16703 }
1007acb3 16704
015dc7e1 16705 return true;
1007acb3
L
16706}
16707
301a9420
AM
16708#if HAVE_LIBDEBUGINFOD
16709/* Return a hex string representation of the build-id. */
16710unsigned char *
16711get_build_id (void * data)
16712{
ca0e11aa 16713 Filedata * filedata = (Filedata *) data;
301a9420 16714 Elf_Internal_Shdr * shdr;
26c527e6 16715 size_t i;
301a9420 16716
55be8fd0
NC
16717 /* Iterate through notes to find note.gnu.build-id.
16718 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16719 for (i = 0, shdr = filedata->section_headers;
16720 i < filedata->file_header.e_shnum && shdr != NULL;
16721 i++, shdr++)
16722 {
16723 if (shdr->sh_type != SHT_NOTE)
16724 continue;
16725
16726 char * next;
16727 char * end;
16728 size_t data_remaining;
16729 size_t min_notesz;
16730 Elf_External_Note * enote;
16731 Elf_Internal_Note inote;
16732
625d49fc
AM
16733 uint64_t offset = shdr->sh_offset;
16734 uint64_t align = shdr->sh_addralign;
16735 uint64_t length = shdr->sh_size;
301a9420
AM
16736
16737 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16738 if (enote == NULL)
16739 continue;
16740
16741 if (align < 4)
16742 align = 4;
16743 else if (align != 4 && align != 8)
f761cb13
AM
16744 {
16745 free (enote);
16746 continue;
16747 }
301a9420
AM
16748
16749 end = (char *) enote + length;
16750 data_remaining = end - (char *) enote;
16751
16752 if (!is_ia64_vms (filedata))
16753 {
16754 min_notesz = offsetof (Elf_External_Note, name);
16755 if (data_remaining < min_notesz)
16756 {
55be8fd0
NC
16757 warn (_("\
16758malformed note encountered in section %s whilst scanning for build-id note\n"),
16759 printable_section_name (filedata, shdr));
f761cb13 16760 free (enote);
55be8fd0 16761 continue;
301a9420
AM
16762 }
16763 data_remaining -= min_notesz;
16764
16765 inote.type = BYTE_GET (enote->type);
16766 inote.namesz = BYTE_GET (enote->namesz);
16767 inote.namedata = enote->name;
16768 inote.descsz = BYTE_GET (enote->descsz);
16769 inote.descdata = ((char *) enote
16770 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16771 inote.descpos = offset + (inote.descdata - (char *) enote);
16772 next = ((char *) enote
16773 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16774 }
16775 else
16776 {
16777 Elf64_External_VMS_Note *vms_enote;
16778
16779 /* PR binutils/15191
16780 Make sure that there is enough data to read. */
16781 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16782 if (data_remaining < min_notesz)
16783 {
55be8fd0
NC
16784 warn (_("\
16785malformed note encountered in section %s whilst scanning for build-id note\n"),
16786 printable_section_name (filedata, shdr));
f761cb13 16787 free (enote);
55be8fd0 16788 continue;
301a9420
AM
16789 }
16790 data_remaining -= min_notesz;
16791
16792 vms_enote = (Elf64_External_VMS_Note *) enote;
16793 inote.type = BYTE_GET (vms_enote->type);
16794 inote.namesz = BYTE_GET (vms_enote->namesz);
16795 inote.namedata = vms_enote->name;
16796 inote.descsz = BYTE_GET (vms_enote->descsz);
16797 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16798 inote.descpos = offset + (inote.descdata - (char *) enote);
16799 next = inote.descdata + align_power (inote.descsz, 3);
16800 }
16801
16802 /* Skip malformed notes. */
16803 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16804 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16805 || (size_t) (next - inote.descdata) < inote.descsz
16806 || ((size_t) (next - inote.descdata)
16807 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16808 {
55be8fd0
NC
16809 warn (_("\
16810malformed note encountered in section %s whilst scanning for build-id note\n"),
16811 printable_section_name (filedata, shdr));
f761cb13 16812 free (enote);
301a9420
AM
16813 continue;
16814 }
16815
16816 /* Check if this is the build-id note. If so then convert the build-id
16817 bytes to a hex string. */
16818 if (inote.namesz > 0
24d127aa 16819 && startswith (inote.namedata, "GNU")
301a9420
AM
16820 && inote.type == NT_GNU_BUILD_ID)
16821 {
26c527e6 16822 size_t j;
301a9420
AM
16823 char * build_id;
16824
16825 build_id = malloc (inote.descsz * 2 + 1);
16826 if (build_id == NULL)
f761cb13
AM
16827 {
16828 free (enote);
16829 return NULL;
16830 }
301a9420
AM
16831
16832 for (j = 0; j < inote.descsz; ++j)
16833 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16834 build_id[inote.descsz * 2] = '\0';
f761cb13 16835 free (enote);
301a9420 16836
55be8fd0 16837 return (unsigned char *) build_id;
301a9420 16838 }
f761cb13 16839 free (enote);
301a9420
AM
16840 }
16841
16842 return NULL;
16843}
16844#endif /* HAVE_LIBDEBUGINFOD */
16845
657d0d47
CC
16846/* If this is not NULL, load_debug_section will only look for sections
16847 within the list of sections given here. */
32ec8896 16848static unsigned int * section_subset = NULL;
657d0d47 16849
015dc7e1 16850bool
dda8d76d 16851load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 16852{
2cf0635d
NC
16853 struct dwarf_section * section = &debug_displays [debug].section;
16854 Elf_Internal_Shdr * sec;
dda8d76d
NC
16855 Filedata * filedata = (Filedata *) data;
16856
e1dbfc17
L
16857 if (!dump_any_debugging)
16858 return false;
16859
f425ec66
NC
16860 /* Without section headers we cannot find any sections. */
16861 if (filedata->section_headers == NULL)
015dc7e1 16862 return false;
f425ec66 16863
9c1ce108
AM
16864 if (filedata->string_table == NULL
16865 && filedata->file_header.e_shstrndx != SHN_UNDEF
16866 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
16867 {
16868 Elf_Internal_Shdr * strs;
16869
16870 /* Read in the string table, so that we have section names to scan. */
16871 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
16872
4dff97b2 16873 if (strs != NULL && strs->sh_size != 0)
dda8d76d 16874 {
9c1ce108
AM
16875 filedata->string_table
16876 = (char *) get_data (NULL, filedata, strs->sh_offset,
16877 1, strs->sh_size, _("string table"));
dda8d76d 16878
9c1ce108
AM
16879 filedata->string_table_length
16880 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
16881 }
16882 }
d966045b
DJ
16883
16884 /* Locate the debug section. */
dda8d76d 16885 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
16886 if (sec != NULL)
16887 section->name = section->uncompressed_name;
16888 else
16889 {
dda8d76d 16890 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
16891 if (sec != NULL)
16892 section->name = section->compressed_name;
16893 }
16894 if (sec == NULL)
015dc7e1 16895 return false;
d966045b 16896
657d0d47
CC
16897 /* If we're loading from a subset of sections, and we've loaded
16898 a section matching this name before, it's likely that it's a
16899 different one. */
16900 if (section_subset != NULL)
16901 free_debug_section (debug);
16902
dda8d76d 16903 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
16904}
16905
19e6b90e
L
16906void
16907free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 16908{
2cf0635d 16909 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 16910
19e6b90e
L
16911 if (section->start == NULL)
16912 return;
1007acb3 16913
19e6b90e
L
16914 free ((char *) section->start);
16915 section->start = NULL;
16916 section->address = 0;
16917 section->size = 0;
a788aedd 16918
9db70fc3
AM
16919 free (section->reloc_info);
16920 section->reloc_info = NULL;
16921 section->num_relocs = 0;
1007acb3
L
16922}
16923
015dc7e1 16924static bool
dda8d76d 16925display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16926{
84714f86
AM
16927 const char *name = (section_name_valid (filedata, section)
16928 ? section_name (filedata, section) : "");
16929 const char *print_name = printable_section_name (filedata, section);
be7d229a 16930 uint64_t length;
015dc7e1 16931 bool result = true;
3f5e193b 16932 int i;
1007acb3 16933
19e6b90e
L
16934 length = section->sh_size;
16935 if (length == 0)
1007acb3 16936 {
74e1a04b 16937 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16938 return true;
1007acb3 16939 }
5dff79d8
NC
16940 if (section->sh_type == SHT_NOBITS)
16941 {
16942 /* There is no point in dumping the contents of a debugging section
16943 which has the NOBITS type - the bits in the file will be random.
16944 This can happen when a file containing a .eh_frame section is
16945 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16946 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16947 print_name);
015dc7e1 16948 return false;
5dff79d8 16949 }
1007acb3 16950
24d127aa 16951 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16952 name = ".debug_info";
1007acb3 16953
19e6b90e
L
16954 /* See if we know how to display the contents of this section. */
16955 for (i = 0; i < max; i++)
d85bf2ba
NC
16956 {
16957 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16958 struct dwarf_section_display * display = debug_displays + i;
16959 struct dwarf_section * sec = & display->section;
d966045b 16960
d85bf2ba 16961 if (streq (sec->uncompressed_name, name)
24d127aa 16962 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16963 || streq (sec->compressed_name, name))
16964 {
015dc7e1 16965 bool secondary = (section != find_section (filedata, name));
1007acb3 16966
d85bf2ba
NC
16967 if (secondary)
16968 free_debug_section (id);
dda8d76d 16969
24d127aa 16970 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16971 sec->name = name;
16972 else if (streq (sec->uncompressed_name, name))
16973 sec->name = sec->uncompressed_name;
16974 else
16975 sec->name = sec->compressed_name;
657d0d47 16976
d85bf2ba
NC
16977 if (load_specific_debug_section (id, section, filedata))
16978 {
16979 /* If this debug section is part of a CU/TU set in a .dwp file,
16980 restrict load_debug_section to the sections in that set. */
16981 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16982
d85bf2ba 16983 result &= display->display (sec, filedata);
657d0d47 16984
d85bf2ba 16985 section_subset = NULL;
1007acb3 16986
44266f36 16987 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16988 free_debug_section (id);
16989 }
16990 break;
16991 }
16992 }
1007acb3 16993
19e6b90e 16994 if (i == max)
1007acb3 16995 {
74e1a04b 16996 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16997 result = false;
1007acb3
L
16998 }
16999
19e6b90e 17000 return result;
5b18a4bc 17001}
103f02d3 17002
aef1f6d0
DJ
17003/* Set DUMP_SECTS for all sections where dumps were requested
17004 based on section name. */
17005
17006static void
dda8d76d 17007initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17008{
2cf0635d 17009 struct dump_list_entry * cur;
aef1f6d0
DJ
17010
17011 for (cur = dump_sects_byname; cur; cur = cur->next)
17012 {
17013 unsigned int i;
015dc7e1 17014 bool any = false;
aef1f6d0 17015
dda8d76d 17016 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17017 if (section_name_valid (filedata, filedata->section_headers + i)
17018 && streq (section_name (filedata, filedata->section_headers + i),
17019 cur->name))
aef1f6d0 17020 {
6431e409 17021 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17022 any = true;
aef1f6d0
DJ
17023 }
17024
835f2fae
NC
17025 if (!any && !filedata->is_separate)
17026 warn (_("Section '%s' was not dumped because it does not exist\n"),
17027 cur->name);
aef1f6d0
DJ
17028 }
17029}
17030
015dc7e1 17031static bool
dda8d76d 17032process_section_contents (Filedata * filedata)
5b18a4bc 17033{
2cf0635d 17034 Elf_Internal_Shdr * section;
19e6b90e 17035 unsigned int i;
015dc7e1 17036 bool res = true;
103f02d3 17037
19e6b90e 17038 if (! do_dump)
015dc7e1 17039 return true;
103f02d3 17040
dda8d76d 17041 initialise_dumps_byname (filedata);
aef1f6d0 17042
dda8d76d 17043 for (i = 0, section = filedata->section_headers;
6431e409 17044 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17045 i++, section++)
17046 {
6431e409 17047 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17048
d6bfbc39
NC
17049 if (filedata->is_separate && ! process_links)
17050 dump &= DEBUG_DUMP;
047c3dbf 17051
19e6b90e 17052#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17053 if (dump & DISASS_DUMP)
17054 {
17055 if (! disassemble_section (section, filedata))
015dc7e1 17056 res = false;
dda8d76d 17057 }
19e6b90e 17058#endif
dda8d76d 17059 if (dump & HEX_DUMP)
32ec8896 17060 {
015dc7e1
AM
17061 if (! dump_section_as_bytes (section, filedata, false))
17062 res = false;
32ec8896 17063 }
103f02d3 17064
dda8d76d 17065 if (dump & RELOC_DUMP)
32ec8896 17066 {
015dc7e1
AM
17067 if (! dump_section_as_bytes (section, filedata, true))
17068 res = false;
32ec8896 17069 }
09c11c86 17070
dda8d76d 17071 if (dump & STRING_DUMP)
32ec8896 17072 {
dda8d76d 17073 if (! dump_section_as_strings (section, filedata))
015dc7e1 17074 res = false;
32ec8896 17075 }
cf13d699 17076
dda8d76d 17077 if (dump & DEBUG_DUMP)
32ec8896 17078 {
dda8d76d 17079 if (! display_debug_section (i, section, filedata))
015dc7e1 17080 res = false;
32ec8896 17081 }
7d9813f1 17082
094e34f2 17083#ifdef ENABLE_LIBCTF
7d9813f1
NA
17084 if (dump & CTF_DUMP)
17085 {
17086 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17087 res = false;
7d9813f1 17088 }
094e34f2 17089#endif
42b6953b
IB
17090 if (dump & SFRAME_DUMP)
17091 {
17092 if (! dump_section_as_sframe (section, filedata))
17093 res = false;
17094 }
5b18a4bc 17095 }
103f02d3 17096
835f2fae 17097 if (! filedata->is_separate)
0ee3043f 17098 {
835f2fae
NC
17099 /* Check to see if the user requested a
17100 dump of a section that does not exist. */
17101 for (; i < filedata->dump.num_dump_sects; i++)
17102 if (filedata->dump.dump_sects[i])
17103 {
ca0e11aa 17104 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17105 res = false;
835f2fae 17106 }
0ee3043f 17107 }
32ec8896
NC
17108
17109 return res;
5b18a4bc 17110}
103f02d3 17111
5b18a4bc 17112static void
19e6b90e 17113process_mips_fpe_exception (int mask)
5b18a4bc 17114{
19e6b90e
L
17115 if (mask)
17116 {
015dc7e1 17117 bool first = true;
32ec8896 17118
19e6b90e 17119 if (mask & OEX_FPU_INEX)
015dc7e1 17120 fputs ("INEX", stdout), first = false;
19e6b90e 17121 if (mask & OEX_FPU_UFLO)
015dc7e1 17122 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17123 if (mask & OEX_FPU_OFLO)
015dc7e1 17124 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17125 if (mask & OEX_FPU_DIV0)
015dc7e1 17126 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17127 if (mask & OEX_FPU_INVAL)
17128 printf ("%sINVAL", first ? "" : "|");
17129 }
5b18a4bc 17130 else
19e6b90e 17131 fputs ("0", stdout);
5b18a4bc 17132}
103f02d3 17133
f6f0e17b
NC
17134/* Display's the value of TAG at location P. If TAG is
17135 greater than 0 it is assumed to be an unknown tag, and
17136 a message is printed to this effect. Otherwise it is
17137 assumed that a message has already been printed.
17138
17139 If the bottom bit of TAG is set it assumed to have a
17140 string value, otherwise it is assumed to have an integer
17141 value.
17142
17143 Returns an updated P pointing to the first unread byte
17144 beyond the end of TAG's value.
17145
17146 Reads at or beyond END will not be made. */
17147
17148static unsigned char *
60abdbed 17149display_tag_value (signed int tag,
f6f0e17b
NC
17150 unsigned char * p,
17151 const unsigned char * const end)
17152{
26c527e6 17153 uint64_t val;
f6f0e17b
NC
17154
17155 if (tag > 0)
17156 printf (" Tag_unknown_%d: ", tag);
17157
17158 if (p >= end)
17159 {
4082ef84 17160 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17161 }
17162 else if (tag & 1)
17163 {
071436c6
NC
17164 /* PR 17531 file: 027-19978-0.004. */
17165 size_t maxlen = (end - p) - 1;
17166
17167 putchar ('"');
4082ef84
NC
17168 if (maxlen > 0)
17169 {
b6ac461a 17170 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17171 p += strnlen ((char *) p, maxlen) + 1;
17172 }
17173 else
17174 {
17175 printf (_("<corrupt string tag>"));
17176 p = (unsigned char *) end;
17177 }
071436c6 17178 printf ("\"\n");
f6f0e17b
NC
17179 }
17180 else
17181 {
cd30bcef 17182 READ_ULEB (val, p, end);
26c527e6 17183 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17184 }
17185
4082ef84 17186 assert (p <= end);
f6f0e17b
NC
17187 return p;
17188}
17189
53a346d8
CZ
17190/* ARC ABI attributes section. */
17191
17192static unsigned char *
17193display_arc_attribute (unsigned char * p,
17194 const unsigned char * const end)
17195{
17196 unsigned int tag;
53a346d8
CZ
17197 unsigned int val;
17198
cd30bcef 17199 READ_ULEB (tag, p, end);
53a346d8
CZ
17200
17201 switch (tag)
17202 {
17203 case Tag_ARC_PCS_config:
cd30bcef 17204 READ_ULEB (val, p, end);
53a346d8
CZ
17205 printf (" Tag_ARC_PCS_config: ");
17206 switch (val)
17207 {
17208 case 0:
17209 printf (_("Absent/Non standard\n"));
17210 break;
17211 case 1:
17212 printf (_("Bare metal/mwdt\n"));
17213 break;
17214 case 2:
17215 printf (_("Bare metal/newlib\n"));
17216 break;
17217 case 3:
17218 printf (_("Linux/uclibc\n"));
17219 break;
17220 case 4:
17221 printf (_("Linux/glibc\n"));
17222 break;
17223 default:
17224 printf (_("Unknown\n"));
17225 break;
17226 }
17227 break;
17228
17229 case Tag_ARC_CPU_base:
cd30bcef 17230 READ_ULEB (val, p, end);
53a346d8
CZ
17231 printf (" Tag_ARC_CPU_base: ");
17232 switch (val)
17233 {
17234 default:
17235 case TAG_CPU_NONE:
17236 printf (_("Absent\n"));
17237 break;
17238 case TAG_CPU_ARC6xx:
17239 printf ("ARC6xx\n");
17240 break;
17241 case TAG_CPU_ARC7xx:
17242 printf ("ARC7xx\n");
17243 break;
17244 case TAG_CPU_ARCEM:
17245 printf ("ARCEM\n");
17246 break;
17247 case TAG_CPU_ARCHS:
17248 printf ("ARCHS\n");
17249 break;
17250 }
17251 break;
17252
17253 case Tag_ARC_CPU_variation:
cd30bcef 17254 READ_ULEB (val, p, end);
53a346d8
CZ
17255 printf (" Tag_ARC_CPU_variation: ");
17256 switch (val)
17257 {
17258 default:
17259 if (val > 0 && val < 16)
53a346d8 17260 printf ("Core%d\n", val);
d8cbc93b
JL
17261 else
17262 printf ("Unknown\n");
17263 break;
17264
53a346d8
CZ
17265 case 0:
17266 printf (_("Absent\n"));
17267 break;
17268 }
17269 break;
17270
17271 case Tag_ARC_CPU_name:
17272 printf (" Tag_ARC_CPU_name: ");
17273 p = display_tag_value (-1, p, end);
17274 break;
17275
17276 case Tag_ARC_ABI_rf16:
cd30bcef 17277 READ_ULEB (val, p, end);
53a346d8
CZ
17278 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17279 break;
17280
17281 case Tag_ARC_ABI_osver:
cd30bcef 17282 READ_ULEB (val, p, end);
53a346d8
CZ
17283 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17284 break;
17285
17286 case Tag_ARC_ABI_pic:
17287 case Tag_ARC_ABI_sda:
cd30bcef 17288 READ_ULEB (val, p, end);
53a346d8
CZ
17289 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17290 : " Tag_ARC_ABI_pic: ");
17291 switch (val)
17292 {
17293 case 0:
17294 printf (_("Absent\n"));
17295 break;
17296 case 1:
17297 printf ("MWDT\n");
17298 break;
17299 case 2:
17300 printf ("GNU\n");
17301 break;
17302 default:
17303 printf (_("Unknown\n"));
17304 break;
17305 }
17306 break;
17307
17308 case Tag_ARC_ABI_tls:
cd30bcef 17309 READ_ULEB (val, p, end);
53a346d8
CZ
17310 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17311 break;
17312
17313 case Tag_ARC_ABI_enumsize:
cd30bcef 17314 READ_ULEB (val, p, end);
53a346d8
CZ
17315 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17316 _("smallest"));
17317 break;
17318
17319 case Tag_ARC_ABI_exceptions:
cd30bcef 17320 READ_ULEB (val, p, end);
53a346d8
CZ
17321 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17322 : _("default"));
17323 break;
17324
17325 case Tag_ARC_ABI_double_size:
cd30bcef 17326 READ_ULEB (val, p, end);
53a346d8
CZ
17327 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17328 break;
17329
17330 case Tag_ARC_ISA_config:
17331 printf (" Tag_ARC_ISA_config: ");
17332 p = display_tag_value (-1, p, end);
17333 break;
17334
17335 case Tag_ARC_ISA_apex:
17336 printf (" Tag_ARC_ISA_apex: ");
17337 p = display_tag_value (-1, p, end);
17338 break;
17339
17340 case Tag_ARC_ISA_mpy_option:
cd30bcef 17341 READ_ULEB (val, p, end);
53a346d8
CZ
17342 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17343 break;
17344
db1e1b45 17345 case Tag_ARC_ATR_version:
cd30bcef 17346 READ_ULEB (val, p, end);
db1e1b45 17347 printf (" Tag_ARC_ATR_version: %d\n", val);
17348 break;
17349
53a346d8
CZ
17350 default:
17351 return display_tag_value (tag & 1, p, end);
17352 }
17353
17354 return p;
17355}
17356
11c1ff18
PB
17357/* ARM EABI attributes section. */
17358typedef struct
17359{
70e99720 17360 unsigned int tag;
2cf0635d 17361 const char * name;
11c1ff18 17362 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17363 unsigned int type;
288f0ba2 17364 const char *const *table;
11c1ff18
PB
17365} arm_attr_public_tag;
17366
288f0ba2 17367static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17368 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17369 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17370 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17371 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17372static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17373static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17374 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17375static const char *const arm_attr_tag_FP_arch[] =
bca38921 17376 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17377 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17378static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17379static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17380 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17381 "NEON for ARMv8.1"};
288f0ba2 17382static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17383 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17384 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17385static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17386 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17387static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17388 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17389static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17390 {"Absolute", "PC-relative", "None"};
288f0ba2 17391static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17392 {"None", "direct", "GOT-indirect"};
288f0ba2 17393static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17394 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17395static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17396static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17397 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17398static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17399static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17400static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17401 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17402static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17403 {"Unused", "small", "int", "forced to int"};
288f0ba2 17404static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17405 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17406static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17407 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17408static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17409 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17410static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17411 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17412 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17413static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17414 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17415 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17416static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17417static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17418 {"Not Allowed", "Allowed"};
288f0ba2 17419static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17420 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17421static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17422 {"Follow architecture", "Allowed"};
288f0ba2 17423static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17424 {"Not Allowed", "Allowed"};
288f0ba2 17425static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17426 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17427 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17428static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17429static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17430 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17431 "TrustZone and Virtualization Extensions"};
288f0ba2 17432static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17433 {"Not Allowed", "Allowed"};
11c1ff18 17434
288f0ba2 17435static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17436 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17437
99db83d0
AC
17438static const char * arm_attr_tag_PAC_extension[] =
17439 {"No PAC/AUT instructions",
17440 "PAC/AUT instructions permitted in the NOP space",
17441 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17442
4b535030
AC
17443static const char * arm_attr_tag_BTI_extension[] =
17444 {"BTI instructions not permitted",
17445 "BTI instructions permitted in the NOP space",
17446 "BTI instructions permitted in the NOP and in the non-NOP space"};
17447
b81ee92f
AC
17448static const char * arm_attr_tag_BTI_use[] =
17449 {"Compiled without branch target enforcement",
17450 "Compiled with branch target enforcement"};
17451
c9fed665
AC
17452static const char * arm_attr_tag_PACRET_use[] =
17453 {"Compiled without return address signing and authentication",
17454 "Compiled with return address signing and authentication"};
17455
11c1ff18
PB
17456#define LOOKUP(id, name) \
17457 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17458static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17459{
17460 {4, "CPU_raw_name", 1, NULL},
17461 {5, "CPU_name", 1, NULL},
17462 LOOKUP(6, CPU_arch),
17463 {7, "CPU_arch_profile", 0, NULL},
17464 LOOKUP(8, ARM_ISA_use),
17465 LOOKUP(9, THUMB_ISA_use),
75375b3e 17466 LOOKUP(10, FP_arch),
11c1ff18 17467 LOOKUP(11, WMMX_arch),
f5f53991
AS
17468 LOOKUP(12, Advanced_SIMD_arch),
17469 LOOKUP(13, PCS_config),
11c1ff18
PB
17470 LOOKUP(14, ABI_PCS_R9_use),
17471 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17472 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17473 LOOKUP(17, ABI_PCS_GOT_use),
17474 LOOKUP(18, ABI_PCS_wchar_t),
17475 LOOKUP(19, ABI_FP_rounding),
17476 LOOKUP(20, ABI_FP_denormal),
17477 LOOKUP(21, ABI_FP_exceptions),
17478 LOOKUP(22, ABI_FP_user_exceptions),
17479 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17480 {24, "ABI_align_needed", 0, NULL},
17481 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17482 LOOKUP(26, ABI_enum_size),
17483 LOOKUP(27, ABI_HardFP_use),
17484 LOOKUP(28, ABI_VFP_args),
17485 LOOKUP(29, ABI_WMMX_args),
17486 LOOKUP(30, ABI_optimization_goals),
17487 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17488 {32, "compatibility", 0, NULL},
f5f53991 17489 LOOKUP(34, CPU_unaligned_access),
75375b3e 17490 LOOKUP(36, FP_HP_extension),
8e79c3df 17491 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17492 LOOKUP(42, MPextension_use),
17493 LOOKUP(44, DIV_use),
15afaa63 17494 LOOKUP(46, DSP_extension),
a7ad558c 17495 LOOKUP(48, MVE_arch),
99db83d0 17496 LOOKUP(50, PAC_extension),
4b535030 17497 LOOKUP(52, BTI_extension),
b81ee92f 17498 LOOKUP(74, BTI_use),
c9fed665 17499 LOOKUP(76, PACRET_use),
f5f53991
AS
17500 {64, "nodefaults", 0, NULL},
17501 {65, "also_compatible_with", 0, NULL},
17502 LOOKUP(66, T2EE_use),
17503 {67, "conformance", 1, NULL},
17504 LOOKUP(68, Virtualization_use),
cd21e546 17505 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17506};
17507#undef LOOKUP
17508
11c1ff18 17509static unsigned char *
f6f0e17b
NC
17510display_arm_attribute (unsigned char * p,
17511 const unsigned char * const end)
11c1ff18 17512{
70e99720 17513 unsigned int tag;
70e99720 17514 unsigned int val;
2cf0635d 17515 arm_attr_public_tag * attr;
11c1ff18 17516 unsigned i;
70e99720 17517 unsigned int type;
11c1ff18 17518
cd30bcef 17519 READ_ULEB (tag, p, end);
11c1ff18 17520 attr = NULL;
2cf0635d 17521 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17522 {
17523 if (arm_attr_public_tags[i].tag == tag)
17524 {
17525 attr = &arm_attr_public_tags[i];
17526 break;
17527 }
17528 }
17529
17530 if (attr)
17531 {
17532 printf (" Tag_%s: ", attr->name);
17533 switch (attr->type)
17534 {
17535 case 0:
17536 switch (tag)
17537 {
17538 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17539 READ_ULEB (val, p, end);
11c1ff18
PB
17540 switch (val)
17541 {
2b692964
NC
17542 case 0: printf (_("None\n")); break;
17543 case 'A': printf (_("Application\n")); break;
17544 case 'R': printf (_("Realtime\n")); break;
17545 case 'M': printf (_("Microcontroller\n")); break;
17546 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17547 default: printf ("??? (%d)\n", val); break;
17548 }
17549 break;
17550
75375b3e 17551 case 24: /* Tag_align_needed. */
cd30bcef 17552 READ_ULEB (val, p, end);
75375b3e
MGD
17553 switch (val)
17554 {
2b692964
NC
17555 case 0: printf (_("None\n")); break;
17556 case 1: printf (_("8-byte\n")); break;
17557 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17558 case 3: printf ("??? 3\n"); break;
17559 default:
17560 if (val <= 12)
dd24e3da 17561 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17562 1 << val);
17563 else
17564 printf ("??? (%d)\n", val);
17565 break;
17566 }
17567 break;
17568
17569 case 25: /* Tag_align_preserved. */
cd30bcef 17570 READ_ULEB (val, p, end);
75375b3e
MGD
17571 switch (val)
17572 {
2b692964
NC
17573 case 0: printf (_("None\n")); break;
17574 case 1: printf (_("8-byte, except leaf SP\n")); break;
17575 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17576 case 3: printf ("??? 3\n"); break;
17577 default:
17578 if (val <= 12)
dd24e3da 17579 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17580 1 << val);
17581 else
17582 printf ("??? (%d)\n", val);
17583 break;
17584 }
17585 break;
17586
11c1ff18 17587 case 32: /* Tag_compatibility. */
071436c6 17588 {
cd30bcef 17589 READ_ULEB (val, p, end);
071436c6 17590 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17591 if (p < end - 1)
17592 {
17593 size_t maxlen = (end - p) - 1;
17594
b6ac461a 17595 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17596 p += strnlen ((char *) p, maxlen) + 1;
17597 }
17598 else
17599 {
17600 printf (_("<corrupt>"));
17601 p = (unsigned char *) end;
17602 }
071436c6 17603 putchar ('\n');
071436c6 17604 }
11c1ff18
PB
17605 break;
17606
f5f53991 17607 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17608 /* PR 17531: file: 001-505008-0.01. */
17609 if (p < end)
17610 p++;
2b692964 17611 printf (_("True\n"));
f5f53991
AS
17612 break;
17613
17614 case 65: /* Tag_also_compatible_with. */
cd30bcef 17615 READ_ULEB (val, p, end);
f5f53991
AS
17616 if (val == 6 /* Tag_CPU_arch. */)
17617 {
cd30bcef 17618 READ_ULEB (val, p, end);
071436c6 17619 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17620 printf ("??? (%d)\n", val);
17621 else
17622 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17623 }
17624 else
17625 printf ("???\n");
071436c6
NC
17626 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17627 ;
f5f53991
AS
17628 break;
17629
11c1ff18 17630 default:
bee0ee85
NC
17631 printf (_("<unknown: %d>\n"), tag);
17632 break;
11c1ff18
PB
17633 }
17634 return p;
17635
17636 case 1:
f6f0e17b 17637 return display_tag_value (-1, p, end);
11c1ff18 17638 case 2:
f6f0e17b 17639 return display_tag_value (0, p, end);
11c1ff18
PB
17640
17641 default:
17642 assert (attr->type & 0x80);
cd30bcef 17643 READ_ULEB (val, p, end);
11c1ff18
PB
17644 type = attr->type & 0x7f;
17645 if (val >= type)
17646 printf ("??? (%d)\n", val);
17647 else
17648 printf ("%s\n", attr->table[val]);
17649 return p;
17650 }
17651 }
11c1ff18 17652
f6f0e17b 17653 return display_tag_value (tag, p, end);
11c1ff18
PB
17654}
17655
104d59d1 17656static unsigned char *
60bca95a 17657display_gnu_attribute (unsigned char * p,
60abdbed 17658 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17659 const unsigned char * const end)
104d59d1 17660{
cd30bcef 17661 unsigned int tag;
60abdbed 17662 unsigned int val;
104d59d1 17663
cd30bcef 17664 READ_ULEB (tag, p, end);
104d59d1
JM
17665
17666 /* Tag_compatibility is the only generic GNU attribute defined at
17667 present. */
17668 if (tag == 32)
17669 {
cd30bcef 17670 READ_ULEB (val, p, end);
071436c6
NC
17671
17672 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17673 if (p == end)
17674 {
071436c6 17675 printf (_("<corrupt>\n"));
f6f0e17b
NC
17676 warn (_("corrupt vendor attribute\n"));
17677 }
17678 else
17679 {
4082ef84
NC
17680 if (p < end - 1)
17681 {
17682 size_t maxlen = (end - p) - 1;
071436c6 17683
b6ac461a 17684 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17685 p += strnlen ((char *) p, maxlen) + 1;
17686 }
17687 else
17688 {
17689 printf (_("<corrupt>"));
17690 p = (unsigned char *) end;
17691 }
071436c6 17692 putchar ('\n');
f6f0e17b 17693 }
104d59d1
JM
17694 return p;
17695 }
17696
17697 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17698 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17699
f6f0e17b 17700 return display_tag_value (tag, p, end);
104d59d1
JM
17701}
17702
85f7484a
PB
17703static unsigned char *
17704display_m68k_gnu_attribute (unsigned char * p,
17705 unsigned int tag,
17706 const unsigned char * const end)
17707{
17708 unsigned int val;
17709
17710 if (tag == Tag_GNU_M68K_ABI_FP)
17711 {
17712 printf (" Tag_GNU_M68K_ABI_FP: ");
17713 if (p == end)
17714 {
17715 printf (_("<corrupt>\n"));
17716 return p;
17717 }
17718 READ_ULEB (val, p, end);
17719
17720 if (val > 3)
17721 printf ("(%#x), ", val);
17722
17723 switch (val & 3)
17724 {
17725 case 0:
17726 printf (_("unspecified hard/soft float\n"));
17727 break;
17728 case 1:
17729 printf (_("hard float\n"));
17730 break;
17731 case 2:
17732 printf (_("soft float\n"));
17733 break;
17734 }
17735 return p;
17736 }
17737
17738 return display_tag_value (tag & 1, p, end);
17739}
17740
34c8bcba 17741static unsigned char *
f6f0e17b 17742display_power_gnu_attribute (unsigned char * p,
60abdbed 17743 unsigned int tag,
f6f0e17b 17744 const unsigned char * const end)
34c8bcba 17745{
005d79fd 17746 unsigned int val;
34c8bcba
JM
17747
17748 if (tag == Tag_GNU_Power_ABI_FP)
17749 {
34c8bcba 17750 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17751 if (p == end)
005d79fd
AM
17752 {
17753 printf (_("<corrupt>\n"));
17754 return p;
17755 }
cd30bcef 17756 READ_ULEB (val, p, end);
60bca95a 17757
005d79fd
AM
17758 if (val > 15)
17759 printf ("(%#x), ", val);
17760
17761 switch (val & 3)
34c8bcba
JM
17762 {
17763 case 0:
005d79fd 17764 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17765 break;
17766 case 1:
005d79fd 17767 printf (_("hard float, "));
34c8bcba
JM
17768 break;
17769 case 2:
005d79fd 17770 printf (_("soft float, "));
34c8bcba 17771 break;
3c7b9897 17772 case 3:
005d79fd 17773 printf (_("single-precision hard float, "));
3c7b9897 17774 break;
005d79fd
AM
17775 }
17776
17777 switch (val & 0xC)
17778 {
17779 case 0:
17780 printf (_("unspecified long double\n"));
17781 break;
17782 case 4:
17783 printf (_("128-bit IBM long double\n"));
17784 break;
17785 case 8:
17786 printf (_("64-bit long double\n"));
17787 break;
17788 case 12:
17789 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
17790 break;
17791 }
17792 return p;
005d79fd 17793 }
34c8bcba 17794
c6e65352
DJ
17795 if (tag == Tag_GNU_Power_ABI_Vector)
17796 {
c6e65352 17797 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 17798 if (p == end)
005d79fd
AM
17799 {
17800 printf (_("<corrupt>\n"));
17801 return p;
17802 }
cd30bcef 17803 READ_ULEB (val, p, end);
005d79fd
AM
17804
17805 if (val > 3)
17806 printf ("(%#x), ", val);
17807
17808 switch (val & 3)
c6e65352
DJ
17809 {
17810 case 0:
005d79fd 17811 printf (_("unspecified\n"));
c6e65352
DJ
17812 break;
17813 case 1:
005d79fd 17814 printf (_("generic\n"));
c6e65352
DJ
17815 break;
17816 case 2:
17817 printf ("AltiVec\n");
17818 break;
17819 case 3:
17820 printf ("SPE\n");
17821 break;
c6e65352
DJ
17822 }
17823 return p;
005d79fd 17824 }
c6e65352 17825
f82e0623
NF
17826 if (tag == Tag_GNU_Power_ABI_Struct_Return)
17827 {
005d79fd 17828 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 17829 if (p == end)
f6f0e17b 17830 {
005d79fd 17831 printf (_("<corrupt>\n"));
f6f0e17b
NC
17832 return p;
17833 }
cd30bcef 17834 READ_ULEB (val, p, end);
0b4362b0 17835
005d79fd
AM
17836 if (val > 2)
17837 printf ("(%#x), ", val);
17838
17839 switch (val & 3)
17840 {
17841 case 0:
17842 printf (_("unspecified\n"));
17843 break;
17844 case 1:
17845 printf ("r3/r4\n");
17846 break;
17847 case 2:
17848 printf (_("memory\n"));
17849 break;
17850 case 3:
17851 printf ("???\n");
17852 break;
17853 }
f82e0623
NF
17854 return p;
17855 }
17856
f6f0e17b 17857 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
17858}
17859
643f7afb
AK
17860static unsigned char *
17861display_s390_gnu_attribute (unsigned char * p,
60abdbed 17862 unsigned int tag,
643f7afb
AK
17863 const unsigned char * const end)
17864{
cd30bcef 17865 unsigned int val;
643f7afb
AK
17866
17867 if (tag == Tag_GNU_S390_ABI_Vector)
17868 {
643f7afb 17869 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 17870 READ_ULEB (val, p, end);
643f7afb
AK
17871
17872 switch (val)
17873 {
17874 case 0:
17875 printf (_("any\n"));
17876 break;
17877 case 1:
17878 printf (_("software\n"));
17879 break;
17880 case 2:
17881 printf (_("hardware\n"));
17882 break;
17883 default:
17884 printf ("??? (%d)\n", val);
17885 break;
17886 }
17887 return p;
17888 }
17889
17890 return display_tag_value (tag & 1, p, end);
17891}
17892
9e8c70f9 17893static void
60abdbed 17894display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
17895{
17896 if (mask)
17897 {
015dc7e1 17898 bool first = true;
071436c6 17899
9e8c70f9 17900 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 17901 fputs ("mul32", stdout), first = false;
9e8c70f9 17902 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 17903 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 17904 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 17905 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 17906 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 17907 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 17908 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 17909 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 17910 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 17911 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 17912 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 17913 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 17914 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 17915 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 17916 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 17917 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 17918 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 17919 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 17920 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17921 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17922 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17923 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17924 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17925 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17926 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17927 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17928 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17929 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17930 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17931 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17932 }
17933 else
071436c6
NC
17934 fputc ('0', stdout);
17935 fputc ('\n', stdout);
9e8c70f9
DM
17936}
17937
3d68f91c 17938static void
60abdbed 17939display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17940{
17941 if (mask)
17942 {
015dc7e1 17943 bool first = true;
071436c6 17944
3d68f91c 17945 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17946 fputs ("fjathplus", stdout), first = false;
3d68f91c 17947 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17948 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17949 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17950 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17951 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17952 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17953 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17954 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17955 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17956 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17957 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17958 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17959 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17960 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17961 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17962 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17963 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17964 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17965 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17966 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17967 }
17968 else
071436c6
NC
17969 fputc ('0', stdout);
17970 fputc ('\n', stdout);
3d68f91c
JM
17971}
17972
9e8c70f9 17973static unsigned char *
f6f0e17b 17974display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17975 unsigned int tag,
f6f0e17b 17976 const unsigned char * const end)
9e8c70f9 17977{
cd30bcef 17978 unsigned int val;
3d68f91c 17979
9e8c70f9
DM
17980 if (tag == Tag_GNU_Sparc_HWCAPS)
17981 {
cd30bcef 17982 READ_ULEB (val, p, end);
9e8c70f9 17983 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17984 display_sparc_hwcaps (val);
17985 return p;
3d68f91c
JM
17986 }
17987 if (tag == Tag_GNU_Sparc_HWCAPS2)
17988 {
cd30bcef 17989 READ_ULEB (val, p, end);
3d68f91c
JM
17990 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17991 display_sparc_hwcaps2 (val);
17992 return p;
17993 }
9e8c70f9 17994
f6f0e17b 17995 return display_tag_value (tag, p, end);
9e8c70f9
DM
17996}
17997
351cdf24 17998static void
32ec8896 17999print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18000{
18001 switch (val)
18002 {
18003 case Val_GNU_MIPS_ABI_FP_ANY:
18004 printf (_("Hard or soft float\n"));
18005 break;
18006 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18007 printf (_("Hard float (double precision)\n"));
18008 break;
18009 case Val_GNU_MIPS_ABI_FP_SINGLE:
18010 printf (_("Hard float (single precision)\n"));
18011 break;
18012 case Val_GNU_MIPS_ABI_FP_SOFT:
18013 printf (_("Soft float\n"));
18014 break;
18015 case Val_GNU_MIPS_ABI_FP_OLD_64:
18016 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18017 break;
18018 case Val_GNU_MIPS_ABI_FP_XX:
18019 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18020 break;
18021 case Val_GNU_MIPS_ABI_FP_64:
18022 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18023 break;
18024 case Val_GNU_MIPS_ABI_FP_64A:
18025 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18026 break;
3350cc01
CM
18027 case Val_GNU_MIPS_ABI_FP_NAN2008:
18028 printf (_("NaN 2008 compatibility\n"));
18029 break;
351cdf24
MF
18030 default:
18031 printf ("??? (%d)\n", val);
18032 break;
18033 }
18034}
18035
2cf19d5c 18036static unsigned char *
f6f0e17b 18037display_mips_gnu_attribute (unsigned char * p,
60abdbed 18038 unsigned int tag,
f6f0e17b 18039 const unsigned char * const end)
2cf19d5c 18040{
2cf19d5c
JM
18041 if (tag == Tag_GNU_MIPS_ABI_FP)
18042 {
32ec8896 18043 unsigned int val;
f6f0e17b 18044
2cf19d5c 18045 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18046 READ_ULEB (val, p, end);
351cdf24 18047 print_mips_fp_abi_value (val);
2cf19d5c
JM
18048 return p;
18049 }
18050
a9f58168
CF
18051 if (tag == Tag_GNU_MIPS_ABI_MSA)
18052 {
32ec8896 18053 unsigned int val;
a9f58168 18054
a9f58168 18055 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18056 READ_ULEB (val, p, end);
a9f58168
CF
18057
18058 switch (val)
18059 {
18060 case Val_GNU_MIPS_ABI_MSA_ANY:
18061 printf (_("Any MSA or not\n"));
18062 break;
18063 case Val_GNU_MIPS_ABI_MSA_128:
18064 printf (_("128-bit MSA\n"));
18065 break;
18066 default:
18067 printf ("??? (%d)\n", val);
18068 break;
18069 }
18070 return p;
18071 }
18072
f6f0e17b 18073 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18074}
18075
59e6276b 18076static unsigned char *
f6f0e17b
NC
18077display_tic6x_attribute (unsigned char * p,
18078 const unsigned char * const end)
59e6276b 18079{
60abdbed 18080 unsigned int tag;
cd30bcef 18081 unsigned int val;
59e6276b 18082
cd30bcef 18083 READ_ULEB (tag, p, end);
59e6276b
JM
18084
18085 switch (tag)
18086 {
75fa6dc1 18087 case Tag_ISA:
75fa6dc1 18088 printf (" Tag_ISA: ");
cd30bcef 18089 READ_ULEB (val, p, end);
59e6276b
JM
18090
18091 switch (val)
18092 {
75fa6dc1 18093 case C6XABI_Tag_ISA_none:
59e6276b
JM
18094 printf (_("None\n"));
18095 break;
75fa6dc1 18096 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18097 printf ("C62x\n");
18098 break;
75fa6dc1 18099 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18100 printf ("C67x\n");
18101 break;
75fa6dc1 18102 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18103 printf ("C67x+\n");
18104 break;
75fa6dc1 18105 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18106 printf ("C64x\n");
18107 break;
75fa6dc1 18108 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18109 printf ("C64x+\n");
18110 break;
75fa6dc1 18111 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18112 printf ("C674x\n");
18113 break;
18114 default:
18115 printf ("??? (%d)\n", val);
18116 break;
18117 }
18118 return p;
18119
87779176 18120 case Tag_ABI_wchar_t:
87779176 18121 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18122 READ_ULEB (val, p, end);
87779176
JM
18123 switch (val)
18124 {
18125 case 0:
18126 printf (_("Not used\n"));
18127 break;
18128 case 1:
18129 printf (_("2 bytes\n"));
18130 break;
18131 case 2:
18132 printf (_("4 bytes\n"));
18133 break;
18134 default:
18135 printf ("??? (%d)\n", val);
18136 break;
18137 }
18138 return p;
18139
18140 case Tag_ABI_stack_align_needed:
87779176 18141 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18142 READ_ULEB (val, p, end);
87779176
JM
18143 switch (val)
18144 {
18145 case 0:
18146 printf (_("8-byte\n"));
18147 break;
18148 case 1:
18149 printf (_("16-byte\n"));
18150 break;
18151 default:
18152 printf ("??? (%d)\n", val);
18153 break;
18154 }
18155 return p;
18156
18157 case Tag_ABI_stack_align_preserved:
cd30bcef 18158 READ_ULEB (val, p, end);
87779176
JM
18159 printf (" Tag_ABI_stack_align_preserved: ");
18160 switch (val)
18161 {
18162 case 0:
18163 printf (_("8-byte\n"));
18164 break;
18165 case 1:
18166 printf (_("16-byte\n"));
18167 break;
18168 default:
18169 printf ("??? (%d)\n", val);
18170 break;
18171 }
18172 return p;
18173
b5593623 18174 case Tag_ABI_DSBT:
cd30bcef 18175 READ_ULEB (val, p, end);
b5593623
JM
18176 printf (" Tag_ABI_DSBT: ");
18177 switch (val)
18178 {
18179 case 0:
18180 printf (_("DSBT addressing not used\n"));
18181 break;
18182 case 1:
18183 printf (_("DSBT addressing used\n"));
18184 break;
18185 default:
18186 printf ("??? (%d)\n", val);
18187 break;
18188 }
18189 return p;
18190
87779176 18191 case Tag_ABI_PID:
cd30bcef 18192 READ_ULEB (val, p, end);
87779176
JM
18193 printf (" Tag_ABI_PID: ");
18194 switch (val)
18195 {
18196 case 0:
18197 printf (_("Data addressing position-dependent\n"));
18198 break;
18199 case 1:
18200 printf (_("Data addressing position-independent, GOT near DP\n"));
18201 break;
18202 case 2:
18203 printf (_("Data addressing position-independent, GOT far from DP\n"));
18204 break;
18205 default:
18206 printf ("??? (%d)\n", val);
18207 break;
18208 }
18209 return p;
18210
18211 case Tag_ABI_PIC:
cd30bcef 18212 READ_ULEB (val, p, end);
87779176
JM
18213 printf (" Tag_ABI_PIC: ");
18214 switch (val)
18215 {
18216 case 0:
18217 printf (_("Code addressing position-dependent\n"));
18218 break;
18219 case 1:
18220 printf (_("Code addressing position-independent\n"));
18221 break;
18222 default:
18223 printf ("??? (%d)\n", val);
18224 break;
18225 }
18226 return p;
18227
18228 case Tag_ABI_array_object_alignment:
cd30bcef 18229 READ_ULEB (val, p, end);
87779176
JM
18230 printf (" Tag_ABI_array_object_alignment: ");
18231 switch (val)
18232 {
18233 case 0:
18234 printf (_("8-byte\n"));
18235 break;
18236 case 1:
18237 printf (_("4-byte\n"));
18238 break;
18239 case 2:
18240 printf (_("16-byte\n"));
18241 break;
18242 default:
18243 printf ("??? (%d)\n", val);
18244 break;
18245 }
18246 return p;
18247
18248 case Tag_ABI_array_object_align_expected:
cd30bcef 18249 READ_ULEB (val, p, end);
87779176
JM
18250 printf (" Tag_ABI_array_object_align_expected: ");
18251 switch (val)
18252 {
18253 case 0:
18254 printf (_("8-byte\n"));
18255 break;
18256 case 1:
18257 printf (_("4-byte\n"));
18258 break;
18259 case 2:
18260 printf (_("16-byte\n"));
18261 break;
18262 default:
18263 printf ("??? (%d)\n", val);
18264 break;
18265 }
18266 return p;
18267
3cbd1c06 18268 case Tag_ABI_compatibility:
071436c6 18269 {
cd30bcef 18270 READ_ULEB (val, p, end);
071436c6 18271 printf (" Tag_ABI_compatibility: ");
071436c6 18272 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18273 if (p < end - 1)
18274 {
18275 size_t maxlen = (end - p) - 1;
18276
b6ac461a 18277 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18278 p += strnlen ((char *) p, maxlen) + 1;
18279 }
18280 else
18281 {
18282 printf (_("<corrupt>"));
18283 p = (unsigned char *) end;
18284 }
071436c6 18285 putchar ('\n');
071436c6
NC
18286 return p;
18287 }
87779176
JM
18288
18289 case Tag_ABI_conformance:
071436c6 18290 {
4082ef84
NC
18291 printf (" Tag_ABI_conformance: \"");
18292 if (p < end - 1)
18293 {
18294 size_t maxlen = (end - p) - 1;
071436c6 18295
b6ac461a 18296 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18297 p += strnlen ((char *) p, maxlen) + 1;
18298 }
18299 else
18300 {
18301 printf (_("<corrupt>"));
18302 p = (unsigned char *) end;
18303 }
071436c6 18304 printf ("\"\n");
071436c6
NC
18305 return p;
18306 }
59e6276b
JM
18307 }
18308
f6f0e17b
NC
18309 return display_tag_value (tag, p, end);
18310}
59e6276b 18311
f6f0e17b 18312static void
60abdbed 18313display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18314{
26c527e6 18315 uint64_t addr = 0;
f6f0e17b
NC
18316 size_t bytes = end - p;
18317
feceaa59 18318 assert (end >= p);
f6f0e17b 18319 while (bytes)
87779176 18320 {
f6f0e17b
NC
18321 int j;
18322 int k;
18323 int lbytes = (bytes > 16 ? 16 : bytes);
18324
26c527e6 18325 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18326
18327 for (j = 0; j < 16; j++)
18328 {
18329 if (j < lbytes)
18330 printf ("%2.2x", p[j]);
18331 else
18332 printf (" ");
18333
18334 if ((j & 3) == 3)
18335 printf (" ");
18336 }
18337
18338 for (j = 0; j < lbytes; j++)
18339 {
18340 k = p[j];
18341 if (k >= ' ' && k < 0x7f)
18342 printf ("%c", k);
18343 else
18344 printf (".");
18345 }
18346
18347 putchar ('\n');
18348
18349 p += lbytes;
18350 bytes -= lbytes;
18351 addr += lbytes;
87779176 18352 }
59e6276b 18353
f6f0e17b 18354 putchar ('\n');
59e6276b
JM
18355}
18356
13761a11 18357static unsigned char *
b0191216 18358display_msp430_attribute (unsigned char * p,
26c527e6 18359 const unsigned char * const end)
13761a11 18360{
26c527e6
AM
18361 uint64_t val;
18362 uint64_t tag;
13761a11 18363
cd30bcef 18364 READ_ULEB (tag, p, end);
0b4362b0 18365
13761a11
NC
18366 switch (tag)
18367 {
18368 case OFBA_MSPABI_Tag_ISA:
13761a11 18369 printf (" Tag_ISA: ");
cd30bcef 18370 READ_ULEB (val, p, end);
13761a11
NC
18371 switch (val)
18372 {
18373 case 0: printf (_("None\n")); break;
18374 case 1: printf (_("MSP430\n")); break;
18375 case 2: printf (_("MSP430X\n")); break;
26c527e6 18376 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18377 }
18378 break;
18379
18380 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18381 printf (" Tag_Code_Model: ");
cd30bcef 18382 READ_ULEB (val, p, end);
13761a11
NC
18383 switch (val)
18384 {
18385 case 0: printf (_("None\n")); break;
18386 case 1: printf (_("Small\n")); break;
18387 case 2: printf (_("Large\n")); break;
26c527e6 18388 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18389 }
18390 break;
18391
18392 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18393 printf (" Tag_Data_Model: ");
cd30bcef 18394 READ_ULEB (val, p, end);
13761a11
NC
18395 switch (val)
18396 {
18397 case 0: printf (_("None\n")); break;
18398 case 1: printf (_("Small\n")); break;
18399 case 2: printf (_("Large\n")); break;
18400 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18401 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18402 }
18403 break;
18404
18405 default:
26c527e6 18406 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18407
18408 if (tag & 1)
18409 {
071436c6 18410 putchar ('"');
4082ef84
NC
18411 if (p < end - 1)
18412 {
18413 size_t maxlen = (end - p) - 1;
18414
b6ac461a 18415 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18416 p += strnlen ((char *) p, maxlen) + 1;
18417 }
18418 else
18419 {
18420 printf (_("<corrupt>"));
18421 p = (unsigned char *) end;
18422 }
071436c6 18423 printf ("\"\n");
13761a11
NC
18424 }
18425 else
18426 {
cd30bcef 18427 READ_ULEB (val, p, end);
26c527e6 18428 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18429 }
18430 break;
18431 }
18432
4082ef84 18433 assert (p <= end);
13761a11
NC
18434 return p;
18435}
18436
c0ea7c52
JL
18437static unsigned char *
18438display_msp430_gnu_attribute (unsigned char * p,
18439 unsigned int tag,
18440 const unsigned char * const end)
18441{
18442 if (tag == Tag_GNU_MSP430_Data_Region)
18443 {
26c527e6 18444 uint64_t val;
c0ea7c52 18445
c0ea7c52 18446 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18447 READ_ULEB (val, p, end);
c0ea7c52
JL
18448
18449 switch (val)
18450 {
18451 case Val_GNU_MSP430_Data_Region_Any:
18452 printf (_("Any Region\n"));
18453 break;
18454 case Val_GNU_MSP430_Data_Region_Lower:
18455 printf (_("Lower Region Only\n"));
18456 break;
18457 default:
26c527e6 18458 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18459 }
18460 return p;
18461 }
18462 return display_tag_value (tag & 1, p, end);
18463}
18464
2dc8dd17
JW
18465struct riscv_attr_tag_t {
18466 const char *name;
cd30bcef 18467 unsigned int tag;
2dc8dd17
JW
18468};
18469
18470static struct riscv_attr_tag_t riscv_attr_tag[] =
18471{
18472#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18473 T(arch),
18474 T(priv_spec),
18475 T(priv_spec_minor),
18476 T(priv_spec_revision),
18477 T(unaligned_access),
18478 T(stack_align),
18479#undef T
18480};
18481
18482static unsigned char *
18483display_riscv_attribute (unsigned char *p,
18484 const unsigned char * const end)
18485{
26c527e6
AM
18486 uint64_t val;
18487 uint64_t tag;
2dc8dd17
JW
18488 struct riscv_attr_tag_t *attr = NULL;
18489 unsigned i;
18490
cd30bcef 18491 READ_ULEB (tag, p, end);
2dc8dd17
JW
18492
18493 /* Find the name of attribute. */
18494 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18495 {
18496 if (riscv_attr_tag[i].tag == tag)
18497 {
18498 attr = &riscv_attr_tag[i];
18499 break;
18500 }
18501 }
18502
18503 if (attr)
18504 printf (" %s: ", attr->name);
18505 else
18506 return display_tag_value (tag, p, end);
18507
18508 switch (tag)
18509 {
18510 case Tag_RISCV_priv_spec:
18511 case Tag_RISCV_priv_spec_minor:
18512 case Tag_RISCV_priv_spec_revision:
cd30bcef 18513 READ_ULEB (val, p, end);
26c527e6 18514 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18515 break;
18516 case Tag_RISCV_unaligned_access:
cd30bcef 18517 READ_ULEB (val, p, end);
2dc8dd17
JW
18518 switch (val)
18519 {
18520 case 0:
18521 printf (_("No unaligned access\n"));
18522 break;
18523 case 1:
18524 printf (_("Unaligned access\n"));
18525 break;
18526 }
18527 break;
18528 case Tag_RISCV_stack_align:
cd30bcef 18529 READ_ULEB (val, p, end);
26c527e6 18530 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18531 break;
18532 case Tag_RISCV_arch:
18533 p = display_tag_value (-1, p, end);
18534 break;
18535 default:
18536 return display_tag_value (tag, p, end);
18537 }
18538
18539 return p;
18540}
18541
0861f561
CQ
18542static unsigned char *
18543display_csky_attribute (unsigned char * p,
18544 const unsigned char * const end)
18545{
26c527e6
AM
18546 uint64_t tag;
18547 uint64_t val;
0861f561
CQ
18548 READ_ULEB (tag, p, end);
18549
18550 if (tag >= Tag_CSKY_MAX)
18551 {
18552 return display_tag_value (-1, p, end);
18553 }
18554
18555 switch (tag)
18556 {
18557 case Tag_CSKY_ARCH_NAME:
18558 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18559 return display_tag_value (-1, p, end);
18560 case Tag_CSKY_CPU_NAME:
18561 printf (" Tag_CSKY_CPU_NAME:\t\t");
18562 return display_tag_value (-1, p, end);
18563
18564 case Tag_CSKY_ISA_FLAGS:
18565 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18566 return display_tag_value (0, p, end);
18567 case Tag_CSKY_ISA_EXT_FLAGS:
18568 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18569 return display_tag_value (0, p, end);
18570
18571 case Tag_CSKY_DSP_VERSION:
18572 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18573 READ_ULEB (val, p, end);
18574 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18575 printf ("DSP Extension\n");
18576 else if (val == VAL_CSKY_DSP_VERSION_2)
18577 printf ("DSP 2.0\n");
18578 break;
18579
18580 case Tag_CSKY_VDSP_VERSION:
18581 printf (" Tag_CSKY_VDSP_VERSION:\t");
18582 READ_ULEB (val, p, end);
26c527e6 18583 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18584 break;
18585
18586 case Tag_CSKY_FPU_VERSION:
18587 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18588 READ_ULEB (val, p, end);
18589 if (val == VAL_CSKY_FPU_VERSION_1)
18590 printf ("ABIV1 FPU Version 1\n");
18591 else if (val == VAL_CSKY_FPU_VERSION_2)
18592 printf ("FPU Version 2\n");
18593 break;
18594
18595 case Tag_CSKY_FPU_ABI:
18596 printf (" Tag_CSKY_FPU_ABI:\t\t");
18597 READ_ULEB (val, p, end);
18598 if (val == VAL_CSKY_FPU_ABI_HARD)
18599 printf ("Hard\n");
18600 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18601 printf ("SoftFP\n");
18602 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18603 printf ("Soft\n");
18604 break;
18605 case Tag_CSKY_FPU_ROUNDING:
18606 READ_ULEB (val, p, end);
f253158f
NC
18607 if (val == 1)
18608 {
18609 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18610 printf ("Needed\n");
18611 }
0861f561
CQ
18612 break;
18613 case Tag_CSKY_FPU_DENORMAL:
18614 READ_ULEB (val, p, end);
f253158f
NC
18615 if (val == 1)
18616 {
18617 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18618 printf ("Needed\n");
18619 }
0861f561
CQ
18620 break;
18621 case Tag_CSKY_FPU_Exception:
18622 READ_ULEB (val, p, end);
f253158f
NC
18623 if (val == 1)
18624 {
18625 printf (" Tag_CSKY_FPU_Exception:\t");
18626 printf ("Needed\n");
18627 }
0861f561
CQ
18628 break;
18629 case Tag_CSKY_FPU_NUMBER_MODULE:
18630 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18631 return display_tag_value (-1, p, end);
18632 case Tag_CSKY_FPU_HARDFP:
18633 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18634 READ_ULEB (val, p, end);
18635 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18636 printf (" Half");
18637 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18638 printf (" Single");
18639 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18640 printf (" Double");
18641 printf ("\n");
18642 break;
18643 default:
18644 return display_tag_value (tag, p, end);
18645 }
18646 return p;
18647}
18648
015dc7e1 18649static bool
dda8d76d 18650process_attributes (Filedata * filedata,
60bca95a 18651 const char * public_name,
104d59d1 18652 unsigned int proc_type,
f6f0e17b 18653 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18654 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18655{
2cf0635d 18656 Elf_Internal_Shdr * sect;
11c1ff18 18657 unsigned i;
015dc7e1 18658 bool res = true;
11c1ff18
PB
18659
18660 /* Find the section header so that we get the size. */
dda8d76d
NC
18661 for (i = 0, sect = filedata->section_headers;
18662 i < filedata->file_header.e_shnum;
11c1ff18
PB
18663 i++, sect++)
18664 {
071436c6
NC
18665 unsigned char * contents;
18666 unsigned char * p;
18667
104d59d1 18668 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18669 continue;
18670
dda8d76d 18671 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18672 sect->sh_size, _("attributes"));
60bca95a 18673 if (contents == NULL)
32ec8896 18674 {
015dc7e1 18675 res = false;
32ec8896
NC
18676 continue;
18677 }
60bca95a 18678
11c1ff18 18679 p = contents;
60abdbed
NC
18680 /* The first character is the version of the attributes.
18681 Currently only version 1, (aka 'A') is recognised here. */
18682 if (*p != 'A')
32ec8896
NC
18683 {
18684 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18685 res = false;
32ec8896 18686 }
60abdbed 18687 else
11c1ff18 18688 {
625d49fc 18689 uint64_t section_len;
071436c6
NC
18690
18691 section_len = sect->sh_size - 1;
11c1ff18 18692 p++;
60bca95a 18693
071436c6 18694 while (section_len > 0)
11c1ff18 18695 {
625d49fc 18696 uint64_t attr_len;
e9847026 18697 unsigned int namelen;
015dc7e1
AM
18698 bool public_section;
18699 bool gnu_section;
11c1ff18 18700
071436c6 18701 if (section_len <= 4)
e0a31db1
NC
18702 {
18703 error (_("Tag section ends prematurely\n"));
015dc7e1 18704 res = false;
e0a31db1
NC
18705 break;
18706 }
071436c6 18707 attr_len = byte_get (p, 4);
11c1ff18 18708 p += 4;
60bca95a 18709
071436c6 18710 if (attr_len > section_len)
11c1ff18 18711 {
071436c6
NC
18712 error (_("Bad attribute length (%u > %u)\n"),
18713 (unsigned) attr_len, (unsigned) section_len);
18714 attr_len = section_len;
015dc7e1 18715 res = false;
11c1ff18 18716 }
74e1a04b 18717 /* PR 17531: file: 001-101425-0.004 */
071436c6 18718 else if (attr_len < 5)
74e1a04b 18719 {
071436c6 18720 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18721 res = false;
74e1a04b
NC
18722 break;
18723 }
e9847026 18724
071436c6
NC
18725 section_len -= attr_len;
18726 attr_len -= 4;
18727
18728 namelen = strnlen ((char *) p, attr_len) + 1;
18729 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18730 {
18731 error (_("Corrupt attribute section name\n"));
015dc7e1 18732 res = false;
e9847026
NC
18733 break;
18734 }
18735
071436c6 18736 printf (_("Attribute Section: "));
b6ac461a 18737 print_symbol_name (INT_MAX, (const char *) p);
071436c6 18738 putchar ('\n');
60bca95a
NC
18739
18740 if (public_name && streq ((char *) p, public_name))
015dc7e1 18741 public_section = true;
11c1ff18 18742 else
015dc7e1 18743 public_section = false;
60bca95a
NC
18744
18745 if (streq ((char *) p, "gnu"))
015dc7e1 18746 gnu_section = true;
104d59d1 18747 else
015dc7e1 18748 gnu_section = false;
60bca95a 18749
11c1ff18 18750 p += namelen;
071436c6 18751 attr_len -= namelen;
e0a31db1 18752
071436c6 18753 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18754 {
e0a31db1 18755 int tag;
cd30bcef 18756 unsigned int val;
625d49fc 18757 uint64_t size;
071436c6 18758 unsigned char * end;
60bca95a 18759
e0a31db1 18760 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18761 if (attr_len < 6)
e0a31db1
NC
18762 {
18763 error (_("Unused bytes at end of section\n"));
015dc7e1 18764 res = false;
e0a31db1
NC
18765 section_len = 0;
18766 break;
18767 }
18768
18769 tag = *(p++);
11c1ff18 18770 size = byte_get (p, 4);
071436c6 18771 if (size > attr_len)
11c1ff18 18772 {
e9847026 18773 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18774 (unsigned) size, (unsigned) attr_len);
015dc7e1 18775 res = false;
071436c6 18776 size = attr_len;
11c1ff18 18777 }
e0a31db1
NC
18778 /* PR binutils/17531: Safe handling of corrupt files. */
18779 if (size < 6)
18780 {
18781 error (_("Bad subsection length (%u < 6)\n"),
18782 (unsigned) size);
015dc7e1 18783 res = false;
e0a31db1
NC
18784 section_len = 0;
18785 break;
18786 }
60bca95a 18787
071436c6 18788 attr_len -= size;
11c1ff18 18789 end = p + size - 1;
071436c6 18790 assert (end <= contents + sect->sh_size);
11c1ff18 18791 p += 4;
60bca95a 18792
11c1ff18
PB
18793 switch (tag)
18794 {
18795 case 1:
2b692964 18796 printf (_("File Attributes\n"));
11c1ff18
PB
18797 break;
18798 case 2:
2b692964 18799 printf (_("Section Attributes:"));
11c1ff18
PB
18800 goto do_numlist;
18801 case 3:
2b692964 18802 printf (_("Symbol Attributes:"));
1a0670f3 18803 /* Fall through. */
11c1ff18
PB
18804 do_numlist:
18805 for (;;)
18806 {
cd30bcef 18807 READ_ULEB (val, p, end);
11c1ff18
PB
18808 if (val == 0)
18809 break;
18810 printf (" %d", val);
18811 }
18812 printf ("\n");
18813 break;
18814 default:
2b692964 18815 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 18816 public_section = false;
11c1ff18
PB
18817 break;
18818 }
60bca95a 18819
071436c6 18820 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
18821 {
18822 while (p < end)
f6f0e17b 18823 p = display_pub_attribute (p, end);
60abdbed 18824 assert (p == end);
104d59d1 18825 }
071436c6 18826 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
18827 {
18828 while (p < end)
18829 p = display_gnu_attribute (p,
f6f0e17b
NC
18830 display_proc_gnu_attribute,
18831 end);
60abdbed 18832 assert (p == end);
11c1ff18 18833 }
071436c6 18834 else if (p < end)
11c1ff18 18835 {
071436c6 18836 printf (_(" Unknown attribute:\n"));
f6f0e17b 18837 display_raw_attribute (p, end);
11c1ff18
PB
18838 p = end;
18839 }
071436c6
NC
18840 else
18841 attr_len = 0;
11c1ff18
PB
18842 }
18843 }
18844 }
d70c5fc7 18845
60bca95a 18846 free (contents);
11c1ff18 18847 }
32ec8896
NC
18848
18849 return res;
11c1ff18
PB
18850}
18851
ccb4c951
RS
18852/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
18853 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
18854 and return the VMA of the next entry, or -1 if there was a problem.
18855 Does not read from DATA_END or beyond. */
ccb4c951 18856
625d49fc
AM
18857static uint64_t
18858print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 18859 unsigned char * data_end)
ccb4c951
RS
18860{
18861 printf (" ");
18862 print_vma (addr, LONG_HEX);
18863 printf (" ");
18864 if (addr < pltgot + 0xfff0)
18865 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
18866 else
18867 printf ("%10s", "");
18868 printf (" ");
18869 if (data == NULL)
2b692964 18870 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
18871 else
18872 {
625d49fc 18873 uint64_t entry;
82b1b41b 18874 unsigned char * from = data + addr - pltgot;
ccb4c951 18875
82b1b41b
NC
18876 if (from + (is_32bit_elf ? 4 : 8) > data_end)
18877 {
18878 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
18879 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 18880 return (uint64_t) -1;
82b1b41b
NC
18881 }
18882 else
18883 {
18884 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18885 print_vma (entry, LONG_HEX);
18886 }
ccb4c951
RS
18887 }
18888 return addr + (is_32bit_elf ? 4 : 8);
18889}
18890
861fb55a
DJ
18891/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
18892 PLTGOT. Print the Address and Initial fields of an entry at VMA
18893 ADDR and return the VMA of the next entry. */
18894
625d49fc
AM
18895static uint64_t
18896print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
18897{
18898 printf (" ");
18899 print_vma (addr, LONG_HEX);
18900 printf (" ");
18901 if (data == NULL)
2b692964 18902 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
18903 else
18904 {
625d49fc 18905 uint64_t entry;
861fb55a
DJ
18906
18907 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
18908 print_vma (entry, LONG_HEX);
18909 }
18910 return addr + (is_32bit_elf ? 4 : 8);
18911}
18912
351cdf24
MF
18913static void
18914print_mips_ases (unsigned int mask)
18915{
18916 if (mask & AFL_ASE_DSP)
18917 fputs ("\n\tDSP ASE", stdout);
18918 if (mask & AFL_ASE_DSPR2)
18919 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
18920 if (mask & AFL_ASE_DSPR3)
18921 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18922 if (mask & AFL_ASE_EVA)
18923 fputs ("\n\tEnhanced VA Scheme", stdout);
18924 if (mask & AFL_ASE_MCU)
18925 fputs ("\n\tMCU (MicroController) ASE", stdout);
18926 if (mask & AFL_ASE_MDMX)
18927 fputs ("\n\tMDMX ASE", stdout);
18928 if (mask & AFL_ASE_MIPS3D)
18929 fputs ("\n\tMIPS-3D ASE", stdout);
18930 if (mask & AFL_ASE_MT)
18931 fputs ("\n\tMT ASE", stdout);
18932 if (mask & AFL_ASE_SMARTMIPS)
18933 fputs ("\n\tSmartMIPS ASE", stdout);
18934 if (mask & AFL_ASE_VIRT)
18935 fputs ("\n\tVZ ASE", stdout);
18936 if (mask & AFL_ASE_MSA)
18937 fputs ("\n\tMSA ASE", stdout);
18938 if (mask & AFL_ASE_MIPS16)
18939 fputs ("\n\tMIPS16 ASE", stdout);
18940 if (mask & AFL_ASE_MICROMIPS)
18941 fputs ("\n\tMICROMIPS ASE", stdout);
18942 if (mask & AFL_ASE_XPA)
18943 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18944 if (mask & AFL_ASE_MIPS16E2)
18945 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18946 if (mask & AFL_ASE_CRC)
18947 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18948 if (mask & AFL_ASE_GINV)
18949 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18950 if (mask & AFL_ASE_LOONGSON_MMI)
18951 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18952 if (mask & AFL_ASE_LOONGSON_CAM)
18953 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18954 if (mask & AFL_ASE_LOONGSON_EXT)
18955 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18956 if (mask & AFL_ASE_LOONGSON_EXT2)
18957 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18958 if (mask == 0)
18959 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18960 else if ((mask & ~AFL_ASE_MASK) != 0)
18961 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18962}
18963
18964static void
18965print_mips_isa_ext (unsigned int isa_ext)
18966{
18967 switch (isa_ext)
18968 {
18969 case 0:
18970 fputs (_("None"), stdout);
18971 break;
18972 case AFL_EXT_XLR:
18973 fputs ("RMI XLR", stdout);
18974 break;
2c629856
N
18975 case AFL_EXT_OCTEON3:
18976 fputs ("Cavium Networks Octeon3", stdout);
18977 break;
351cdf24
MF
18978 case AFL_EXT_OCTEON2:
18979 fputs ("Cavium Networks Octeon2", stdout);
18980 break;
18981 case AFL_EXT_OCTEONP:
18982 fputs ("Cavium Networks OcteonP", stdout);
18983 break;
351cdf24
MF
18984 case AFL_EXT_OCTEON:
18985 fputs ("Cavium Networks Octeon", stdout);
18986 break;
18987 case AFL_EXT_5900:
18988 fputs ("Toshiba R5900", stdout);
18989 break;
18990 case AFL_EXT_4650:
18991 fputs ("MIPS R4650", stdout);
18992 break;
18993 case AFL_EXT_4010:
18994 fputs ("LSI R4010", stdout);
18995 break;
18996 case AFL_EXT_4100:
18997 fputs ("NEC VR4100", stdout);
18998 break;
18999 case AFL_EXT_3900:
19000 fputs ("Toshiba R3900", stdout);
19001 break;
19002 case AFL_EXT_10000:
19003 fputs ("MIPS R10000", stdout);
19004 break;
19005 case AFL_EXT_SB1:
19006 fputs ("Broadcom SB-1", stdout);
19007 break;
19008 case AFL_EXT_4111:
19009 fputs ("NEC VR4111/VR4181", stdout);
19010 break;
19011 case AFL_EXT_4120:
19012 fputs ("NEC VR4120", stdout);
19013 break;
19014 case AFL_EXT_5400:
19015 fputs ("NEC VR5400", stdout);
19016 break;
19017 case AFL_EXT_5500:
19018 fputs ("NEC VR5500", stdout);
19019 break;
19020 case AFL_EXT_LOONGSON_2E:
19021 fputs ("ST Microelectronics Loongson 2E", stdout);
19022 break;
19023 case AFL_EXT_LOONGSON_2F:
19024 fputs ("ST Microelectronics Loongson 2F", stdout);
19025 break;
38bf472a
MR
19026 case AFL_EXT_INTERAPTIV_MR2:
19027 fputs ("Imagination interAptiv MR2", stdout);
19028 break;
351cdf24 19029 default:
00ac7aa0 19030 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19031 }
19032}
19033
32ec8896 19034static signed int
351cdf24
MF
19035get_mips_reg_size (int reg_size)
19036{
19037 return (reg_size == AFL_REG_NONE) ? 0
19038 : (reg_size == AFL_REG_32) ? 32
19039 : (reg_size == AFL_REG_64) ? 64
19040 : (reg_size == AFL_REG_128) ? 128
19041 : -1;
19042}
19043
015dc7e1 19044static bool
dda8d76d 19045process_mips_specific (Filedata * filedata)
5b18a4bc 19046{
2cf0635d 19047 Elf_Internal_Dyn * entry;
351cdf24 19048 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19049 size_t liblist_offset = 0;
19050 size_t liblistno = 0;
19051 size_t conflictsno = 0;
19052 size_t options_offset = 0;
19053 size_t conflicts_offset = 0;
861fb55a
DJ
19054 size_t pltrelsz = 0;
19055 size_t pltrel = 0;
625d49fc
AM
19056 uint64_t pltgot = 0;
19057 uint64_t mips_pltgot = 0;
19058 uint64_t jmprel = 0;
19059 uint64_t local_gotno = 0;
19060 uint64_t gotsym = 0;
19061 uint64_t symtabno = 0;
015dc7e1 19062 bool res = true;
103f02d3 19063
dda8d76d 19064 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19065 display_mips_gnu_attribute))
015dc7e1 19066 res = false;
2cf19d5c 19067
dda8d76d 19068 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19069
19070 if (sect != NULL)
19071 {
19072 Elf_External_ABIFlags_v0 *abiflags_ext;
19073 Elf_Internal_ABIFlags_v0 abiflags_in;
19074
19075 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19076 {
19077 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19078 res = false;
32ec8896 19079 }
351cdf24
MF
19080 else
19081 {
dda8d76d 19082 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19083 sect->sh_size, _("MIPS ABI Flags section"));
19084 if (abiflags_ext)
19085 {
19086 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19087 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19088 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19089 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19090 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19091 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19092 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19093 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19094 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19095 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19096 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19097
19098 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19099 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19100 if (abiflags_in.isa_rev > 1)
19101 printf ("r%d", abiflags_in.isa_rev);
19102 printf ("\nGPR size: %d",
19103 get_mips_reg_size (abiflags_in.gpr_size));
19104 printf ("\nCPR1 size: %d",
19105 get_mips_reg_size (abiflags_in.cpr1_size));
19106 printf ("\nCPR2 size: %d",
19107 get_mips_reg_size (abiflags_in.cpr2_size));
19108 fputs ("\nFP ABI: ", stdout);
19109 print_mips_fp_abi_value (abiflags_in.fp_abi);
19110 fputs ("ISA Extension: ", stdout);
19111 print_mips_isa_ext (abiflags_in.isa_ext);
19112 fputs ("\nASEs:", stdout);
19113 print_mips_ases (abiflags_in.ases);
19114 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19115 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19116 fputc ('\n', stdout);
19117 free (abiflags_ext);
19118 }
19119 }
19120 }
19121
19e6b90e 19122 /* We have a lot of special sections. Thanks SGI! */
978c4450 19123 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19124 {
19125 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19126 sect = find_section (filedata, ".got");
bbdd9a68
MR
19127 if (sect != NULL)
19128 {
19129 unsigned char *data_end;
19130 unsigned char *data;
625d49fc 19131 uint64_t ent, end;
bbdd9a68
MR
19132 int addr_size;
19133
19134 pltgot = sect->sh_addr;
19135
19136 ent = pltgot;
19137 addr_size = (is_32bit_elf ? 4 : 8);
19138 end = pltgot + sect->sh_size;
19139
dda8d76d 19140 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19141 end - pltgot, 1,
19142 _("Global Offset Table data"));
19143 /* PR 12855: Null data is handled gracefully throughout. */
19144 data_end = data + (end - pltgot);
19145
19146 printf (_("\nStatic GOT:\n"));
19147 printf (_(" Canonical gp value: "));
19148 print_vma (ent + 0x7ff0, LONG_HEX);
19149 printf ("\n\n");
19150
19151 /* In a dynamic binary GOT[0] is reserved for the dynamic
19152 loader to store the lazy resolver pointer, however in
19153 a static binary it may well have been omitted and GOT
19154 reduced to a table of addresses.
19155 PR 21344: Check for the entry being fully available
19156 before fetching it. */
19157 if (data
19158 && data + ent - pltgot + addr_size <= data_end
19159 && byte_get (data + ent - pltgot, addr_size) == 0)
19160 {
19161 printf (_(" Reserved entries:\n"));
19162 printf (_(" %*s %10s %*s\n"),
19163 addr_size * 2, _("Address"), _("Access"),
19164 addr_size * 2, _("Value"));
19165 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19166 printf ("\n");
625d49fc 19167 if (ent == (uint64_t) -1)
bbdd9a68
MR
19168 goto sgot_print_fail;
19169
19170 /* Check for the MSB of GOT[1] being set, identifying a
19171 GNU object. This entry will be used by some runtime
19172 loaders, to store the module pointer. Otherwise this
19173 is an ordinary local entry.
19174 PR 21344: Check for the entry being fully available
19175 before fetching it. */
19176 if (data
19177 && data + ent - pltgot + addr_size <= data_end
19178 && (byte_get (data + ent - pltgot, addr_size)
19179 >> (addr_size * 8 - 1)) != 0)
19180 {
19181 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19182 printf ("\n");
625d49fc 19183 if (ent == (uint64_t) -1)
bbdd9a68
MR
19184 goto sgot_print_fail;
19185 }
19186 printf ("\n");
19187 }
19188
f17e9d8a 19189 if (data != NULL && ent < end)
bbdd9a68
MR
19190 {
19191 printf (_(" Local entries:\n"));
19192 printf (" %*s %10s %*s\n",
19193 addr_size * 2, _("Address"), _("Access"),
19194 addr_size * 2, _("Value"));
19195 while (ent < end)
19196 {
19197 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19198 printf ("\n");
625d49fc 19199 if (ent == (uint64_t) -1)
bbdd9a68
MR
19200 goto sgot_print_fail;
19201 }
19202 printf ("\n");
19203 }
19204
19205 sgot_print_fail:
9db70fc3 19206 free (data);
bbdd9a68
MR
19207 }
19208 return res;
19209 }
252b5132 19210
978c4450 19211 for (entry = filedata->dynamic_section;
071436c6 19212 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19213 (entry < filedata->dynamic_section + filedata->dynamic_nent
19214 && entry->d_tag != DT_NULL);
071436c6 19215 ++entry)
252b5132
RH
19216 switch (entry->d_tag)
19217 {
19218 case DT_MIPS_LIBLIST:
d93f0186 19219 liblist_offset
dda8d76d 19220 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19221 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19222 break;
19223 case DT_MIPS_LIBLISTNO:
19224 liblistno = entry->d_un.d_val;
19225 break;
19226 case DT_MIPS_OPTIONS:
dda8d76d 19227 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19228 break;
19229 case DT_MIPS_CONFLICT:
d93f0186 19230 conflicts_offset
dda8d76d 19231 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19232 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19233 break;
19234 case DT_MIPS_CONFLICTNO:
19235 conflictsno = entry->d_un.d_val;
19236 break;
ccb4c951 19237 case DT_PLTGOT:
861fb55a
DJ
19238 pltgot = entry->d_un.d_ptr;
19239 break;
ccb4c951
RS
19240 case DT_MIPS_LOCAL_GOTNO:
19241 local_gotno = entry->d_un.d_val;
19242 break;
19243 case DT_MIPS_GOTSYM:
19244 gotsym = entry->d_un.d_val;
19245 break;
19246 case DT_MIPS_SYMTABNO:
19247 symtabno = entry->d_un.d_val;
19248 break;
861fb55a
DJ
19249 case DT_MIPS_PLTGOT:
19250 mips_pltgot = entry->d_un.d_ptr;
19251 break;
19252 case DT_PLTREL:
19253 pltrel = entry->d_un.d_val;
19254 break;
19255 case DT_PLTRELSZ:
19256 pltrelsz = entry->d_un.d_val;
19257 break;
19258 case DT_JMPREL:
19259 jmprel = entry->d_un.d_ptr;
19260 break;
252b5132
RH
19261 default:
19262 break;
19263 }
19264
19265 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19266 {
2cf0635d 19267 Elf32_External_Lib * elib;
252b5132
RH
19268 size_t cnt;
19269
dda8d76d 19270 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19271 sizeof (Elf32_External_Lib),
19272 liblistno,
19273 _("liblist section data"));
a6e9f9df 19274 if (elib)
252b5132 19275 {
26c527e6
AM
19276 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19277 "\nSection '.liblist' contains %zu entries:\n",
19278 liblistno),
19279 liblistno);
2b692964 19280 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19281 stdout);
19282
19283 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19284 {
a6e9f9df 19285 Elf32_Lib liblist;
91d6fa6a 19286 time_t atime;
d5b07ef4 19287 char timebuf[128];
2cf0635d 19288 struct tm * tmp;
a6e9f9df
AM
19289
19290 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19291 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19292 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19293 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19294 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19295
91d6fa6a 19296 tmp = gmtime (&atime);
e9e44622
JJ
19297 snprintf (timebuf, sizeof (timebuf),
19298 "%04u-%02u-%02uT%02u:%02u:%02u",
19299 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19300 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19301
26c527e6 19302 printf ("%3zu: ", cnt);
84714f86 19303 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19304 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19305 else
2b692964 19306 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19307 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19308 liblist.l_version);
a6e9f9df
AM
19309
19310 if (liblist.l_flags == 0)
2b692964 19311 puts (_(" NONE"));
a6e9f9df
AM
19312 else
19313 {
19314 static const struct
252b5132 19315 {
2cf0635d 19316 const char * name;
a6e9f9df 19317 int bit;
252b5132 19318 }
a6e9f9df
AM
19319 l_flags_vals[] =
19320 {
19321 { " EXACT_MATCH", LL_EXACT_MATCH },
19322 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19323 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19324 { " EXPORTS", LL_EXPORTS },
19325 { " DELAY_LOAD", LL_DELAY_LOAD },
19326 { " DELTA", LL_DELTA }
19327 };
19328 int flags = liblist.l_flags;
19329 size_t fcnt;
19330
60bca95a 19331 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19332 if ((flags & l_flags_vals[fcnt].bit) != 0)
19333 {
19334 fputs (l_flags_vals[fcnt].name, stdout);
19335 flags ^= l_flags_vals[fcnt].bit;
19336 }
19337 if (flags != 0)
19338 printf (" %#x", (unsigned int) flags);
252b5132 19339
a6e9f9df
AM
19340 puts ("");
19341 }
252b5132 19342 }
252b5132 19343
a6e9f9df
AM
19344 free (elib);
19345 }
32ec8896 19346 else
015dc7e1 19347 res = false;
252b5132
RH
19348 }
19349
19350 if (options_offset != 0)
19351 {
2cf0635d 19352 Elf_External_Options * eopt;
252b5132
RH
19353 size_t offset;
19354 int cnt;
19355
19356 /* Find the section header so that we get the size. */
dda8d76d 19357 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19358 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19359 if (sect == NULL)
19360 {
19361 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19362 return false;
071436c6 19363 }
7fc0c668
NC
19364 /* PR 24243 */
19365 if (sect->sh_size < sizeof (* eopt))
19366 {
19367 error (_("The MIPS options section is too small.\n"));
015dc7e1 19368 return false;
7fc0c668 19369 }
252b5132 19370
dda8d76d 19371 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19372 sect->sh_size, _("options"));
a6e9f9df 19373 if (eopt)
252b5132 19374 {
fd17d1e6 19375 Elf_Internal_Options option;
76da6bbe 19376
a6e9f9df 19377 offset = cnt = 0;
82b1b41b 19378 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19379 {
2cf0635d 19380 Elf_External_Options * eoption;
fd17d1e6 19381 unsigned int optsize;
252b5132 19382
a6e9f9df 19383 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19384
fd17d1e6 19385 optsize = BYTE_GET (eoption->size);
76da6bbe 19386
82b1b41b 19387 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19388 if (optsize < sizeof (* eopt)
19389 || optsize > sect->sh_size - offset)
82b1b41b 19390 {
645f43a8 19391 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19392 optsize);
645f43a8 19393 free (eopt);
015dc7e1 19394 return false;
82b1b41b 19395 }
fd17d1e6 19396 offset += optsize;
a6e9f9df
AM
19397 ++cnt;
19398 }
252b5132 19399
d3a49aa8
AM
19400 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19401 "\nSection '%s' contains %d entries:\n",
19402 cnt),
dda8d76d 19403 printable_section_name (filedata, sect), cnt);
76da6bbe 19404
82b1b41b 19405 offset = 0;
a6e9f9df 19406 while (cnt-- > 0)
252b5132 19407 {
a6e9f9df 19408 size_t len;
fd17d1e6
AM
19409 Elf_External_Options * eoption;
19410
19411 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19412
19413 option.kind = BYTE_GET (eoption->kind);
19414 option.size = BYTE_GET (eoption->size);
19415 option.section = BYTE_GET (eoption->section);
19416 option.info = BYTE_GET (eoption->info);
a6e9f9df 19417
fd17d1e6 19418 switch (option.kind)
252b5132 19419 {
a6e9f9df
AM
19420 case ODK_NULL:
19421 /* This shouldn't happen. */
d0c4e780 19422 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19423 option.section, option.info);
a6e9f9df 19424 break;
2e6be59c 19425
a6e9f9df
AM
19426 case ODK_REGINFO:
19427 printf (" REGINFO ");
dda8d76d 19428 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19429 {
2cf0635d 19430 Elf32_External_RegInfo * ereg;
b34976b6 19431 Elf32_RegInfo reginfo;
a6e9f9df 19432
2e6be59c 19433 /* 32bit form. */
fd17d1e6
AM
19434 if (option.size < (sizeof (Elf_External_Options)
19435 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19436 {
19437 printf (_("<corrupt>\n"));
19438 error (_("Truncated MIPS REGINFO option\n"));
19439 cnt = 0;
19440 break;
19441 }
19442
fd17d1e6 19443 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19444
a6e9f9df
AM
19445 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19446 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19447 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19448 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19449 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19450 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19451
d0c4e780
AM
19452 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19453 reginfo.ri_gprmask, reginfo.ri_gp_value);
19454 printf (" "
19455 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19456 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19457 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19458 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19459 }
19460 else
19461 {
19462 /* 64 bit form. */
2cf0635d 19463 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19464 Elf64_Internal_RegInfo reginfo;
19465
fd17d1e6
AM
19466 if (option.size < (sizeof (Elf_External_Options)
19467 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19468 {
19469 printf (_("<corrupt>\n"));
19470 error (_("Truncated MIPS REGINFO option\n"));
19471 cnt = 0;
19472 break;
19473 }
19474
fd17d1e6 19475 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19476 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19477 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19478 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19479 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19480 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19481 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19482
d0c4e780
AM
19483 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19484 reginfo.ri_gprmask, reginfo.ri_gp_value);
19485 printf (" "
19486 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19487 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19488 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19489 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19490 }
fd17d1e6 19491 offset += option.size;
a6e9f9df 19492 continue;
2e6be59c 19493
a6e9f9df
AM
19494 case ODK_EXCEPTIONS:
19495 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19496 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19497 fputs (") fpe_max(", stdout);
fd17d1e6 19498 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19499 fputs (")", stdout);
19500
fd17d1e6 19501 if (option.info & OEX_PAGE0)
a6e9f9df 19502 fputs (" PAGE0", stdout);
fd17d1e6 19503 if (option.info & OEX_SMM)
a6e9f9df 19504 fputs (" SMM", stdout);
fd17d1e6 19505 if (option.info & OEX_FPDBUG)
a6e9f9df 19506 fputs (" FPDBUG", stdout);
fd17d1e6 19507 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19508 fputs (" DISMISS", stdout);
19509 break;
2e6be59c 19510
a6e9f9df
AM
19511 case ODK_PAD:
19512 fputs (" PAD ", stdout);
fd17d1e6 19513 if (option.info & OPAD_PREFIX)
a6e9f9df 19514 fputs (" PREFIX", stdout);
fd17d1e6 19515 if (option.info & OPAD_POSTFIX)
a6e9f9df 19516 fputs (" POSTFIX", stdout);
fd17d1e6 19517 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19518 fputs (" SYMBOL", stdout);
19519 break;
2e6be59c 19520
a6e9f9df
AM
19521 case ODK_HWPATCH:
19522 fputs (" HWPATCH ", stdout);
fd17d1e6 19523 if (option.info & OHW_R4KEOP)
a6e9f9df 19524 fputs (" R4KEOP", stdout);
fd17d1e6 19525 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19526 fputs (" R8KPFETCH", stdout);
fd17d1e6 19527 if (option.info & OHW_R5KEOP)
a6e9f9df 19528 fputs (" R5KEOP", stdout);
fd17d1e6 19529 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19530 fputs (" R5KCVTL", stdout);
19531 break;
2e6be59c 19532
a6e9f9df
AM
19533 case ODK_FILL:
19534 fputs (" FILL ", stdout);
19535 /* XXX Print content of info word? */
19536 break;
2e6be59c 19537
a6e9f9df
AM
19538 case ODK_TAGS:
19539 fputs (" TAGS ", stdout);
19540 /* XXX Print content of info word? */
19541 break;
2e6be59c 19542
a6e9f9df
AM
19543 case ODK_HWAND:
19544 fputs (" HWAND ", stdout);
fd17d1e6 19545 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19546 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19547 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19548 fputs (" R4KEOP_CLEAN", stdout);
19549 break;
2e6be59c 19550
a6e9f9df
AM
19551 case ODK_HWOR:
19552 fputs (" HWOR ", stdout);
fd17d1e6 19553 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19554 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19555 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19556 fputs (" R4KEOP_CLEAN", stdout);
19557 break;
2e6be59c 19558
a6e9f9df 19559 case ODK_GP_GROUP:
d0c4e780 19560 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19561 option.info & OGP_GROUP,
19562 (option.info & OGP_SELF) >> 16);
a6e9f9df 19563 break;
2e6be59c 19564
a6e9f9df 19565 case ODK_IDENT:
d0c4e780 19566 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19567 option.info & OGP_GROUP,
19568 (option.info & OGP_SELF) >> 16);
a6e9f9df 19569 break;
2e6be59c 19570
a6e9f9df
AM
19571 default:
19572 /* This shouldn't happen. */
d0c4e780 19573 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19574 option.kind, option.section, option.info);
a6e9f9df 19575 break;
252b5132 19576 }
a6e9f9df 19577
2cf0635d 19578 len = sizeof (* eopt);
fd17d1e6 19579 while (len < option.size)
82b1b41b 19580 {
fd17d1e6 19581 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19582
82b1b41b
NC
19583 if (ISPRINT (datum))
19584 printf ("%c", datum);
19585 else
19586 printf ("\\%03o", datum);
19587 len ++;
19588 }
a6e9f9df 19589 fputs ("\n", stdout);
82b1b41b 19590
fd17d1e6 19591 offset += option.size;
252b5132 19592 }
a6e9f9df 19593 free (eopt);
252b5132 19594 }
32ec8896 19595 else
015dc7e1 19596 res = false;
252b5132
RH
19597 }
19598
19599 if (conflicts_offset != 0 && conflictsno != 0)
19600 {
2cf0635d 19601 Elf32_Conflict * iconf;
252b5132
RH
19602 size_t cnt;
19603
978c4450 19604 if (filedata->dynamic_symbols == NULL)
252b5132 19605 {
591a748a 19606 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19607 return false;
252b5132
RH
19608 }
19609
7296a62a
NC
19610 /* PR 21345 - print a slightly more helpful error message
19611 if we are sure that the cmalloc will fail. */
645f43a8 19612 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19613 {
26c527e6
AM
19614 error (_("Overlarge number of conflicts detected: %zx\n"),
19615 conflictsno);
015dc7e1 19616 return false;
7296a62a
NC
19617 }
19618
3f5e193b 19619 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19620 if (iconf == NULL)
19621 {
8b73c356 19622 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19623 return false;
252b5132
RH
19624 }
19625
9ea033b2 19626 if (is_32bit_elf)
252b5132 19627 {
2cf0635d 19628 Elf32_External_Conflict * econf32;
a6e9f9df 19629
3f5e193b 19630 econf32 = (Elf32_External_Conflict *)
95099889
AM
19631 get_data (NULL, filedata, conflicts_offset,
19632 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19633 if (!econf32)
5a814d6d
AM
19634 {
19635 free (iconf);
015dc7e1 19636 return false;
5a814d6d 19637 }
252b5132
RH
19638
19639 for (cnt = 0; cnt < conflictsno; ++cnt)
19640 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19641
19642 free (econf32);
252b5132
RH
19643 }
19644 else
19645 {
2cf0635d 19646 Elf64_External_Conflict * econf64;
a6e9f9df 19647
3f5e193b 19648 econf64 = (Elf64_External_Conflict *)
95099889
AM
19649 get_data (NULL, filedata, conflicts_offset,
19650 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19651 if (!econf64)
5a814d6d
AM
19652 {
19653 free (iconf);
015dc7e1 19654 return false;
5a814d6d 19655 }
252b5132
RH
19656
19657 for (cnt = 0; cnt < conflictsno; ++cnt)
19658 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19659
19660 free (econf64);
252b5132
RH
19661 }
19662
26c527e6
AM
19663 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19664 "\nSection '.conflict' contains %zu entries:\n",
19665 conflictsno),
19666 conflictsno);
252b5132
RH
19667 puts (_(" Num: Index Value Name"));
19668
19669 for (cnt = 0; cnt < conflictsno; ++cnt)
19670 {
26c527e6 19671 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19672
978c4450 19673 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19674 printf (_("<corrupt symbol index>"));
d79b3d50 19675 else
e0a31db1
NC
19676 {
19677 Elf_Internal_Sym * psym;
19678
978c4450 19679 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19680 print_vma (psym->st_value, FULL_HEX);
19681 putchar (' ');
84714f86 19682 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19683 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19684 else
19685 printf (_("<corrupt: %14ld>"), psym->st_name);
19686 }
31104126 19687 putchar ('\n');
252b5132
RH
19688 }
19689
252b5132
RH
19690 free (iconf);
19691 }
19692
ccb4c951
RS
19693 if (pltgot != 0 && local_gotno != 0)
19694 {
625d49fc 19695 uint64_t ent, local_end, global_end;
bbeee7ea 19696 size_t i, offset;
2cf0635d 19697 unsigned char * data;
82b1b41b 19698 unsigned char * data_end;
bbeee7ea 19699 int addr_size;
ccb4c951 19700
91d6fa6a 19701 ent = pltgot;
ccb4c951
RS
19702 addr_size = (is_32bit_elf ? 4 : 8);
19703 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19704
74e1a04b
NC
19705 /* PR binutils/17533 file: 012-111227-0.004 */
19706 if (symtabno < gotsym)
19707 {
26c527e6
AM
19708 error (_("The GOT symbol offset (%" PRIu64
19709 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19710 gotsym, symtabno);
015dc7e1 19711 return false;
74e1a04b 19712 }
82b1b41b 19713
74e1a04b 19714 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19715 /* PR 17531: file: 54c91a34. */
19716 if (global_end < local_end)
19717 {
26c527e6 19718 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19719 return false;
82b1b41b 19720 }
948f632f 19721
dda8d76d
NC
19722 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19723 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19724 global_end - pltgot, 1,
19725 _("Global Offset Table data"));
919383ac 19726 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19727 data_end = data + (global_end - pltgot);
59245841 19728
ccb4c951
RS
19729 printf (_("\nPrimary GOT:\n"));
19730 printf (_(" Canonical gp value: "));
19731 print_vma (pltgot + 0x7ff0, LONG_HEX);
19732 printf ("\n\n");
19733
19734 printf (_(" Reserved entries:\n"));
19735 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19736 addr_size * 2, _("Address"), _("Access"),
19737 addr_size * 2, _("Initial"));
82b1b41b 19738 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19739 printf (_(" Lazy resolver\n"));
625d49fc 19740 if (ent == (uint64_t) -1)
82b1b41b 19741 goto got_print_fail;
75ec1fdb 19742
c4ab9505
MR
19743 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19744 This entry will be used by some runtime loaders, to store the
19745 module pointer. Otherwise this is an ordinary local entry.
19746 PR 21344: Check for the entry being fully available before
19747 fetching it. */
19748 if (data
19749 && data + ent - pltgot + addr_size <= data_end
19750 && (byte_get (data + ent - pltgot, addr_size)
19751 >> (addr_size * 8 - 1)) != 0)
19752 {
19753 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19754 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19755 if (ent == (uint64_t) -1)
c4ab9505 19756 goto got_print_fail;
ccb4c951
RS
19757 }
19758 printf ("\n");
19759
f17e9d8a 19760 if (data != NULL && ent < local_end)
ccb4c951
RS
19761 {
19762 printf (_(" Local entries:\n"));
cc5914eb 19763 printf (" %*s %10s %*s\n",
2b692964
NC
19764 addr_size * 2, _("Address"), _("Access"),
19765 addr_size * 2, _("Initial"));
91d6fa6a 19766 while (ent < local_end)
ccb4c951 19767 {
82b1b41b 19768 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19769 printf ("\n");
625d49fc 19770 if (ent == (uint64_t) -1)
82b1b41b 19771 goto got_print_fail;
ccb4c951
RS
19772 }
19773 printf ("\n");
19774 }
19775
f17e9d8a 19776 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19777 {
19778 int sym_width;
19779
19780 printf (_(" Global entries:\n"));
cc5914eb 19781 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19782 addr_size * 2, _("Address"),
19783 _("Access"),
2b692964 19784 addr_size * 2, _("Initial"),
9cf03b7e
NC
19785 addr_size * 2, _("Sym.Val."),
19786 _("Type"),
19787 /* Note for translators: "Ndx" = abbreviated form of "Index". */
19788 _("Ndx"), _("Name"));
0b4362b0 19789
ccb4c951 19790 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 19791
ccb4c951
RS
19792 for (i = gotsym; i < symtabno; i++)
19793 {
82b1b41b 19794 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19795 printf (" ");
e0a31db1 19796
978c4450 19797 if (filedata->dynamic_symbols == NULL)
e0a31db1 19798 printf (_("<no dynamic symbols>"));
978c4450 19799 else if (i < filedata->num_dynamic_syms)
e0a31db1 19800 {
978c4450 19801 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
19802
19803 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
19804 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
19805
19806 bool is_special;
19807 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
19808 if (is_special)
19809 printf ("%3s ", s);
19810 else
19811 printf ("%3u ", psym->st_shndx);
e0a31db1 19812
84714f86 19813 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19814 print_symbol_name (sym_width,
84714f86 19815 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19816 else
19817 printf (_("<corrupt: %14ld>"), psym->st_name);
19818 }
ccb4c951 19819 else
26c527e6
AM
19820 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
19821 i);
e0a31db1 19822
ccb4c951 19823 printf ("\n");
625d49fc 19824 if (ent == (uint64_t) -1)
82b1b41b 19825 break;
ccb4c951
RS
19826 }
19827 printf ("\n");
19828 }
19829
82b1b41b 19830 got_print_fail:
9db70fc3 19831 free (data);
ccb4c951
RS
19832 }
19833
861fb55a
DJ
19834 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
19835 {
625d49fc 19836 uint64_t ent, end;
26c527e6
AM
19837 uint64_t offset, rel_offset;
19838 uint64_t count, i;
2cf0635d 19839 unsigned char * data;
861fb55a 19840 int addr_size, sym_width;
2cf0635d 19841 Elf_Internal_Rela * rels;
861fb55a 19842
dda8d76d 19843 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
19844 if (pltrel == DT_RELA)
19845 {
dda8d76d 19846 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19847 return false;
861fb55a
DJ
19848 }
19849 else
19850 {
dda8d76d 19851 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 19852 return false;
861fb55a
DJ
19853 }
19854
91d6fa6a 19855 ent = mips_pltgot;
861fb55a
DJ
19856 addr_size = (is_32bit_elf ? 4 : 8);
19857 end = mips_pltgot + (2 + count) * addr_size;
19858
dda8d76d
NC
19859 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
19860 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 19861 1, _("Procedure Linkage Table data"));
59245841 19862 if (data == NULL)
288f0ba2
AM
19863 {
19864 free (rels);
015dc7e1 19865 return false;
288f0ba2 19866 }
59245841 19867
9cf03b7e 19868 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
19869 printf (_(" Reserved entries:\n"));
19870 printf (_(" %*s %*s Purpose\n"),
2b692964 19871 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 19872 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19873 printf (_(" PLT lazy resolver\n"));
91d6fa6a 19874 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 19875 printf (_(" Module pointer\n"));
861fb55a
DJ
19876 printf ("\n");
19877
19878 printf (_(" Entries:\n"));
cc5914eb 19879 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
19880 addr_size * 2, _("Address"),
19881 addr_size * 2, _("Initial"),
19882 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
19883 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
19884 for (i = 0; i < count; i++)
19885 {
26c527e6 19886 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 19887
91d6fa6a 19888 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 19889 printf (" ");
e0a31db1 19890
978c4450 19891 if (idx >= filedata->num_dynamic_syms)
26c527e6 19892 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 19893 else
e0a31db1 19894 {
978c4450 19895 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
19896
19897 print_vma (psym->st_value, LONG_HEX);
19898 printf (" %-7s %3s ",
dda8d76d 19899 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 19900 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 19901 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19902 print_symbol_name (sym_width,
84714f86 19903 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19904 else
19905 printf (_("<corrupt: %14ld>"), psym->st_name);
19906 }
861fb55a
DJ
19907 printf ("\n");
19908 }
19909 printf ("\n");
19910
9db70fc3 19911 free (data);
861fb55a
DJ
19912 free (rels);
19913 }
19914
32ec8896 19915 return res;
252b5132
RH
19916}
19917
015dc7e1 19918static bool
dda8d76d 19919process_nds32_specific (Filedata * filedata)
35c08157
KLC
19920{
19921 Elf_Internal_Shdr *sect = NULL;
19922
dda8d76d 19923 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 19924 if (sect != NULL && sect->sh_size >= 4)
35c08157 19925 {
9c7b8e9b
AM
19926 unsigned char *buf;
19927 unsigned int flag;
35c08157
KLC
19928
19929 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19930 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19931 _("NDS32 elf flags section"));
35c08157 19932
9c7b8e9b 19933 if (buf == NULL)
015dc7e1 19934 return false;
32ec8896 19935
9c7b8e9b
AM
19936 flag = byte_get (buf, 4);
19937 free (buf);
19938 switch (flag & 0x3)
35c08157
KLC
19939 {
19940 case 0:
19941 printf ("(VEC_SIZE):\tNo entry.\n");
19942 break;
19943 case 1:
19944 printf ("(VEC_SIZE):\t4 bytes\n");
19945 break;
19946 case 2:
19947 printf ("(VEC_SIZE):\t16 bytes\n");
19948 break;
19949 case 3:
19950 printf ("(VEC_SIZE):\treserved\n");
19951 break;
19952 }
19953 }
19954
015dc7e1 19955 return true;
35c08157
KLC
19956}
19957
015dc7e1 19958static bool
dda8d76d 19959process_gnu_liblist (Filedata * filedata)
047b2264 19960{
2cf0635d
NC
19961 Elf_Internal_Shdr * section;
19962 Elf_Internal_Shdr * string_sec;
19963 Elf32_External_Lib * elib;
19964 char * strtab;
c256ffe7 19965 size_t strtab_size;
047b2264 19966 size_t cnt;
26c527e6 19967 uint64_t num_liblist;
047b2264 19968 unsigned i;
015dc7e1 19969 bool res = true;
047b2264
JJ
19970
19971 if (! do_arch)
015dc7e1 19972 return true;
047b2264 19973
dda8d76d
NC
19974 for (i = 0, section = filedata->section_headers;
19975 i < filedata->file_header.e_shnum;
b34976b6 19976 i++, section++)
047b2264
JJ
19977 {
19978 switch (section->sh_type)
19979 {
19980 case SHT_GNU_LIBLIST:
dda8d76d 19981 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19982 break;
19983
3f5e193b 19984 elib = (Elf32_External_Lib *)
dda8d76d 19985 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19986 _("liblist section data"));
047b2264
JJ
19987
19988 if (elib == NULL)
32ec8896 19989 {
015dc7e1 19990 res = false;
32ec8896
NC
19991 break;
19992 }
047b2264 19993
dda8d76d
NC
19994 string_sec = filedata->section_headers + section->sh_link;
19995 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19996 string_sec->sh_size,
19997 _("liblist string table"));
047b2264
JJ
19998 if (strtab == NULL
19999 || section->sh_entsize != sizeof (Elf32_External_Lib))
20000 {
20001 free (elib);
2842702f 20002 free (strtab);
015dc7e1 20003 res = false;
047b2264
JJ
20004 break;
20005 }
59245841 20006 strtab_size = string_sec->sh_size;
047b2264 20007
d3a49aa8 20008 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20009 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20010 " entries:\n",
20011 "\nLibrary list section '%s' contains %" PRIu64
20012 " entries:\n",
d3a49aa8 20013 num_liblist),
dda8d76d 20014 printable_section_name (filedata, section),
d3a49aa8 20015 num_liblist);
047b2264 20016
2b692964 20017 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20018
20019 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20020 ++cnt)
20021 {
20022 Elf32_Lib liblist;
91d6fa6a 20023 time_t atime;
d5b07ef4 20024 char timebuf[128];
2cf0635d 20025 struct tm * tmp;
047b2264
JJ
20026
20027 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20028 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20029 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20030 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20031 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20032
91d6fa6a 20033 tmp = gmtime (&atime);
e9e44622
JJ
20034 snprintf (timebuf, sizeof (timebuf),
20035 "%04u-%02u-%02uT%02u:%02u:%02u",
20036 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20037 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20038
26c527e6 20039 printf ("%3zu: ", cnt);
047b2264 20040 if (do_wide)
c256ffe7 20041 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20042 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20043 else
c256ffe7 20044 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20045 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20046 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20047 liblist.l_version, liblist.l_flags);
20048 }
20049
20050 free (elib);
2842702f 20051 free (strtab);
047b2264
JJ
20052 }
20053 }
20054
32ec8896 20055 return res;
047b2264
JJ
20056}
20057
9437c45b 20058static const char *
dda8d76d 20059get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20060{
20061 static char buff[64];
103f02d3 20062
dda8d76d 20063 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20064 switch (e_type)
20065 {
57346661 20066 case NT_AUXV:
1ec5cd37 20067 return _("NT_AUXV (auxiliary vector)");
57346661 20068 case NT_PRSTATUS:
1ec5cd37 20069 return _("NT_PRSTATUS (prstatus structure)");
57346661 20070 case NT_FPREGSET:
1ec5cd37 20071 return _("NT_FPREGSET (floating point registers)");
57346661 20072 case NT_PRPSINFO:
1ec5cd37 20073 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20074 case NT_TASKSTRUCT:
1ec5cd37 20075 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20076 case NT_GDB_TDESC:
20077 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20078 case NT_PRXFPREG:
1ec5cd37 20079 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20080 case NT_PPC_VMX:
20081 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20082 case NT_PPC_VSX:
20083 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20084 case NT_PPC_TAR:
20085 return _("NT_PPC_TAR (ppc TAR register)");
20086 case NT_PPC_PPR:
20087 return _("NT_PPC_PPR (ppc PPR register)");
20088 case NT_PPC_DSCR:
20089 return _("NT_PPC_DSCR (ppc DSCR register)");
20090 case NT_PPC_EBB:
20091 return _("NT_PPC_EBB (ppc EBB registers)");
20092 case NT_PPC_PMU:
20093 return _("NT_PPC_PMU (ppc PMU registers)");
20094 case NT_PPC_TM_CGPR:
20095 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20096 case NT_PPC_TM_CFPR:
20097 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20098 case NT_PPC_TM_CVMX:
20099 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20100 case NT_PPC_TM_CVSX:
3fd21718 20101 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20102 case NT_PPC_TM_SPR:
20103 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20104 case NT_PPC_TM_CTAR:
20105 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20106 case NT_PPC_TM_CPPR:
20107 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20108 case NT_PPC_TM_CDSCR:
20109 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20110 case NT_386_TLS:
20111 return _("NT_386_TLS (x86 TLS information)");
20112 case NT_386_IOPERM:
20113 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20114 case NT_X86_XSTATE:
20115 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20116 case NT_X86_CET:
20117 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
20118 case NT_S390_HIGH_GPRS:
20119 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20120 case NT_S390_TIMER:
20121 return _("NT_S390_TIMER (s390 timer register)");
20122 case NT_S390_TODCMP:
20123 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20124 case NT_S390_TODPREG:
20125 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20126 case NT_S390_CTRS:
20127 return _("NT_S390_CTRS (s390 control registers)");
20128 case NT_S390_PREFIX:
20129 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20130 case NT_S390_LAST_BREAK:
20131 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20132 case NT_S390_SYSTEM_CALL:
20133 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20134 case NT_S390_TDB:
20135 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20136 case NT_S390_VXRS_LOW:
20137 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20138 case NT_S390_VXRS_HIGH:
20139 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20140 case NT_S390_GS_CB:
20141 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20142 case NT_S390_GS_BC:
20143 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20144 case NT_ARM_VFP:
20145 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20146 case NT_ARM_TLS:
20147 return _("NT_ARM_TLS (AArch TLS registers)");
20148 case NT_ARM_HW_BREAK:
20149 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20150 case NT_ARM_HW_WATCH:
20151 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20152 case NT_ARM_SYSTEM_CALL:
20153 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20154 case NT_ARM_SVE:
20155 return _("NT_ARM_SVE (AArch SVE registers)");
20156 case NT_ARM_PAC_MASK:
20157 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20158 case NT_ARM_PACA_KEYS:
20159 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20160 case NT_ARM_PACG_KEYS:
20161 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20162 case NT_ARM_TAGGED_ADDR_CTRL:
20163 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20164 case NT_ARM_SSVE:
20165 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20166 case NT_ARM_ZA:
20167 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20168 case NT_ARM_ZT:
20169 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20170 case NT_ARM_PAC_ENABLED_KEYS:
20171 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20172 case NT_ARC_V2:
20173 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20174 case NT_RISCV_CSR:
20175 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20176 case NT_PSTATUS:
1ec5cd37 20177 return _("NT_PSTATUS (pstatus structure)");
57346661 20178 case NT_FPREGS:
1ec5cd37 20179 return _("NT_FPREGS (floating point registers)");
57346661 20180 case NT_PSINFO:
1ec5cd37 20181 return _("NT_PSINFO (psinfo structure)");
57346661 20182 case NT_LWPSTATUS:
1ec5cd37 20183 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20184 case NT_LWPSINFO:
1ec5cd37 20185 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20186 case NT_WIN32PSTATUS:
1ec5cd37 20187 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20188 case NT_SIGINFO:
20189 return _("NT_SIGINFO (siginfo_t data)");
20190 case NT_FILE:
20191 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20192 default:
20193 break;
20194 }
20195 else
20196 switch (e_type)
20197 {
20198 case NT_VERSION:
20199 return _("NT_VERSION (version)");
20200 case NT_ARCH:
20201 return _("NT_ARCH (architecture)");
9ef920e9 20202 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20203 return _("OPEN");
9ef920e9 20204 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20205 return _("func");
c8795e1f
NC
20206 case NT_GO_BUILDID:
20207 return _("GO BUILDID");
3ac925fc
LB
20208 case FDO_PACKAGING_METADATA:
20209 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20210 default:
20211 break;
20212 }
20213
e9e44622 20214 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20215 return buff;
779fe533
NC
20216}
20217
015dc7e1 20218static bool
9ece1fa9
TT
20219print_core_note (Elf_Internal_Note *pnote)
20220{
20221 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20222 uint64_t count, page_size;
9ece1fa9
TT
20223 unsigned char *descdata, *filenames, *descend;
20224
20225 if (pnote->type != NT_FILE)
04ac15ab
AS
20226 {
20227 if (do_wide)
20228 printf ("\n");
015dc7e1 20229 return true;
04ac15ab 20230 }
9ece1fa9 20231
9ece1fa9
TT
20232 if (!is_32bit_elf)
20233 {
20234 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
20235 /* Still "successful". */
015dc7e1 20236 return true;
9ece1fa9 20237 }
9ece1fa9
TT
20238
20239 if (pnote->descsz < 2 * addr_size)
20240 {
32ec8896 20241 error (_(" Malformed note - too short for header\n"));
015dc7e1 20242 return false;
9ece1fa9
TT
20243 }
20244
20245 descdata = (unsigned char *) pnote->descdata;
20246 descend = descdata + pnote->descsz;
20247
20248 if (descdata[pnote->descsz - 1] != '\0')
20249 {
32ec8896 20250 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20251 return false;
9ece1fa9
TT
20252 }
20253
20254 count = byte_get (descdata, addr_size);
20255 descdata += addr_size;
20256
20257 page_size = byte_get (descdata, addr_size);
20258 descdata += addr_size;
20259
625d49fc 20260 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20261 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20262 {
32ec8896 20263 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20264 return false;
9ece1fa9
TT
20265 }
20266
20267 printf (_(" Page size: "));
20268 print_vma (page_size, DEC);
20269 printf ("\n");
20270
20271 printf (_(" %*s%*s%*s\n"),
20272 (int) (2 + 2 * addr_size), _("Start"),
20273 (int) (4 + 2 * addr_size), _("End"),
20274 (int) (4 + 2 * addr_size), _("Page Offset"));
20275 filenames = descdata + count * 3 * addr_size;
595712bb 20276 while (count-- > 0)
9ece1fa9 20277 {
625d49fc 20278 uint64_t start, end, file_ofs;
9ece1fa9
TT
20279
20280 if (filenames == descend)
20281 {
32ec8896 20282 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20283 return false;
9ece1fa9
TT
20284 }
20285
20286 start = byte_get (descdata, addr_size);
20287 descdata += addr_size;
20288 end = byte_get (descdata, addr_size);
20289 descdata += addr_size;
20290 file_ofs = byte_get (descdata, addr_size);
20291 descdata += addr_size;
20292
20293 printf (" ");
20294 print_vma (start, FULL_HEX);
20295 printf (" ");
20296 print_vma (end, FULL_HEX);
20297 printf (" ");
20298 print_vma (file_ofs, FULL_HEX);
20299 printf ("\n %s\n", filenames);
20300
20301 filenames += 1 + strlen ((char *) filenames);
20302 }
20303
015dc7e1 20304 return true;
9ece1fa9
TT
20305}
20306
1118d252
RM
20307static const char *
20308get_gnu_elf_note_type (unsigned e_type)
20309{
1449284b 20310 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20311 switch (e_type)
20312 {
20313 case NT_GNU_ABI_TAG:
20314 return _("NT_GNU_ABI_TAG (ABI version tag)");
20315 case NT_GNU_HWCAP:
20316 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20317 case NT_GNU_BUILD_ID:
20318 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20319 case NT_GNU_GOLD_VERSION:
20320 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20321 case NT_GNU_PROPERTY_TYPE_0:
20322 return _("NT_GNU_PROPERTY_TYPE_0");
20323 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20324 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20325 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20326 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20327 default:
1449284b
NC
20328 {
20329 static char buff[64];
1118d252 20330
1449284b
NC
20331 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20332 return buff;
20333 }
20334 }
1118d252
RM
20335}
20336
a9eafb08
L
20337static void
20338decode_x86_compat_isa (unsigned int bitmask)
20339{
20340 while (bitmask)
20341 {
20342 unsigned int bit = bitmask & (- bitmask);
20343
20344 bitmask &= ~ bit;
20345 switch (bit)
20346 {
20347 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20348 printf ("i486");
20349 break;
20350 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20351 printf ("586");
20352 break;
20353 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20354 printf ("686");
20355 break;
20356 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20357 printf ("SSE");
20358 break;
20359 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20360 printf ("SSE2");
20361 break;
20362 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20363 printf ("SSE3");
20364 break;
20365 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20366 printf ("SSSE3");
20367 break;
20368 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20369 printf ("SSE4_1");
20370 break;
20371 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20372 printf ("SSE4_2");
20373 break;
20374 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20375 printf ("AVX");
20376 break;
20377 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20378 printf ("AVX2");
20379 break;
20380 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20381 printf ("AVX512F");
20382 break;
20383 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20384 printf ("AVX512CD");
20385 break;
20386 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20387 printf ("AVX512ER");
20388 break;
20389 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20390 printf ("AVX512PF");
20391 break;
20392 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20393 printf ("AVX512VL");
20394 break;
20395 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20396 printf ("AVX512DQ");
20397 break;
20398 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20399 printf ("AVX512BW");
20400 break;
65b3d26e
L
20401 default:
20402 printf (_("<unknown: %x>"), bit);
20403 break;
a9eafb08
L
20404 }
20405 if (bitmask)
20406 printf (", ");
20407 }
20408}
20409
9ef920e9 20410static void
32930e4e 20411decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20412{
0a59decb 20413 if (!bitmask)
90c745dc
L
20414 {
20415 printf (_("<None>"));
20416 return;
20417 }
90c745dc 20418
9ef920e9
NC
20419 while (bitmask)
20420 {
1fc87489 20421 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20422
20423 bitmask &= ~ bit;
20424 switch (bit)
20425 {
32930e4e 20426 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20427 printf ("CMOV");
20428 break;
32930e4e 20429 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20430 printf ("SSE");
20431 break;
32930e4e 20432 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20433 printf ("SSE2");
20434 break;
32930e4e 20435 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20436 printf ("SSE3");
20437 break;
32930e4e 20438 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20439 printf ("SSSE3");
20440 break;
32930e4e 20441 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20442 printf ("SSE4_1");
20443 break;
32930e4e 20444 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20445 printf ("SSE4_2");
20446 break;
32930e4e 20447 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20448 printf ("AVX");
20449 break;
32930e4e 20450 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20451 printf ("AVX2");
20452 break;
32930e4e 20453 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20454 printf ("FMA");
20455 break;
32930e4e 20456 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20457 printf ("AVX512F");
20458 break;
32930e4e 20459 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20460 printf ("AVX512CD");
20461 break;
32930e4e 20462 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20463 printf ("AVX512ER");
20464 break;
32930e4e 20465 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20466 printf ("AVX512PF");
20467 break;
32930e4e 20468 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20469 printf ("AVX512VL");
20470 break;
32930e4e 20471 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20472 printf ("AVX512DQ");
20473 break;
32930e4e 20474 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20475 printf ("AVX512BW");
20476 break;
32930e4e 20477 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20478 printf ("AVX512_4FMAPS");
20479 break;
32930e4e 20480 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20481 printf ("AVX512_4VNNIW");
20482 break;
32930e4e 20483 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20484 printf ("AVX512_BITALG");
20485 break;
32930e4e 20486 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20487 printf ("AVX512_IFMA");
20488 break;
32930e4e 20489 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20490 printf ("AVX512_VBMI");
20491 break;
32930e4e 20492 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20493 printf ("AVX512_VBMI2");
20494 break;
32930e4e 20495 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20496 printf ("AVX512_VNNI");
20497 break;
32930e4e 20498 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20499 printf ("AVX512_BF16");
20500 break;
65b3d26e
L
20501 default:
20502 printf (_("<unknown: %x>"), bit);
20503 break;
9ef920e9
NC
20504 }
20505 if (bitmask)
20506 printf (", ");
20507 }
20508}
20509
28cdbb18
SM
20510static const char *
20511get_amdgpu_elf_note_type (unsigned int e_type)
20512{
20513 switch (e_type)
20514 {
20515 case NT_AMDGPU_METADATA:
20516 return _("NT_AMDGPU_METADATA (code object metadata)");
20517 default:
20518 {
20519 static char buf[64];
20520 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20521 return buf;
20522 }
20523 }
20524}
20525
32930e4e
L
20526static void
20527decode_x86_isa (unsigned int bitmask)
20528{
32930e4e
L
20529 while (bitmask)
20530 {
20531 unsigned int bit = bitmask & (- bitmask);
20532
20533 bitmask &= ~ bit;
20534 switch (bit)
20535 {
b0ab0693
L
20536 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20537 printf ("x86-64-baseline");
20538 break;
32930e4e
L
20539 case GNU_PROPERTY_X86_ISA_1_V2:
20540 printf ("x86-64-v2");
20541 break;
20542 case GNU_PROPERTY_X86_ISA_1_V3:
20543 printf ("x86-64-v3");
20544 break;
20545 case GNU_PROPERTY_X86_ISA_1_V4:
20546 printf ("x86-64-v4");
20547 break;
20548 default:
20549 printf (_("<unknown: %x>"), bit);
20550 break;
20551 }
20552 if (bitmask)
20553 printf (", ");
20554 }
20555}
20556
ee2fdd6f 20557static void
a9eafb08 20558decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20559{
0a59decb 20560 if (!bitmask)
90c745dc
L
20561 {
20562 printf (_("<None>"));
20563 return;
20564 }
90c745dc 20565
ee2fdd6f
L
20566 while (bitmask)
20567 {
20568 unsigned int bit = bitmask & (- bitmask);
20569
20570 bitmask &= ~ bit;
20571 switch (bit)
20572 {
20573 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20574 printf ("IBT");
ee2fdd6f 20575 break;
48580982 20576 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20577 printf ("SHSTK");
48580982 20578 break;
279d901e
L
20579 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20580 printf ("LAM_U48");
20581 break;
20582 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20583 printf ("LAM_U57");
20584 break;
ee2fdd6f
L
20585 default:
20586 printf (_("<unknown: %x>"), bit);
20587 break;
20588 }
20589 if (bitmask)
20590 printf (", ");
20591 }
20592}
20593
a9eafb08
L
20594static void
20595decode_x86_feature_2 (unsigned int bitmask)
20596{
0a59decb 20597 if (!bitmask)
90c745dc
L
20598 {
20599 printf (_("<None>"));
20600 return;
20601 }
90c745dc 20602
a9eafb08
L
20603 while (bitmask)
20604 {
20605 unsigned int bit = bitmask & (- bitmask);
20606
20607 bitmask &= ~ bit;
20608 switch (bit)
20609 {
20610 case GNU_PROPERTY_X86_FEATURE_2_X86:
20611 printf ("x86");
20612 break;
20613 case GNU_PROPERTY_X86_FEATURE_2_X87:
20614 printf ("x87");
20615 break;
20616 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20617 printf ("MMX");
20618 break;
20619 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20620 printf ("XMM");
20621 break;
20622 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20623 printf ("YMM");
20624 break;
20625 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20626 printf ("ZMM");
20627 break;
a308b89d
L
20628 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20629 printf ("TMM");
20630 break;
32930e4e
L
20631 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20632 printf ("MASK");
20633 break;
a9eafb08
L
20634 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20635 printf ("FXSR");
20636 break;
20637 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20638 printf ("XSAVE");
20639 break;
20640 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20641 printf ("XSAVEOPT");
20642 break;
20643 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20644 printf ("XSAVEC");
20645 break;
65b3d26e
L
20646 default:
20647 printf (_("<unknown: %x>"), bit);
20648 break;
a9eafb08
L
20649 }
20650 if (bitmask)
20651 printf (", ");
20652 }
20653}
20654
cd702818
SD
20655static void
20656decode_aarch64_feature_1_and (unsigned int bitmask)
20657{
20658 while (bitmask)
20659 {
20660 unsigned int bit = bitmask & (- bitmask);
20661
20662 bitmask &= ~ bit;
20663 switch (bit)
20664 {
20665 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20666 printf ("BTI");
20667 break;
20668
20669 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20670 printf ("PAC");
20671 break;
20672
20673 default:
20674 printf (_("<unknown: %x>"), bit);
20675 break;
20676 }
20677 if (bitmask)
20678 printf (", ");
20679 }
20680}
20681
6320fd00
L
20682static void
20683decode_1_needed (unsigned int bitmask)
20684{
20685 while (bitmask)
20686 {
20687 unsigned int bit = bitmask & (- bitmask);
20688
20689 bitmask &= ~ bit;
20690 switch (bit)
20691 {
20692 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20693 printf ("indirect external access");
20694 break;
20695 default:
20696 printf (_("<unknown: %x>"), bit);
20697 break;
20698 }
20699 if (bitmask)
20700 printf (", ");
20701 }
20702}
20703
9ef920e9 20704static void
dda8d76d 20705print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20706{
20707 unsigned char * ptr = (unsigned char *) pnote->descdata;
20708 unsigned char * ptr_end = ptr + pnote->descsz;
20709 unsigned int size = is_32bit_elf ? 4 : 8;
20710
20711 printf (_(" Properties: "));
20712
1fc87489 20713 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20714 {
20715 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20716 return;
20717 }
20718
6ab2c4ed 20719 while (ptr < ptr_end)
9ef920e9 20720 {
1fc87489 20721 unsigned int j;
6ab2c4ed
MC
20722 unsigned int type;
20723 unsigned int datasz;
20724
20725 if ((size_t) (ptr_end - ptr) < 8)
20726 {
20727 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20728 break;
20729 }
20730
20731 type = byte_get (ptr, 4);
20732 datasz = byte_get (ptr + 4, 4);
9ef920e9 20733
1fc87489 20734 ptr += 8;
9ef920e9 20735
6ab2c4ed 20736 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20737 {
1fc87489
L
20738 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20739 type, datasz);
9ef920e9 20740 break;
1fc87489 20741 }
9ef920e9 20742
1fc87489
L
20743 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20744 {
dda8d76d
NC
20745 if (filedata->file_header.e_machine == EM_X86_64
20746 || filedata->file_header.e_machine == EM_IAMCU
20747 || filedata->file_header.e_machine == EM_386)
1fc87489 20748 {
aa7bca9b
L
20749 unsigned int bitmask;
20750
20751 if (datasz == 4)
0a59decb 20752 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20753 else
20754 bitmask = 0;
20755
1fc87489
L
20756 switch (type)
20757 {
20758 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20759 if (datasz != 4)
aa7bca9b
L
20760 printf (_("x86 ISA used: <corrupt length: %#x> "),
20761 datasz);
1fc87489 20762 else
aa7bca9b
L
20763 {
20764 printf ("x86 ISA used: ");
20765 decode_x86_isa (bitmask);
20766 }
1fc87489 20767 goto next;
9ef920e9 20768
1fc87489 20769 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20770 if (datasz != 4)
aa7bca9b
L
20771 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20772 datasz);
1fc87489 20773 else
aa7bca9b
L
20774 {
20775 printf ("x86 ISA needed: ");
20776 decode_x86_isa (bitmask);
20777 }
1fc87489 20778 goto next;
9ef920e9 20779
ee2fdd6f 20780 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20781 if (datasz != 4)
aa7bca9b
L
20782 printf (_("x86 feature: <corrupt length: %#x> "),
20783 datasz);
ee2fdd6f 20784 else
aa7bca9b
L
20785 {
20786 printf ("x86 feature: ");
a9eafb08
L
20787 decode_x86_feature_1 (bitmask);
20788 }
20789 goto next;
20790
20791 case GNU_PROPERTY_X86_FEATURE_2_USED:
20792 if (datasz != 4)
20793 printf (_("x86 feature used: <corrupt length: %#x> "),
20794 datasz);
20795 else
20796 {
20797 printf ("x86 feature used: ");
20798 decode_x86_feature_2 (bitmask);
20799 }
20800 goto next;
20801
20802 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
20803 if (datasz != 4)
20804 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
20805 else
20806 {
20807 printf ("x86 feature needed: ");
20808 decode_x86_feature_2 (bitmask);
20809 }
20810 goto next;
20811
20812 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
20813 if (datasz != 4)
20814 printf (_("x86 ISA used: <corrupt length: %#x> "),
20815 datasz);
20816 else
20817 {
20818 printf ("x86 ISA used: ");
20819 decode_x86_compat_isa (bitmask);
20820 }
20821 goto next;
20822
20823 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
20824 if (datasz != 4)
20825 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20826 datasz);
20827 else
20828 {
20829 printf ("x86 ISA needed: ");
20830 decode_x86_compat_isa (bitmask);
aa7bca9b 20831 }
ee2fdd6f
L
20832 goto next;
20833
32930e4e
L
20834 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
20835 if (datasz != 4)
20836 printf (_("x86 ISA used: <corrupt length: %#x> "),
20837 datasz);
20838 else
20839 {
20840 printf ("x86 ISA used: ");
20841 decode_x86_compat_2_isa (bitmask);
20842 }
20843 goto next;
20844
20845 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
20846 if (datasz != 4)
20847 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20848 datasz);
20849 else
20850 {
20851 printf ("x86 ISA needed: ");
20852 decode_x86_compat_2_isa (bitmask);
20853 }
20854 goto next;
20855
1fc87489
L
20856 default:
20857 break;
20858 }
20859 }
cd702818
SD
20860 else if (filedata->file_header.e_machine == EM_AARCH64)
20861 {
20862 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
20863 {
20864 printf ("AArch64 feature: ");
20865 if (datasz != 4)
20866 printf (_("<corrupt length: %#x> "), datasz);
20867 else
20868 decode_aarch64_feature_1_and (byte_get (ptr, 4));
20869 goto next;
20870 }
20871 }
1fc87489
L
20872 }
20873 else
20874 {
20875 switch (type)
9ef920e9 20876 {
1fc87489
L
20877 case GNU_PROPERTY_STACK_SIZE:
20878 printf (_("stack size: "));
20879 if (datasz != size)
20880 printf (_("<corrupt length: %#x> "), datasz);
20881 else
26c527e6 20882 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
20883 goto next;
20884
20885 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
20886 printf ("no copy on protected ");
20887 if (datasz)
20888 printf (_("<corrupt length: %#x> "), datasz);
20889 goto next;
20890
20891 default:
5a767724
L
20892 if ((type >= GNU_PROPERTY_UINT32_AND_LO
20893 && type <= GNU_PROPERTY_UINT32_AND_HI)
20894 || (type >= GNU_PROPERTY_UINT32_OR_LO
20895 && type <= GNU_PROPERTY_UINT32_OR_HI))
20896 {
6320fd00
L
20897 switch (type)
20898 {
20899 case GNU_PROPERTY_1_NEEDED:
20900 if (datasz != 4)
20901 printf (_("1_needed: <corrupt length: %#x> "),
20902 datasz);
20903 else
20904 {
20905 unsigned int bitmask = byte_get (ptr, 4);
20906 printf ("1_needed: ");
20907 decode_1_needed (bitmask);
20908 }
20909 goto next;
20910
20911 default:
20912 break;
20913 }
5a767724
L
20914 if (type <= GNU_PROPERTY_UINT32_AND_HI)
20915 printf (_("UINT32_AND (%#x): "), type);
20916 else
20917 printf (_("UINT32_OR (%#x): "), type);
20918 if (datasz != 4)
20919 printf (_("<corrupt length: %#x> "), datasz);
20920 else
20921 printf ("%#x", (unsigned int) byte_get (ptr, 4));
20922 goto next;
20923 }
9ef920e9
NC
20924 break;
20925 }
9ef920e9
NC
20926 }
20927
1fc87489
L
20928 if (type < GNU_PROPERTY_LOPROC)
20929 printf (_("<unknown type %#x data: "), type);
20930 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 20931 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
20932 else
20933 printf (_("<application-specific type %#x data: "), type);
20934 for (j = 0; j < datasz; ++j)
20935 printf ("%02x ", ptr[j] & 0xff);
20936 printf (">");
20937
dc1e8a47 20938 next:
9ef920e9 20939 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
20940 if (ptr == ptr_end)
20941 break;
1fc87489 20942
6ab2c4ed
MC
20943 if (do_wide)
20944 printf (", ");
20945 else
20946 printf ("\n\t");
9ef920e9
NC
20947 }
20948
20949 printf ("\n");
20950}
20951
015dc7e1 20952static bool
dda8d76d 20953print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20954{
1449284b 20955 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20956 switch (pnote->type)
20957 {
20958 case NT_GNU_BUILD_ID:
20959 {
26c527e6 20960 size_t i;
664f90a3
TT
20961
20962 printf (_(" Build ID: "));
20963 for (i = 0; i < pnote->descsz; ++i)
20964 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20965 printf ("\n");
664f90a3
TT
20966 }
20967 break;
20968
20969 case NT_GNU_ABI_TAG:
20970 {
26c527e6 20971 unsigned int os, major, minor, subminor;
664f90a3
TT
20972 const char *osname;
20973
3102e897
NC
20974 /* PR 17531: file: 030-599401-0.004. */
20975 if (pnote->descsz < 16)
20976 {
20977 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20978 break;
20979 }
20980
664f90a3
TT
20981 os = byte_get ((unsigned char *) pnote->descdata, 4);
20982 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20983 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20984 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20985
20986 switch (os)
20987 {
20988 case GNU_ABI_TAG_LINUX:
20989 osname = "Linux";
20990 break;
20991 case GNU_ABI_TAG_HURD:
20992 osname = "Hurd";
20993 break;
20994 case GNU_ABI_TAG_SOLARIS:
20995 osname = "Solaris";
20996 break;
20997 case GNU_ABI_TAG_FREEBSD:
20998 osname = "FreeBSD";
20999 break;
21000 case GNU_ABI_TAG_NETBSD:
21001 osname = "NetBSD";
21002 break;
14ae95f2
RM
21003 case GNU_ABI_TAG_SYLLABLE:
21004 osname = "Syllable";
21005 break;
21006 case GNU_ABI_TAG_NACL:
21007 osname = "NaCl";
21008 break;
664f90a3
TT
21009 default:
21010 osname = "Unknown";
21011 break;
21012 }
21013
26c527e6 21014 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21015 major, minor, subminor);
21016 }
21017 break;
926c5385
CC
21018
21019 case NT_GNU_GOLD_VERSION:
21020 {
26c527e6 21021 size_t i;
926c5385
CC
21022
21023 printf (_(" Version: "));
21024 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21025 printf ("%c", pnote->descdata[i]);
21026 printf ("\n");
21027 }
21028 break;
1449284b
NC
21029
21030 case NT_GNU_HWCAP:
21031 {
26c527e6 21032 unsigned int num_entries, mask;
1449284b
NC
21033
21034 /* Hardware capabilities information. Word 0 is the number of entries.
21035 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21036 is a series of entries, where each entry is a single byte followed
21037 by a nul terminated string. The byte gives the bit number to test
21038 if enabled in the bitmask. */
21039 printf (_(" Hardware Capabilities: "));
21040 if (pnote->descsz < 8)
21041 {
32ec8896 21042 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21043 return false;
1449284b
NC
21044 }
21045 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21046 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21047 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21048 /* FIXME: Add code to display the entries... */
21049 }
21050 break;
21051
9ef920e9 21052 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21053 print_gnu_property_note (filedata, pnote);
9ef920e9 21054 break;
9abca702 21055
1449284b
NC
21056 default:
21057 /* Handle unrecognised types. An error message should have already been
21058 created by get_gnu_elf_note_type(), so all that we need to do is to
21059 display the data. */
21060 {
26c527e6 21061 size_t i;
1449284b
NC
21062
21063 printf (_(" Description data: "));
21064 for (i = 0; i < pnote->descsz; ++i)
21065 printf ("%02x ", pnote->descdata[i] & 0xff);
21066 printf ("\n");
21067 }
21068 break;
664f90a3
TT
21069 }
21070
015dc7e1 21071 return true;
664f90a3
TT
21072}
21073
685080f2
NC
21074static const char *
21075get_v850_elf_note_type (enum v850_notes n_type)
21076{
21077 static char buff[64];
21078
21079 switch (n_type)
21080 {
21081 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21082 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21083 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21084 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21085 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21086 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21087 default:
21088 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21089 return buff;
21090 }
21091}
21092
015dc7e1 21093static bool
685080f2
NC
21094print_v850_note (Elf_Internal_Note * pnote)
21095{
21096 unsigned int val;
21097
21098 if (pnote->descsz != 4)
015dc7e1 21099 return false;
32ec8896 21100
685080f2
NC
21101 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21102
21103 if (val == 0)
21104 {
21105 printf (_("not set\n"));
015dc7e1 21106 return true;
685080f2
NC
21107 }
21108
21109 switch (pnote->type)
21110 {
21111 case V850_NOTE_ALIGNMENT:
21112 switch (val)
21113 {
015dc7e1
AM
21114 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21115 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21116 }
21117 break;
14ae95f2 21118
685080f2
NC
21119 case V850_NOTE_DATA_SIZE:
21120 switch (val)
21121 {
015dc7e1
AM
21122 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21123 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21124 }
21125 break;
14ae95f2 21126
685080f2
NC
21127 case V850_NOTE_FPU_INFO:
21128 switch (val)
21129 {
015dc7e1
AM
21130 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21131 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21132 }
21133 break;
14ae95f2 21134
685080f2
NC
21135 case V850_NOTE_MMU_INFO:
21136 case V850_NOTE_CACHE_INFO:
21137 case V850_NOTE_SIMD_INFO:
21138 if (val == EF_RH850_SIMD)
21139 {
21140 printf (_("yes\n"));
015dc7e1 21141 return true;
685080f2
NC
21142 }
21143 break;
21144
21145 default:
21146 /* An 'unknown note type' message will already have been displayed. */
21147 break;
21148 }
21149
21150 printf (_("unknown value: %x\n"), val);
015dc7e1 21151 return false;
685080f2
NC
21152}
21153
015dc7e1 21154static bool
c6056a74
SF
21155process_netbsd_elf_note (Elf_Internal_Note * pnote)
21156{
21157 unsigned int version;
21158
21159 switch (pnote->type)
21160 {
21161 case NT_NETBSD_IDENT:
b966f55f
AM
21162 if (pnote->descsz < 1)
21163 break;
c6056a74
SF
21164 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21165 if ((version / 10000) % 100)
b966f55f 21166 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21167 version, version / 100000000, (version / 1000000) % 100,
21168 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21169 'A' + (version / 10000) % 26);
c6056a74
SF
21170 else
21171 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21172 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21173 (version / 100) % 100);
015dc7e1 21174 return true;
c6056a74
SF
21175
21176 case NT_NETBSD_MARCH:
9abca702 21177 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21178 pnote->descdata);
015dc7e1 21179 return true;
c6056a74 21180
9abca702 21181 case NT_NETBSD_PAX:
b966f55f
AM
21182 if (pnote->descsz < 1)
21183 break;
9abca702
CZ
21184 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21185 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21186 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21187 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21188 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21189 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21190 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21191 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21192 return true;
c6056a74 21193 }
b966f55f
AM
21194
21195 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21196 pnote->descsz, pnote->type);
015dc7e1 21197 return false;
c6056a74
SF
21198}
21199
f4ddf30f 21200static const char *
dda8d76d 21201get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21202{
f4ddf30f
JB
21203 switch (e_type)
21204 {
21205 case NT_FREEBSD_THRMISC:
21206 return _("NT_THRMISC (thrmisc structure)");
21207 case NT_FREEBSD_PROCSTAT_PROC:
21208 return _("NT_PROCSTAT_PROC (proc data)");
21209 case NT_FREEBSD_PROCSTAT_FILES:
21210 return _("NT_PROCSTAT_FILES (files data)");
21211 case NT_FREEBSD_PROCSTAT_VMMAP:
21212 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21213 case NT_FREEBSD_PROCSTAT_GROUPS:
21214 return _("NT_PROCSTAT_GROUPS (groups data)");
21215 case NT_FREEBSD_PROCSTAT_UMASK:
21216 return _("NT_PROCSTAT_UMASK (umask data)");
21217 case NT_FREEBSD_PROCSTAT_RLIMIT:
21218 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21219 case NT_FREEBSD_PROCSTAT_OSREL:
21220 return _("NT_PROCSTAT_OSREL (osreldate data)");
21221 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21222 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21223 case NT_FREEBSD_PROCSTAT_AUXV:
21224 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21225 case NT_FREEBSD_PTLWPINFO:
21226 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21227 case NT_FREEBSD_X86_SEGBASES:
21228 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21229 }
dda8d76d 21230 return get_note_type (filedata, e_type);
f4ddf30f
JB
21231}
21232
9437c45b 21233static const char *
dda8d76d 21234get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21235{
21236 static char buff[64];
21237
540e6170
CZ
21238 switch (e_type)
21239 {
21240 case NT_NETBSDCORE_PROCINFO:
21241 /* NetBSD core "procinfo" structure. */
21242 return _("NetBSD procinfo structure");
9437c45b 21243
540e6170
CZ
21244 case NT_NETBSDCORE_AUXV:
21245 return _("NetBSD ELF auxiliary vector data");
9437c45b 21246
06d949ec
KR
21247 case NT_NETBSDCORE_LWPSTATUS:
21248 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21249
540e6170 21250 default:
06d949ec 21251 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21252 defined for NetBSD core files. If the note type is less
21253 than the start of the machine-dependent note types, we don't
21254 understand it. */
21255
21256 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21257 {
21258 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21259 return buff;
21260 }
21261 break;
9437c45b
JT
21262 }
21263
dda8d76d 21264 switch (filedata->file_header.e_machine)
9437c45b
JT
21265 {
21266 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21267 and PT_GETFPREGS == mach+2. */
21268
21269 case EM_OLD_ALPHA:
21270 case EM_ALPHA:
21271 case EM_SPARC:
21272 case EM_SPARC32PLUS:
21273 case EM_SPARCV9:
21274 switch (e_type)
21275 {
2b692964 21276 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21277 return _("PT_GETREGS (reg structure)");
2b692964 21278 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21279 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21280 default:
21281 break;
21282 }
21283 break;
21284
c0d38b0e
CZ
21285 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21286 There's also old PT___GETREGS40 == mach + 1 for old reg
21287 structure which lacks GBR. */
21288 case EM_SH:
21289 switch (e_type)
21290 {
21291 case NT_NETBSDCORE_FIRSTMACH + 1:
21292 return _("PT___GETREGS40 (old reg structure)");
21293 case NT_NETBSDCORE_FIRSTMACH + 3:
21294 return _("PT_GETREGS (reg structure)");
21295 case NT_NETBSDCORE_FIRSTMACH + 5:
21296 return _("PT_GETFPREGS (fpreg structure)");
21297 default:
21298 break;
21299 }
21300 break;
21301
9437c45b
JT
21302 /* On all other arch's, PT_GETREGS == mach+1 and
21303 PT_GETFPREGS == mach+3. */
21304 default:
21305 switch (e_type)
21306 {
2b692964 21307 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21308 return _("PT_GETREGS (reg structure)");
2b692964 21309 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21310 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21311 default:
21312 break;
21313 }
21314 }
21315
9cf03b7e 21316 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21317 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21318 return buff;
21319}
21320
98ca73af
FC
21321static const char *
21322get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21323{
21324 switch (e_type)
21325 {
21326 case NT_OPENBSD_PROCINFO:
21327 return _("OpenBSD procinfo structure");
21328 case NT_OPENBSD_AUXV:
21329 return _("OpenBSD ELF auxiliary vector data");
21330 case NT_OPENBSD_REGS:
21331 return _("OpenBSD regular registers");
21332 case NT_OPENBSD_FPREGS:
21333 return _("OpenBSD floating point registers");
21334 case NT_OPENBSD_WCOOKIE:
21335 return _("OpenBSD window cookie");
21336 }
21337
21338 return get_note_type (filedata, e_type);
21339}
21340
e263a66b
CC
21341static const char *
21342get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21343{
21344 switch (e_type)
21345 {
21346 case QNT_DEBUG_FULLPATH:
21347 return _("QNX debug fullpath");
21348 case QNT_DEBUG_RELOC:
21349 return _("QNX debug relocation");
21350 case QNT_STACK:
21351 return _("QNX stack");
21352 case QNT_GENERATOR:
21353 return _("QNX generator");
21354 case QNT_DEFAULT_LIB:
21355 return _("QNX default library");
21356 case QNT_CORE_SYSINFO:
21357 return _("QNX core sysinfo");
21358 case QNT_CORE_INFO:
21359 return _("QNX core info");
21360 case QNT_CORE_STATUS:
21361 return _("QNX core status");
21362 case QNT_CORE_GREG:
21363 return _("QNX general registers");
21364 case QNT_CORE_FPREG:
21365 return _("QNX floating point registers");
21366 case QNT_LINK_MAP:
21367 return _("QNX link map");
21368 }
21369
21370 return get_note_type (filedata, e_type);
21371}
21372
70616151
TT
21373static const char *
21374get_stapsdt_note_type (unsigned e_type)
21375{
21376 static char buff[64];
21377
21378 switch (e_type)
21379 {
21380 case NT_STAPSDT:
21381 return _("NT_STAPSDT (SystemTap probe descriptors)");
21382
21383 default:
21384 break;
21385 }
21386
21387 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21388 return buff;
21389}
21390
015dc7e1 21391static bool
c6a9fc58
TT
21392print_stapsdt_note (Elf_Internal_Note *pnote)
21393{
3ca60c57 21394 size_t len, maxlen;
26c527e6 21395 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21396 char *data = pnote->descdata;
21397 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21398 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21399 char *provider, *probe, *arg_fmt;
21400
3ca60c57
NC
21401 if (pnote->descsz < (addr_size * 3))
21402 goto stapdt_note_too_small;
21403
c6a9fc58
TT
21404 pc = byte_get ((unsigned char *) data, addr_size);
21405 data += addr_size;
3ca60c57 21406
c6a9fc58
TT
21407 base_addr = byte_get ((unsigned char *) data, addr_size);
21408 data += addr_size;
3ca60c57 21409
c6a9fc58
TT
21410 semaphore = byte_get ((unsigned char *) data, addr_size);
21411 data += addr_size;
21412
3ca60c57
NC
21413 if (data >= data_end)
21414 goto stapdt_note_too_small;
21415 maxlen = data_end - data;
21416 len = strnlen (data, maxlen);
21417 if (len < maxlen)
21418 {
21419 provider = data;
21420 data += len + 1;
21421 }
21422 else
21423 goto stapdt_note_too_small;
21424
21425 if (data >= data_end)
21426 goto stapdt_note_too_small;
21427 maxlen = data_end - data;
21428 len = strnlen (data, maxlen);
21429 if (len < maxlen)
21430 {
21431 probe = data;
21432 data += len + 1;
21433 }
21434 else
21435 goto stapdt_note_too_small;
9abca702 21436
3ca60c57
NC
21437 if (data >= data_end)
21438 goto stapdt_note_too_small;
21439 maxlen = data_end - data;
21440 len = strnlen (data, maxlen);
21441 if (len < maxlen)
21442 {
21443 arg_fmt = data;
21444 data += len + 1;
21445 }
21446 else
21447 goto stapdt_note_too_small;
c6a9fc58
TT
21448
21449 printf (_(" Provider: %s\n"), provider);
21450 printf (_(" Name: %s\n"), probe);
21451 printf (_(" Location: "));
21452 print_vma (pc, FULL_HEX);
21453 printf (_(", Base: "));
21454 print_vma (base_addr, FULL_HEX);
21455 printf (_(", Semaphore: "));
21456 print_vma (semaphore, FULL_HEX);
9cf03b7e 21457 printf ("\n");
c6a9fc58
TT
21458 printf (_(" Arguments: %s\n"), arg_fmt);
21459
21460 return data == data_end;
3ca60c57
NC
21461
21462 stapdt_note_too_small:
21463 printf (_(" <corrupt - note is too small>\n"));
21464 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21465 return false;
c6a9fc58
TT
21466}
21467
e5382207
LB
21468static bool
21469print_fdo_note (Elf_Internal_Note * pnote)
21470{
21471 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21472 {
21473 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21474 return true;
21475 }
21476 return false;
21477}
21478
00e98fc7
TG
21479static const char *
21480get_ia64_vms_note_type (unsigned e_type)
21481{
21482 static char buff[64];
21483
21484 switch (e_type)
21485 {
21486 case NT_VMS_MHD:
21487 return _("NT_VMS_MHD (module header)");
21488 case NT_VMS_LNM:
21489 return _("NT_VMS_LNM (language name)");
21490 case NT_VMS_SRC:
21491 return _("NT_VMS_SRC (source files)");
21492 case NT_VMS_TITLE:
9cf03b7e 21493 return "NT_VMS_TITLE";
00e98fc7
TG
21494 case NT_VMS_EIDC:
21495 return _("NT_VMS_EIDC (consistency check)");
21496 case NT_VMS_FPMODE:
21497 return _("NT_VMS_FPMODE (FP mode)");
21498 case NT_VMS_LINKTIME:
9cf03b7e 21499 return "NT_VMS_LINKTIME";
00e98fc7
TG
21500 case NT_VMS_IMGNAM:
21501 return _("NT_VMS_IMGNAM (image name)");
21502 case NT_VMS_IMGID:
21503 return _("NT_VMS_IMGID (image id)");
21504 case NT_VMS_LINKID:
21505 return _("NT_VMS_LINKID (link id)");
21506 case NT_VMS_IMGBID:
21507 return _("NT_VMS_IMGBID (build id)");
21508 case NT_VMS_GSTNAM:
21509 return _("NT_VMS_GSTNAM (sym table name)");
21510 case NT_VMS_ORIG_DYN:
9cf03b7e 21511 return "NT_VMS_ORIG_DYN";
00e98fc7 21512 case NT_VMS_PATCHTIME:
9cf03b7e 21513 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21514 default:
21515 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21516 return buff;
21517 }
21518}
21519
015dc7e1 21520static bool
00e98fc7
TG
21521print_ia64_vms_note (Elf_Internal_Note * pnote)
21522{
26c527e6 21523 unsigned int maxlen = pnote->descsz;
8d18bf79 21524
26c527e6 21525 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21526 goto desc_size_fail;
21527
00e98fc7
TG
21528 switch (pnote->type)
21529 {
21530 case NT_VMS_MHD:
8d18bf79
NC
21531 if (maxlen <= 36)
21532 goto desc_size_fail;
21533
26c527e6 21534 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21535
21536 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21537 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21538 if (l + 34 < maxlen)
21539 {
21540 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21541 if (l + 35 < maxlen)
21542 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21543 else
21544 printf (_(" Module version : <missing>\n"));
21545 }
00e98fc7 21546 else
8d18bf79
NC
21547 {
21548 printf (_(" Module name : <missing>\n"));
21549 printf (_(" Module version : <missing>\n"));
21550 }
00e98fc7 21551 break;
8d18bf79 21552
00e98fc7 21553 case NT_VMS_LNM:
8d18bf79 21554 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21555 break;
8d18bf79 21556
00e98fc7 21557 case NT_VMS_FPMODE:
9cf03b7e 21558 printf (_(" Floating Point mode: "));
8d18bf79
NC
21559 if (maxlen < 8)
21560 goto desc_size_fail;
21561 /* FIXME: Generate an error if descsz > 8 ? */
21562
b8281767 21563 printf ("0x%016" PRIx64 "\n",
625d49fc 21564 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21565 break;
8d18bf79 21566
00e98fc7
TG
21567 case NT_VMS_LINKTIME:
21568 printf (_(" Link time: "));
8d18bf79
NC
21569 if (maxlen < 8)
21570 goto desc_size_fail;
21571 /* FIXME: Generate an error if descsz > 8 ? */
21572
0e3c1eeb 21573 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21574 printf ("\n");
21575 break;
8d18bf79 21576
00e98fc7
TG
21577 case NT_VMS_PATCHTIME:
21578 printf (_(" Patch time: "));
8d18bf79
NC
21579 if (maxlen < 8)
21580 goto desc_size_fail;
21581 /* FIXME: Generate an error if descsz > 8 ? */
21582
0e3c1eeb 21583 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21584 printf ("\n");
21585 break;
8d18bf79 21586
00e98fc7 21587 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21588 if (maxlen < 34)
21589 goto desc_size_fail;
21590
00e98fc7 21591 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21592 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21593 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21594 printf (_(" Last modified : "));
0e3c1eeb 21595 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21596 printf (_("\n Link flags : "));
b8281767 21597 printf ("0x%016" PRIx64 "\n",
625d49fc 21598 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21599 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21600 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21601 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21602 break;
8d18bf79 21603
00e98fc7 21604 case NT_VMS_IMGNAM:
8d18bf79 21605 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21606 break;
8d18bf79 21607
00e98fc7 21608 case NT_VMS_GSTNAM:
8d18bf79 21609 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21610 break;
8d18bf79 21611
00e98fc7 21612 case NT_VMS_IMGID:
8d18bf79 21613 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21614 break;
8d18bf79 21615
00e98fc7 21616 case NT_VMS_LINKID:
8d18bf79 21617 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21618 break;
8d18bf79 21619
00e98fc7 21620 default:
015dc7e1 21621 return false;
00e98fc7 21622 }
8d18bf79 21623
015dc7e1 21624 return true;
8d18bf79
NC
21625
21626 desc_size_fail:
21627 printf (_(" <corrupt - data size is too small>\n"));
21628 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21629 return false;
00e98fc7
TG
21630}
21631
fd486f32
AM
21632struct build_attr_cache {
21633 Filedata *filedata;
21634 char *strtab;
26c527e6 21635 uint64_t strtablen;
fd486f32 21636 Elf_Internal_Sym *symtab;
26c527e6 21637 uint64_t nsyms;
fd486f32
AM
21638} ba_cache;
21639
6f156d7a
NC
21640/* Find the symbol associated with a build attribute that is attached
21641 to address OFFSET. If PNAME is non-NULL then store the name of
21642 the symbol (if found) in the provided pointer, Returns NULL if a
21643 symbol could not be found. */
c799a79d 21644
6f156d7a 21645static Elf_Internal_Sym *
015dc7e1 21646get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21647 uint64_t offset,
015dc7e1
AM
21648 bool is_open_attr,
21649 const char **pname)
9ef920e9 21650{
fd486f32
AM
21651 Elf_Internal_Sym *saved_sym = NULL;
21652 Elf_Internal_Sym *sym;
9ef920e9 21653
dda8d76d 21654 if (filedata->section_headers != NULL
fd486f32 21655 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21656 {
c799a79d 21657 Elf_Internal_Shdr * symsec;
9ef920e9 21658
fd486f32
AM
21659 free (ba_cache.strtab);
21660 ba_cache.strtab = NULL;
21661 free (ba_cache.symtab);
21662 ba_cache.symtab = NULL;
21663
c799a79d 21664 /* Load the symbol and string sections. */
dda8d76d
NC
21665 for (symsec = filedata->section_headers;
21666 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21667 symsec ++)
9ef920e9 21668 {
28d13567
AM
21669 if (symsec->sh_type == SHT_SYMTAB
21670 && get_symtab (filedata, symsec,
21671 &ba_cache.symtab, &ba_cache.nsyms,
21672 &ba_cache.strtab, &ba_cache.strtablen))
21673 break;
9ef920e9 21674 }
fd486f32 21675 ba_cache.filedata = filedata;
9ef920e9
NC
21676 }
21677
fd486f32 21678 if (ba_cache.symtab == NULL)
6f156d7a 21679 return NULL;
9ef920e9 21680
c799a79d 21681 /* Find a symbol whose value matches offset. */
fd486f32 21682 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21683 if (sym->st_value == offset)
21684 {
fd486f32 21685 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21686 /* Huh ? This should not happen. */
21687 continue;
9ef920e9 21688
fd486f32 21689 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21690 continue;
9ef920e9 21691
9b9b1092 21692 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21693 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21694 if (ba_cache.strtab[sym->st_name] == '$'
21695 && ba_cache.strtab[sym->st_name + 1] != 0
21696 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21697 continue;
21698
c799a79d
NC
21699 if (is_open_attr)
21700 {
21701 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21702 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21703 FUNC symbols entirely. */
21704 switch (ELF_ST_TYPE (sym->st_info))
21705 {
c799a79d 21706 case STT_OBJECT:
6f156d7a 21707 case STT_FILE:
c799a79d 21708 saved_sym = sym;
6f156d7a
NC
21709 if (sym->st_size)
21710 {
21711 /* If the symbol has a size associated
21712 with it then we can stop searching. */
fd486f32 21713 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21714 }
c799a79d 21715 continue;
9ef920e9 21716
c799a79d
NC
21717 case STT_FUNC:
21718 /* Ignore function symbols. */
21719 continue;
21720
21721 default:
21722 break;
21723 }
21724
21725 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21726 {
c799a79d
NC
21727 case STB_GLOBAL:
21728 if (saved_sym == NULL
21729 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21730 saved_sym = sym;
21731 break;
c871dade 21732
c799a79d
NC
21733 case STB_LOCAL:
21734 if (saved_sym == NULL)
21735 saved_sym = sym;
21736 break;
21737
21738 default:
9ef920e9
NC
21739 break;
21740 }
21741 }
c799a79d
NC
21742 else
21743 {
21744 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21745 continue;
21746
21747 saved_sym = sym;
21748 break;
21749 }
21750 }
21751
6f156d7a 21752 if (saved_sym && pname)
fd486f32 21753 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21754
21755 return saved_sym;
c799a79d
NC
21756}
21757
d20e98ab
NC
21758/* Returns true iff addr1 and addr2 are in the same section. */
21759
015dc7e1 21760static bool
26c527e6 21761same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21762{
21763 Elf_Internal_Shdr * a1;
21764 Elf_Internal_Shdr * a2;
21765
21766 a1 = find_section_by_address (filedata, addr1);
21767 a2 = find_section_by_address (filedata, addr2);
9abca702 21768
d20e98ab
NC
21769 return a1 == a2 && a1 != NULL;
21770}
21771
015dc7e1 21772static bool
dda8d76d
NC
21773print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21774 Filedata * filedata)
c799a79d 21775{
26c527e6
AM
21776 static uint64_t global_offset = 0;
21777 static uint64_t global_end = 0;
21778 static uint64_t func_offset = 0;
21779 static uint64_t func_end = 0;
c871dade 21780
015dc7e1
AM
21781 Elf_Internal_Sym *sym;
21782 const char *name;
26c527e6
AM
21783 uint64_t start;
21784 uint64_t end;
015dc7e1 21785 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21786
21787 switch (pnote->descsz)
c799a79d 21788 {
6f156d7a
NC
21789 case 0:
21790 /* A zero-length description means that the range of
21791 the previous note of the same type should be used. */
c799a79d 21792 if (is_open_attr)
c871dade 21793 {
6f156d7a 21794 if (global_end > global_offset)
26c527e6
AM
21795 printf (_(" Applies to region from %#" PRIx64
21796 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 21797 else
26c527e6
AM
21798 printf (_(" Applies to region from %#" PRIx64
21799 "\n"), global_offset);
c799a79d
NC
21800 }
21801 else
21802 {
6f156d7a 21803 if (func_end > func_offset)
26c527e6
AM
21804 printf (_(" Applies to region from %#" PRIx64
21805 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 21806 else
26c527e6
AM
21807 printf (_(" Applies to region from %#" PRIx64
21808 "\n"), func_offset);
c871dade 21809 }
015dc7e1 21810 return true;
9ef920e9 21811
6f156d7a
NC
21812 case 4:
21813 start = byte_get ((unsigned char *) pnote->descdata, 4);
21814 end = 0;
21815 break;
21816
21817 case 8:
c74147bb
NC
21818 start = byte_get ((unsigned char *) pnote->descdata, 4);
21819 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
21820 break;
21821
21822 case 16:
21823 start = byte_get ((unsigned char *) pnote->descdata, 8);
21824 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
21825 break;
9abca702 21826
6f156d7a 21827 default:
c799a79d
NC
21828 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
21829 printf (_(" <invalid descsz>"));
015dc7e1 21830 return false;
c799a79d
NC
21831 }
21832
6f156d7a
NC
21833 name = NULL;
21834 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
21835 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
21836 in order to avoid them being confused with the start address of the
21837 first function in the file... */
21838 if (sym == NULL && is_open_attr)
21839 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
21840 & name);
6f156d7a
NC
21841
21842 if (end == 0 && sym != NULL && sym->st_size > 0)
21843 end = start + sym->st_size;
c799a79d
NC
21844
21845 if (is_open_attr)
21846 {
d20e98ab
NC
21847 /* FIXME: Need to properly allow for section alignment.
21848 16 is just the alignment used on x86_64. */
21849 if (global_end > 0
21850 && start > BFD_ALIGN (global_end, 16)
21851 /* Build notes are not guaranteed to be organised in order of
21852 increasing address, but we should find the all of the notes
21853 for one section in the same place. */
21854 && same_section (filedata, start, global_end))
26c527e6
AM
21855 warn (_("Gap in build notes detected from %#" PRIx64
21856 " to %#" PRIx64 "\n"),
6f156d7a
NC
21857 global_end + 1, start - 1);
21858
26c527e6 21859 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21860 global_offset = start;
21861
21862 if (end)
21863 {
26c527e6 21864 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21865 global_end = end;
21866 }
c799a79d
NC
21867 }
21868 else
21869 {
26c527e6 21870 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
21871 func_offset = start;
21872
21873 if (end)
21874 {
26c527e6 21875 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
21876 func_end = end;
21877 }
c799a79d
NC
21878 }
21879
6f156d7a
NC
21880 if (sym && name)
21881 printf (_(" (%s)"), name);
21882
21883 printf ("\n");
015dc7e1 21884 return true;
9ef920e9
NC
21885}
21886
015dc7e1 21887static bool
9ef920e9
NC
21888print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
21889{
1d15e434
NC
21890 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
21891 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
21892 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
21893 char name_type;
21894 char name_attribute;
1d15e434 21895 const char * expected_types;
9ef920e9
NC
21896 const char * name = pnote->namedata;
21897 const char * text;
88305e1b 21898 signed int left;
9ef920e9
NC
21899
21900 if (name == NULL || pnote->namesz < 2)
21901 {
21902 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21903 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21904 return false;
9ef920e9
NC
21905 }
21906
6f156d7a
NC
21907 if (do_wide)
21908 left = 28;
21909 else
21910 left = 20;
88305e1b
NC
21911
21912 /* Version 2 of the spec adds a "GA" prefix to the name field. */
21913 if (name[0] == 'G' && name[1] == 'A')
21914 {
6f156d7a
NC
21915 if (pnote->namesz < 4)
21916 {
21917 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 21918 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 21919 return false;
6f156d7a
NC
21920 }
21921
88305e1b
NC
21922 printf ("GA");
21923 name += 2;
21924 left -= 2;
21925 }
21926
9ef920e9
NC
21927 switch ((name_type = * name))
21928 {
21929 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21930 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21931 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21932 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21933 printf ("%c", * name);
88305e1b 21934 left --;
9ef920e9
NC
21935 break;
21936 default:
21937 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 21938 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 21939 return false;
9ef920e9
NC
21940 }
21941
9ef920e9
NC
21942 ++ name;
21943 text = NULL;
21944
21945 switch ((name_attribute = * name))
21946 {
21947 case GNU_BUILD_ATTRIBUTE_VERSION:
21948 text = _("<version>");
1d15e434 21949 expected_types = string_expected;
9ef920e9
NC
21950 ++ name;
21951 break;
21952 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21953 text = _("<stack prot>");
75d7d298 21954 expected_types = "!+*";
9ef920e9
NC
21955 ++ name;
21956 break;
21957 case GNU_BUILD_ATTRIBUTE_RELRO:
21958 text = _("<relro>");
1d15e434 21959 expected_types = bool_expected;
9ef920e9
NC
21960 ++ name;
21961 break;
21962 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
21963 text = _("<stack size>");
1d15e434 21964 expected_types = number_expected;
9ef920e9
NC
21965 ++ name;
21966 break;
21967 case GNU_BUILD_ATTRIBUTE_TOOL:
21968 text = _("<tool>");
1d15e434 21969 expected_types = string_expected;
9ef920e9
NC
21970 ++ name;
21971 break;
21972 case GNU_BUILD_ATTRIBUTE_ABI:
21973 text = _("<ABI>");
21974 expected_types = "$*";
21975 ++ name;
21976 break;
21977 case GNU_BUILD_ATTRIBUTE_PIC:
21978 text = _("<PIC>");
1d15e434 21979 expected_types = number_expected;
9ef920e9
NC
21980 ++ name;
21981 break;
a8be5506
NC
21982 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
21983 text = _("<short enum>");
1d15e434 21984 expected_types = bool_expected;
a8be5506
NC
21985 ++ name;
21986 break;
9ef920e9
NC
21987 default:
21988 if (ISPRINT (* name))
21989 {
21990 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21991
21992 if (len > left && ! do_wide)
21993 len = left;
75d7d298 21994 printf ("%.*s:", len, name);
9ef920e9 21995 left -= len;
0dd6ae21 21996 name += len;
9ef920e9
NC
21997 }
21998 else
21999 {
3e6b6445 22000 static char tmpbuf [128];
88305e1b 22001
3e6b6445
NC
22002 error (_("unrecognised byte in name field: %d\n"), * name);
22003 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22004 text = tmpbuf;
22005 name ++;
9ef920e9
NC
22006 }
22007 expected_types = "*$!+";
22008 break;
22009 }
22010
22011 if (text)
88305e1b 22012 left -= printf ("%s", text);
9ef920e9
NC
22013
22014 if (strchr (expected_types, name_type) == NULL)
75d7d298 22015 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22016
26c527e6 22017 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22018 {
26c527e6
AM
22019 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22020 pnote->namesz,
22021 name - pnote->namedata);
015dc7e1 22022 return false;
9ef920e9
NC
22023 }
22024
22025 if (left < 1 && ! do_wide)
015dc7e1 22026 return true;
9ef920e9
NC
22027
22028 switch (name_type)
22029 {
22030 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22031 {
26c527e6
AM
22032 unsigned int bytes;
22033 uint64_t val = 0;
22034 unsigned int shift = 0;
22035 char *decoded = NULL;
ddef72cd 22036
b06b2c92
NC
22037 bytes = pnote->namesz - (name - pnote->namedata);
22038 if (bytes > 0)
22039 /* The -1 is because the name field is always 0 terminated, and we
22040 want to be able to ensure that the shift in the while loop below
22041 will not overflow. */
22042 -- bytes;
22043
ddef72cd
NC
22044 if (bytes > sizeof (val))
22045 {
3e6b6445
NC
22046 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22047 bytes);
22048 bytes = sizeof (val);
ddef72cd 22049 }
3e6b6445
NC
22050 /* We do not bother to warn if bytes == 0 as this can
22051 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22052
22053 while (bytes --)
22054 {
26c527e6 22055 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22056
22057 val |= byte << shift;
9ef920e9
NC
22058 shift += 8;
22059 }
22060
75d7d298 22061 switch (name_attribute)
9ef920e9 22062 {
75d7d298 22063 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22064 switch (val)
22065 {
75d7d298
NC
22066 case 0: decoded = "static"; break;
22067 case 1: decoded = "pic"; break;
22068 case 2: decoded = "PIC"; break;
22069 case 3: decoded = "pie"; break;
22070 case 4: decoded = "PIE"; break;
22071 default: break;
9ef920e9 22072 }
75d7d298
NC
22073 break;
22074 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22075 switch (val)
9ef920e9 22076 {
75d7d298
NC
22077 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22078 case 0: decoded = "off"; break;
22079 case 1: decoded = "on"; break;
22080 case 2: decoded = "all"; break;
22081 case 3: decoded = "strong"; break;
22082 case 4: decoded = "explicit"; break;
22083 default: break;
9ef920e9 22084 }
75d7d298
NC
22085 break;
22086 default:
22087 break;
9ef920e9
NC
22088 }
22089
75d7d298 22090 if (decoded != NULL)
3e6b6445 22091 {
b6ac461a 22092 print_symbol_name (-left, decoded);
3e6b6445
NC
22093 left = 0;
22094 }
22095 else if (val == 0)
22096 {
22097 printf ("0x0");
22098 left -= 3;
22099 }
9ef920e9 22100 else
75d7d298
NC
22101 {
22102 if (do_wide)
26c527e6 22103 left -= printf ("0x%" PRIx64, val);
75d7d298 22104 else
26c527e6 22105 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22106 }
9ef920e9
NC
22107 }
22108 break;
22109 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22110 left -= print_symbol_name (- left, name);
9ef920e9
NC
22111 break;
22112 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22113 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22114 break;
22115 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22116 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22117 break;
22118 }
22119
22120 if (do_wide && left > 0)
22121 printf ("%-*s", left, " ");
9abca702 22122
015dc7e1 22123 return true;
9ef920e9
NC
22124}
22125
2952f10c
SM
22126/* Print the contents of PNOTE as hex. */
22127
22128static void
22129print_note_contents_hex (Elf_Internal_Note *pnote)
22130{
22131 if (pnote->descsz)
22132 {
26c527e6 22133 size_t i;
2952f10c
SM
22134
22135 printf (_(" description data: "));
22136 for (i = 0; i < pnote->descsz; i++)
22137 printf ("%02x ", pnote->descdata[i] & 0xff);
22138 if (!do_wide)
22139 printf ("\n");
22140 }
22141
22142 if (do_wide)
22143 printf ("\n");
22144}
22145
22146#if defined HAVE_MSGPACK
22147
22148static void
22149print_indents (int n)
22150{
22151 printf (" ");
22152
22153 for (int i = 0; i < n; i++)
22154 printf (" ");
22155}
22156
22157/* Print OBJ in human-readable form. */
22158
22159static void
22160dump_msgpack_obj (const msgpack_object *obj, int indent)
22161{
22162 switch (obj->type)
22163 {
22164 case MSGPACK_OBJECT_NIL:
22165 printf ("(nil)");
22166 break;
22167
22168 case MSGPACK_OBJECT_BOOLEAN:
22169 printf ("%s", obj->via.boolean ? "true" : "false");
22170 break;
22171
22172 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22173 printf ("%" PRIu64, obj->via.u64);
22174 break;
22175
22176 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22177 printf ("%" PRIi64, obj->via.i64);
22178 break;
22179
22180 case MSGPACK_OBJECT_FLOAT32:
22181 case MSGPACK_OBJECT_FLOAT64:
22182 printf ("%f", obj->via.f64);
22183 break;
22184
22185 case MSGPACK_OBJECT_STR:
22186 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22187 break;
22188
22189 case MSGPACK_OBJECT_ARRAY:
22190 {
22191 const msgpack_object_array *array = &obj->via.array;
22192
22193 printf ("[\n");
22194 ++indent;
22195
22196 for (uint32_t i = 0; i < array->size; ++i)
22197 {
22198 const msgpack_object *item = &array->ptr[i];
22199
22200 print_indents (indent);
22201 dump_msgpack_obj (item, indent);
22202 printf (",\n");
22203 }
22204
22205 --indent;
22206 print_indents (indent);
22207 printf ("]");
22208 break;
22209 }
22210 break;
22211
22212 case MSGPACK_OBJECT_MAP:
22213 {
22214 const msgpack_object_map *map = &obj->via.map;
22215
22216 printf ("{\n");
22217 ++indent;
22218
22219 for (uint32_t i = 0; i < map->size; ++i)
22220 {
22221 const msgpack_object_kv *kv = &map->ptr[i];
22222 const msgpack_object *key = &kv->key;
22223 const msgpack_object *val = &kv->val;
22224
22225 print_indents (indent);
22226 dump_msgpack_obj (key, indent);
22227 printf (": ");
22228 dump_msgpack_obj (val, indent);
22229
22230 printf (",\n");
22231 }
22232
22233 --indent;
22234 print_indents (indent);
22235 printf ("}");
22236
22237 break;
22238 }
22239
22240 case MSGPACK_OBJECT_BIN:
22241 printf ("(bin)");
22242 break;
22243
22244 case MSGPACK_OBJECT_EXT:
22245 printf ("(ext)");
22246 break;
22247 }
22248}
22249
22250static void
22251dump_msgpack (const msgpack_unpacked *msg)
22252{
22253 print_indents (0);
22254 dump_msgpack_obj (&msg->data, 0);
22255 printf ("\n");
22256}
22257
22258#endif /* defined HAVE_MSGPACK */
22259
22260static bool
22261print_amdgpu_note (Elf_Internal_Note *pnote)
22262{
22263#if defined HAVE_MSGPACK
22264 /* If msgpack is available, decode and dump the note's content. */
22265 bool ret;
22266 msgpack_unpacked msg;
22267 msgpack_unpack_return msgpack_ret;
22268
22269 assert (pnote->type == NT_AMDGPU_METADATA);
22270
22271 msgpack_unpacked_init (&msg);
22272 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22273 NULL);
22274
22275 switch (msgpack_ret)
22276 {
22277 case MSGPACK_UNPACK_SUCCESS:
22278 dump_msgpack (&msg);
22279 ret = true;
22280 break;
22281
22282 default:
22283 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22284 ret = false;
22285 break;
22286 }
22287
22288 msgpack_unpacked_destroy (&msg);
22289 return ret;
22290#else
22291 /* msgpack is not available, dump contents as hex. */
22292 print_note_contents_hex (pnote);
22293 return true;
22294#endif
22295}
22296
e263a66b
CC
22297static bool
22298print_qnx_note (Elf_Internal_Note *pnote)
22299{
22300 switch (pnote->type)
22301 {
22302 case QNT_STACK:
22303 if (pnote->descsz != 12)
22304 goto desc_size_fail;
22305
22306 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22307 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22308 printf (_(" Stack allocated: %" PRIx32 "\n"),
22309 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22310 printf (_(" Executable: %s\n"),
22311 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22312 break;
22313
22314 default:
22315 print_note_contents_hex(pnote);
22316 }
22317 return true;
22318
22319desc_size_fail:
22320 printf (_(" <corrupt - data size is too small>\n"));
22321 error (_("corrupt QNX note: data size is too small\n"));
22322 return false;
22323}
22324
22325
6d118b09
NC
22326/* Note that by the ELF standard, the name field is already null byte
22327 terminated, and namesz includes the terminating null byte.
22328 I.E. the value of namesz for the name "FSF" is 4.
22329
e3c8793a 22330 If the value of namesz is zero, there is no name present. */
9ef920e9 22331
015dc7e1 22332static bool
9ef920e9 22333process_note (Elf_Internal_Note * pnote,
dda8d76d 22334 Filedata * filedata)
779fe533 22335{
2cf0635d
NC
22336 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22337 const char * nt;
9437c45b
JT
22338
22339 if (pnote->namesz == 0)
1ec5cd37
NC
22340 /* If there is no note name, then use the default set of
22341 note type strings. */
dda8d76d 22342 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22343
24d127aa 22344 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22345 /* GNU-specific object file notes. */
22346 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22347
28cdbb18
SM
22348 else if (startswith (pnote->namedata, "AMDGPU"))
22349 /* AMDGPU-specific object file notes. */
22350 nt = get_amdgpu_elf_note_type (pnote->type);
22351
24d127aa 22352 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22353 /* FreeBSD-specific core file notes. */
dda8d76d 22354 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22355
24d127aa 22356 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22357 /* NetBSD-specific core file notes. */
dda8d76d 22358 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22359
24d127aa 22360 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22361 /* NetBSD-specific core file notes. */
22362 return process_netbsd_elf_note (pnote);
22363
24d127aa 22364 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22365 /* NetBSD-specific core file notes. */
22366 return process_netbsd_elf_note (pnote);
22367
98ca73af
FC
22368 else if (startswith (pnote->namedata, "OpenBSD"))
22369 /* OpenBSD-specific core file notes. */
22370 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22371
e263a66b
CC
22372 else if (startswith (pnote->namedata, "QNX"))
22373 /* QNX-specific core file notes. */
22374 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22375
e9b095a5 22376 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22377 {
22378 /* SPU-specific core file notes. */
22379 nt = pnote->namedata + 4;
22380 name = "SPU";
22381 }
22382
24d127aa 22383 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22384 /* VMS/ia64-specific file notes. */
22385 nt = get_ia64_vms_note_type (pnote->type);
22386
24d127aa 22387 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22388 nt = get_stapsdt_note_type (pnote->type);
22389
9437c45b 22390 else
1ec5cd37
NC
22391 /* Don't recognize this note name; just use the default set of
22392 note type strings. */
dda8d76d 22393 nt = get_note_type (filedata, pnote->type);
9437c45b 22394
1449284b 22395 printf (" ");
9ef920e9 22396
24d127aa 22397 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22398 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22399 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22400 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22401 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22402 print_gnu_build_attribute_name (pnote);
22403 else
b6ac461a 22404 print_symbol_name (-20, name);
9ef920e9
NC
22405
22406 if (do_wide)
22407 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22408 else
22409 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22410
24d127aa 22411 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22412 return print_ia64_vms_note (pnote);
24d127aa 22413 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22414 return print_gnu_note (filedata, pnote);
24d127aa 22415 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22416 return print_stapsdt_note (pnote);
24d127aa 22417 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22418 return print_core_note (pnote);
e5382207
LB
22419 else if (startswith (pnote->namedata, "FDO"))
22420 return print_fdo_note (pnote);
24d127aa 22421 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22422 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22423 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22424 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22425 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22426 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22427 else if (startswith (pnote->namedata, "AMDGPU")
22428 && pnote->type == NT_AMDGPU_METADATA)
22429 return print_amdgpu_note (pnote);
e263a66b
CC
22430 else if (startswith (pnote->namedata, "QNX"))
22431 return print_qnx_note (pnote);
779fe533 22432
2952f10c 22433 print_note_contents_hex (pnote);
015dc7e1 22434 return true;
1449284b 22435}
6d118b09 22436
015dc7e1 22437static bool
dda8d76d
NC
22438process_notes_at (Filedata * filedata,
22439 Elf_Internal_Shdr * section,
625d49fc
AM
22440 uint64_t offset,
22441 uint64_t length,
22442 uint64_t align)
779fe533 22443{
015dc7e1
AM
22444 Elf_External_Note *pnotes;
22445 Elf_External_Note *external;
22446 char *end;
22447 bool res = true;
103f02d3 22448
779fe533 22449 if (length <= 0)
015dc7e1 22450 return false;
103f02d3 22451
1449284b
NC
22452 if (section)
22453 {
dda8d76d 22454 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22455 if (pnotes)
32ec8896 22456 {
dda8d76d 22457 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22458 {
22459 free (pnotes);
015dc7e1 22460 return false;
f761cb13 22461 }
32ec8896 22462 }
1449284b
NC
22463 }
22464 else
82ed9683 22465 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22466 _("notes"));
4dff97b2 22467
dd24e3da 22468 if (pnotes == NULL)
015dc7e1 22469 return false;
779fe533 22470
103f02d3 22471 external = pnotes;
103f02d3 22472
ca0e11aa
NC
22473 if (filedata->is_separate)
22474 printf (_("In linked file '%s': "), filedata->file_name);
22475 else
22476 printf ("\n");
1449284b 22477 if (section)
ca0e11aa 22478 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22479 else
26c527e6
AM
22480 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22481 " with length 0x%08" PRIx64 ":\n"),
22482 offset, length);
1449284b 22483
82ed9683
L
22484 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22485 specifies that notes should be aligned to 4 bytes in 32-bit
22486 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22487 we also support 4 byte alignment in 64-bit objects. If section
22488 alignment is less than 4, we treate alignment as 4 bytes. */
22489 if (align < 4)
22490 align = 4;
22491 else if (align != 4 && align != 8)
22492 {
26c527e6
AM
22493 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22494 align);
a788aedd 22495 free (pnotes);
015dc7e1 22496 return false;
82ed9683
L
22497 }
22498
dbe15e4e 22499 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22500
c8071705
NC
22501 end = (char *) pnotes + length;
22502 while ((char *) external < end)
779fe533 22503 {
b34976b6 22504 Elf_Internal_Note inote;
15b42fb0 22505 size_t min_notesz;
4dff97b2 22506 char * next;
2cf0635d 22507 char * temp = NULL;
c8071705 22508 size_t data_remaining = end - (char *) external;
6d118b09 22509
dda8d76d 22510 if (!is_ia64_vms (filedata))
15b42fb0 22511 {
9dd3a467
NC
22512 /* PR binutils/15191
22513 Make sure that there is enough data to read. */
15b42fb0
AM
22514 min_notesz = offsetof (Elf_External_Note, name);
22515 if (data_remaining < min_notesz)
9dd3a467 22516 {
26c527e6 22517 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22518 "not enough for a full note\n",
26c527e6 22519 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22520 "not enough for a full note\n",
22521 data_remaining),
26c527e6 22522 data_remaining);
9dd3a467
NC
22523 break;
22524 }
5396a86e
AM
22525 data_remaining -= min_notesz;
22526
15b42fb0
AM
22527 inote.type = BYTE_GET (external->type);
22528 inote.namesz = BYTE_GET (external->namesz);
22529 inote.namedata = external->name;
22530 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22531 inote.descdata = ((char *) external
4dff97b2 22532 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22533 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22534 next = ((char *) external
4dff97b2 22535 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22536 }
00e98fc7 22537 else
15b42fb0
AM
22538 {
22539 Elf64_External_VMS_Note *vms_external;
00e98fc7 22540
9dd3a467
NC
22541 /* PR binutils/15191
22542 Make sure that there is enough data to read. */
15b42fb0
AM
22543 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22544 if (data_remaining < min_notesz)
9dd3a467 22545 {
26c527e6 22546 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22547 "not enough for a full note\n",
26c527e6 22548 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22549 "not enough for a full note\n",
22550 data_remaining),
26c527e6 22551 data_remaining);
9dd3a467
NC
22552 break;
22553 }
5396a86e 22554 data_remaining -= min_notesz;
3e55a963 22555
15b42fb0
AM
22556 vms_external = (Elf64_External_VMS_Note *) external;
22557 inote.type = BYTE_GET (vms_external->type);
22558 inote.namesz = BYTE_GET (vms_external->namesz);
22559 inote.namedata = vms_external->name;
22560 inote.descsz = BYTE_GET (vms_external->descsz);
22561 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22562 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22563 next = inote.descdata + align_power (inote.descsz, 3);
22564 }
22565
5396a86e
AM
22566 /* PR 17531: file: 3443835e. */
22567 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22568 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22569 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22570 || (size_t) (next - inote.descdata) < inote.descsz
22571 || ((size_t) (next - inote.descdata)
22572 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22573 {
26c527e6
AM
22574 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22575 (char *) external - (char *) pnotes);
22576 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22577 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22578 break;
22579 }
22580
15b42fb0 22581 external = (Elf_External_Note *) next;
dd24e3da 22582
6d118b09
NC
22583 /* Verify that name is null terminated. It appears that at least
22584 one version of Linux (RedHat 6.0) generates corefiles that don't
22585 comply with the ELF spec by failing to include the null byte in
22586 namesz. */
18344509 22587 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22588 {
5396a86e 22589 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22590 {
5396a86e
AM
22591 temp = (char *) malloc (inote.namesz + 1);
22592 if (temp == NULL)
22593 {
22594 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22595 res = false;
5396a86e
AM
22596 break;
22597 }
76da6bbe 22598
5396a86e
AM
22599 memcpy (temp, inote.namedata, inote.namesz);
22600 inote.namedata = temp;
22601 }
22602 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22603 }
22604
dda8d76d 22605 if (! process_note (& inote, filedata))
015dc7e1 22606 res = false;
103f02d3 22607
9db70fc3
AM
22608 free (temp);
22609 temp = NULL;
779fe533
NC
22610 }
22611
22612 free (pnotes);
103f02d3 22613
779fe533
NC
22614 return res;
22615}
22616
015dc7e1 22617static bool
dda8d76d 22618process_corefile_note_segments (Filedata * filedata)
779fe533 22619{
015dc7e1 22620 Elf_Internal_Phdr *segment;
b34976b6 22621 unsigned int i;
015dc7e1 22622 bool res = true;
103f02d3 22623
dda8d76d 22624 if (! get_program_headers (filedata))
015dc7e1 22625 return true;
103f02d3 22626
dda8d76d
NC
22627 for (i = 0, segment = filedata->program_headers;
22628 i < filedata->file_header.e_phnum;
b34976b6 22629 i++, segment++)
779fe533
NC
22630 {
22631 if (segment->p_type == PT_NOTE)
625d49fc
AM
22632 if (! process_notes_at (filedata, NULL, segment->p_offset,
22633 segment->p_filesz, segment->p_align))
015dc7e1 22634 res = false;
779fe533 22635 }
103f02d3 22636
779fe533
NC
22637 return res;
22638}
22639
015dc7e1 22640static bool
625d49fc 22641process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22642{
22643 Elf_External_Note * pnotes;
22644 Elf_External_Note * external;
c8071705 22645 char * end;
015dc7e1 22646 bool res = true;
685080f2
NC
22647
22648 if (length <= 0)
015dc7e1 22649 return false;
685080f2 22650
dda8d76d 22651 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22652 _("v850 notes"));
22653 if (pnotes == NULL)
015dc7e1 22654 return false;
685080f2
NC
22655
22656 external = pnotes;
c8071705 22657 end = (char*) pnotes + length;
685080f2 22658
26c527e6
AM
22659 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22660 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22661 offset, length);
685080f2 22662
c8071705 22663 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22664 {
22665 Elf_External_Note * next;
22666 Elf_Internal_Note inote;
22667
22668 inote.type = BYTE_GET (external->type);
22669 inote.namesz = BYTE_GET (external->namesz);
22670 inote.namedata = external->name;
22671 inote.descsz = BYTE_GET (external->descsz);
22672 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22673 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22674
c8071705
NC
22675 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22676 {
22677 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22678 inote.descdata = inote.namedata;
22679 inote.namesz = 0;
22680 }
22681
685080f2
NC
22682 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22683
c8071705 22684 if ( ((char *) next > end)
685080f2
NC
22685 || ((char *) next < (char *) pnotes))
22686 {
26c527e6
AM
22687 warn (_("corrupt descsz found in note at offset %#tx\n"),
22688 (char *) external - (char *) pnotes);
22689 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22690 inote.type, inote.namesz, inote.descsz);
22691 break;
22692 }
22693
22694 external = next;
22695
22696 /* Prevent out-of-bounds indexing. */
c8071705 22697 if ( inote.namedata + inote.namesz > end
685080f2
NC
22698 || inote.namedata + inote.namesz < inote.namedata)
22699 {
26c527e6
AM
22700 warn (_("corrupt namesz found in note at offset %#zx\n"),
22701 (char *) external - (char *) pnotes);
22702 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22703 inote.type, inote.namesz, inote.descsz);
22704 break;
22705 }
22706
22707 printf (" %s: ", get_v850_elf_note_type (inote.type));
22708
22709 if (! print_v850_note (& inote))
22710 {
015dc7e1 22711 res = false;
26c527e6 22712 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22713 inote.namesz, inote.descsz);
22714 }
22715 }
22716
22717 free (pnotes);
22718
22719 return res;
22720}
22721
015dc7e1 22722static bool
dda8d76d 22723process_note_sections (Filedata * filedata)
1ec5cd37 22724{
015dc7e1 22725 Elf_Internal_Shdr *section;
26c527e6 22726 size_t i;
32ec8896 22727 unsigned int n = 0;
015dc7e1 22728 bool res = true;
1ec5cd37 22729
dda8d76d
NC
22730 for (i = 0, section = filedata->section_headers;
22731 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22732 i++, section++)
685080f2
NC
22733 {
22734 if (section->sh_type == SHT_NOTE)
22735 {
625d49fc
AM
22736 if (! process_notes_at (filedata, section, section->sh_offset,
22737 section->sh_size, section->sh_addralign))
015dc7e1 22738 res = false;
685080f2
NC
22739 n++;
22740 }
22741
dda8d76d
NC
22742 if (( filedata->file_header.e_machine == EM_V800
22743 || filedata->file_header.e_machine == EM_V850
22744 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22745 && section->sh_type == SHT_RENESAS_INFO)
22746 {
625d49fc
AM
22747 if (! process_v850_notes (filedata, section->sh_offset,
22748 section->sh_size))
015dc7e1 22749 res = false;
685080f2
NC
22750 n++;
22751 }
22752 }
df565f32
NC
22753
22754 if (n == 0)
22755 /* Try processing NOTE segments instead. */
dda8d76d 22756 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22757
22758 return res;
22759}
22760
015dc7e1 22761static bool
dda8d76d 22762process_notes (Filedata * filedata)
779fe533
NC
22763{
22764 /* If we have not been asked to display the notes then do nothing. */
22765 if (! do_notes)
015dc7e1 22766 return true;
103f02d3 22767
dda8d76d
NC
22768 if (filedata->file_header.e_type != ET_CORE)
22769 return process_note_sections (filedata);
103f02d3 22770
779fe533 22771 /* No program headers means no NOTE segment. */
dda8d76d
NC
22772 if (filedata->file_header.e_phnum > 0)
22773 return process_corefile_note_segments (filedata);
779fe533 22774
ca0e11aa
NC
22775 if (filedata->is_separate)
22776 printf (_("No notes found in linked file '%s'.\n"),
22777 filedata->file_name);
22778 else
22779 printf (_("No notes found file.\n"));
22780
015dc7e1 22781 return true;
779fe533
NC
22782}
22783
60abdbed
NC
22784static unsigned char *
22785display_public_gnu_attributes (unsigned char * start,
22786 const unsigned char * const end)
22787{
22788 printf (_(" Unknown GNU attribute: %s\n"), start);
22789
22790 start += strnlen ((char *) start, end - start);
22791 display_raw_attribute (start, end);
22792
22793 return (unsigned char *) end;
22794}
22795
22796static unsigned char *
22797display_generic_attribute (unsigned char * start,
22798 unsigned int tag,
22799 const unsigned char * const end)
22800{
22801 if (tag == 0)
22802 return (unsigned char *) end;
22803
22804 return display_tag_value (tag, start, end);
22805}
22806
015dc7e1 22807static bool
dda8d76d 22808process_arch_specific (Filedata * filedata)
252b5132 22809{
a952a375 22810 if (! do_arch)
015dc7e1 22811 return true;
a952a375 22812
dda8d76d 22813 switch (filedata->file_header.e_machine)
252b5132 22814 {
53a346d8
CZ
22815 case EM_ARC:
22816 case EM_ARC_COMPACT:
22817 case EM_ARC_COMPACT2:
b5c37946
SJ
22818 case EM_ARC_COMPACT3:
22819 case EM_ARC_COMPACT3_64:
dda8d76d 22820 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
22821 display_arc_attribute,
22822 display_generic_attribute);
11c1ff18 22823 case EM_ARM:
dda8d76d 22824 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
22825 display_arm_attribute,
22826 display_generic_attribute);
22827
252b5132 22828 case EM_MIPS:
4fe85591 22829 case EM_MIPS_RS3_LE:
dda8d76d 22830 return process_mips_specific (filedata);
60abdbed
NC
22831
22832 case EM_MSP430:
dda8d76d 22833 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 22834 display_msp430_attribute,
c0ea7c52 22835 display_msp430_gnu_attribute);
60abdbed 22836
2dc8dd17
JW
22837 case EM_RISCV:
22838 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
22839 display_riscv_attribute,
22840 display_generic_attribute);
22841
35c08157 22842 case EM_NDS32:
dda8d76d 22843 return process_nds32_specific (filedata);
60abdbed 22844
85f7484a
PB
22845 case EM_68K:
22846 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
22847 display_m68k_gnu_attribute);
22848
34c8bcba 22849 case EM_PPC:
b82317dd 22850 case EM_PPC64:
dda8d76d 22851 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22852 display_power_gnu_attribute);
22853
643f7afb
AK
22854 case EM_S390:
22855 case EM_S390_OLD:
dda8d76d 22856 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22857 display_s390_gnu_attribute);
22858
9e8c70f9
DM
22859 case EM_SPARC:
22860 case EM_SPARC32PLUS:
22861 case EM_SPARCV9:
dda8d76d 22862 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
22863 display_sparc_gnu_attribute);
22864
59e6276b 22865 case EM_TI_C6000:
dda8d76d 22866 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
22867 display_tic6x_attribute,
22868 display_generic_attribute);
22869
0861f561
CQ
22870 case EM_CSKY:
22871 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
22872 display_csky_attribute, NULL);
22873
252b5132 22874 default:
dda8d76d 22875 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
22876 display_public_gnu_attributes,
22877 display_generic_attribute);
252b5132 22878 }
252b5132
RH
22879}
22880
015dc7e1 22881static bool
dda8d76d 22882get_file_header (Filedata * filedata)
252b5132 22883{
9ea033b2 22884 /* Read in the identity array. */
dda8d76d 22885 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22886 return false;
252b5132 22887
9ea033b2 22888 /* Determine how to read the rest of the header. */
dda8d76d 22889 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 22890 {
1a0670f3
AM
22891 default:
22892 case ELFDATANONE:
adab8cdc
AO
22893 case ELFDATA2LSB:
22894 byte_get = byte_get_little_endian;
22895 byte_put = byte_put_little_endian;
22896 break;
22897 case ELFDATA2MSB:
22898 byte_get = byte_get_big_endian;
22899 byte_put = byte_put_big_endian;
22900 break;
9ea033b2
NC
22901 }
22902
22903 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 22904 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
22905
22906 /* Read in the rest of the header. */
22907 if (is_32bit_elf)
22908 {
22909 Elf32_External_Ehdr ehdr32;
252b5132 22910
dda8d76d 22911 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22912 return false;
103f02d3 22913
dda8d76d
NC
22914 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
22915 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
22916 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
22917 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
22918 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
22919 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
22920 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
22921 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
22922 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
22923 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
22924 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
22925 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
22926 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 22927 }
252b5132 22928 else
9ea033b2
NC
22929 {
22930 Elf64_External_Ehdr ehdr64;
a952a375 22931
dda8d76d 22932 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 22933 return false;
103f02d3 22934
dda8d76d
NC
22935 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
22936 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
22937 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
22938 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
22939 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
22940 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
22941 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
22942 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
22943 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
22944 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
22945 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
22946 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
22947 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 22948 }
252b5132 22949
015dc7e1 22950 return true;
252b5132
RH
22951}
22952
13acb58d
AM
22953static void
22954free_filedata (Filedata *filedata)
22955{
22956 free (filedata->program_interpreter);
13acb58d 22957 free (filedata->program_headers);
13acb58d 22958 free (filedata->section_headers);
13acb58d 22959 free (filedata->string_table);
13acb58d 22960 free (filedata->dump.dump_sects);
13acb58d 22961 free (filedata->dynamic_strings);
13acb58d 22962 free (filedata->dynamic_symbols);
13acb58d 22963 free (filedata->dynamic_syminfo);
13acb58d 22964 free (filedata->dynamic_section);
13acb58d
AM
22965
22966 while (filedata->symtab_shndx_list != NULL)
22967 {
22968 elf_section_list *next = filedata->symtab_shndx_list->next;
22969 free (filedata->symtab_shndx_list);
22970 filedata->symtab_shndx_list = next;
22971 }
22972
22973 free (filedata->section_headers_groups);
13acb58d
AM
22974
22975 if (filedata->section_groups)
22976 {
22977 size_t i;
22978 struct group_list * g;
22979 struct group_list * next;
22980
22981 for (i = 0; i < filedata->group_count; i++)
22982 {
22983 for (g = filedata->section_groups [i].root; g != NULL; g = next)
22984 {
22985 next = g->next;
22986 free (g);
22987 }
22988 }
22989
22990 free (filedata->section_groups);
13acb58d 22991 }
066f8fbe
AM
22992 memset (&filedata->section_headers, 0,
22993 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
22994}
22995
dda8d76d
NC
22996static void
22997close_file (Filedata * filedata)
22998{
22999 if (filedata)
23000 {
23001 if (filedata->handle)
23002 fclose (filedata->handle);
23003 free (filedata);
23004 }
23005}
23006
23007void
23008close_debug_file (void * data)
23009{
13acb58d 23010 free_filedata ((Filedata *) data);
dda8d76d
NC
23011 close_file ((Filedata *) data);
23012}
23013
23014static Filedata *
015dc7e1 23015open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23016{
23017 struct stat statbuf;
23018 Filedata * filedata = NULL;
23019
23020 if (stat (pathname, & statbuf) < 0
23021 || ! S_ISREG (statbuf.st_mode))
23022 goto fail;
23023
23024 filedata = calloc (1, sizeof * filedata);
23025 if (filedata == NULL)
23026 goto fail;
23027
23028 filedata->handle = fopen (pathname, "rb");
23029 if (filedata->handle == NULL)
23030 goto fail;
23031
be7d229a 23032 filedata->file_size = statbuf.st_size;
dda8d76d 23033 filedata->file_name = pathname;
ca0e11aa 23034 filedata->is_separate = is_separate;
dda8d76d
NC
23035
23036 if (! get_file_header (filedata))
23037 goto fail;
23038
4de91c10
AM
23039 if (!get_section_headers (filedata, false))
23040 goto fail;
dda8d76d
NC
23041
23042 return filedata;
23043
23044 fail:
23045 if (filedata)
23046 {
23047 if (filedata->handle)
23048 fclose (filedata->handle);
23049 free (filedata);
23050 }
23051 return NULL;
23052}
23053
23054void *
23055open_debug_file (const char * pathname)
23056{
015dc7e1 23057 return open_file (pathname, true);
dda8d76d
NC
23058}
23059
835f2fae
NC
23060static void
23061initialise_dump_sects (Filedata * filedata)
23062{
23063 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23064 Note we do this even if cmdline_dump_sects is empty because we
23065 must make sure that the dump_sets array is zeroed out before each
23066 object file is processed. */
23067 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23068 memset (filedata->dump.dump_sects, 0,
23069 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23070
23071 if (cmdline.num_dump_sects > 0)
23072 {
23073 if (filedata->dump.num_dump_sects == 0)
23074 /* A sneaky way of allocating the dump_sects array. */
23075 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23076
23077 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23078 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23079 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23080 }
23081}
23082
94585d6d
NC
23083static bool
23084might_need_separate_debug_info (Filedata * filedata)
23085{
23086 /* Debuginfo files do not need further separate file loading. */
23087 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23088 return false;
23089
23090 /* Since do_follow_links might be enabled by default, only treat it as an
23091 indication that separate files should be loaded if setting it was a
23092 deliberate user action. */
23093 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23094 return true;
23095
23096 if (process_links || do_syms || do_unwind
23097 || dump_any_debugging || do_dump || do_debugging)
23098 return true;
23099
23100 return false;
23101}
23102
fb52b2f4
NC
23103/* Process one ELF object file according to the command line options.
23104 This file may actually be stored in an archive. The file is
32ec8896
NC
23105 positioned at the start of the ELF object. Returns TRUE if no
23106 problems were encountered, FALSE otherwise. */
fb52b2f4 23107
015dc7e1 23108static bool
dda8d76d 23109process_object (Filedata * filedata)
252b5132 23110{
015dc7e1 23111 bool have_separate_files;
252b5132 23112 unsigned int i;
015dc7e1 23113 bool res;
252b5132 23114
dda8d76d 23115 if (! get_file_header (filedata))
252b5132 23116 {
dda8d76d 23117 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23118 return false;
252b5132
RH
23119 }
23120
23121 /* Initialise per file variables. */
978c4450
AM
23122 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23123 filedata->version_info[i] = 0;
252b5132 23124
978c4450
AM
23125 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23126 filedata->dynamic_info[i] = 0;
23127 filedata->dynamic_info_DT_GNU_HASH = 0;
23128 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23129
23130 /* Process the file. */
23131 if (show_name)
dda8d76d 23132 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23133
835f2fae 23134 initialise_dump_sects (filedata);
d70c5fc7 23135
4de91c10
AM
23136 /* There may be some extensions in the first section header. Don't
23137 bomb if we can't read it. */
23138 get_section_headers (filedata, true);
23139
dda8d76d 23140 if (! process_file_header (filedata))
4de91c10
AM
23141 {
23142 res = false;
23143 goto out;
23144 }
252b5132 23145
e331b18d
AM
23146 /* Throw away the single section header read above, so that we
23147 re-read the entire set. */
23148 free (filedata->section_headers);
23149 filedata->section_headers = NULL;
23150
dda8d76d 23151 if (! process_section_headers (filedata))
2f62977e 23152 {
32ec8896 23153 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23154 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23155
2f62977e 23156 if (! do_using_dynamic)
015dc7e1 23157 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23158 }
252b5132 23159
dda8d76d 23160 if (! process_section_groups (filedata))
32ec8896 23161 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23162 do_unwind = false;
d1f5c6e3 23163
93df3340
AM
23164 process_program_headers (filedata);
23165
23166 res = process_dynamic_section (filedata);
252b5132 23167
dda8d76d 23168 if (! process_relocs (filedata))
015dc7e1 23169 res = false;
252b5132 23170
dda8d76d 23171 if (! process_unwind (filedata))
015dc7e1 23172 res = false;
4d6ed7c8 23173
dda8d76d 23174 if (! process_symbol_table (filedata))
015dc7e1 23175 res = false;
252b5132 23176
0f03783c 23177 if (! process_lto_symbol_tables (filedata))
015dc7e1 23178 res = false;
b9e920ec 23179
dda8d76d 23180 if (! process_syminfo (filedata))
015dc7e1 23181 res = false;
252b5132 23182
dda8d76d 23183 if (! process_version_sections (filedata))
015dc7e1 23184 res = false;
252b5132 23185
94585d6d 23186 if (might_need_separate_debug_info (filedata))
24841daa 23187 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23188 else
015dc7e1 23189 have_separate_files = false;
dda8d76d
NC
23190
23191 if (! process_section_contents (filedata))
015dc7e1 23192 res = false;
f5842774 23193
24841daa 23194 if (have_separate_files)
dda8d76d 23195 {
24841daa
NC
23196 separate_info * d;
23197
23198 for (d = first_separate_info; d != NULL; d = d->next)
23199 {
835f2fae
NC
23200 initialise_dump_sects (d->handle);
23201
ca0e11aa 23202 if (process_links && ! process_file_header (d->handle))
015dc7e1 23203 res = false;
ca0e11aa 23204 else if (! process_section_headers (d->handle))
015dc7e1 23205 res = false;
d6bfbc39 23206 else if (! process_section_contents (d->handle))
015dc7e1 23207 res = false;
ca0e11aa
NC
23208 else if (process_links)
23209 {
ca0e11aa 23210 if (! process_section_groups (d->handle))
015dc7e1 23211 res = false;
93df3340 23212 process_program_headers (d->handle);
ca0e11aa 23213 if (! process_dynamic_section (d->handle))
015dc7e1 23214 res = false;
ca0e11aa 23215 if (! process_relocs (d->handle))
015dc7e1 23216 res = false;
ca0e11aa 23217 if (! process_unwind (d->handle))
015dc7e1 23218 res = false;
ca0e11aa 23219 if (! process_symbol_table (d->handle))
015dc7e1 23220 res = false;
ca0e11aa 23221 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23222 res = false;
ca0e11aa 23223 if (! process_syminfo (d->handle))
015dc7e1 23224 res = false;
ca0e11aa 23225 if (! process_version_sections (d->handle))
015dc7e1 23226 res = false;
ca0e11aa 23227 if (! process_notes (d->handle))
015dc7e1 23228 res = false;
ca0e11aa 23229 }
24841daa
NC
23230 }
23231
23232 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23233 }
23234
23235 if (! process_notes (filedata))
015dc7e1 23236 res = false;
103f02d3 23237
dda8d76d 23238 if (! process_gnu_liblist (filedata))
015dc7e1 23239 res = false;
047b2264 23240
dda8d76d 23241 if (! process_arch_specific (filedata))
015dc7e1 23242 res = false;
252b5132 23243
4de91c10 23244 out:
13acb58d 23245 free_filedata (filedata);
e4b17d5c 23246
19e6b90e 23247 free_debug_memory ();
18bd398b 23248
32ec8896 23249 return res;
252b5132
RH
23250}
23251
2cf0635d 23252/* Process an ELF archive.
32ec8896
NC
23253 On entry the file is positioned just after the ARMAG string.
23254 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23255
015dc7e1
AM
23256static bool
23257process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23258{
23259 struct archive_info arch;
23260 struct archive_info nested_arch;
23261 size_t got;
015dc7e1 23262 bool ret = true;
2cf0635d 23263
015dc7e1 23264 show_name = true;
2cf0635d
NC
23265
23266 /* The ARCH structure is used to hold information about this archive. */
23267 arch.file_name = NULL;
23268 arch.file = NULL;
23269 arch.index_array = NULL;
23270 arch.sym_table = NULL;
23271 arch.longnames = NULL;
23272
23273 /* The NESTED_ARCH structure is used as a single-item cache of information
23274 about a nested archive (when members of a thin archive reside within
23275 another regular archive file). */
23276 nested_arch.file_name = NULL;
23277 nested_arch.file = NULL;
23278 nested_arch.index_array = NULL;
23279 nested_arch.sym_table = NULL;
23280 nested_arch.longnames = NULL;
23281
dda8d76d 23282 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23283 filedata->file_size, is_thin_archive,
23284 do_archive_index) != 0)
2cf0635d 23285 {
015dc7e1 23286 ret = false;
2cf0635d 23287 goto out;
4145f1d5 23288 }
fb52b2f4 23289
4145f1d5
NC
23290 if (do_archive_index)
23291 {
2cf0635d 23292 if (arch.sym_table == NULL)
1cb7d8b1
AM
23293 error (_("%s: unable to dump the index as none was found\n"),
23294 filedata->file_name);
4145f1d5
NC
23295 else
23296 {
26c527e6
AM
23297 uint64_t i, l;
23298 uint64_t current_pos;
4145f1d5 23299
26c527e6
AM
23300 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23301 " %#" PRIx64 " bytes in the symbol table)\n"),
23302 filedata->file_name, arch.index_num,
1cb7d8b1 23303 arch.sym_size);
dda8d76d
NC
23304
23305 current_pos = ftell (filedata->handle);
4145f1d5 23306
2cf0635d 23307 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23308 {
1cb7d8b1
AM
23309 if (i == 0
23310 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23311 {
23312 char * member_name
23313 = get_archive_member_name_at (&arch, arch.index_array[i],
23314 &nested_arch);
2cf0635d 23315
1cb7d8b1
AM
23316 if (member_name != NULL)
23317 {
23318 char * qualified_name
23319 = make_qualified_name (&arch, &nested_arch,
23320 member_name);
2cf0635d 23321
1cb7d8b1
AM
23322 if (qualified_name != NULL)
23323 {
23324 printf (_("Contents of binary %s at offset "),
23325 qualified_name);
c2a7d3f5
NC
23326 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23327 putchar ('\n');
1cb7d8b1
AM
23328 free (qualified_name);
23329 }
fd486f32 23330 free (member_name);
4145f1d5
NC
23331 }
23332 }
2cf0635d
NC
23333
23334 if (l >= arch.sym_size)
4145f1d5 23335 {
1cb7d8b1
AM
23336 error (_("%s: end of the symbol table reached "
23337 "before the end of the index\n"),
dda8d76d 23338 filedata->file_name);
015dc7e1 23339 ret = false;
cb8f3167 23340 break;
4145f1d5 23341 }
591f7597 23342 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23343 printf ("\t%.*s\n",
23344 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23345 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23346 }
23347
67ce483b 23348 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23349 l = (l + 7) & ~ 7;
23350 else
23351 l += l & 1;
23352
2cf0635d 23353 if (l < arch.sym_size)
32ec8896 23354 {
26c527e6 23355 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23356 "but without corresponding entries in "
23357 "the index table\n",
26c527e6 23358 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23359 "but without corresponding entries in "
23360 "the index table\n",
23361 arch.sym_size - l),
dda8d76d 23362 filedata->file_name, arch.sym_size - l);
015dc7e1 23363 ret = false;
32ec8896 23364 }
4145f1d5 23365
63cf857e 23366 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23367 {
1cb7d8b1
AM
23368 error (_("%s: failed to seek back to start of object files "
23369 "in the archive\n"),
dda8d76d 23370 filedata->file_name);
015dc7e1 23371 ret = false;
2cf0635d 23372 goto out;
4145f1d5 23373 }
fb52b2f4 23374 }
4145f1d5
NC
23375
23376 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23377 && !do_segments && !do_header && !do_dump && !do_version
23378 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23379 && !do_section_groups && !do_dyn_syms)
2cf0635d 23380 {
015dc7e1 23381 ret = true; /* Archive index only. */
2cf0635d
NC
23382 goto out;
23383 }
fb52b2f4
NC
23384 }
23385
fb52b2f4
NC
23386 while (1)
23387 {
2cf0635d
NC
23388 char * name;
23389 size_t namelen;
23390 char * qualified_name;
23391
23392 /* Read the next archive header. */
63cf857e 23393 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23394 {
23395 error (_("%s: failed to seek to next archive header\n"),
23396 arch.file_name);
015dc7e1 23397 ret = false;
1cb7d8b1
AM
23398 break;
23399 }
dda8d76d 23400 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23401 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23402 {
23403 if (got == 0)
2cf0635d 23404 break;
28e817cc
NC
23405 /* PR 24049 - we cannot use filedata->file_name as this will
23406 have already been freed. */
23407 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23408
015dc7e1 23409 ret = false;
1cb7d8b1
AM
23410 break;
23411 }
2cf0635d 23412 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23413 {
23414 error (_("%s: did not find a valid archive header\n"),
23415 arch.file_name);
015dc7e1 23416 ret = false;
1cb7d8b1
AM
23417 break;
23418 }
2cf0635d
NC
23419
23420 arch.next_arhdr_offset += sizeof arch.arhdr;
23421
978c4450 23422 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23423
23424 name = get_archive_member_name (&arch, &nested_arch);
23425 if (name == NULL)
fb52b2f4 23426 {
28e817cc 23427 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23428 ret = false;
d989285c 23429 break;
fb52b2f4 23430 }
2cf0635d 23431 namelen = strlen (name);
fb52b2f4 23432
2cf0635d
NC
23433 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23434 if (qualified_name == NULL)
fb52b2f4 23435 {
28e817cc 23436 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23437 free (name);
015dc7e1 23438 ret = false;
d989285c 23439 break;
fb52b2f4
NC
23440 }
23441
2cf0635d 23442 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23443 {
23444 /* This is a proxy for an external member of a thin archive. */
23445 Filedata * member_filedata;
23446 char * member_file_name = adjust_relative_path
dda8d76d 23447 (filedata->file_name, name, namelen);
32ec8896 23448
fd486f32 23449 free (name);
1cb7d8b1
AM
23450 if (member_file_name == NULL)
23451 {
fd486f32 23452 free (qualified_name);
015dc7e1 23453 ret = false;
1cb7d8b1
AM
23454 break;
23455 }
2cf0635d 23456
015dc7e1 23457 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23458 if (member_filedata == NULL)
23459 {
23460 error (_("Input file '%s' is not readable.\n"), member_file_name);
23461 free (member_file_name);
fd486f32 23462 free (qualified_name);
015dc7e1 23463 ret = false;
1cb7d8b1
AM
23464 break;
23465 }
2cf0635d 23466
978c4450 23467 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23468 member_filedata->file_name = qualified_name;
2cf0635d 23469
75a2da57
AH
23470 /* The call to process_object() expects the file to be at the beginning. */
23471 rewind (member_filedata->handle);
23472
1cb7d8b1 23473 if (! process_object (member_filedata))
015dc7e1 23474 ret = false;
2cf0635d 23475
1cb7d8b1
AM
23476 close_file (member_filedata);
23477 free (member_file_name);
1cb7d8b1 23478 }
2cf0635d 23479 else if (is_thin_archive)
1cb7d8b1
AM
23480 {
23481 Filedata thin_filedata;
eb02c04d 23482
1cb7d8b1 23483 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23484
a043396b
NC
23485 /* PR 15140: Allow for corrupt thin archives. */
23486 if (nested_arch.file == NULL)
23487 {
23488 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23489 qualified_name, name);
fd486f32
AM
23490 free (qualified_name);
23491 free (name);
015dc7e1 23492 ret = false;
a043396b
NC
23493 break;
23494 }
fd486f32 23495 free (name);
a043396b 23496
1cb7d8b1 23497 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23498 filedata->archive_file_offset
23499 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23500
1cb7d8b1
AM
23501 /* The nested archive file will have been opened and setup by
23502 get_archive_member_name. */
63cf857e
AM
23503 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23504 SEEK_SET) != 0)
1cb7d8b1
AM
23505 {
23506 error (_("%s: failed to seek to archive member.\n"),
23507 nested_arch.file_name);
fd486f32 23508 free (qualified_name);
015dc7e1 23509 ret = false;
1cb7d8b1
AM
23510 break;
23511 }
2cf0635d 23512
dda8d76d
NC
23513 thin_filedata.handle = nested_arch.file;
23514 thin_filedata.file_name = qualified_name;
9abca702 23515
1cb7d8b1 23516 if (! process_object (& thin_filedata))
015dc7e1 23517 ret = false;
1cb7d8b1 23518 }
2cf0635d 23519 else
1cb7d8b1 23520 {
fd486f32 23521 free (name);
978c4450 23522 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23523 filedata->file_name = qualified_name;
1cb7d8b1 23524 if (! process_object (filedata))
015dc7e1 23525 ret = false;
237877b8 23526 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23527 /* Stop looping with "negative" archive_file_size. */
978c4450 23528 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23529 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23530 }
fb52b2f4 23531
2cf0635d 23532 free (qualified_name);
fb52b2f4
NC
23533 }
23534
4145f1d5 23535 out:
2cf0635d
NC
23536 if (nested_arch.file != NULL)
23537 fclose (nested_arch.file);
23538 release_archive (&nested_arch);
23539 release_archive (&arch);
fb52b2f4 23540
d989285c 23541 return ret;
fb52b2f4
NC
23542}
23543
015dc7e1 23544static bool
2cf0635d 23545process_file (char * file_name)
fb52b2f4 23546{
dda8d76d 23547 Filedata * filedata = NULL;
fb52b2f4
NC
23548 struct stat statbuf;
23549 char armag[SARMAG];
015dc7e1 23550 bool ret = true;
fb52b2f4
NC
23551
23552 if (stat (file_name, &statbuf) < 0)
23553 {
f24ddbdd
NC
23554 if (errno == ENOENT)
23555 error (_("'%s': No such file\n"), file_name);
23556 else
23557 error (_("Could not locate '%s'. System error message: %s\n"),
23558 file_name, strerror (errno));
015dc7e1 23559 return false;
f24ddbdd
NC
23560 }
23561
23562 if (! S_ISREG (statbuf.st_mode))
23563 {
23564 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23565 return false;
fb52b2f4
NC
23566 }
23567
dda8d76d
NC
23568 filedata = calloc (1, sizeof * filedata);
23569 if (filedata == NULL)
23570 {
23571 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23572 return false;
dda8d76d
NC
23573 }
23574
23575 filedata->file_name = file_name;
23576 filedata->handle = fopen (file_name, "rb");
23577 if (filedata->handle == NULL)
fb52b2f4 23578 {
f24ddbdd 23579 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23580 free (filedata);
015dc7e1 23581 return false;
fb52b2f4
NC
23582 }
23583
dda8d76d 23584 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23585 {
4145f1d5 23586 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23587 fclose (filedata->handle);
23588 free (filedata);
015dc7e1 23589 return false;
fb52b2f4
NC
23590 }
23591
be7d229a 23592 filedata->file_size = statbuf.st_size;
015dc7e1 23593 filedata->is_separate = false;
f54498b4 23594
fb52b2f4 23595 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23596 {
015dc7e1
AM
23597 if (! process_archive (filedata, false))
23598 ret = false;
32ec8896 23599 }
2cf0635d 23600 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23601 {
015dc7e1
AM
23602 if ( ! process_archive (filedata, true))
23603 ret = false;
32ec8896 23604 }
fb52b2f4
NC
23605 else
23606 {
1b513401 23607 if (do_archive_index && !check_all)
4145f1d5
NC
23608 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23609 file_name);
23610
dda8d76d 23611 rewind (filedata->handle);
978c4450 23612 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23613
dda8d76d 23614 if (! process_object (filedata))
015dc7e1 23615 ret = false;
fb52b2f4
NC
23616 }
23617
dda8d76d 23618 fclose (filedata->handle);
8fb879cd
AM
23619 free (filedata->section_headers);
23620 free (filedata->program_headers);
23621 free (filedata->string_table);
6431e409 23622 free (filedata->dump.dump_sects);
dda8d76d 23623 free (filedata);
32ec8896 23624
fd486f32 23625 free (ba_cache.strtab);
1bd6175a 23626 ba_cache.strtab = NULL;
fd486f32 23627 free (ba_cache.symtab);
1bd6175a 23628 ba_cache.symtab = NULL;
fd486f32
AM
23629 ba_cache.filedata = NULL;
23630
fb52b2f4
NC
23631 return ret;
23632}
23633
252b5132
RH
23634#ifdef SUPPORT_DISASSEMBLY
23635/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23636 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23637 symbols. */
252b5132
RH
23638
23639void
2cf0635d 23640print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23641{
23642 fprintf (outfile,"0x%8.8x", addr);
23643}
23644
e3c8793a 23645/* Needed by the i386 disassembler. */
dda8d76d 23646
252b5132
RH
23647void
23648db_task_printsym (unsigned int addr)
23649{
23650 print_address (addr, stderr);
23651}
23652#endif
23653
23654int
2cf0635d 23655main (int argc, char ** argv)
252b5132 23656{
ff78d6d6
L
23657 int err;
23658
87b9f255 23659#ifdef HAVE_LC_MESSAGES
252b5132 23660 setlocale (LC_MESSAGES, "");
3882b010 23661#endif
3882b010 23662 setlocale (LC_CTYPE, "");
252b5132
RH
23663 bindtextdomain (PACKAGE, LOCALEDIR);
23664 textdomain (PACKAGE);
23665
869b9d07
MM
23666 expandargv (&argc, &argv);
23667
dda8d76d 23668 parse_args (& cmdline, argc, argv);
59f14fc0 23669
18bd398b 23670 if (optind < (argc - 1))
1b513401
NC
23671 /* When displaying information for more than one file,
23672 prefix the information with the file name. */
015dc7e1 23673 show_name = true;
5656ba2c
L
23674 else if (optind >= argc)
23675 {
1b513401 23676 /* Ensure that the warning is always displayed. */
015dc7e1 23677 do_checks = true;
1b513401 23678
5656ba2c
L
23679 warn (_("Nothing to do.\n"));
23680 usage (stderr);
23681 }
18bd398b 23682
015dc7e1 23683 err = false;
252b5132 23684 while (optind < argc)
32ec8896 23685 if (! process_file (argv[optind++]))
015dc7e1 23686 err = true;
252b5132 23687
9db70fc3 23688 free (cmdline.dump_sects);
252b5132 23689
7d9813f1
NA
23690 free (dump_ctf_symtab_name);
23691 free (dump_ctf_strtab_name);
23692 free (dump_ctf_parent_name);
23693
32ec8896 23694 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23695}