]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Simplify readelf's RELR relocation display.
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
fd67aa11 2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
1f5a3546
FS
47#ifdef HAVE_ZSTD
48#include <zstd.h>
49#endif
7bfd842d 50#include <wchar.h>
252b5132 51
2952f10c
SM
52#if defined HAVE_MSGPACK
53#include <msgpack.h>
54#endif
55
19936277 56/* Define BFD64 here, even if our default architecture is 32 bit ELF
625d49fc 57 as this will allow us to read in and parse 64bit and 32bit ELF files. */
19936277 58#define BFD64
a952a375 59
3db64b00
AM
60#include "bfd.h"
61#include "bucomm.h"
3284fe0c 62#include "elfcomm.h"
0d646226 63#include "demanguse.h"
19e6b90e 64#include "dwarf.h"
7d9813f1 65#include "ctf-api.h"
42b6953b 66#include "sframe-api.h"
79bc120c 67#include "demangle.h"
252b5132
RH
68
69#include "elf/common.h"
70#include "elf/external.h"
71#include "elf/internal.h"
252b5132 72
4b78141a
NC
73
74/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
75 we can obtain the H8 reloc numbers. We need these for the
76 get_reloc_size() function. We include h8.h again after defining
77 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
78
79#include "elf/h8.h"
80#undef _ELF_H8_H
81
82/* Undo the effects of #including reloc-macros.h. */
83
84#undef START_RELOC_NUMBERS
85#undef RELOC_NUMBER
86#undef FAKE_RELOC
87#undef EMPTY_RELOC
88#undef END_RELOC_NUMBERS
89#undef _RELOC_MACROS_H
90
252b5132
RH
91/* The following headers use the elf/reloc-macros.h file to
92 automatically generate relocation recognition functions
93 such as elf_mips_reloc_type() */
94
95#define RELOC_MACROS_GEN_FUNC
96
a06ea964 97#include "elf/aarch64.h"
252b5132 98#include "elf/alpha.h"
c077c580 99#include "elf/amdgpu.h"
3b16e843 100#include "elf/arc.h"
252b5132 101#include "elf/arm.h"
3b16e843 102#include "elf/avr.h"
1d65ded4 103#include "elf/bfin.h"
60bca95a 104#include "elf/cr16.h"
3b16e843 105#include "elf/cris.h"
1c0d3aa6 106#include "elf/crx.h"
b8891f8d 107#include "elf/csky.h"
252b5132
RH
108#include "elf/d10v.h"
109#include "elf/d30v.h"
d172d4ba 110#include "elf/dlx.h"
aca4efc7 111#include "elf/bpf.h"
cfb8c092 112#include "elf/epiphany.h"
252b5132 113#include "elf/fr30.h"
5c70f934 114#include "elf/frv.h"
3f8107ab 115#include "elf/ft32.h"
3b16e843
NC
116#include "elf/h8.h"
117#include "elf/hppa.h"
118#include "elf/i386.h"
f954747f
AM
119#include "elf/i370.h"
120#include "elf/i860.h"
121#include "elf/i960.h"
3b16e843 122#include "elf/ia64.h"
1e4cf259 123#include "elf/ip2k.h"
6e712424 124#include "elf/kvx.h"
84e94c90 125#include "elf/lm32.h"
1c0d3aa6 126#include "elf/iq2000.h"
49f58d10 127#include "elf/m32c.h"
3b16e843
NC
128#include "elf/m32r.h"
129#include "elf/m68k.h"
75751cd9 130#include "elf/m68hc11.h"
7b4ae824 131#include "elf/s12z.h"
252b5132 132#include "elf/mcore.h"
15ab5209 133#include "elf/mep.h"
a3c62988 134#include "elf/metag.h"
7ba29e2a 135#include "elf/microblaze.h"
3b16e843 136#include "elf/mips.h"
3c3bdf30 137#include "elf/mmix.h"
3b16e843
NC
138#include "elf/mn10200.h"
139#include "elf/mn10300.h"
5506d11a 140#include "elf/moxie.h"
4970f871 141#include "elf/mt.h"
2469cfa2 142#include "elf/msp430.h"
35c08157 143#include "elf/nds32.h"
fe944acf 144#include "elf/nfp.h"
13761a11 145#include "elf/nios2.h"
73589c9d 146#include "elf/or1k.h"
7d466069 147#include "elf/pj.h"
3b16e843 148#include "elf/ppc.h"
c833c019 149#include "elf/ppc64.h"
2b100bb5 150#include "elf/pru.h"
03336641 151#include "elf/riscv.h"
99c513f6 152#include "elf/rl78.h"
c7927a3c 153#include "elf/rx.h"
a85d7ed0 154#include "elf/s390.h"
1c0d3aa6 155#include "elf/score.h"
3b16e843
NC
156#include "elf/sh.h"
157#include "elf/sparc.h"
e9f53129 158#include "elf/spu.h"
40b36596 159#include "elf/tic6x.h"
aa137e4d
NC
160#include "elf/tilegx.h"
161#include "elf/tilepro.h"
3b16e843 162#include "elf/v850.h"
179d3252 163#include "elf/vax.h"
619ed720 164#include "elf/visium.h"
f96bd6c2 165#include "elf/wasm32.h"
3b16e843 166#include "elf/x86-64.h"
f6c1a2d5 167#include "elf/xgate.h"
93fbbb04 168#include "elf/xstormy16.h"
88da6820 169#include "elf/xtensa.h"
6655dba2 170#include "elf/z80.h"
e9a0721f 171#include "elf/loongarch.h"
b5c37946 172#include "elf/bpf.h"
252b5132 173
252b5132 174#include "getopt.h"
566b0d53 175#include "libiberty.h"
09c11c86 176#include "safe-ctype.h"
2cf0635d 177#include "filenames.h"
252b5132 178
15b42fb0
AM
179#ifndef offsetof
180#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
181#endif
182
6a40cf0c
NC
183typedef struct elf_section_list
184{
dda8d76d
NC
185 Elf_Internal_Shdr * hdr;
186 struct elf_section_list * next;
6a40cf0c
NC
187} elf_section_list;
188
dda8d76d
NC
189/* Flag bits indicating particular types of dump. */
190#define HEX_DUMP (1 << 0) /* The -x command line switch. */
8e8d0b63 191#ifdef SUPPORT_DISASSEMBLY
dda8d76d 192#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
8e8d0b63 193#endif
dda8d76d
NC
194#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
195#define STRING_DUMP (1 << 3) /* The -p command line switch. */
196#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 197#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
42b6953b 198#define SFRAME_DUMP (1 << 6) /* The --sframe command line switch. */
8e8d0b63 199#define AUTO_DUMP (1 << 7) /* The -j command line switch. */
dda8d76d
NC
200
201typedef unsigned char dump_type;
202
203/* A linked list of the section names for which dumps were requested. */
204struct dump_list_entry
205{
206 char * name;
207 dump_type type;
208 struct dump_list_entry * next;
209};
210
6431e409
AM
211/* A dynamic array of flags indicating for which sections a dump
212 has been requested via command line switches. */
1b513401
NC
213struct dump_data
214{
6431e409
AM
215 dump_type * dump_sects;
216 unsigned int num_dump_sects;
217};
218
219static struct dump_data cmdline;
220
221static struct dump_list_entry * dump_sects_byname;
222
2cf0635d 223char * program_name = "readelf";
dda8d76d 224
015dc7e1
AM
225static bool show_name = false;
226static bool do_dynamic = false;
227static bool do_syms = false;
228static bool do_dyn_syms = false;
229static bool do_lto_syms = false;
230static bool do_reloc = false;
231static bool do_sections = false;
232static bool do_section_groups = false;
233static bool do_section_details = false;
234static bool do_segments = false;
235static bool do_unwind = false;
236static bool do_using_dynamic = false;
237static bool do_header = false;
238static bool do_dump = false;
239static bool do_version = false;
240static bool do_histogram = false;
241static bool do_debugging = false;
242static bool do_ctf = false;
42b6953b 243static bool do_sframe = false;
015dc7e1
AM
244static bool do_arch = false;
245static bool do_notes = false;
246static bool do_archive_index = false;
247static bool check_all = false;
248static bool is_32bit_elf = false;
249static bool decompress_dumps = false;
250static bool do_not_show_symbol_truncation = false;
251static bool do_demangle = false; /* Pretty print C++ symbol names. */
252static bool process_links = false;
e1dbfc17 253static bool dump_any_debugging = false;
b6ac461a 254static bool extra_sym_info = false;
79bc120c 255static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 256static int sym_base = 0;
252b5132 257
7d9813f1
NA
258static char *dump_ctf_parent_name;
259static char *dump_ctf_symtab_name;
260static char *dump_ctf_strtab_name;
261
e4b17d5c
L
262struct group_list
263{
dda8d76d
NC
264 struct group_list * next;
265 unsigned int section_index;
e4b17d5c
L
266};
267
268struct group
269{
dda8d76d
NC
270 struct group_list * root;
271 unsigned int group_index;
e4b17d5c
L
272};
273
978c4450
AM
274typedef struct filedata
275{
276 const char * file_name;
015dc7e1 277 bool is_separate;
978c4450 278 FILE * handle;
be7d229a 279 uint64_t file_size;
978c4450 280 Elf_Internal_Ehdr file_header;
26c527e6
AM
281 uint64_t archive_file_offset;
282 uint64_t archive_file_size;
066f8fbe 283 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
284 Elf_Internal_Shdr * section_headers;
285 Elf_Internal_Phdr * program_headers;
286 char * string_table;
26c527e6
AM
287 uint64_t string_table_length;
288 uint64_t dynamic_addr;
be7d229a 289 uint64_t dynamic_size;
26c527e6 290 uint64_t dynamic_nent;
978c4450 291 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 292 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450 293 char * dynamic_strings;
26c527e6 294 uint64_t dynamic_strings_length;
8ac10c5b 295 Elf_Internal_Shdr * dynamic_symtab_section;
26c527e6 296 uint64_t num_dynamic_syms;
978c4450 297 Elf_Internal_Sym * dynamic_symbols;
26c527e6 298 uint64_t version_info[16];
978c4450
AM
299 unsigned int dynamic_syminfo_nent;
300 Elf_Internal_Syminfo * dynamic_syminfo;
26c527e6 301 uint64_t dynamic_syminfo_offset;
be7d229a
AM
302 uint64_t nbuckets;
303 uint64_t nchains;
625d49fc
AM
304 uint64_t * buckets;
305 uint64_t * chains;
be7d229a
AM
306 uint64_t ngnubuckets;
307 uint64_t ngnuchains;
625d49fc
AM
308 uint64_t * gnubuckets;
309 uint64_t * gnuchains;
310 uint64_t * mipsxlat;
311 uint64_t gnusymidx;
13acb58d 312 char * program_interpreter;
bc227f4c 313 uint64_t dynamic_info[DT_RELRENT + 1];
625d49fc
AM
314 uint64_t dynamic_info_DT_GNU_HASH;
315 uint64_t dynamic_info_DT_MIPS_XHASH;
978c4450
AM
316 elf_section_list * symtab_shndx_list;
317 size_t group_count;
318 struct group * section_groups;
319 struct group ** section_headers_groups;
320 /* A dynamic array of flags indicating for which sections a dump of
321 some kind has been requested. It is reset on a per-object file
322 basis and then initialised from the cmdline_dump_sects array,
323 the results of interpreting the -w switch, and the
324 dump_sects_byname list. */
325 struct dump_data dump;
326} Filedata;
aef1f6d0 327
c256ffe7 328/* How to print a vma value. */
843dd992
NC
329typedef enum print_mode
330{
331 HEX,
047c3dbf 332 HEX_5,
843dd992
NC
333 DEC,
334 DEC_5,
335 UNSIGNED,
047c3dbf 336 UNSIGNED_5,
843dd992 337 PREFIX_HEX,
047c3dbf 338 PREFIX_HEX_5,
843dd992 339 FULL_HEX,
047c3dbf 340 LONG_HEX,
fcf8f323 341 ZERO_HEX,
047c3dbf
NL
342 OCTAL,
343 OCTAL_5
843dd992
NC
344}
345print_mode;
346
b3aa80b4
NC
347typedef enum unicode_display_type
348{
349 unicode_default = 0,
350 unicode_locale,
351 unicode_escape,
352 unicode_hex,
353 unicode_highlight,
354 unicode_invalid
355} unicode_display_type;
356
357static unicode_display_type unicode_display = unicode_default;
358
a7fd1186
FS
359typedef enum
360{
361 reltype_unknown,
362 reltype_rel,
363 reltype_rela,
364 reltype_relr
365} relocation_type;
366
bb4d2ac2
L
367/* Versioned symbol info. */
368enum versioned_symbol_info
369{
370 symbol_undefined,
371 symbol_hidden,
372 symbol_public
373};
374
63cf857e
AM
375static int
376fseek64 (FILE *stream, int64_t offset, int whence)
377{
378#if defined (HAVE_FSEEKO64)
379 off64_t o = offset;
380 if (o != offset)
381 {
382 errno = EINVAL;
383 return -1;
384 }
385 return fseeko64 (stream, o, whence);
386#elif defined (HAVE_FSEEKO)
387 off_t o = offset;
388 if (o != offset)
389 {
390 errno = EINVAL;
391 return -1;
392 }
393 return fseeko (stream, o, whence);
394#else
395 long o = offset;
396 if (o != offset)
397 {
398 errno = EINVAL;
399 return -1;
400 }
401 return fseek (stream, o, whence);
402#endif
403}
404
32ec8896 405static const char * get_symbol_version_string
26c527e6 406 (Filedata *, bool, const char *, size_t, unsigned,
32ec8896 407 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 408
8e8d0b63
NC
409static bool process_notes_at
410 (Filedata *, Elf_Internal_Shdr *, uint64_t, uint64_t, uint64_t);
411
9c19a809
NC
412#define UNKNOWN -1
413
84714f86
AM
414static inline const char *
415section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
416{
417 return filedata->string_table + hdr->sh_name;
418}
b9e920ec 419
84714f86
AM
420static inline bool
421section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
422{
b6ac461a
NC
423 return (filedata != NULL
424 && hdr != NULL
84714f86
AM
425 && filedata->string_table != NULL
426 && hdr->sh_name < filedata->string_table_length);
427}
b9e920ec 428
b6ac461a
NC
429/* Returns true if the given index is real/valid. Note: "real" here
430 means "references a real section in the section header" and not
431 "is a valid section index as per the ELF standard". */
432
433static inline bool
434section_index_real (const Filedata *filedata, unsigned int ndx)
84714f86 435{
b6ac461a
NC
436 return (filedata != NULL
437 && filedata->section_headers != NULL
438 && ndx < filedata->file_header.e_shnum
439 && ndx > 0);
84714f86 440}
b6ac461a 441
ee42cf8c 442#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 443
84714f86
AM
444static inline bool
445valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
446{
447 return strtab != NULL && offset < strtab_size;
448}
449
450static inline bool
451valid_dynamic_name (const Filedata *filedata, uint64_t offset)
452{
453 return valid_symbol_name (filedata->dynamic_strings,
454 filedata->dynamic_strings_length, offset);
455}
456
d79b3d50
NC
457/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
458 already been called and verified that the string exists. */
84714f86
AM
459static inline const char *
460get_dynamic_name (const Filedata *filedata, size_t offset)
461{
462 return filedata->dynamic_strings + offset;
463}
18bd398b 464
61865e30
NC
465#define REMOVE_ARCH_BITS(ADDR) \
466 do \
467 { \
dda8d76d 468 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
469 (ADDR) &= ~1; \
470 } \
471 while (0)
f16a9783
MS
472
473/* Get the correct GNU hash section name. */
978c4450
AM
474#define GNU_HASH_SECTION_NAME(filedata) \
475 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 476\f
dda8d76d
NC
477/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
478 OFFSET + the offset of the current archive member, if we are examining an
479 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
480 allocate a buffer using malloc and fill that. In either case return the
481 pointer to the start of the retrieved data or NULL if something went wrong.
482 If something does go wrong and REASON is not NULL then emit an error
483 message using REASON as part of the context. */
59245841 484
c256ffe7 485static void *
be7d229a
AM
486get_data (void *var,
487 Filedata *filedata,
26c527e6 488 uint64_t offset,
be7d229a
AM
489 uint64_t size,
490 uint64_t nmemb,
491 const char *reason)
a6e9f9df 492{
2cf0635d 493 void * mvar;
be7d229a 494 uint64_t amt = size * nmemb;
a6e9f9df 495
c256ffe7 496 if (size == 0 || nmemb == 0)
a6e9f9df
AM
497 return NULL;
498
be7d229a
AM
499 /* If size_t is smaller than uint64_t, eg because you are building
500 on a 32-bit host, then make sure that when the sizes are cast to
501 size_t no information is lost. */
7c1c1904
AM
502 if ((size_t) size != size
503 || (size_t) nmemb != nmemb
be7d229a
AM
504 || (size_t) amt != amt
505 || amt / size != nmemb
506 || (size_t) amt + 1 == 0)
57028622
NC
507 {
508 if (reason)
b8281767
AM
509 error (_("Size overflow prevents reading %" PRIu64
510 " elements of size %" PRIu64 " for %s\n"),
be7d229a 511 nmemb, size, reason);
57028622
NC
512 return NULL;
513 }
514
c22b42ce 515 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 516 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
517 if (filedata->archive_file_offset > filedata->file_size
518 || offset > filedata->file_size - filedata->archive_file_offset
519 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 520 {
049b0c3a 521 if (reason)
b8281767 522 error (_("Reading %" PRIu64 " bytes extends past end of file for %s\n"),
be7d229a 523 amt, reason);
a6e9f9df
AM
524 return NULL;
525 }
526
63cf857e
AM
527 if (fseek64 (filedata->handle, filedata->archive_file_offset + offset,
528 SEEK_SET))
071436c6
NC
529 {
530 if (reason)
26c527e6 531 error (_("Unable to seek to %#" PRIx64 " for %s\n"),
978c4450 532 filedata->archive_file_offset + offset, reason);
071436c6
NC
533 return NULL;
534 }
535
a6e9f9df
AM
536 mvar = var;
537 if (mvar == NULL)
538 {
7c1c1904
AM
539 /* + 1 so that we can '\0' terminate invalid string table sections. */
540 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
541
542 if (mvar == NULL)
543 {
049b0c3a 544 if (reason)
b8281767 545 error (_("Out of memory allocating %" PRIu64 " bytes for %s\n"),
be7d229a 546 amt, reason);
a6e9f9df
AM
547 return NULL;
548 }
c256ffe7 549
c9c1d674 550 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
551 }
552
dda8d76d 553 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 554 {
049b0c3a 555 if (reason)
b8281767 556 error (_("Unable to read in %" PRIu64 " bytes of %s\n"),
be7d229a 557 amt, reason);
a6e9f9df
AM
558 if (mvar != var)
559 free (mvar);
560 return NULL;
561 }
562
563 return mvar;
564}
565
32ec8896
NC
566/* Print a VMA value in the MODE specified.
567 Returns the number of characters displayed. */
cb8f3167 568
32ec8896 569static unsigned int
625d49fc 570print_vma (uint64_t vma, print_mode mode)
66543521 571{
32ec8896 572 unsigned int nc = 0;
66543521 573
14a91970 574 switch (mode)
66543521 575 {
14a91970
AM
576 case FULL_HEX:
577 nc = printf ("0x");
1a0670f3 578 /* Fall through. */
14a91970 579 case LONG_HEX:
f493c217 580 if (!is_32bit_elf)
625d49fc
AM
581 return nc + printf ("%16.16" PRIx64, vma);
582 return nc + printf ("%8.8" PRIx64, vma);
b19aac67 583
fcf8f323
NC
584 case ZERO_HEX:
585 if (is_32bit_elf)
586 return printf ("%08" PRIx64, vma);
587 return printf ("%016" PRIx64, vma);
588
14a91970
AM
589 case DEC_5:
590 if (vma <= 99999)
625d49fc 591 return printf ("%5" PRId64, vma);
1a0670f3 592 /* Fall through. */
14a91970
AM
593 case PREFIX_HEX:
594 nc = printf ("0x");
1a0670f3 595 /* Fall through. */
14a91970 596 case HEX:
625d49fc 597 return nc + printf ("%" PRIx64, vma);
b19aac67 598
047c3dbf
NL
599 case PREFIX_HEX_5:
600 nc = printf ("0x");
601 /* Fall through. */
602 case HEX_5:
625d49fc 603 return nc + printf ("%05" PRIx64, vma);
047c3dbf 604
14a91970 605 case DEC:
625d49fc 606 return printf ("%" PRId64, vma);
b19aac67 607
14a91970 608 case UNSIGNED:
625d49fc 609 return printf ("%" PRIu64, vma);
32ec8896 610
047c3dbf 611 case UNSIGNED_5:
625d49fc 612 return printf ("%5" PRIu64, vma);
047c3dbf
NL
613
614 case OCTAL:
625d49fc 615 return printf ("%" PRIo64, vma);
047c3dbf
NL
616
617 case OCTAL_5:
625d49fc 618 return printf ("%5" PRIo64, vma);
047c3dbf 619
32ec8896
NC
620 default:
621 /* FIXME: Report unrecognised mode ? */
622 return 0;
f7a99963 623 }
f7a99963
NC
624}
625
047c3dbf 626
7bfd842d 627/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 628 multibye characters (assuming the host environment supports them).
31104126 629
b6ac461a
NC
630 Display at most abs(WIDTH) characters, truncating as necessary,
631 unless do_wide or extra_sym_info is true.
7bfd842d 632
0942c7ab
NC
633 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
634 abs(WIDTH) - 5 characters followed by "[...]".
635
7bfd842d
NC
636 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
637 padding as necessary.
171191ba
NC
638
639 Returns the number of emitted characters. */
640
641static unsigned int
b6ac461a 642print_symbol_name (signed int width, const char * symbol)
31104126 643{
015dc7e1
AM
644 bool extra_padding = false;
645 bool do_dots = false;
32ec8896 646 signed int num_printed = 0;
3bfcb652 647#ifdef HAVE_MBSTATE_T
7bfd842d 648 mbstate_t state;
3bfcb652 649#endif
32ec8896 650 unsigned int width_remaining;
79bc120c 651 const void * alloced_symbol = NULL;
961c521f 652
7bfd842d 653 if (width < 0)
961c521f 654 {
88305e1b 655 /* Keep the width positive. This helps the code below. */
961c521f 656 width = - width;
015dc7e1 657 extra_padding = true;
0b4362b0 658 }
56d8f8a9
NC
659 else if (width == 0)
660 return 0;
961c521f 661
b6ac461a 662 if (do_wide || extra_sym_info)
7bfd842d
NC
663 /* Set the remaining width to a very large value.
664 This simplifies the code below. */
665 width_remaining = INT_MAX;
666 else
0942c7ab
NC
667 {
668 width_remaining = width;
b6ac461a 669
0942c7ab
NC
670 if (! do_not_show_symbol_truncation
671 && (int) strlen (symbol) > width)
672 {
673 width_remaining -= 5;
674 if ((int) width_remaining < 0)
675 width_remaining = 0;
015dc7e1 676 do_dots = true;
0942c7ab
NC
677 }
678 }
cb8f3167 679
3bfcb652 680#ifdef HAVE_MBSTATE_T
7bfd842d
NC
681 /* Initialise the multibyte conversion state. */
682 memset (& state, 0, sizeof (state));
3bfcb652 683#endif
961c521f 684
79bc120c
NC
685 if (do_demangle && *symbol)
686 {
687 const char * res = cplus_demangle (symbol, demangle_flags);
688
689 if (res != NULL)
690 alloced_symbol = symbol = res;
691 }
692
7bfd842d
NC
693 while (width_remaining)
694 {
695 size_t n;
7bfd842d 696 const char c = *symbol++;
961c521f 697
7bfd842d 698 if (c == 0)
961c521f
NC
699 break;
700
b3aa80b4
NC
701 if (ISPRINT (c))
702 {
703 putchar (c);
704 width_remaining --;
705 num_printed ++;
706 }
707 else if (ISCNTRL (c))
961c521f 708 {
b3aa80b4
NC
709 /* Do not print control characters directly as they can affect terminal
710 settings. Such characters usually appear in the names generated
711 by the assembler for local labels. */
712
7bfd842d 713 if (width_remaining < 2)
961c521f
NC
714 break;
715
7bfd842d
NC
716 printf ("^%c", c + 0x40);
717 width_remaining -= 2;
171191ba 718 num_printed += 2;
961c521f 719 }
b3aa80b4 720 else if (c == 0x7f)
7bfd842d 721 {
b3aa80b4
NC
722 if (width_remaining < 5)
723 break;
724 printf ("<DEL>");
725 width_remaining -= 5;
726 num_printed += 5;
727 }
728 else if (unicode_display != unicode_locale
729 && unicode_display != unicode_default)
730 {
731 /* Display unicode characters as something else. */
732 unsigned char bytes[4];
733 bool is_utf8;
795588ae 734 unsigned int nbytes;
b3aa80b4
NC
735
736 bytes[0] = c;
737
738 if (bytes[0] < 0xc0)
739 {
740 nbytes = 1;
741 is_utf8 = false;
742 }
743 else
744 {
745 bytes[1] = *symbol++;
746
747 if ((bytes[1] & 0xc0) != 0x80)
748 {
749 is_utf8 = false;
750 /* Do not consume this character. It may only
751 be the first byte in the sequence that was
752 corrupt. */
753 --symbol;
754 nbytes = 1;
755 }
756 else if ((bytes[0] & 0x20) == 0)
757 {
758 is_utf8 = true;
759 nbytes = 2;
760 }
761 else
762 {
763 bytes[2] = *symbol++;
764
765 if ((bytes[2] & 0xc0) != 0x80)
766 {
767 is_utf8 = false;
768 symbol -= 2;
769 nbytes = 1;
770 }
771 else if ((bytes[0] & 0x10) == 0)
772 {
773 is_utf8 = true;
774 nbytes = 3;
775 }
776 else
777 {
778 bytes[3] = *symbol++;
779
780 nbytes = 4;
781
782 if ((bytes[3] & 0xc0) != 0x80)
783 {
784 is_utf8 = false;
785 symbol -= 3;
786 nbytes = 1;
787 }
788 else
789 is_utf8 = true;
790 }
791 }
792 }
793
794 if (unicode_display == unicode_invalid)
795 is_utf8 = false;
796
797 if (unicode_display == unicode_hex || ! is_utf8)
798 {
795588ae 799 unsigned int i;
b3aa80b4
NC
800
801 if (width_remaining < (nbytes * 2) + 2)
802 break;
803
804 putchar (is_utf8 ? '<' : '{');
805 printf ("0x");
806 for (i = 0; i < nbytes; i++)
807 printf ("%02x", bytes[i]);
808 putchar (is_utf8 ? '>' : '}');
809 }
810 else
811 {
812 if (unicode_display == unicode_highlight && isatty (1))
813 printf ("\x1B[31;47m"); /* Red. */
814
815 switch (nbytes)
816 {
817 case 2:
818 if (width_remaining < 6)
819 break;
820 printf ("\\u%02x%02x",
821 (bytes[0] & 0x1c) >> 2,
822 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
823 break;
824 case 3:
825 if (width_remaining < 6)
826 break;
827 printf ("\\u%02x%02x",
828 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
829 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
830 break;
831 case 4:
832 if (width_remaining < 8)
833 break;
834 printf ("\\u%02x%02x%02x",
835 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
836 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
837 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
838
839 break;
840 default:
841 /* URG. */
842 break;
843 }
844
845 if (unicode_display == unicode_highlight && isatty (1))
846 printf ("\033[0m"); /* Default colour. */
847 }
848
849 if (bytes[nbytes - 1] == 0)
850 break;
7bfd842d 851 }
961c521f
NC
852 else
853 {
3bfcb652
NC
854#ifdef HAVE_MBSTATE_T
855 wchar_t w;
856#endif
7bfd842d
NC
857 /* Let printf do the hard work of displaying multibyte characters. */
858 printf ("%.1s", symbol - 1);
859 width_remaining --;
860 num_printed ++;
861
3bfcb652 862#ifdef HAVE_MBSTATE_T
7bfd842d
NC
863 /* Try to find out how many bytes made up the character that was
864 just printed. Advance the symbol pointer past the bytes that
865 were displayed. */
866 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
867#else
868 n = 1;
869#endif
7bfd842d
NC
870 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
871 symbol += (n - 1);
961c521f 872 }
961c521f 873 }
171191ba 874
0942c7ab
NC
875 if (do_dots)
876 num_printed += printf ("[...]");
877
7bfd842d 878 if (extra_padding && num_printed < width)
171191ba
NC
879 {
880 /* Fill in the remaining spaces. */
7bfd842d
NC
881 printf ("%-*s", width - num_printed, " ");
882 num_printed = width;
171191ba
NC
883 }
884
79bc120c 885 free ((void *) alloced_symbol);
171191ba 886 return num_printed;
31104126
NC
887}
888
1449284b 889/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
890 the given section's name. Like print_symbol, except that it does not try
891 to print multibyte characters, it just interprets them as hex values. */
892
893static const char *
dda8d76d 894printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 895{
b6ac461a
NC
896#define NUM_SEC_NAME_BUFS 5
897#define MAX_PRINT_SEC_NAME_LEN 256
898
899 static int sec_name_buf_index = 0;
900 /* We use a rotating array of static buffers, so that multiple successive calls
901 to printable_section_name() will still work. eg when used in a printf. */
902 static char sec_name_buf [NUM_SEC_NAME_BUFS][MAX_PRINT_SEC_NAME_LEN + 1];
903
904 const char * name;
905 char * buf;
906 char * buf_start;
74e1a04b
NC
907 char c;
908 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
909
b6ac461a
NC
910 /* Validate the input parameters. */
911 if (filedata == NULL)
912 return _("<internal error>");
913 if (sec == NULL)
914 return _("<none>");
915 if (filedata->string_table == NULL)
916 return _("<no-strings>");
917 if (sec->sh_name >= filedata->string_table_length)
918 return _("<corrupt>");
919
920 /* Select a buffer to use. */
921 buf_start = buf = sec_name_buf[sec_name_buf_index];
922 if (++sec_name_buf_index >= NUM_SEC_NAME_BUFS)
923 sec_name_buf_index = 0;
924
925 name = section_name (filedata, sec);
926
74e1a04b
NC
927 while ((c = * name ++) != 0)
928 {
929 if (ISCNTRL (c))
930 {
931 if (remaining < 2)
932 break;
948f632f 933
74e1a04b
NC
934 * buf ++ = '^';
935 * buf ++ = c + 0x40;
936 remaining -= 2;
937 }
938 else if (ISPRINT (c))
939 {
940 * buf ++ = c;
941 remaining -= 1;
942 }
943 else
944 {
945 static char hex[17] = "0123456789ABCDEF";
946
947 if (remaining < 4)
948 break;
949 * buf ++ = '<';
950 * buf ++ = hex[(c & 0xf0) >> 4];
951 * buf ++ = hex[c & 0x0f];
952 * buf ++ = '>';
953 remaining -= 4;
954 }
955
956 if (remaining == 0)
957 break;
958 }
959
960 * buf = 0;
b6ac461a
NC
961 return buf_start;
962}
963
964/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
965 This OS has so many departures from the ELF standard that we test it at
966 many places. */
967
968static inline bool
969is_ia64_vms (Filedata * filedata)
970{
971 return filedata->file_header.e_machine == EM_IA_64
972 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
74e1a04b
NC
973}
974
975static const char *
b6ac461a
NC
976printable_section_name_from_index (Filedata * filedata,
977 size_t ndx,
978 bool * is_special)
74e1a04b 979{
b6ac461a
NC
980 if (is_special != NULL)
981 * is_special = true;
982
983 switch (ndx)
984 {
985 case SHN_UNDEF: return "UND";
986 case SHN_ABS: return "ABS";
987 case SHN_COMMON: return "COM";
988 break;
989 }
990
991 if (filedata != NULL)
992 {
993 switch (filedata->file_header.e_machine)
994 {
995 case EM_MIPS:
996 if (ndx == SHN_MIPS_SCOMMON)
997 return "SCOMMON";
998 if (ndx == SHN_MIPS_SUNDEFINED)
999 return "SUNDEF";
1000 break;
1001
1002 case EM_TI_C6000:
1003 if (ndx == SHN_TIC6X_SCOMMON)
1004 return "SCOM";
1005 break;
1006
1007 case EM_X86_64:
1008 case EM_L1OM:
1009 case EM_K1OM:
1010 if (ndx == SHN_X86_64_LCOMMON)
1011 return "LARGE_COM";
1012 break;
1013
1014 case EM_IA_64:
1015 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
1016 && ndx == SHN_IA_64_ANSI_COMMON)
1017 return "ANSI_COM";
1018
1019 if (is_ia64_vms (filedata) && ndx == SHN_IA_64_VMS_SYMVEC)
1020 return "VMS_SYMVEC";
1021 break;
1022
1023 default:
1024 break;
1025 }
74e1a04b 1026
b6ac461a
NC
1027 if (filedata->section_headers != NULL
1028 && ndx < filedata->file_header.e_shnum)
1029 {
1030 const char * res;
1031
1032 res = printable_section_name (filedata, filedata->section_headers + ndx);
1033 if (is_special != NULL)
1034 * is_special = (res[0] == '<');
1035
1036 return res;
1037 }
1038 }
1039
1040 static char name_buf[40];
1041 unsigned int short_ndx = (unsigned int) (ndx & 0xffff);
1042
1043 if (ndx >= SHN_LOPROC && ndx <= SHN_HIPROC)
1044 sprintf (name_buf, "PRC[0x%04x]", short_ndx);
1045 else if (ndx >= SHN_LOOS && ndx <= SHN_HIOS)
1046 sprintf (name_buf, "OS [0x%04x]", short_ndx);
1047 else if (ndx >= SHN_LORESERVE)
1048 sprintf (name_buf, "RSV[0x%04x]", short_ndx);
1049 else if (filedata->file_header.e_shnum != 0
1050 && ndx >= filedata->file_header.e_shnum)
1051 sprintf (name_buf, _("BAD[0x%lx]"), (long) ndx);
1052 else
1053 sprintf (name_buf, "<section 0x%lx>", (long) ndx);
1054
1055 return name_buf;
74e1a04b
NC
1056}
1057
89fac5e3
RS
1058/* Return a pointer to section NAME, or NULL if no such section exists. */
1059
1060static Elf_Internal_Shdr *
dda8d76d 1061find_section (Filedata * filedata, const char * name)
89fac5e3
RS
1062{
1063 unsigned int i;
1064
68807c3c
NC
1065 if (filedata->section_headers == NULL)
1066 return NULL;
dda8d76d
NC
1067
1068 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
1069 if (section_name_valid (filedata, filedata->section_headers + i)
1070 && streq (section_name (filedata, filedata->section_headers + i),
1071 name))
dda8d76d 1072 return filedata->section_headers + i;
89fac5e3
RS
1073
1074 return NULL;
1075}
1076
0b6ae522
DJ
1077/* Return a pointer to a section containing ADDR, or NULL if no such
1078 section exists. */
1079
1080static Elf_Internal_Shdr *
625d49fc 1081find_section_by_address (Filedata * filedata, uint64_t addr)
0b6ae522
DJ
1082{
1083 unsigned int i;
1084
68807c3c
NC
1085 if (filedata->section_headers == NULL)
1086 return NULL;
1087
dda8d76d 1088 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 1089 {
dda8d76d
NC
1090 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1091
0b6ae522
DJ
1092 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
1093 return sec;
1094 }
1095
1096 return NULL;
1097}
1098
071436c6 1099static Elf_Internal_Shdr *
dda8d76d 1100find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
1101{
1102 unsigned int i;
1103
68807c3c
NC
1104 if (filedata->section_headers == NULL)
1105 return NULL;
1106
dda8d76d 1107 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 1108 {
dda8d76d
NC
1109 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1110
071436c6
NC
1111 if (sec->sh_type == type)
1112 return sec;
1113 }
1114
1115 return NULL;
1116}
1117
fcf8f323
NC
1118static Elf_Internal_Shdr *
1119find_section_by_name (Filedata * filedata, const char * name)
1120{
1121 unsigned int i;
1122
1123 if (filedata->section_headers == NULL || filedata->string_table_length == 0)
1124 return NULL;
1125
1126 for (i = 0; i < filedata->file_header.e_shnum; i++)
1127 {
1128 Elf_Internal_Shdr *sec = filedata->section_headers + i;
1129
1130 if (sec->sh_name < filedata->string_table_length
1131 && streq (name, filedata->string_table + sec->sh_name))
1132 return sec;
1133 }
1134
1135 return NULL;
1136}
1137
657d0d47
CC
1138/* Return a pointer to section NAME, or NULL if no such section exists,
1139 restricted to the list of sections given in SET. */
1140
1141static Elf_Internal_Shdr *
dda8d76d 1142find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
1143{
1144 unsigned int i;
1145
68807c3c
NC
1146 if (filedata->section_headers == NULL)
1147 return NULL;
1148
657d0d47
CC
1149 if (set != NULL)
1150 {
1151 while ((i = *set++) > 0)
b814a36d
NC
1152 {
1153 /* See PR 21156 for a reproducer. */
dda8d76d 1154 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1155 continue; /* FIXME: Should we issue an error message ? */
1156
84714f86
AM
1157 if (section_name_valid (filedata, filedata->section_headers + i)
1158 && streq (section_name (filedata, filedata->section_headers + i),
1159 name))
dda8d76d 1160 return filedata->section_headers + i;
b814a36d 1161 }
657d0d47
CC
1162 }
1163
dda8d76d 1164 return find_section (filedata, name);
657d0d47
CC
1165}
1166
bcedfee6 1167/* Guess the relocation size commonly used by the specific machines. */
252b5132 1168
015dc7e1 1169static bool
2dc4cec1 1170guess_is_rela (unsigned int e_machine)
252b5132 1171{
9c19a809 1172 switch (e_machine)
252b5132
RH
1173 {
1174 /* Targets that use REL relocations. */
252b5132 1175 case EM_386:
22abe556 1176 case EM_IAMCU:
f954747f 1177 case EM_960:
e9f53129 1178 case EM_ARM:
2b0337b0 1179 case EM_D10V:
252b5132 1180 case EM_CYGNUS_D10V:
e9f53129 1181 case EM_DLX:
252b5132 1182 case EM_MIPS:
4fe85591 1183 case EM_MIPS_RS3_LE:
e9f53129 1184 case EM_CYGNUS_M32R:
1c0d3aa6 1185 case EM_SCORE:
f6c1a2d5 1186 case EM_XGATE:
fe944acf 1187 case EM_NFP:
aca4efc7 1188 case EM_BPF:
015dc7e1 1189 return false;
103f02d3 1190
252b5132
RH
1191 /* Targets that use RELA relocations. */
1192 case EM_68K:
f954747f 1193 case EM_860:
a06ea964 1194 case EM_AARCH64:
cfb8c092 1195 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1196 case EM_ALPHA:
1197 case EM_ALTERA_NIOS2:
886a2506
NC
1198 case EM_ARC:
1199 case EM_ARC_COMPACT:
1200 case EM_ARC_COMPACT2:
b5c37946
SJ
1201 case EM_ARC_COMPACT3:
1202 case EM_ARC_COMPACT3_64:
e9f53129
AM
1203 case EM_AVR:
1204 case EM_AVR_OLD:
1205 case EM_BLACKFIN:
60bca95a 1206 case EM_CR16:
e9f53129
AM
1207 case EM_CRIS:
1208 case EM_CRX:
b8891f8d 1209 case EM_CSKY:
2b0337b0 1210 case EM_D30V:
252b5132 1211 case EM_CYGNUS_D30V:
2b0337b0 1212 case EM_FR30:
3f8107ab 1213 case EM_FT32:
252b5132 1214 case EM_CYGNUS_FR30:
5c70f934 1215 case EM_CYGNUS_FRV:
e9f53129
AM
1216 case EM_H8S:
1217 case EM_H8_300:
1218 case EM_H8_300H:
800eeca4 1219 case EM_IA_64:
1e4cf259
NC
1220 case EM_IP2K:
1221 case EM_IP2K_OLD:
3b36097d 1222 case EM_IQ2000:
6e712424 1223 case EM_KVX:
84e94c90 1224 case EM_LATTICEMICO32:
ff7eeb89 1225 case EM_M32C_OLD:
49f58d10 1226 case EM_M32C:
e9f53129
AM
1227 case EM_M32R:
1228 case EM_MCORE:
15ab5209 1229 case EM_CYGNUS_MEP:
a3c62988 1230 case EM_METAG:
e9f53129
AM
1231 case EM_MMIX:
1232 case EM_MN10200:
1233 case EM_CYGNUS_MN10200:
1234 case EM_MN10300:
1235 case EM_CYGNUS_MN10300:
5506d11a 1236 case EM_MOXIE:
e9f53129
AM
1237 case EM_MSP430:
1238 case EM_MSP430_OLD:
d031aafb 1239 case EM_MT:
35c08157 1240 case EM_NDS32:
64fd6348 1241 case EM_NIOS32:
73589c9d 1242 case EM_OR1K:
e9f53129
AM
1243 case EM_PPC64:
1244 case EM_PPC:
2b100bb5 1245 case EM_TI_PRU:
e23eba97 1246 case EM_RISCV:
99c513f6 1247 case EM_RL78:
c7927a3c 1248 case EM_RX:
e9f53129
AM
1249 case EM_S390:
1250 case EM_S390_OLD:
1251 case EM_SH:
1252 case EM_SPARC:
1253 case EM_SPARC32PLUS:
1254 case EM_SPARCV9:
1255 case EM_SPU:
40b36596 1256 case EM_TI_C6000:
aa137e4d
NC
1257 case EM_TILEGX:
1258 case EM_TILEPRO:
708e2187 1259 case EM_V800:
e9f53129
AM
1260 case EM_V850:
1261 case EM_CYGNUS_V850:
1262 case EM_VAX:
619ed720 1263 case EM_VISIUM:
e9f53129 1264 case EM_X86_64:
8a9036a4 1265 case EM_L1OM:
7a9068fe 1266 case EM_K1OM:
e9f53129
AM
1267 case EM_XSTORMY16:
1268 case EM_XTENSA:
1269 case EM_XTENSA_OLD:
7ba29e2a
NC
1270 case EM_MICROBLAZE:
1271 case EM_MICROBLAZE_OLD:
f96bd6c2 1272 case EM_WEBASSEMBLY:
015dc7e1 1273 return true;
103f02d3 1274
e9f53129
AM
1275 case EM_68HC05:
1276 case EM_68HC08:
1277 case EM_68HC11:
1278 case EM_68HC16:
1279 case EM_FX66:
1280 case EM_ME16:
d1133906 1281 case EM_MMA:
d1133906
NC
1282 case EM_NCPU:
1283 case EM_NDR1:
e9f53129 1284 case EM_PCP:
d1133906 1285 case EM_ST100:
e9f53129 1286 case EM_ST19:
d1133906 1287 case EM_ST7:
e9f53129
AM
1288 case EM_ST9PLUS:
1289 case EM_STARCORE:
d1133906 1290 case EM_SVX:
e9f53129 1291 case EM_TINYJ:
9c19a809
NC
1292 default:
1293 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1294 return false;
9c19a809
NC
1295 }
1296}
252b5132 1297
dda8d76d 1298/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1299 Returns TRUE upon success, FALSE otherwise. If successful then a
1300 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1301 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1302 responsibility to free the allocated buffer. */
1303
015dc7e1 1304static bool
26c527e6
AM
1305slurp_rela_relocs (Filedata *filedata,
1306 uint64_t rel_offset,
1307 uint64_t rel_size,
1308 Elf_Internal_Rela **relasp,
1309 uint64_t *nrelasp)
9c19a809 1310{
2cf0635d 1311 Elf_Internal_Rela * relas;
26c527e6 1312 uint64_t nrelas;
4d6ed7c8 1313 unsigned int i;
252b5132 1314
4d6ed7c8
NC
1315 if (is_32bit_elf)
1316 {
2cf0635d 1317 Elf32_External_Rela * erelas;
103f02d3 1318
dda8d76d 1319 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1320 rel_size, _("32-bit relocation data"));
a6e9f9df 1321 if (!erelas)
015dc7e1 1322 return false;
252b5132 1323
4d6ed7c8 1324 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1325
3f5e193b
NC
1326 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1327 sizeof (Elf_Internal_Rela));
103f02d3 1328
4d6ed7c8
NC
1329 if (relas == NULL)
1330 {
c256ffe7 1331 free (erelas);
591a748a 1332 error (_("out of memory parsing relocs\n"));
015dc7e1 1333 return false;
4d6ed7c8 1334 }
103f02d3 1335
4d6ed7c8
NC
1336 for (i = 0; i < nrelas; i++)
1337 {
1338 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1339 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1340 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1341 }
103f02d3 1342
4d6ed7c8
NC
1343 free (erelas);
1344 }
1345 else
1346 {
2cf0635d 1347 Elf64_External_Rela * erelas;
103f02d3 1348
dda8d76d 1349 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1350 rel_size, _("64-bit relocation data"));
a6e9f9df 1351 if (!erelas)
015dc7e1 1352 return false;
4d6ed7c8
NC
1353
1354 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1355
3f5e193b
NC
1356 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1357 sizeof (Elf_Internal_Rela));
103f02d3 1358
4d6ed7c8
NC
1359 if (relas == NULL)
1360 {
c256ffe7 1361 free (erelas);
591a748a 1362 error (_("out of memory parsing relocs\n"));
015dc7e1 1363 return false;
9c19a809 1364 }
4d6ed7c8
NC
1365
1366 for (i = 0; i < nrelas; i++)
9c19a809 1367 {
66543521
AM
1368 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1369 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1370 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a 1371
dda8d76d
NC
1372 if (filedata->file_header.e_machine == EM_MIPS
1373 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1374 {
1375 /* In little-endian objects, r_info isn't really a
1376 64-bit little-endian value: it has a 32-bit
1377 little-endian symbol index followed by four
1378 individual byte fields. Reorder INFO
1379 accordingly. */
625d49fc 1380 uint64_t inf = relas[i].r_info;
91d6fa6a
NC
1381 inf = (((inf & 0xffffffff) << 32)
1382 | ((inf >> 56) & 0xff)
1383 | ((inf >> 40) & 0xff00)
1384 | ((inf >> 24) & 0xff0000)
1385 | ((inf >> 8) & 0xff000000));
1386 relas[i].r_info = inf;
861fb55a 1387 }
4d6ed7c8 1388 }
103f02d3 1389
4d6ed7c8
NC
1390 free (erelas);
1391 }
32ec8896 1392
4d6ed7c8
NC
1393 *relasp = relas;
1394 *nrelasp = nrelas;
015dc7e1 1395 return true;
4d6ed7c8 1396}
103f02d3 1397
dda8d76d 1398/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1399 Returns TRUE upon success, FALSE otherwise. If successful then a
1400 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1401 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1402 responsibility to free the allocated buffer. */
1403
015dc7e1 1404static bool
26c527e6
AM
1405slurp_rel_relocs (Filedata *filedata,
1406 uint64_t rel_offset,
1407 uint64_t rel_size,
1408 Elf_Internal_Rela **relsp,
1409 uint64_t *nrelsp)
4d6ed7c8 1410{
2cf0635d 1411 Elf_Internal_Rela * rels;
26c527e6 1412 uint64_t nrels;
4d6ed7c8 1413 unsigned int i;
103f02d3 1414
4d6ed7c8
NC
1415 if (is_32bit_elf)
1416 {
2cf0635d 1417 Elf32_External_Rel * erels;
103f02d3 1418
dda8d76d 1419 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1420 rel_size, _("32-bit relocation data"));
a6e9f9df 1421 if (!erels)
015dc7e1 1422 return false;
103f02d3 1423
4d6ed7c8 1424 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1425
3f5e193b 1426 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1427
4d6ed7c8
NC
1428 if (rels == NULL)
1429 {
c256ffe7 1430 free (erels);
591a748a 1431 error (_("out of memory parsing relocs\n"));
015dc7e1 1432 return false;
4d6ed7c8
NC
1433 }
1434
1435 for (i = 0; i < nrels; i++)
1436 {
1437 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1438 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1439 rels[i].r_addend = 0;
9ea033b2 1440 }
4d6ed7c8
NC
1441
1442 free (erels);
9c19a809
NC
1443 }
1444 else
1445 {
2cf0635d 1446 Elf64_External_Rel * erels;
9ea033b2 1447
dda8d76d 1448 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1449 rel_size, _("64-bit relocation data"));
a6e9f9df 1450 if (!erels)
015dc7e1 1451 return false;
103f02d3 1452
4d6ed7c8 1453 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1454
3f5e193b 1455 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1456
4d6ed7c8 1457 if (rels == NULL)
9c19a809 1458 {
c256ffe7 1459 free (erels);
591a748a 1460 error (_("out of memory parsing relocs\n"));
015dc7e1 1461 return false;
4d6ed7c8 1462 }
103f02d3 1463
4d6ed7c8
NC
1464 for (i = 0; i < nrels; i++)
1465 {
66543521
AM
1466 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1467 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1468 rels[i].r_addend = 0;
861fb55a 1469
dda8d76d
NC
1470 if (filedata->file_header.e_machine == EM_MIPS
1471 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1472 {
1473 /* In little-endian objects, r_info isn't really a
1474 64-bit little-endian value: it has a 32-bit
1475 little-endian symbol index followed by four
1476 individual byte fields. Reorder INFO
1477 accordingly. */
625d49fc 1478 uint64_t inf = rels[i].r_info;
91d6fa6a
NC
1479 inf = (((inf & 0xffffffff) << 32)
1480 | ((inf >> 56) & 0xff)
1481 | ((inf >> 40) & 0xff00)
1482 | ((inf >> 24) & 0xff0000)
1483 | ((inf >> 8) & 0xff000000));
1484 rels[i].r_info = inf;
861fb55a 1485 }
4d6ed7c8 1486 }
103f02d3 1487
4d6ed7c8
NC
1488 free (erels);
1489 }
32ec8896 1490
4d6ed7c8
NC
1491 *relsp = rels;
1492 *nrelsp = nrels;
015dc7e1 1493 return true;
4d6ed7c8 1494}
103f02d3 1495
aca88567
NC
1496/* Returns the reloc type extracted from the reloc info field. */
1497
1498static unsigned int
625d49fc 1499get_reloc_type (Filedata * filedata, uint64_t reloc_info)
aca88567
NC
1500{
1501 if (is_32bit_elf)
1502 return ELF32_R_TYPE (reloc_info);
1503
dda8d76d 1504 switch (filedata->file_header.e_machine)
aca88567
NC
1505 {
1506 case EM_MIPS:
1507 /* Note: We assume that reloc_info has already been adjusted for us. */
1508 return ELF64_MIPS_R_TYPE (reloc_info);
1509
1510 case EM_SPARCV9:
1511 return ELF64_R_TYPE_ID (reloc_info);
1512
1513 default:
1514 return ELF64_R_TYPE (reloc_info);
1515 }
1516}
1517
1518/* Return the symbol index extracted from the reloc info field. */
1519
625d49fc
AM
1520static uint64_t
1521get_reloc_symindex (uint64_t reloc_info)
aca88567
NC
1522{
1523 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1524}
1525
015dc7e1 1526static inline bool
dda8d76d 1527uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1528{
1529 return
dda8d76d 1530 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1531 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1532 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1533 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1534 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1535}
1536
fcf8f323
NC
1537
1538static const char *
1539get_symbol_at (Elf_Internal_Sym * symtab,
1540 uint64_t nsyms,
1541 char * strtab,
1542 uint64_t strtablen,
1543 uint64_t where,
1544 uint64_t * offset_return)
1545{
1546 Elf_Internal_Sym * beg = symtab;
1547 Elf_Internal_Sym * end = symtab + nsyms;
1548 Elf_Internal_Sym * best = NULL;
1549 uint64_t dist = 0x100000;
1550
1551 /* FIXME: Since this function is likely to be called repeatedly with
1552 slightly increasing addresses each time, we could speed things up by
1553 caching the last returned value and starting our search from there. */
1554 while (beg < end)
1555 {
1556 Elf_Internal_Sym * sym;
1557 uint64_t value;
1558
1559 sym = beg + (end - beg) / 2;
1560
1561 value = sym->st_value;
1562
1563 if (sym->st_name != 0
1564 && where >= value
1565 && where - value < dist)
1566 {
1567 best = sym;
1568 dist = where - value;
1569 if (dist == 0)
1570 break;
1571 }
1572
1573 if (where < value)
1574 end = sym;
1575 else
1576 beg = sym + 1;
1577 }
1578
1579 if (best == NULL)
1580 return NULL;
1581
1582 if (best->st_name >= strtablen)
1583 return NULL;
1584
1585 if (offset_return != NULL)
1586 * offset_return = dist;
1587
1588 return strtab + best->st_name;
1589}
1590
1591static void
1592print_relr_addr_and_sym (Elf_Internal_Sym * symtab,
1593 uint64_t nsyms,
1594 char * strtab,
1595 uint64_t strtablen,
1596 uint64_t where)
1597{
1598 const char * symname = NULL;
1599 uint64_t offset = 0;
1600
1601 print_vma (where, ZERO_HEX);
1602 printf (" ");
1603
1604 symname = get_symbol_at (symtab, nsyms, strtab, strtablen, where, & offset);
1605
1606 if (symname == NULL)
1607 printf ("<no sym>");
1608 else if (offset == 0)
1609 print_symbol_name (38, symname);
1610 else
1611 {
1612 print_symbol_name (28, symname);
1613 printf (" + ");
1614 print_vma (offset, PREFIX_HEX);
1615 }
1616}
1617
1618static /* signed */ int
1619symcmp (const void *p, const void *q)
1620{
1621 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
1622 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
1623
1624 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
1625}
1626
1627static bool
1628dump_relr_relocations (Filedata * filedata,
1629 Elf_Internal_Shdr * section,
1630 Elf_Internal_Sym * symtab,
1631 uint64_t nsyms,
1632 char * strtab,
1633 uint64_t strtablen)
1634{
1635 uint64_t * relrs;
1636 uint64_t nentries, i;
1637 uint64_t relr_size = section->sh_size;
1638 int relr_entsize = section->sh_entsize;
1639 uint64_t relr_offset = section->sh_offset;
1640 uint64_t where = 0;
1641 int num_bits_in_entry;
1642
1643 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size, _("RELR relocation data"));
1644 if (relrs == NULL)
1645 return false;
1646
1647 if (relr_entsize == 0)
1648 relr_entsize = is_32bit_elf ? 4 : 8;
1649
1650 nentries = relr_size / relr_entsize;
1651
1652 if (relr_entsize == sizeof (Elf32_External_Relr))
1653 num_bits_in_entry = 31;
1654 else if (relr_entsize == sizeof (Elf64_External_Relr))
1655 num_bits_in_entry = 63;
1656 else
1657 {
1658 warn (_("Unexpected entsize for RELR section\n"));
1659 return false;
1660 }
1661
1662 /* Symbol tables are not sorted on address, but we want a quick lookup
1663 for the symbol associated with each address computed below, so sort
1664 the table now. FIXME: This assumes that the symbol table will not
1665 be used later on for some other purpose. */
1666 qsort (symtab, nsyms, sizeof (Elf_Internal_Sym), symcmp);
1667
21061c38
FS
1668 if (relr_entsize == 4)
1669 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323 1670 else
21061c38 1671 printf (_ ("Index: Entry Address Symbolic Address\n"));
fcf8f323
NC
1672
1673 for (i = 0; i < nentries; i++)
1674 {
1675 uint64_t entry;
1676
1677 if (relr_entsize == 4)
1678 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1679 else
1680 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1681
1682 /* We assume that there will never be more than 9999 entries. */
1683 printf (_("%04u: "), (unsigned int) i);
1684 print_vma (entry, ZERO_HEX);
1685 printf (" ");
1686
1687 if ((entry & 1) == 0)
1688 {
1689 where = entry;
1690 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, where);
fcf8f323
NC
1691 printf ("\n");
1692 where += relr_entsize;
1693 }
1694 else
1695 {
1696 bool first = true;
1697 int j;
1698
1699 /* The least significant bit is ignored. */
1700 if (entry == 1)
1701 warn (_("Malformed RELR bitmap - no significant bits are set\n"));
1702 else if (i == 0)
1703 warn (_("Unusual RELR bitmap - no previous entry to set the base address\n"));
1704
1705 for (j = 0; entry >>= 1; j++)
1706 if ((entry & 1) == 1)
1707 {
1708 uint64_t addr = where + (j * relr_entsize);
1709
1710 if (first)
1711 {
1712 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, addr);
fcf8f323
NC
1713 first = false;
1714 }
1715 else
1716 {
1717 printf (_("\n%*s "), relr_entsize == 4 ? 15 : 23, " ");
1718 print_relr_addr_and_sym (symtab, nsyms, strtab, strtablen, addr);
1719 }
1720 }
1721
1722 printf ("\n");
1723 where += num_bits_in_entry * relr_entsize;
1724 }
1725 }
1726
1727 free (relrs);
1728 return true;
1729}
1730
d3ba0551
AM
1731/* Display the contents of the relocation data found at the specified
1732 offset. */
ee42cf8c 1733
015dc7e1 1734static bool
fcf8f323
NC
1735dump_relocations (Filedata * filedata,
1736 uint64_t rel_offset,
1737 uint64_t rel_size,
1738 Elf_Internal_Sym * symtab,
1739 uint64_t nsyms,
1740 char * strtab,
1741 uint64_t strtablen,
1742 relocation_type rel_type,
1743 bool is_dynsym)
26c527e6
AM
1744{
1745 size_t i;
2cf0635d 1746 Elf_Internal_Rela * rels;
015dc7e1 1747 bool res = true;
103f02d3 1748
a7fd1186
FS
1749 if (rel_type == reltype_unknown)
1750 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1751
a7fd1186 1752 if (rel_type == reltype_rela)
4d6ed7c8 1753 {
dda8d76d 1754 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1755 return false;
4d6ed7c8 1756 }
a7fd1186 1757 else if (rel_type == reltype_rel)
4d6ed7c8 1758 {
dda8d76d 1759 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1760 return false;
252b5132 1761 }
a7fd1186
FS
1762 else if (rel_type == reltype_relr)
1763 {
fcf8f323
NC
1764 /* This should have been handled by display_relocations(). */
1765 return false;
a7fd1186 1766 }
252b5132 1767
410f7a12
L
1768 if (is_32bit_elf)
1769 {
a7fd1186 1770 if (rel_type == reltype_rela)
2c71103e
NC
1771 {
1772 if (do_wide)
1773 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1774 else
1775 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1776 }
410f7a12 1777 else
2c71103e
NC
1778 {
1779 if (do_wide)
1780 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1781 else
1782 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1783 }
410f7a12 1784 }
252b5132 1785 else
410f7a12 1786 {
a7fd1186 1787 if (rel_type == reltype_rela)
2c71103e
NC
1788 {
1789 if (do_wide)
8beeaeb7 1790 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1791 else
1792 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1793 }
410f7a12 1794 else
2c71103e
NC
1795 {
1796 if (do_wide)
8beeaeb7 1797 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1798 else
1799 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1800 }
410f7a12 1801 }
252b5132
RH
1802
1803 for (i = 0; i < rel_size; i++)
1804 {
2cf0635d 1805 const char * rtype;
625d49fc
AM
1806 uint64_t offset;
1807 uint64_t inf;
1808 uint64_t symtab_index;
1809 uint64_t type;
103f02d3 1810
b34976b6 1811 offset = rels[i].r_offset;
91d6fa6a 1812 inf = rels[i].r_info;
103f02d3 1813
dda8d76d 1814 type = get_reloc_type (filedata, inf);
91d6fa6a 1815 symtab_index = get_reloc_symindex (inf);
252b5132 1816
410f7a12
L
1817 if (is_32bit_elf)
1818 {
39dbeff8
AM
1819 printf ("%8.8lx %8.8lx ",
1820 (unsigned long) offset & 0xffffffff,
91d6fa6a 1821 (unsigned long) inf & 0xffffffff);
410f7a12
L
1822 }
1823 else
1824 {
39dbeff8 1825 printf (do_wide
b8281767
AM
1826 ? "%16.16" PRIx64 " %16.16" PRIx64 " "
1827 : "%12.12" PRIx64 " %12.12" PRIx64 " ",
625d49fc 1828 offset, inf);
410f7a12 1829 }
103f02d3 1830
dda8d76d 1831 switch (filedata->file_header.e_machine)
252b5132
RH
1832 {
1833 default:
1834 rtype = NULL;
1835 break;
1836
a06ea964
NC
1837 case EM_AARCH64:
1838 rtype = elf_aarch64_reloc_type (type);
1839 break;
1840
2b0337b0 1841 case EM_M32R:
252b5132 1842 case EM_CYGNUS_M32R:
9ea033b2 1843 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1844 break;
1845
1846 case EM_386:
22abe556 1847 case EM_IAMCU:
9ea033b2 1848 rtype = elf_i386_reloc_type (type);
252b5132
RH
1849 break;
1850
ba2685cc
AM
1851 case EM_68HC11:
1852 case EM_68HC12:
1853 rtype = elf_m68hc11_reloc_type (type);
1854 break;
75751cd9 1855
7b4ae824
JD
1856 case EM_S12Z:
1857 rtype = elf_s12z_reloc_type (type);
1858 break;
1859
252b5132 1860 case EM_68K:
9ea033b2 1861 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1862 break;
1863
f954747f
AM
1864 case EM_960:
1865 rtype = elf_i960_reloc_type (type);
1866 break;
1867
adde6300 1868 case EM_AVR:
2b0337b0 1869 case EM_AVR_OLD:
adde6300
AM
1870 rtype = elf_avr_reloc_type (type);
1871 break;
1872
9ea033b2
NC
1873 case EM_OLD_SPARCV9:
1874 case EM_SPARC32PLUS:
1875 case EM_SPARCV9:
252b5132 1876 case EM_SPARC:
9ea033b2 1877 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1878 break;
1879
e9f53129
AM
1880 case EM_SPU:
1881 rtype = elf_spu_reloc_type (type);
1882 break;
1883
708e2187
NC
1884 case EM_V800:
1885 rtype = v800_reloc_type (type);
1886 break;
2b0337b0 1887 case EM_V850:
252b5132 1888 case EM_CYGNUS_V850:
9ea033b2 1889 rtype = v850_reloc_type (type);
252b5132
RH
1890 break;
1891
2b0337b0 1892 case EM_D10V:
252b5132 1893 case EM_CYGNUS_D10V:
9ea033b2 1894 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1895 break;
1896
2b0337b0 1897 case EM_D30V:
252b5132 1898 case EM_CYGNUS_D30V:
9ea033b2 1899 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1900 break;
1901
d172d4ba
NC
1902 case EM_DLX:
1903 rtype = elf_dlx_reloc_type (type);
1904 break;
1905
252b5132 1906 case EM_SH:
9ea033b2 1907 rtype = elf_sh_reloc_type (type);
252b5132
RH
1908 break;
1909
2b0337b0 1910 case EM_MN10300:
252b5132 1911 case EM_CYGNUS_MN10300:
9ea033b2 1912 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1913 break;
1914
2b0337b0 1915 case EM_MN10200:
252b5132 1916 case EM_CYGNUS_MN10200:
9ea033b2 1917 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1918 break;
1919
2b0337b0 1920 case EM_FR30:
252b5132 1921 case EM_CYGNUS_FR30:
9ea033b2 1922 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1923 break;
1924
ba2685cc
AM
1925 case EM_CYGNUS_FRV:
1926 rtype = elf_frv_reloc_type (type);
1927 break;
5c70f934 1928
b8891f8d
AJ
1929 case EM_CSKY:
1930 rtype = elf_csky_reloc_type (type);
1931 break;
1932
3f8107ab
AM
1933 case EM_FT32:
1934 rtype = elf_ft32_reloc_type (type);
1935 break;
1936
252b5132 1937 case EM_MCORE:
9ea033b2 1938 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1939 break;
1940
3c3bdf30
NC
1941 case EM_MMIX:
1942 rtype = elf_mmix_reloc_type (type);
1943 break;
1944
5506d11a
AM
1945 case EM_MOXIE:
1946 rtype = elf_moxie_reloc_type (type);
1947 break;
1948
2469cfa2 1949 case EM_MSP430:
dda8d76d 1950 if (uses_msp430x_relocs (filedata))
13761a11
NC
1951 {
1952 rtype = elf_msp430x_reloc_type (type);
1953 break;
1954 }
1a0670f3 1955 /* Fall through. */
2469cfa2
NC
1956 case EM_MSP430_OLD:
1957 rtype = elf_msp430_reloc_type (type);
1958 break;
1959
35c08157
KLC
1960 case EM_NDS32:
1961 rtype = elf_nds32_reloc_type (type);
1962 break;
1963
252b5132 1964 case EM_PPC:
9ea033b2 1965 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1966 break;
1967
c833c019
AM
1968 case EM_PPC64:
1969 rtype = elf_ppc64_reloc_type (type);
1970 break;
1971
252b5132 1972 case EM_MIPS:
4fe85591 1973 case EM_MIPS_RS3_LE:
9ea033b2 1974 rtype = elf_mips_reloc_type (type);
252b5132
RH
1975 break;
1976
e23eba97
NC
1977 case EM_RISCV:
1978 rtype = elf_riscv_reloc_type (type);
1979 break;
1980
252b5132 1981 case EM_ALPHA:
9ea033b2 1982 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1983 break;
1984
1985 case EM_ARM:
9ea033b2 1986 rtype = elf_arm_reloc_type (type);
252b5132
RH
1987 break;
1988
584da044 1989 case EM_ARC:
886a2506
NC
1990 case EM_ARC_COMPACT:
1991 case EM_ARC_COMPACT2:
b5c37946
SJ
1992 case EM_ARC_COMPACT3:
1993 case EM_ARC_COMPACT3_64:
9ea033b2 1994 rtype = elf_arc_reloc_type (type);
252b5132
RH
1995 break;
1996
1997 case EM_PARISC:
69e617ca 1998 rtype = elf_hppa_reloc_type (type);
252b5132 1999 break;
7d466069 2000
b8720f9d
JL
2001 case EM_H8_300:
2002 case EM_H8_300H:
2003 case EM_H8S:
2004 rtype = elf_h8_reloc_type (type);
2005 break;
2006
73589c9d
CS
2007 case EM_OR1K:
2008 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
2009 break;
2010
7d466069 2011 case EM_PJ:
2b0337b0 2012 case EM_PJ_OLD:
7d466069
ILT
2013 rtype = elf_pj_reloc_type (type);
2014 break;
800eeca4
JW
2015 case EM_IA_64:
2016 rtype = elf_ia64_reloc_type (type);
2017 break;
1b61cf92 2018
6e712424
PI
2019 case EM_KVX:
2020 rtype = elf_kvx_reloc_type (type);
2021 break;
2022
1b61cf92
HPN
2023 case EM_CRIS:
2024 rtype = elf_cris_reloc_type (type);
2025 break;
535c37ff 2026
f954747f
AM
2027 case EM_860:
2028 rtype = elf_i860_reloc_type (type);
2029 break;
2030
bcedfee6 2031 case EM_X86_64:
8a9036a4 2032 case EM_L1OM:
7a9068fe 2033 case EM_K1OM:
bcedfee6
NC
2034 rtype = elf_x86_64_reloc_type (type);
2035 break;
a85d7ed0 2036
f954747f
AM
2037 case EM_S370:
2038 rtype = i370_reloc_type (type);
2039 break;
2040
53c7db4b
KH
2041 case EM_S390_OLD:
2042 case EM_S390:
2043 rtype = elf_s390_reloc_type (type);
2044 break;
93fbbb04 2045
1c0d3aa6
NC
2046 case EM_SCORE:
2047 rtype = elf_score_reloc_type (type);
2048 break;
2049
93fbbb04
GK
2050 case EM_XSTORMY16:
2051 rtype = elf_xstormy16_reloc_type (type);
2052 break;
179d3252 2053
1fe1f39c
NC
2054 case EM_CRX:
2055 rtype = elf_crx_reloc_type (type);
2056 break;
2057
179d3252
JT
2058 case EM_VAX:
2059 rtype = elf_vax_reloc_type (type);
2060 break;
1e4cf259 2061
619ed720
EB
2062 case EM_VISIUM:
2063 rtype = elf_visium_reloc_type (type);
2064 break;
2065
aca4efc7
JM
2066 case EM_BPF:
2067 rtype = elf_bpf_reloc_type (type);
2068 break;
2069
cfb8c092
NC
2070 case EM_ADAPTEVA_EPIPHANY:
2071 rtype = elf_epiphany_reloc_type (type);
2072 break;
2073
1e4cf259
NC
2074 case EM_IP2K:
2075 case EM_IP2K_OLD:
2076 rtype = elf_ip2k_reloc_type (type);
2077 break;
3b36097d
SC
2078
2079 case EM_IQ2000:
2080 rtype = elf_iq2000_reloc_type (type);
2081 break;
88da6820
NC
2082
2083 case EM_XTENSA_OLD:
2084 case EM_XTENSA:
2085 rtype = elf_xtensa_reloc_type (type);
2086 break;
a34e3ecb 2087
84e94c90
NC
2088 case EM_LATTICEMICO32:
2089 rtype = elf_lm32_reloc_type (type);
2090 break;
2091
ff7eeb89 2092 case EM_M32C_OLD:
49f58d10
JB
2093 case EM_M32C:
2094 rtype = elf_m32c_reloc_type (type);
2095 break;
2096
d031aafb
NS
2097 case EM_MT:
2098 rtype = elf_mt_reloc_type (type);
a34e3ecb 2099 break;
1d65ded4
CM
2100
2101 case EM_BLACKFIN:
2102 rtype = elf_bfin_reloc_type (type);
2103 break;
15ab5209
DB
2104
2105 case EM_CYGNUS_MEP:
2106 rtype = elf_mep_reloc_type (type);
2107 break;
60bca95a
NC
2108
2109 case EM_CR16:
2110 rtype = elf_cr16_reloc_type (type);
2111 break;
dd24e3da 2112
7ba29e2a
NC
2113 case EM_MICROBLAZE:
2114 case EM_MICROBLAZE_OLD:
2115 rtype = elf_microblaze_reloc_type (type);
2116 break;
c7927a3c 2117
99c513f6
DD
2118 case EM_RL78:
2119 rtype = elf_rl78_reloc_type (type);
2120 break;
2121
c7927a3c
NC
2122 case EM_RX:
2123 rtype = elf_rx_reloc_type (type);
2124 break;
c29aca4a 2125
a3c62988
NC
2126 case EM_METAG:
2127 rtype = elf_metag_reloc_type (type);
2128 break;
2129
40b36596
JM
2130 case EM_TI_C6000:
2131 rtype = elf_tic6x_reloc_type (type);
2132 break;
aa137e4d
NC
2133
2134 case EM_TILEGX:
2135 rtype = elf_tilegx_reloc_type (type);
2136 break;
2137
2138 case EM_TILEPRO:
2139 rtype = elf_tilepro_reloc_type (type);
2140 break;
f6c1a2d5 2141
f96bd6c2
PC
2142 case EM_WEBASSEMBLY:
2143 rtype = elf_wasm32_reloc_type (type);
2144 break;
2145
f6c1a2d5
NC
2146 case EM_XGATE:
2147 rtype = elf_xgate_reloc_type (type);
2148 break;
36591ba1
SL
2149
2150 case EM_ALTERA_NIOS2:
2151 rtype = elf_nios2_reloc_type (type);
2152 break;
2b100bb5
DD
2153
2154 case EM_TI_PRU:
2155 rtype = elf_pru_reloc_type (type);
2156 break;
fe944acf
FT
2157
2158 case EM_NFP:
2159 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
2160 rtype = elf_nfp3200_reloc_type (type);
2161 else
2162 rtype = elf_nfp_reloc_type (type);
2163 break;
6655dba2
SB
2164
2165 case EM_Z80:
2166 rtype = elf_z80_reloc_type (type);
2167 break;
e9a0721f 2168
2169 case EM_LOONGARCH:
2170 rtype = elf_loongarch_reloc_type (type);
2171 break;
2172
0c857ef4
SM
2173 case EM_AMDGPU:
2174 rtype = elf_amdgpu_reloc_type (type);
2175 break;
252b5132
RH
2176 }
2177
2178 if (rtype == NULL)
39dbeff8 2179 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 2180 else
5c144731 2181 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 2182
dda8d76d 2183 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 2184 && rtype != NULL
7ace3541 2185 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 2186 && rel_type == reltype_rela)
7ace3541
RH
2187 {
2188 switch (rels[i].r_addend)
2189 {
2190 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
2191 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
2192 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
2193 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
2194 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
2195 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
2196 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
2197 default: rtype = NULL;
2198 }
32ec8896 2199
7ace3541
RH
2200 if (rtype)
2201 printf (" (%s)", rtype);
2202 else
2203 {
2204 putchar (' ');
26c527e6
AM
2205 printf (_("<unknown addend: %" PRIx64 ">"),
2206 rels[i].r_addend);
015dc7e1 2207 res = false;
7ace3541
RH
2208 }
2209 }
2210 else if (symtab_index)
252b5132 2211 {
af3fc3bc 2212 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 2213 {
27a45f42
AS
2214 error (_(" bad symbol index: %08lx in reloc\n"),
2215 (unsigned long) symtab_index);
015dc7e1 2216 res = false;
32ec8896 2217 }
af3fc3bc 2218 else
19936277 2219 {
2cf0635d 2220 Elf_Internal_Sym * psym;
bb4d2ac2
L
2221 const char * version_string;
2222 enum versioned_symbol_info sym_info;
2223 unsigned short vna_other;
19936277 2224
af3fc3bc 2225 psym = symtab + symtab_index;
103f02d3 2226
bb4d2ac2 2227 version_string
dda8d76d 2228 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
2229 strtab, strtablen,
2230 symtab_index,
2231 psym,
2232 &sym_info,
2233 &vna_other);
2234
af3fc3bc 2235 printf (" ");
171191ba 2236
d8045f23
NC
2237 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
2238 {
2239 const char * name;
2240 unsigned int len;
2241 unsigned int width = is_32bit_elf ? 8 : 14;
2242
2243 /* Relocations against GNU_IFUNC symbols do not use the value
2244 of the symbol as the address to relocate against. Instead
2245 they invoke the function named by the symbol and use its
2246 result as the address for relocation.
2247
2248 To indicate this to the user, do not display the value of
2249 the symbol in the "Symbols's Value" field. Instead show
2250 its name followed by () as a hint that the symbol is
2251 invoked. */
2252
2253 if (strtab == NULL
2254 || psym->st_name == 0
2255 || psym->st_name >= strtablen)
2256 name = "??";
2257 else
2258 name = strtab + psym->st_name;
2259
b6ac461a 2260 len = print_symbol_name (width, name);
bb4d2ac2
L
2261 if (version_string)
2262 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2263 version_string);
d8045f23
NC
2264 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2265 }
2266 else
2267 {
2268 print_vma (psym->st_value, LONG_HEX);
171191ba 2269
d8045f23
NC
2270 printf (is_32bit_elf ? " " : " ");
2271 }
103f02d3 2272
af3fc3bc 2273 if (psym->st_name == 0)
f1ef08cb 2274 {
2cf0635d 2275 const char * sec_name = "<null>";
f1ef08cb
AM
2276
2277 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
b6ac461a
NC
2278 sec_name = printable_section_name_from_index
2279 (filedata, psym->st_shndx, NULL);
2280
2281 print_symbol_name (22, sec_name);
f1ef08cb 2282 }
af3fc3bc 2283 else if (strtab == NULL)
d79b3d50 2284 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2285 else if (psym->st_name >= strtablen)
32ec8896 2286 {
27a45f42
AS
2287 error (_("<corrupt string table index: %3ld>\n"),
2288 psym->st_name);
015dc7e1 2289 res = false;
32ec8896 2290 }
af3fc3bc 2291 else
bb4d2ac2 2292 {
b6ac461a 2293 print_symbol_name (22, strtab + psym->st_name);
bb4d2ac2
L
2294 if (version_string)
2295 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2296 version_string);
2297 }
103f02d3 2298
a7fd1186 2299 if (rel_type == reltype_rela)
171191ba 2300 {
625d49fc 2301 uint64_t off = rels[i].r_addend;
171191ba 2302
625d49fc
AM
2303 if ((int64_t) off < 0)
2304 printf (" - %" PRIx64, -off);
171191ba 2305 else
625d49fc 2306 printf (" + %" PRIx64, off);
171191ba 2307 }
19936277 2308 }
252b5132 2309 }
a7fd1186 2310 else if (rel_type == reltype_rela)
f7a99963 2311 {
625d49fc 2312 uint64_t off = rels[i].r_addend;
e04d7088
L
2313
2314 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
625d49fc
AM
2315 if ((int64_t) off < 0)
2316 printf ("-%" PRIx64, -off);
e04d7088 2317 else
625d49fc 2318 printf ("%" PRIx64, off);
f7a99963 2319 }
252b5132 2320
dda8d76d 2321 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2322 && rtype != NULL
2323 && streq (rtype, "R_SPARC_OLO10"))
26c527e6 2324 printf (" + %" PRIx64, ELF64_R_TYPE_DATA (inf));
351b4b40 2325
252b5132 2326 putchar ('\n');
2c71103e 2327
dda8d76d 2328 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2329 {
625d49fc
AM
2330 uint64_t type2 = ELF64_MIPS_R_TYPE2 (inf);
2331 uint64_t type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2332 const char * rtype2 = elf_mips_reloc_type (type2);
2333 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2334
2c71103e
NC
2335 printf (" Type2: ");
2336
2337 if (rtype2 == NULL)
39dbeff8
AM
2338 printf (_("unrecognized: %-7lx"),
2339 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2340 else
2341 printf ("%-17.17s", rtype2);
2342
18bd398b 2343 printf ("\n Type3: ");
2c71103e
NC
2344
2345 if (rtype3 == NULL)
39dbeff8
AM
2346 printf (_("unrecognized: %-7lx"),
2347 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2348 else
2349 printf ("%-17.17s", rtype3);
2350
53c7db4b 2351 putchar ('\n');
2c71103e 2352 }
252b5132
RH
2353 }
2354
c8286bd1 2355 free (rels);
32ec8896
NC
2356
2357 return res;
252b5132
RH
2358}
2359
37c18eed
SD
2360static const char *
2361get_aarch64_dynamic_type (unsigned long type)
2362{
2363 switch (type)
2364 {
2365 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2366 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2367 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2368 default:
2369 return NULL;
2370 }
2371}
2372
252b5132 2373static const char *
d3ba0551 2374get_mips_dynamic_type (unsigned long type)
252b5132
RH
2375{
2376 switch (type)
2377 {
2378 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2379 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2380 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2381 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2382 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2383 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2384 case DT_MIPS_MSYM: return "MIPS_MSYM";
2385 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2386 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2387 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2388 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2389 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2390 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2391 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2392 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2393 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2394 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2395 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2396 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2397 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2398 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2399 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2400 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2401 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2402 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2403 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2404 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2405 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2406 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2407 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2408 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2409 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2410 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2411 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2412 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2413 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2414 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2415 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2416 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2417 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2418 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2419 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2420 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2421 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2422 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2423 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2424 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2425 default:
2426 return NULL;
2427 }
2428}
2429
9a097730 2430static const char *
d3ba0551 2431get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2432{
2433 switch (type)
2434 {
2435 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2436 default:
2437 return NULL;
2438 }
103f02d3
UD
2439}
2440
7490d522
AM
2441static const char *
2442get_ppc_dynamic_type (unsigned long type)
2443{
2444 switch (type)
2445 {
a7f2871e 2446 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2447 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2448 default:
2449 return NULL;
2450 }
2451}
2452
f1cb7e17 2453static const char *
d3ba0551 2454get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2455{
2456 switch (type)
2457 {
a7f2871e
AM
2458 case DT_PPC64_GLINK: return "PPC64_GLINK";
2459 case DT_PPC64_OPD: return "PPC64_OPD";
2460 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2461 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2462 default:
2463 return NULL;
2464 }
2465}
2466
103f02d3 2467static const char *
d3ba0551 2468get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2469{
2470 switch (type)
2471 {
2472 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2473 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2474 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2475 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2476 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2477 case DT_HP_PREINIT: return "HP_PREINIT";
2478 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2479 case DT_HP_NEEDED: return "HP_NEEDED";
2480 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2481 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2482 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2483 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2484 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2485 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2486 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2487 case DT_HP_FILTERED: return "HP_FILTERED";
2488 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2489 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2490 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2491 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2492 case DT_PLT: return "PLT";
2493 case DT_PLT_SIZE: return "PLT_SIZE";
2494 case DT_DLT: return "DLT";
2495 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2496 default:
2497 return NULL;
2498 }
2499}
9a097730 2500
ecc51f48 2501static const char *
d3ba0551 2502get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2503{
2504 switch (type)
2505 {
148b93f2
NC
2506 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2507 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2508 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2509 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2510 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2511 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2512 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2513 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2514 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2515 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2516 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2517 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2518 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2519 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2520 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2521 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2522 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2523 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2524 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2525 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2526 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2527 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2528 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2529 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2530 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2531 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2532 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2533 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2534 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2535 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2536 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2537 default:
2538 return NULL;
2539 }
2540}
2541
fd85a6a1
NC
2542static const char *
2543get_solaris_section_type (unsigned long type)
2544{
2545 switch (type)
2546 {
2547 case 0x6fffffee: return "SUNW_ancillary";
2548 case 0x6fffffef: return "SUNW_capchain";
2549 case 0x6ffffff0: return "SUNW_capinfo";
2550 case 0x6ffffff1: return "SUNW_symsort";
2551 case 0x6ffffff2: return "SUNW_tlssort";
2552 case 0x6ffffff3: return "SUNW_LDYNSYM";
2553 case 0x6ffffff4: return "SUNW_dof";
2554 case 0x6ffffff5: return "SUNW_cap";
2555 case 0x6ffffff6: return "SUNW_SIGNATURE";
2556 case 0x6ffffff7: return "SUNW_ANNOTATE";
2557 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2558 case 0x6ffffff9: return "SUNW_DEBUG";
2559 case 0x6ffffffa: return "SUNW_move";
2560 case 0x6ffffffb: return "SUNW_COMDAT";
2561 case 0x6ffffffc: return "SUNW_syminfo";
2562 case 0x6ffffffd: return "SUNW_verdef";
2563 case 0x6ffffffe: return "SUNW_verneed";
2564 case 0x6fffffff: return "SUNW_versym";
2565 case 0x70000000: return "SPARC_GOTDATA";
2566 default: return NULL;
2567 }
2568}
2569
fabcb361
RH
2570static const char *
2571get_alpha_dynamic_type (unsigned long type)
2572{
2573 switch (type)
2574 {
2575 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2576 default: return NULL;
fabcb361
RH
2577 }
2578}
2579
1c0d3aa6
NC
2580static const char *
2581get_score_dynamic_type (unsigned long type)
2582{
2583 switch (type)
2584 {
2585 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2586 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2587 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2588 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2589 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2590 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2591 default: return NULL;
1c0d3aa6
NC
2592 }
2593}
2594
40b36596
JM
2595static const char *
2596get_tic6x_dynamic_type (unsigned long type)
2597{
2598 switch (type)
2599 {
2600 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2601 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2602 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2603 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2604 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2605 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2606 default: return NULL;
40b36596
JM
2607 }
2608}
1c0d3aa6 2609
36591ba1
SL
2610static const char *
2611get_nios2_dynamic_type (unsigned long type)
2612{
2613 switch (type)
2614 {
2615 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2616 default: return NULL;
36591ba1
SL
2617 }
2618}
2619
fd85a6a1
NC
2620static const char *
2621get_solaris_dynamic_type (unsigned long type)
2622{
2623 switch (type)
2624 {
2625 case 0x6000000d: return "SUNW_AUXILIARY";
2626 case 0x6000000e: return "SUNW_RTLDINF";
2627 case 0x6000000f: return "SUNW_FILTER";
2628 case 0x60000010: return "SUNW_CAP";
2629 case 0x60000011: return "SUNW_SYMTAB";
2630 case 0x60000012: return "SUNW_SYMSZ";
2631 case 0x60000013: return "SUNW_SORTENT";
2632 case 0x60000014: return "SUNW_SYMSORT";
2633 case 0x60000015: return "SUNW_SYMSORTSZ";
2634 case 0x60000016: return "SUNW_TLSSORT";
2635 case 0x60000017: return "SUNW_TLSSORTSZ";
2636 case 0x60000018: return "SUNW_CAPINFO";
2637 case 0x60000019: return "SUNW_STRPAD";
2638 case 0x6000001a: return "SUNW_CAPCHAIN";
2639 case 0x6000001b: return "SUNW_LDMACH";
2640 case 0x6000001d: return "SUNW_CAPCHAINENT";
2641 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2642 case 0x60000021: return "SUNW_PARENT";
2643 case 0x60000023: return "SUNW_ASLR";
2644 case 0x60000025: return "SUNW_RELAX";
2645 case 0x60000029: return "SUNW_NXHEAP";
2646 case 0x6000002b: return "SUNW_NXSTACK";
2647
2648 case 0x70000001: return "SPARC_REGISTER";
2649 case 0x7ffffffd: return "AUXILIARY";
2650 case 0x7ffffffe: return "USED";
2651 case 0x7fffffff: return "FILTER";
2652
15f205b1 2653 default: return NULL;
fd85a6a1
NC
2654 }
2655}
2656
8155b853
NC
2657static const char *
2658get_riscv_dynamic_type (unsigned long type)
2659{
2660 switch (type)
2661 {
2662 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2663 default:
2664 return NULL;
2665 }
2666}
2667
832ca732
L
2668static const char *
2669get_x86_64_dynamic_type (unsigned long type)
2670{
2671 switch (type)
2672 {
2673 case DT_X86_64_PLT:
2674 return "DT_X86_64_PLT";
2675 case DT_X86_64_PLTSZ:
2676 return "DT_X86_64_PLTSZ";
2677 case DT_X86_64_PLTENT:
2678 return "DT_X86_64_PLTENT";
2679 default:
2680 return NULL;
2681 }
2682}
2683
252b5132 2684static const char *
dda8d76d 2685get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2686{
e9e44622 2687 static char buff[64];
252b5132
RH
2688
2689 switch (type)
2690 {
2691 case DT_NULL: return "NULL";
2692 case DT_NEEDED: return "NEEDED";
2693 case DT_PLTRELSZ: return "PLTRELSZ";
2694 case DT_PLTGOT: return "PLTGOT";
2695 case DT_HASH: return "HASH";
2696 case DT_STRTAB: return "STRTAB";
2697 case DT_SYMTAB: return "SYMTAB";
2698 case DT_RELA: return "RELA";
2699 case DT_RELASZ: return "RELASZ";
2700 case DT_RELAENT: return "RELAENT";
2701 case DT_STRSZ: return "STRSZ";
2702 case DT_SYMENT: return "SYMENT";
2703 case DT_INIT: return "INIT";
2704 case DT_FINI: return "FINI";
2705 case DT_SONAME: return "SONAME";
2706 case DT_RPATH: return "RPATH";
2707 case DT_SYMBOLIC: return "SYMBOLIC";
2708 case DT_REL: return "REL";
2709 case DT_RELSZ: return "RELSZ";
2710 case DT_RELENT: return "RELENT";
dd207c13
FS
2711 case DT_RELR: return "RELR";
2712 case DT_RELRSZ: return "RELRSZ";
2713 case DT_RELRENT: return "RELRENT";
252b5132
RH
2714 case DT_PLTREL: return "PLTREL";
2715 case DT_DEBUG: return "DEBUG";
2716 case DT_TEXTREL: return "TEXTREL";
2717 case DT_JMPREL: return "JMPREL";
2718 case DT_BIND_NOW: return "BIND_NOW";
2719 case DT_INIT_ARRAY: return "INIT_ARRAY";
2720 case DT_FINI_ARRAY: return "FINI_ARRAY";
2721 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2722 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2723 case DT_RUNPATH: return "RUNPATH";
2724 case DT_FLAGS: return "FLAGS";
2d0e6f43 2725
d1133906
NC
2726 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2727 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2728 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2729
05107a46 2730 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2731 case DT_PLTPADSZ: return "PLTPADSZ";
2732 case DT_MOVEENT: return "MOVEENT";
2733 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2734 case DT_FEATURE: return "FEATURE";
252b5132
RH
2735 case DT_POSFLAG_1: return "POSFLAG_1";
2736 case DT_SYMINSZ: return "SYMINSZ";
2737 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2738
252b5132 2739 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2740 case DT_CONFIG: return "CONFIG";
2741 case DT_DEPAUDIT: return "DEPAUDIT";
2742 case DT_AUDIT: return "AUDIT";
2743 case DT_PLTPAD: return "PLTPAD";
2744 case DT_MOVETAB: return "MOVETAB";
252b5132 2745 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2746
252b5132 2747 case DT_VERSYM: return "VERSYM";
103f02d3 2748
67a4f2b7
AO
2749 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2750 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2751 case DT_RELACOUNT: return "RELACOUNT";
2752 case DT_RELCOUNT: return "RELCOUNT";
2753 case DT_FLAGS_1: return "FLAGS_1";
2754 case DT_VERDEF: return "VERDEF";
2755 case DT_VERDEFNUM: return "VERDEFNUM";
2756 case DT_VERNEED: return "VERNEED";
2757 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2758
019148e4 2759 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2760 case DT_USED: return "USED";
2761 case DT_FILTER: return "FILTER";
103f02d3 2762
047b2264
JJ
2763 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2764 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2765 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2766 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2767 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2768 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2769 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2770
252b5132
RH
2771 default:
2772 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2773 {
2cf0635d 2774 const char * result;
103f02d3 2775
dda8d76d 2776 switch (filedata->file_header.e_machine)
252b5132 2777 {
37c18eed
SD
2778 case EM_AARCH64:
2779 result = get_aarch64_dynamic_type (type);
2780 break;
252b5132 2781 case EM_MIPS:
4fe85591 2782 case EM_MIPS_RS3_LE:
252b5132
RH
2783 result = get_mips_dynamic_type (type);
2784 break;
9a097730
RH
2785 case EM_SPARCV9:
2786 result = get_sparc64_dynamic_type (type);
2787 break;
7490d522
AM
2788 case EM_PPC:
2789 result = get_ppc_dynamic_type (type);
2790 break;
f1cb7e17
AM
2791 case EM_PPC64:
2792 result = get_ppc64_dynamic_type (type);
2793 break;
ecc51f48
NC
2794 case EM_IA_64:
2795 result = get_ia64_dynamic_type (type);
2796 break;
fabcb361
RH
2797 case EM_ALPHA:
2798 result = get_alpha_dynamic_type (type);
2799 break;
1c0d3aa6
NC
2800 case EM_SCORE:
2801 result = get_score_dynamic_type (type);
2802 break;
40b36596
JM
2803 case EM_TI_C6000:
2804 result = get_tic6x_dynamic_type (type);
2805 break;
36591ba1
SL
2806 case EM_ALTERA_NIOS2:
2807 result = get_nios2_dynamic_type (type);
2808 break;
8155b853
NC
2809 case EM_RISCV:
2810 result = get_riscv_dynamic_type (type);
2811 break;
832ca732
L
2812 case EM_X86_64:
2813 result = get_x86_64_dynamic_type (type);
2814 break;
252b5132 2815 default:
dda8d76d 2816 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2817 result = get_solaris_dynamic_type (type);
2818 else
2819 result = NULL;
252b5132
RH
2820 break;
2821 }
2822
2823 if (result != NULL)
2824 return result;
2825
e9e44622 2826 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2827 }
eec8f817 2828 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2829 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2830 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2831 {
2cf0635d 2832 const char * result;
103f02d3 2833
dda8d76d 2834 switch (filedata->file_header.e_machine)
103f02d3
UD
2835 {
2836 case EM_PARISC:
2837 result = get_parisc_dynamic_type (type);
2838 break;
148b93f2
NC
2839 case EM_IA_64:
2840 result = get_ia64_dynamic_type (type);
2841 break;
103f02d3 2842 default:
dda8d76d 2843 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2844 result = get_solaris_dynamic_type (type);
2845 else
2846 result = NULL;
103f02d3
UD
2847 break;
2848 }
2849
2850 if (result != NULL)
2851 return result;
2852
e9e44622
JJ
2853 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2854 type);
103f02d3 2855 }
252b5132 2856 else
e9e44622 2857 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2858
252b5132
RH
2859 return buff;
2860 }
2861}
2862
93df3340
AM
2863static bool get_program_headers (Filedata *);
2864static bool get_dynamic_section (Filedata *);
2865
2866static void
2867locate_dynamic_section (Filedata *filedata)
2868{
26c527e6 2869 uint64_t dynamic_addr = 0;
be7d229a 2870 uint64_t dynamic_size = 0;
93df3340
AM
2871
2872 if (filedata->file_header.e_phnum != 0
2873 && get_program_headers (filedata))
2874 {
2875 Elf_Internal_Phdr *segment;
2876 unsigned int i;
2877
2878 for (i = 0, segment = filedata->program_headers;
2879 i < filedata->file_header.e_phnum;
2880 i++, segment++)
2881 {
2882 if (segment->p_type == PT_DYNAMIC)
2883 {
2884 dynamic_addr = segment->p_offset;
2885 dynamic_size = segment->p_filesz;
2886
2887 if (filedata->section_headers != NULL)
2888 {
2889 Elf_Internal_Shdr *sec;
2890
2891 sec = find_section (filedata, ".dynamic");
2892 if (sec != NULL)
2893 {
2894 if (sec->sh_size == 0
2895 || sec->sh_type == SHT_NOBITS)
2896 {
2897 dynamic_addr = 0;
2898 dynamic_size = 0;
2899 }
2900 else
2901 {
2902 dynamic_addr = sec->sh_offset;
2903 dynamic_size = sec->sh_size;
2904 }
2905 }
2906 }
2907
2908 if (dynamic_addr > filedata->file_size
2909 || (dynamic_size > filedata->file_size - dynamic_addr))
2910 {
2911 dynamic_addr = 0;
2912 dynamic_size = 0;
2913 }
2914 break;
2915 }
2916 }
2917 }
2918 filedata->dynamic_addr = dynamic_addr;
2919 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2920}
2921
2922static bool
2923is_pie (Filedata *filedata)
2924{
2925 Elf_Internal_Dyn *entry;
2926
2927 if (filedata->dynamic_size == 0)
2928 locate_dynamic_section (filedata);
2929 if (filedata->dynamic_size <= 1)
2930 return false;
2931
2932 if (!get_dynamic_section (filedata))
2933 return false;
2934
2935 for (entry = filedata->dynamic_section;
2936 entry < filedata->dynamic_section + filedata->dynamic_nent;
2937 entry++)
2938 {
2939 if (entry->d_tag == DT_FLAGS_1)
2940 {
2941 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2942 return true;
2943 break;
2944 }
2945 }
2946 return false;
2947}
2948
252b5132 2949static char *
93df3340 2950get_file_type (Filedata *filedata)
252b5132 2951{
93df3340 2952 unsigned e_type = filedata->file_header.e_type;
89246a0e 2953 static char buff[64];
252b5132
RH
2954
2955 switch (e_type)
2956 {
32ec8896
NC
2957 case ET_NONE: return _("NONE (None)");
2958 case ET_REL: return _("REL (Relocatable file)");
2959 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2960 case ET_DYN:
2961 if (is_pie (filedata))
2962 return _("DYN (Position-Independent Executable file)");
2963 else
2964 return _("DYN (Shared object file)");
32ec8896 2965 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2966
2967 default:
2968 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2969 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2970 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2971 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2972 else
e9e44622 2973 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2974 return buff;
2975 }
2976}
2977
2978static char *
d3ba0551 2979get_machine_name (unsigned e_machine)
252b5132 2980{
b34976b6 2981 static char buff[64]; /* XXX */
252b5132
RH
2982
2983 switch (e_machine)
2984 {
55e22ca8
NC
2985 /* Please keep this switch table sorted by increasing EM_ value. */
2986 /* 0 */
c45021f2
NC
2987 case EM_NONE: return _("None");
2988 case EM_M32: return "WE32100";
2989 case EM_SPARC: return "Sparc";
2990 case EM_386: return "Intel 80386";
2991 case EM_68K: return "MC68000";
2992 case EM_88K: return "MC88000";
22abe556 2993 case EM_IAMCU: return "Intel MCU";
fb70ec17 2994 case EM_860: return "Intel 80860";
c45021f2
NC
2995 case EM_MIPS: return "MIPS R3000";
2996 case EM_S370: return "IBM System/370";
55e22ca8 2997 /* 10 */
7036c0e1 2998 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2999 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 3000 case EM_PARISC: return "HPPA";
55e22ca8 3001 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 3002 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 3003 case EM_960: return "Intel 80960";
c45021f2 3004 case EM_PPC: return "PowerPC";
55e22ca8 3005 /* 20 */
285d1771 3006 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
3007 case EM_S390_OLD:
3008 case EM_S390: return "IBM S/390";
3009 case EM_SPU: return "SPU";
3010 /* 30 */
3011 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
3012 case EM_FR20: return "Fujitsu FR20";
3013 case EM_RH32: return "TRW RH32";
b34976b6 3014 case EM_MCORE: return "MCORE";
55e22ca8 3015 /* 40 */
7036c0e1
AJ
3016 case EM_ARM: return "ARM";
3017 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 3018 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
3019 case EM_SPARCV9: return "Sparc v9";
3020 case EM_TRICORE: return "Siemens Tricore";
584da044 3021 case EM_ARC: return "ARC";
c2dcd04e
NC
3022 case EM_H8_300: return "Renesas H8/300";
3023 case EM_H8_300H: return "Renesas H8/300H";
3024 case EM_H8S: return "Renesas H8S";
3025 case EM_H8_500: return "Renesas H8/500";
55e22ca8 3026 /* 50 */
30800947 3027 case EM_IA_64: return "Intel IA-64";
252b5132
RH
3028 case EM_MIPS_X: return "Stanford MIPS-X";
3029 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 3030 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
3031 case EM_MMA: return "Fujitsu Multimedia Accelerator";
3032 case EM_PCP: return "Siemens PCP";
3033 case EM_NCPU: return "Sony nCPU embedded RISC processor";
90de8f9c 3034 case EM_NDR1: return "Denso NDR1 microprocessor";
7036c0e1
AJ
3035 case EM_STARCORE: return "Motorola Star*Core processor";
3036 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 3037 /* 60 */
7036c0e1
AJ
3038 case EM_ST100: return "STMicroelectronics ST100 processor";
3039 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 3040 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
3041 case EM_PDSP: return "Sony DSP processor";
3042 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
3043 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
3044 case EM_FX66: return "Siemens FX66 microcontroller";
3045 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
3046 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
3047 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 3048 /* 70 */
7036c0e1
AJ
3049 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
3050 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
3051 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
3052 case EM_SVX: return "Silicon Graphics SVx";
3053 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
3054 case EM_VAX: return "Digital VAX";
1b61cf92 3055 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
3056 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
3057 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
3058 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 3059 /* 80 */
b34976b6 3060 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 3061 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 3062 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
3063 case EM_AVR_OLD:
3064 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
3065 case EM_CYGNUS_FR30:
3066 case EM_FR30: return "Fujitsu FR30";
3067 case EM_CYGNUS_D10V:
3068 case EM_D10V: return "d10v";
3069 case EM_CYGNUS_D30V:
3070 case EM_D30V: return "d30v";
3071 case EM_CYGNUS_V850:
3072 case EM_V850: return "Renesas V850";
3073 case EM_CYGNUS_M32R:
3074 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
3075 case EM_CYGNUS_MN10300:
3076 case EM_MN10300: return "mn10300";
3077 /* 90 */
3078 case EM_CYGNUS_MN10200:
3079 case EM_MN10200: return "mn10200";
3080 case EM_PJ: return "picoJava";
73589c9d 3081 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 3082 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
3083 case EM_XTENSA_OLD:
3084 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
3085 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
3086 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
3087 case EM_NS32K: return "National Semiconductor 32000 series";
3088 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
3089 case EM_SNP1K: return "Trebia SNP 1000 processor";
3090 /* 100 */
9abca702 3091 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
3092 case EM_IP2K_OLD:
3093 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
3094 case EM_MAX: return "MAX Processor";
3095 case EM_CR: return "National Semiconductor CompactRISC";
3096 case EM_F2MC16: return "Fujitsu F2MC16";
3097 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 3098 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
3099 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
3100 case EM_SEP: return "Sharp embedded microprocessor";
3101 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 3102 /* 110 */
11636f9e
JM
3103 case EM_UNICORE: return "Unicore";
3104 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
3105 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 3106 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
3107 case EM_CRX: return "National Semiconductor CRX microprocessor";
3108 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 3109 case EM_C166:
d70c5fc7 3110 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
3111 case EM_M16C: return "Renesas M16C series microprocessors";
3112 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
3113 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
3114 /* 120 */
3115 case EM_M32C: return "Renesas M32c";
3116 /* 130 */
11636f9e
JM
3117 case EM_TSK3000: return "Altium TSK3000 core";
3118 case EM_RS08: return "Freescale RS08 embedded processor";
3119 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 3120 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
3121 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
3122 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 3123 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 3124 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 3125 /* 140 */
11636f9e
JM
3126 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
3127 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
3128 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
3129 case EM_TI_PRU: return "TI PRU I/O processor";
3130 /* 160 */
11636f9e
JM
3131 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
3132 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
3133 case EM_R32C: return "Renesas R32C series microprocessors";
3134 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
3135 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
3136 case EM_8051: return "Intel 8051 and variants";
3137 case EM_STXP7X: return "STMicroelectronics STxP7x family";
3138 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
3139 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
3140 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 3141 /* 170 */
11636f9e
JM
3142 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
3143 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
3144 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 3145 case EM_RX: return "Renesas RX";
a3c62988 3146 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
3147 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
3148 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
3149 case EM_CR16:
3150 case EM_MICROBLAZE:
3151 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
3152 case EM_ETPU: return "Freescale Extended Time Processing Unit";
3153 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
3154 /* 180 */
3155 case EM_L1OM: return "Intel L1OM";
3156 case EM_K1OM: return "Intel K1OM";
3157 case EM_INTEL182: return "Intel (reserved)";
3158 case EM_AARCH64: return "AArch64";
3159 case EM_ARM184: return "ARM (reserved)";
3160 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
3161 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
3162 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
3163 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 3164 /* 190 */
11636f9e 3165 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 3166 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
3167 case EM_CLOUDSHIELD: return "CloudShield architecture family";
3168 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
3169 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 3170 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 3171 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 3172 case EM_RL78: return "Renesas RL78";
6d913794 3173 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
3174 case EM_78K0R: return "Renesas 78K0R";
3175 /* 200 */
6d913794 3176 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
3177 case EM_BA1: return "Beyond BA1 CPU architecture";
3178 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
3179 case EM_XCORE: return "XMOS xCORE processor family";
3180 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 3181 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 3182 /* 210 */
6d913794
NC
3183 case EM_KM32: return "KM211 KM32 32-bit processor";
3184 case EM_KMX32: return "KM211 KMX32 32-bit processor";
3185 case EM_KMX16: return "KM211 KMX16 16-bit processor";
3186 case EM_KMX8: return "KM211 KMX8 8-bit processor";
3187 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 3188 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
3189 case EM_COGE: return "Cognitive Smart Memory Processor";
3190 case EM_COOL: return "Bluechip Systems CoolEngine";
3191 case EM_NORC: return "Nanoradio Optimized RISC";
3192 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 3193 /* 220 */
15f205b1 3194 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
3195 case EM_VISIUM: return "CDS VISIUMcore processor";
3196 case EM_FT32: return "FTDI Chip FT32";
3197 case EM_MOXIE: return "Moxie";
3198 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
3199 /* 230 (all reserved) */
3200 /* 240 */
55e22ca8
NC
3201 case EM_RISCV: return "RISC-V";
3202 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
3203 case EM_CEVA: return "CEVA Processor Architecture Family";
3204 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 3205 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
3206 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
3207 case EM_IMG1: return "Imagination Technologies";
3208 /* 250 */
fe944acf 3209 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
3210 case EM_VE: return "NEC Vector Engine";
3211 case EM_CSKY: return "C-SKY";
b5c37946 3212 case EM_ARC_COMPACT3_64: return "Synopsys ARCv3 64-bit processor";
4cf2ad72 3213 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
b5c37946 3214 case EM_ARC_COMPACT3: return "Synopsys ARCv3 32-bit processor";
4cf2ad72
CC
3215 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
3216 case EM_65816: return "WDC 65816/65C816";
01a8c731 3217 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 3218 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
3219
3220 /* Large numbers... */
3221 case EM_MT: return "Morpho Techologies MT processor";
3222 case EM_ALPHA: return "Alpha";
3223 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 3224 case EM_DLX: return "OpenDLX";
55e22ca8
NC
3225 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
3226 case EM_IQ2000: return "Vitesse IQ2000";
3227 case EM_M32C_OLD:
3228 case EM_NIOS32: return "Altera Nios";
3229 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3230 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3231 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3232 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3233
252b5132 3234 default:
35d9dd2f 3235 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3236 return buff;
3237 }
3238}
3239
f8c4789c
AM
3240static char *
3241decode_ARC_machine_flags (char *out, unsigned e_flags, unsigned e_machine)
a9522a21
AB
3242{
3243 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3244 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3245 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3246 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3247 architectures.
3248
3249 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3250 but also sets a specific architecture type in the e_flags field.
3251
3252 However, when decoding the flags we don't worry if we see an
3253 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3254 ARCEM architecture type. */
3255
3256 switch (e_flags & EF_ARC_MACH_MSK)
3257 {
3258 /* We only expect these to occur for EM_ARC_COMPACT2. */
3259 case EF_ARC_CPU_ARCV2EM:
f8c4789c 3260 out = stpcpy (out, ", ARC EM");
a9522a21
AB
3261 break;
3262 case EF_ARC_CPU_ARCV2HS:
f8c4789c 3263 out = stpcpy (out, ", ARC HS");
a9522a21
AB
3264 break;
3265
3266 /* We only expect these to occur for EM_ARC_COMPACT. */
3267 case E_ARC_MACH_ARC600:
f8c4789c 3268 out = stpcpy (out, ", ARC600");
a9522a21
AB
3269 break;
3270 case E_ARC_MACH_ARC601:
f8c4789c 3271 out = stpcpy (out, ", ARC601");
a9522a21
AB
3272 break;
3273 case E_ARC_MACH_ARC700:
f8c4789c 3274 out = stpcpy (out, ", ARC700");
a9522a21
AB
3275 break;
3276
3277 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3278 new ELF with new architecture being read by an old version of
3279 readelf, or (c) An ELF built with non-GNU compiler that does not
3280 set the architecture in the e_flags. */
3281 default:
3282 if (e_machine == EM_ARC_COMPACT)
f8c4789c 3283 out = stpcpy (out, ", Unknown ARCompact");
a9522a21 3284 else
f8c4789c 3285 out = stpcpy (out, ", Unknown ARC");
a9522a21
AB
3286 break;
3287 }
3288
3289 switch (e_flags & EF_ARC_OSABI_MSK)
3290 {
3291 case E_ARC_OSABI_ORIG:
f8c4789c 3292 out = stpcpy (out, ", (ABI:legacy)");
a9522a21
AB
3293 break;
3294 case E_ARC_OSABI_V2:
f8c4789c 3295 out = stpcpy (out, ", (ABI:v2)");
a9522a21
AB
3296 break;
3297 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3298 case E_ARC_OSABI_V3:
f8c4789c 3299 out = stpcpy (out, ", v3 no-legacy-syscalls ABI");
a9522a21 3300 break;
53a346d8 3301 case E_ARC_OSABI_V4:
f8c4789c 3302 out = stpcpy (out, ", v4 ABI");
53a346d8 3303 break;
a9522a21 3304 default:
f8c4789c 3305 out = stpcpy (out, ", unrecognised ARC OSABI flag");
a9522a21
AB
3306 break;
3307 }
f8c4789c 3308 return out;
a9522a21
AB
3309}
3310
f8c4789c
AM
3311static char *
3312decode_ARM_machine_flags (char *out, unsigned e_flags)
f3485b74
NC
3313{
3314 unsigned eabi;
015dc7e1 3315 bool unknown = false;
f3485b74
NC
3316
3317 eabi = EF_ARM_EABI_VERSION (e_flags);
3318 e_flags &= ~ EF_ARM_EABIMASK;
3319
3320 /* Handle "generic" ARM flags. */
3321 if (e_flags & EF_ARM_RELEXEC)
3322 {
f8c4789c 3323 out = stpcpy (out, ", relocatable executable");
f3485b74
NC
3324 e_flags &= ~ EF_ARM_RELEXEC;
3325 }
76da6bbe 3326
18a20338
CL
3327 if (e_flags & EF_ARM_PIC)
3328 {
f8c4789c 3329 out = stpcpy (out, ", position independent");
18a20338
CL
3330 e_flags &= ~ EF_ARM_PIC;
3331 }
3332
f3485b74
NC
3333 /* Now handle EABI specific flags. */
3334 switch (eabi)
3335 {
3336 default:
f8c4789c 3337 out = stpcpy (out, ", <unrecognized EABI>");
f3485b74 3338 if (e_flags)
015dc7e1 3339 unknown = true;
f3485b74
NC
3340 break;
3341
3342 case EF_ARM_EABI_VER1:
f8c4789c 3343 out = stpcpy (out, ", Version1 EABI");
f3485b74
NC
3344 while (e_flags)
3345 {
3346 unsigned flag;
76da6bbe 3347
f3485b74
NC
3348 /* Process flags one bit at a time. */
3349 flag = e_flags & - e_flags;
3350 e_flags &= ~ flag;
76da6bbe 3351
f3485b74
NC
3352 switch (flag)
3353 {
a5bcd848 3354 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3355 out = stpcpy (out, ", sorted symbol tables");
f3485b74 3356 break;
76da6bbe 3357
f3485b74 3358 default:
015dc7e1 3359 unknown = true;
f3485b74
NC
3360 break;
3361 }
3362 }
3363 break;
76da6bbe 3364
a5bcd848 3365 case EF_ARM_EABI_VER2:
f8c4789c 3366 out = stpcpy (out, ", Version2 EABI");
a5bcd848
PB
3367 while (e_flags)
3368 {
3369 unsigned flag;
3370
3371 /* Process flags one bit at a time. */
3372 flag = e_flags & - e_flags;
3373 e_flags &= ~ flag;
3374
3375 switch (flag)
3376 {
3377 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f8c4789c 3378 out = stpcpy (out, ", sorted symbol tables");
a5bcd848
PB
3379 break;
3380
3381 case EF_ARM_DYNSYMSUSESEGIDX:
f8c4789c 3382 out = stpcpy (out, ", dynamic symbols use segment index");
a5bcd848
PB
3383 break;
3384
3385 case EF_ARM_MAPSYMSFIRST:
f8c4789c 3386 out = stpcpy (out, ", mapping symbols precede others");
a5bcd848
PB
3387 break;
3388
3389 default:
015dc7e1 3390 unknown = true;
a5bcd848
PB
3391 break;
3392 }
3393 }
3394 break;
3395
d507cf36 3396 case EF_ARM_EABI_VER3:
f8c4789c 3397 out = stpcpy (out, ", Version3 EABI");
8cb51566
PB
3398 break;
3399
3400 case EF_ARM_EABI_VER4:
f8c4789c 3401 out = stpcpy (out, ", Version4 EABI");
3bfcb652
NC
3402 while (e_flags)
3403 {
3404 unsigned flag;
3405
3406 /* Process flags one bit at a time. */
3407 flag = e_flags & - e_flags;
3408 e_flags &= ~ flag;
3409
3410 switch (flag)
3411 {
3412 case EF_ARM_BE8:
f8c4789c 3413 out = stpcpy (out, ", BE8");
3bfcb652
NC
3414 break;
3415
3416 case EF_ARM_LE8:
f8c4789c 3417 out = stpcpy (out, ", LE8");
3bfcb652
NC
3418 break;
3419
3420 default:
015dc7e1 3421 unknown = true;
3bfcb652
NC
3422 break;
3423 }
3bfcb652
NC
3424 }
3425 break;
3a4a14e9
PB
3426
3427 case EF_ARM_EABI_VER5:
f8c4789c 3428 out = stpcpy (out, ", Version5 EABI");
d507cf36
PB
3429 while (e_flags)
3430 {
3431 unsigned flag;
3432
3433 /* Process flags one bit at a time. */
3434 flag = e_flags & - e_flags;
3435 e_flags &= ~ flag;
3436
3437 switch (flag)
3438 {
3439 case EF_ARM_BE8:
f8c4789c 3440 out = stpcpy (out, ", BE8");
d507cf36
PB
3441 break;
3442
3443 case EF_ARM_LE8:
f8c4789c 3444 out = stpcpy (out, ", LE8");
d507cf36
PB
3445 break;
3446
3bfcb652 3447 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
f8c4789c 3448 out = stpcpy (out, ", soft-float ABI");
3bfcb652
NC
3449 break;
3450
3451 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
f8c4789c 3452 out = stpcpy (out, ", hard-float ABI");
3bfcb652
NC
3453 break;
3454
d507cf36 3455 default:
015dc7e1 3456 unknown = true;
d507cf36
PB
3457 break;
3458 }
3459 }
3460 break;
3461
f3485b74 3462 case EF_ARM_EABI_UNKNOWN:
f8c4789c 3463 out = stpcpy (out, ", GNU EABI");
f3485b74
NC
3464 while (e_flags)
3465 {
3466 unsigned flag;
76da6bbe 3467
f3485b74
NC
3468 /* Process flags one bit at a time. */
3469 flag = e_flags & - e_flags;
3470 e_flags &= ~ flag;
76da6bbe 3471
f3485b74
NC
3472 switch (flag)
3473 {
a5bcd848 3474 case EF_ARM_INTERWORK:
f8c4789c 3475 out = stpcpy (out, ", interworking enabled");
f3485b74 3476 break;
76da6bbe 3477
a5bcd848 3478 case EF_ARM_APCS_26:
f8c4789c 3479 out = stpcpy (out, ", uses APCS/26");
f3485b74 3480 break;
76da6bbe 3481
a5bcd848 3482 case EF_ARM_APCS_FLOAT:
f8c4789c 3483 out = stpcpy (out, ", uses APCS/float");
f3485b74 3484 break;
76da6bbe 3485
a5bcd848 3486 case EF_ARM_PIC:
f8c4789c 3487 out = stpcpy (out, ", position independent");
f3485b74 3488 break;
76da6bbe 3489
a5bcd848 3490 case EF_ARM_ALIGN8:
f8c4789c 3491 out = stpcpy (out, ", 8 bit structure alignment");
f3485b74 3492 break;
76da6bbe 3493
a5bcd848 3494 case EF_ARM_NEW_ABI:
f8c4789c 3495 out = stpcpy (out, ", uses new ABI");
f3485b74 3496 break;
76da6bbe 3497
a5bcd848 3498 case EF_ARM_OLD_ABI:
f8c4789c 3499 out = stpcpy (out, ", uses old ABI");
f3485b74 3500 break;
76da6bbe 3501
a5bcd848 3502 case EF_ARM_SOFT_FLOAT:
f8c4789c 3503 out = stpcpy (out, ", software FP");
f3485b74 3504 break;
76da6bbe 3505
90e01f86 3506 case EF_ARM_VFP_FLOAT:
f8c4789c 3507 out = stpcpy (out, ", VFP");
90e01f86
ILT
3508 break;
3509
fde78edd 3510 case EF_ARM_MAVERICK_FLOAT:
f8c4789c 3511 out = stpcpy (out, ", Maverick FP");
fde78edd
NC
3512 break;
3513
f3485b74 3514 default:
015dc7e1 3515 unknown = true;
f3485b74
NC
3516 break;
3517 }
3518 }
3519 }
f3485b74
NC
3520
3521 if (unknown)
f8c4789c
AM
3522 out = stpcpy (out,_(", <unknown>"));
3523 return out;
f3485b74
NC
3524}
3525
f8c4789c
AM
3526static char *
3527decode_AVR_machine_flags (char *out, unsigned e_flags)
343433df 3528{
343433df
AB
3529 switch (e_flags & EF_AVR_MACH)
3530 {
3531 case E_AVR_MACH_AVR1:
f8c4789c 3532 out = stpcpy (out, ", avr:1");
343433df
AB
3533 break;
3534 case E_AVR_MACH_AVR2:
f8c4789c 3535 out = stpcpy (out, ", avr:2");
343433df
AB
3536 break;
3537 case E_AVR_MACH_AVR25:
f8c4789c 3538 out = stpcpy (out, ", avr:25");
343433df
AB
3539 break;
3540 case E_AVR_MACH_AVR3:
f8c4789c 3541 out = stpcpy (out, ", avr:3");
343433df
AB
3542 break;
3543 case E_AVR_MACH_AVR31:
f8c4789c 3544 out = stpcpy (out, ", avr:31");
343433df
AB
3545 break;
3546 case E_AVR_MACH_AVR35:
f8c4789c 3547 out = stpcpy (out, ", avr:35");
343433df
AB
3548 break;
3549 case E_AVR_MACH_AVR4:
f8c4789c 3550 out = stpcpy (out, ", avr:4");
343433df
AB
3551 break;
3552 case E_AVR_MACH_AVR5:
f8c4789c 3553 out = stpcpy (out, ", avr:5");
343433df
AB
3554 break;
3555 case E_AVR_MACH_AVR51:
f8c4789c 3556 out = stpcpy (out, ", avr:51");
343433df
AB
3557 break;
3558 case E_AVR_MACH_AVR6:
f8c4789c 3559 out = stpcpy (out, ", avr:6");
343433df
AB
3560 break;
3561 case E_AVR_MACH_AVRTINY:
f8c4789c 3562 out = stpcpy (out, ", avr:100");
343433df
AB
3563 break;
3564 case E_AVR_MACH_XMEGA1:
f8c4789c 3565 out = stpcpy (out, ", avr:101");
343433df
AB
3566 break;
3567 case E_AVR_MACH_XMEGA2:
f8c4789c 3568 out = stpcpy (out, ", avr:102");
343433df
AB
3569 break;
3570 case E_AVR_MACH_XMEGA3:
f8c4789c 3571 out = stpcpy (out, ", avr:103");
343433df
AB
3572 break;
3573 case E_AVR_MACH_XMEGA4:
f8c4789c 3574 out = stpcpy (out, ", avr:104");
343433df
AB
3575 break;
3576 case E_AVR_MACH_XMEGA5:
f8c4789c 3577 out = stpcpy (out, ", avr:105");
343433df
AB
3578 break;
3579 case E_AVR_MACH_XMEGA6:
f8c4789c 3580 out = stpcpy (out, ", avr:106");
343433df
AB
3581 break;
3582 case E_AVR_MACH_XMEGA7:
f8c4789c 3583 out = stpcpy (out, ", avr:107");
343433df
AB
3584 break;
3585 default:
f8c4789c 3586 out = stpcpy (out, ", avr:<unknown>");
343433df
AB
3587 break;
3588 }
3589
343433df 3590 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
f8c4789c
AM
3591 out = stpcpy (out, ", link-relax");
3592 return out;
343433df
AB
3593}
3594
f8c4789c
AM
3595static char *
3596decode_BLACKFIN_machine_flags (char *out, unsigned e_flags)
3597{
3598 if (e_flags & EF_BFIN_PIC)
3599 out = stpcpy (out, ", PIC");
3600
3601 if (e_flags & EF_BFIN_FDPIC)
3602 out = stpcpy (out, ", FDPIC");
3603
3604 if (e_flags & EF_BFIN_CODE_IN_L1)
3605 out = stpcpy (out, ", code in L1");
3606
3607 if (e_flags & EF_BFIN_DATA_IN_L1)
3608 out = stpcpy (out, ", data in L1");
3609 return out;
3610}
3611
3612static char *
3613decode_FRV_machine_flags (char *out, unsigned e_flags)
3614{
3615 switch (e_flags & EF_FRV_CPU_MASK)
3616 {
3617 case EF_FRV_CPU_GENERIC:
3618 break;
3619
3620 default:
3621 out = stpcpy (out, ", fr???");
3622 break;
3623
3624 case EF_FRV_CPU_FR300:
3625 out = stpcpy (out, ", fr300");
3626 break;
3627
3628 case EF_FRV_CPU_FR400:
3629 out = stpcpy (out, ", fr400");
3630 break;
3631 case EF_FRV_CPU_FR405:
3632 out = stpcpy (out, ", fr405");
3633 break;
3634
3635 case EF_FRV_CPU_FR450:
3636 out = stpcpy (out, ", fr450");
3637 break;
3638
3639 case EF_FRV_CPU_FR500:
3640 out = stpcpy (out, ", fr500");
3641 break;
3642 case EF_FRV_CPU_FR550:
3643 out = stpcpy (out, ", fr550");
3644 break;
3645
3646 case EF_FRV_CPU_SIMPLE:
3647 out = stpcpy (out, ", simple");
3648 break;
3649 case EF_FRV_CPU_TOMCAT:
3650 out = stpcpy (out, ", tomcat");
3651 break;
3652 }
3653 return out;
3654}
3655
3656static char *
3657decode_IA64_machine_flags (char *out, unsigned e_flags, Filedata *filedata)
3658{
3659 if ((e_flags & EF_IA_64_ABI64))
3660 out = stpcpy (out, ", 64-bit");
3661 else
3662 out = stpcpy (out, ", 32-bit");
3663 if ((e_flags & EF_IA_64_REDUCEDFP))
3664 out = stpcpy (out, ", reduced fp model");
3665 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3666 out = stpcpy (out, ", no function descriptors, constant gp");
3667 else if ((e_flags & EF_IA_64_CONS_GP))
3668 out = stpcpy (out, ", constant gp");
3669 if ((e_flags & EF_IA_64_ABSOLUTE))
3670 out = stpcpy (out, ", absolute");
3671 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
3672 {
3673 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3674 out = stpcpy (out, ", vms_linkages");
3675 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3676 {
3677 case EF_IA_64_VMS_COMCOD_SUCCESS:
3678 break;
3679 case EF_IA_64_VMS_COMCOD_WARNING:
3680 out = stpcpy (out, ", warning");
3681 break;
3682 case EF_IA_64_VMS_COMCOD_ERROR:
3683 out = stpcpy (out, ", error");
3684 break;
3685 case EF_IA_64_VMS_COMCOD_ABORT:
3686 out = stpcpy (out, ", abort");
3687 break;
3688 default:
3689 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3690 e_flags & EF_IA_64_VMS_COMCOD);
3691 out = stpcpy (out, ", <unknown>");
3692 }
3693 }
3694 return out;
3695}
3696
3697static char *
3698decode_LOONGARCH_machine_flags (char *out, unsigned int e_flags)
3699{
3700 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3701 out = stpcpy (out, ", SOFT-FLOAT");
3702 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3703 out = stpcpy (out, ", SINGLE-FLOAT");
3704 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3705 out = stpcpy (out, ", DOUBLE-FLOAT");
3706
3707 if (EF_LOONGARCH_IS_OBJ_V0 (e_flags))
3708 out = stpcpy (out, ", OBJ-v0");
3709 else if (EF_LOONGARCH_IS_OBJ_V1 (e_flags))
3710 out = stpcpy (out, ", OBJ-v1");
3711 return out;
3712}
3713
3714static char *
3715decode_M68K_machine_flags (char *out, unsigned int e_flags)
3716{
3717 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
3718 out = stpcpy (out, ", m68000");
3719 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3720 out = stpcpy (out, ", cpu32");
3721 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3722 out = stpcpy (out, ", fido_a");
3723 else
3724 {
3725 char const *isa = _("unknown");
3726 char const *mac = _("unknown mac");
3727 char const *additional = NULL;
3728
3729 switch (e_flags & EF_M68K_CF_ISA_MASK)
3730 {
3731 case EF_M68K_CF_ISA_A_NODIV:
3732 isa = "A";
3733 additional = ", nodiv";
3734 break;
3735 case EF_M68K_CF_ISA_A:
3736 isa = "A";
3737 break;
3738 case EF_M68K_CF_ISA_A_PLUS:
3739 isa = "A+";
3740 break;
3741 case EF_M68K_CF_ISA_B_NOUSP:
3742 isa = "B";
3743 additional = ", nousp";
3744 break;
3745 case EF_M68K_CF_ISA_B:
3746 isa = "B";
3747 break;
3748 case EF_M68K_CF_ISA_C:
3749 isa = "C";
3750 break;
3751 case EF_M68K_CF_ISA_C_NODIV:
3752 isa = "C";
3753 additional = ", nodiv";
3754 break;
3755 }
3756 out = stpcpy (out, ", cf, isa ");
3757 out = stpcpy (out, isa);
3758 if (additional)
3759 out = stpcpy (out, additional);
3760 if (e_flags & EF_M68K_CF_FLOAT)
3761 out = stpcpy (out, ", float");
3762 switch (e_flags & EF_M68K_CF_MAC_MASK)
3763 {
3764 case 0:
3765 mac = NULL;
3766 break;
3767 case EF_M68K_CF_MAC:
3768 mac = "mac";
3769 break;
3770 case EF_M68K_CF_EMAC:
3771 mac = "emac";
3772 break;
3773 case EF_M68K_CF_EMAC_B:
3774 mac = "emac_b";
3775 break;
3776 }
3777 if (mac)
3778 {
3779 out = stpcpy (out, ", ");
3780 out = stpcpy (out, mac);
3781 }
3782 }
3783 return out;
3784}
3785
3786static char *
3787decode_MeP_machine_flags (char *out, unsigned int e_flags)
3788{
3789 switch (e_flags & EF_MEP_CPU_MASK)
3790 {
3791 case EF_MEP_CPU_MEP:
3792 out = stpcpy (out, ", generic MeP");
3793 break;
3794 case EF_MEP_CPU_C2:
3795 out = stpcpy (out, ", MeP C2");
3796 break;
3797 case EF_MEP_CPU_C3:
3798 out = stpcpy (out, ", MeP C3");
3799 break;
3800 case EF_MEP_CPU_C4:
3801 out = stpcpy (out, ", MeP C4");
3802 break;
3803 case EF_MEP_CPU_C5:
3804 out = stpcpy (out, ", MeP C5");
3805 break;
3806 case EF_MEP_CPU_H1:
3807 out = stpcpy (out, ", MeP H1");
3808 break;
3809 default:
3810 out = stpcpy (out, _(", <unknown MeP cpu type>"));
3811 break;
3812 }
3813
3814 switch (e_flags & EF_MEP_COP_MASK)
3815 {
3816 case EF_MEP_COP_NONE:
3817 break;
3818 case EF_MEP_COP_AVC:
3819 out = stpcpy (out, ", AVC coprocessor");
3820 break;
3821 case EF_MEP_COP_AVC2:
3822 out = stpcpy (out, ", AVC2 coprocessor");
3823 break;
3824 case EF_MEP_COP_FMAX:
3825 out = stpcpy (out, ", FMAX coprocessor");
3826 break;
3827 case EF_MEP_COP_IVC2:
3828 out = stpcpy (out, ", IVC2 coprocessor");
3829 break;
3830 default:
3831 out = stpcpy (out, _("<unknown MeP copro type>"));
3832 break;
3833 }
3834
3835 if (e_flags & EF_MEP_LIBRARY)
3836 out = stpcpy (out, ", Built for Library");
3837
3838 if (e_flags & EF_MEP_INDEX_MASK)
3839 out += sprintf (out, ", Configuration Index: %#x",
3840 e_flags & EF_MEP_INDEX_MASK);
3841
3842 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3843 out += sprintf (out, _(", unknown flags bits: %#x"),
3844 e_flags & ~ EF_MEP_ALL_FLAGS);
3845 return out;
3846}
3847
3848static char *
3849decode_MIPS_machine_flags (char *out, unsigned int e_flags)
3850{
3851 if (e_flags & EF_MIPS_NOREORDER)
3852 out = stpcpy (out, ", noreorder");
3853
3854 if (e_flags & EF_MIPS_PIC)
3855 out = stpcpy (out, ", pic");
3856
3857 if (e_flags & EF_MIPS_CPIC)
3858 out = stpcpy (out, ", cpic");
3859
3860 if (e_flags & EF_MIPS_UCODE)
3861 out = stpcpy (out, ", ugen_reserved");
3862
3863 if (e_flags & EF_MIPS_ABI2)
3864 out = stpcpy (out, ", abi2");
3865
3866 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3867 out = stpcpy (out, ", odk first");
3868
3869 if (e_flags & EF_MIPS_32BITMODE)
3870 out = stpcpy (out, ", 32bitmode");
3871
3872 if (e_flags & EF_MIPS_NAN2008)
3873 out = stpcpy (out, ", nan2008");
3874
3875 if (e_flags & EF_MIPS_FP64)
3876 out = stpcpy (out, ", fp64");
3877
3878 switch ((e_flags & EF_MIPS_MACH))
3879 {
d173146d 3880 case EF_MIPS_MACH_3900:
f8c4789c
AM
3881 out = stpcpy (out, ", 3900");
3882 break;
d173146d 3883 case EF_MIPS_MACH_4010:
f8c4789c
AM
3884 out = stpcpy (out, ", 4010");
3885 break;
d173146d 3886 case EF_MIPS_MACH_4100:
f8c4789c
AM
3887 out = stpcpy (out, ", 4100");
3888 break;
d173146d 3889 case EF_MIPS_MACH_4111:
f8c4789c
AM
3890 out = stpcpy (out, ", 4111");
3891 break;
d173146d 3892 case EF_MIPS_MACH_4120:
f8c4789c
AM
3893 out = stpcpy (out, ", 4120");
3894 break;
d173146d 3895 case EF_MIPS_MACH_4650:
f8c4789c
AM
3896 out = stpcpy (out, ", 4650");
3897 break;
d173146d 3898 case EF_MIPS_MACH_5400:
f8c4789c
AM
3899 out = stpcpy (out, ", 5400");
3900 break;
d173146d 3901 case EF_MIPS_MACH_5500:
f8c4789c
AM
3902 out = stpcpy (out, ", 5500");
3903 break;
d173146d 3904 case EF_MIPS_MACH_5900:
f8c4789c
AM
3905 out = stpcpy (out, ", 5900");
3906 break;
d173146d 3907 case EF_MIPS_MACH_SB1:
f8c4789c
AM
3908 out = stpcpy (out, ", sb1");
3909 break;
d173146d 3910 case EF_MIPS_MACH_9000:
f8c4789c
AM
3911 out = stpcpy (out, ", 9000");
3912 break;
d173146d 3913 case EF_MIPS_MACH_LS2E:
f8c4789c
AM
3914 out = stpcpy (out, ", loongson-2e");
3915 break;
d173146d 3916 case EF_MIPS_MACH_LS2F:
f8c4789c
AM
3917 out = stpcpy (out, ", loongson-2f");
3918 break;
d173146d 3919 case EF_MIPS_MACH_GS464:
f8c4789c
AM
3920 out = stpcpy (out, ", gs464");
3921 break;
d173146d 3922 case EF_MIPS_MACH_GS464E:
f8c4789c
AM
3923 out = stpcpy (out, ", gs464e");
3924 break;
d173146d 3925 case EF_MIPS_MACH_GS264E:
f8c4789c
AM
3926 out = stpcpy (out, ", gs264e");
3927 break;
d173146d 3928 case EF_MIPS_MACH_OCTEON:
f8c4789c
AM
3929 out = stpcpy (out, ", octeon");
3930 break;
d173146d 3931 case EF_MIPS_MACH_OCTEON2:
f8c4789c
AM
3932 out = stpcpy (out, ", octeon2");
3933 break;
d173146d 3934 case EF_MIPS_MACH_OCTEON3:
f8c4789c
AM
3935 out = stpcpy (out, ", octeon3");
3936 break;
d173146d 3937 case EF_MIPS_MACH_XLR:
f8c4789c
AM
3938 out = stpcpy (out, ", xlr");
3939 break;
d173146d 3940 case EF_MIPS_MACH_IAMR2:
f8c4789c
AM
3941 out = stpcpy (out, ", interaptiv-mr2");
3942 break;
d173146d 3943 case EF_MIPS_MACH_ALLEGREX:
f8c4789c
AM
3944 out = stpcpy (out, ", allegrex");
3945 break;
3946 case 0:
3947 /* We simply ignore the field in this case to avoid confusion:
3948 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3949 extension. */
3950 break;
3951 default:
3952 out = stpcpy (out, _(", unknown CPU"));
3953 break;
3954 }
3955
3956 switch ((e_flags & EF_MIPS_ABI))
3957 {
d173146d 3958 case EF_MIPS_ABI_O32:
f8c4789c
AM
3959 out = stpcpy (out, ", o32");
3960 break;
d173146d 3961 case EF_MIPS_ABI_O64:
f8c4789c
AM
3962 out = stpcpy (out, ", o64");
3963 break;
d173146d 3964 case EF_MIPS_ABI_EABI32:
f8c4789c
AM
3965 out = stpcpy (out, ", eabi32");
3966 break;
d173146d 3967 case EF_MIPS_ABI_EABI64:
f8c4789c
AM
3968 out = stpcpy (out, ", eabi64");
3969 break;
3970 case 0:
3971 /* We simply ignore the field in this case to avoid confusion:
3972 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3973 This means it is likely to be an o32 file, but not for
3974 sure. */
3975 break;
3976 default:
3977 out = stpcpy (out, _(", unknown ABI"));
3978 break;
3979 }
3980
3981 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3982 out = stpcpy (out, ", mdmx");
3983
3984 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3985 out = stpcpy (out, ", mips16");
3986
3987 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3988 out = stpcpy (out, ", micromips");
3989
3990 switch ((e_flags & EF_MIPS_ARCH))
3991 {
d173146d 3992 case EF_MIPS_ARCH_1:
f8c4789c
AM
3993 out = stpcpy (out, ", mips1");
3994 break;
d173146d 3995 case EF_MIPS_ARCH_2:
f8c4789c
AM
3996 out = stpcpy (out, ", mips2");
3997 break;
d173146d 3998 case EF_MIPS_ARCH_3:
f8c4789c
AM
3999 out = stpcpy (out, ", mips3");
4000 break;
d173146d 4001 case EF_MIPS_ARCH_4:
f8c4789c
AM
4002 out = stpcpy (out, ", mips4");
4003 break;
d173146d 4004 case EF_MIPS_ARCH_5:
f8c4789c
AM
4005 out = stpcpy (out, ", mips5");
4006 break;
d173146d 4007 case EF_MIPS_ARCH_32:
f8c4789c
AM
4008 out = stpcpy (out, ", mips32");
4009 break;
d173146d 4010 case EF_MIPS_ARCH_32R2:
f8c4789c
AM
4011 out = stpcpy (out, ", mips32r2");
4012 break;
d173146d 4013 case EF_MIPS_ARCH_32R6:
f8c4789c
AM
4014 out = stpcpy (out, ", mips32r6");
4015 break;
d173146d 4016 case EF_MIPS_ARCH_64:
f8c4789c
AM
4017 out = stpcpy (out, ", mips64");
4018 break;
d173146d 4019 case EF_MIPS_ARCH_64R2:
f8c4789c
AM
4020 out = stpcpy (out, ", mips64r2");
4021 break;
d173146d 4022 case EF_MIPS_ARCH_64R6:
f8c4789c
AM
4023 out = stpcpy (out, ", mips64r6");
4024 break;
4025 default:
4026 out = stpcpy (out, _(", unknown ISA"));
4027 break;
4028 }
4029 return out;
4030}
4031
4032static char *
4033decode_MSP430_machine_flags (char *out, unsigned e_flags)
4034{
4035 out = stpcpy (out, _(": architecture variant: "));
4036 switch (e_flags & EF_MSP430_MACH)
4037 {
4038 case E_MSP430_MACH_MSP430x11:
4039 out = stpcpy (out, "MSP430x11");
4040 break;
4041 case E_MSP430_MACH_MSP430x11x1:
4042 out = stpcpy (out, "MSP430x11x1 ");
4043 break;
4044 case E_MSP430_MACH_MSP430x12:
4045 out = stpcpy (out, "MSP430x12");
4046 break;
4047 case E_MSP430_MACH_MSP430x13:
4048 out = stpcpy (out, "MSP430x13");
4049 break;
4050 case E_MSP430_MACH_MSP430x14:
4051 out = stpcpy (out, "MSP430x14");
4052 break;
4053 case E_MSP430_MACH_MSP430x15:
4054 out = stpcpy (out, "MSP430x15");
4055 break;
4056 case E_MSP430_MACH_MSP430x16:
4057 out = stpcpy (out, "MSP430x16");
4058 break;
4059 case E_MSP430_MACH_MSP430x31:
4060 out = stpcpy (out, "MSP430x31");
4061 break;
4062 case E_MSP430_MACH_MSP430x32:
4063 out = stpcpy (out, "MSP430x32");
4064 break;
4065 case E_MSP430_MACH_MSP430x33:
4066 out = stpcpy (out, "MSP430x33");
4067 break;
4068 case E_MSP430_MACH_MSP430x41:
4069 out = stpcpy (out, "MSP430x41");
4070 break;
4071 case E_MSP430_MACH_MSP430x42:
4072 out = stpcpy (out, "MSP430x42");
4073 break;
4074 case E_MSP430_MACH_MSP430x43:
4075 out = stpcpy (out, "MSP430x43");
4076 break;
4077 case E_MSP430_MACH_MSP430x44:
4078 out = stpcpy (out, "MSP430x44");
4079 break;
4080 case E_MSP430_MACH_MSP430X :
4081 out = stpcpy (out, "MSP430X");
4082 break;
4083 default:
4084 out = stpcpy (out, _(": unknown"));
4085 break;
4086 }
4087
4088 if (e_flags & ~ EF_MSP430_MACH)
4089 out = stpcpy (out, _(": unknown extra flag bits also present"));
4090 return out;
4091}
4092
4093static char *
4094decode_NDS32_machine_flags (char *out, unsigned e_flags)
35c08157
KLC
4095{
4096 unsigned abi;
4097 unsigned arch;
4098 unsigned config;
4099 unsigned version;
015dc7e1 4100 bool has_fpu = false;
35c08157
KLC
4101
4102 static const char *ABI_STRINGS[] =
4103 {
4104 "ABI v0", /* use r5 as return register; only used in N1213HC */
4105 "ABI v1", /* use r0 as return register */
4106 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
4107 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
4108 "AABI",
4109 "ABI2 FP+"
35c08157
KLC
4110 };
4111 static const char *VER_STRINGS[] =
4112 {
4113 "Andes ELF V1.3 or older",
4114 "Andes ELF V1.3.1",
4115 "Andes ELF V1.4"
4116 };
4117 static const char *ARCH_STRINGS[] =
4118 {
4119 "",
4120 "Andes Star v1.0",
4121 "Andes Star v2.0",
4122 "Andes Star v3.0",
4123 "Andes Star v3.0m"
4124 };
4125
4126 abi = EF_NDS_ABI & e_flags;
4127 arch = EF_NDS_ARCH & e_flags;
4128 config = EF_NDS_INST & e_flags;
4129 version = EF_NDS32_ELF_VERSION & e_flags;
4130
35c08157
KLC
4131 switch (abi)
4132 {
4133 case E_NDS_ABI_V0:
4134 case E_NDS_ABI_V1:
4135 case E_NDS_ABI_V2:
4136 case E_NDS_ABI_V2FP:
4137 case E_NDS_ABI_AABI:
40c7a7cb 4138 case E_NDS_ABI_V2FP_PLUS:
35c08157 4139 /* In case there are holes in the array. */
f8c4789c 4140 out += sprintf (out, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
35c08157
KLC
4141 break;
4142
4143 default:
f8c4789c 4144 out = stpcpy (out, ", <unrecognized ABI>");
35c08157
KLC
4145 break;
4146 }
4147
4148 switch (version)
4149 {
4150 case E_NDS32_ELF_VER_1_2:
4151 case E_NDS32_ELF_VER_1_3:
4152 case E_NDS32_ELF_VER_1_4:
f8c4789c 4153 out += sprintf (out, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
35c08157
KLC
4154 break;
4155
4156 default:
f8c4789c 4157 out = stpcpy (out, ", <unrecognized ELF version number>");
35c08157
KLC
4158 break;
4159 }
4160
4161 if (E_NDS_ABI_V0 == abi)
4162 {
4163 /* OLD ABI; only used in N1213HC, has performance extension 1. */
f8c4789c 4164 out = stpcpy (out, ", Andes Star v1.0, N1213HC, MAC, PERF1");
35c08157 4165 if (arch == E_NDS_ARCH_STAR_V1_0)
f8c4789c
AM
4166 out = stpcpy (out, ", 16b"); /* has 16-bit instructions */
4167 return out;
35c08157
KLC
4168 }
4169
4170 switch (arch)
4171 {
4172 case E_NDS_ARCH_STAR_V1_0:
4173 case E_NDS_ARCH_STAR_V2_0:
4174 case E_NDS_ARCH_STAR_V3_0:
4175 case E_NDS_ARCH_STAR_V3_M:
f8c4789c 4176 out += sprintf (out, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
35c08157
KLC
4177 break;
4178
4179 default:
f8c4789c 4180 out = stpcpy (out, ", <unrecognized architecture>");
35c08157
KLC
4181 /* ARCH version determines how the e_flags are interpreted.
4182 If it is unknown, we cannot proceed. */
f8c4789c 4183 return out;
35c08157
KLC
4184 }
4185
4186 /* Newer ABI; Now handle architecture specific flags. */
4187 if (arch == E_NDS_ARCH_STAR_V1_0)
4188 {
4189 if (config & E_NDS32_HAS_MFUSR_PC_INST)
f8c4789c 4190 out = stpcpy (out, ", MFUSR_PC");
35c08157
KLC
4191
4192 if (!(config & E_NDS32_HAS_NO_MAC_INST))
f8c4789c 4193 out = stpcpy (out, ", MAC");
35c08157
KLC
4194
4195 if (config & E_NDS32_HAS_DIV_INST)
f8c4789c 4196 out = stpcpy (out, ", DIV");
35c08157
KLC
4197
4198 if (config & E_NDS32_HAS_16BIT_INST)
f8c4789c 4199 out = stpcpy (out, ", 16b");
35c08157
KLC
4200 }
4201 else
4202 {
4203 if (config & E_NDS32_HAS_MFUSR_PC_INST)
4204 {
4205 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4206 out = stpcpy (out, ", [B8]");
35c08157 4207 else
f8c4789c 4208 out = stpcpy (out, ", EX9");
35c08157
KLC
4209 }
4210
4211 if (config & E_NDS32_HAS_MAC_DX_INST)
f8c4789c 4212 out = stpcpy (out, ", MAC_DX");
35c08157
KLC
4213
4214 if (config & E_NDS32_HAS_DIV_DX_INST)
f8c4789c 4215 out = stpcpy (out, ", DIV_DX");
35c08157
KLC
4216
4217 if (config & E_NDS32_HAS_16BIT_INST)
4218 {
4219 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4220 out = stpcpy (out, ", 16b");
35c08157 4221 else
f8c4789c 4222 out = stpcpy (out, ", IFC");
35c08157
KLC
4223 }
4224 }
4225
4226 if (config & E_NDS32_HAS_EXT_INST)
f8c4789c 4227 out = stpcpy (out, ", PERF1");
35c08157
KLC
4228
4229 if (config & E_NDS32_HAS_EXT2_INST)
f8c4789c 4230 out = stpcpy (out, ", PERF2");
35c08157
KLC
4231
4232 if (config & E_NDS32_HAS_FPU_INST)
4233 {
015dc7e1 4234 has_fpu = true;
f8c4789c 4235 out = stpcpy (out, ", FPU_SP");
35c08157
KLC
4236 }
4237
4238 if (config & E_NDS32_HAS_FPU_DP_INST)
4239 {
015dc7e1 4240 has_fpu = true;
f8c4789c 4241 out = stpcpy (out, ", FPU_DP");
35c08157
KLC
4242 }
4243
4244 if (config & E_NDS32_HAS_FPU_MAC_INST)
4245 {
015dc7e1 4246 has_fpu = true;
f8c4789c 4247 out = stpcpy (out, ", FPU_MAC");
35c08157
KLC
4248 }
4249
4250 if (has_fpu)
4251 {
4252 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
4253 {
4254 case E_NDS32_FPU_REG_8SP_4DP:
f8c4789c 4255 out = stpcpy (out, ", FPU_REG:8/4");
35c08157
KLC
4256 break;
4257 case E_NDS32_FPU_REG_16SP_8DP:
f8c4789c 4258 out = stpcpy (out, ", FPU_REG:16/8");
35c08157
KLC
4259 break;
4260 case E_NDS32_FPU_REG_32SP_16DP:
f8c4789c 4261 out = stpcpy (out, ", FPU_REG:32/16");
35c08157
KLC
4262 break;
4263 case E_NDS32_FPU_REG_32SP_32DP:
f8c4789c 4264 out = stpcpy (out, ", FPU_REG:32/32");
35c08157
KLC
4265 break;
4266 }
4267 }
4268
4269 if (config & E_NDS32_HAS_AUDIO_INST)
f8c4789c 4270 out = stpcpy (out, ", AUDIO");
35c08157
KLC
4271
4272 if (config & E_NDS32_HAS_STRING_INST)
f8c4789c 4273 out = stpcpy (out, ", STR");
35c08157
KLC
4274
4275 if (config & E_NDS32_HAS_REDUCED_REGS)
f8c4789c 4276 out = stpcpy (out, ", 16REG");
35c08157
KLC
4277
4278 if (config & E_NDS32_HAS_VIDEO_INST)
4279 {
4280 if (version <= E_NDS32_ELF_VER_1_3)
f8c4789c 4281 out = stpcpy (out, ", VIDEO");
35c08157 4282 else
f8c4789c 4283 out = stpcpy (out, ", SATURATION");
35c08157
KLC
4284 }
4285
4286 if (config & E_NDS32_HAS_ENCRIPT_INST)
f8c4789c 4287 out = stpcpy (out, ", ENCRP");
35c08157
KLC
4288
4289 if (config & E_NDS32_HAS_L2C_INST)
f8c4789c
AM
4290 out = stpcpy (out, ", L2C");
4291
4292 return out;
35c08157
KLC
4293}
4294
f8c4789c
AM
4295static char *
4296decode_PARISC_machine_flags (char *out, unsigned e_flags)
4297{
4298 switch (e_flags & EF_PARISC_ARCH)
4299 {
4300 case EFA_PARISC_1_0:
4301 out = stpcpy (out, ", PA-RISC 1.0");
4302 break;
4303 case EFA_PARISC_1_1:
4304 out = stpcpy (out, ", PA-RISC 1.1");
4305 break;
4306 case EFA_PARISC_2_0:
4307 out = stpcpy (out, ", PA-RISC 2.0");
4308 break;
4309 default:
4310 break;
4311 }
4312 if (e_flags & EF_PARISC_TRAPNIL)
4313 out = stpcpy (out, ", trapnil");
4314 if (e_flags & EF_PARISC_EXT)
4315 out = stpcpy (out, ", ext");
4316 if (e_flags & EF_PARISC_LSB)
4317 out = stpcpy (out, ", lsb");
4318 if (e_flags & EF_PARISC_WIDE)
4319 out = stpcpy (out, ", wide");
4320 if (e_flags & EF_PARISC_NO_KABP)
4321 out = stpcpy (out, ", no kabp");
4322 if (e_flags & EF_PARISC_LAZYSWAP)
4323 out = stpcpy (out, ", lazyswap");
4324 return out;
4325}
4326
4327static char *
4328decode_RISCV_machine_flags (char *out, unsigned e_flags)
4329{
4330 if (e_flags & EF_RISCV_RVC)
4331 out = stpcpy (out, ", RVC");
4332
4333 if (e_flags & EF_RISCV_RVE)
4334 out = stpcpy (out, ", RVE");
4335
4336 if (e_flags & EF_RISCV_TSO)
4337 out = stpcpy (out, ", TSO");
4338
4339 switch (e_flags & EF_RISCV_FLOAT_ABI)
4340 {
4341 case EF_RISCV_FLOAT_ABI_SOFT:
4342 out = stpcpy (out, ", soft-float ABI");
4343 break;
4344
4345 case EF_RISCV_FLOAT_ABI_SINGLE:
4346 out = stpcpy (out, ", single-float ABI");
4347 break;
4348
4349 case EF_RISCV_FLOAT_ABI_DOUBLE:
4350 out = stpcpy (out, ", double-float ABI");
4351 break;
4352
4353 case EF_RISCV_FLOAT_ABI_QUAD:
4354 out = stpcpy (out, ", quad-float ABI");
4355 break;
4356 }
4357 return out;
4358}
4359
4360static char *
4361decode_RL78_machine_flags (char *out, unsigned e_flags)
4362{
4363 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4364 {
4365 case E_FLAG_RL78_ANY_CPU:
4366 break;
4367 case E_FLAG_RL78_G10:
4368 out = stpcpy (out, ", G10");
4369 break;
4370 case E_FLAG_RL78_G13:
4371 out = stpcpy (out, ", G13");
4372 break;
4373 case E_FLAG_RL78_G14:
4374 out = stpcpy (out, ", G14");
4375 break;
4376 }
4377 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4378 out = stpcpy (out, ", 64-bit doubles");
4379 return out;
4380}
4381
4382static char *
4383decode_RX_machine_flags (char *out, unsigned e_flags)
4384{
4385 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4386 out = stpcpy (out, ", 64-bit doubles");
4387 if (e_flags & E_FLAG_RX_DSP)
4388 out = stpcpy (out, ", dsp");
4389 if (e_flags & E_FLAG_RX_PID)
4390 out = stpcpy (out, ", pid");
4391 if (e_flags & E_FLAG_RX_ABI)
4392 out = stpcpy (out, ", RX ABI");
4393 if (e_flags & E_FLAG_RX_SINSNS_SET)
4394 out = stpcpy (out, (e_flags & E_FLAG_RX_SINSNS_YES
4395 ? ", uses String instructions"
4396 : ", bans String instructions"));
4397 if (e_flags & E_FLAG_RX_V2)
4398 out = stpcpy (out, ", V2");
4399 if (e_flags & E_FLAG_RX_V3)
4400 out = stpcpy (out, ", V3");
4401 return out;
4402}
4403
4404static char *
4405decode_SH_machine_flags (char *out, unsigned e_flags)
4406{
4407 switch ((e_flags & EF_SH_MACH_MASK))
4408 {
4409 case EF_SH1:
4410 out = stpcpy (out, ", sh1");
4411 break;
4412 case EF_SH2:
4413 out = stpcpy (out, ", sh2");
4414 break;
4415 case EF_SH3:
4416 out = stpcpy (out, ", sh3");
4417 break;
4418 case EF_SH_DSP:
4419 out = stpcpy (out, ", sh-dsp");
4420 break;
4421 case EF_SH3_DSP:
4422 out = stpcpy (out, ", sh3-dsp");
4423 break;
4424 case EF_SH4AL_DSP:
4425 out = stpcpy (out, ", sh4al-dsp");
4426 break;
4427 case EF_SH3E:
4428 out = stpcpy (out, ", sh3e");
4429 break;
4430 case EF_SH4:
4431 out = stpcpy (out, ", sh4");
4432 break;
4433 case EF_SH5:
4434 out = stpcpy (out, ", sh5");
4435 break;
4436 case EF_SH2E:
4437 out = stpcpy (out, ", sh2e");
4438 break;
4439 case EF_SH4A:
4440 out = stpcpy (out, ", sh4a");
4441 break;
4442 case EF_SH2A:
4443 out = stpcpy (out, ", sh2a");
4444 break;
4445 case EF_SH4_NOFPU:
4446 out = stpcpy (out, ", sh4-nofpu");
4447 break;
4448 case EF_SH4A_NOFPU:
4449 out = stpcpy (out, ", sh4a-nofpu");
4450 break;
4451 case EF_SH2A_NOFPU:
4452 out = stpcpy (out, ", sh2a-nofpu");
4453 break;
4454 case EF_SH3_NOMMU:
4455 out = stpcpy (out, ", sh3-nommu");
4456 break;
4457 case EF_SH4_NOMMU_NOFPU:
4458 out = stpcpy (out, ", sh4-nommu-nofpu");
4459 break;
4460 case EF_SH2A_SH4_NOFPU:
4461 out = stpcpy (out, ", sh2a-nofpu-or-sh4-nommu-nofpu");
4462 break;
4463 case EF_SH2A_SH3_NOFPU:
4464 out = stpcpy (out, ", sh2a-nofpu-or-sh3-nommu");
4465 break;
4466 case EF_SH2A_SH4:
4467 out = stpcpy (out, ", sh2a-or-sh4");
4468 break;
4469 case EF_SH2A_SH3E:
4470 out = stpcpy (out, ", sh2a-or-sh3e");
4471 break;
4472 default:
4473 out = stpcpy (out, _(", unknown ISA"));
4474 break;
4475 }
4476
4477 if (e_flags & EF_SH_PIC)
4478 out = stpcpy (out, ", pic");
4479
4480 if (e_flags & EF_SH_FDPIC)
4481 out = stpcpy (out, ", fdpic");
4482 return out;
4483}
4484
4485static char *
4486decode_SPARC_machine_flags (char *out, unsigned e_flags)
4487{
4488 if (e_flags & EF_SPARC_32PLUS)
4489 out = stpcpy (out, ", v8+");
4490
4491 if (e_flags & EF_SPARC_SUN_US1)
4492 out = stpcpy (out, ", ultrasparcI");
4493
4494 if (e_flags & EF_SPARC_SUN_US3)
4495 out = stpcpy (out, ", ultrasparcIII");
4496
4497 if (e_flags & EF_SPARC_HAL_R1)
4498 out = stpcpy (out, ", halr1");
4499
4500 if (e_flags & EF_SPARC_LEDATA)
4501 out = stpcpy (out, ", ledata");
4502
4503 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4504 out = stpcpy (out, ", tso");
4505
4506 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4507 out = stpcpy (out, ", pso");
4508
4509 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4510 out = stpcpy (out, ", rmo");
4511 return out;
4512}
4513
4514static char *
4515decode_V800_machine_flags (char *out, unsigned int e_flags)
4516{
4517 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
4518 out = stpcpy (out, ", RH850 ABI");
4519
4520 if (e_flags & EF_V800_850E3)
4521 out = stpcpy (out, ", V3 architecture");
4522
4523 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
4524 out = stpcpy (out, ", FPU not used");
4525
4526 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
4527 out = stpcpy (out, ", regmode: COMMON");
4528
4529 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
4530 out = stpcpy (out, ", r4 not used");
4531
4532 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
4533 out = stpcpy (out, ", r30 not used");
4534
4535 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
4536 out = stpcpy (out, ", r5 not used");
4537
4538 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
4539 out = stpcpy (out, ", r2 not used");
4540
4541 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
4542 {
4543 switch (e_flags & - e_flags)
4544 {
4545 case EF_RH850_FPU_DOUBLE:
4546 out = stpcpy (out, ", double precision FPU");
4547 break;
4548 case EF_RH850_FPU_SINGLE:
4549 out = stpcpy (out, ", single precision FPU");
4550 break;
4551 case EF_RH850_REGMODE22:
4552 out = stpcpy (out, ", regmode:22");
4553 break;
4554 case EF_RH850_REGMODE32:
4555 out = stpcpy (out, ", regmode:23");
4556 break;
4557 case EF_RH850_GP_FIX:
4558 out = stpcpy (out, ", r4 fixed");
4559 break;
4560 case EF_RH850_GP_NOFIX:
4561 out = stpcpy (out, ", r4 free");
4562 break;
4563 case EF_RH850_EP_FIX:
4564 out = stpcpy (out, ", r30 fixed");
4565 break;
4566 case EF_RH850_EP_NOFIX:
4567 out = stpcpy (out, ", r30 free");
4568 break;
4569 case EF_RH850_TP_FIX:
4570 out = stpcpy (out, ", r5 fixed");
4571 break;
4572 case EF_RH850_TP_NOFIX:
4573 out = stpcpy (out, ", r5 free");
4574 break;
4575 case EF_RH850_REG2_RESERVE:
4576 out = stpcpy (out, ", r2 fixed");
4577 break;
4578 case EF_RH850_REG2_NORESERVE:
4579 out = stpcpy (out, ", r2 free");
4580 break;
4581 default:
4582 break;
4583 }
4584 }
4585 return out;
4586}
4587
4588static char *
4589decode_V850_machine_flags (char *out, unsigned int e_flags)
4590{
4591 switch (e_flags & EF_V850_ARCH)
4592 {
4593 case E_V850E3V5_ARCH:
4594 out = stpcpy (out, ", v850e3v5");
4595 break;
4596 case E_V850E2V3_ARCH:
4597 out = stpcpy (out, ", v850e2v3");
4598 break;
4599 case E_V850E2_ARCH:
4600 out = stpcpy (out, ", v850e2");
4601 break;
4602 case E_V850E1_ARCH:
4603 out = stpcpy (out, ", v850e1");
4604 break;
4605 case E_V850E_ARCH:
4606 out = stpcpy (out, ", v850e");
4607 break;
4608 case E_V850_ARCH:
4609 out = stpcpy (out, ", v850");
4610 break;
4611 default:
4612 out = stpcpy (out, _(", unknown v850 architecture variant"));
4613 break;
4614 }
4615 return out;
4616}
4617
4618static char *
4619decode_Z80_machine_flags (char *out, unsigned int e_flags)
4620{
4621 switch (e_flags & EF_Z80_MACH_MSK)
4622 {
4623 case EF_Z80_MACH_Z80:
4624 out = stpcpy (out, ", Z80");
4625 break;
4626 case EF_Z80_MACH_Z180:
4627 out = stpcpy (out, ", Z180");
4628 break;
4629 case EF_Z80_MACH_R800:
4630 out = stpcpy (out, ", R800");
4631 break;
4632 case EF_Z80_MACH_EZ80_Z80:
4633 out = stpcpy (out, ", EZ80");
4634 break;
4635 case EF_Z80_MACH_EZ80_ADL:
4636 out = stpcpy (out, ", EZ80, ADL");
4637 break;
4638 case EF_Z80_MACH_GBZ80:
4639 out = stpcpy (out, ", GBZ80");
4640 break;
4641 case EF_Z80_MACH_Z80N:
4642 out = stpcpy (out, ", Z80N");
4643 break;
4644 default:
4645 out = stpcpy (out, _(", unknown"));
4646 break;
4647 }
4648 return out;
4649}
4650
4651static char *
4652decode_AMDGPU_machine_flags (char *out, unsigned int e_flags, Filedata *filedata)
c077c580
SM
4653{
4654 unsigned char *e_ident = filedata->file_header.e_ident;
4655 unsigned char osabi = e_ident[EI_OSABI];
4656 unsigned char abiversion = e_ident[EI_ABIVERSION];
4657 unsigned int mach;
4658
4659 /* HSA OS ABI v2 used a different encoding, but we don't need to support it,
4660 it has been deprecated for a while.
4661
4662 The PAL, MESA3D and NONE OS ABIs are not properly versioned, at the time
4663 of writing, they use the same flags as HSA v3, so the code below uses that
4664 assumption. */
4665 if (osabi == ELFOSABI_AMDGPU_HSA && abiversion < ELFABIVERSION_AMDGPU_HSA_V3)
f8c4789c 4666 return out;
c077c580
SM
4667
4668 mach = e_flags & EF_AMDGPU_MACH;
4669 switch (mach)
4670 {
4671#define AMDGPU_CASE(code, string) \
f8c4789c 4672 case code: out = stpcpy (out, ", " string); break;
c077c580
SM
4673 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX600, "gfx600")
4674 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX601, "gfx601")
4675 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX700, "gfx700")
4676 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX701, "gfx701")
4677 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX702, "gfx702")
4678 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX703, "gfx703")
4679 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX704, "gfx704")
4680 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX801, "gfx801")
4681 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX802, "gfx802")
4682 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX803, "gfx803")
4683 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX810, "gfx810")
4684 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX900, "gfx900")
4685 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX902, "gfx902")
4686 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX904, "gfx904")
4687 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX906, "gfx906")
4688 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX908, "gfx908")
4689 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX909, "gfx909")
4690 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90C, "gfx90c")
4691 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1010, "gfx1010")
4692 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1011, "gfx1011")
4693 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1012, "gfx1012")
4694 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1030, "gfx1030")
4695 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1031, "gfx1031")
4696 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1032, "gfx1032")
4697 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1033, "gfx1033")
a7a0cb6c
SM
4698 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1100, "gfx1100")
4699 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1101, "gfx1101")
4700 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1102, "gfx1102")
c077c580
SM
4701 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX602, "gfx602")
4702 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX705, "gfx705")
4703 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX805, "gfx805")
4704 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1035, "gfx1035")
4705 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1034, "gfx1034")
4706 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX90A, "gfx90a")
4707 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX940, "gfx940")
4708 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1013, "gfx1013")
4709 AMDGPU_CASE (EF_AMDGPU_MACH_AMDGCN_GFX1036, "gfx1036")
4710 default:
f8c4789c 4711 out += sprintf (out, _(", <unknown AMDGPU GPU type: %#x>"), mach);
c077c580
SM
4712 break;
4713#undef AMDGPU_CASE
4714 }
4715
c077c580
SM
4716 e_flags &= ~EF_AMDGPU_MACH;
4717
4718 if ((osabi == ELFOSABI_AMDGPU_HSA
4719 && abiversion == ELFABIVERSION_AMDGPU_HSA_V3)
4720 || osabi != ELFOSABI_AMDGPU_HSA)
4721 {
4722 /* For HSA v3 and other OS ABIs. */
4723 if (e_flags & EF_AMDGPU_FEATURE_XNACK_V3)
4724 {
f8c4789c 4725 out = stpcpy (out, ", xnack on");
c077c580
SM
4726 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V3;
4727 }
4728
4729 if (e_flags & EF_AMDGPU_FEATURE_SRAMECC_V3)
4730 {
f8c4789c 4731 out = stpcpy (out, ", sramecc on");
c077c580
SM
4732 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V3;
4733 }
4734 }
4735 else
4736 {
4737 /* For HSA v4+. */
4738 int xnack, sramecc;
4739
4740 xnack = e_flags & EF_AMDGPU_FEATURE_XNACK_V4;
4741 switch (xnack)
4742 {
4743 case EF_AMDGPU_FEATURE_XNACK_UNSUPPORTED_V4:
4744 break;
4745
4746 case EF_AMDGPU_FEATURE_XNACK_ANY_V4:
f8c4789c 4747 out = stpcpy (out, ", xnack any");
c077c580
SM
4748 break;
4749
4750 case EF_AMDGPU_FEATURE_XNACK_OFF_V4:
f8c4789c 4751 out = stpcpy (out, ", xnack off");
c077c580
SM
4752 break;
4753
4754 case EF_AMDGPU_FEATURE_XNACK_ON_V4:
f8c4789c 4755 out = stpcpy (out, ", xnack on");
c077c580
SM
4756 break;
4757
4758 default:
f8c4789c 4759 out += sprintf (out, _(", <unknown xnack value: %#x>"), xnack);
c077c580
SM
4760 break;
4761 }
4762
c077c580
SM
4763 e_flags &= ~EF_AMDGPU_FEATURE_XNACK_V4;
4764
4765 sramecc = e_flags & EF_AMDGPU_FEATURE_SRAMECC_V4;
4766 switch (sramecc)
4767 {
4768 case EF_AMDGPU_FEATURE_SRAMECC_UNSUPPORTED_V4:
4769 break;
4770
4771 case EF_AMDGPU_FEATURE_SRAMECC_ANY_V4:
f8c4789c 4772 out = stpcpy (out, ", sramecc any");
c077c580
SM
4773 break;
4774
4775 case EF_AMDGPU_FEATURE_SRAMECC_OFF_V4:
f8c4789c 4776 out = stpcpy (out, ", sramecc off");
c077c580
SM
4777 break;
4778
4779 case EF_AMDGPU_FEATURE_SRAMECC_ON_V4:
f8c4789c 4780 out = stpcpy (out, ", sramecc on");
c077c580
SM
4781 break;
4782
4783 default:
f8c4789c 4784 out += sprintf (out, _(", <unknown sramecc value: %#x>"), sramecc);
c077c580
SM
4785 break;
4786 }
4787
c077c580
SM
4788 e_flags &= ~EF_AMDGPU_FEATURE_SRAMECC_V4;
4789 }
4790
4791 if (e_flags != 0)
f8c4789c
AM
4792 out += sprintf (out, _(", unknown flags bits: %#x"), e_flags);
4793 return out;
c077c580
SM
4794}
4795
252b5132 4796static char *
dda8d76d 4797get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 4798{
b34976b6 4799 static char buf[1024];
f8c4789c 4800 char *out = buf;
252b5132
RH
4801
4802 buf[0] = '\0';
76da6bbe 4803
252b5132
RH
4804 if (e_flags)
4805 {
4806 switch (e_machine)
4807 {
4808 default:
4809 break;
4810
b5c37946 4811 case EM_ARC_COMPACT3:
f8c4789c 4812 out = stpcpy (out, ", HS5x");
b5c37946
SJ
4813 break;
4814
4815 case EM_ARC_COMPACT3_64:
f8c4789c 4816 out = stpcpy (out, ", HS6x");
b5c37946
SJ
4817 break;
4818
886a2506 4819 case EM_ARC_COMPACT2:
886a2506 4820 case EM_ARC_COMPACT:
f8c4789c
AM
4821 out = decode_ARC_machine_flags (out, e_flags, e_machine);
4822 break;
886a2506 4823
f3485b74 4824 case EM_ARM:
f8c4789c 4825 out = decode_ARM_machine_flags (out, e_flags);
f3485b74 4826 break;
76da6bbe 4827
f8c4789c
AM
4828 case EM_AVR:
4829 out = decode_AVR_machine_flags (out, e_flags);
4830 break;
343433df 4831
781303ce 4832 case EM_BLACKFIN:
f8c4789c 4833 out = decode_BLACKFIN_machine_flags (out, e_flags);
781303ce
MF
4834 break;
4835
ec2dfb42 4836 case EM_CYGNUS_FRV:
f8c4789c 4837 out = decode_FRV_machine_flags (out, e_flags);
1c877e87 4838 break;
ec2dfb42 4839
53c7db4b 4840 case EM_68K:
f8c4789c 4841 out = decode_M68K_machine_flags (out, e_flags);
53c7db4b 4842 break;
33c63f9d 4843
c077c580 4844 case EM_AMDGPU:
f8c4789c 4845 out = decode_AMDGPU_machine_flags (out, e_flags, filedata);
c077c580
SM
4846 break;
4847
153a2776 4848 case EM_CYGNUS_MEP:
f8c4789c 4849 out = decode_MeP_machine_flags (out, e_flags);
153a2776
NC
4850 break;
4851
252b5132
RH
4852 case EM_PPC:
4853 if (e_flags & EF_PPC_EMB)
f8c4789c 4854 out = stpcpy (out, ", emb");
252b5132
RH
4855
4856 if (e_flags & EF_PPC_RELOCATABLE)
f8c4789c 4857 out = stpcpy (out, _(", relocatable"));
252b5132
RH
4858
4859 if (e_flags & EF_PPC_RELOCATABLE_LIB)
f8c4789c 4860 out = stpcpy (out, _(", relocatable-lib"));
252b5132
RH
4861 break;
4862
ee67d69a
AM
4863 case EM_PPC64:
4864 if (e_flags & EF_PPC64_ABI)
f8c4789c 4865 out += sprintf (out, ", abiv%d", e_flags & EF_PPC64_ABI);
ee67d69a
AM
4866 break;
4867
708e2187 4868 case EM_V800:
f8c4789c 4869 out = decode_V800_machine_flags (out, e_flags);
708e2187
NC
4870 break;
4871
2b0337b0 4872 case EM_V850:
252b5132 4873 case EM_CYGNUS_V850:
f8c4789c 4874 out = decode_V850_machine_flags (out, e_flags);
252b5132
RH
4875 break;
4876
2b0337b0 4877 case EM_M32R:
252b5132
RH
4878 case EM_CYGNUS_M32R:
4879 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
f8c4789c 4880 out = stpcpy (out, ", m32r");
252b5132
RH
4881 break;
4882
4883 case EM_MIPS:
4fe85591 4884 case EM_MIPS_RS3_LE:
f8c4789c 4885 out = decode_MIPS_machine_flags (out, e_flags);
252b5132 4886 break;
351b4b40 4887
35c08157 4888 case EM_NDS32:
f8c4789c 4889 out = decode_NDS32_machine_flags (out, e_flags);
35c08157
KLC
4890 break;
4891
fe944acf
FT
4892 case EM_NFP:
4893 switch (EF_NFP_MACH (e_flags))
4894 {
4895 case E_NFP_MACH_3200:
f8c4789c 4896 out = stpcpy (out, ", NFP-32xx");
fe944acf
FT
4897 break;
4898 case E_NFP_MACH_6000:
f8c4789c 4899 out = stpcpy (out, ", NFP-6xxx");
fe944acf
FT
4900 break;
4901 }
4902 break;
4903
e23eba97 4904 case EM_RISCV:
f8c4789c 4905 out = decode_RISCV_machine_flags (out, e_flags);
e23eba97
NC
4906 break;
4907
ccde1100 4908 case EM_SH:
f8c4789c 4909 out = decode_SH_machine_flags (out, e_flags);
ccde1100 4910 break;
948f632f 4911
f8c4789c
AM
4912 case EM_OR1K:
4913 if (e_flags & EF_OR1K_NODELAY)
4914 out = stpcpy (out, ", no delay");
4915 break;
57346661 4916
f8c4789c
AM
4917 case EM_BPF:
4918 out += sprintf (out, ", CPU Version: %u", e_flags & EF_BPF_CPUVER);
4919 break;
b5c37946 4920
351b4b40 4921 case EM_SPARCV9:
f8c4789c 4922 out = decode_SPARC_machine_flags (out, e_flags);
351b4b40 4923 break;
7d466069 4924
103f02d3 4925 case EM_PARISC:
f8c4789c 4926 out = decode_PARISC_machine_flags (out, e_flags);
30800947 4927 break;
76da6bbe 4928
7d466069 4929 case EM_PJ:
2b0337b0 4930 case EM_PJ_OLD:
7d466069 4931 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
f8c4789c 4932 out = stpcpy (out, ", new calling convention");
7d466069
ILT
4933
4934 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
f8c4789c 4935 out = stpcpy (out, ", gnu calling convention");
7d466069 4936 break;
4d6ed7c8
NC
4937
4938 case EM_IA_64:
f8c4789c 4939 out = decode_IA64_machine_flags (out, e_flags, filedata);
4d6ed7c8 4940 break;
179d3252
JT
4941
4942 case EM_VAX:
4943 if ((e_flags & EF_VAX_NONPIC))
f8c4789c 4944 out = stpcpy (out, ", non-PIC");
179d3252 4945 if ((e_flags & EF_VAX_DFLOAT))
f8c4789c 4946 out = stpcpy (out, ", D-Float");
179d3252 4947 if ((e_flags & EF_VAX_GFLOAT))
f8c4789c 4948 out = stpcpy (out, ", G-Float");
179d3252 4949 break;
c7927a3c 4950
f8c4789c 4951 case EM_VISIUM:
619ed720 4952 if (e_flags & EF_VISIUM_ARCH_MCM)
f8c4789c 4953 out = stpcpy (out, ", mcm");
619ed720 4954 else if (e_flags & EF_VISIUM_ARCH_MCM24)
f8c4789c 4955 out = stpcpy (out, ", mcm24");
619ed720 4956 if (e_flags & EF_VISIUM_ARCH_GR6)
f8c4789c 4957 out = stpcpy (out, ", gr6");
619ed720
EB
4958 break;
4959
4046d87a 4960 case EM_RL78:
f8c4789c 4961 out = decode_RL78_machine_flags (out, e_flags);
4046d87a 4962 break;
0b4362b0 4963
c7927a3c 4964 case EM_RX:
f8c4789c 4965 out = decode_RX_machine_flags (out, e_flags);
d4cb0ea0 4966 break;
55786da2
AK
4967
4968 case EM_S390:
4969 if (e_flags & EF_S390_HIGH_GPRS)
f8c4789c 4970 out = stpcpy (out, ", highgprs");
d4cb0ea0 4971 break;
40b36596
JM
4972
4973 case EM_TI_C6000:
4974 if ((e_flags & EF_C6000_REL))
f8c4789c 4975 out = stpcpy (out, ", relocatable module");
d4cb0ea0 4976 break;
13761a11 4977
6e712424
PI
4978 case EM_KVX:
4979 if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_1)
4980 strcat (buf, ", Kalray VLIW kv3-1");
4981 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV3_2)
4982 strcat (buf, ", Kalray VLIW kv3-2");
4983 else if ((e_flags & (ELF_KVX_CORE_MAJOR_MASK | ELF_KVX_CORE_MINOR_MASK)) == ELF_KVX_CORE_KV4_1)
4984 strcat (buf, ", Kalray VLIW kv4-1");
4985 else
4986 strcat (buf, ", unknown KVX MPPA");
4987 break;
4988
13761a11 4989 case EM_MSP430:
f8c4789c 4990 out = decode_MSP430_machine_flags (out, e_flags);
6655dba2
SB
4991 break;
4992
4993 case EM_Z80:
f8c4789c 4994 out = decode_Z80_machine_flags (out, e_flags);
6655dba2 4995 break;
c4a7e6b5 4996
f8c4789c
AM
4997 case EM_LOONGARCH:
4998 out = decode_LOONGARCH_machine_flags (out, e_flags);
e9a0721f 4999 break;
252b5132
RH
5000 }
5001 }
5002
5003 return buf;
5004}
5005
252b5132 5006static const char *
dda8d76d 5007get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
5008{
5009 static char buff[32];
5010
5011 switch (osabi)
5012 {
5013 case ELFOSABI_NONE: return "UNIX - System V";
5014 case ELFOSABI_HPUX: return "UNIX - HP-UX";
5015 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 5016 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
5017 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
5018 case ELFOSABI_AIX: return "UNIX - AIX";
5019 case ELFOSABI_IRIX: return "UNIX - IRIX";
5020 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
5021 case ELFOSABI_TRU64: return "UNIX - TRU64";
5022 case ELFOSABI_MODESTO: return "Novell - Modesto";
5023 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
5024 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
5025 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 5026 case ELFOSABI_AROS: return "AROS";
11636f9e 5027 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
5028 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
5029 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 5030 default:
40b36596 5031 if (osabi >= 64)
dda8d76d 5032 switch (filedata->file_header.e_machine)
40b36596 5033 {
37870be8
SM
5034 case EM_AMDGPU:
5035 switch (osabi)
5036 {
5037 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
5038 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
5039 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
5040 default:
5041 break;
5042 }
5043 break;
5044
40b36596
JM
5045 case EM_ARM:
5046 switch (osabi)
5047 {
5048 case ELFOSABI_ARM: return "ARM";
18a20338 5049 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
5050 default:
5051 break;
5052 }
5053 break;
5054
5055 case EM_MSP430:
5056 case EM_MSP430_OLD:
619ed720 5057 case EM_VISIUM:
40b36596
JM
5058 switch (osabi)
5059 {
5060 case ELFOSABI_STANDALONE: return _("Standalone App");
5061 default:
5062 break;
5063 }
5064 break;
5065
5066 case EM_TI_C6000:
5067 switch (osabi)
5068 {
5069 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
5070 case ELFOSABI_C6000_LINUX: return "Linux C6000";
5071 default:
5072 break;
5073 }
5074 break;
5075
5076 default:
5077 break;
5078 }
e9e44622 5079 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
5080 return buff;
5081 }
5082}
5083
a06ea964
NC
5084static const char *
5085get_aarch64_segment_type (unsigned long type)
5086{
5087 switch (type)
5088 {
32ec8896 5089 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
d0ff5ca9 5090 case PT_AARCH64_MEMTAG_MTE: return "AARCH64_MEMTAG_MTE";
32ec8896 5091 default: return NULL;
a06ea964 5092 }
a06ea964
NC
5093}
5094
b294bdf8
MM
5095static const char *
5096get_arm_segment_type (unsigned long type)
5097{
5098 switch (type)
5099 {
32ec8896
NC
5100 case PT_ARM_EXIDX: return "EXIDX";
5101 default: return NULL;
b294bdf8 5102 }
b294bdf8
MM
5103}
5104
b4cbbe8f
AK
5105static const char *
5106get_s390_segment_type (unsigned long type)
5107{
5108 switch (type)
5109 {
5110 case PT_S390_PGSTE: return "S390_PGSTE";
5111 default: return NULL;
5112 }
5113}
5114
d3ba0551
AM
5115static const char *
5116get_mips_segment_type (unsigned long type)
252b5132
RH
5117{
5118 switch (type)
5119 {
32ec8896
NC
5120 case PT_MIPS_REGINFO: return "REGINFO";
5121 case PT_MIPS_RTPROC: return "RTPROC";
5122 case PT_MIPS_OPTIONS: return "OPTIONS";
5123 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
5124 default: return NULL;
252b5132 5125 }
252b5132
RH
5126}
5127
103f02d3 5128static const char *
d3ba0551 5129get_parisc_segment_type (unsigned long type)
103f02d3
UD
5130{
5131 switch (type)
5132 {
103f02d3
UD
5133 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
5134 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 5135 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 5136 default: return NULL;
103f02d3 5137 }
103f02d3
UD
5138}
5139
4d6ed7c8 5140static const char *
d3ba0551 5141get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
5142{
5143 switch (type)
5144 {
5145 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
5146 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 5147 default: return NULL;
4d6ed7c8 5148 }
4d6ed7c8
NC
5149}
5150
40b36596
JM
5151static const char *
5152get_tic6x_segment_type (unsigned long type)
5153{
5154 switch (type)
5155 {
32ec8896
NC
5156 case PT_C6000_PHATTR: return "C6000_PHATTR";
5157 default: return NULL;
40b36596 5158 }
40b36596
JM
5159}
5160
fbc95f1e
KC
5161static const char *
5162get_riscv_segment_type (unsigned long type)
5163{
5164 switch (type)
5165 {
5166 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5167 default: return NULL;
5168 }
5169}
5170
df3a023b
AM
5171static const char *
5172get_hpux_segment_type (unsigned long type, unsigned e_machine)
5173{
5174 if (e_machine == EM_PARISC)
5175 switch (type)
5176 {
5177 case PT_HP_TLS: return "HP_TLS";
5178 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
5179 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
5180 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
5181 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
5182 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
5183 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
5184 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
5185 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
5186 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
5187 case PT_HP_PARALLEL: return "HP_PARALLEL";
5188 case PT_HP_FASTBIND: return "HP_FASTBIND";
5189 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
5190 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
5191 case PT_HP_STACK: return "HP_STACK";
5192 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
5193 default: return NULL;
5194 }
5195
5196 if (e_machine == EM_IA_64)
5197 switch (type)
5198 {
5199 case PT_HP_TLS: return "HP_TLS";
5200 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
5201 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
5202 case PT_IA_64_HP_STACK: return "HP_STACK";
5203 default: return NULL;
5204 }
5205
5206 return NULL;
5207}
5208
5522f910
NC
5209static const char *
5210get_solaris_segment_type (unsigned long type)
5211{
5212 switch (type)
5213 {
5214 case 0x6464e550: return "PT_SUNW_UNWIND";
5215 case 0x6474e550: return "PT_SUNW_EH_FRAME";
5216 case 0x6ffffff7: return "PT_LOSUNW";
5217 case 0x6ffffffa: return "PT_SUNWBSS";
5218 case 0x6ffffffb: return "PT_SUNWSTACK";
5219 case 0x6ffffffc: return "PT_SUNWDTRACE";
5220 case 0x6ffffffd: return "PT_SUNWCAP";
5221 case 0x6fffffff: return "PT_HISUNW";
32ec8896 5222 default: return NULL;
5522f910
NC
5223 }
5224}
5225
252b5132 5226static const char *
dda8d76d 5227get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 5228{
b34976b6 5229 static char buff[32];
252b5132
RH
5230
5231 switch (p_type)
5232 {
b34976b6
AM
5233 case PT_NULL: return "NULL";
5234 case PT_LOAD: return "LOAD";
252b5132 5235 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
5236 case PT_INTERP: return "INTERP";
5237 case PT_NOTE: return "NOTE";
5238 case PT_SHLIB: return "SHLIB";
5239 case PT_PHDR: return "PHDR";
13ae64f3 5240 case PT_TLS: return "TLS";
32ec8896 5241 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 5242 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 5243 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 5244 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
cf0e0a0b 5245 case PT_GNU_SFRAME: return "GNU_SFRAME";
65765700 5246
80251d41 5247 case PT_OPENBSD_MUTABLE: return "OPENBSD_MUTABLE";
3eba3ef3
NC
5248 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
5249 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
73b22419 5250 case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI";
d86205c3 5251 case PT_OPENBSD_SYSCALLS: return "OPENBSD_SYSCALLS";
3eba3ef3 5252 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 5253
252b5132 5254 default:
df3a023b 5255 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 5256 {
2cf0635d 5257 const char * result;
103f02d3 5258
dda8d76d 5259 switch (filedata->file_header.e_machine)
252b5132 5260 {
a06ea964
NC
5261 case EM_AARCH64:
5262 result = get_aarch64_segment_type (p_type);
5263 break;
b294bdf8
MM
5264 case EM_ARM:
5265 result = get_arm_segment_type (p_type);
5266 break;
252b5132 5267 case EM_MIPS:
4fe85591 5268 case EM_MIPS_RS3_LE:
252b5132
RH
5269 result = get_mips_segment_type (p_type);
5270 break;
103f02d3
UD
5271 case EM_PARISC:
5272 result = get_parisc_segment_type (p_type);
5273 break;
4d6ed7c8
NC
5274 case EM_IA_64:
5275 result = get_ia64_segment_type (p_type);
5276 break;
40b36596
JM
5277 case EM_TI_C6000:
5278 result = get_tic6x_segment_type (p_type);
5279 break;
b4cbbe8f
AK
5280 case EM_S390:
5281 case EM_S390_OLD:
5282 result = get_s390_segment_type (p_type);
5283 break;
fbc95f1e
KC
5284 case EM_RISCV:
5285 result = get_riscv_segment_type (p_type);
5286 break;
252b5132
RH
5287 default:
5288 result = NULL;
5289 break;
5290 }
103f02d3 5291
252b5132
RH
5292 if (result != NULL)
5293 return result;
103f02d3 5294
1a9ccd70 5295 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
5296 }
5297 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 5298 {
df3a023b 5299 const char * result = NULL;
103f02d3 5300
df3a023b 5301 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 5302 {
df3a023b
AM
5303 case ELFOSABI_GNU:
5304 case ELFOSABI_FREEBSD:
5305 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
5306 {
5307 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
5308 result = buff;
5309 }
103f02d3 5310 break;
df3a023b
AM
5311 case ELFOSABI_HPUX:
5312 result = get_hpux_segment_type (p_type,
5313 filedata->file_header.e_machine);
5314 break;
5315 case ELFOSABI_SOLARIS:
5316 result = get_solaris_segment_type (p_type);
00428cca 5317 break;
103f02d3 5318 default:
103f02d3
UD
5319 break;
5320 }
103f02d3
UD
5321 if (result != NULL)
5322 return result;
5323
1a9ccd70 5324 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 5325 }
252b5132 5326 else
e9e44622 5327 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
5328
5329 return buff;
5330 }
5331}
5332
53a346d8
CZ
5333static const char *
5334get_arc_section_type_name (unsigned int sh_type)
5335{
5336 switch (sh_type)
5337 {
5338 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
5339 default:
5340 break;
5341 }
5342 return NULL;
5343}
5344
252b5132 5345static const char *
d3ba0551 5346get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
5347{
5348 switch (sh_type)
5349 {
b34976b6
AM
5350 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
5351 case SHT_MIPS_MSYM: return "MIPS_MSYM";
5352 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
5353 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
5354 case SHT_MIPS_UCODE: return "MIPS_UCODE";
5355 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
5356 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
5357 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
5358 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
5359 case SHT_MIPS_RELD: return "MIPS_RELD";
5360 case SHT_MIPS_IFACE: return "MIPS_IFACE";
5361 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
5362 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
5363 case SHT_MIPS_SHDR: return "MIPS_SHDR";
5364 case SHT_MIPS_FDESC: return "MIPS_FDESC";
5365 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
5366 case SHT_MIPS_DENSE: return "MIPS_DENSE";
5367 case SHT_MIPS_PDESC: return "MIPS_PDESC";
5368 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
5369 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
5370 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
5371 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
5372 case SHT_MIPS_LINE: return "MIPS_LINE";
5373 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
5374 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
5375 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
5376 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
5377 case SHT_MIPS_DWARF: return "MIPS_DWARF";
5378 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
5379 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
5380 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
5381 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
5382 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
5383 case SHT_MIPS_XLATE: return "MIPS_XLATE";
5384 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
5385 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
5386 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
5387 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 5388 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 5389 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 5390 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
5391 default:
5392 break;
5393 }
5394 return NULL;
5395}
5396
103f02d3 5397static const char *
d3ba0551 5398get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
5399{
5400 switch (sh_type)
5401 {
5402 case SHT_PARISC_EXT: return "PARISC_EXT";
5403 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
5404 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
5405 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
5406 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
5407 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 5408 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 5409 default: return NULL;
103f02d3 5410 }
103f02d3
UD
5411}
5412
4d6ed7c8 5413static const char *
dda8d76d 5414get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 5415{
18bd398b 5416 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 5417 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 5418 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 5419
4d6ed7c8
NC
5420 switch (sh_type)
5421 {
148b93f2
NC
5422 case SHT_IA_64_EXT: return "IA_64_EXT";
5423 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
5424 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
5425 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
5426 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
5427 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
5428 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
5429 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
5430 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
5431 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
5432 default:
5433 break;
5434 }
5435 return NULL;
5436}
5437
d2b2c203
DJ
5438static const char *
5439get_x86_64_section_type_name (unsigned int sh_type)
5440{
5441 switch (sh_type)
5442 {
5443 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 5444 default: return NULL;
d2b2c203 5445 }
d2b2c203
DJ
5446}
5447
a06ea964
NC
5448static const char *
5449get_aarch64_section_type_name (unsigned int sh_type)
5450{
5451 switch (sh_type)
5452 {
32ec8896
NC
5453 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
5454 default: return NULL;
a06ea964 5455 }
a06ea964
NC
5456}
5457
40a18ebd
NC
5458static const char *
5459get_arm_section_type_name (unsigned int sh_type)
5460{
5461 switch (sh_type)
5462 {
7f6fed87
NC
5463 case SHT_ARM_EXIDX: return "ARM_EXIDX";
5464 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
5465 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
5466 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
5467 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 5468 default: return NULL;
40a18ebd 5469 }
40a18ebd
NC
5470}
5471
40b36596
JM
5472static const char *
5473get_tic6x_section_type_name (unsigned int sh_type)
5474{
5475 switch (sh_type)
5476 {
32ec8896
NC
5477 case SHT_C6000_UNWIND: return "C6000_UNWIND";
5478 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
5479 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
5480 case SHT_TI_ICODE: return "TI_ICODE";
5481 case SHT_TI_XREF: return "TI_XREF";
5482 case SHT_TI_HANDLER: return "TI_HANDLER";
5483 case SHT_TI_INITINFO: return "TI_INITINFO";
5484 case SHT_TI_PHATTRS: return "TI_PHATTRS";
5485 default: return NULL;
40b36596 5486 }
40b36596
JM
5487}
5488
13761a11 5489static const char *
b0191216 5490get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
5491{
5492 switch (sh_type)
5493 {
32ec8896
NC
5494 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
5495 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
5496 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
5497 default: return NULL;
13761a11
NC
5498 }
5499}
5500
fe944acf
FT
5501static const char *
5502get_nfp_section_type_name (unsigned int sh_type)
5503{
5504 switch (sh_type)
5505 {
5506 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
5507 case SHT_NFP_INITREG: return "NFP_INITREG";
5508 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
5509 default: return NULL;
5510 }
5511}
5512
685080f2
NC
5513static const char *
5514get_v850_section_type_name (unsigned int sh_type)
5515{
5516 switch (sh_type)
5517 {
32ec8896
NC
5518 case SHT_V850_SCOMMON: return "V850 Small Common";
5519 case SHT_V850_TCOMMON: return "V850 Tiny Common";
5520 case SHT_V850_ZCOMMON: return "V850 Zero Common";
5521 case SHT_RENESAS_IOP: return "RENESAS IOP";
5522 case SHT_RENESAS_INFO: return "RENESAS INFO";
5523 default: return NULL;
685080f2
NC
5524 }
5525}
5526
2dc8dd17
JW
5527static const char *
5528get_riscv_section_type_name (unsigned int sh_type)
5529{
5530 switch (sh_type)
5531 {
5532 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
5533 default: return NULL;
5534 }
5535}
5536
0861f561
CQ
5537static const char *
5538get_csky_section_type_name (unsigned int sh_type)
5539{
5540 switch (sh_type)
5541 {
5542 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
5543 default: return NULL;
5544 }
5545}
5546
252b5132 5547static const char *
dda8d76d 5548get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 5549{
b34976b6 5550 static char buff[32];
9fb71ee4 5551 const char * result;
252b5132
RH
5552
5553 switch (sh_type)
5554 {
5555 case SHT_NULL: return "NULL";
5556 case SHT_PROGBITS: return "PROGBITS";
5557 case SHT_SYMTAB: return "SYMTAB";
5558 case SHT_STRTAB: return "STRTAB";
5559 case SHT_RELA: return "RELA";
5560 case SHT_HASH: return "HASH";
5561 case SHT_DYNAMIC: return "DYNAMIC";
5562 case SHT_NOTE: return "NOTE";
5563 case SHT_NOBITS: return "NOBITS";
5564 case SHT_REL: return "REL";
5565 case SHT_SHLIB: return "SHLIB";
5566 case SHT_DYNSYM: return "DYNSYM";
8e8d0b63 5567 /* 12 and 13 are not defined. */
d1133906
NC
5568 case SHT_INIT_ARRAY: return "INIT_ARRAY";
5569 case SHT_FINI_ARRAY: return "FINI_ARRAY";
5570 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
93ebe586 5571 case SHT_GROUP: return "GROUP";
67ce483b 5572 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
8e8d0b63
NC
5573 case SHT_RELR: return "RELR";
5574 /* End of generic section types. */
5575
5576 /* OS specific section types: */
252b5132
RH
5577 case SHT_GNU_verdef: return "VERDEF";
5578 case SHT_GNU_verneed: return "VERNEED";
5579 case SHT_GNU_versym: return "VERSYM";
8e8d0b63 5580 case SHT_GNU_INCREMENTAL_INPUTS: return "GNU_INCREMENTAL_INPUTS";
b34976b6 5581 case 0x6ffffff0: return "VERSYM";
8e8d0b63
NC
5582 case SHT_GNU_ATTRIBUTES: return "GNU_ATTRIBUTES";
5583 case SHT_GNU_HASH: return "GNU_HASH";
5584 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
b34976b6 5585 case 0x6ffffffc: return "VERDEF";
252b5132
RH
5586 case 0x7ffffffd: return "AUXILIARY";
5587 case 0x7fffffff: return "FILTER";
5588
5589 default:
5590 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
5591 {
dda8d76d 5592 switch (filedata->file_header.e_machine)
252b5132 5593 {
53a346d8
CZ
5594 case EM_ARC:
5595 case EM_ARC_COMPACT:
5596 case EM_ARC_COMPACT2:
b5c37946
SJ
5597 case EM_ARC_COMPACT3:
5598 case EM_ARC_COMPACT3_64:
53a346d8
CZ
5599 result = get_arc_section_type_name (sh_type);
5600 break;
252b5132 5601 case EM_MIPS:
4fe85591 5602 case EM_MIPS_RS3_LE:
252b5132
RH
5603 result = get_mips_section_type_name (sh_type);
5604 break;
103f02d3
UD
5605 case EM_PARISC:
5606 result = get_parisc_section_type_name (sh_type);
5607 break;
4d6ed7c8 5608 case EM_IA_64:
dda8d76d 5609 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 5610 break;
d2b2c203 5611 case EM_X86_64:
8a9036a4 5612 case EM_L1OM:
7a9068fe 5613 case EM_K1OM:
d2b2c203
DJ
5614 result = get_x86_64_section_type_name (sh_type);
5615 break;
a06ea964
NC
5616 case EM_AARCH64:
5617 result = get_aarch64_section_type_name (sh_type);
5618 break;
40a18ebd
NC
5619 case EM_ARM:
5620 result = get_arm_section_type_name (sh_type);
5621 break;
40b36596
JM
5622 case EM_TI_C6000:
5623 result = get_tic6x_section_type_name (sh_type);
5624 break;
13761a11 5625 case EM_MSP430:
b0191216 5626 result = get_msp430_section_type_name (sh_type);
13761a11 5627 break;
fe944acf
FT
5628 case EM_NFP:
5629 result = get_nfp_section_type_name (sh_type);
5630 break;
685080f2
NC
5631 case EM_V800:
5632 case EM_V850:
5633 case EM_CYGNUS_V850:
5634 result = get_v850_section_type_name (sh_type);
5635 break;
2dc8dd17
JW
5636 case EM_RISCV:
5637 result = get_riscv_section_type_name (sh_type);
5638 break;
0861f561
CQ
5639 case EM_CSKY:
5640 result = get_csky_section_type_name (sh_type);
5641 break;
252b5132
RH
5642 default:
5643 result = NULL;
5644 break;
5645 }
5646
5647 if (result != NULL)
5648 return result;
5649
9fb71ee4 5650 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
5651 }
5652 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 5653 {
dda8d76d 5654 switch (filedata->file_header.e_machine)
148b93f2
NC
5655 {
5656 case EM_IA_64:
dda8d76d 5657 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
5658 break;
5659 default:
dda8d76d 5660 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
5661 result = get_solaris_section_type (sh_type);
5662 else
1b4b80bf
NC
5663 {
5664 switch (sh_type)
5665 {
5666 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
5667 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
5668 case SHT_GNU_HASH: result = "GNU_HASH"; break;
5669 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
5670 default:
5671 result = NULL;
5672 break;
5673 }
5674 }
148b93f2
NC
5675 break;
5676 }
5677
5678 if (result != NULL)
5679 return result;
5680
9fb71ee4 5681 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 5682 }
252b5132 5683 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 5684 {
dda8d76d 5685 switch (filedata->file_header.e_machine)
685080f2
NC
5686 {
5687 case EM_V800:
5688 case EM_V850:
5689 case EM_CYGNUS_V850:
9fb71ee4 5690 result = get_v850_section_type_name (sh_type);
a9fb83be 5691 break;
685080f2 5692 default:
9fb71ee4 5693 result = NULL;
685080f2
NC
5694 break;
5695 }
5696
9fb71ee4
NC
5697 if (result != NULL)
5698 return result;
5699
5700 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 5701 }
252b5132 5702 else
a7dbfd1c
NC
5703 /* This message is probably going to be displayed in a 15
5704 character wide field, so put the hex value first. */
5705 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 5706
252b5132
RH
5707 return buff;
5708 }
5709}
5710
79bc120c
NC
5711enum long_option_values
5712{
5713 OPTION_DEBUG_DUMP = 512,
5714 OPTION_DYN_SYMS,
0f03783c 5715 OPTION_LTO_SYMS,
79bc120c
NC
5716 OPTION_DWARF_DEPTH,
5717 OPTION_DWARF_START,
5718 OPTION_DWARF_CHECK,
5719 OPTION_CTF_DUMP,
5720 OPTION_CTF_PARENT,
5721 OPTION_CTF_SYMBOLS,
5722 OPTION_CTF_STRINGS,
42b6953b 5723 OPTION_SFRAME_DUMP,
79bc120c
NC
5724 OPTION_WITH_SYMBOL_VERSIONS,
5725 OPTION_RECURSE_LIMIT,
5726 OPTION_NO_RECURSE_LIMIT,
047c3dbf 5727 OPTION_NO_DEMANGLING,
b6ac461a 5728 OPTION_NO_EXTRA_SYM_INFO,
047c3dbf 5729 OPTION_SYM_BASE
79bc120c 5730};
2979dc34 5731
85b1c36d 5732static struct option options[] =
252b5132 5733{
79bc120c
NC
5734 /* Note - This table is alpha-sorted on the 'val'
5735 field in order to make adding new options easier. */
5736 {"arch-specific", no_argument, 0, 'A'},
b34976b6 5737 {"all", no_argument, 0, 'a'},
79bc120c
NC
5738 {"demangle", optional_argument, 0, 'C'},
5739 {"archive-index", no_argument, 0, 'c'},
5740 {"use-dynamic", no_argument, 0, 'D'},
5741 {"dynamic", no_argument, 0, 'd'},
b34976b6 5742 {"headers", no_argument, 0, 'e'},
79bc120c
NC
5743 {"section-groups", no_argument, 0, 'g'},
5744 {"help", no_argument, 0, 'H'},
5745 {"file-header", no_argument, 0, 'h'},
b34976b6 5746 {"histogram", no_argument, 0, 'I'},
8e8d0b63 5747 {"display-section", required_argument, 0, 'j'},
79bc120c
NC
5748 {"lint", no_argument, 0, 'L'},
5749 {"enable-checks", no_argument, 0, 'L'},
5750 {"program-headers", no_argument, 0, 'l'},
b34976b6 5751 {"segments", no_argument, 0, 'l'},
595cf52e 5752 {"full-section-name",no_argument, 0, 'N'},
79bc120c 5753 {"notes", no_argument, 0, 'n'},
ca0e11aa 5754 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
5755 {"string-dump", required_argument, 0, 'p'},
5756 {"relocated-dump", required_argument, 0, 'R'},
5757 {"relocs", no_argument, 0, 'r'},
5758 {"section-headers", no_argument, 0, 'S'},
5759 {"sections", no_argument, 0, 'S'},
b34976b6
AM
5760 {"symbols", no_argument, 0, 's'},
5761 {"syms", no_argument, 0, 's'},
79bc120c
NC
5762 {"silent-truncation",no_argument, 0, 'T'},
5763 {"section-details", no_argument, 0, 't'},
b3aa80b4 5764 {"unicode", required_argument, NULL, 'U'},
09c11c86 5765 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5766 {"version-info", no_argument, 0, 'V'},
5767 {"version", no_argument, 0, 'v'},
5768 {"wide", no_argument, 0, 'W'},
b6ac461a 5769 {"extra-sym-info", no_argument, 0, 'X'},
b34976b6 5770 {"hex-dump", required_argument, 0, 'x'},
0e602686 5771 {"decompress", no_argument, 0, 'z'},
252b5132 5772
79bc120c 5773 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
b6ac461a 5774 {"no-extra-sym-info",no_argument, 0, OPTION_NO_EXTRA_SYM_INFO},
79bc120c
NC
5775 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5776 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5777 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5778 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5779 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5780 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5781 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5782 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5783 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5784#ifdef ENABLE_LIBCTF
d344b407 5785 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5786 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5787 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5788 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5789#endif
42b6953b 5790 {"sframe", optional_argument, 0, OPTION_SFRAME_DUMP},
047c3dbf 5791 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5792
b34976b6 5793 {0, no_argument, 0, 0}
252b5132
RH
5794};
5795
5796static void
2cf0635d 5797usage (FILE * stream)
252b5132 5798{
92f01d61
JM
5799 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5800 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5801 fprintf (stream, _(" Options are:\n"));
5802 fprintf (stream, _("\
5803 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5804 fprintf (stream, _("\
5805 -h --file-header Display the ELF file header\n"));
5806 fprintf (stream, _("\
5807 -l --program-headers Display the program headers\n"));
5808 fprintf (stream, _("\
5809 --segments An alias for --program-headers\n"));
5810 fprintf (stream, _("\
5811 -S --section-headers Display the sections' header\n"));
5812 fprintf (stream, _("\
5813 --sections An alias for --section-headers\n"));
5814 fprintf (stream, _("\
5815 -g --section-groups Display the section groups\n"));
5816 fprintf (stream, _("\
5817 -t --section-details Display the section details\n"));
5818 fprintf (stream, _("\
5819 -e --headers Equivalent to: -h -l -S\n"));
5820 fprintf (stream, _("\
5821 -s --syms Display the symbol table\n"));
5822 fprintf (stream, _("\
5823 --symbols An alias for --syms\n"));
5824 fprintf (stream, _("\
5825 --dyn-syms Display the dynamic symbol table\n"));
5826 fprintf (stream, _("\
5827 --lto-syms Display LTO symbol tables\n"));
5828 fprintf (stream, _("\
047c3dbf
NL
5829 --sym-base=[0|8|10|16] \n\
5830 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5831 mixed (the default), octal, decimal, hexadecimal.\n"));
5832 fprintf (stream, _("\
0d646226
AM
5833 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5834 display_demangler_styles (stream, _("\
5835 STYLE can be "));
d6249f5f
AM
5836 fprintf (stream, _("\
5837 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5838 fprintf (stream, _("\
5839 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5840 fprintf (stream, _("\
5841 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5842 fprintf (stream, _("\
5843 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5844 Display unicode characters as determined by the current locale\n\
5845 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5846 escape sequences, or treat them as invalid and display as\n\
5847 \"{hex sequences}\"\n"));
d6249f5f 5848 fprintf (stream, _("\
b6ac461a
NC
5849 -X --extra-sym-info Display extra information when showing symbols\n"));
5850 fprintf (stream, _("\
5851 --no-extra-sym-info Do not display extra information when showing symbols (default)\n"));
5852 fprintf (stream, _("\
5853 -n --notes Display the contents of note sections (if present)\n"));
d6249f5f
AM
5854 fprintf (stream, _("\
5855 -r --relocs Display the relocations (if present)\n"));
5856 fprintf (stream, _("\
5857 -u --unwind Display the unwind info (if present)\n"));
5858 fprintf (stream, _("\
5859 -d --dynamic Display the dynamic section (if present)\n"));
5860 fprintf (stream, _("\
5861 -V --version-info Display the version sections (if present)\n"));
5862 fprintf (stream, _("\
5863 -A --arch-specific Display architecture specific information (if any)\n"));
5864 fprintf (stream, _("\
5865 -c --archive-index Display the symbol/file index in an archive\n"));
5866 fprintf (stream, _("\
5867 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5868 fprintf (stream, _("\
5869 -L --lint|--enable-checks\n\
5870 Display warning messages for possible problems\n"));
5871 fprintf (stream, _("\
09c11c86 5872 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5873 Dump the contents of section <number|name> as bytes\n"));
5874 fprintf (stream, _("\
09c11c86 5875 -p --string-dump=<number|name>\n\
d6249f5f
AM
5876 Dump the contents of section <number|name> as strings\n"));
5877 fprintf (stream, _("\
cf13d699 5878 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5879 Dump the relocated contents of section <number|name>\n"));
5880 fprintf (stream, _("\
5881 -z --decompress Decompress section before dumping it\n"));
8e8d0b63
NC
5882 fprintf (stream, _("\n\
5883 -j --display-section=<name|number>\n\
5884 Display the contents of the indicated section. Can be repeated\n"));
d6249f5f
AM
5885 fprintf (stream, _("\
5886 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5887 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5888 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5889 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5890 U/=trace_info]\n\
5891 Display the contents of DWARF debug sections\n"));
5892 fprintf (stream, _("\
5893 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5894 debuginfo files\n"));
5895 fprintf (stream, _("\
5896 -P --process-links Display the contents of non-debug sections in separate\n\
5897 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5898#if DEFAULT_FOR_FOLLOW_LINKS
5899 fprintf (stream, _("\
d6249f5f
AM
5900 -wK --debug-dump=follow-links\n\
5901 Follow links to separate debug info files (default)\n"));
5902 fprintf (stream, _("\
5903 -wN --debug-dump=no-follow-links\n\
5904 Do not follow links to separate debug info files\n"));
c46b7066
NC
5905#else
5906 fprintf (stream, _("\
d6249f5f
AM
5907 -wK --debug-dump=follow-links\n\
5908 Follow links to separate debug info files\n"));
5909 fprintf (stream, _("\
5910 -wN --debug-dump=no-follow-links\n\
5911 Do not follow links to separate debug info files\n\
5912 (default)\n"));
bed566bb
NC
5913#endif
5914#if HAVE_LIBDEBUGINFOD
5915 fprintf (stream, _("\
5916 -wD --debug-dump=use-debuginfod\n\
5917 When following links, also query debuginfod servers (default)\n"));
5918 fprintf (stream, _("\
5919 -wE --debug-dump=do-not-use-debuginfod\n\
5920 When following links, do not query debuginfod servers\n"));
c46b7066 5921#endif
fd2f0033 5922 fprintf (stream, _("\
d6249f5f
AM
5923 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5924 fprintf (stream, _("\
5925 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5926#ifdef ENABLE_LIBCTF
7d9813f1 5927 fprintf (stream, _("\
d6249f5f
AM
5928 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5929 fprintf (stream, _("\
80b56fad 5930 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5931 fprintf (stream, _("\
7d9813f1 5932 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5933 Use section <number|name> as the CTF external symtab\n"));
5934 fprintf (stream, _("\
7d9813f1 5935 --ctf-strings=<number|name>\n\
d6249f5f 5936 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5937#endif
42b6953b
IB
5938 fprintf (stream, _("\
5939 --sframe[=NAME] Display SFrame info from section NAME, (default '.sframe')\n"));
7d9813f1 5940
252b5132 5941#ifdef SUPPORT_DISASSEMBLY
92f01d61 5942 fprintf (stream, _("\
09c11c86
NC
5943 -i --instruction-dump=<number|name>\n\
5944 Disassemble the contents of section <number|name>\n"));
252b5132 5945#endif
92f01d61 5946 fprintf (stream, _("\
d6249f5f
AM
5947 -I --histogram Display histogram of bucket list lengths\n"));
5948 fprintf (stream, _("\
5949 -W --wide Allow output width to exceed 80 characters\n"));
5950 fprintf (stream, _("\
5951 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5952 fprintf (stream, _("\
5953 @<file> Read options from <file>\n"));
5954 fprintf (stream, _("\
5955 -H --help Display this information\n"));
5956 fprintf (stream, _("\
8b53311e 5957 -v --version Display the version number of readelf\n"));
1118d252 5958
92f01d61
JM
5959 if (REPORT_BUGS_TO[0] && stream == stdout)
5960 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5961
92f01d61 5962 exit (stream == stdout ? 0 : 1);
252b5132
RH
5963}
5964
18bd398b
NC
5965/* Record the fact that the user wants the contents of section number
5966 SECTION to be displayed using the method(s) encoded as flags bits
5967 in TYPE. Note, TYPE can be zero if we are creating the array for
5968 the first time. */
5969
252b5132 5970static void
6431e409
AM
5971request_dump_bynumber (struct dump_data *dumpdata,
5972 unsigned int section, dump_type type)
252b5132 5973{
6431e409 5974 if (section >= dumpdata->num_dump_sects)
252b5132 5975 {
2cf0635d 5976 dump_type * new_dump_sects;
252b5132 5977
3f5e193b 5978 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5979 sizeof (* new_dump_sects));
252b5132
RH
5980
5981 if (new_dump_sects == NULL)
591a748a 5982 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5983 else
5984 {
6431e409 5985 if (dumpdata->dump_sects)
21b65bac
NC
5986 {
5987 /* Copy current flag settings. */
6431e409
AM
5988 memcpy (new_dump_sects, dumpdata->dump_sects,
5989 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5990
6431e409 5991 free (dumpdata->dump_sects);
21b65bac 5992 }
252b5132 5993
6431e409
AM
5994 dumpdata->dump_sects = new_dump_sects;
5995 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5996 }
5997 }
5998
6431e409
AM
5999 if (dumpdata->dump_sects)
6000 dumpdata->dump_sects[section] |= type;
252b5132
RH
6001}
6002
aef1f6d0
DJ
6003/* Request a dump by section name. */
6004
6005static void
2cf0635d 6006request_dump_byname (const char * section, dump_type type)
aef1f6d0 6007{
2cf0635d 6008 struct dump_list_entry * new_request;
aef1f6d0 6009
3f5e193b
NC
6010 new_request = (struct dump_list_entry *)
6011 malloc (sizeof (struct dump_list_entry));
aef1f6d0 6012 if (!new_request)
591a748a 6013 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6014
6015 new_request->name = strdup (section);
6016 if (!new_request->name)
591a748a 6017 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
6018
6019 new_request->type = type;
6020
6021 new_request->next = dump_sects_byname;
6022 dump_sects_byname = new_request;
6023}
6024
cf13d699 6025static inline void
6431e409 6026request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
6027{
6028 int section;
6029 char * cp;
6030
015dc7e1 6031 do_dump = true;
cf13d699
NC
6032 section = strtoul (optarg, & cp, 0);
6033
6034 if (! *cp && section >= 0)
6431e409 6035 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
6036 else
6037 request_dump_byname (optarg, type);
6038}
6039
252b5132 6040static void
6431e409 6041parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
6042{
6043 int c;
6044
6045 if (argc < 2)
92f01d61 6046 usage (stderr);
252b5132
RH
6047
6048 while ((c = getopt_long
8e8d0b63 6049 (argc, argv, "ACDHILNPR:STU:VWXacdeghi:j:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 6050 {
252b5132
RH
6051 switch (c)
6052 {
6053 case 0:
6054 /* Long options. */
6055 break;
6056 case 'H':
92f01d61 6057 usage (stdout);
252b5132
RH
6058 break;
6059
6060 case 'a':
015dc7e1
AM
6061 do_syms = true;
6062 do_reloc = true;
6063 do_unwind = true;
6064 do_dynamic = true;
6065 do_header = true;
6066 do_sections = true;
6067 do_section_groups = true;
6068 do_segments = true;
6069 do_version = true;
6070 do_histogram = true;
6071 do_arch = true;
6072 do_notes = true;
252b5132 6073 break;
79bc120c 6074
f5842774 6075 case 'g':
015dc7e1 6076 do_section_groups = true;
f5842774 6077 break;
5477e8a0 6078 case 't':
595cf52e 6079 case 'N':
015dc7e1
AM
6080 do_sections = true;
6081 do_section_details = true;
595cf52e 6082 break;
252b5132 6083 case 'e':
015dc7e1
AM
6084 do_header = true;
6085 do_sections = true;
6086 do_segments = true;
252b5132 6087 break;
a952a375 6088 case 'A':
015dc7e1 6089 do_arch = true;
a952a375 6090 break;
252b5132 6091 case 'D':
015dc7e1 6092 do_using_dynamic = true;
252b5132
RH
6093 break;
6094 case 'r':
015dc7e1 6095 do_reloc = true;
252b5132 6096 break;
4d6ed7c8 6097 case 'u':
015dc7e1 6098 do_unwind = true;
4d6ed7c8 6099 break;
252b5132 6100 case 'h':
015dc7e1 6101 do_header = true;
252b5132
RH
6102 break;
6103 case 'l':
015dc7e1 6104 do_segments = true;
252b5132
RH
6105 break;
6106 case 's':
015dc7e1 6107 do_syms = true;
252b5132
RH
6108 break;
6109 case 'S':
015dc7e1 6110 do_sections = true;
252b5132
RH
6111 break;
6112 case 'd':
015dc7e1 6113 do_dynamic = true;
252b5132 6114 break;
a952a375 6115 case 'I':
015dc7e1 6116 do_histogram = true;
a952a375 6117 break;
779fe533 6118 case 'n':
015dc7e1 6119 do_notes = true;
779fe533 6120 break;
4145f1d5 6121 case 'c':
015dc7e1 6122 do_archive_index = true;
4145f1d5 6123 break;
1b513401 6124 case 'L':
015dc7e1 6125 do_checks = true;
1b513401 6126 break;
ca0e11aa 6127 case 'P':
015dc7e1
AM
6128 process_links = true;
6129 do_follow_links = true;
e1dbfc17 6130 dump_any_debugging = true;
ca0e11aa 6131 break;
8e8d0b63
NC
6132 case 'j':
6133 request_dump (dumpdata, AUTO_DUMP);
6134 break;
252b5132 6135 case 'x':
6431e409 6136 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 6137 break;
09c11c86 6138 case 'p':
6431e409 6139 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
6140 break;
6141 case 'R':
6431e409 6142 request_dump (dumpdata, RELOC_DUMP);
09c11c86 6143 break;
0e602686 6144 case 'z':
015dc7e1 6145 decompress_dumps = true;
0e602686 6146 break;
252b5132 6147 case 'w':
0f03783c 6148 if (optarg == NULL)
613ff48b 6149 {
015dc7e1 6150 do_debugging = true;
94585d6d
NC
6151 do_dump = true;
6152 dump_any_debugging = true;
613ff48b
CC
6153 dwarf_select_sections_all ();
6154 }
252b5132
RH
6155 else
6156 {
015dc7e1 6157 do_debugging = false;
94585d6d
NC
6158 if (dwarf_select_sections_by_letters (optarg))
6159 {
6160 do_dump = true;
6161 dump_any_debugging = true;
6162 }
252b5132
RH
6163 }
6164 break;
2979dc34 6165 case OPTION_DEBUG_DUMP:
0f03783c 6166 if (optarg == NULL)
d6249f5f 6167 {
94585d6d 6168 do_dump = true;
d6249f5f 6169 do_debugging = true;
94585d6d 6170 dump_any_debugging = true;
d6249f5f
AM
6171 dwarf_select_sections_all ();
6172 }
2979dc34
JJ
6173 else
6174 {
015dc7e1 6175 do_debugging = false;
94585d6d
NC
6176 if (dwarf_select_sections_by_names (optarg))
6177 {
6178 do_dump = true;
6179 dump_any_debugging = true;
6180 }
2979dc34
JJ
6181 }
6182 break;
fd2f0033
TT
6183 case OPTION_DWARF_DEPTH:
6184 {
6185 char *cp;
6186
6187 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
6188 }
6189 break;
6190 case OPTION_DWARF_START:
6191 {
6192 char *cp;
6193
6194 dwarf_start_die = strtoul (optarg, & cp, 0);
6195 }
6196 break;
4723351a 6197 case OPTION_DWARF_CHECK:
015dc7e1 6198 dwarf_check = true;
4723351a 6199 break;
7d9813f1 6200 case OPTION_CTF_DUMP:
015dc7e1 6201 do_ctf = true;
6431e409 6202 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
6203 break;
6204 case OPTION_CTF_SYMBOLS:
df16e041 6205 free (dump_ctf_symtab_name);
7d9813f1
NA
6206 dump_ctf_symtab_name = strdup (optarg);
6207 break;
6208 case OPTION_CTF_STRINGS:
df16e041 6209 free (dump_ctf_strtab_name);
7d9813f1
NA
6210 dump_ctf_strtab_name = strdup (optarg);
6211 break;
6212 case OPTION_CTF_PARENT:
df16e041 6213 free (dump_ctf_parent_name);
7d9813f1
NA
6214 dump_ctf_parent_name = strdup (optarg);
6215 break;
42b6953b
IB
6216 case OPTION_SFRAME_DUMP:
6217 do_sframe = true;
6218 /* Providing section name is optional. request_dump (), however,
6219 thrives on non NULL optarg. Handle it explicitly here. */
6220 if (optarg != NULL)
6221 request_dump (dumpdata, SFRAME_DUMP);
6222 else
6223 {
6224 do_dump = true;
6225 const char *sframe_sec_name = strdup (".sframe");
6226 request_dump_byname (sframe_sec_name, SFRAME_DUMP);
6227 }
6228 break;
2c610e4b 6229 case OPTION_DYN_SYMS:
015dc7e1 6230 do_dyn_syms = true;
2c610e4b 6231 break;
0f03783c 6232 case OPTION_LTO_SYMS:
015dc7e1 6233 do_lto_syms = true;
0f03783c 6234 break;
b6ac461a
NC
6235 case 'X':
6236 extra_sym_info = true;
6237 break;
6238 case OPTION_NO_EXTRA_SYM_INFO:
6239 extra_sym_info = false;
6240 break;
6241
252b5132
RH
6242#ifdef SUPPORT_DISASSEMBLY
6243 case 'i':
6431e409 6244 request_dump (dumpdata, DISASS_DUMP);
cf13d699 6245 break;
252b5132
RH
6246#endif
6247 case 'v':
6248 print_version (program_name);
6249 break;
6250 case 'V':
015dc7e1 6251 do_version = true;
252b5132 6252 break;
d974e256 6253 case 'W':
015dc7e1 6254 do_wide = true;
d974e256 6255 break;
0942c7ab 6256 case 'T':
015dc7e1 6257 do_not_show_symbol_truncation = true;
0942c7ab 6258 break;
79bc120c 6259 case 'C':
015dc7e1 6260 do_demangle = true;
79bc120c
NC
6261 if (optarg != NULL)
6262 {
6263 enum demangling_styles style;
6264
6265 style = cplus_demangle_name_to_style (optarg);
6266 if (style == unknown_demangling)
6267 error (_("unknown demangling style `%s'"), optarg);
6268
6269 cplus_demangle_set_style (style);
6270 }
6271 break;
6272 case OPTION_NO_DEMANGLING:
015dc7e1 6273 do_demangle = false;
79bc120c
NC
6274 break;
6275 case OPTION_RECURSE_LIMIT:
6276 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
6277 break;
6278 case OPTION_NO_RECURSE_LIMIT:
6279 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
6280 break;
6281 case OPTION_WITH_SYMBOL_VERSIONS:
6282 /* Ignored for backward compatibility. */
6283 break;
b9e920ec 6284
b3aa80b4
NC
6285 case 'U':
6286 if (optarg == NULL)
6287 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
6288 else if (streq (optarg, "default") || streq (optarg, "d"))
6289 unicode_display = unicode_default;
6290 else if (streq (optarg, "locale") || streq (optarg, "l"))
6291 unicode_display = unicode_locale;
6292 else if (streq (optarg, "escape") || streq (optarg, "e"))
6293 unicode_display = unicode_escape;
6294 else if (streq (optarg, "invalid") || streq (optarg, "i"))
6295 unicode_display = unicode_invalid;
6296 else if (streq (optarg, "hex") || streq (optarg, "x"))
6297 unicode_display = unicode_hex;
6298 else if (streq (optarg, "highlight") || streq (optarg, "h"))
6299 unicode_display = unicode_highlight;
6300 else
6301 error (_("invalid argument to -U/--unicode: %s"), optarg);
6302 break;
6303
047c3dbf
NL
6304 case OPTION_SYM_BASE:
6305 sym_base = 0;
6306 if (optarg != NULL)
6307 {
6308 sym_base = strtoul (optarg, NULL, 0);
6309 switch (sym_base)
6310 {
6311 case 0:
6312 case 8:
6313 case 10:
6314 case 16:
6315 break;
6316
6317 default:
6318 sym_base = 0;
6319 break;
6320 }
6321 }
6322 break;
6323
252b5132 6324 default:
252b5132
RH
6325 /* xgettext:c-format */
6326 error (_("Invalid option '-%c'\n"), c);
1a0670f3 6327 /* Fall through. */
252b5132 6328 case '?':
92f01d61 6329 usage (stderr);
252b5132
RH
6330 }
6331 }
6332
4d6ed7c8 6333 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 6334 && !do_segments && !do_header && !do_dump && !do_version
f5842774 6335 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 6336 && !do_section_groups && !do_archive_index
0f03783c 6337 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
6338 {
6339 if (do_checks)
6340 {
015dc7e1
AM
6341 check_all = true;
6342 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
6343 do_segments = do_header = do_dump = do_version = true;
6344 do_histogram = do_debugging = do_arch = do_notes = true;
6345 do_section_groups = do_archive_index = do_dyn_syms = true;
6346 do_lto_syms = true;
1b513401
NC
6347 }
6348 else
6349 usage (stderr);
6350 }
252b5132
RH
6351}
6352
6353static const char *
d3ba0551 6354get_elf_class (unsigned int elf_class)
252b5132 6355{
b34976b6 6356 static char buff[32];
103f02d3 6357
252b5132
RH
6358 switch (elf_class)
6359 {
6360 case ELFCLASSNONE: return _("none");
e3c8793a
NC
6361 case ELFCLASS32: return "ELF32";
6362 case ELFCLASS64: return "ELF64";
ab5e7794 6363 default:
e9e44622 6364 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 6365 return buff;
252b5132
RH
6366 }
6367}
6368
6369static const char *
d3ba0551 6370get_data_encoding (unsigned int encoding)
252b5132 6371{
b34976b6 6372 static char buff[32];
103f02d3 6373
252b5132
RH
6374 switch (encoding)
6375 {
6376 case ELFDATANONE: return _("none");
33c63f9d
CM
6377 case ELFDATA2LSB: return _("2's complement, little endian");
6378 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 6379 default:
e9e44622 6380 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 6381 return buff;
252b5132
RH
6382 }
6383}
6384
521f7268
NC
6385static bool
6386check_magic_number (Filedata * filedata, Elf_Internal_Ehdr * header)
6387{
6388 if (header->e_ident[EI_MAG0] == ELFMAG0
6389 && header->e_ident[EI_MAG1] == ELFMAG1
6390 && header->e_ident[EI_MAG2] == ELFMAG2
6391 && header->e_ident[EI_MAG3] == ELFMAG3)
6392 return true;
6393
6394 /* Some compilers produce object files that are not in the ELF file format.
6395 As an aid to users of readelf, try to identify these cases and suggest
6396 alternative tools.
6397
6398 FIXME: It is not clear if all four bytes are used as constant magic
6399 valus by all compilers. It may be necessary to recode this function if
6400 different tools use different length sequences. */
6401
6402 static struct
6403 {
6404 unsigned char magic[4];
6405 const char * obj_message;
6406 const char * ar_message;
6407 }
6408 known_magic[] =
6409 {
6410 { { 'B', 'C', 0xc0, 0xde },
6411 N_("This is a LLVM bitcode file - try using llvm-bcanalyzer\n"),
90de8f9c 6412 N_("This is a LLVM bitcode file - try extracting and then using llvm-bcanalyzer\n")
521f7268
NC
6413 },
6414 { { 'g', 'o', ' ', 'o' },
6415 N_("This is a GO binary file - try using 'go tool objdump' or 'go tool nm'\n"),
6416 NULL
6417 }
6418 };
6419 int i;
6420
6421 for (i = ARRAY_SIZE (known_magic); i--;)
6422 {
6423 if (header->e_ident[EI_MAG0] == known_magic[i].magic[0]
6424 && header->e_ident[EI_MAG1] == known_magic[i].magic[1]
6425 && header->e_ident[EI_MAG2] == known_magic[i].magic[2]
6426 && header->e_ident[EI_MAG3] == known_magic[i].magic[3])
6427 {
6428 /* Some compiler's analyzer tools do not handle archives,
6429 so we provide two different kinds of error message. */
6430 if (filedata->archive_file_size > 0
6431 && known_magic[i].ar_message != NULL)
b3ea2010 6432 error ("%s", known_magic[i].ar_message);
521f7268 6433 else
b3ea2010 6434 error ("%s", known_magic[i].obj_message);
521f7268
NC
6435 return false;
6436 }
6437 }
6438
6439 error (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
6440 return false;
6441}
6442
dda8d76d 6443/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 6444
015dc7e1 6445static bool
dda8d76d 6446process_file_header (Filedata * filedata)
252b5132 6447{
dda8d76d
NC
6448 Elf_Internal_Ehdr * header = & filedata->file_header;
6449
521f7268
NC
6450 if (! check_magic_number (filedata, header))
6451 return false;
252b5132 6452
ca0e11aa
NC
6453 if (! filedata->is_separate)
6454 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 6455
252b5132
RH
6456 if (do_header)
6457 {
32ec8896 6458 unsigned i;
252b5132 6459
ca0e11aa
NC
6460 if (filedata->is_separate)
6461 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
6462 else
6463 printf (_("ELF Header:\n"));
252b5132 6464 printf (_(" Magic: "));
b34976b6 6465 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 6466 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
6467 printf ("\n");
6468 printf (_(" Class: %s\n"),
dda8d76d 6469 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 6470 printf (_(" Data: %s\n"),
dda8d76d 6471 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 6472 printf (_(" Version: %d%s\n"),
dda8d76d
NC
6473 header->e_ident[EI_VERSION],
6474 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 6475 ? _(" (current)")
dda8d76d 6476 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 6477 ? _(" <unknown>")
789be9f7 6478 : "")));
252b5132 6479 printf (_(" OS/ABI: %s\n"),
dda8d76d 6480 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 6481 printf (_(" ABI Version: %d\n"),
dda8d76d 6482 header->e_ident[EI_ABIVERSION]);
252b5132 6483 printf (_(" Type: %s\n"),
93df3340 6484 get_file_type (filedata));
252b5132 6485 printf (_(" Machine: %s\n"),
dda8d76d 6486 get_machine_name (header->e_machine));
252b5132 6487 printf (_(" Version: 0x%lx\n"),
e8a64888 6488 header->e_version);
76da6bbe 6489
f7a99963 6490 printf (_(" Entry point address: "));
e8a64888 6491 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 6492 printf (_("\n Start of program headers: "));
e8a64888 6493 print_vma (header->e_phoff, DEC);
f7a99963 6494 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 6495 print_vma (header->e_shoff, DEC);
f7a99963 6496 printf (_(" (bytes into file)\n"));
76da6bbe 6497
252b5132 6498 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 6499 header->e_flags,
dda8d76d 6500 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
6501 printf (_(" Size of this header: %u (bytes)\n"),
6502 header->e_ehsize);
6503 printf (_(" Size of program headers: %u (bytes)\n"),
6504 header->e_phentsize);
6505 printf (_(" Number of program headers: %u"),
6506 header->e_phnum);
dda8d76d
NC
6507 if (filedata->section_headers != NULL
6508 && header->e_phnum == PN_XNUM
6509 && filedata->section_headers[0].sh_info != 0)
2969c3b3 6510 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 6511 putc ('\n', stdout);
e8a64888
AM
6512 printf (_(" Size of section headers: %u (bytes)\n"),
6513 header->e_shentsize);
6514 printf (_(" Number of section headers: %u"),
6515 header->e_shnum);
dda8d76d 6516 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
6517 {
6518 header->e_shnum = filedata->section_headers[0].sh_size;
6519 printf (" (%u)", header->e_shnum);
6520 }
560f3c1c 6521 putc ('\n', stdout);
e8a64888
AM
6522 printf (_(" Section header string table index: %u"),
6523 header->e_shstrndx);
dda8d76d
NC
6524 if (filedata->section_headers != NULL
6525 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
6526 {
6527 header->e_shstrndx = filedata->section_headers[0].sh_link;
6528 printf (" (%u)", header->e_shstrndx);
6529 }
6530 if (header->e_shstrndx != SHN_UNDEF
6531 && header->e_shstrndx >= header->e_shnum)
6532 {
6533 header->e_shstrndx = SHN_UNDEF;
6534 printf (_(" <corrupt: out of range>"));
6535 }
560f3c1c
AM
6536 putc ('\n', stdout);
6537 }
6538
dda8d76d 6539 if (filedata->section_headers != NULL)
560f3c1c 6540 {
dda8d76d
NC
6541 if (header->e_phnum == PN_XNUM
6542 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
6543 {
6544 /* Throw away any cached read of PN_XNUM headers. */
6545 free (filedata->program_headers);
6546 filedata->program_headers = NULL;
6547 header->e_phnum = filedata->section_headers[0].sh_info;
6548 }
dda8d76d
NC
6549 if (header->e_shnum == SHN_UNDEF)
6550 header->e_shnum = filedata->section_headers[0].sh_size;
6551 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
6552 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 6553 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 6554 header->e_shstrndx = SHN_UNDEF;
252b5132 6555 }
103f02d3 6556
015dc7e1 6557 return true;
9ea033b2
NC
6558}
6559
dda8d76d
NC
6560/* Read in the program headers from FILEDATA and store them in PHEADERS.
6561 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
6562
015dc7e1 6563static bool
dda8d76d 6564get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6565{
2cf0635d
NC
6566 Elf32_External_Phdr * phdrs;
6567 Elf32_External_Phdr * external;
6568 Elf_Internal_Phdr * internal;
b34976b6 6569 unsigned int i;
dda8d76d
NC
6570 unsigned int size = filedata->file_header.e_phentsize;
6571 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6572
6573 /* PR binutils/17531: Cope with unexpected section header sizes. */
6574 if (size == 0 || num == 0)
015dc7e1 6575 return false;
e0a31db1
NC
6576 if (size < sizeof * phdrs)
6577 {
6578 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6579 return false;
e0a31db1
NC
6580 }
6581 if (size > sizeof * phdrs)
6582 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6583
dda8d76d 6584 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
6585 size, num, _("program headers"));
6586 if (phdrs == NULL)
015dc7e1 6587 return false;
9ea033b2 6588
91d6fa6a 6589 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6590 i < filedata->file_header.e_phnum;
b34976b6 6591 i++, internal++, external++)
252b5132 6592 {
9ea033b2
NC
6593 internal->p_type = BYTE_GET (external->p_type);
6594 internal->p_offset = BYTE_GET (external->p_offset);
6595 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6596 internal->p_paddr = BYTE_GET (external->p_paddr);
6597 internal->p_filesz = BYTE_GET (external->p_filesz);
6598 internal->p_memsz = BYTE_GET (external->p_memsz);
6599 internal->p_flags = BYTE_GET (external->p_flags);
6600 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
6601 }
6602
9ea033b2 6603 free (phdrs);
015dc7e1 6604 return true;
252b5132
RH
6605}
6606
dda8d76d
NC
6607/* Read in the program headers from FILEDATA and store them in PHEADERS.
6608 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
6609
015dc7e1 6610static bool
dda8d76d 6611get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 6612{
2cf0635d
NC
6613 Elf64_External_Phdr * phdrs;
6614 Elf64_External_Phdr * external;
6615 Elf_Internal_Phdr * internal;
b34976b6 6616 unsigned int i;
dda8d76d
NC
6617 unsigned int size = filedata->file_header.e_phentsize;
6618 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
6619
6620 /* PR binutils/17531: Cope with unexpected section header sizes. */
6621 if (size == 0 || num == 0)
015dc7e1 6622 return false;
e0a31db1
NC
6623 if (size < sizeof * phdrs)
6624 {
6625 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 6626 return false;
e0a31db1
NC
6627 }
6628 if (size > sizeof * phdrs)
6629 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 6630
dda8d76d 6631 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 6632 size, num, _("program headers"));
a6e9f9df 6633 if (!phdrs)
015dc7e1 6634 return false;
9ea033b2 6635
91d6fa6a 6636 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 6637 i < filedata->file_header.e_phnum;
b34976b6 6638 i++, internal++, external++)
9ea033b2
NC
6639 {
6640 internal->p_type = BYTE_GET (external->p_type);
6641 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
6642 internal->p_offset = BYTE_GET (external->p_offset);
6643 internal->p_vaddr = BYTE_GET (external->p_vaddr);
6644 internal->p_paddr = BYTE_GET (external->p_paddr);
6645 internal->p_filesz = BYTE_GET (external->p_filesz);
6646 internal->p_memsz = BYTE_GET (external->p_memsz);
6647 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
6648 }
6649
6650 free (phdrs);
015dc7e1 6651 return true;
9ea033b2 6652}
252b5132 6653
32ec8896 6654/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 6655
015dc7e1 6656static bool
dda8d76d 6657get_program_headers (Filedata * filedata)
d93f0186 6658{
2cf0635d 6659 Elf_Internal_Phdr * phdrs;
d93f0186
NC
6660
6661 /* Check cache of prior read. */
dda8d76d 6662 if (filedata->program_headers != NULL)
015dc7e1 6663 return true;
d93f0186 6664
82156ab7
NC
6665 /* Be kind to memory checkers by looking for
6666 e_phnum values which we know must be invalid. */
dda8d76d 6667 if (filedata->file_header.e_phnum
82156ab7 6668 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 6669 >= filedata->file_size)
82156ab7
NC
6670 {
6671 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 6672 filedata->file_header.e_phnum);
015dc7e1 6673 return false;
82156ab7 6674 }
d93f0186 6675
dda8d76d 6676 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 6677 sizeof (Elf_Internal_Phdr));
d93f0186
NC
6678 if (phdrs == NULL)
6679 {
8b73c356 6680 error (_("Out of memory reading %u program headers\n"),
dda8d76d 6681 filedata->file_header.e_phnum);
015dc7e1 6682 return false;
d93f0186
NC
6683 }
6684
6685 if (is_32bit_elf
dda8d76d
NC
6686 ? get_32bit_program_headers (filedata, phdrs)
6687 : get_64bit_program_headers (filedata, phdrs))
d93f0186 6688 {
dda8d76d 6689 filedata->program_headers = phdrs;
015dc7e1 6690 return true;
d93f0186
NC
6691 }
6692
6693 free (phdrs);
015dc7e1 6694 return false;
d93f0186
NC
6695}
6696
93df3340 6697/* Print program header info and locate dynamic section. */
2f62977e 6698
93df3340 6699static void
dda8d76d 6700process_program_headers (Filedata * filedata)
252b5132 6701{
2cf0635d 6702 Elf_Internal_Phdr * segment;
b34976b6 6703 unsigned int i;
1a9ccd70 6704 Elf_Internal_Phdr * previous_load = NULL;
252b5132 6705
dda8d76d 6706 if (filedata->file_header.e_phnum == 0)
252b5132 6707 {
82f2dbf7 6708 /* PR binutils/12467. */
dda8d76d 6709 if (filedata->file_header.e_phoff != 0)
93df3340
AM
6710 warn (_("possibly corrupt ELF header - it has a non-zero program"
6711 " header offset, but no program headers\n"));
82f2dbf7 6712 else if (do_segments)
ca0e11aa
NC
6713 {
6714 if (filedata->is_separate)
6715 printf (_("\nThere are no program headers in linked file '%s'.\n"),
6716 filedata->file_name);
6717 else
6718 printf (_("\nThere are no program headers in this file.\n"));
6719 }
93df3340 6720 goto no_headers;
252b5132
RH
6721 }
6722
6723 if (do_segments && !do_header)
6724 {
ca0e11aa
NC
6725 if (filedata->is_separate)
6726 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 6727 filedata->file_name, get_file_type (filedata));
ca0e11aa 6728 else
93df3340 6729 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
b8281767 6730 printf (_("Entry point 0x%" PRIx64 "\n"),
625d49fc 6731 filedata->file_header.e_entry);
b8281767
AM
6732 printf (ngettext ("There is %d program header,"
6733 " starting at offset %" PRIu64 "\n",
6734 "There are %d program headers,"
6735 " starting at offset %" PRIu64 "\n",
dda8d76d
NC
6736 filedata->file_header.e_phnum),
6737 filedata->file_header.e_phnum,
625d49fc 6738 filedata->file_header.e_phoff);
252b5132
RH
6739 }
6740
dda8d76d 6741 if (! get_program_headers (filedata))
93df3340 6742 goto no_headers;
103f02d3 6743
252b5132
RH
6744 if (do_segments)
6745 {
dda8d76d 6746 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
6747 printf (_("\nProgram Headers:\n"));
6748 else
6749 printf (_("\nProgram Headers:\n"));
76da6bbe 6750
f7a99963
NC
6751 if (is_32bit_elf)
6752 printf
6753 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
6754 else if (do_wide)
6755 printf
6756 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
6757 else
6758 {
6759 printf
6760 (_(" Type Offset VirtAddr PhysAddr\n"));
6761 printf
6762 (_(" FileSiz MemSiz Flags Align\n"));
6763 }
252b5132
RH
6764 }
6765
26c527e6 6766 uint64_t dynamic_addr = 0;
be7d229a 6767 uint64_t dynamic_size = 0;
dda8d76d
NC
6768 for (i = 0, segment = filedata->program_headers;
6769 i < filedata->file_header.e_phnum;
b34976b6 6770 i++, segment++)
252b5132
RH
6771 {
6772 if (do_segments)
6773 {
dda8d76d 6774 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
6775
6776 if (is_32bit_elf)
6777 {
6778 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6779 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
6780 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
6781 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
6782 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
6783 printf ("%c%c%c ",
6784 (segment->p_flags & PF_R ? 'R' : ' '),
6785 (segment->p_flags & PF_W ? 'W' : ' '),
6786 (segment->p_flags & PF_X ? 'E' : ' '));
6787 printf ("%#lx", (unsigned long) segment->p_align);
6788 }
d974e256
JJ
6789 else if (do_wide)
6790 {
6791 if ((unsigned long) segment->p_offset == segment->p_offset)
6792 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
6793 else
6794 {
6795 print_vma (segment->p_offset, FULL_HEX);
6796 putchar (' ');
6797 }
6798
6799 print_vma (segment->p_vaddr, FULL_HEX);
6800 putchar (' ');
6801 print_vma (segment->p_paddr, FULL_HEX);
6802 putchar (' ');
6803
6804 if ((unsigned long) segment->p_filesz == segment->p_filesz)
6805 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
6806 else
6807 {
6808 print_vma (segment->p_filesz, FULL_HEX);
6809 putchar (' ');
6810 }
6811
6812 if ((unsigned long) segment->p_memsz == segment->p_memsz)
6813 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
6814 else
6815 {
f48e6c45 6816 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
6817 }
6818
6819 printf (" %c%c%c ",
6820 (segment->p_flags & PF_R ? 'R' : ' '),
6821 (segment->p_flags & PF_W ? 'W' : ' '),
6822 (segment->p_flags & PF_X ? 'E' : ' '));
6823
6824 if ((unsigned long) segment->p_align == segment->p_align)
6825 printf ("%#lx", (unsigned long) segment->p_align);
6826 else
6827 {
6828 print_vma (segment->p_align, PREFIX_HEX);
6829 }
6830 }
f7a99963
NC
6831 else
6832 {
6833 print_vma (segment->p_offset, FULL_HEX);
6834 putchar (' ');
6835 print_vma (segment->p_vaddr, FULL_HEX);
6836 putchar (' ');
6837 print_vma (segment->p_paddr, FULL_HEX);
6838 printf ("\n ");
6839 print_vma (segment->p_filesz, FULL_HEX);
6840 putchar (' ');
6841 print_vma (segment->p_memsz, FULL_HEX);
6842 printf (" %c%c%c ",
6843 (segment->p_flags & PF_R ? 'R' : ' '),
6844 (segment->p_flags & PF_W ? 'W' : ' '),
6845 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 6846 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 6847 }
252b5132 6848
1a9ccd70
NC
6849 putc ('\n', stdout);
6850 }
f54498b4 6851
252b5132
RH
6852 switch (segment->p_type)
6853 {
1a9ccd70 6854 case PT_LOAD:
502d895c
NC
6855#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
6856 required by the ELF standard, several programs, including the Linux
6857 kernel, make use of non-ordered segments. */
1a9ccd70
NC
6858 if (previous_load
6859 && previous_load->p_vaddr > segment->p_vaddr)
6860 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6861#endif
1a9ccd70
NC
6862 if (segment->p_memsz < segment->p_filesz)
6863 error (_("the segment's file size is larger than its memory size\n"));
6864 previous_load = segment;
6865 break;
6866
6867 case PT_PHDR:
6868 /* PR 20815 - Verify that the program header is loaded into memory. */
6869 if (i > 0 && previous_load != NULL)
6870 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6871 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6872 {
6873 unsigned int j;
6874
dda8d76d 6875 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6876 {
6877 Elf_Internal_Phdr *load = filedata->program_headers + j;
6878 if (load->p_type == PT_LOAD
6879 && load->p_offset <= segment->p_offset
6880 && (load->p_offset + load->p_filesz
6881 >= segment->p_offset + segment->p_filesz)
6882 && load->p_vaddr <= segment->p_vaddr
6883 && (load->p_vaddr + load->p_filesz
6884 >= segment->p_vaddr + segment->p_filesz))
6885 break;
6886 }
dda8d76d 6887 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6888 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6889 }
6890 break;
6891
252b5132 6892 case PT_DYNAMIC:
93df3340 6893 if (dynamic_addr)
252b5132
RH
6894 error (_("more than one dynamic segment\n"));
6895
20737c13
AM
6896 /* By default, assume that the .dynamic section is the first
6897 section in the DYNAMIC segment. */
93df3340
AM
6898 dynamic_addr = segment->p_offset;
6899 dynamic_size = segment->p_filesz;
20737c13 6900
b2d38a17
NC
6901 /* Try to locate the .dynamic section. If there is
6902 a section header table, we can easily locate it. */
dda8d76d 6903 if (filedata->section_headers != NULL)
b2d38a17 6904 {
2cf0635d 6905 Elf_Internal_Shdr * sec;
b2d38a17 6906
dda8d76d 6907 sec = find_section (filedata, ".dynamic");
89fac5e3 6908 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6909 {
93df3340
AM
6910 /* A corresponding .dynamic section is expected, but on
6911 IA-64/OpenVMS it is OK for it to be missing. */
6912 if (!is_ia64_vms (filedata))
6913 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6914 break;
6915 }
6916
42bb2e33 6917 if (sec->sh_type == SHT_NOBITS)
20737c13 6918 {
93df3340
AM
6919 dynamic_addr = 0;
6920 dynamic_size = 0;
20737c13
AM
6921 break;
6922 }
42bb2e33 6923
93df3340
AM
6924 dynamic_addr = sec->sh_offset;
6925 dynamic_size = sec->sh_size;
b2d38a17 6926
8ac10c5b
L
6927 /* The PT_DYNAMIC segment, which is used by the run-time
6928 loader, should exactly match the .dynamic section. */
6929 if (do_checks
93df3340
AM
6930 && (dynamic_addr != segment->p_offset
6931 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6932 warn (_("\
6933the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6934 }
39e224f6
MW
6935
6936 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6937 segment. Check this after matching against the section headers
6938 so we don't warn on debuginfo file (which have NOBITS .dynamic
6939 sections). */
93df3340
AM
6940 if (dynamic_addr > filedata->file_size
6941 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6942 {
6943 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6944 dynamic_addr = 0;
6945 dynamic_size = 0;
39e224f6 6946 }
252b5132
RH
6947 break;
6948
6949 case PT_INTERP:
13acb58d
AM
6950 if (segment->p_offset >= filedata->file_size
6951 || segment->p_filesz > filedata->file_size - segment->p_offset
6952 || segment->p_filesz - 1 >= (size_t) -2
63cf857e
AM
6953 || fseek64 (filedata->handle,
6954 filedata->archive_file_offset + segment->p_offset,
6955 SEEK_SET))
252b5132
RH
6956 error (_("Unable to find program interpreter name\n"));
6957 else
6958 {
13acb58d
AM
6959 size_t len = segment->p_filesz;
6960 free (filedata->program_interpreter);
6961 filedata->program_interpreter = xmalloc (len + 1);
6962 len = fread (filedata->program_interpreter, 1, len,
6963 filedata->handle);
6964 filedata->program_interpreter[len] = 0;
252b5132
RH
6965
6966 if (do_segments)
f54498b4 6967 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6968 filedata->program_interpreter);
252b5132
RH
6969 }
6970 break;
6971 }
252b5132
RH
6972 }
6973
dda8d76d
NC
6974 if (do_segments
6975 && filedata->section_headers != NULL
6976 && filedata->string_table != NULL)
252b5132
RH
6977 {
6978 printf (_("\n Section to Segment mapping:\n"));
6979 printf (_(" Segment Sections...\n"));
6980
dda8d76d 6981 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6982 {
9ad5cbcf 6983 unsigned int j;
2cf0635d 6984 Elf_Internal_Shdr * section;
252b5132 6985
dda8d76d
NC
6986 segment = filedata->program_headers + i;
6987 section = filedata->section_headers + 1;
252b5132
RH
6988
6989 printf (" %2.2d ", i);
6990
dda8d76d 6991 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6992 {
f4638467
AM
6993 if (!ELF_TBSS_SPECIAL (section, segment)
6994 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6995 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6996 }
6997
6998 putc ('\n',stdout);
6999 }
7000 }
7001
93df3340
AM
7002 filedata->dynamic_addr = dynamic_addr;
7003 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
7004 return;
7005
7006 no_headers:
7007 filedata->dynamic_addr = 0;
7008 filedata->dynamic_size = 1;
252b5132
RH
7009}
7010
7011
d93f0186
NC
7012/* Find the file offset corresponding to VMA by using the program headers. */
7013
26c527e6 7014static int64_t
625d49fc 7015offset_from_vma (Filedata * filedata, uint64_t vma, uint64_t size)
d93f0186 7016{
2cf0635d 7017 Elf_Internal_Phdr * seg;
d93f0186 7018
dda8d76d 7019 if (! get_program_headers (filedata))
d93f0186
NC
7020 {
7021 warn (_("Cannot interpret virtual addresses without program headers.\n"));
7022 return (long) vma;
7023 }
7024
dda8d76d
NC
7025 for (seg = filedata->program_headers;
7026 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
7027 ++seg)
7028 {
7029 if (seg->p_type != PT_LOAD)
7030 continue;
7031
7032 if (vma >= (seg->p_vaddr & -seg->p_align)
7033 && vma + size <= seg->p_vaddr + seg->p_filesz)
7034 return vma - seg->p_vaddr + seg->p_offset;
7035 }
7036
26c527e6
AM
7037 warn (_("Virtual address %#" PRIx64
7038 " not located in any PT_LOAD segment.\n"), vma);
7039 return vma;
d93f0186
NC
7040}
7041
7042
dda8d76d
NC
7043/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
7044 If PROBE is true, this is just a probe and we do not generate any error
7045 messages if the load fails. */
049b0c3a 7046
015dc7e1
AM
7047static bool
7048get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 7049{
2cf0635d
NC
7050 Elf32_External_Shdr * shdrs;
7051 Elf_Internal_Shdr * internal;
dda8d76d
NC
7052 unsigned int i;
7053 unsigned int size = filedata->file_header.e_shentsize;
7054 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7055
7056 /* PR binutils/17531: Cope with unexpected section header sizes. */
7057 if (size == 0 || num == 0)
015dc7e1 7058 return false;
907b52f4
NC
7059
7060 /* The section header cannot be at the start of the file - that is
7061 where the ELF file header is located. A file with absolutely no
7062 sections in it will use a shoff of 0. */
7063 if (filedata->file_header.e_shoff == 0)
7064 return false;
7065
049b0c3a
NC
7066 if (size < sizeof * shdrs)
7067 {
7068 if (! probe)
7069 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7070 return false;
049b0c3a
NC
7071 }
7072 if (!probe && size > sizeof * shdrs)
7073 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 7074
dda8d76d 7075 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
7076 size, num,
7077 probe ? NULL : _("section headers"));
7078 if (shdrs == NULL)
015dc7e1 7079 return false;
252b5132 7080
dda8d76d
NC
7081 filedata->section_headers = (Elf_Internal_Shdr *)
7082 cmalloc (num, sizeof (Elf_Internal_Shdr));
7083 if (filedata->section_headers == NULL)
252b5132 7084 {
049b0c3a 7085 if (!probe)
8b73c356 7086 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7087 free (shdrs);
015dc7e1 7088 return false;
252b5132
RH
7089 }
7090
dda8d76d 7091 for (i = 0, internal = filedata->section_headers;
560f3c1c 7092 i < num;
b34976b6 7093 i++, internal++)
252b5132
RH
7094 {
7095 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7096 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
7097 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7098 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7099 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7100 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7101 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7102 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7103 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
7104 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
7105 if (!probe && internal->sh_link > num)
7106 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7107 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7108 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
7109 }
7110
7111 free (shdrs);
015dc7e1 7112 return true;
252b5132
RH
7113}
7114
dda8d76d
NC
7115/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
7116
015dc7e1
AM
7117static bool
7118get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 7119{
dda8d76d
NC
7120 Elf64_External_Shdr * shdrs;
7121 Elf_Internal_Shdr * internal;
7122 unsigned int i;
7123 unsigned int size = filedata->file_header.e_shentsize;
7124 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
7125
7126 /* PR binutils/17531: Cope with unexpected section header sizes. */
7127 if (size == 0 || num == 0)
015dc7e1 7128 return false;
dda8d76d 7129
907b52f4
NC
7130 /* The section header cannot be at the start of the file - that is
7131 where the ELF file header is located. A file with absolutely no
7132 sections in it will use a shoff of 0. */
7133 if (filedata->file_header.e_shoff == 0)
7134 return false;
7135
049b0c3a
NC
7136 if (size < sizeof * shdrs)
7137 {
7138 if (! probe)
7139 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 7140 return false;
049b0c3a 7141 }
dda8d76d 7142
049b0c3a
NC
7143 if (! probe && size > sizeof * shdrs)
7144 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 7145
dda8d76d
NC
7146 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
7147 filedata->file_header.e_shoff,
049b0c3a
NC
7148 size, num,
7149 probe ? NULL : _("section headers"));
7150 if (shdrs == NULL)
015dc7e1 7151 return false;
9ea033b2 7152
dda8d76d
NC
7153 filedata->section_headers = (Elf_Internal_Shdr *)
7154 cmalloc (num, sizeof (Elf_Internal_Shdr));
7155 if (filedata->section_headers == NULL)
9ea033b2 7156 {
049b0c3a 7157 if (! probe)
8b73c356 7158 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 7159 free (shdrs);
015dc7e1 7160 return false;
9ea033b2
NC
7161 }
7162
dda8d76d 7163 for (i = 0, internal = filedata->section_headers;
560f3c1c 7164 i < num;
b34976b6 7165 i++, internal++)
9ea033b2
NC
7166 {
7167 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
7168 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
7169 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
7170 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
7171 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
7172 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
7173 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
7174 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
7175 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
7176 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
7177 if (!probe && internal->sh_link > num)
7178 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
7179 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
7180 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
7181 }
7182
7183 free (shdrs);
015dc7e1 7184 return true;
9ea033b2
NC
7185}
7186
4de91c10
AM
7187static bool
7188get_section_headers (Filedata *filedata, bool probe)
7189{
7190 if (filedata->section_headers != NULL)
7191 return true;
7192
4de91c10
AM
7193 if (is_32bit_elf)
7194 return get_32bit_section_headers (filedata, probe);
7195 else
7196 return get_64bit_section_headers (filedata, probe);
7197}
7198
252b5132 7199static Elf_Internal_Sym *
26c527e6
AM
7200get_32bit_elf_symbols (Filedata *filedata,
7201 Elf_Internal_Shdr *section,
7202 uint64_t *num_syms_return)
252b5132 7203{
26c527e6 7204 uint64_t number = 0;
dd24e3da 7205 Elf32_External_Sym * esyms = NULL;
ba5cdace 7206 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 7207 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7208 Elf_Internal_Sym * psym;
b34976b6 7209 unsigned int j;
e3d39609 7210 elf_section_list * entry;
252b5132 7211
c9c1d674
EG
7212 if (section->sh_size == 0)
7213 {
7214 if (num_syms_return != NULL)
7215 * num_syms_return = 0;
7216 return NULL;
7217 }
7218
dd24e3da 7219 /* Run some sanity checks first. */
c9c1d674 7220 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7221 {
26c527e6 7222 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7223 printable_section_name (filedata, section),
26c527e6 7224 section->sh_entsize);
ba5cdace 7225 goto exit_point;
dd24e3da
NC
7226 }
7227
dda8d76d 7228 if (section->sh_size > filedata->file_size)
f54498b4 7229 {
26c527e6 7230 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7231 printable_section_name (filedata, section),
26c527e6 7232 section->sh_size);
f54498b4
NC
7233 goto exit_point;
7234 }
7235
dd24e3da
NC
7236 number = section->sh_size / section->sh_entsize;
7237
7238 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
7239 {
26c527e6
AM
7240 error (_("Size (%#" PRIx64 ") of section %s "
7241 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7242 section->sh_size,
dda8d76d 7243 printable_section_name (filedata, section),
26c527e6 7244 section->sh_entsize);
ba5cdace 7245 goto exit_point;
dd24e3da
NC
7246 }
7247
dda8d76d 7248 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7249 section->sh_size, _("symbols"));
dd24e3da 7250 if (esyms == NULL)
ba5cdace 7251 goto exit_point;
252b5132 7252
e3d39609 7253 shndx = NULL;
978c4450 7254 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7255 {
26c527e6 7256 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7257 continue;
7258
7259 if (shndx != NULL)
7260 {
7261 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7262 free (shndx);
7263 }
7264
7265 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7266 entry->hdr->sh_offset,
7267 1, entry->hdr->sh_size,
7268 _("symbol table section indices"));
7269 if (shndx == NULL)
7270 goto exit_point;
7271
7272 /* PR17531: file: heap-buffer-overflow */
7273 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7274 {
26c527e6 7275 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7276 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7277 entry->hdr->sh_size,
7278 section->sh_size);
e3d39609 7279 goto exit_point;
c9c1d674 7280 }
e3d39609 7281 }
9ad5cbcf 7282
3f5e193b 7283 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
7284
7285 if (isyms == NULL)
7286 {
26c527e6 7287 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
dd24e3da 7288 goto exit_point;
252b5132
RH
7289 }
7290
dd24e3da 7291 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
7292 {
7293 psym->st_name = BYTE_GET (esyms[j].st_name);
7294 psym->st_value = BYTE_GET (esyms[j].st_value);
7295 psym->st_size = BYTE_GET (esyms[j].st_size);
7296 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 7297 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7298 psym->st_shndx
7299 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7300 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7301 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
7302 psym->st_info = BYTE_GET (esyms[j].st_info);
7303 psym->st_other = BYTE_GET (esyms[j].st_other);
7304 }
7305
dd24e3da 7306 exit_point:
e3d39609
NC
7307 free (shndx);
7308 free (esyms);
252b5132 7309
ba5cdace
NC
7310 if (num_syms_return != NULL)
7311 * num_syms_return = isyms == NULL ? 0 : number;
7312
252b5132
RH
7313 return isyms;
7314}
7315
9ea033b2 7316static Elf_Internal_Sym *
26c527e6
AM
7317get_64bit_elf_symbols (Filedata *filedata,
7318 Elf_Internal_Shdr *section,
7319 uint64_t *num_syms_return)
9ea033b2 7320{
26c527e6 7321 uint64_t number = 0;
ba5cdace
NC
7322 Elf64_External_Sym * esyms = NULL;
7323 Elf_External_Sym_Shndx * shndx = NULL;
7324 Elf_Internal_Sym * isyms = NULL;
2cf0635d 7325 Elf_Internal_Sym * psym;
b34976b6 7326 unsigned int j;
e3d39609 7327 elf_section_list * entry;
9ea033b2 7328
c9c1d674
EG
7329 if (section->sh_size == 0)
7330 {
7331 if (num_syms_return != NULL)
7332 * num_syms_return = 0;
7333 return NULL;
7334 }
7335
dd24e3da 7336 /* Run some sanity checks first. */
c9c1d674 7337 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 7338 {
26c527e6 7339 error (_("Section %s has an invalid sh_entsize of %#" PRIx64 "\n"),
dda8d76d 7340 printable_section_name (filedata, section),
26c527e6 7341 section->sh_entsize);
ba5cdace 7342 goto exit_point;
dd24e3da
NC
7343 }
7344
dda8d76d 7345 if (section->sh_size > filedata->file_size)
f54498b4 7346 {
26c527e6 7347 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
dda8d76d 7348 printable_section_name (filedata, section),
26c527e6 7349 section->sh_size);
f54498b4
NC
7350 goto exit_point;
7351 }
7352
dd24e3da
NC
7353 number = section->sh_size / section->sh_entsize;
7354
7355 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
7356 {
26c527e6
AM
7357 error (_("Size (%#" PRIx64 ") of section %s "
7358 "is not a multiple of its sh_entsize (%#" PRIx64 ")\n"),
7359 section->sh_size,
dda8d76d 7360 printable_section_name (filedata, section),
26c527e6 7361 section->sh_entsize);
ba5cdace 7362 goto exit_point;
dd24e3da
NC
7363 }
7364
dda8d76d 7365 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 7366 section->sh_size, _("symbols"));
a6e9f9df 7367 if (!esyms)
ba5cdace 7368 goto exit_point;
9ea033b2 7369
e3d39609 7370 shndx = NULL;
978c4450 7371 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609 7372 {
26c527e6 7373 if (entry->hdr->sh_link != (size_t) (section - filedata->section_headers))
e3d39609
NC
7374 continue;
7375
7376 if (shndx != NULL)
7377 {
7378 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
7379 free (shndx);
c9c1d674 7380 }
e3d39609
NC
7381
7382 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
7383 entry->hdr->sh_offset,
7384 1, entry->hdr->sh_size,
7385 _("symbol table section indices"));
7386 if (shndx == NULL)
7387 goto exit_point;
7388
7389 /* PR17531: file: heap-buffer-overflow */
7390 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
7391 {
26c527e6 7392 error (_("Index section %s has an sh_size of %#" PRIx64 " - expected %#" PRIx64 "\n"),
e3d39609 7393 printable_section_name (filedata, entry->hdr),
26c527e6
AM
7394 entry->hdr->sh_size,
7395 section->sh_size);
e3d39609
NC
7396 goto exit_point;
7397 }
7398 }
9ad5cbcf 7399
3f5e193b 7400 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
7401
7402 if (isyms == NULL)
7403 {
26c527e6 7404 error (_("Out of memory reading %" PRIu64 " symbols\n"), number);
ba5cdace 7405 goto exit_point;
9ea033b2
NC
7406 }
7407
ba5cdace 7408 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
7409 {
7410 psym->st_name = BYTE_GET (esyms[j].st_name);
7411 psym->st_info = BYTE_GET (esyms[j].st_info);
7412 psym->st_other = BYTE_GET (esyms[j].st_other);
7413 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 7414
4fbb74a6 7415 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
7416 psym->st_shndx
7417 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
7418 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
7419 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 7420
66543521
AM
7421 psym->st_value = BYTE_GET (esyms[j].st_value);
7422 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
7423 }
7424
ba5cdace 7425 exit_point:
e3d39609
NC
7426 free (shndx);
7427 free (esyms);
ba5cdace
NC
7428
7429 if (num_syms_return != NULL)
7430 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
7431
7432 return isyms;
7433}
7434
4de91c10
AM
7435static Elf_Internal_Sym *
7436get_elf_symbols (Filedata *filedata,
7437 Elf_Internal_Shdr *section,
26c527e6 7438 uint64_t *num_syms_return)
4de91c10
AM
7439{
7440 if (is_32bit_elf)
7441 return get_32bit_elf_symbols (filedata, section, num_syms_return);
7442 else
7443 return get_64bit_elf_symbols (filedata, section, num_syms_return);
7444}
7445
d1133906 7446static const char *
625d49fc 7447get_elf_section_flags (Filedata * filedata, uint64_t sh_flags)
d1133906 7448{
5477e8a0 7449 static char buff[1024];
2cf0635d 7450 char * p = buff;
32ec8896
NC
7451 unsigned int field_size = is_32bit_elf ? 8 : 16;
7452 signed int sindex;
7453 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
625d49fc
AM
7454 uint64_t os_flags = 0;
7455 uint64_t proc_flags = 0;
7456 uint64_t unknown_flags = 0;
148b93f2 7457 static const struct
5477e8a0 7458 {
2cf0635d 7459 const char * str;
32ec8896 7460 unsigned int len;
5477e8a0
L
7461 }
7462 flags [] =
7463 {
cfcac11d
NC
7464 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
7465 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
7466 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
7467 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
7468 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
7469 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
7470 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
7471 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
7472 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
7473 /* 9 */ { STRING_COMMA_LEN ("TLS") },
7474 /* IA-64 specific. */
7475 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
7476 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
7477 /* IA-64 OpenVMS specific. */
7478 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
7479 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
7480 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
7481 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
7482 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
7483 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 7484 /* Generic. */
cfcac11d 7485 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 7486 /* SPARC specific. */
77115a4a 7487 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
7488 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
7489 /* ARM specific. */
7490 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 7491 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
7492 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
7493 /* GNU specific. */
7494 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
7495 /* VLE specific. */
7496 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
7497 /* GNU specific. */
7498 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
7499 };
7500
7501 if (do_section_details)
f8c4789c
AM
7502 p += sprintf (p, "[%*.*lx]: ",
7503 field_size, field_size, (unsigned long) sh_flags);
76da6bbe 7504
d1133906
NC
7505 while (sh_flags)
7506 {
625d49fc 7507 uint64_t flag;
d1133906
NC
7508
7509 flag = sh_flags & - sh_flags;
7510 sh_flags &= ~ flag;
76da6bbe 7511
5477e8a0 7512 if (do_section_details)
d1133906 7513 {
5477e8a0
L
7514 switch (flag)
7515 {
91d6fa6a
NC
7516 case SHF_WRITE: sindex = 0; break;
7517 case SHF_ALLOC: sindex = 1; break;
7518 case SHF_EXECINSTR: sindex = 2; break;
7519 case SHF_MERGE: sindex = 3; break;
7520 case SHF_STRINGS: sindex = 4; break;
7521 case SHF_INFO_LINK: sindex = 5; break;
7522 case SHF_LINK_ORDER: sindex = 6; break;
7523 case SHF_OS_NONCONFORMING: sindex = 7; break;
7524 case SHF_GROUP: sindex = 8; break;
7525 case SHF_TLS: sindex = 9; break;
18ae9cc1 7526 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 7527 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 7528
5477e8a0 7529 default:
91d6fa6a 7530 sindex = -1;
dda8d76d 7531 switch (filedata->file_header.e_machine)
148b93f2 7532 {
cfcac11d 7533 case EM_IA_64:
148b93f2 7534 if (flag == SHF_IA_64_SHORT)
91d6fa6a 7535 sindex = 10;
148b93f2 7536 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 7537 sindex = 11;
dda8d76d 7538 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
7539 switch (flag)
7540 {
91d6fa6a
NC
7541 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
7542 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
7543 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
7544 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
7545 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
7546 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
7547 default: break;
7548 }
cfcac11d
NC
7549 break;
7550
caa83f8b 7551 case EM_386:
22abe556 7552 case EM_IAMCU:
caa83f8b 7553 case EM_X86_64:
7f502d6c 7554 case EM_L1OM:
7a9068fe 7555 case EM_K1OM:
cfcac11d
NC
7556 case EM_OLD_SPARCV9:
7557 case EM_SPARC32PLUS:
7558 case EM_SPARCV9:
7559 case EM_SPARC:
18ae9cc1 7560 if (flag == SHF_ORDERED)
91d6fa6a 7561 sindex = 19;
cfcac11d 7562 break;
ac4c9b04
MG
7563
7564 case EM_ARM:
7565 switch (flag)
7566 {
7567 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 7568 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
7569 case SHF_COMDEF: sindex = 23; break;
7570 default: break;
7571 }
7572 break;
83eef883
AFB
7573 case EM_PPC:
7574 if (flag == SHF_PPC_VLE)
7575 sindex = 25;
7576 break;
99fabbc9
JL
7577 default:
7578 break;
7579 }
ac4c9b04 7580
99fabbc9
JL
7581 switch (filedata->file_header.e_ident[EI_OSABI])
7582 {
7583 case ELFOSABI_GNU:
7584 case ELFOSABI_FREEBSD:
7585 if (flag == SHF_GNU_RETAIN)
7586 sindex = 26;
7587 /* Fall through */
7588 case ELFOSABI_NONE:
7589 if (flag == SHF_GNU_MBIND)
7590 /* We should not recognize SHF_GNU_MBIND for
7591 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7592 not set the EI_OSABI header byte. */
7593 sindex = 24;
7594 break;
cfcac11d
NC
7595 default:
7596 break;
148b93f2 7597 }
99fabbc9 7598 break;
5477e8a0
L
7599 }
7600
91d6fa6a 7601 if (sindex != -1)
5477e8a0 7602 {
8d5ff12c
L
7603 if (p != buff + field_size + 4)
7604 {
7605 if (size < (10 + 2))
bee0ee85
NC
7606 {
7607 warn (_("Internal error: not enough buffer room for section flag info"));
7608 return _("<unknown>");
7609 }
8d5ff12c
L
7610 size -= 2;
7611 *p++ = ',';
7612 *p++ = ' ';
7613 }
7614
91d6fa6a
NC
7615 size -= flags [sindex].len;
7616 p = stpcpy (p, flags [sindex].str);
5477e8a0 7617 }
3b22753a 7618 else if (flag & SHF_MASKOS)
8d5ff12c 7619 os_flags |= flag;
d1133906 7620 else if (flag & SHF_MASKPROC)
8d5ff12c 7621 proc_flags |= flag;
d1133906 7622 else
8d5ff12c 7623 unknown_flags |= flag;
5477e8a0
L
7624 }
7625 else
7626 {
7627 switch (flag)
7628 {
7629 case SHF_WRITE: *p = 'W'; break;
7630 case SHF_ALLOC: *p = 'A'; break;
7631 case SHF_EXECINSTR: *p = 'X'; break;
7632 case SHF_MERGE: *p = 'M'; break;
7633 case SHF_STRINGS: *p = 'S'; break;
7634 case SHF_INFO_LINK: *p = 'I'; break;
7635 case SHF_LINK_ORDER: *p = 'L'; break;
7636 case SHF_OS_NONCONFORMING: *p = 'O'; break;
7637 case SHF_GROUP: *p = 'G'; break;
7638 case SHF_TLS: *p = 'T'; break;
18ae9cc1 7639 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 7640 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
7641
7642 default:
dda8d76d
NC
7643 if ((filedata->file_header.e_machine == EM_X86_64
7644 || filedata->file_header.e_machine == EM_L1OM
7645 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
7646 && flag == SHF_X86_64_LARGE)
7647 *p = 'l';
dda8d76d 7648 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 7649 && flag == SHF_ARM_PURECODE)
99fabbc9 7650 *p = 'y';
dda8d76d 7651 else if (filedata->file_header.e_machine == EM_PPC
83eef883 7652 && flag == SHF_PPC_VLE)
99fabbc9 7653 *p = 'v';
5477e8a0
L
7654 else if (flag & SHF_MASKOS)
7655 {
99fabbc9
JL
7656 switch (filedata->file_header.e_ident[EI_OSABI])
7657 {
7658 case ELFOSABI_GNU:
7659 case ELFOSABI_FREEBSD:
7660 if (flag == SHF_GNU_RETAIN)
7661 {
7662 *p = 'R';
7663 break;
7664 }
7665 /* Fall through */
7666 case ELFOSABI_NONE:
7667 if (flag == SHF_GNU_MBIND)
7668 {
7669 /* We should not recognize SHF_GNU_MBIND for
7670 ELFOSABI_NONE, but binutils as of 2019-07-23 did
7671 not set the EI_OSABI header byte. */
7672 *p = 'D';
7673 break;
7674 }
7675 /* Fall through */
7676 default:
7677 *p = 'o';
7678 sh_flags &= ~SHF_MASKOS;
7679 break;
7680 }
5477e8a0
L
7681 }
7682 else if (flag & SHF_MASKPROC)
7683 {
7684 *p = 'p';
7685 sh_flags &= ~ SHF_MASKPROC;
7686 }
7687 else
7688 *p = 'x';
7689 break;
7690 }
7691 p++;
d1133906
NC
7692 }
7693 }
76da6bbe 7694
8d5ff12c
L
7695 if (do_section_details)
7696 {
7697 if (os_flags)
7698 {
8d5ff12c
L
7699 if (p != buff + field_size + 4)
7700 {
f8c4789c 7701 if (size < 2 + 5 + field_size + 1)
bee0ee85
NC
7702 {
7703 warn (_("Internal error: not enough buffer room for section flag info"));
7704 return _("<unknown>");
7705 }
8d5ff12c
L
7706 size -= 2;
7707 *p++ = ',';
7708 *p++ = ' ';
7709 }
f8c4789c
AM
7710 size -= 5 + field_size;
7711 p += sprintf (p, "OS (%*.*lx)", field_size, field_size,
7712 (unsigned long) os_flags);
8d5ff12c
L
7713 }
7714 if (proc_flags)
7715 {
8d5ff12c
L
7716 if (p != buff + field_size + 4)
7717 {
f8c4789c 7718 if (size < 2 + 7 + field_size + 1)
bee0ee85
NC
7719 {
7720 warn (_("Internal error: not enough buffer room for section flag info"));
7721 return _("<unknown>");
7722 }
8d5ff12c
L
7723 size -= 2;
7724 *p++ = ',';
7725 *p++ = ' ';
7726 }
f8c4789c
AM
7727 size -= 7 + field_size;
7728 p += sprintf (p, "PROC (%*.*lx)", field_size, field_size,
7729 (unsigned long) proc_flags);
8d5ff12c
L
7730 }
7731 if (unknown_flags)
7732 {
8d5ff12c
L
7733 if (p != buff + field_size + 4)
7734 {
f8c4789c 7735 if (size < 2 + 10 + field_size + 1)
bee0ee85
NC
7736 {
7737 warn (_("Internal error: not enough buffer room for section flag info"));
7738 return _("<unknown>");
7739 }
8d5ff12c
L
7740 size -= 2;
7741 *p++ = ',';
7742 *p++ = ' ';
7743 }
f8c4789c
AM
7744 size -= 10 + field_size;
7745 p += sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
7746 (unsigned long) unknown_flags);
8d5ff12c
L
7747 }
7748 }
7749
e9e44622 7750 *p = '\0';
d1133906
NC
7751 return buff;
7752}
7753
5844b465 7754static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
be7d229a
AM
7755get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf,
7756 uint64_t size)
77115a4a
L
7757{
7758 if (is_32bit_elf)
7759 {
7760 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 7761
ebdf1ebf
NC
7762 if (size < sizeof (* echdr))
7763 {
7764 error (_("Compressed section is too small even for a compression header\n"));
7765 return 0;
7766 }
7767
77115a4a
L
7768 chdr->ch_type = BYTE_GET (echdr->ch_type);
7769 chdr->ch_size = BYTE_GET (echdr->ch_size);
7770 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7771 return sizeof (*echdr);
7772 }
7773 else
7774 {
7775 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 7776
ebdf1ebf
NC
7777 if (size < sizeof (* echdr))
7778 {
7779 error (_("Compressed section is too small even for a compression header\n"));
7780 return 0;
7781 }
7782
77115a4a
L
7783 chdr->ch_type = BYTE_GET (echdr->ch_type);
7784 chdr->ch_size = BYTE_GET (echdr->ch_size);
7785 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
7786 return sizeof (*echdr);
7787 }
7788}
7789
015dc7e1 7790static bool
dda8d76d 7791process_section_headers (Filedata * filedata)
252b5132 7792{
2cf0635d 7793 Elf_Internal_Shdr * section;
b34976b6 7794 unsigned int i;
252b5132 7795
dda8d76d 7796 if (filedata->file_header.e_shnum == 0)
252b5132 7797 {
82f2dbf7 7798 /* PR binutils/12467. */
dda8d76d 7799 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
7800 {
7801 warn (_("possibly corrupt ELF file header - it has a non-zero"
7802 " section header offset, but no section headers\n"));
015dc7e1 7803 return false;
32ec8896 7804 }
82f2dbf7 7805 else if (do_sections)
252b5132
RH
7806 printf (_("\nThere are no sections in this file.\n"));
7807
015dc7e1 7808 return true;
252b5132
RH
7809 }
7810
7811 if (do_sections && !do_header)
ca0e11aa
NC
7812 {
7813 if (filedata->is_separate && process_links)
7814 printf (_("In linked file '%s': "), filedata->file_name);
7815 if (! filedata->is_separate || process_links)
7816 printf (ngettext ("There is %d section header, "
26c527e6 7817 "starting at offset %#" PRIx64 ":\n",
ca0e11aa 7818 "There are %d section headers, "
26c527e6 7819 "starting at offset %#" PRIx64 ":\n",
ca0e11aa
NC
7820 filedata->file_header.e_shnum),
7821 filedata->file_header.e_shnum,
26c527e6 7822 filedata->file_header.e_shoff);
ca0e11aa 7823 }
252b5132 7824
4de91c10
AM
7825 if (!get_section_headers (filedata, false))
7826 return false;
252b5132
RH
7827
7828 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
7829 if (filedata->file_header.e_shstrndx != SHN_UNDEF
7830 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 7831 {
dda8d76d 7832 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 7833
c256ffe7
JJ
7834 if (section->sh_size != 0)
7835 {
dda8d76d
NC
7836 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
7837 1, section->sh_size,
7838 _("string table"));
0de14b54 7839
dda8d76d 7840 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 7841 }
252b5132
RH
7842 }
7843
7844 /* Scan the sections for the dynamic symbol table
e3c8793a 7845 and dynamic string table and debug sections. */
89fac5e3 7846 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 7847 switch (filedata->file_header.e_machine)
89fac5e3
RS
7848 {
7849 case EM_MIPS:
7850 case EM_MIPS_RS3_LE:
7851 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
7852 FDE addresses. However, the ABI also has a semi-official ILP32
7853 variant for which the normal FDE address size rules apply.
7854
7855 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
7856 section, where XX is the size of longs in bits. Unfortunately,
7857 earlier compilers provided no way of distinguishing ILP32 objects
7858 from LP64 objects, so if there's any doubt, we should assume that
7859 the official LP64 form is being used. */
d173146d 7860 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == EF_MIPS_ABI_EABI64
dda8d76d 7861 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
7862 eh_addr_size = 8;
7863 break;
0f56a26a
DD
7864
7865 case EM_H8_300:
7866 case EM_H8_300H:
dda8d76d 7867 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7868 {
7869 case E_H8_MACH_H8300:
7870 case E_H8_MACH_H8300HN:
7871 case E_H8_MACH_H8300SN:
7872 case E_H8_MACH_H8300SXN:
7873 eh_addr_size = 2;
7874 break;
7875 case E_H8_MACH_H8300H:
7876 case E_H8_MACH_H8300S:
7877 case E_H8_MACH_H8300SX:
7878 eh_addr_size = 4;
7879 break;
7880 }
f4236fe4
DD
7881 break;
7882
ff7eeb89 7883 case EM_M32C_OLD:
f4236fe4 7884 case EM_M32C:
dda8d76d 7885 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7886 {
7887 case EF_M32C_CPU_M16C:
7888 eh_addr_size = 2;
7889 break;
7890 }
7891 break;
89fac5e3
RS
7892 }
7893
76ca31c0
NC
7894#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7895 do \
7896 { \
be7d229a 7897 uint64_t expected_entsize = is_32bit_elf ? size32 : size64; \
76ca31c0 7898 if (section->sh_entsize != expected_entsize) \
9dd3a467 7899 { \
f493c217 7900 error (_("Section %d has invalid sh_entsize of %" PRIx64 "\n"), \
625d49fc 7901 i, section->sh_entsize); \
f493c217 7902 error (_("(Using the expected size of %" PRIx64 " for the rest of this dump)\n"), \
be7d229a 7903 expected_entsize); \
9dd3a467 7904 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7905 } \
7906 } \
08d8fa11 7907 while (0)
9dd3a467
NC
7908
7909#define CHECK_ENTSIZE(section, i, type) \
1b513401 7910 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7911 sizeof (Elf64_External_##type))
7912
dda8d76d
NC
7913 for (i = 0, section = filedata->section_headers;
7914 i < filedata->file_header.e_shnum;
b34976b6 7915 i++, section++)
252b5132 7916 {
b6ac461a 7917 const char *name = printable_section_name (filedata, section);
252b5132 7918
1b513401
NC
7919 /* Run some sanity checks on the headers and
7920 possibly fill in some file data as well. */
7921 switch (section->sh_type)
252b5132 7922 {
1b513401 7923 case SHT_DYNSYM:
978c4450 7924 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7925 {
7926 error (_("File contains multiple dynamic symbol tables\n"));
7927 continue;
7928 }
7929
08d8fa11 7930 CHECK_ENTSIZE (section, i, Sym);
978c4450 7931 filedata->dynamic_symbols
4de91c10 7932 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7933 filedata->dynamic_symtab_section = section;
1b513401
NC
7934 break;
7935
7936 case SHT_STRTAB:
7937 if (streq (name, ".dynstr"))
252b5132 7938 {
1b513401
NC
7939 if (filedata->dynamic_strings != NULL)
7940 {
7941 error (_("File contains multiple dynamic string tables\n"));
7942 continue;
7943 }
7944
7945 filedata->dynamic_strings
7946 = (char *) get_data (NULL, filedata, section->sh_offset,
7947 1, section->sh_size, _("dynamic strings"));
7948 filedata->dynamic_strings_length
7949 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7950 filedata->dynamic_strtab_section = section;
252b5132 7951 }
1b513401
NC
7952 break;
7953
7954 case SHT_SYMTAB_SHNDX:
7955 {
7956 elf_section_list * entry = xmalloc (sizeof * entry);
7957
7958 entry->hdr = section;
7959 entry->next = filedata->symtab_shndx_list;
7960 filedata->symtab_shndx_list = entry;
7961 }
7962 break;
7963
7964 case SHT_SYMTAB:
7965 CHECK_ENTSIZE (section, i, Sym);
7966 break;
7967
7968 case SHT_GROUP:
7969 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7970 break;
252b5132 7971
1b513401
NC
7972 case SHT_REL:
7973 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7974 if (do_checks && section->sh_size == 0)
1b513401
NC
7975 warn (_("Section '%s': zero-sized relocation section\n"), name);
7976 break;
7977
7978 case SHT_RELA:
7979 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7980 if (do_checks && section->sh_size == 0)
1b513401
NC
7981 warn (_("Section '%s': zero-sized relocation section\n"), name);
7982 break;
7983
682351b9
AM
7984 case SHT_RELR:
7985 CHECK_ENTSIZE (section, i, Relr);
7986 break;
7987
1b513401
NC
7988 case SHT_NOTE:
7989 case SHT_PROGBITS:
546cb2d8
NC
7990 /* Having a zero sized section is not illegal according to the
7991 ELF standard, but it might be an indication that something
7992 is wrong. So issue a warning if we are running in lint mode. */
7993 if (do_checks && section->sh_size == 0)
1b513401
NC
7994 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7995 break;
7996
7997 default:
7998 break;
7999 }
8000
8001 if ((do_debugging || do_debug_info || do_debug_abbrevs
8002 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
8003 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
8004 || do_debug_str || do_debug_str_offsets || do_debug_loc
8005 || do_debug_ranges
1b513401 8006 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
8007 && (startswith (name, ".debug_")
8008 || startswith (name, ".zdebug_")))
252b5132 8009 {
1b315056
CS
8010 if (name[1] == 'z')
8011 name += sizeof (".zdebug_") - 1;
8012 else
8013 name += sizeof (".debug_") - 1;
252b5132
RH
8014
8015 if (do_debugging
24d127aa
ML
8016 || (do_debug_info && startswith (name, "info"))
8017 || (do_debug_info && startswith (name, "types"))
8018 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 8019 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
8020 || (do_debug_lines && startswith (name, "line."))
8021 || (do_debug_pubnames && startswith (name, "pubnames"))
8022 || (do_debug_pubtypes && startswith (name, "pubtypes"))
8023 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
8024 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
8025 || (do_debug_aranges && startswith (name, "aranges"))
8026 || (do_debug_ranges && startswith (name, "ranges"))
8027 || (do_debug_ranges && startswith (name, "rnglists"))
8028 || (do_debug_frames && startswith (name, "frame"))
8029 || (do_debug_macinfo && startswith (name, "macinfo"))
8030 || (do_debug_macinfo && startswith (name, "macro"))
8031 || (do_debug_str && startswith (name, "str"))
8032 || (do_debug_links && startswith (name, "sup"))
8033 || (do_debug_str_offsets && startswith (name, "str_offsets"))
8034 || (do_debug_loc && startswith (name, "loc"))
8035 || (do_debug_loc && startswith (name, "loclists"))
8036 || (do_debug_addr && startswith (name, "addr"))
8037 || (do_debug_cu_index && startswith (name, "cu_index"))
8038 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 8039 )
6431e409 8040 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 8041 }
a262ae96 8042 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 8043 else if ((do_debugging || do_debug_info)
24d127aa 8044 && startswith (name, ".gnu.linkonce.wi."))
6431e409 8045 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 8046 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 8047 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
1878f44b
NC
8048 else if (do_debug_frames && streq (name, ".eh_frame_hdr"))
8049 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
8050 else if (do_gdb_index && (streq (name, ".gdb_index")
8051 || streq (name, ".debug_names")))
6431e409 8052 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
8053 /* Trace sections for Itanium VMS. */
8054 else if ((do_debugging || do_trace_info || do_trace_abbrevs
8055 || do_trace_aranges)
24d127aa 8056 && startswith (name, ".trace_"))
6f875884
TG
8057 {
8058 name += sizeof (".trace_") - 1;
8059
8060 if (do_debugging
8061 || (do_trace_info && streq (name, "info"))
8062 || (do_trace_abbrevs && streq (name, "abbrev"))
8063 || (do_trace_aranges && streq (name, "aranges"))
8064 )
6431e409 8065 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 8066 }
dda8d76d 8067 else if ((do_debugging || do_debug_links)
24d127aa
ML
8068 && (startswith (name, ".gnu_debuglink")
8069 || startswith (name, ".gnu_debugaltlink")))
6431e409 8070 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
8071 }
8072
8073 if (! do_sections)
015dc7e1 8074 return true;
252b5132 8075
ca0e11aa 8076 if (filedata->is_separate && ! process_links)
015dc7e1 8077 return true;
ca0e11aa
NC
8078
8079 if (filedata->is_separate)
8080 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
8081 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
8082 printf (_("\nSection Headers:\n"));
8083 else
8084 printf (_("\nSection Header:\n"));
76da6bbe 8085
f7a99963 8086 if (is_32bit_elf)
595cf52e 8087 {
5477e8a0 8088 if (do_section_details)
595cf52e
L
8089 {
8090 printf (_(" [Nr] Name\n"));
5477e8a0 8091 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
8092 }
8093 else
8094 printf
8095 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
8096 }
d974e256 8097 else if (do_wide)
595cf52e 8098 {
5477e8a0 8099 if (do_section_details)
595cf52e
L
8100 {
8101 printf (_(" [Nr] Name\n"));
5477e8a0 8102 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
8103 }
8104 else
8105 printf
8106 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
8107 }
f7a99963
NC
8108 else
8109 {
5477e8a0 8110 if (do_section_details)
595cf52e
L
8111 {
8112 printf (_(" [Nr] Name\n"));
5477e8a0
L
8113 printf (_(" Type Address Offset Link\n"));
8114 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
8115 }
8116 else
8117 {
8118 printf (_(" [Nr] Name Type Address Offset\n"));
8119 printf (_(" Size EntSize Flags Link Info Align\n"));
8120 }
f7a99963 8121 }
252b5132 8122
5477e8a0
L
8123 if (do_section_details)
8124 printf (_(" Flags\n"));
8125
dda8d76d
NC
8126 for (i = 0, section = filedata->section_headers;
8127 i < filedata->file_header.e_shnum;
b34976b6 8128 i++, section++)
252b5132 8129 {
dd905818
NC
8130 /* Run some sanity checks on the section header. */
8131
8132 /* Check the sh_link field. */
8133 switch (section->sh_type)
8134 {
285e3f99 8135 case SHT_REL:
fcf8f323 8136 case SHT_RELR:
285e3f99
AM
8137 case SHT_RELA:
8138 if (section->sh_link == 0
8139 && (filedata->file_header.e_type == ET_EXEC
8140 || filedata->file_header.e_type == ET_DYN))
8141 /* A dynamic relocation section where all entries use a
8142 zero symbol index need not specify a symtab section. */
8143 break;
8144 /* Fall through. */
dd905818
NC
8145 case SHT_SYMTAB_SHNDX:
8146 case SHT_GROUP:
8147 case SHT_HASH:
8148 case SHT_GNU_HASH:
8149 case SHT_GNU_versym:
285e3f99 8150 if (section->sh_link == 0
dda8d76d
NC
8151 || section->sh_link >= filedata->file_header.e_shnum
8152 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
8153 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
8154 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
8155 i, section->sh_link);
8156 break;
8157
8158 case SHT_DYNAMIC:
8159 case SHT_SYMTAB:
8160 case SHT_DYNSYM:
8161 case SHT_GNU_verneed:
8162 case SHT_GNU_verdef:
8163 case SHT_GNU_LIBLIST:
285e3f99 8164 if (section->sh_link == 0
dda8d76d
NC
8165 || section->sh_link >= filedata->file_header.e_shnum
8166 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
8167 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
8168 i, section->sh_link);
8169 break;
8170
8171 case SHT_INIT_ARRAY:
8172 case SHT_FINI_ARRAY:
8173 case SHT_PREINIT_ARRAY:
8174 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8175 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8176 i, section->sh_link);
8177 break;
8178
8179 default:
8180 /* FIXME: Add support for target specific section types. */
8181#if 0 /* Currently we do not check other section types as there are too
8182 many special cases. Stab sections for example have a type
8183 of SHT_PROGBITS but an sh_link field that links to the .stabstr
8184 section. */
8185 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
8186 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
8187 i, section->sh_link);
8188#endif
8189 break;
8190 }
8191
8192 /* Check the sh_info field. */
8193 switch (section->sh_type)
8194 {
8195 case SHT_REL:
8196 case SHT_RELA:
285e3f99
AM
8197 if (section->sh_info == 0
8198 && (filedata->file_header.e_type == ET_EXEC
8199 || filedata->file_header.e_type == ET_DYN))
8200 /* Dynamic relocations apply to segments, so they do not
8201 need to specify the section they relocate. */
8202 break;
8203 if (section->sh_info == 0
dda8d76d
NC
8204 || section->sh_info >= filedata->file_header.e_shnum
8205 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
8206 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
8207 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
8208 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
8209 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
8210 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 8211 /* FIXME: Are other section types valid ? */
dda8d76d 8212 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
8213 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
8214 i, section->sh_info);
dd905818
NC
8215 break;
8216
8217 case SHT_DYNAMIC:
8218 case SHT_HASH:
8219 case SHT_SYMTAB_SHNDX:
8220 case SHT_INIT_ARRAY:
8221 case SHT_FINI_ARRAY:
8222 case SHT_PREINIT_ARRAY:
8223 if (section->sh_info != 0)
8224 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8225 i, section->sh_info);
8226 break;
8227
8228 case SHT_GROUP:
8229 case SHT_SYMTAB:
8230 case SHT_DYNSYM:
8231 /* A symbol index - we assume that it is valid. */
8232 break;
8233
8234 default:
8235 /* FIXME: Add support for target specific section types. */
8236 if (section->sh_type == SHT_NOBITS)
8237 /* NOBITS section headers with non-zero sh_info fields can be
8238 created when a binary is stripped of everything but its debug
1a9ccd70
NC
8239 information. The stripped sections have their headers
8240 preserved but their types set to SHT_NOBITS. So do not check
8241 this type of section. */
dd905818
NC
8242 ;
8243 else if (section->sh_flags & SHF_INFO_LINK)
8244 {
dda8d76d 8245 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
8246 warn (_("[%2u]: Expected link to another section in info field"), i);
8247 }
a91e1603
L
8248 else if (section->sh_type < SHT_LOOS
8249 && (section->sh_flags & SHF_GNU_MBIND) == 0
8250 && section->sh_info != 0)
dd905818
NC
8251 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
8252 i, section->sh_info);
8253 break;
8254 }
8255
3e6b6445 8256 /* Check the sh_size field. */
dda8d76d 8257 if (section->sh_size > filedata->file_size
3e6b6445
NC
8258 && section->sh_type != SHT_NOBITS
8259 && section->sh_type != SHT_NULL
8260 && section->sh_type < SHT_LOOS)
8261 warn (_("Size of section %u is larger than the entire file!\n"), i);
8262
7bfd842d 8263 printf (" [%2u] ", i);
5477e8a0 8264 if (do_section_details)
dda8d76d 8265 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 8266 else
b6ac461a 8267 print_symbol_name (-17, printable_section_name (filedata, section));
0b4362b0 8268
ea52a088 8269 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 8270 get_section_type_name (filedata, section->sh_type));
0b4362b0 8271
f7a99963
NC
8272 if (is_32bit_elf)
8273 {
cfcac11d
NC
8274 const char * link_too_big = NULL;
8275
f7a99963 8276 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 8277
f7a99963
NC
8278 printf ( " %6.6lx %6.6lx %2.2lx",
8279 (unsigned long) section->sh_offset,
8280 (unsigned long) section->sh_size,
8281 (unsigned long) section->sh_entsize);
d1133906 8282
5477e8a0
L
8283 if (do_section_details)
8284 fputs (" ", stdout);
8285 else
dda8d76d 8286 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8287
dda8d76d 8288 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
8289 {
8290 link_too_big = "";
8291 /* The sh_link value is out of range. Normally this indicates
caa83f8b 8292 an error but it can have special values in Solaris binaries. */
dda8d76d 8293 switch (filedata->file_header.e_machine)
cfcac11d 8294 {
caa83f8b 8295 case EM_386:
22abe556 8296 case EM_IAMCU:
caa83f8b 8297 case EM_X86_64:
7f502d6c 8298 case EM_L1OM:
7a9068fe 8299 case EM_K1OM:
cfcac11d
NC
8300 case EM_OLD_SPARCV9:
8301 case EM_SPARC32PLUS:
8302 case EM_SPARCV9:
8303 case EM_SPARC:
8304 if (section->sh_link == (SHN_BEFORE & 0xffff))
8305 link_too_big = "BEFORE";
8306 else if (section->sh_link == (SHN_AFTER & 0xffff))
8307 link_too_big = "AFTER";
8308 break;
8309 default:
8310 break;
8311 }
8312 }
8313
8314 if (do_section_details)
8315 {
8316 if (link_too_big != NULL && * link_too_big)
8317 printf ("<%s> ", link_too_big);
8318 else
8319 printf ("%2u ", section->sh_link);
8320 printf ("%3u %2lu\n", section->sh_info,
8321 (unsigned long) section->sh_addralign);
8322 }
8323 else
8324 printf ("%2u %3u %2lu\n",
8325 section->sh_link,
8326 section->sh_info,
8327 (unsigned long) section->sh_addralign);
8328
8329 if (link_too_big && ! * link_too_big)
8330 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
8331 i, section->sh_link);
f7a99963 8332 }
d974e256
JJ
8333 else if (do_wide)
8334 {
8335 print_vma (section->sh_addr, LONG_HEX);
8336
8337 if ((long) section->sh_offset == section->sh_offset)
8338 printf (" %6.6lx", (unsigned long) section->sh_offset);
8339 else
8340 {
8341 putchar (' ');
8342 print_vma (section->sh_offset, LONG_HEX);
8343 }
8344
8345 if ((unsigned long) section->sh_size == section->sh_size)
8346 printf (" %6.6lx", (unsigned long) section->sh_size);
8347 else
8348 {
8349 putchar (' ');
8350 print_vma (section->sh_size, LONG_HEX);
8351 }
8352
8353 if ((unsigned long) section->sh_entsize == section->sh_entsize)
8354 printf (" %2.2lx", (unsigned long) section->sh_entsize);
8355 else
8356 {
8357 putchar (' ');
8358 print_vma (section->sh_entsize, LONG_HEX);
8359 }
8360
5477e8a0
L
8361 if (do_section_details)
8362 fputs (" ", stdout);
8363 else
dda8d76d 8364 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 8365
72de5009 8366 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
8367
8368 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 8369 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
8370 else
8371 {
8372 print_vma (section->sh_addralign, DEC);
8373 putchar ('\n');
8374 }
8375 }
5477e8a0 8376 else if (do_section_details)
595cf52e 8377 {
55cc53e9 8378 putchar (' ');
595cf52e
L
8379 print_vma (section->sh_addr, LONG_HEX);
8380 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 8381 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
8382 else
8383 {
8384 printf (" ");
8385 print_vma (section->sh_offset, LONG_HEX);
8386 }
72de5009 8387 printf (" %u\n ", section->sh_link);
595cf52e 8388 print_vma (section->sh_size, LONG_HEX);
5477e8a0 8389 putchar (' ');
595cf52e
L
8390 print_vma (section->sh_entsize, LONG_HEX);
8391
72de5009
AM
8392 printf (" %-16u %lu\n",
8393 section->sh_info,
595cf52e
L
8394 (unsigned long) section->sh_addralign);
8395 }
f7a99963
NC
8396 else
8397 {
8398 putchar (' ');
8399 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
8400 if ((long) section->sh_offset == section->sh_offset)
8401 printf (" %8.8lx", (unsigned long) section->sh_offset);
8402 else
8403 {
8404 printf (" ");
8405 print_vma (section->sh_offset, LONG_HEX);
8406 }
f7a99963
NC
8407 printf ("\n ");
8408 print_vma (section->sh_size, LONG_HEX);
8409 printf (" ");
8410 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 8411
dda8d76d 8412 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 8413
72de5009
AM
8414 printf (" %2u %3u %lu\n",
8415 section->sh_link,
8416 section->sh_info,
f7a99963
NC
8417 (unsigned long) section->sh_addralign);
8418 }
5477e8a0
L
8419
8420 if (do_section_details)
77115a4a 8421 {
dda8d76d 8422 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
8423 if ((section->sh_flags & SHF_COMPRESSED) != 0)
8424 {
8425 /* Minimum section size is 12 bytes for 32-bit compression
8426 header + 12 bytes for compressed data header. */
8427 unsigned char buf[24];
d8024a91 8428
77115a4a 8429 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 8430 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
8431 sizeof (buf), _("compression header")))
8432 {
8433 Elf_Internal_Chdr chdr;
d8024a91 8434
5844b465
NC
8435 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
8436 printf (_(" [<corrupt>]\n"));
77115a4a 8437 else
5844b465 8438 {
89dbeac7 8439 if (chdr.ch_type == ch_compress_zlib)
5844b465 8440 printf (" ZLIB, ");
89dbeac7 8441 else if (chdr.ch_type == ch_compress_zstd)
1369522f 8442 printf (" ZSTD, ");
5844b465
NC
8443 else
8444 printf (_(" [<unknown>: 0x%x], "),
8445 chdr.ch_type);
8446 print_vma (chdr.ch_size, LONG_HEX);
8447 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
8448 }
77115a4a
L
8449 }
8450 }
8451 }
252b5132
RH
8452 }
8453
5477e8a0 8454 if (!do_section_details)
3dbcc61d 8455 {
9fb71ee4
NC
8456 /* The ordering of the letters shown here matches the ordering of the
8457 corresponding SHF_xxx values, and hence the order in which these
8458 letters will be displayed to the user. */
8459 printf (_("Key to Flags:\n\
8460 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
8461 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 8462 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
8463 switch (filedata->file_header.e_ident[EI_OSABI])
8464 {
8465 case ELFOSABI_GNU:
8466 case ELFOSABI_FREEBSD:
8467 printf (_("R (retain), "));
8468 /* Fall through */
8469 case ELFOSABI_NONE:
8470 printf (_("D (mbind), "));
8471 break;
8472 default:
8473 break;
8474 }
dda8d76d
NC
8475 if (filedata->file_header.e_machine == EM_X86_64
8476 || filedata->file_header.e_machine == EM_L1OM
8477 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 8478 printf (_("l (large), "));
dda8d76d 8479 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 8480 printf (_("y (purecode), "));
dda8d76d 8481 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 8482 printf (_("v (VLE), "));
9fb71ee4 8483 printf ("p (processor specific)\n");
0b4362b0 8484 }
d1133906 8485
015dc7e1 8486 return true;
252b5132
RH
8487}
8488
015dc7e1 8489static bool
fcf8f323
NC
8490get_symtab (Filedata * filedata,
8491 Elf_Internal_Shdr * symsec,
8492 Elf_Internal_Sym ** symtab,
8493 uint64_t * nsyms,
8494 char ** strtab,
8495 uint64_t * strtablen)
28d13567
AM
8496{
8497 *strtab = NULL;
8498 *strtablen = 0;
4de91c10 8499 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
8500
8501 if (*symtab == NULL)
015dc7e1 8502 return false;
28d13567
AM
8503
8504 if (symsec->sh_link != 0)
8505 {
8506 Elf_Internal_Shdr *strsec;
8507
8508 if (symsec->sh_link >= filedata->file_header.e_shnum)
8509 {
8510 error (_("Bad sh_link in symbol table section\n"));
8511 free (*symtab);
8512 *symtab = NULL;
8513 *nsyms = 0;
015dc7e1 8514 return false;
28d13567
AM
8515 }
8516
8517 strsec = filedata->section_headers + symsec->sh_link;
8518
8519 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
8520 1, strsec->sh_size, _("string table"));
8521 if (*strtab == NULL)
8522 {
8523 free (*symtab);
8524 *symtab = NULL;
8525 *nsyms = 0;
015dc7e1 8526 return false;
28d13567
AM
8527 }
8528 *strtablen = strsec->sh_size;
8529 }
015dc7e1 8530 return true;
28d13567
AM
8531}
8532
f5842774
L
8533static const char *
8534get_group_flags (unsigned int flags)
8535{
1449284b 8536 static char buff[128];
220453ec 8537
6d913794
NC
8538 if (flags == 0)
8539 return "";
8540 else if (flags == GRP_COMDAT)
8541 return "COMDAT ";
f5842774 8542
89246a0e
AM
8543 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
8544 flags,
8545 flags & GRP_MASKOS ? _("<OS specific>") : "",
8546 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
8547 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
8548 ? _("<unknown>") : ""));
6d913794 8549
f5842774
L
8550 return buff;
8551}
8552
015dc7e1 8553static bool
dda8d76d 8554process_section_groups (Filedata * filedata)
f5842774 8555{
2cf0635d 8556 Elf_Internal_Shdr * section;
f5842774 8557 unsigned int i;
2cf0635d
NC
8558 struct group * group;
8559 Elf_Internal_Shdr * symtab_sec;
8560 Elf_Internal_Shdr * strtab_sec;
8561 Elf_Internal_Sym * symtab;
26c527e6 8562 uint64_t num_syms;
2cf0635d 8563 char * strtab;
c256ffe7 8564 size_t strtab_size;
d1f5c6e3
L
8565
8566 /* Don't process section groups unless needed. */
8567 if (!do_unwind && !do_section_groups)
015dc7e1 8568 return true;
f5842774 8569
dda8d76d 8570 if (filedata->file_header.e_shnum == 0)
f5842774
L
8571 {
8572 if (do_section_groups)
ca0e11aa
NC
8573 {
8574 if (filedata->is_separate)
8575 printf (_("\nThere are no sections group in linked file '%s'.\n"),
8576 filedata->file_name);
8577 else
8578 printf (_("\nThere are no section groups in this file.\n"));
8579 }
015dc7e1 8580 return true;
f5842774
L
8581 }
8582
dda8d76d 8583 if (filedata->section_headers == NULL)
f5842774
L
8584 {
8585 error (_("Section headers are not available!\n"));
fa1908fd 8586 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 8587 return false;
f5842774
L
8588 }
8589
978c4450
AM
8590 filedata->section_headers_groups
8591 = (struct group **) calloc (filedata->file_header.e_shnum,
8592 sizeof (struct group *));
e4b17d5c 8593
978c4450 8594 if (filedata->section_headers_groups == NULL)
e4b17d5c 8595 {
8b73c356 8596 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 8597 filedata->file_header.e_shnum);
015dc7e1 8598 return false;
e4b17d5c
L
8599 }
8600
f5842774 8601 /* Scan the sections for the group section. */
978c4450 8602 filedata->group_count = 0;
dda8d76d
NC
8603 for (i = 0, section = filedata->section_headers;
8604 i < filedata->file_header.e_shnum;
f5842774 8605 i++, section++)
e4b17d5c 8606 if (section->sh_type == SHT_GROUP)
978c4450 8607 filedata->group_count++;
e4b17d5c 8608
978c4450 8609 if (filedata->group_count == 0)
d1f5c6e3
L
8610 {
8611 if (do_section_groups)
ca0e11aa
NC
8612 {
8613 if (filedata->is_separate)
8614 printf (_("\nThere are no section groups in linked file '%s'.\n"),
8615 filedata->file_name);
8616 else
8617 printf (_("\nThere are no section groups in this file.\n"));
8618 }
d1f5c6e3 8619
015dc7e1 8620 return true;
d1f5c6e3
L
8621 }
8622
978c4450
AM
8623 filedata->section_groups = (struct group *) calloc (filedata->group_count,
8624 sizeof (struct group));
e4b17d5c 8625
978c4450 8626 if (filedata->section_groups == NULL)
e4b17d5c 8627 {
26c527e6 8628 error (_("Out of memory reading %zu groups\n"), filedata->group_count);
015dc7e1 8629 return false;
e4b17d5c
L
8630 }
8631
d1f5c6e3
L
8632 symtab_sec = NULL;
8633 strtab_sec = NULL;
8634 symtab = NULL;
ba5cdace 8635 num_syms = 0;
d1f5c6e3 8636 strtab = NULL;
c256ffe7 8637 strtab_size = 0;
ca0e11aa
NC
8638
8639 if (filedata->is_separate)
8640 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 8641
978c4450 8642 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 8643 i < filedata->file_header.e_shnum;
e4b17d5c 8644 i++, section++)
f5842774
L
8645 {
8646 if (section->sh_type == SHT_GROUP)
8647 {
dda8d76d 8648 const char * name = printable_section_name (filedata, section);
74e1a04b 8649 const char * group_name;
2cf0635d
NC
8650 unsigned char * start;
8651 unsigned char * indices;
f5842774 8652 unsigned int entry, j, size;
2cf0635d
NC
8653 Elf_Internal_Shdr * sec;
8654 Elf_Internal_Sym * sym;
f5842774
L
8655
8656 /* Get the symbol table. */
dda8d76d
NC
8657 if (section->sh_link >= filedata->file_header.e_shnum
8658 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 8659 != SHT_SYMTAB))
f5842774
L
8660 {
8661 error (_("Bad sh_link in group section `%s'\n"), name);
8662 continue;
8663 }
d1f5c6e3
L
8664
8665 if (symtab_sec != sec)
8666 {
8667 symtab_sec = sec;
9db70fc3 8668 free (symtab);
4de91c10 8669 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 8670 }
f5842774 8671
dd24e3da
NC
8672 if (symtab == NULL)
8673 {
8674 error (_("Corrupt header in group section `%s'\n"), name);
8675 continue;
8676 }
8677
ba5cdace
NC
8678 if (section->sh_info >= num_syms)
8679 {
8680 error (_("Bad sh_info in group section `%s'\n"), name);
8681 continue;
8682 }
8683
f5842774
L
8684 sym = symtab + section->sh_info;
8685
8686 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
8687 {
4fbb74a6 8688 if (sym->st_shndx == 0
dda8d76d 8689 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
8690 {
8691 error (_("Bad sh_info in group section `%s'\n"), name);
8692 continue;
8693 }
ba2685cc 8694
b6ac461a
NC
8695 group_name = printable_section_name (filedata,
8696 filedata->section_headers
8697 + sym->st_shndx);
c256ffe7 8698 strtab_sec = NULL;
9db70fc3 8699 free (strtab);
f5842774 8700 strtab = NULL;
c256ffe7 8701 strtab_size = 0;
f5842774
L
8702 }
8703 else
8704 {
8705 /* Get the string table. */
dda8d76d 8706 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
8707 {
8708 strtab_sec = NULL;
9db70fc3 8709 free (strtab);
c256ffe7
JJ
8710 strtab = NULL;
8711 strtab_size = 0;
8712 }
8713 else if (strtab_sec
dda8d76d 8714 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
8715 {
8716 strtab_sec = sec;
9db70fc3 8717 free (strtab);
071436c6 8718
dda8d76d 8719 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
8720 1, strtab_sec->sh_size,
8721 _("string table"));
c256ffe7 8722 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 8723 }
c256ffe7 8724 group_name = sym->st_name < strtab_size
2b692964 8725 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
8726 }
8727
c9c1d674
EG
8728 /* PR 17531: file: loop. */
8729 if (section->sh_entsize > section->sh_size)
8730 {
26c527e6
AM
8731 error (_("Section %s has sh_entsize (%#" PRIx64 ")"
8732 " which is larger than its size (%#" PRIx64 ")\n"),
dda8d76d 8733 printable_section_name (filedata, section),
26c527e6
AM
8734 section->sh_entsize,
8735 section->sh_size);
61dd8e19 8736 continue;
c9c1d674
EG
8737 }
8738
dda8d76d 8739 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
8740 1, section->sh_size,
8741 _("section data"));
59245841
NC
8742 if (start == NULL)
8743 continue;
f5842774
L
8744
8745 indices = start;
8746 size = (section->sh_size / section->sh_entsize) - 1;
8747 entry = byte_get (indices, 4);
8748 indices += 4;
e4b17d5c
L
8749
8750 if (do_section_groups)
8751 {
2b692964 8752 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 8753 get_group_flags (entry), i, name, group_name, size);
ba2685cc 8754
e4b17d5c
L
8755 printf (_(" [Index] Name\n"));
8756 }
8757
8758 group->group_index = i;
8759
f5842774
L
8760 for (j = 0; j < size; j++)
8761 {
2cf0635d 8762 struct group_list * g;
e4b17d5c 8763
f5842774
L
8764 entry = byte_get (indices, 4);
8765 indices += 4;
8766
dda8d76d 8767 if (entry >= filedata->file_header.e_shnum)
391cb864 8768 {
57028622
NC
8769 static unsigned num_group_errors = 0;
8770
8771 if (num_group_errors ++ < 10)
8772 {
8773 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 8774 entry, i, filedata->file_header.e_shnum - 1);
57028622 8775 if (num_group_errors == 10)
67ce483b 8776 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 8777 }
391cb864
L
8778 continue;
8779 }
391cb864 8780
978c4450 8781 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 8782 {
d1f5c6e3
L
8783 if (entry)
8784 {
57028622
NC
8785 static unsigned num_errs = 0;
8786
8787 if (num_errs ++ < 10)
8788 {
8789 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
8790 entry, i,
978c4450 8791 filedata->section_headers_groups [entry]->group_index);
57028622
NC
8792 if (num_errs == 10)
8793 warn (_("Further error messages about already contained group sections suppressed\n"));
8794 }
d1f5c6e3
L
8795 continue;
8796 }
8797 else
8798 {
8799 /* Intel C/C++ compiler may put section 0 in a
32ec8896 8800 section group. We just warn it the first time
d1f5c6e3 8801 and ignore it afterwards. */
015dc7e1 8802 static bool warned = false;
d1f5c6e3
L
8803 if (!warned)
8804 {
8805 error (_("section 0 in group section [%5u]\n"),
978c4450 8806 filedata->section_headers_groups [entry]->group_index);
015dc7e1 8807 warned = true;
d1f5c6e3
L
8808 }
8809 }
e4b17d5c
L
8810 }
8811
978c4450 8812 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
8813
8814 if (do_section_groups)
8815 {
dda8d76d
NC
8816 sec = filedata->section_headers + entry;
8817 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
8818 }
8819
3f5e193b 8820 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
8821 g->section_index = entry;
8822 g->next = group->root;
8823 group->root = g;
f5842774
L
8824 }
8825
9db70fc3 8826 free (start);
e4b17d5c
L
8827
8828 group++;
f5842774
L
8829 }
8830 }
8831
9db70fc3
AM
8832 free (symtab);
8833 free (strtab);
015dc7e1 8834 return true;
f5842774
L
8835}
8836
28f997cf
TG
8837/* Data used to display dynamic fixups. */
8838
8839struct ia64_vms_dynfixup
8840{
625d49fc
AM
8841 uint64_t needed_ident; /* Library ident number. */
8842 uint64_t needed; /* Index in the dstrtab of the library name. */
8843 uint64_t fixup_needed; /* Index of the library. */
8844 uint64_t fixup_rela_cnt; /* Number of fixups. */
8845 uint64_t fixup_rela_off; /* Fixups offset in the dynamic segment. */
28f997cf
TG
8846};
8847
8848/* Data used to display dynamic relocations. */
8849
8850struct ia64_vms_dynimgrela
8851{
625d49fc
AM
8852 uint64_t img_rela_cnt; /* Number of relocations. */
8853 uint64_t img_rela_off; /* Reloc offset in the dynamic segment. */
28f997cf
TG
8854};
8855
8856/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
8857 library). */
8858
015dc7e1 8859static bool
dda8d76d
NC
8860dump_ia64_vms_dynamic_fixups (Filedata * filedata,
8861 struct ia64_vms_dynfixup * fixup,
8862 const char * strtab,
8863 unsigned int strtab_sz)
28f997cf 8864{
32ec8896 8865 Elf64_External_VMS_IMAGE_FIXUP * imfs;
26c527e6 8866 size_t i;
32ec8896 8867 const char * lib_name;
28f997cf 8868
978c4450
AM
8869 imfs = get_data (NULL, filedata,
8870 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8871 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8872 _("dynamic section image fixups"));
8873 if (!imfs)
015dc7e1 8874 return false;
28f997cf
TG
8875
8876 if (fixup->needed < strtab_sz)
8877 lib_name = strtab + fixup->needed;
8878 else
8879 {
26c527e6
AM
8880 warn (_("corrupt library name index of %#" PRIx64
8881 " found in dynamic entry"), fixup->needed);
28f997cf
TG
8882 lib_name = "???";
8883 }
736990c4 8884
26c527e6
AM
8885 printf (_("\nImage fixups for needed library #%" PRId64
8886 ": %s - ident: %" PRIx64 "\n"),
8887 fixup->fixup_needed, lib_name, fixup->needed_ident);
28f997cf
TG
8888 printf
8889 (_("Seg Offset Type SymVec DataType\n"));
8890
26c527e6 8891 for (i = 0; i < (size_t) fixup->fixup_rela_cnt; i++)
28f997cf
TG
8892 {
8893 unsigned int type;
8894 const char *rtype;
8895
8896 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
625d49fc 8897 printf ("%016" PRIx64 " ", BYTE_GET (imfs [i].fixup_offset));
28f997cf
TG
8898 type = BYTE_GET (imfs [i].type);
8899 rtype = elf_ia64_reloc_type (type);
8900 if (rtype == NULL)
f493c217 8901 printf ("0x%08x ", type);
28f997cf 8902 else
f493c217 8903 printf ("%-32s ", rtype);
28f997cf
TG
8904 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8905 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8906 }
8907
8908 free (imfs);
015dc7e1 8909 return true;
28f997cf
TG
8910}
8911
8912/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8913
015dc7e1 8914static bool
dda8d76d 8915dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8916{
8917 Elf64_External_VMS_IMAGE_RELA *imrs;
26c527e6 8918 size_t i;
28f997cf 8919
978c4450
AM
8920 imrs = get_data (NULL, filedata,
8921 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8922 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8923 _("dynamic section image relocations"));
28f997cf 8924 if (!imrs)
015dc7e1 8925 return false;
28f997cf
TG
8926
8927 printf (_("\nImage relocs\n"));
8928 printf
8929 (_("Seg Offset Type Addend Seg Sym Off\n"));
8930
26c527e6 8931 for (i = 0; i < (size_t) imgrela->img_rela_cnt; i++)
28f997cf
TG
8932 {
8933 unsigned int type;
8934 const char *rtype;
8935
8936 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
625d49fc 8937 printf ("%08" PRIx64 " ", BYTE_GET (imrs [i].rela_offset));
28f997cf
TG
8938 type = BYTE_GET (imrs [i].type);
8939 rtype = elf_ia64_reloc_type (type);
8940 if (rtype == NULL)
8941 printf ("0x%08x ", type);
8942 else
8943 printf ("%-31s ", rtype);
8944 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8945 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
625d49fc 8946 printf ("%08" PRIx64 "\n", BYTE_GET (imrs [i].sym_offset));
28f997cf
TG
8947 }
8948
8949 free (imrs);
015dc7e1 8950 return true;
28f997cf
TG
8951}
8952
8953/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8954
015dc7e1 8955static bool
dda8d76d 8956process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8957{
8958 struct ia64_vms_dynfixup fixup;
8959 struct ia64_vms_dynimgrela imgrela;
8960 Elf_Internal_Dyn *entry;
625d49fc
AM
8961 uint64_t strtab_off = 0;
8962 uint64_t strtab_sz = 0;
28f997cf 8963 char *strtab = NULL;
015dc7e1 8964 bool res = true;
28f997cf
TG
8965
8966 memset (&fixup, 0, sizeof (fixup));
8967 memset (&imgrela, 0, sizeof (imgrela));
8968
8969 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8970 for (entry = filedata->dynamic_section;
8971 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8972 entry++)
8973 {
8974 switch (entry->d_tag)
8975 {
8976 case DT_IA_64_VMS_STRTAB_OFFSET:
8977 strtab_off = entry->d_un.d_val;
8978 break;
8979 case DT_STRSZ:
8980 strtab_sz = entry->d_un.d_val;
8981 if (strtab == NULL)
978c4450
AM
8982 strtab = get_data (NULL, filedata,
8983 filedata->dynamic_addr + strtab_off,
28f997cf 8984 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8985 if (strtab == NULL)
8986 strtab_sz = 0;
28f997cf
TG
8987 break;
8988
8989 case DT_IA_64_VMS_NEEDED_IDENT:
8990 fixup.needed_ident = entry->d_un.d_val;
8991 break;
8992 case DT_NEEDED:
8993 fixup.needed = entry->d_un.d_val;
8994 break;
8995 case DT_IA_64_VMS_FIXUP_NEEDED:
8996 fixup.fixup_needed = entry->d_un.d_val;
8997 break;
8998 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8999 fixup.fixup_rela_cnt = entry->d_un.d_val;
9000 break;
9001 case DT_IA_64_VMS_FIXUP_RELA_OFF:
9002 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 9003 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 9004 res = false;
28f997cf 9005 break;
28f997cf
TG
9006 case DT_IA_64_VMS_IMG_RELA_CNT:
9007 imgrela.img_rela_cnt = entry->d_un.d_val;
9008 break;
9009 case DT_IA_64_VMS_IMG_RELA_OFF:
9010 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 9011 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 9012 res = false;
28f997cf
TG
9013 break;
9014
9015 default:
9016 break;
9017 }
9018 }
9019
9db70fc3 9020 free (strtab);
28f997cf
TG
9021
9022 return res;
9023}
9024
85b1c36d 9025static struct
566b0d53 9026{
2cf0635d 9027 const char * name;
566b0d53
L
9028 int reloc;
9029 int size;
a7fd1186 9030 relocation_type rel_type;
32ec8896
NC
9031}
9032 dynamic_relocations [] =
566b0d53 9033{
a7fd1186
FS
9034 { "REL", DT_REL, DT_RELSZ, reltype_rel },
9035 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
9036 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
9037 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
9038};
9039
8e8d0b63
NC
9040static relocation_type
9041rel_type_from_sh_type (unsigned int sh_type)
9042{
9043 switch (sh_type)
9044 {
9045 case SHT_RELA: return reltype_rela;
9046 case SHT_REL: return reltype_rel;
9047 case SHT_RELR: return reltype_relr;
9048 default: return reltype_unknown;
9049 }
9050}
9051
9052static bool
9053display_relocations (Elf_Internal_Shdr * section,
9054 Filedata * filedata)
9055{
fcf8f323
NC
9056 relocation_type rel_type = rel_type_from_sh_type (section->sh_type);
9057
9058 if (rel_type == reltype_unknown)
8e8d0b63
NC
9059 return false;
9060
9061 uint64_t rel_size = section->sh_size;
9062
9063 if (rel_size == 0)
9064 return false;
9065
9066 if (filedata->is_separate)
9067 printf (_("\nIn linked file '%s' relocation section "),
9068 filedata->file_name);
9069 else
9070 printf (_("\nRelocation section "));
9071
9072 if (filedata->string_table == NULL)
9073 printf ("%d", section->sh_name);
9074 else
9075 printf ("'%s'", printable_section_name (filedata, section));
9076
9077 uint64_t num_rela = rel_size / section->sh_entsize;
9078 uint64_t rel_offset = section->sh_offset;
9079
9080 printf (ngettext (" at offset %#" PRIx64
9081 " contains %" PRIu64 " entry:\n",
9082 " at offset %#" PRIx64
9083 " contains %" PRId64 " entries:\n",
9084 num_rela),
9085 rel_offset, num_rela);
9086
fcf8f323
NC
9087 Elf_Internal_Shdr * symsec;
9088 Elf_Internal_Sym * symtab = NULL;
9089 uint64_t nsyms = 0;
9090 uint64_t strtablen = 0;
9091 char * strtab = NULL;
8e8d0b63
NC
9092
9093 if (section->sh_link == 0
9094 || section->sh_link >= filedata->file_header.e_shnum)
fcf8f323
NC
9095 {
9096 /* Symbol data not available.
9097 This can happen, especially with RELR relocs.
9098 See if there is a .symtab section present.
9099 If so then use it. */
9100 symsec = find_section_by_name (filedata, ".symtab");
9101 }
9102 else
9103 {
9104 symsec = filedata->section_headers + section->sh_link;
8e8d0b63 9105
fcf8f323
NC
9106 if (symsec->sh_type != SHT_SYMTAB
9107 && symsec->sh_type != SHT_DYNSYM)
9108 return false;
9109 }
8e8d0b63 9110
fcf8f323
NC
9111 if (symsec != NULL
9112 && !get_symtab (filedata, symsec, &symtab, &nsyms, &strtab, &strtablen))
8e8d0b63
NC
9113 return false;
9114
fcf8f323
NC
9115 bool res;
9116
9117 if (rel_type == reltype_relr)
9118 res = dump_relr_relocations (filedata, section, symtab, nsyms, strtab, strtablen);
9119 else
9120 res = dump_relocations (filedata, rel_offset, rel_size,
9121 symtab, nsyms, strtab, strtablen,
9122 rel_type,
9123 symsec == NULL ? false : symsec->sh_type == SHT_DYNSYM);
8e8d0b63
NC
9124 free (strtab);
9125 free (symtab);
9126
9127 return res;
9128}
9129
252b5132 9130/* Process the reloc section. */
18bd398b 9131
015dc7e1 9132static bool
dda8d76d 9133process_relocs (Filedata * filedata)
252b5132 9134{
26c527e6
AM
9135 uint64_t rel_size;
9136 uint64_t rel_offset;
252b5132 9137
252b5132 9138 if (!do_reloc)
015dc7e1 9139 return true;
252b5132
RH
9140
9141 if (do_using_dynamic)
9142 {
a7fd1186 9143 relocation_type rel_type;
2cf0635d 9144 const char * name;
015dc7e1 9145 bool has_dynamic_reloc;
566b0d53 9146 unsigned int i;
0de14b54 9147
015dc7e1 9148 has_dynamic_reloc = false;
252b5132 9149
566b0d53 9150 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 9151 {
a7fd1186 9152 rel_type = dynamic_relocations [i].rel_type;
566b0d53 9153 name = dynamic_relocations [i].name;
978c4450
AM
9154 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
9155 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 9156
32ec8896 9157 if (rel_size)
015dc7e1 9158 has_dynamic_reloc = true;
566b0d53 9159
a7fd1186 9160 if (rel_type == reltype_unknown)
aa903cfb 9161 {
566b0d53 9162 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 9163 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
9164 {
9165 case DT_REL:
a7fd1186 9166 rel_type = reltype_rel;
566b0d53
L
9167 break;
9168 case DT_RELA:
a7fd1186 9169 rel_type = reltype_rela;
566b0d53
L
9170 break;
9171 }
aa903cfb 9172 }
252b5132 9173
566b0d53
L
9174 if (rel_size)
9175 {
ca0e11aa
NC
9176 if (filedata->is_separate)
9177 printf
26c527e6
AM
9178 (_("\nIn linked file '%s' section '%s' at offset %#" PRIx64
9179 " contains %" PRId64 " bytes:\n"),
ca0e11aa
NC
9180 filedata->file_name, name, rel_offset, rel_size);
9181 else
9182 printf
26c527e6
AM
9183 (_("\n'%s' relocation section at offset %#" PRIx64
9184 " contains %" PRId64 " bytes:\n"),
ca0e11aa 9185 name, rel_offset, rel_size);
252b5132 9186
dda8d76d
NC
9187 dump_relocations (filedata,
9188 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 9189 rel_size,
978c4450
AM
9190 filedata->dynamic_symbols,
9191 filedata->num_dynamic_syms,
9192 filedata->dynamic_strings,
9193 filedata->dynamic_strings_length,
a7fd1186 9194 rel_type, true /* is_dynamic */);
566b0d53 9195 }
252b5132 9196 }
566b0d53 9197
dda8d76d
NC
9198 if (is_ia64_vms (filedata))
9199 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 9200 has_dynamic_reloc = true;
28f997cf 9201
566b0d53 9202 if (! has_dynamic_reloc)
ca0e11aa
NC
9203 {
9204 if (filedata->is_separate)
9205 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
9206 filedata->file_name);
9207 else
9208 printf (_("\nThere are no dynamic relocations in this file.\n"));
9209 }
252b5132
RH
9210 }
9211 else
9212 {
2cf0635d 9213 Elf_Internal_Shdr * section;
26c527e6 9214 size_t i;
015dc7e1 9215 bool found = false;
252b5132 9216
dda8d76d
NC
9217 for (i = 0, section = filedata->section_headers;
9218 i < filedata->file_header.e_shnum;
b34976b6 9219 i++, section++)
252b5132 9220 {
8e8d0b63
NC
9221 if (display_relocations (section, filedata))
9222 found = true;
252b5132
RH
9223 }
9224
9225 if (! found)
45ac8f4f
NC
9226 {
9227 /* Users sometimes forget the -D option, so try to be helpful. */
9228 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
9229 {
978c4450 9230 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 9231 {
ca0e11aa
NC
9232 if (filedata->is_separate)
9233 printf (_("\nThere are no static relocations in linked file '%s'."),
9234 filedata->file_name);
9235 else
9236 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
9237 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
9238
9239 break;
9240 }
9241 }
9242 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
9243 {
9244 if (filedata->is_separate)
9245 printf (_("\nThere are no relocations in linked file '%s'.\n"),
9246 filedata->file_name);
9247 else
9248 printf (_("\nThere are no relocations in this file.\n"));
9249 }
45ac8f4f 9250 }
252b5132
RH
9251 }
9252
015dc7e1 9253 return true;
252b5132
RH
9254}
9255
4d6ed7c8
NC
9256/* An absolute address consists of a section and an offset. If the
9257 section is NULL, the offset itself is the address, otherwise, the
9258 address equals to LOAD_ADDRESS(section) + offset. */
9259
9260struct absaddr
948f632f
DA
9261{
9262 unsigned short section;
625d49fc 9263 uint64_t offset;
948f632f 9264};
4d6ed7c8 9265
948f632f
DA
9266/* Find the nearest symbol at or below ADDR. Returns the symbol
9267 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 9268
4d6ed7c8 9269static void
26c527e6
AM
9270find_symbol_for_address (Filedata *filedata,
9271 Elf_Internal_Sym *symtab,
9272 uint64_t nsyms,
9273 const char *strtab,
9274 uint64_t strtab_size,
9275 struct absaddr addr,
9276 const char **symname,
9277 uint64_t *offset)
4d6ed7c8 9278{
625d49fc 9279 uint64_t dist = 0x100000;
2cf0635d 9280 Elf_Internal_Sym * sym;
948f632f
DA
9281 Elf_Internal_Sym * beg;
9282 Elf_Internal_Sym * end;
2cf0635d 9283 Elf_Internal_Sym * best = NULL;
4d6ed7c8 9284
0b6ae522 9285 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
9286 beg = symtab;
9287 end = symtab + nsyms;
0b6ae522 9288
948f632f 9289 while (beg < end)
4d6ed7c8 9290 {
625d49fc 9291 uint64_t value;
948f632f
DA
9292
9293 sym = beg + (end - beg) / 2;
0b6ae522 9294
948f632f 9295 value = sym->st_value;
0b6ae522
DJ
9296 REMOVE_ARCH_BITS (value);
9297
948f632f 9298 if (sym->st_name != 0
4d6ed7c8 9299 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
9300 && addr.offset >= value
9301 && addr.offset - value < dist)
4d6ed7c8
NC
9302 {
9303 best = sym;
0b6ae522 9304 dist = addr.offset - value;
4d6ed7c8
NC
9305 if (!dist)
9306 break;
9307 }
948f632f
DA
9308
9309 if (addr.offset < value)
9310 end = sym;
9311 else
9312 beg = sym + 1;
4d6ed7c8 9313 }
1b31d05e 9314
4d6ed7c8
NC
9315 if (best)
9316 {
57346661 9317 *symname = (best->st_name >= strtab_size
2b692964 9318 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
9319 *offset = dist;
9320 return;
9321 }
1b31d05e 9322
4d6ed7c8
NC
9323 *symname = NULL;
9324 *offset = addr.offset;
9325}
9326
948f632f
DA
9327/* Process the unwind section. */
9328
9329#include "unwind-ia64.h"
9330
9331struct ia64_unw_table_entry
9332{
9333 struct absaddr start;
9334 struct absaddr end;
9335 struct absaddr info;
9336};
9337
9338struct ia64_unw_aux_info
9339{
32ec8896 9340 struct ia64_unw_table_entry * table; /* Unwind table. */
26c527e6 9341 uint64_t table_len; /* Length of unwind table. */
32ec8896 9342 unsigned char * info; /* Unwind info. */
26c527e6 9343 uint64_t info_size; /* Size of unwind info. */
625d49fc
AM
9344 uint64_t info_addr; /* Starting address of unwind info. */
9345 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9346 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9347 uint64_t nsyms; /* Number of symbols. */
32ec8896 9348 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9349 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9350 char * strtab; /* The string table. */
26c527e6 9351 uint64_t strtab_size; /* Size of string table. */
948f632f
DA
9352};
9353
015dc7e1 9354static bool
dda8d76d 9355dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 9356{
2cf0635d 9357 struct ia64_unw_table_entry * tp;
26c527e6 9358 size_t j, nfuns;
4d6ed7c8 9359 int in_body;
015dc7e1 9360 bool res = true;
7036c0e1 9361
948f632f
DA
9362 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9363 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9364 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9365 aux->funtab[nfuns++] = aux->symtab[j];
9366 aux->nfuns = nfuns;
9367 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9368
4d6ed7c8
NC
9369 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9370 {
625d49fc
AM
9371 uint64_t stamp;
9372 uint64_t offset;
2cf0635d
NC
9373 const unsigned char * dp;
9374 const unsigned char * head;
53774b7e 9375 const unsigned char * end;
2cf0635d 9376 const char * procname;
4d6ed7c8 9377
dda8d76d 9378 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 9379 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
9380
9381 fputs ("\n<", stdout);
9382
9383 if (procname)
9384 {
9385 fputs (procname, stdout);
9386
9387 if (offset)
26c527e6 9388 printf ("+%" PRIx64, offset);
4d6ed7c8
NC
9389 }
9390
9391 fputs (">: [", stdout);
9392 print_vma (tp->start.offset, PREFIX_HEX);
9393 fputc ('-', stdout);
9394 print_vma (tp->end.offset, PREFIX_HEX);
26c527e6
AM
9395 printf ("], info at +0x%" PRIx64 "\n",
9396 tp->info.offset - aux->seg_base);
4d6ed7c8 9397
53774b7e
NC
9398 /* PR 17531: file: 86232b32. */
9399 if (aux->info == NULL)
9400 continue;
9401
97c0a079
AM
9402 offset = tp->info.offset;
9403 if (tp->info.section)
9404 {
9405 if (tp->info.section >= filedata->file_header.e_shnum)
9406 {
26c527e6
AM
9407 warn (_("Invalid section %u in table entry %td\n"),
9408 tp->info.section, tp - aux->table);
015dc7e1 9409 res = false;
97c0a079
AM
9410 continue;
9411 }
9412 offset += filedata->section_headers[tp->info.section].sh_addr;
9413 }
9414 offset -= aux->info_addr;
53774b7e 9415 /* PR 17531: file: 0997b4d1. */
90679903
AM
9416 if (offset >= aux->info_size
9417 || aux->info_size - offset < 8)
53774b7e 9418 {
26c527e6
AM
9419 warn (_("Invalid offset %" PRIx64 " in table entry %td\n"),
9420 tp->info.offset, tp - aux->table);
015dc7e1 9421 res = false;
53774b7e
NC
9422 continue;
9423 }
9424
97c0a079 9425 head = aux->info + offset;
a4a00738 9426 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 9427
86f55779 9428 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
9429 (unsigned) UNW_VER (stamp),
9430 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
9431 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
9432 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 9433 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
9434
9435 if (UNW_VER (stamp) != 1)
9436 {
2b692964 9437 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
9438 continue;
9439 }
9440
9441 in_body = 0;
53774b7e
NC
9442 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
9443 /* PR 17531: file: 16ceda89. */
9444 if (end > aux->info + aux->info_size)
9445 end = aux->info + aux->info_size;
9446 for (dp = head + 8; dp < end;)
b4477bc8 9447 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 9448 }
948f632f
DA
9449
9450 free (aux->funtab);
32ec8896
NC
9451
9452 return res;
4d6ed7c8
NC
9453}
9454
015dc7e1 9455static bool
dda8d76d
NC
9456slurp_ia64_unwind_table (Filedata * filedata,
9457 struct ia64_unw_aux_info * aux,
9458 Elf_Internal_Shdr * sec)
4d6ed7c8 9459{
26c527e6 9460 uint64_t size, nrelas, i;
2cf0635d
NC
9461 Elf_Internal_Phdr * seg;
9462 struct ia64_unw_table_entry * tep;
9463 Elf_Internal_Shdr * relsec;
9464 Elf_Internal_Rela * rela;
9465 Elf_Internal_Rela * rp;
9466 unsigned char * table;
9467 unsigned char * tp;
9468 Elf_Internal_Sym * sym;
9469 const char * relname;
4d6ed7c8 9470
53774b7e
NC
9471 aux->table_len = 0;
9472
4d6ed7c8
NC
9473 /* First, find the starting address of the segment that includes
9474 this section: */
9475
dda8d76d 9476 if (filedata->file_header.e_phnum)
4d6ed7c8 9477 {
dda8d76d 9478 if (! get_program_headers (filedata))
015dc7e1 9479 return false;
4d6ed7c8 9480
dda8d76d
NC
9481 for (seg = filedata->program_headers;
9482 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 9483 ++seg)
4d6ed7c8
NC
9484 {
9485 if (seg->p_type != PT_LOAD)
9486 continue;
9487
9488 if (sec->sh_addr >= seg->p_vaddr
9489 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9490 {
9491 aux->seg_base = seg->p_vaddr;
9492 break;
9493 }
9494 }
4d6ed7c8
NC
9495 }
9496
9497 /* Second, build the unwind table from the contents of the unwind section: */
9498 size = sec->sh_size;
dda8d76d 9499 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9500 _("unwind table"));
a6e9f9df 9501 if (!table)
015dc7e1 9502 return false;
4d6ed7c8 9503
53774b7e 9504 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 9505 aux->table = (struct ia64_unw_table_entry *)
53774b7e 9506 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 9507 tep = aux->table;
53774b7e
NC
9508
9509 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
9510 {
9511 tep->start.section = SHN_UNDEF;
9512 tep->end.section = SHN_UNDEF;
9513 tep->info.section = SHN_UNDEF;
c6a0c689
AM
9514 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9515 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
9516 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
9517 tep->start.offset += aux->seg_base;
9518 tep->end.offset += aux->seg_base;
9519 tep->info.offset += aux->seg_base;
9520 }
9521 free (table);
9522
41e92641 9523 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
9524 for (relsec = filedata->section_headers;
9525 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
9526 ++relsec)
9527 {
9528 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9529 || relsec->sh_info >= filedata->file_header.e_shnum
9530 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
9531 continue;
9532
dda8d76d 9533 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 9534 & rela, & nrelas))
53774b7e
NC
9535 {
9536 free (aux->table);
9537 aux->table = NULL;
9538 aux->table_len = 0;
015dc7e1 9539 return false;
53774b7e 9540 }
4d6ed7c8
NC
9541
9542 for (rp = rela; rp < rela + nrelas; ++rp)
9543 {
4770fb94 9544 unsigned int sym_ndx;
726bd37d
AM
9545 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9546 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 9547
82b1b41b
NC
9548 /* PR 17531: file: 9fa67536. */
9549 if (relname == NULL)
9550 {
726bd37d 9551 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
9552 continue;
9553 }
948f632f 9554
24d127aa 9555 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 9556 {
82b1b41b 9557 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
9558 continue;
9559 }
9560
89fac5e3 9561 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 9562
53774b7e
NC
9563 /* PR 17531: file: 5bc8d9bf. */
9564 if (i >= aux->table_len)
9565 {
26c527e6
AM
9566 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
9567 i);
53774b7e
NC
9568 continue;
9569 }
9570
4770fb94
AM
9571 sym_ndx = get_reloc_symindex (rp->r_info);
9572 if (sym_ndx >= aux->nsyms)
9573 {
9574 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9575 sym_ndx);
9576 continue;
9577 }
9578 sym = aux->symtab + sym_ndx;
9579
53774b7e 9580 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
9581 {
9582 case 0:
9583 aux->table[i].start.section = sym->st_shndx;
e466bc6e 9584 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9585 break;
9586 case 1:
9587 aux->table[i].end.section = sym->st_shndx;
e466bc6e 9588 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9589 break;
9590 case 2:
9591 aux->table[i].info.section = sym->st_shndx;
e466bc6e 9592 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
9593 break;
9594 default:
9595 break;
9596 }
9597 }
9598
9599 free (rela);
9600 }
9601
015dc7e1 9602 return true;
4d6ed7c8
NC
9603}
9604
015dc7e1 9605static bool
dda8d76d 9606ia64_process_unwind (Filedata * filedata)
4d6ed7c8 9607{
2cf0635d
NC
9608 Elf_Internal_Shdr * sec;
9609 Elf_Internal_Shdr * unwsec = NULL;
26c527e6 9610 uint64_t i, unwcount = 0, unwstart = 0;
57346661 9611 struct ia64_unw_aux_info aux;
015dc7e1 9612 bool res = true;
f1467e33 9613
4d6ed7c8
NC
9614 memset (& aux, 0, sizeof (aux));
9615
dda8d76d 9616 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 9617 {
28d13567 9618 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 9619 {
28d13567 9620 if (aux.symtab)
4082ef84 9621 {
28d13567
AM
9622 error (_("Multiple symbol tables encountered\n"));
9623 free (aux.symtab);
9624 aux.symtab = NULL;
4082ef84 9625 free (aux.strtab);
28d13567 9626 aux.strtab = NULL;
4082ef84 9627 }
28d13567
AM
9628 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9629 &aux.strtab, &aux.strtab_size))
015dc7e1 9630 return false;
4d6ed7c8
NC
9631 }
9632 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
9633 unwcount++;
9634 }
9635
9636 if (!unwcount)
9637 printf (_("\nThere are no unwind sections in this file.\n"));
9638
9639 while (unwcount-- > 0)
9640 {
84714f86 9641 const char *suffix;
579f31ac
JJ
9642 size_t len, len2;
9643
dda8d76d
NC
9644 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
9645 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
9646 if (sec->sh_type == SHT_IA_64_UNWIND)
9647 {
9648 unwsec = sec;
9649 break;
9650 }
4082ef84
NC
9651 /* We have already counted the number of SHT_IA64_UNWIND
9652 sections so the loop above should never fail. */
9653 assert (unwsec != NULL);
579f31ac
JJ
9654
9655 unwstart = i + 1;
9656 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
9657
e4b17d5c
L
9658 if ((unwsec->sh_flags & SHF_GROUP) != 0)
9659 {
9660 /* We need to find which section group it is in. */
4082ef84 9661 struct group_list * g;
e4b17d5c 9662
978c4450
AM
9663 if (filedata->section_headers_groups == NULL
9664 || filedata->section_headers_groups[i] == NULL)
dda8d76d 9665 i = filedata->file_header.e_shnum;
4082ef84 9666 else
e4b17d5c 9667 {
978c4450 9668 g = filedata->section_headers_groups[i]->root;
18bd398b 9669
4082ef84
NC
9670 for (; g != NULL; g = g->next)
9671 {
dda8d76d 9672 sec = filedata->section_headers + g->section_index;
e4b17d5c 9673
84714f86
AM
9674 if (section_name_valid (filedata, sec)
9675 && streq (section_name (filedata, sec),
9676 ELF_STRING_ia64_unwind_info))
4082ef84
NC
9677 break;
9678 }
9679
9680 if (g == NULL)
dda8d76d 9681 i = filedata->file_header.e_shnum;
4082ef84 9682 }
e4b17d5c 9683 }
84714f86
AM
9684 else if (section_name_valid (filedata, unwsec)
9685 && startswith (section_name (filedata, unwsec),
e9b095a5 9686 ELF_STRING_ia64_unwind_once))
579f31ac 9687 {
18bd398b 9688 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 9689 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 9690 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9691 for (i = 0, sec = filedata->section_headers;
9692 i < filedata->file_header.e_shnum;
579f31ac 9693 ++i, ++sec)
84714f86
AM
9694 if (section_name_valid (filedata, sec)
9695 && startswith (section_name (filedata, sec),
e9b095a5 9696 ELF_STRING_ia64_unwind_info_once)
84714f86 9697 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9698 break;
9699 }
9700 else
9701 {
9702 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 9703 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
9704 len = sizeof (ELF_STRING_ia64_unwind) - 1;
9705 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
9706 suffix = "";
84714f86
AM
9707 if (section_name_valid (filedata, unwsec)
9708 && startswith (section_name (filedata, unwsec),
9709 ELF_STRING_ia64_unwind))
9710 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
9711 for (i = 0, sec = filedata->section_headers;
9712 i < filedata->file_header.e_shnum;
579f31ac 9713 ++i, ++sec)
84714f86
AM
9714 if (section_name_valid (filedata, sec)
9715 && startswith (section_name (filedata, sec),
9716 ELF_STRING_ia64_unwind_info)
9717 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
9718 break;
9719 }
9720
dda8d76d 9721 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
9722 {
9723 printf (_("\nCould not find unwind info section for "));
9724
dda8d76d 9725 if (filedata->string_table == NULL)
579f31ac
JJ
9726 printf ("%d", unwsec->sh_name);
9727 else
dda8d76d 9728 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
9729 }
9730 else
4d6ed7c8 9731 {
4d6ed7c8 9732 aux.info_addr = sec->sh_addr;
dda8d76d 9733 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
9734 sec->sh_size,
9735 _("unwind info"));
59245841 9736 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 9737
579f31ac 9738 printf (_("\nUnwind section "));
4d6ed7c8 9739
dda8d76d 9740 if (filedata->string_table == NULL)
579f31ac
JJ
9741 printf ("%d", unwsec->sh_name);
9742 else
dda8d76d 9743 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 9744
26c527e6
AM
9745 printf (_(" at offset %#" PRIx64 " contains %" PRIu64 " entries:\n"),
9746 unwsec->sh_offset,
9747 unwsec->sh_size / (3 * eh_addr_size));
4d6ed7c8 9748
dda8d76d 9749 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 9750 && aux.table_len > 0)
dda8d76d 9751 dump_ia64_unwind (filedata, & aux);
579f31ac 9752
9db70fc3
AM
9753 free ((char *) aux.table);
9754 free ((char *) aux.info);
579f31ac
JJ
9755 aux.table = NULL;
9756 aux.info = NULL;
9757 }
4d6ed7c8 9758 }
4d6ed7c8 9759
9db70fc3
AM
9760 free (aux.symtab);
9761 free ((char *) aux.strtab);
32ec8896
NC
9762
9763 return res;
4d6ed7c8
NC
9764}
9765
3f5e193b 9766struct hppa_unw_table_entry
32ec8896
NC
9767{
9768 struct absaddr start;
9769 struct absaddr end;
9770 unsigned int Cannot_unwind:1; /* 0 */
9771 unsigned int Millicode:1; /* 1 */
9772 unsigned int Millicode_save_sr0:1; /* 2 */
9773 unsigned int Region_description:2; /* 3..4 */
9774 unsigned int reserved1:1; /* 5 */
9775 unsigned int Entry_SR:1; /* 6 */
9776 unsigned int Entry_FR:4; /* Number saved 7..10 */
9777 unsigned int Entry_GR:5; /* Number saved 11..15 */
9778 unsigned int Args_stored:1; /* 16 */
9779 unsigned int Variable_Frame:1; /* 17 */
9780 unsigned int Separate_Package_Body:1; /* 18 */
9781 unsigned int Frame_Extension_Millicode:1; /* 19 */
9782 unsigned int Stack_Overflow_Check:1; /* 20 */
9783 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
9784 unsigned int Ada_Region:1; /* 22 */
9785 unsigned int cxx_info:1; /* 23 */
9786 unsigned int cxx_try_catch:1; /* 24 */
9787 unsigned int sched_entry_seq:1; /* 25 */
9788 unsigned int reserved2:1; /* 26 */
9789 unsigned int Save_SP:1; /* 27 */
9790 unsigned int Save_RP:1; /* 28 */
9791 unsigned int Save_MRP_in_frame:1; /* 29 */
9792 unsigned int extn_ptr_defined:1; /* 30 */
9793 unsigned int Cleanup_defined:1; /* 31 */
9794
9795 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
9796 unsigned int HP_UX_interrupt_marker:1; /* 1 */
9797 unsigned int Large_frame:1; /* 2 */
9798 unsigned int Pseudo_SP_Set:1; /* 3 */
9799 unsigned int reserved4:1; /* 4 */
9800 unsigned int Total_frame_size:27; /* 5..31 */
9801};
3f5e193b 9802
57346661 9803struct hppa_unw_aux_info
948f632f 9804{
32ec8896 9805 struct hppa_unw_table_entry * table; /* Unwind table. */
26c527e6 9806 uint64_t table_len; /* Length of unwind table. */
625d49fc 9807 uint64_t seg_base; /* Starting address of segment. */
32ec8896 9808 Elf_Internal_Sym * symtab; /* The symbol table. */
26c527e6 9809 uint64_t nsyms; /* Number of symbols. */
32ec8896 9810 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 9811 uint64_t nfuns; /* Number of entries in funtab. */
32ec8896 9812 char * strtab; /* The string table. */
26c527e6 9813 uint64_t strtab_size; /* Size of string table. */
948f632f 9814};
57346661 9815
015dc7e1 9816static bool
dda8d76d 9817dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 9818{
2cf0635d 9819 struct hppa_unw_table_entry * tp;
26c527e6 9820 uint64_t j, nfuns;
015dc7e1 9821 bool res = true;
948f632f
DA
9822
9823 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9824 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9825 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9826 aux->funtab[nfuns++] = aux->symtab[j];
9827 aux->nfuns = nfuns;
9828 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 9829
57346661
AM
9830 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
9831 {
625d49fc 9832 uint64_t offset;
2cf0635d 9833 const char * procname;
57346661 9834
dda8d76d 9835 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
9836 aux->strtab_size, tp->start, &procname,
9837 &offset);
9838
9839 fputs ("\n<", stdout);
9840
9841 if (procname)
9842 {
9843 fputs (procname, stdout);
9844
9845 if (offset)
26c527e6 9846 printf ("+%" PRIx64, offset);
57346661
AM
9847 }
9848
9849 fputs (">: [", stdout);
9850 print_vma (tp->start.offset, PREFIX_HEX);
9851 fputc ('-', stdout);
9852 print_vma (tp->end.offset, PREFIX_HEX);
9853 printf ("]\n\t");
9854
18bd398b
NC
9855#define PF(_m) if (tp->_m) printf (#_m " ");
9856#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
9857 PF(Cannot_unwind);
9858 PF(Millicode);
9859 PF(Millicode_save_sr0);
18bd398b 9860 /* PV(Region_description); */
57346661
AM
9861 PF(Entry_SR);
9862 PV(Entry_FR);
9863 PV(Entry_GR);
9864 PF(Args_stored);
9865 PF(Variable_Frame);
9866 PF(Separate_Package_Body);
9867 PF(Frame_Extension_Millicode);
9868 PF(Stack_Overflow_Check);
9869 PF(Two_Instruction_SP_Increment);
9870 PF(Ada_Region);
9871 PF(cxx_info);
9872 PF(cxx_try_catch);
9873 PF(sched_entry_seq);
9874 PF(Save_SP);
9875 PF(Save_RP);
9876 PF(Save_MRP_in_frame);
9877 PF(extn_ptr_defined);
9878 PF(Cleanup_defined);
9879 PF(MPE_XL_interrupt_marker);
9880 PF(HP_UX_interrupt_marker);
9881 PF(Large_frame);
9882 PF(Pseudo_SP_Set);
9883 PV(Total_frame_size);
9884#undef PF
9885#undef PV
9886 }
9887
18bd398b 9888 printf ("\n");
948f632f
DA
9889
9890 free (aux->funtab);
32ec8896
NC
9891
9892 return res;
57346661
AM
9893}
9894
015dc7e1 9895static bool
dda8d76d
NC
9896slurp_hppa_unwind_table (Filedata * filedata,
9897 struct hppa_unw_aux_info * aux,
9898 Elf_Internal_Shdr * sec)
57346661 9899{
26c527e6 9900 uint64_t size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9901 Elf_Internal_Phdr * seg;
9902 struct hppa_unw_table_entry * tep;
9903 Elf_Internal_Shdr * relsec;
9904 Elf_Internal_Rela * rela;
9905 Elf_Internal_Rela * rp;
9906 unsigned char * table;
9907 unsigned char * tp;
9908 Elf_Internal_Sym * sym;
9909 const char * relname;
57346661 9910
57346661
AM
9911 /* First, find the starting address of the segment that includes
9912 this section. */
dda8d76d 9913 if (filedata->file_header.e_phnum)
57346661 9914 {
dda8d76d 9915 if (! get_program_headers (filedata))
015dc7e1 9916 return false;
57346661 9917
dda8d76d
NC
9918 for (seg = filedata->program_headers;
9919 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9920 ++seg)
9921 {
9922 if (seg->p_type != PT_LOAD)
9923 continue;
9924
9925 if (sec->sh_addr >= seg->p_vaddr
9926 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9927 {
9928 aux->seg_base = seg->p_vaddr;
9929 break;
9930 }
9931 }
9932 }
9933
9934 /* Second, build the unwind table from the contents of the unwind
9935 section. */
9936 size = sec->sh_size;
dda8d76d 9937 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9938 _("unwind table"));
57346661 9939 if (!table)
015dc7e1 9940 return false;
57346661 9941
1c0751b2
DA
9942 unw_ent_size = 16;
9943 nentries = size / unw_ent_size;
9944 size = unw_ent_size * nentries;
57346661 9945
e3fdc001 9946 aux->table_len = nentries;
3f5e193b
NC
9947 tep = aux->table = (struct hppa_unw_table_entry *)
9948 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9949
1c0751b2 9950 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9951 {
9952 unsigned int tmp1, tmp2;
9953
9954 tep->start.section = SHN_UNDEF;
9955 tep->end.section = SHN_UNDEF;
9956
1c0751b2
DA
9957 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9958 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9959 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9960 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9961
9962 tep->start.offset += aux->seg_base;
9963 tep->end.offset += aux->seg_base;
57346661
AM
9964
9965 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9966 tep->Millicode = (tmp1 >> 30) & 0x1;
9967 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9968 tep->Region_description = (tmp1 >> 27) & 0x3;
9969 tep->reserved1 = (tmp1 >> 26) & 0x1;
9970 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9971 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9972 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9973 tep->Args_stored = (tmp1 >> 15) & 0x1;
9974 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9975 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9976 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9977 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9978 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9979 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9980 tep->cxx_info = (tmp1 >> 8) & 0x1;
9981 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9982 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9983 tep->reserved2 = (tmp1 >> 5) & 0x1;
9984 tep->Save_SP = (tmp1 >> 4) & 0x1;
9985 tep->Save_RP = (tmp1 >> 3) & 0x1;
9986 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9987 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9988 tep->Cleanup_defined = tmp1 & 0x1;
9989
9990 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9991 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9992 tep->Large_frame = (tmp2 >> 29) & 0x1;
9993 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9994 tep->reserved4 = (tmp2 >> 27) & 0x1;
9995 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9996 }
9997 free (table);
9998
9999 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
10000 for (relsec = filedata->section_headers;
10001 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
10002 ++relsec)
10003 {
10004 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
10005 || relsec->sh_info >= filedata->file_header.e_shnum
10006 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
10007 continue;
10008
dda8d76d 10009 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 10010 & rela, & nrelas))
015dc7e1 10011 return false;
57346661
AM
10012
10013 for (rp = rela; rp < rela + nrelas; ++rp)
10014 {
4770fb94 10015 unsigned int sym_ndx;
726bd37d
AM
10016 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
10017 relname = elf_hppa_reloc_type (r_type);
57346661 10018
726bd37d
AM
10019 if (relname == NULL)
10020 {
10021 warn (_("Skipping unknown relocation type: %u\n"), r_type);
10022 continue;
10023 }
10024
57346661 10025 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 10026 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 10027 {
726bd37d 10028 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
10029 continue;
10030 }
10031
10032 i = rp->r_offset / unw_ent_size;
726bd37d
AM
10033 if (i >= aux->table_len)
10034 {
26c527e6
AM
10035 warn (_("Skipping reloc with overlarge offset: %#" PRIx64 "\n"),
10036 i);
726bd37d
AM
10037 continue;
10038 }
57346661 10039
4770fb94
AM
10040 sym_ndx = get_reloc_symindex (rp->r_info);
10041 if (sym_ndx >= aux->nsyms)
10042 {
10043 warn (_("Skipping reloc with invalid symbol index: %u\n"),
10044 sym_ndx);
10045 continue;
10046 }
10047 sym = aux->symtab + sym_ndx;
10048
43f6cd05 10049 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
10050 {
10051 case 0:
10052 aux->table[i].start.section = sym->st_shndx;
1e456d54 10053 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
10054 break;
10055 case 1:
10056 aux->table[i].end.section = sym->st_shndx;
1e456d54 10057 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
10058 break;
10059 default:
10060 break;
10061 }
10062 }
10063
10064 free (rela);
10065 }
10066
015dc7e1 10067 return true;
57346661
AM
10068}
10069
015dc7e1 10070static bool
dda8d76d 10071hppa_process_unwind (Filedata * filedata)
57346661 10072{
57346661 10073 struct hppa_unw_aux_info aux;
2cf0635d 10074 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 10075 Elf_Internal_Shdr * sec;
26c527e6 10076 size_t i;
015dc7e1 10077 bool res = true;
57346661 10078
dda8d76d 10079 if (filedata->string_table == NULL)
015dc7e1 10080 return false;
1b31d05e
NC
10081
10082 memset (& aux, 0, sizeof (aux));
57346661 10083
dda8d76d 10084 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10085 {
28d13567 10086 if (sec->sh_type == SHT_SYMTAB)
57346661 10087 {
28d13567 10088 if (aux.symtab)
4082ef84 10089 {
28d13567
AM
10090 error (_("Multiple symbol tables encountered\n"));
10091 free (aux.symtab);
10092 aux.symtab = NULL;
4082ef84 10093 free (aux.strtab);
28d13567 10094 aux.strtab = NULL;
4082ef84 10095 }
28d13567
AM
10096 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10097 &aux.strtab, &aux.strtab_size))
015dc7e1 10098 return false;
57346661 10099 }
84714f86
AM
10100 else if (section_name_valid (filedata, sec)
10101 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
10102 unwsec = sec;
10103 }
10104
10105 if (!unwsec)
10106 printf (_("\nThere are no unwind sections in this file.\n"));
10107
dda8d76d 10108 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 10109 {
84714f86
AM
10110 if (section_name_valid (filedata, sec)
10111 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 10112 {
26c527e6 10113 uint64_t num_unwind = sec->sh_size / 16;
dda8d76d 10114
26c527e6
AM
10115 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
10116 "contains %" PRIu64 " entry:\n",
10117 "\nUnwind section '%s' at offset %#" PRIx64 " "
10118 "contains %" PRIu64 " entries:\n",
d3a49aa8 10119 num_unwind),
dda8d76d 10120 printable_section_name (filedata, sec),
26c527e6 10121 sec->sh_offset,
d3a49aa8 10122 num_unwind);
57346661 10123
dda8d76d 10124 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 10125 res = false;
66b09c7e
S
10126
10127 if (res && aux.table_len > 0)
32ec8896 10128 {
dda8d76d 10129 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 10130 res = false;
32ec8896 10131 }
57346661 10132
9db70fc3 10133 free ((char *) aux.table);
57346661
AM
10134 aux.table = NULL;
10135 }
10136 }
10137
9db70fc3
AM
10138 free (aux.symtab);
10139 free ((char *) aux.strtab);
32ec8896
NC
10140
10141 return res;
57346661
AM
10142}
10143
0b6ae522
DJ
10144struct arm_section
10145{
a734115a
NC
10146 unsigned char * data; /* The unwind data. */
10147 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
10148 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
26c527e6 10149 uint64_t nrelas; /* The number of relocations. */
a734115a
NC
10150 unsigned int rel_type; /* REL or RELA ? */
10151 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
10152};
10153
10154struct arm_unw_aux_info
10155{
dda8d76d 10156 Filedata * filedata; /* The file containing the unwind sections. */
a734115a 10157 Elf_Internal_Sym * symtab; /* The file's symbol table. */
26c527e6 10158 uint64_t nsyms; /* Number of symbols. */
948f632f 10159 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
26c527e6 10160 uint64_t nfuns; /* Number of these symbols. */
a734115a 10161 char * strtab; /* The file's string table. */
26c527e6 10162 uint64_t strtab_size; /* Size of string table. */
0b6ae522
DJ
10163};
10164
10165static const char *
dda8d76d
NC
10166arm_print_vma_and_name (Filedata * filedata,
10167 struct arm_unw_aux_info * aux,
625d49fc 10168 uint64_t fn,
dda8d76d 10169 struct absaddr addr)
0b6ae522
DJ
10170{
10171 const char *procname;
625d49fc 10172 uint64_t sym_offset;
0b6ae522
DJ
10173
10174 if (addr.section == SHN_UNDEF)
10175 addr.offset = fn;
10176
dda8d76d 10177 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
10178 aux->strtab_size, addr, &procname,
10179 &sym_offset);
10180
10181 print_vma (fn, PREFIX_HEX);
10182
10183 if (procname)
10184 {
10185 fputs (" <", stdout);
10186 fputs (procname, stdout);
10187
10188 if (sym_offset)
26c527e6 10189 printf ("+0x%" PRIx64, sym_offset);
0b6ae522
DJ
10190 fputc ('>', stdout);
10191 }
10192
10193 return procname;
10194}
10195
10196static void
10197arm_free_section (struct arm_section *arm_sec)
10198{
9db70fc3
AM
10199 free (arm_sec->data);
10200 free (arm_sec->rela);
0b6ae522
DJ
10201}
10202
a734115a
NC
10203/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
10204 cached section and install SEC instead.
10205 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
10206 and return its valued in * WORDP, relocating if necessary.
1b31d05e 10207 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 10208 relocation's offset in ADDR.
1b31d05e
NC
10209 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
10210 into the string table of the symbol associated with the reloc. If no
10211 reloc was applied store -1 there.
10212 5) Return TRUE upon success, FALSE otherwise. */
a734115a 10213
015dc7e1 10214static bool
dda8d76d
NC
10215get_unwind_section_word (Filedata * filedata,
10216 struct arm_unw_aux_info * aux,
1b31d05e
NC
10217 struct arm_section * arm_sec,
10218 Elf_Internal_Shdr * sec,
625d49fc 10219 uint64_t word_offset,
1b31d05e
NC
10220 unsigned int * wordp,
10221 struct absaddr * addr,
625d49fc 10222 uint64_t * sym_name)
0b6ae522
DJ
10223{
10224 Elf_Internal_Rela *rp;
10225 Elf_Internal_Sym *sym;
10226 const char * relname;
10227 unsigned int word;
015dc7e1 10228 bool wrapped;
0b6ae522 10229
e0a31db1 10230 if (sec == NULL || arm_sec == NULL)
015dc7e1 10231 return false;
e0a31db1 10232
0b6ae522
DJ
10233 addr->section = SHN_UNDEF;
10234 addr->offset = 0;
10235
1b31d05e 10236 if (sym_name != NULL)
625d49fc 10237 *sym_name = (uint64_t) -1;
1b31d05e 10238
a734115a 10239 /* If necessary, update the section cache. */
0b6ae522
DJ
10240 if (sec != arm_sec->sec)
10241 {
10242 Elf_Internal_Shdr *relsec;
10243
10244 arm_free_section (arm_sec);
10245
10246 arm_sec->sec = sec;
dda8d76d 10247 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 10248 sec->sh_size, _("unwind data"));
0b6ae522
DJ
10249 arm_sec->rela = NULL;
10250 arm_sec->nrelas = 0;
10251
dda8d76d
NC
10252 for (relsec = filedata->section_headers;
10253 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
10254 ++relsec)
10255 {
dda8d76d
NC
10256 if (relsec->sh_info >= filedata->file_header.e_shnum
10257 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
10258 /* PR 15745: Check the section type as well. */
10259 || (relsec->sh_type != SHT_REL
10260 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
10261 continue;
10262
a734115a 10263 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
10264 if (relsec->sh_type == SHT_REL)
10265 {
dda8d76d 10266 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10267 relsec->sh_size,
10268 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10269 return false;
0b6ae522 10270 }
1ae40aa4 10271 else /* relsec->sh_type == SHT_RELA */
0b6ae522 10272 {
dda8d76d 10273 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
10274 relsec->sh_size,
10275 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 10276 return false;
0b6ae522 10277 }
1ae40aa4 10278 break;
0b6ae522
DJ
10279 }
10280
10281 arm_sec->next_rela = arm_sec->rela;
10282 }
10283
a734115a 10284 /* If there is no unwind data we can do nothing. */
0b6ae522 10285 if (arm_sec->data == NULL)
015dc7e1 10286 return false;
0b6ae522 10287
e0a31db1 10288 /* If the offset is invalid then fail. */
f32ba729
NC
10289 if (/* PR 21343 *//* PR 18879 */
10290 sec->sh_size < 4
625d49fc 10291 || word_offset > sec->sh_size - 4)
015dc7e1 10292 return false;
e0a31db1 10293
a734115a 10294 /* Get the word at the required offset. */
0b6ae522
DJ
10295 word = byte_get (arm_sec->data + word_offset, 4);
10296
0eff7165
NC
10297 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
10298 if (arm_sec->rela == NULL)
10299 {
10300 * wordp = word;
015dc7e1 10301 return true;
0eff7165
NC
10302 }
10303
a734115a 10304 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 10305 wrapped = false;
0b6ae522
DJ
10306 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
10307 {
625d49fc 10308 uint64_t prelval, offset;
0b6ae522
DJ
10309
10310 if (rp->r_offset > word_offset && !wrapped)
10311 {
10312 rp = arm_sec->rela;
015dc7e1 10313 wrapped = true;
0b6ae522
DJ
10314 }
10315 if (rp->r_offset > word_offset)
10316 break;
10317
10318 if (rp->r_offset & 3)
10319 {
26c527e6
AM
10320 warn (_("Skipping unexpected relocation at offset %#" PRIx64 "\n"),
10321 rp->r_offset);
0b6ae522
DJ
10322 continue;
10323 }
10324
10325 if (rp->r_offset < word_offset)
10326 continue;
10327
74e1a04b
NC
10328 /* PR 17531: file: 027-161405-0.004 */
10329 if (aux->symtab == NULL)
10330 continue;
10331
0b6ae522
DJ
10332 if (arm_sec->rel_type == SHT_REL)
10333 {
10334 offset = word & 0x7fffffff;
10335 if (offset & 0x40000000)
625d49fc 10336 offset |= ~ (uint64_t) 0x7fffffff;
0b6ae522 10337 }
a734115a 10338 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 10339 offset = rp->r_addend;
a734115a 10340 else
74e1a04b
NC
10341 {
10342 error (_("Unknown section relocation type %d encountered\n"),
10343 arm_sec->rel_type);
10344 break;
10345 }
0b6ae522 10346
071436c6
NC
10347 /* PR 17531 file: 027-1241568-0.004. */
10348 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
10349 {
26c527e6
AM
10350 error (_("Bad symbol index in unwind relocation "
10351 "(%" PRIu64 " > %" PRIu64 ")\n"),
10352 ELF32_R_SYM (rp->r_info), aux->nsyms);
071436c6
NC
10353 break;
10354 }
10355
10356 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
10357 offset += sym->st_value;
10358 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
10359
a734115a 10360 /* Check that we are processing the expected reloc type. */
dda8d76d 10361 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
10362 {
10363 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10364 if (relname == NULL)
10365 {
10366 warn (_("Skipping unknown ARM relocation type: %d\n"),
10367 (int) ELF32_R_TYPE (rp->r_info));
10368 continue;
10369 }
a734115a
NC
10370
10371 if (streq (relname, "R_ARM_NONE"))
10372 continue;
0b4362b0 10373
a734115a
NC
10374 if (! streq (relname, "R_ARM_PREL31"))
10375 {
071436c6 10376 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
10377 continue;
10378 }
10379 }
dda8d76d 10380 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
10381 {
10382 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
10383 if (relname == NULL)
10384 {
10385 warn (_("Skipping unknown C6000 relocation type: %d\n"),
10386 (int) ELF32_R_TYPE (rp->r_info));
10387 continue;
10388 }
0b4362b0 10389
a734115a
NC
10390 if (streq (relname, "R_C6000_NONE"))
10391 continue;
10392
10393 if (! streq (relname, "R_C6000_PREL31"))
10394 {
071436c6 10395 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
10396 continue;
10397 }
10398
10399 prelval >>= 1;
10400 }
10401 else
74e1a04b
NC
10402 {
10403 /* This function currently only supports ARM and TI unwinders. */
10404 warn (_("Only TI and ARM unwinders are currently supported\n"));
10405 break;
10406 }
fa197c1c 10407
625d49fc 10408 word = (word & ~ (uint64_t) 0x7fffffff) | (prelval & 0x7fffffff);
0b6ae522
DJ
10409 addr->section = sym->st_shndx;
10410 addr->offset = offset;
74e1a04b 10411
1b31d05e
NC
10412 if (sym_name)
10413 * sym_name = sym->st_name;
0b6ae522
DJ
10414 break;
10415 }
10416
10417 *wordp = word;
10418 arm_sec->next_rela = rp;
10419
015dc7e1 10420 return true;
0b6ae522
DJ
10421}
10422
a734115a
NC
10423static const char *tic6x_unwind_regnames[16] =
10424{
0b4362b0
RM
10425 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
10426 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
10427 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
10428};
fa197c1c 10429
0b6ae522 10430static void
fa197c1c 10431decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 10432{
fa197c1c
PB
10433 int i;
10434
10435 for (i = 12; mask; mask >>= 1, i--)
10436 {
10437 if (mask & 1)
10438 {
10439 fputs (tic6x_unwind_regnames[i], stdout);
10440 if (mask > 1)
10441 fputs (", ", stdout);
10442 }
10443 }
10444}
0b6ae522
DJ
10445
10446#define ADVANCE \
10447 if (remaining == 0 && more_words) \
10448 { \
10449 data_offset += 4; \
dda8d76d 10450 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 10451 data_offset, & word, & addr, NULL)) \
015dc7e1 10452 return false; \
0b6ae522
DJ
10453 remaining = 4; \
10454 more_words--; \
10455 } \
10456
10457#define GET_OP(OP) \
10458 ADVANCE; \
10459 if (remaining) \
10460 { \
10461 remaining--; \
10462 (OP) = word >> 24; \
10463 word <<= 8; \
10464 } \
10465 else \
10466 { \
2b692964 10467 printf (_("[Truncated opcode]\n")); \
015dc7e1 10468 return false; \
0b6ae522 10469 } \
cc5914eb 10470 printf ("0x%02x ", OP)
0b6ae522 10471
015dc7e1 10472static bool
dda8d76d
NC
10473decode_arm_unwind_bytecode (Filedata * filedata,
10474 struct arm_unw_aux_info * aux,
948f632f
DA
10475 unsigned int word,
10476 unsigned int remaining,
10477 unsigned int more_words,
625d49fc 10478 uint64_t data_offset,
948f632f
DA
10479 Elf_Internal_Shdr * data_sec,
10480 struct arm_section * data_arm_sec)
fa197c1c
PB
10481{
10482 struct absaddr addr;
015dc7e1 10483 bool res = true;
0b6ae522
DJ
10484
10485 /* Decode the unwinding instructions. */
10486 while (1)
10487 {
10488 unsigned int op, op2;
10489
10490 ADVANCE;
10491 if (remaining == 0)
10492 break;
10493 remaining--;
10494 op = word >> 24;
10495 word <<= 8;
10496
cc5914eb 10497 printf (" 0x%02x ", op);
0b6ae522
DJ
10498
10499 if ((op & 0xc0) == 0x00)
10500 {
10501 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10502
cc5914eb 10503 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
10504 }
10505 else if ((op & 0xc0) == 0x40)
10506 {
10507 int offset = ((op & 0x3f) << 2) + 4;
61865e30 10508
cc5914eb 10509 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
10510 }
10511 else if ((op & 0xf0) == 0x80)
10512 {
10513 GET_OP (op2);
10514 if (op == 0x80 && op2 == 0)
10515 printf (_("Refuse to unwind"));
10516 else
10517 {
10518 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 10519 bool first = true;
0b6ae522 10520 int i;
2b692964 10521
0b6ae522
DJ
10522 printf ("pop {");
10523 for (i = 0; i < 12; i++)
10524 if (mask & (1 << i))
10525 {
10526 if (first)
015dc7e1 10527 first = false;
0b6ae522
DJ
10528 else
10529 printf (", ");
10530 printf ("r%d", 4 + i);
10531 }
10532 printf ("}");
10533 }
10534 }
10535 else if ((op & 0xf0) == 0x90)
10536 {
10537 if (op == 0x9d || op == 0x9f)
10538 printf (_(" [Reserved]"));
10539 else
cc5914eb 10540 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
10541 }
10542 else if ((op & 0xf0) == 0xa0)
10543 {
10544 int end = 4 + (op & 0x07);
015dc7e1 10545 bool first = true;
0b6ae522 10546 int i;
61865e30 10547
0b6ae522
DJ
10548 printf (" pop {");
10549 for (i = 4; i <= end; i++)
10550 {
10551 if (first)
015dc7e1 10552 first = false;
0b6ae522
DJ
10553 else
10554 printf (", ");
10555 printf ("r%d", i);
10556 }
10557 if (op & 0x08)
10558 {
1b31d05e 10559 if (!first)
0b6ae522
DJ
10560 printf (", ");
10561 printf ("r14");
10562 }
10563 printf ("}");
10564 }
10565 else if (op == 0xb0)
10566 printf (_(" finish"));
10567 else if (op == 0xb1)
10568 {
10569 GET_OP (op2);
10570 if (op2 == 0 || (op2 & 0xf0) != 0)
10571 printf (_("[Spare]"));
10572 else
10573 {
10574 unsigned int mask = op2 & 0x0f;
015dc7e1 10575 bool first = true;
0b6ae522 10576 int i;
61865e30 10577
0b6ae522
DJ
10578 printf ("pop {");
10579 for (i = 0; i < 12; i++)
10580 if (mask & (1 << i))
10581 {
10582 if (first)
015dc7e1 10583 first = false;
0b6ae522
DJ
10584 else
10585 printf (", ");
10586 printf ("r%d", i);
10587 }
10588 printf ("}");
10589 }
10590 }
10591 else if (op == 0xb2)
10592 {
b115cf96 10593 unsigned char buf[9];
0b6ae522 10594 unsigned int i, len;
26c527e6 10595 uint64_t offset;
61865e30 10596
b115cf96 10597 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
10598 {
10599 GET_OP (buf[i]);
10600 if ((buf[i] & 0x80) == 0)
10601 break;
10602 }
4082ef84 10603 if (i == sizeof (buf))
32ec8896 10604 {
27a45f42 10605 error (_("corrupt change to vsp\n"));
015dc7e1 10606 res = false;
32ec8896 10607 }
4082ef84
NC
10608 else
10609 {
015dc7e1 10610 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
10611 assert (len == i + 1);
10612 offset = offset * 4 + 0x204;
26c527e6 10613 printf ("vsp = vsp + %" PRId64, offset);
4082ef84 10614 }
0b6ae522 10615 }
61865e30 10616 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 10617 {
61865e30
NC
10618 unsigned int first, last;
10619
10620 GET_OP (op2);
10621 first = op2 >> 4;
10622 last = op2 & 0x0f;
10623 if (op == 0xc8)
10624 first = first + 16;
10625 printf ("pop {D%d", first);
10626 if (last)
10627 printf ("-D%d", first + last);
10628 printf ("}");
10629 }
09854a88
TB
10630 else if (op == 0xb4)
10631 printf (_(" pop {ra_auth_code}"));
b62fb887
SP
10632 else if (op == 0xb5)
10633 printf (_(" vsp as modifier for PAC validation"));
61865e30
NC
10634 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
10635 {
10636 unsigned int count = op & 0x07;
10637
10638 printf ("pop {D8");
10639 if (count)
10640 printf ("-D%d", 8 + count);
10641 printf ("}");
10642 }
10643 else if (op >= 0xc0 && op <= 0xc5)
10644 {
10645 unsigned int count = op & 0x07;
10646
10647 printf (" pop {wR10");
10648 if (count)
10649 printf ("-wR%d", 10 + count);
10650 printf ("}");
10651 }
10652 else if (op == 0xc6)
10653 {
10654 unsigned int first, last;
10655
10656 GET_OP (op2);
10657 first = op2 >> 4;
10658 last = op2 & 0x0f;
10659 printf ("pop {wR%d", first);
10660 if (last)
10661 printf ("-wR%d", first + last);
10662 printf ("}");
10663 }
10664 else if (op == 0xc7)
10665 {
10666 GET_OP (op2);
10667 if (op2 == 0 || (op2 & 0xf0) != 0)
10668 printf (_("[Spare]"));
0b6ae522
DJ
10669 else
10670 {
61865e30 10671 unsigned int mask = op2 & 0x0f;
015dc7e1 10672 bool first = true;
61865e30
NC
10673 int i;
10674
10675 printf ("pop {");
10676 for (i = 0; i < 4; i++)
10677 if (mask & (1 << i))
10678 {
10679 if (first)
015dc7e1 10680 first = false;
61865e30
NC
10681 else
10682 printf (", ");
10683 printf ("wCGR%d", i);
10684 }
10685 printf ("}");
0b6ae522
DJ
10686 }
10687 }
61865e30 10688 else
32ec8896
NC
10689 {
10690 printf (_(" [unsupported opcode]"));
015dc7e1 10691 res = false;
32ec8896
NC
10692 }
10693
0b6ae522
DJ
10694 printf ("\n");
10695 }
32ec8896
NC
10696
10697 return res;
fa197c1c
PB
10698}
10699
015dc7e1 10700static bool
dda8d76d
NC
10701decode_tic6x_unwind_bytecode (Filedata * filedata,
10702 struct arm_unw_aux_info * aux,
948f632f
DA
10703 unsigned int word,
10704 unsigned int remaining,
10705 unsigned int more_words,
625d49fc 10706 uint64_t data_offset,
948f632f
DA
10707 Elf_Internal_Shdr * data_sec,
10708 struct arm_section * data_arm_sec)
fa197c1c
PB
10709{
10710 struct absaddr addr;
10711
10712 /* Decode the unwinding instructions. */
10713 while (1)
10714 {
10715 unsigned int op, op2;
10716
10717 ADVANCE;
10718 if (remaining == 0)
10719 break;
10720 remaining--;
10721 op = word >> 24;
10722 word <<= 8;
10723
9cf03b7e 10724 printf (" 0x%02x ", op);
fa197c1c
PB
10725
10726 if ((op & 0xc0) == 0x00)
10727 {
10728 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 10729 printf (" sp = sp + %d", offset);
fa197c1c
PB
10730 }
10731 else if ((op & 0xc0) == 0x80)
10732 {
10733 GET_OP (op2);
10734 if (op == 0x80 && op2 == 0)
10735 printf (_("Refuse to unwind"));
10736 else
10737 {
10738 unsigned int mask = ((op & 0x1f) << 8) | op2;
10739 if (op & 0x20)
10740 printf ("pop compact {");
10741 else
10742 printf ("pop {");
10743
10744 decode_tic6x_unwind_regmask (mask);
10745 printf("}");
10746 }
10747 }
10748 else if ((op & 0xf0) == 0xc0)
10749 {
10750 unsigned int reg;
10751 unsigned int nregs;
10752 unsigned int i;
10753 const char *name;
a734115a
NC
10754 struct
10755 {
32ec8896
NC
10756 unsigned int offset;
10757 unsigned int reg;
fa197c1c
PB
10758 } regpos[16];
10759
10760 /* Scan entire instruction first so that GET_OP output is not
10761 interleaved with disassembly. */
10762 nregs = 0;
10763 for (i = 0; nregs < (op & 0xf); i++)
10764 {
10765 GET_OP (op2);
10766 reg = op2 >> 4;
10767 if (reg != 0xf)
10768 {
10769 regpos[nregs].offset = i * 2;
10770 regpos[nregs].reg = reg;
10771 nregs++;
10772 }
10773
10774 reg = op2 & 0xf;
10775 if (reg != 0xf)
10776 {
10777 regpos[nregs].offset = i * 2 + 1;
10778 regpos[nregs].reg = reg;
10779 nregs++;
10780 }
10781 }
10782
10783 printf (_("pop frame {"));
18344509 10784 if (nregs == 0)
fa197c1c 10785 {
18344509
NC
10786 printf (_("*corrupt* - no registers specified"));
10787 }
10788 else
10789 {
10790 reg = nregs - 1;
10791 for (i = i * 2; i > 0; i--)
fa197c1c 10792 {
18344509
NC
10793 if (regpos[reg].offset == i - 1)
10794 {
10795 name = tic6x_unwind_regnames[regpos[reg].reg];
10796 if (reg > 0)
10797 reg--;
10798 }
10799 else
10800 name = _("[pad]");
fa197c1c 10801
18344509
NC
10802 fputs (name, stdout);
10803 if (i > 1)
10804 printf (", ");
10805 }
fa197c1c
PB
10806 }
10807
10808 printf ("}");
10809 }
10810 else if (op == 0xd0)
10811 printf (" MOV FP, SP");
10812 else if (op == 0xd1)
10813 printf (" __c6xabi_pop_rts");
10814 else if (op == 0xd2)
10815 {
10816 unsigned char buf[9];
10817 unsigned int i, len;
26c527e6 10818 uint64_t offset;
a734115a 10819
fa197c1c
PB
10820 for (i = 0; i < sizeof (buf); i++)
10821 {
10822 GET_OP (buf[i]);
10823 if ((buf[i] & 0x80) == 0)
10824 break;
10825 }
0eff7165
NC
10826 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
10827 if (i == sizeof (buf))
10828 {
0eff7165 10829 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 10830 return false;
0eff7165 10831 }
948f632f 10832
015dc7e1 10833 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
10834 assert (len == i + 1);
10835 offset = offset * 8 + 0x408;
26c527e6 10836 printf (_("sp = sp + %" PRId64), offset);
fa197c1c
PB
10837 }
10838 else if ((op & 0xf0) == 0xe0)
10839 {
10840 if ((op & 0x0f) == 7)
10841 printf (" RETURN");
10842 else
10843 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
10844 }
10845 else
10846 {
10847 printf (_(" [unsupported opcode]"));
10848 }
10849 putchar ('\n');
10850 }
32ec8896 10851
015dc7e1 10852 return true;
fa197c1c
PB
10853}
10854
625d49fc
AM
10855static uint64_t
10856arm_expand_prel31 (Filedata * filedata, uint64_t word, uint64_t where)
fa197c1c 10857{
625d49fc 10858 uint64_t offset;
fa197c1c
PB
10859
10860 offset = word & 0x7fffffff;
10861 if (offset & 0x40000000)
625d49fc 10862 offset |= ~ (uint64_t) 0x7fffffff;
fa197c1c 10863
dda8d76d 10864 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
10865 offset <<= 1;
10866
10867 return offset + where;
10868}
10869
015dc7e1 10870static bool
dda8d76d
NC
10871decode_arm_unwind (Filedata * filedata,
10872 struct arm_unw_aux_info * aux,
1b31d05e
NC
10873 unsigned int word,
10874 unsigned int remaining,
625d49fc 10875 uint64_t data_offset,
1b31d05e
NC
10876 Elf_Internal_Shdr * data_sec,
10877 struct arm_section * data_arm_sec)
fa197c1c
PB
10878{
10879 int per_index;
10880 unsigned int more_words = 0;
37e14bc3 10881 struct absaddr addr;
625d49fc 10882 uint64_t sym_name = (uint64_t) -1;
015dc7e1 10883 bool res = true;
fa197c1c
PB
10884
10885 if (remaining == 0)
10886 {
1b31d05e
NC
10887 /* Fetch the first word.
10888 Note - when decoding an object file the address extracted
10889 here will always be 0. So we also pass in the sym_name
10890 parameter so that we can find the symbol associated with
10891 the personality routine. */
dda8d76d 10892 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 10893 & word, & addr, & sym_name))
015dc7e1 10894 return false;
1b31d05e 10895
fa197c1c
PB
10896 remaining = 4;
10897 }
c93dbb25
CZ
10898 else
10899 {
10900 addr.section = SHN_UNDEF;
10901 addr.offset = 0;
10902 }
fa197c1c
PB
10903
10904 if ((word & 0x80000000) == 0)
10905 {
10906 /* Expand prel31 for personality routine. */
625d49fc 10907 uint64_t fn;
fa197c1c
PB
10908 const char *procname;
10909
dda8d76d 10910 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10911 printf (_(" Personality routine: "));
1b31d05e
NC
10912 if (fn == 0
10913 && addr.section == SHN_UNDEF && addr.offset == 0
625d49fc 10914 && sym_name != (uint64_t) -1 && sym_name < aux->strtab_size)
1b31d05e
NC
10915 {
10916 procname = aux->strtab + sym_name;
10917 print_vma (fn, PREFIX_HEX);
10918 if (procname)
10919 {
10920 fputs (" <", stdout);
10921 fputs (procname, stdout);
10922 fputc ('>', stdout);
10923 }
10924 }
10925 else
dda8d76d 10926 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10927 fputc ('\n', stdout);
10928
10929 /* The GCC personality routines use the standard compact
10930 encoding, starting with one byte giving the number of
10931 words. */
10932 if (procname != NULL
24d127aa
ML
10933 && (startswith (procname, "__gcc_personality_v0")
10934 || startswith (procname, "__gxx_personality_v0")
10935 || startswith (procname, "__gcj_personality_v0")
10936 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10937 {
10938 remaining = 0;
10939 more_words = 1;
10940 ADVANCE;
10941 if (!remaining)
10942 {
10943 printf (_(" [Truncated data]\n"));
015dc7e1 10944 return false;
fa197c1c
PB
10945 }
10946 more_words = word >> 24;
10947 word <<= 8;
10948 remaining--;
10949 per_index = -1;
10950 }
10951 else
015dc7e1 10952 return true;
fa197c1c
PB
10953 }
10954 else
10955 {
1b31d05e 10956 /* ARM EHABI Section 6.3:
0b4362b0 10957
1b31d05e 10958 An exception-handling table entry for the compact model looks like:
0b4362b0 10959
1b31d05e
NC
10960 31 30-28 27-24 23-0
10961 -- ----- ----- ----
10962 1 0 index Data for personalityRoutine[index] */
10963
dda8d76d 10964 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10965 && (word & 0x70000000))
32ec8896
NC
10966 {
10967 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10968 res = false;
32ec8896 10969 }
1b31d05e 10970
fa197c1c 10971 per_index = (word >> 24) & 0x7f;
1b31d05e 10972 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10973 if (per_index == 0)
10974 {
10975 more_words = 0;
10976 word <<= 8;
10977 remaining--;
10978 }
10979 else if (per_index < 3)
10980 {
10981 more_words = (word >> 16) & 0xff;
10982 word <<= 16;
10983 remaining -= 2;
10984 }
10985 }
10986
dda8d76d 10987 switch (filedata->file_header.e_machine)
fa197c1c
PB
10988 {
10989 case EM_ARM:
10990 if (per_index < 3)
10991 {
dda8d76d 10992 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10993 data_offset, data_sec, data_arm_sec))
015dc7e1 10994 res = false;
fa197c1c
PB
10995 }
10996 else
1b31d05e
NC
10997 {
10998 warn (_("Unknown ARM compact model index encountered\n"));
10999 printf (_(" [reserved]\n"));
015dc7e1 11000 res = false;
1b31d05e 11001 }
fa197c1c
PB
11002 break;
11003
11004 case EM_TI_C6000:
11005 if (per_index < 3)
11006 {
dda8d76d 11007 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 11008 data_offset, data_sec, data_arm_sec))
015dc7e1 11009 res = false;
fa197c1c
PB
11010 }
11011 else if (per_index < 5)
11012 {
11013 if (((word >> 17) & 0x7f) == 0x7f)
11014 printf (_(" Restore stack from frame pointer\n"));
11015 else
11016 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
11017 printf (_(" Registers restored: "));
11018 if (per_index == 4)
11019 printf (" (compact) ");
11020 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
11021 putchar ('\n');
11022 printf (_(" Return register: %s\n"),
11023 tic6x_unwind_regnames[word & 0xf]);
11024 }
11025 else
1b31d05e 11026 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
11027 break;
11028
11029 default:
74e1a04b 11030 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 11031 filedata->file_header.e_machine);
015dc7e1 11032 res = false;
fa197c1c 11033 }
0b6ae522
DJ
11034
11035 /* Decode the descriptors. Not implemented. */
32ec8896
NC
11036
11037 return res;
0b6ae522
DJ
11038}
11039
015dc7e1 11040static bool
dda8d76d
NC
11041dump_arm_unwind (Filedata * filedata,
11042 struct arm_unw_aux_info * aux,
11043 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
11044{
11045 struct arm_section exidx_arm_sec, extab_arm_sec;
11046 unsigned int i, exidx_len;
26c527e6 11047 uint64_t j, nfuns;
015dc7e1 11048 bool res = true;
0b6ae522
DJ
11049
11050 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
11051 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
11052 exidx_len = exidx_sec->sh_size / 8;
11053
948f632f
DA
11054 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
11055 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
11056 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
11057 aux->funtab[nfuns++] = aux->symtab[j];
11058 aux->nfuns = nfuns;
11059 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
11060
0b6ae522
DJ
11061 for (i = 0; i < exidx_len; i++)
11062 {
11063 unsigned int exidx_fn, exidx_entry;
11064 struct absaddr fn_addr, entry_addr;
625d49fc 11065 uint64_t fn;
0b6ae522
DJ
11066
11067 fputc ('\n', stdout);
11068
dda8d76d 11069 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11070 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 11071 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 11072 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 11073 {
948f632f 11074 free (aux->funtab);
1b31d05e
NC
11075 arm_free_section (& exidx_arm_sec);
11076 arm_free_section (& extab_arm_sec);
015dc7e1 11077 return false;
0b6ae522
DJ
11078 }
11079
83c257ca
NC
11080 /* ARM EHABI, Section 5:
11081 An index table entry consists of 2 words.
11082 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
11083 if (exidx_fn & 0x80000000)
32ec8896
NC
11084 {
11085 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 11086 res = false;
32ec8896 11087 }
83c257ca 11088
dda8d76d 11089 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 11090
dda8d76d 11091 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
11092 fputs (": ", stdout);
11093
11094 if (exidx_entry == 1)
11095 {
11096 print_vma (exidx_entry, PREFIX_HEX);
11097 fputs (" [cantunwind]\n", stdout);
11098 }
11099 else if (exidx_entry & 0x80000000)
11100 {
11101 print_vma (exidx_entry, PREFIX_HEX);
11102 fputc ('\n', stdout);
dda8d76d 11103 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
11104 }
11105 else
11106 {
625d49fc 11107 uint64_t table, table_offset = 0;
0b6ae522
DJ
11108 Elf_Internal_Shdr *table_sec;
11109
11110 fputs ("@", stdout);
dda8d76d 11111 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
11112 print_vma (table, PREFIX_HEX);
11113 printf ("\n");
11114
11115 /* Locate the matching .ARM.extab. */
11116 if (entry_addr.section != SHN_UNDEF
dda8d76d 11117 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 11118 {
dda8d76d 11119 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 11120 table_offset = entry_addr.offset;
1a915552 11121 /* PR 18879 */
625d49fc 11122 if (table_offset > table_sec->sh_size)
1a915552 11123 {
26c527e6
AM
11124 warn (_("Unwind entry contains corrupt offset (%#" PRIx64 ") into section %s\n"),
11125 table_offset,
dda8d76d 11126 printable_section_name (filedata, table_sec));
015dc7e1 11127 res = false;
1a915552
NC
11128 continue;
11129 }
0b6ae522
DJ
11130 }
11131 else
11132 {
dda8d76d 11133 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
11134 if (table_sec != NULL)
11135 table_offset = table - table_sec->sh_addr;
11136 }
32ec8896 11137
0b6ae522
DJ
11138 if (table_sec == NULL)
11139 {
26c527e6
AM
11140 warn (_("Could not locate .ARM.extab section containing %#" PRIx64 ".\n"),
11141 table);
015dc7e1 11142 res = false;
0b6ae522
DJ
11143 continue;
11144 }
32ec8896 11145
dda8d76d 11146 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 11147 &extab_arm_sec))
015dc7e1 11148 res = false;
0b6ae522
DJ
11149 }
11150 }
11151
11152 printf ("\n");
11153
948f632f 11154 free (aux->funtab);
0b6ae522
DJ
11155 arm_free_section (&exidx_arm_sec);
11156 arm_free_section (&extab_arm_sec);
32ec8896
NC
11157
11158 return res;
0b6ae522
DJ
11159}
11160
fa197c1c 11161/* Used for both ARM and C6X unwinding tables. */
1b31d05e 11162
015dc7e1 11163static bool
dda8d76d 11164arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
11165{
11166 struct arm_unw_aux_info aux;
11167 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522 11168 Elf_Internal_Shdr *sec;
26c527e6 11169 size_t i;
fa197c1c 11170 unsigned int sec_type;
015dc7e1 11171 bool res = true;
0b6ae522 11172
dda8d76d 11173 switch (filedata->file_header.e_machine)
fa197c1c
PB
11174 {
11175 case EM_ARM:
11176 sec_type = SHT_ARM_EXIDX;
11177 break;
11178
11179 case EM_TI_C6000:
11180 sec_type = SHT_C6000_UNWIND;
11181 break;
11182
0b4362b0 11183 default:
74e1a04b 11184 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 11185 filedata->file_header.e_machine);
015dc7e1 11186 return false;
fa197c1c
PB
11187 }
11188
dda8d76d 11189 if (filedata->string_table == NULL)
015dc7e1 11190 return false;
1b31d05e
NC
11191
11192 memset (& aux, 0, sizeof (aux));
dda8d76d 11193 aux.filedata = filedata;
0b6ae522 11194
dda8d76d 11195 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 11196 {
28d13567 11197 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 11198 {
28d13567 11199 if (aux.symtab)
74e1a04b 11200 {
28d13567
AM
11201 error (_("Multiple symbol tables encountered\n"));
11202 free (aux.symtab);
11203 aux.symtab = NULL;
74e1a04b 11204 free (aux.strtab);
28d13567 11205 aux.strtab = NULL;
74e1a04b 11206 }
28d13567
AM
11207 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
11208 &aux.strtab, &aux.strtab_size))
015dc7e1 11209 return false;
0b6ae522 11210 }
fa197c1c 11211 else if (sec->sh_type == sec_type)
0b6ae522
DJ
11212 unwsec = sec;
11213 }
11214
1b31d05e 11215 if (unwsec == NULL)
0b6ae522 11216 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 11217 else
dda8d76d 11218 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
11219 {
11220 if (sec->sh_type == sec_type)
11221 {
26c527e6
AM
11222 uint64_t num_unwind = sec->sh_size / (2 * eh_addr_size);
11223 printf (ngettext ("\nUnwind section '%s' at offset %#" PRIx64 " "
11224 "contains %" PRIu64 " entry:\n",
11225 "\nUnwind section '%s' at offset %#" PRIx64 " "
11226 "contains %" PRIu64 " entries:\n",
d3a49aa8 11227 num_unwind),
dda8d76d 11228 printable_section_name (filedata, sec),
26c527e6 11229 sec->sh_offset,
d3a49aa8 11230 num_unwind);
0b6ae522 11231
dda8d76d 11232 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 11233 res = false;
1b31d05e
NC
11234 }
11235 }
0b6ae522 11236
9db70fc3
AM
11237 free (aux.symtab);
11238 free ((char *) aux.strtab);
32ec8896
NC
11239
11240 return res;
0b6ae522
DJ
11241}
11242
3ecc00ec
NC
11243static bool
11244no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
11245{
11246 printf (_("No processor specific unwind information to decode\n"));
11247 return true;
11248}
11249
015dc7e1 11250static bool
dda8d76d 11251process_unwind (Filedata * filedata)
57346661 11252{
2cf0635d
NC
11253 struct unwind_handler
11254 {
32ec8896 11255 unsigned int machtype;
015dc7e1 11256 bool (* handler)(Filedata *);
2cf0635d
NC
11257 } handlers[] =
11258 {
0b6ae522 11259 { EM_ARM, arm_process_unwind },
57346661
AM
11260 { EM_IA_64, ia64_process_unwind },
11261 { EM_PARISC, hppa_process_unwind },
fa197c1c 11262 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
11263 { EM_386, no_processor_specific_unwind },
11264 { EM_X86_64, no_processor_specific_unwind },
32ec8896 11265 { 0, NULL }
57346661
AM
11266 };
11267 int i;
11268
11269 if (!do_unwind)
015dc7e1 11270 return true;
57346661
AM
11271
11272 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
11273 if (filedata->file_header.e_machine == handlers[i].machtype)
11274 return handlers[i].handler (filedata);
57346661 11275
1b31d05e 11276 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 11277 get_machine_name (filedata->file_header.e_machine));
015dc7e1 11278 return true;
57346661
AM
11279}
11280
37c18eed
SD
11281static void
11282dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
11283{
11284 switch (entry->d_tag)
11285 {
11286 case DT_AARCH64_BTI_PLT:
1dbade74 11287 case DT_AARCH64_PAC_PLT:
37c18eed
SD
11288 break;
11289 default:
11290 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11291 break;
11292 }
11293 putchar ('\n');
11294}
11295
252b5132 11296static void
978c4450 11297dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
11298{
11299 switch (entry->d_tag)
11300 {
11301 case DT_MIPS_FLAGS:
11302 if (entry->d_un.d_val == 0)
4b68bca3 11303 printf (_("NONE"));
252b5132
RH
11304 else
11305 {
11306 static const char * opts[] =
11307 {
11308 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
11309 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
11310 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
11311 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
11312 "RLD_ORDER_SAFE"
11313 };
11314 unsigned int cnt;
015dc7e1 11315 bool first = true;
2b692964 11316
60bca95a 11317 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
11318 if (entry->d_un.d_val & (1 << cnt))
11319 {
11320 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 11321 first = false;
252b5132 11322 }
252b5132
RH
11323 }
11324 break;
103f02d3 11325
252b5132 11326 case DT_MIPS_IVERSION:
84714f86 11327 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11328 printf (_("Interface Version: %s"),
84714f86 11329 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11330 else
f493c217 11331 printf (_("Interface Version: <corrupt: %" PRIx64 ">"),
625d49fc 11332 entry->d_un.d_ptr);
252b5132 11333 break;
103f02d3 11334
252b5132
RH
11335 case DT_MIPS_TIME_STAMP:
11336 {
d5b07ef4 11337 char timebuf[128];
2cf0635d 11338 struct tm * tmp;
91d6fa6a 11339 time_t atime = entry->d_un.d_val;
82b1b41b 11340
91d6fa6a 11341 tmp = gmtime (&atime);
82b1b41b
NC
11342 /* PR 17531: file: 6accc532. */
11343 if (tmp == NULL)
11344 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
11345 else
11346 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
11347 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11348 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 11349 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
11350 }
11351 break;
103f02d3 11352
252b5132
RH
11353 case DT_MIPS_RLD_VERSION:
11354 case DT_MIPS_LOCAL_GOTNO:
11355 case DT_MIPS_CONFLICTNO:
11356 case DT_MIPS_LIBLISTNO:
11357 case DT_MIPS_SYMTABNO:
11358 case DT_MIPS_UNREFEXTNO:
11359 case DT_MIPS_HIPAGENO:
11360 case DT_MIPS_DELTA_CLASS_NO:
11361 case DT_MIPS_DELTA_INSTANCE_NO:
11362 case DT_MIPS_DELTA_RELOC_NO:
11363 case DT_MIPS_DELTA_SYM_NO:
11364 case DT_MIPS_DELTA_CLASSSYM_NO:
11365 case DT_MIPS_COMPACT_SIZE:
c69075ac 11366 print_vma (entry->d_un.d_val, DEC);
252b5132 11367 break;
103f02d3 11368
f16a9783 11369 case DT_MIPS_XHASH:
978c4450
AM
11370 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11371 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
11372 /* Falls through. */
11373
103f02d3 11374 default:
4b68bca3 11375 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 11376 }
4b68bca3 11377 putchar ('\n');
103f02d3
UD
11378}
11379
103f02d3 11380static void
2cf0635d 11381dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
11382{
11383 switch (entry->d_tag)
11384 {
11385 case DT_HP_DLD_FLAGS:
11386 {
11387 static struct
11388 {
26c527e6 11389 unsigned int bit;
2cf0635d 11390 const char * str;
5e220199
NC
11391 }
11392 flags[] =
11393 {
11394 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
11395 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
11396 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
11397 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
11398 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
11399 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
11400 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
11401 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
11402 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
11403 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
11404 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
11405 { DT_HP_GST, "HP_GST" },
11406 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
11407 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
11408 { DT_HP_NODELETE, "HP_NODELETE" },
11409 { DT_HP_GROUP, "HP_GROUP" },
11410 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 11411 };
015dc7e1 11412 bool first = true;
5e220199 11413 size_t cnt;
625d49fc 11414 uint64_t val = entry->d_un.d_val;
103f02d3 11415
60bca95a 11416 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 11417 if (val & flags[cnt].bit)
30800947
NC
11418 {
11419 if (! first)
11420 putchar (' ');
11421 fputs (flags[cnt].str, stdout);
015dc7e1 11422 first = false;
30800947
NC
11423 val ^= flags[cnt].bit;
11424 }
76da6bbe 11425
103f02d3 11426 if (val != 0 || first)
f7a99963
NC
11427 {
11428 if (! first)
11429 putchar (' ');
11430 print_vma (val, HEX);
11431 }
103f02d3
UD
11432 }
11433 break;
76da6bbe 11434
252b5132 11435 default:
f7a99963
NC
11436 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11437 break;
252b5132 11438 }
35b1837e 11439 putchar ('\n');
252b5132
RH
11440}
11441
28f997cf
TG
11442/* VMS vs Unix time offset and factor. */
11443
11444#define VMS_EPOCH_OFFSET 35067168000000000LL
11445#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
11446#ifndef INT64_MIN
11447#define INT64_MIN (-9223372036854775807LL - 1)
11448#endif
28f997cf
TG
11449
11450/* Display a VMS time in a human readable format. */
11451
11452static void
0e3c1eeb 11453print_vms_time (int64_t vmstime)
28f997cf 11454{
dccc31de 11455 struct tm *tm = NULL;
28f997cf
TG
11456 time_t unxtime;
11457
dccc31de
AM
11458 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
11459 {
11460 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
11461 unxtime = vmstime;
11462 if (unxtime == vmstime)
11463 tm = gmtime (&unxtime);
11464 }
11465 if (tm != NULL)
11466 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
11467 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
11468 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf 11469}
28f997cf 11470
ecc51f48 11471static void
2cf0635d 11472dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
11473{
11474 switch (entry->d_tag)
11475 {
0de14b54 11476 case DT_IA_64_PLT_RESERVE:
bdf4d63a 11477 /* First 3 slots reserved. */
ecc51f48
NC
11478 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11479 printf (" -- ");
11480 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
11481 break;
11482
28f997cf 11483 case DT_IA_64_VMS_LINKTIME:
28f997cf 11484 print_vms_time (entry->d_un.d_val);
28f997cf
TG
11485 break;
11486
11487 case DT_IA_64_VMS_LNKFLAGS:
11488 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11489 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
11490 printf (" CALL_DEBUG");
11491 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
11492 printf (" NOP0BUFS");
11493 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
11494 printf (" P0IMAGE");
11495 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
11496 printf (" MKTHREADS");
11497 if (entry->d_un.d_val & VMS_LF_UPCALLS)
11498 printf (" UPCALLS");
11499 if (entry->d_un.d_val & VMS_LF_IMGSTA)
11500 printf (" IMGSTA");
11501 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
11502 printf (" INITIALIZE");
11503 if (entry->d_un.d_val & VMS_LF_MAIN)
11504 printf (" MAIN");
11505 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
11506 printf (" EXE_INIT");
11507 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
11508 printf (" TBK_IN_IMG");
11509 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
11510 printf (" DBG_IN_IMG");
11511 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
11512 printf (" TBK_IN_DSF");
11513 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
11514 printf (" DBG_IN_DSF");
11515 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
11516 printf (" SIGNATURES");
11517 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
11518 printf (" REL_SEG_OFF");
11519 break;
11520
bdf4d63a
JJ
11521 default:
11522 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
11523 break;
ecc51f48 11524 }
bdf4d63a 11525 putchar ('\n');
ecc51f48
NC
11526}
11527
015dc7e1 11528static bool
dda8d76d 11529get_32bit_dynamic_section (Filedata * filedata)
252b5132 11530{
2cf0635d
NC
11531 Elf32_External_Dyn * edyn;
11532 Elf32_External_Dyn * ext;
11533 Elf_Internal_Dyn * entry;
103f02d3 11534
978c4450
AM
11535 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
11536 filedata->dynamic_addr, 1,
11537 filedata->dynamic_size,
11538 _("dynamic section"));
a6e9f9df 11539 if (!edyn)
015dc7e1 11540 return false;
103f02d3 11541
071436c6
NC
11542 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11543 might not have the luxury of section headers. Look for the DT_NULL
11544 terminator to determine the number of entries. */
978c4450
AM
11545 for (ext = edyn, filedata->dynamic_nent = 0;
11546 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11547 ext++)
11548 {
978c4450 11549 filedata->dynamic_nent++;
ba2685cc
AM
11550 if (BYTE_GET (ext->d_tag) == DT_NULL)
11551 break;
11552 }
252b5132 11553
978c4450
AM
11554 filedata->dynamic_section
11555 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11556 if (filedata->dynamic_section == NULL)
252b5132 11557 {
26c527e6
AM
11558 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11559 filedata->dynamic_nent);
9ea033b2 11560 free (edyn);
015dc7e1 11561 return false;
9ea033b2 11562 }
252b5132 11563
978c4450
AM
11564 for (ext = edyn, entry = filedata->dynamic_section;
11565 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11566 ext++, entry++)
9ea033b2 11567 {
fb514b26
AM
11568 entry->d_tag = BYTE_GET (ext->d_tag);
11569 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11570 }
11571
9ea033b2
NC
11572 free (edyn);
11573
015dc7e1 11574 return true;
9ea033b2
NC
11575}
11576
015dc7e1 11577static bool
dda8d76d 11578get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 11579{
2cf0635d
NC
11580 Elf64_External_Dyn * edyn;
11581 Elf64_External_Dyn * ext;
11582 Elf_Internal_Dyn * entry;
103f02d3 11583
071436c6 11584 /* Read in the data. */
978c4450
AM
11585 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
11586 filedata->dynamic_addr, 1,
11587 filedata->dynamic_size,
11588 _("dynamic section"));
a6e9f9df 11589 if (!edyn)
015dc7e1 11590 return false;
103f02d3 11591
071436c6
NC
11592 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
11593 might not have the luxury of section headers. Look for the DT_NULL
11594 terminator to determine the number of entries. */
978c4450 11595 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 11596 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 11597 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
11598 ext++)
11599 {
978c4450 11600 filedata->dynamic_nent++;
66543521 11601 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
11602 break;
11603 }
252b5132 11604
978c4450
AM
11605 filedata->dynamic_section
11606 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
11607 if (filedata->dynamic_section == NULL)
252b5132 11608 {
26c527e6
AM
11609 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
11610 filedata->dynamic_nent);
252b5132 11611 free (edyn);
015dc7e1 11612 return false;
252b5132
RH
11613 }
11614
071436c6 11615 /* Convert from external to internal formats. */
978c4450
AM
11616 for (ext = edyn, entry = filedata->dynamic_section;
11617 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 11618 ext++, entry++)
252b5132 11619 {
66543521
AM
11620 entry->d_tag = BYTE_GET (ext->d_tag);
11621 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
11622 }
11623
11624 free (edyn);
11625
015dc7e1 11626 return true;
9ea033b2
NC
11627}
11628
4de91c10
AM
11629static bool
11630get_dynamic_section (Filedata *filedata)
11631{
11632 if (filedata->dynamic_section)
11633 return true;
11634
11635 if (is_32bit_elf)
11636 return get_32bit_dynamic_section (filedata);
11637 else
11638 return get_64bit_dynamic_section (filedata);
11639}
11640
e9e44622 11641static void
625d49fc 11642print_dynamic_flags (uint64_t flags)
d1133906 11643{
015dc7e1 11644 bool first = true;
13ae64f3 11645
d1133906
NC
11646 while (flags)
11647 {
625d49fc 11648 uint64_t flag;
d1133906
NC
11649
11650 flag = flags & - flags;
11651 flags &= ~ flag;
11652
e9e44622 11653 if (first)
015dc7e1 11654 first = false;
e9e44622
JJ
11655 else
11656 putc (' ', stdout);
13ae64f3 11657
d1133906
NC
11658 switch (flag)
11659 {
e9e44622
JJ
11660 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
11661 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
11662 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
11663 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
11664 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 11665 default: fputs (_("unknown"), stdout); break;
d1133906
NC
11666 }
11667 }
e9e44622 11668 puts ("");
d1133906
NC
11669}
11670
625d49fc 11671static uint64_t *
be7d229a 11672get_dynamic_data (Filedata * filedata, uint64_t number, unsigned int ent_size)
10ca4b04
L
11673{
11674 unsigned char * e_data;
625d49fc 11675 uint64_t * i_data;
10ca4b04 11676
be7d229a
AM
11677 /* If size_t is smaller than uint64_t, eg because you are building
11678 on a 32-bit host, then make sure that when number is cast to
11679 size_t no information is lost. */
11680 if ((size_t) number != number
11681 || ent_size * number / ent_size != number)
10ca4b04 11682 {
be7d229a 11683 error (_("Size overflow prevents reading %" PRIu64
b8281767 11684 " elements of size %u\n"),
be7d229a 11685 number, ent_size);
10ca4b04
L
11686 return NULL;
11687 }
11688
11689 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
11690 attempting to allocate memory when the read is bound to fail. */
11691 if (ent_size * number > filedata->file_size)
11692 {
b8281767 11693 error (_("Invalid number of dynamic entries: %" PRIu64 "\n"),
be7d229a 11694 number);
10ca4b04
L
11695 return NULL;
11696 }
11697
11698 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
11699 if (e_data == NULL)
11700 {
b8281767 11701 error (_("Out of memory reading %" PRIu64 " dynamic entries\n"),
be7d229a 11702 number);
10ca4b04
L
11703 return NULL;
11704 }
11705
11706 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
11707 {
b8281767 11708 error (_("Unable to read in %" PRIu64 " bytes of dynamic data\n"),
be7d229a 11709 number * ent_size);
10ca4b04
L
11710 free (e_data);
11711 return NULL;
11712 }
11713
625d49fc 11714 i_data = (uint64_t *) cmalloc ((size_t) number, sizeof (*i_data));
10ca4b04
L
11715 if (i_data == NULL)
11716 {
b8281767 11717 error (_("Out of memory allocating space for %" PRIu64 " dynamic entries\n"),
be7d229a 11718 number);
10ca4b04
L
11719 free (e_data);
11720 return NULL;
11721 }
11722
11723 while (number--)
11724 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
11725
11726 free (e_data);
11727
11728 return i_data;
11729}
11730
26c527e6 11731static uint64_t
10ca4b04
L
11732get_num_dynamic_syms (Filedata * filedata)
11733{
26c527e6 11734 uint64_t num_of_syms = 0;
10ca4b04
L
11735
11736 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
11737 return num_of_syms;
11738
978c4450 11739 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
11740 {
11741 unsigned char nb[8];
11742 unsigned char nc[8];
11743 unsigned int hash_ent_size = 4;
11744
11745 if ((filedata->file_header.e_machine == EM_ALPHA
11746 || filedata->file_header.e_machine == EM_S390
11747 || filedata->file_header.e_machine == EM_S390_OLD)
11748 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
11749 hash_ent_size = 8;
11750
63cf857e
AM
11751 if (fseek64 (filedata->handle,
11752 (filedata->archive_file_offset
11753 + offset_from_vma (filedata,
11754 filedata->dynamic_info[DT_HASH],
11755 sizeof nb + sizeof nc)),
11756 SEEK_SET))
10ca4b04
L
11757 {
11758 error (_("Unable to seek to start of dynamic information\n"));
11759 goto no_hash;
11760 }
11761
11762 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
11763 {
11764 error (_("Failed to read in number of buckets\n"));
11765 goto no_hash;
11766 }
11767
11768 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
11769 {
11770 error (_("Failed to read in number of chains\n"));
11771 goto no_hash;
11772 }
11773
978c4450
AM
11774 filedata->nbuckets = byte_get (nb, hash_ent_size);
11775 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 11776
2482f306
AM
11777 if (filedata->nbuckets != 0 && filedata->nchains != 0)
11778 {
11779 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
11780 hash_ent_size);
11781 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
11782 hash_ent_size);
001890e1 11783
2482f306
AM
11784 if (filedata->buckets != NULL && filedata->chains != NULL)
11785 num_of_syms = filedata->nchains;
11786 }
ceb9bf11 11787 no_hash:
10ca4b04
L
11788 if (num_of_syms == 0)
11789 {
9db70fc3
AM
11790 free (filedata->buckets);
11791 filedata->buckets = NULL;
11792 free (filedata->chains);
11793 filedata->chains = NULL;
978c4450 11794 filedata->nbuckets = 0;
10ca4b04
L
11795 }
11796 }
11797
978c4450 11798 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
11799 {
11800 unsigned char nb[16];
625d49fc
AM
11801 uint64_t i, maxchain = 0xffffffff, bitmaskwords;
11802 uint64_t buckets_vma;
26c527e6 11803 uint64_t hn;
10ca4b04 11804
63cf857e
AM
11805 if (fseek64 (filedata->handle,
11806 (filedata->archive_file_offset
11807 + offset_from_vma (filedata,
11808 filedata->dynamic_info_DT_GNU_HASH,
11809 sizeof nb)),
11810 SEEK_SET))
10ca4b04
L
11811 {
11812 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11813 goto no_gnu_hash;
11814 }
11815
11816 if (fread (nb, 16, 1, filedata->handle) != 1)
11817 {
11818 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
11819 goto no_gnu_hash;
11820 }
11821
978c4450
AM
11822 filedata->ngnubuckets = byte_get (nb, 4);
11823 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 11824 bitmaskwords = byte_get (nb + 8, 4);
978c4450 11825 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
11826 if (is_32bit_elf)
11827 buckets_vma += bitmaskwords * 4;
11828 else
11829 buckets_vma += bitmaskwords * 8;
11830
63cf857e
AM
11831 if (fseek64 (filedata->handle,
11832 (filedata->archive_file_offset
11833 + offset_from_vma (filedata, buckets_vma, 4)),
11834 SEEK_SET))
10ca4b04
L
11835 {
11836 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11837 goto no_gnu_hash;
11838 }
11839
978c4450
AM
11840 filedata->gnubuckets
11841 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 11842
978c4450 11843 if (filedata->gnubuckets == NULL)
90837ea7 11844 goto no_gnu_hash;
10ca4b04 11845
978c4450
AM
11846 for (i = 0; i < filedata->ngnubuckets; i++)
11847 if (filedata->gnubuckets[i] != 0)
10ca4b04 11848 {
978c4450 11849 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 11850 goto no_gnu_hash;
10ca4b04 11851
978c4450
AM
11852 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
11853 maxchain = filedata->gnubuckets[i];
10ca4b04
L
11854 }
11855
11856 if (maxchain == 0xffffffff)
90837ea7 11857 goto no_gnu_hash;
10ca4b04 11858
978c4450 11859 maxchain -= filedata->gnusymidx;
10ca4b04 11860
63cf857e
AM
11861 if (fseek64 (filedata->handle,
11862 (filedata->archive_file_offset
11863 + offset_from_vma (filedata,
11864 buckets_vma + 4 * (filedata->ngnubuckets
11865 + maxchain),
11866 4)),
11867 SEEK_SET))
10ca4b04
L
11868 {
11869 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11870 goto no_gnu_hash;
11871 }
11872
11873 do
11874 {
11875 if (fread (nb, 4, 1, filedata->handle) != 1)
11876 {
11877 error (_("Failed to determine last chain length\n"));
10ca4b04
L
11878 goto no_gnu_hash;
11879 }
11880
11881 if (maxchain + 1 == 0)
90837ea7 11882 goto no_gnu_hash;
10ca4b04
L
11883
11884 ++maxchain;
11885 }
11886 while ((byte_get (nb, 4) & 1) == 0);
11887
63cf857e
AM
11888 if (fseek64 (filedata->handle,
11889 (filedata->archive_file_offset
11890 + offset_from_vma (filedata, (buckets_vma
11891 + 4 * filedata->ngnubuckets),
11892 4)),
11893 SEEK_SET))
10ca4b04
L
11894 {
11895 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11896 goto no_gnu_hash;
11897 }
11898
978c4450
AM
11899 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11900 filedata->ngnuchains = maxchain;
10ca4b04 11901
978c4450 11902 if (filedata->gnuchains == NULL)
90837ea7 11903 goto no_gnu_hash;
10ca4b04 11904
978c4450 11905 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11906 {
63cf857e
AM
11907 if (fseek64 (filedata->handle,
11908 (filedata->archive_file_offset
11909 + offset_from_vma (filedata, (buckets_vma
11910 + 4 * (filedata->ngnubuckets
11911 + maxchain)), 4)),
11912 SEEK_SET))
10ca4b04
L
11913 {
11914 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11915 goto no_gnu_hash;
11916 }
11917
978c4450 11918 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11919 if (filedata->mipsxlat == NULL)
11920 goto no_gnu_hash;
10ca4b04
L
11921 }
11922
978c4450
AM
11923 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11924 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11925 {
625d49fc
AM
11926 uint64_t si = filedata->gnubuckets[hn];
11927 uint64_t off = si - filedata->gnusymidx;
10ca4b04
L
11928
11929 do
11930 {
978c4450 11931 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11932 {
c31ab5a0
AM
11933 if (off < filedata->ngnuchains
11934 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11935 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11936 }
11937 else
11938 {
11939 if (si >= num_of_syms)
11940 num_of_syms = si + 1;
11941 }
11942 si++;
11943 }
978c4450
AM
11944 while (off < filedata->ngnuchains
11945 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11946 }
11947
90837ea7 11948 if (num_of_syms == 0)
10ca4b04 11949 {
90837ea7 11950 no_gnu_hash:
9db70fc3
AM
11951 free (filedata->mipsxlat);
11952 filedata->mipsxlat = NULL;
11953 free (filedata->gnuchains);
11954 filedata->gnuchains = NULL;
11955 free (filedata->gnubuckets);
11956 filedata->gnubuckets = NULL;
978c4450
AM
11957 filedata->ngnubuckets = 0;
11958 filedata->ngnuchains = 0;
10ca4b04
L
11959 }
11960 }
11961
11962 return num_of_syms;
11963}
11964
b2d38a17
NC
11965/* Parse and display the contents of the dynamic section. */
11966
015dc7e1 11967static bool
dda8d76d 11968process_dynamic_section (Filedata * filedata)
9ea033b2 11969{
2cf0635d 11970 Elf_Internal_Dyn * entry;
9ea033b2 11971
93df3340 11972 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11973 {
11974 if (do_dynamic)
ca0e11aa
NC
11975 {
11976 if (filedata->is_separate)
11977 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11978 filedata->file_name);
11979 else
11980 printf (_("\nThere is no dynamic section in this file.\n"));
11981 }
9ea033b2 11982
015dc7e1 11983 return true;
9ea033b2
NC
11984 }
11985
4de91c10
AM
11986 if (!get_dynamic_section (filedata))
11987 return false;
9ea033b2 11988
252b5132 11989 /* Find the appropriate symbol table. */
978c4450 11990 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11991 {
26c527e6 11992 uint64_t num_of_syms;
2482f306 11993
978c4450
AM
11994 for (entry = filedata->dynamic_section;
11995 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11996 ++entry)
10ca4b04 11997 if (entry->d_tag == DT_SYMTAB)
978c4450 11998 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11999 else if (entry->d_tag == DT_SYMENT)
978c4450 12000 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 12001 else if (entry->d_tag == DT_HASH)
978c4450 12002 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 12003 else if (entry->d_tag == DT_GNU_HASH)
978c4450 12004 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
12005 else if ((filedata->file_header.e_machine == EM_MIPS
12006 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
12007 && entry->d_tag == DT_MIPS_XHASH)
12008 {
978c4450
AM
12009 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
12010 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 12011 }
252b5132 12012
2482f306
AM
12013 num_of_syms = get_num_dynamic_syms (filedata);
12014
12015 if (num_of_syms != 0
12016 && filedata->dynamic_symbols == NULL
12017 && filedata->dynamic_info[DT_SYMTAB]
978c4450 12018 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
12019 {
12020 Elf_Internal_Phdr *seg;
625d49fc 12021 uint64_t vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 12022
2482f306
AM
12023 if (! get_program_headers (filedata))
12024 {
12025 error (_("Cannot interpret virtual addresses "
12026 "without program headers.\n"));
015dc7e1 12027 return false;
2482f306 12028 }
252b5132 12029
2482f306
AM
12030 for (seg = filedata->program_headers;
12031 seg < filedata->program_headers + filedata->file_header.e_phnum;
12032 ++seg)
12033 {
12034 if (seg->p_type != PT_LOAD)
12035 continue;
252b5132 12036
2482f306
AM
12037 if (seg->p_offset + seg->p_filesz > filedata->file_size)
12038 {
12039 /* See PR 21379 for a reproducer. */
12040 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 12041 return false;
2482f306 12042 }
252b5132 12043
2482f306
AM
12044 if (vma >= (seg->p_vaddr & -seg->p_align)
12045 && vma < seg->p_vaddr + seg->p_filesz)
12046 {
12047 /* Since we do not know how big the symbol table is,
12048 we default to reading in up to the end of PT_LOAD
12049 segment and processing that. This is overkill, I
12050 know, but it should work. */
12051 Elf_Internal_Shdr section;
12052 section.sh_offset = (vma - seg->p_vaddr
12053 + seg->p_offset);
12054 section.sh_size = (num_of_syms
12055 * filedata->dynamic_info[DT_SYMENT]);
12056 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
12057
12058 if (do_checks
12059 && filedata->dynamic_symtab_section != NULL
12060 && ((filedata->dynamic_symtab_section->sh_offset
12061 != section.sh_offset)
12062 || (filedata->dynamic_symtab_section->sh_size
12063 != section.sh_size)
12064 || (filedata->dynamic_symtab_section->sh_entsize
12065 != section.sh_entsize)))
12066 warn (_("\
12067the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
12068
2482f306
AM
12069 section.sh_name = filedata->string_table_length;
12070 filedata->dynamic_symbols
4de91c10 12071 = get_elf_symbols (filedata, &section,
2482f306
AM
12072 &filedata->num_dynamic_syms);
12073 if (filedata->dynamic_symbols == NULL
12074 || filedata->num_dynamic_syms != num_of_syms)
12075 {
12076 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 12077 return false;
2482f306
AM
12078 }
12079 break;
12080 }
12081 }
12082 }
12083 }
252b5132
RH
12084
12085 /* Similarly find a string table. */
978c4450
AM
12086 if (filedata->dynamic_strings == NULL)
12087 for (entry = filedata->dynamic_section;
12088 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
12089 ++entry)
12090 {
12091 if (entry->d_tag == DT_STRTAB)
978c4450 12092 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 12093
10ca4b04 12094 if (entry->d_tag == DT_STRSZ)
978c4450 12095 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 12096
978c4450
AM
12097 if (filedata->dynamic_info[DT_STRTAB]
12098 && filedata->dynamic_info[DT_STRSZ])
10ca4b04 12099 {
26c527e6 12100 uint64_t offset;
be7d229a 12101 uint64_t str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
12102
12103 offset = offset_from_vma (filedata,
978c4450 12104 filedata->dynamic_info[DT_STRTAB],
10ca4b04 12105 str_tab_len);
8ac10c5b
L
12106 if (do_checks
12107 && filedata->dynamic_strtab_section
12108 && ((filedata->dynamic_strtab_section->sh_offset
12109 != (file_ptr) offset)
12110 || (filedata->dynamic_strtab_section->sh_size
12111 != str_tab_len)))
12112 warn (_("\
12113the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
12114
978c4450
AM
12115 filedata->dynamic_strings
12116 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
12117 _("dynamic string table"));
12118 if (filedata->dynamic_strings == NULL)
10ca4b04
L
12119 {
12120 error (_("Corrupt DT_STRTAB dynamic entry\n"));
12121 break;
12122 }
e3d39609 12123
978c4450 12124 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
12125 break;
12126 }
12127 }
252b5132
RH
12128
12129 /* And find the syminfo section if available. */
978c4450 12130 if (filedata->dynamic_syminfo == NULL)
252b5132 12131 {
26c527e6 12132 uint64_t syminsz = 0;
252b5132 12133
978c4450
AM
12134 for (entry = filedata->dynamic_section;
12135 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12136 ++entry)
252b5132
RH
12137 {
12138 if (entry->d_tag == DT_SYMINENT)
12139 {
12140 /* Note: these braces are necessary to avoid a syntax
12141 error from the SunOS4 C compiler. */
049b0c3a
NC
12142 /* PR binutils/17531: A corrupt file can trigger this test.
12143 So do not use an assert, instead generate an error message. */
12144 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 12145 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 12146 (int) entry->d_un.d_val);
252b5132
RH
12147 }
12148 else if (entry->d_tag == DT_SYMINSZ)
12149 syminsz = entry->d_un.d_val;
12150 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
12151 filedata->dynamic_syminfo_offset
12152 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
12153 }
12154
978c4450 12155 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 12156 {
2cf0635d
NC
12157 Elf_External_Syminfo * extsyminfo;
12158 Elf_External_Syminfo * extsym;
12159 Elf_Internal_Syminfo * syminfo;
252b5132
RH
12160
12161 /* There is a syminfo section. Read the data. */
3f5e193b 12162 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
12163 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
12164 1, syminsz, _("symbol information"));
a6e9f9df 12165 if (!extsyminfo)
015dc7e1 12166 return false;
252b5132 12167
978c4450 12168 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
12169 {
12170 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 12171 free (filedata->dynamic_syminfo);
e3d39609 12172 }
978c4450
AM
12173 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
12174 if (filedata->dynamic_syminfo == NULL)
252b5132 12175 {
26c527e6
AM
12176 error (_("Out of memory allocating %" PRIu64
12177 " bytes for dynamic symbol info\n"),
12178 syminsz);
015dc7e1 12179 return false;
252b5132
RH
12180 }
12181
2482f306
AM
12182 filedata->dynamic_syminfo_nent
12183 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 12184 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
12185 syminfo < (filedata->dynamic_syminfo
12186 + filedata->dynamic_syminfo_nent);
86dba8ee 12187 ++syminfo, ++extsym)
252b5132 12188 {
86dba8ee
AM
12189 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
12190 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
12191 }
12192
12193 free (extsyminfo);
12194 }
12195 }
12196
978c4450 12197 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 12198 {
f253158f 12199 if (filedata->is_separate)
26c527e6
AM
12200 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
12201 "\nIn linked file '%s' the dynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12202 filedata->dynamic_nent),
f253158f
NC
12203 filedata->file_name,
12204 filedata->dynamic_addr,
26c527e6 12205 filedata->dynamic_nent);
84a9f195 12206 else
02da71ee 12207 printf (ngettext ("\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entry:\n",
26c527e6
AM
12208 "\nDynamic section at offset %#" PRIx64 " contains %" PRIu64 " entries:\n",
12209 filedata->dynamic_nent),
84a9f195 12210 filedata->dynamic_addr,
26c527e6 12211 filedata->dynamic_nent);
ca0e11aa 12212 }
252b5132
RH
12213 if (do_dynamic)
12214 printf (_(" Tag Type Name/Value\n"));
12215
978c4450
AM
12216 for (entry = filedata->dynamic_section;
12217 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 12218 entry++)
252b5132
RH
12219 {
12220 if (do_dynamic)
f7a99963 12221 {
2cf0635d 12222 const char * dtype;
e699b9ff 12223
f7a99963
NC
12224 putchar (' ');
12225 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 12226 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 12227 printf (" (%s)%*s", dtype,
32ec8896 12228 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 12229 }
252b5132
RH
12230
12231 switch (entry->d_tag)
12232 {
d1133906
NC
12233 case DT_FLAGS:
12234 if (do_dynamic)
e9e44622 12235 print_dynamic_flags (entry->d_un.d_val);
d1133906 12236 break;
76da6bbe 12237
252b5132
RH
12238 case DT_AUXILIARY:
12239 case DT_FILTER:
019148e4
L
12240 case DT_CONFIG:
12241 case DT_DEPAUDIT:
12242 case DT_AUDIT:
252b5132
RH
12243 if (do_dynamic)
12244 {
019148e4 12245 switch (entry->d_tag)
b34976b6 12246 {
019148e4
L
12247 case DT_AUXILIARY:
12248 printf (_("Auxiliary library"));
12249 break;
12250
12251 case DT_FILTER:
12252 printf (_("Filter library"));
12253 break;
12254
b34976b6 12255 case DT_CONFIG:
019148e4
L
12256 printf (_("Configuration file"));
12257 break;
12258
12259 case DT_DEPAUDIT:
12260 printf (_("Dependency audit library"));
12261 break;
12262
12263 case DT_AUDIT:
12264 printf (_("Audit library"));
12265 break;
12266 }
252b5132 12267
84714f86 12268 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 12269 printf (": [%s]\n",
84714f86 12270 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 12271 else
f7a99963
NC
12272 {
12273 printf (": ");
12274 print_vma (entry->d_un.d_val, PREFIX_HEX);
12275 putchar ('\n');
12276 }
252b5132
RH
12277 }
12278 break;
12279
dcefbbbd 12280 case DT_FEATURE:
252b5132
RH
12281 if (do_dynamic)
12282 {
12283 printf (_("Flags:"));
86f55779 12284
252b5132
RH
12285 if (entry->d_un.d_val == 0)
12286 printf (_(" None\n"));
12287 else
12288 {
26c527e6 12289 uint64_t val = entry->d_un.d_val;
86f55779 12290
252b5132
RH
12291 if (val & DTF_1_PARINIT)
12292 {
12293 printf (" PARINIT");
12294 val ^= DTF_1_PARINIT;
12295 }
dcefbbbd
L
12296 if (val & DTF_1_CONFEXP)
12297 {
12298 printf (" CONFEXP");
12299 val ^= DTF_1_CONFEXP;
12300 }
252b5132 12301 if (val != 0)
26c527e6 12302 printf (" %" PRIx64, val);
252b5132
RH
12303 puts ("");
12304 }
12305 }
12306 break;
12307
12308 case DT_POSFLAG_1:
12309 if (do_dynamic)
12310 {
12311 printf (_("Flags:"));
86f55779 12312
252b5132
RH
12313 if (entry->d_un.d_val == 0)
12314 printf (_(" None\n"));
12315 else
12316 {
26c527e6 12317 uint64_t val = entry->d_un.d_val;
86f55779 12318
252b5132
RH
12319 if (val & DF_P1_LAZYLOAD)
12320 {
12321 printf (" LAZYLOAD");
12322 val ^= DF_P1_LAZYLOAD;
12323 }
12324 if (val & DF_P1_GROUPPERM)
12325 {
12326 printf (" GROUPPERM");
12327 val ^= DF_P1_GROUPPERM;
12328 }
12329 if (val != 0)
26c527e6 12330 printf (" %" PRIx64, val);
252b5132
RH
12331 puts ("");
12332 }
12333 }
12334 break;
12335
12336 case DT_FLAGS_1:
12337 if (do_dynamic)
12338 {
12339 printf (_("Flags:"));
12340 if (entry->d_un.d_val == 0)
12341 printf (_(" None\n"));
12342 else
12343 {
26c527e6 12344 uint64_t val = entry->d_un.d_val;
86f55779 12345
252b5132
RH
12346 if (val & DF_1_NOW)
12347 {
12348 printf (" NOW");
12349 val ^= DF_1_NOW;
12350 }
12351 if (val & DF_1_GLOBAL)
12352 {
12353 printf (" GLOBAL");
12354 val ^= DF_1_GLOBAL;
12355 }
12356 if (val & DF_1_GROUP)
12357 {
12358 printf (" GROUP");
12359 val ^= DF_1_GROUP;
12360 }
12361 if (val & DF_1_NODELETE)
12362 {
12363 printf (" NODELETE");
12364 val ^= DF_1_NODELETE;
12365 }
12366 if (val & DF_1_LOADFLTR)
12367 {
12368 printf (" LOADFLTR");
12369 val ^= DF_1_LOADFLTR;
12370 }
12371 if (val & DF_1_INITFIRST)
12372 {
12373 printf (" INITFIRST");
12374 val ^= DF_1_INITFIRST;
12375 }
12376 if (val & DF_1_NOOPEN)
12377 {
12378 printf (" NOOPEN");
12379 val ^= DF_1_NOOPEN;
12380 }
12381 if (val & DF_1_ORIGIN)
12382 {
12383 printf (" ORIGIN");
12384 val ^= DF_1_ORIGIN;
12385 }
12386 if (val & DF_1_DIRECT)
12387 {
12388 printf (" DIRECT");
12389 val ^= DF_1_DIRECT;
12390 }
12391 if (val & DF_1_TRANS)
12392 {
12393 printf (" TRANS");
12394 val ^= DF_1_TRANS;
12395 }
12396 if (val & DF_1_INTERPOSE)
12397 {
12398 printf (" INTERPOSE");
12399 val ^= DF_1_INTERPOSE;
12400 }
f7db6139 12401 if (val & DF_1_NODEFLIB)
dcefbbbd 12402 {
f7db6139
L
12403 printf (" NODEFLIB");
12404 val ^= DF_1_NODEFLIB;
dcefbbbd
L
12405 }
12406 if (val & DF_1_NODUMP)
12407 {
12408 printf (" NODUMP");
12409 val ^= DF_1_NODUMP;
12410 }
34b60028 12411 if (val & DF_1_CONFALT)
dcefbbbd 12412 {
34b60028
L
12413 printf (" CONFALT");
12414 val ^= DF_1_CONFALT;
12415 }
12416 if (val & DF_1_ENDFILTEE)
12417 {
12418 printf (" ENDFILTEE");
12419 val ^= DF_1_ENDFILTEE;
12420 }
12421 if (val & DF_1_DISPRELDNE)
12422 {
12423 printf (" DISPRELDNE");
12424 val ^= DF_1_DISPRELDNE;
12425 }
12426 if (val & DF_1_DISPRELPND)
12427 {
12428 printf (" DISPRELPND");
12429 val ^= DF_1_DISPRELPND;
12430 }
12431 if (val & DF_1_NODIRECT)
12432 {
12433 printf (" NODIRECT");
12434 val ^= DF_1_NODIRECT;
12435 }
12436 if (val & DF_1_IGNMULDEF)
12437 {
12438 printf (" IGNMULDEF");
12439 val ^= DF_1_IGNMULDEF;
12440 }
12441 if (val & DF_1_NOKSYMS)
12442 {
12443 printf (" NOKSYMS");
12444 val ^= DF_1_NOKSYMS;
12445 }
12446 if (val & DF_1_NOHDR)
12447 {
12448 printf (" NOHDR");
12449 val ^= DF_1_NOHDR;
12450 }
12451 if (val & DF_1_EDITED)
12452 {
12453 printf (" EDITED");
12454 val ^= DF_1_EDITED;
12455 }
12456 if (val & DF_1_NORELOC)
12457 {
12458 printf (" NORELOC");
12459 val ^= DF_1_NORELOC;
12460 }
12461 if (val & DF_1_SYMINTPOSE)
12462 {
12463 printf (" SYMINTPOSE");
12464 val ^= DF_1_SYMINTPOSE;
12465 }
12466 if (val & DF_1_GLOBAUDIT)
12467 {
12468 printf (" GLOBAUDIT");
12469 val ^= DF_1_GLOBAUDIT;
12470 }
12471 if (val & DF_1_SINGLETON)
12472 {
12473 printf (" SINGLETON");
12474 val ^= DF_1_SINGLETON;
dcefbbbd 12475 }
5c383f02
RO
12476 if (val & DF_1_STUB)
12477 {
12478 printf (" STUB");
12479 val ^= DF_1_STUB;
12480 }
12481 if (val & DF_1_PIE)
12482 {
12483 printf (" PIE");
12484 val ^= DF_1_PIE;
12485 }
b1202ffa
L
12486 if (val & DF_1_KMOD)
12487 {
12488 printf (" KMOD");
12489 val ^= DF_1_KMOD;
12490 }
12491 if (val & DF_1_WEAKFILTER)
12492 {
12493 printf (" WEAKFILTER");
12494 val ^= DF_1_WEAKFILTER;
12495 }
12496 if (val & DF_1_NOCOMMON)
12497 {
12498 printf (" NOCOMMON");
12499 val ^= DF_1_NOCOMMON;
12500 }
252b5132 12501 if (val != 0)
26c527e6 12502 printf (" %" PRIx64, val);
252b5132
RH
12503 puts ("");
12504 }
12505 }
12506 break;
12507
12508 case DT_PLTREL:
978c4450 12509 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 12510 if (do_dynamic)
dda8d76d 12511 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
12512 break;
12513
12514 case DT_NULL :
12515 case DT_NEEDED :
12516 case DT_PLTGOT :
12517 case DT_HASH :
12518 case DT_STRTAB :
12519 case DT_SYMTAB :
12520 case DT_RELA :
12521 case DT_INIT :
12522 case DT_FINI :
12523 case DT_SONAME :
12524 case DT_RPATH :
12525 case DT_SYMBOLIC:
12526 case DT_REL :
a7fd1186 12527 case DT_RELR :
252b5132
RH
12528 case DT_DEBUG :
12529 case DT_TEXTREL :
12530 case DT_JMPREL :
019148e4 12531 case DT_RUNPATH :
978c4450 12532 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
12533
12534 if (do_dynamic)
12535 {
84714f86 12536 const char *name;
252b5132 12537
84714f86
AM
12538 if (valid_dynamic_name (filedata, entry->d_un.d_val))
12539 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12540 else
d79b3d50 12541 name = NULL;
252b5132
RH
12542
12543 if (name)
12544 {
12545 switch (entry->d_tag)
12546 {
12547 case DT_NEEDED:
12548 printf (_("Shared library: [%s]"), name);
12549
13acb58d
AM
12550 if (filedata->program_interpreter
12551 && streq (name, filedata->program_interpreter))
f7a99963 12552 printf (_(" program interpreter"));
252b5132
RH
12553 break;
12554
12555 case DT_SONAME:
f7a99963 12556 printf (_("Library soname: [%s]"), name);
252b5132
RH
12557 break;
12558
12559 case DT_RPATH:
f7a99963 12560 printf (_("Library rpath: [%s]"), name);
252b5132
RH
12561 break;
12562
019148e4
L
12563 case DT_RUNPATH:
12564 printf (_("Library runpath: [%s]"), name);
12565 break;
12566
252b5132 12567 default:
f7a99963
NC
12568 print_vma (entry->d_un.d_val, PREFIX_HEX);
12569 break;
252b5132
RH
12570 }
12571 }
12572 else
f7a99963
NC
12573 print_vma (entry->d_un.d_val, PREFIX_HEX);
12574
12575 putchar ('\n');
252b5132
RH
12576 }
12577 break;
12578
12579 case DT_PLTRELSZ:
12580 case DT_RELASZ :
12581 case DT_STRSZ :
12582 case DT_RELSZ :
12583 case DT_RELAENT :
a7fd1186
FS
12584 case DT_RELRENT :
12585 case DT_RELRSZ :
252b5132
RH
12586 case DT_SYMENT :
12587 case DT_RELENT :
978c4450 12588 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 12589 /* Fall through. */
252b5132
RH
12590 case DT_PLTPADSZ:
12591 case DT_MOVEENT :
12592 case DT_MOVESZ :
04d8355a 12593 case DT_PREINIT_ARRAYSZ:
252b5132
RH
12594 case DT_INIT_ARRAYSZ:
12595 case DT_FINI_ARRAYSZ:
047b2264
JJ
12596 case DT_GNU_CONFLICTSZ:
12597 case DT_GNU_LIBLISTSZ:
252b5132 12598 if (do_dynamic)
f7a99963
NC
12599 {
12600 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 12601 printf (_(" (bytes)\n"));
f7a99963 12602 }
252b5132
RH
12603 break;
12604
12605 case DT_VERDEFNUM:
12606 case DT_VERNEEDNUM:
12607 case DT_RELACOUNT:
12608 case DT_RELCOUNT:
12609 if (do_dynamic)
f7a99963
NC
12610 {
12611 print_vma (entry->d_un.d_val, UNSIGNED);
12612 putchar ('\n');
12613 }
252b5132
RH
12614 break;
12615
12616 case DT_SYMINSZ:
12617 case DT_SYMINENT:
12618 case DT_SYMINFO:
12619 case DT_USED:
12620 case DT_INIT_ARRAY:
12621 case DT_FINI_ARRAY:
12622 if (do_dynamic)
12623 {
d79b3d50 12624 if (entry->d_tag == DT_USED
84714f86 12625 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 12626 {
84714f86
AM
12627 const char *name
12628 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 12629
b34976b6 12630 if (*name)
252b5132
RH
12631 {
12632 printf (_("Not needed object: [%s]\n"), name);
12633 break;
12634 }
12635 }
103f02d3 12636
f7a99963
NC
12637 print_vma (entry->d_un.d_val, PREFIX_HEX);
12638 putchar ('\n');
252b5132
RH
12639 }
12640 break;
12641
12642 case DT_BIND_NOW:
12643 /* The value of this entry is ignored. */
35b1837e
AM
12644 if (do_dynamic)
12645 putchar ('\n');
252b5132 12646 break;
103f02d3 12647
047b2264
JJ
12648 case DT_GNU_PRELINKED:
12649 if (do_dynamic)
12650 {
2cf0635d 12651 struct tm * tmp;
91d6fa6a 12652 time_t atime = entry->d_un.d_val;
047b2264 12653
91d6fa6a 12654 tmp = gmtime (&atime);
071436c6
NC
12655 /* PR 17533 file: 041-1244816-0.004. */
12656 if (tmp == NULL)
26c527e6
AM
12657 printf (_("<corrupt time val: %" PRIx64),
12658 (uint64_t) atime);
071436c6
NC
12659 else
12660 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
12661 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
12662 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
12663
12664 }
12665 break;
12666
fdc90cb4 12667 case DT_GNU_HASH:
978c4450 12668 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
12669 if (do_dynamic)
12670 {
12671 print_vma (entry->d_un.d_val, PREFIX_HEX);
12672 putchar ('\n');
12673 }
12674 break;
12675
a5da3dee
VDM
12676 case DT_GNU_FLAGS_1:
12677 if (do_dynamic)
12678 {
12679 printf (_("Flags:"));
12680 if (entry->d_un.d_val == 0)
12681 printf (_(" None\n"));
12682 else
12683 {
26c527e6 12684 uint64_t val = entry->d_un.d_val;
a5da3dee
VDM
12685
12686 if (val & DF_GNU_1_UNIQUE)
12687 {
12688 printf (" UNIQUE");
12689 val ^= DF_GNU_1_UNIQUE;
12690 }
12691 if (val != 0)
26c527e6 12692 printf (" %" PRIx64, val);
a5da3dee
VDM
12693 puts ("");
12694 }
12695 }
12696 break;
12697
252b5132
RH
12698 default:
12699 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
12700 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
12701 = entry->d_un.d_val;
252b5132
RH
12702
12703 if (do_dynamic)
12704 {
dda8d76d 12705 switch (filedata->file_header.e_machine)
252b5132 12706 {
37c18eed
SD
12707 case EM_AARCH64:
12708 dynamic_section_aarch64_val (entry);
12709 break;
252b5132 12710 case EM_MIPS:
4fe85591 12711 case EM_MIPS_RS3_LE:
978c4450 12712 dynamic_section_mips_val (filedata, entry);
252b5132 12713 break;
103f02d3 12714 case EM_PARISC:
b2d38a17 12715 dynamic_section_parisc_val (entry);
103f02d3 12716 break;
ecc51f48 12717 case EM_IA_64:
b2d38a17 12718 dynamic_section_ia64_val (entry);
ecc51f48 12719 break;
252b5132 12720 default:
f7a99963
NC
12721 print_vma (entry->d_un.d_val, PREFIX_HEX);
12722 putchar ('\n');
252b5132
RH
12723 }
12724 }
12725 break;
12726 }
12727 }
12728
015dc7e1 12729 return true;
252b5132
RH
12730}
12731
12732static char *
d3ba0551 12733get_ver_flags (unsigned int flags)
252b5132 12734{
6d4f21f6 12735 static char buff[128];
252b5132
RH
12736
12737 buff[0] = 0;
12738
12739 if (flags == 0)
12740 return _("none");
12741
12742 if (flags & VER_FLG_BASE)
7bb1ad17 12743 strcat (buff, "BASE");
252b5132
RH
12744
12745 if (flags & VER_FLG_WEAK)
12746 {
12747 if (flags & VER_FLG_BASE)
7bb1ad17 12748 strcat (buff, " | ");
252b5132 12749
7bb1ad17 12750 strcat (buff, "WEAK");
252b5132
RH
12751 }
12752
44ec90b9
RO
12753 if (flags & VER_FLG_INFO)
12754 {
12755 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 12756 strcat (buff, " | ");
44ec90b9 12757
7bb1ad17 12758 strcat (buff, "INFO");
44ec90b9
RO
12759 }
12760
12761 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
12762 {
12763 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
12764 strcat (buff, " | ");
12765
12766 strcat (buff, _("<unknown>"));
12767 }
252b5132
RH
12768
12769 return buff;
12770}
12771
12772/* Display the contents of the version sections. */
98fb390a 12773
015dc7e1 12774static bool
dda8d76d 12775process_version_sections (Filedata * filedata)
252b5132 12776{
2cf0635d 12777 Elf_Internal_Shdr * section;
b34976b6 12778 unsigned i;
015dc7e1 12779 bool found = false;
252b5132
RH
12780
12781 if (! do_version)
015dc7e1 12782 return true;
252b5132 12783
dda8d76d
NC
12784 for (i = 0, section = filedata->section_headers;
12785 i < filedata->file_header.e_shnum;
b34976b6 12786 i++, section++)
252b5132
RH
12787 {
12788 switch (section->sh_type)
12789 {
12790 case SHT_GNU_verdef:
12791 {
2cf0635d 12792 Elf_External_Verdef * edefs;
26c527e6
AM
12793 size_t idx;
12794 size_t cnt;
2cf0635d 12795 char * endbuf;
252b5132 12796
015dc7e1 12797 found = true;
252b5132 12798
ca0e11aa
NC
12799 if (filedata->is_separate)
12800 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
12801 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
12802 section->sh_info),
12803 filedata->file_name,
12804 printable_section_name (filedata, section),
12805 section->sh_info);
12806 else
12807 printf (ngettext ("\nVersion definition section '%s' "
12808 "contains %u entry:\n",
12809 "\nVersion definition section '%s' "
12810 "contains %u entries:\n",
12811 section->sh_info),
12812 printable_section_name (filedata, section),
12813 section->sh_info);
047c3dbf 12814
625d49fc 12815 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12816 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12817 section->sh_offset, section->sh_link,
b6ac461a 12818 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12819
3f5e193b 12820 edefs = (Elf_External_Verdef *)
dda8d76d 12821 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 12822 _("version definition section"));
a6e9f9df
AM
12823 if (!edefs)
12824 break;
59245841 12825 endbuf = (char *) edefs + section->sh_size;
252b5132 12826
1445030f 12827 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 12828 {
2cf0635d
NC
12829 char * vstart;
12830 Elf_External_Verdef * edef;
b34976b6 12831 Elf_Internal_Verdef ent;
2cf0635d 12832 Elf_External_Verdaux * eaux;
b34976b6 12833 Elf_Internal_Verdaux aux;
26c527e6 12834 size_t isum;
b34976b6 12835 int j;
103f02d3 12836
252b5132 12837 vstart = ((char *) edefs) + idx;
54806181
AM
12838 if (vstart + sizeof (*edef) > endbuf)
12839 break;
252b5132
RH
12840
12841 edef = (Elf_External_Verdef *) vstart;
12842
12843 ent.vd_version = BYTE_GET (edef->vd_version);
12844 ent.vd_flags = BYTE_GET (edef->vd_flags);
12845 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
12846 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
12847 ent.vd_hash = BYTE_GET (edef->vd_hash);
12848 ent.vd_aux = BYTE_GET (edef->vd_aux);
12849 ent.vd_next = BYTE_GET (edef->vd_next);
12850
26c527e6 12851 printf (_(" %#06zx: Rev: %d Flags: %s"),
252b5132
RH
12852 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
12853
12854 printf (_(" Index: %d Cnt: %d "),
12855 ent.vd_ndx, ent.vd_cnt);
12856
452bf675 12857 /* Check for overflow. */
1445030f 12858 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
12859 break;
12860
252b5132
RH
12861 vstart += ent.vd_aux;
12862
1445030f
AM
12863 if (vstart + sizeof (*eaux) > endbuf)
12864 break;
252b5132
RH
12865 eaux = (Elf_External_Verdaux *) vstart;
12866
12867 aux.vda_name = BYTE_GET (eaux->vda_name);
12868 aux.vda_next = BYTE_GET (eaux->vda_next);
12869
84714f86 12870 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 12871 printf (_("Name: %s\n"),
84714f86 12872 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
12873 else
12874 printf (_("Name index: %ld\n"), aux.vda_name);
12875
12876 isum = idx + ent.vd_aux;
12877
b34976b6 12878 for (j = 1; j < ent.vd_cnt; j++)
252b5132 12879 {
1445030f
AM
12880 if (aux.vda_next < sizeof (*eaux)
12881 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
12882 {
12883 warn (_("Invalid vda_next field of %lx\n"),
12884 aux.vda_next);
12885 j = ent.vd_cnt;
12886 break;
12887 }
dd24e3da 12888 /* Check for overflow. */
7e26601c 12889 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12890 break;
12891
252b5132
RH
12892 isum += aux.vda_next;
12893 vstart += aux.vda_next;
12894
54806181
AM
12895 if (vstart + sizeof (*eaux) > endbuf)
12896 break;
1445030f 12897 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12898
12899 aux.vda_name = BYTE_GET (eaux->vda_name);
12900 aux.vda_next = BYTE_GET (eaux->vda_next);
12901
84714f86 12902 if (valid_dynamic_name (filedata, aux.vda_name))
26c527e6 12903 printf (_(" %#06zx: Parent %d: %s\n"),
978c4450 12904 isum, j,
84714f86 12905 get_dynamic_name (filedata, aux.vda_name));
252b5132 12906 else
26c527e6 12907 printf (_(" %#06zx: Parent %d, name index: %ld\n"),
252b5132
RH
12908 isum, j, aux.vda_name);
12909 }
dd24e3da 12910
54806181
AM
12911 if (j < ent.vd_cnt)
12912 printf (_(" Version def aux past end of section\n"));
252b5132 12913
c9f02c3e
MR
12914 /* PR 17531:
12915 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12916 if (ent.vd_next < sizeof (*edef)
12917 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12918 {
12919 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12920 cnt = section->sh_info;
12921 break;
12922 }
452bf675 12923 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12924 break;
12925
252b5132
RH
12926 idx += ent.vd_next;
12927 }
dd24e3da 12928
54806181
AM
12929 if (cnt < section->sh_info)
12930 printf (_(" Version definition past end of section\n"));
252b5132
RH
12931
12932 free (edefs);
12933 }
12934 break;
103f02d3 12935
252b5132
RH
12936 case SHT_GNU_verneed:
12937 {
2cf0635d 12938 Elf_External_Verneed * eneed;
26c527e6
AM
12939 size_t idx;
12940 size_t cnt;
2cf0635d 12941 char * endbuf;
252b5132 12942
015dc7e1 12943 found = true;
252b5132 12944
ca0e11aa
NC
12945 if (filedata->is_separate)
12946 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12947 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12948 section->sh_info),
12949 filedata->file_name,
12950 printable_section_name (filedata, section),
12951 section->sh_info);
12952 else
12953 printf (ngettext ("\nVersion needs section '%s' "
12954 "contains %u entry:\n",
12955 "\nVersion needs section '%s' "
12956 "contains %u entries:\n",
12957 section->sh_info),
12958 printable_section_name (filedata, section),
12959 section->sh_info);
047c3dbf 12960
625d49fc 12961 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
12962 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
12963 section->sh_offset, section->sh_link,
b6ac461a 12964 printable_section_name_from_index (filedata, section->sh_link, NULL));
252b5132 12965
dda8d76d 12966 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12967 section->sh_offset, 1,
12968 section->sh_size,
9cf03b7e 12969 _("Version Needs section"));
a6e9f9df
AM
12970 if (!eneed)
12971 break;
59245841 12972 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12973
12974 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12975 {
2cf0635d 12976 Elf_External_Verneed * entry;
b34976b6 12977 Elf_Internal_Verneed ent;
26c527e6 12978 size_t isum;
b34976b6 12979 int j;
2cf0635d 12980 char * vstart;
252b5132
RH
12981
12982 vstart = ((char *) eneed) + idx;
54806181
AM
12983 if (vstart + sizeof (*entry) > endbuf)
12984 break;
252b5132
RH
12985
12986 entry = (Elf_External_Verneed *) vstart;
12987
12988 ent.vn_version = BYTE_GET (entry->vn_version);
12989 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12990 ent.vn_file = BYTE_GET (entry->vn_file);
12991 ent.vn_aux = BYTE_GET (entry->vn_aux);
12992 ent.vn_next = BYTE_GET (entry->vn_next);
12993
26c527e6 12994 printf (_(" %#06zx: Version: %d"), idx, ent.vn_version);
252b5132 12995
84714f86 12996 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12997 printf (_(" File: %s"),
84714f86 12998 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12999 else
13000 printf (_(" File: %lx"), ent.vn_file);
13001
13002 printf (_(" Cnt: %d\n"), ent.vn_cnt);
13003
dd24e3da 13004 /* Check for overflow. */
7e26601c 13005 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 13006 break;
252b5132
RH
13007 vstart += ent.vn_aux;
13008
13009 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
13010 {
2cf0635d 13011 Elf_External_Vernaux * eaux;
b34976b6 13012 Elf_Internal_Vernaux aux;
252b5132 13013
54806181
AM
13014 if (vstart + sizeof (*eaux) > endbuf)
13015 break;
252b5132
RH
13016 eaux = (Elf_External_Vernaux *) vstart;
13017
13018 aux.vna_hash = BYTE_GET (eaux->vna_hash);
13019 aux.vna_flags = BYTE_GET (eaux->vna_flags);
13020 aux.vna_other = BYTE_GET (eaux->vna_other);
13021 aux.vna_name = BYTE_GET (eaux->vna_name);
13022 aux.vna_next = BYTE_GET (eaux->vna_next);
13023
84714f86 13024 if (valid_dynamic_name (filedata, aux.vna_name))
26c527e6 13025 printf (_(" %#06zx: Name: %s"),
84714f86 13026 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 13027 else
26c527e6 13028 printf (_(" %#06zx: Name index: %lx"),
252b5132
RH
13029 isum, aux.vna_name);
13030
13031 printf (_(" Flags: %s Version: %d\n"),
13032 get_ver_flags (aux.vna_flags), aux.vna_other);
13033
1445030f
AM
13034 if (aux.vna_next < sizeof (*eaux)
13035 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
13036 {
13037 warn (_("Invalid vna_next field of %lx\n"),
13038 aux.vna_next);
13039 j = ent.vn_cnt;
13040 break;
13041 }
1445030f
AM
13042 /* Check for overflow. */
13043 if (aux.vna_next > (size_t) (endbuf - vstart))
13044 break;
252b5132
RH
13045 isum += aux.vna_next;
13046 vstart += aux.vna_next;
13047 }
9cf03b7e 13048
54806181 13049 if (j < ent.vn_cnt)
f9a6a8f0 13050 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 13051
1445030f
AM
13052 if (ent.vn_next < sizeof (*entry)
13053 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 13054 {
452bf675 13055 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
13056 cnt = section->sh_info;
13057 break;
13058 }
1445030f
AM
13059 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
13060 break;
252b5132
RH
13061 idx += ent.vn_next;
13062 }
9cf03b7e 13063
54806181 13064 if (cnt < section->sh_info)
9cf03b7e 13065 warn (_("Missing Version Needs information\n"));
103f02d3 13066
252b5132
RH
13067 free (eneed);
13068 }
13069 break;
13070
13071 case SHT_GNU_versym:
13072 {
2cf0635d 13073 Elf_Internal_Shdr * link_section;
26c527e6 13074 uint64_t total;
8b73c356 13075 unsigned int cnt;
2cf0635d
NC
13076 unsigned char * edata;
13077 unsigned short * data;
13078 char * strtab;
13079 Elf_Internal_Sym * symbols;
13080 Elf_Internal_Shdr * string_sec;
26c527e6
AM
13081 uint64_t num_syms;
13082 uint64_t off;
252b5132 13083
dda8d76d 13084 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13085 break;
13086
dda8d76d 13087 link_section = filedata->section_headers + section->sh_link;
08d8fa11 13088 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 13089
dda8d76d 13090 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
13091 break;
13092
015dc7e1 13093 found = true;
252b5132 13094
4de91c10 13095 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
13096 if (symbols == NULL)
13097 break;
252b5132 13098
dda8d76d 13099 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 13100
dda8d76d 13101 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
13102 string_sec->sh_size,
13103 _("version string table"));
a6e9f9df 13104 if (!strtab)
0429c154
MS
13105 {
13106 free (symbols);
13107 break;
13108 }
252b5132 13109
ca0e11aa 13110 if (filedata->is_separate)
26c527e6
AM
13111 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entry:\n",
13112 "\nIn linked file '%s' the version symbols section '%s' contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13113 total),
13114 filedata->file_name,
13115 printable_section_name (filedata, section),
26c527e6 13116 total);
ca0e11aa
NC
13117 else
13118 printf (ngettext ("\nVersion symbols section '%s' "
26c527e6 13119 "contains %" PRIu64 " entry:\n",
ca0e11aa 13120 "\nVersion symbols section '%s' "
26c527e6 13121 "contains %" PRIu64 " entries:\n",
ca0e11aa
NC
13122 total),
13123 printable_section_name (filedata, section),
26c527e6 13124 total);
252b5132 13125
625d49fc 13126 printf (_(" Addr: 0x%016" PRIx64), section->sh_addr);
26c527e6
AM
13127 printf (_(" Offset: 0x%08" PRIx64 " Link: %u (%s)\n"),
13128 section->sh_offset, section->sh_link,
dda8d76d 13129 printable_section_name (filedata, link_section));
252b5132 13130
dda8d76d 13131 off = offset_from_vma (filedata,
978c4450 13132 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 13133 total * sizeof (short));
95099889
AM
13134 edata = (unsigned char *) get_data (NULL, filedata, off,
13135 sizeof (short), total,
13136 _("version symbol data"));
a6e9f9df
AM
13137 if (!edata)
13138 {
13139 free (strtab);
0429c154 13140 free (symbols);
a6e9f9df
AM
13141 break;
13142 }
252b5132 13143
3f5e193b 13144 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
13145
13146 for (cnt = total; cnt --;)
b34976b6
AM
13147 data[cnt] = byte_get (edata + cnt * sizeof (short),
13148 sizeof (short));
252b5132
RH
13149
13150 free (edata);
13151
13152 for (cnt = 0; cnt < total; cnt += 4)
13153 {
13154 int j, nn;
ab273396
AM
13155 char *name;
13156 char *invalid = _("*invalid*");
252b5132
RH
13157
13158 printf (" %03x:", cnt);
13159
13160 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 13161 switch (data[cnt + j])
252b5132
RH
13162 {
13163 case 0:
13164 fputs (_(" 0 (*local*) "), stdout);
13165 break;
13166
13167 case 1:
13168 fputs (_(" 1 (*global*) "), stdout);
13169 break;
13170
13171 default:
c244d050
NC
13172 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
13173 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 13174
dd24e3da 13175 /* If this index value is greater than the size of the symbols
ba5cdace 13176 array, break to avoid an out-of-bounds read. */
26c527e6 13177 if (cnt + j >= num_syms)
dd24e3da
NC
13178 {
13179 warn (_("invalid index into symbol array\n"));
13180 break;
13181 }
13182
ab273396 13183 name = NULL;
978c4450 13184 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 13185 {
b34976b6 13186 Elf_Internal_Verneed ivn;
26c527e6 13187 uint64_t offset;
252b5132 13188
d93f0186 13189 offset = offset_from_vma
978c4450
AM
13190 (filedata,
13191 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 13192 sizeof (Elf_External_Verneed));
252b5132 13193
b34976b6 13194 do
252b5132 13195 {
b34976b6
AM
13196 Elf_Internal_Vernaux ivna;
13197 Elf_External_Verneed evn;
13198 Elf_External_Vernaux evna;
26c527e6 13199 uint64_t a_off;
252b5132 13200
dda8d76d 13201 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
13202 _("version need")) == NULL)
13203 break;
0b4362b0 13204
252b5132
RH
13205 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13206 ivn.vn_next = BYTE_GET (evn.vn_next);
13207
13208 a_off = offset + ivn.vn_aux;
13209
13210 do
13211 {
dda8d76d 13212 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
13213 1, _("version need aux (2)")) == NULL)
13214 {
13215 ivna.vna_next = 0;
13216 ivna.vna_other = 0;
13217 }
13218 else
13219 {
13220 ivna.vna_next = BYTE_GET (evna.vna_next);
13221 ivna.vna_other = BYTE_GET (evna.vna_other);
13222 }
252b5132
RH
13223
13224 a_off += ivna.vna_next;
13225 }
b34976b6 13226 while (ivna.vna_other != data[cnt + j]
252b5132
RH
13227 && ivna.vna_next != 0);
13228
b34976b6 13229 if (ivna.vna_other == data[cnt + j])
252b5132
RH
13230 {
13231 ivna.vna_name = BYTE_GET (evna.vna_name);
13232
54806181 13233 if (ivna.vna_name >= string_sec->sh_size)
ab273396 13234 name = invalid;
54806181
AM
13235 else
13236 name = strtab + ivna.vna_name;
252b5132
RH
13237 break;
13238 }
13239
13240 offset += ivn.vn_next;
13241 }
13242 while (ivn.vn_next);
13243 }
00d93f34 13244
ab273396 13245 if (data[cnt + j] != 0x8001
978c4450 13246 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 13247 {
b34976b6
AM
13248 Elf_Internal_Verdef ivd;
13249 Elf_External_Verdef evd;
26c527e6 13250 uint64_t offset;
252b5132 13251
d93f0186 13252 offset = offset_from_vma
978c4450
AM
13253 (filedata,
13254 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 13255 sizeof evd);
252b5132
RH
13256
13257 do
13258 {
dda8d76d 13259 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
13260 _("version def")) == NULL)
13261 {
13262 ivd.vd_next = 0;
948f632f 13263 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
13264 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
13265 break;
59245841
NC
13266 }
13267 else
13268 {
13269 ivd.vd_next = BYTE_GET (evd.vd_next);
13270 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13271 }
252b5132
RH
13272
13273 offset += ivd.vd_next;
13274 }
c244d050 13275 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
13276 && ivd.vd_next != 0);
13277
c244d050 13278 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 13279 {
b34976b6
AM
13280 Elf_External_Verdaux evda;
13281 Elf_Internal_Verdaux ivda;
252b5132
RH
13282
13283 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13284
dda8d76d 13285 if (get_data (&evda, filedata,
59245841
NC
13286 offset - ivd.vd_next + ivd.vd_aux,
13287 sizeof (evda), 1,
13288 _("version def aux")) == NULL)
13289 break;
252b5132
RH
13290
13291 ivda.vda_name = BYTE_GET (evda.vda_name);
13292
54806181 13293 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
13294 name = invalid;
13295 else if (name != NULL && name != invalid)
13296 name = _("*both*");
54806181
AM
13297 else
13298 name = strtab + ivda.vda_name;
252b5132
RH
13299 }
13300 }
ab273396
AM
13301 if (name != NULL)
13302 nn += printf ("(%s%-*s",
13303 name,
13304 12 - (int) strlen (name),
13305 ")");
252b5132
RH
13306
13307 if (nn < 18)
13308 printf ("%*c", 18 - nn, ' ');
13309 }
13310
13311 putchar ('\n');
13312 }
13313
13314 free (data);
13315 free (strtab);
13316 free (symbols);
13317 }
13318 break;
103f02d3 13319
252b5132
RH
13320 default:
13321 break;
13322 }
13323 }
13324
13325 if (! found)
ca0e11aa
NC
13326 {
13327 if (filedata->is_separate)
13328 printf (_("\nNo version information found in linked file '%s'.\n"),
13329 filedata->file_name);
13330 else
13331 printf (_("\nNo version information found in this file.\n"));
13332 }
252b5132 13333
015dc7e1 13334 return true;
252b5132
RH
13335}
13336
d1133906 13337static const char *
dda8d76d 13338get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 13339{
89246a0e 13340 static char buff[64];
252b5132
RH
13341
13342 switch (binding)
13343 {
b34976b6
AM
13344 case STB_LOCAL: return "LOCAL";
13345 case STB_GLOBAL: return "GLOBAL";
13346 case STB_WEAK: return "WEAK";
252b5132
RH
13347 default:
13348 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
13349 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
13350 binding);
252b5132 13351 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
13352 {
13353 if (binding == STB_GNU_UNIQUE
df3a023b 13354 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
13355 return "UNIQUE";
13356 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
13357 }
252b5132 13358 else
e9e44622 13359 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
13360 return buff;
13361 }
13362}
13363
d1133906 13364static const char *
dda8d76d 13365get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 13366{
89246a0e 13367 static char buff[64];
252b5132
RH
13368
13369 switch (type)
13370 {
b34976b6
AM
13371 case STT_NOTYPE: return "NOTYPE";
13372 case STT_OBJECT: return "OBJECT";
13373 case STT_FUNC: return "FUNC";
13374 case STT_SECTION: return "SECTION";
13375 case STT_FILE: return "FILE";
13376 case STT_COMMON: return "COMMON";
13377 case STT_TLS: return "TLS";
15ab5209
DB
13378 case STT_RELC: return "RELC";
13379 case STT_SRELC: return "SRELC";
252b5132
RH
13380 default:
13381 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 13382 {
dda8d76d 13383 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 13384 return "THUMB_FUNC";
103f02d3 13385
dda8d76d 13386 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
13387 return "REGISTER";
13388
dda8d76d 13389 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
13390 return "PARISC_MILLI";
13391
e9e44622 13392 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 13393 }
252b5132 13394 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 13395 {
dda8d76d 13396 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
13397 {
13398 if (type == STT_HP_OPAQUE)
13399 return "HP_OPAQUE";
13400 if (type == STT_HP_STUB)
13401 return "HP_STUB";
13402 }
13403
8654c01f
ML
13404 if (type == STT_GNU_IFUNC
13405 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
13406 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
13407 return "IFUNC";
13408
e9e44622 13409 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 13410 }
252b5132 13411 else
e9e44622 13412 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
13413 return buff;
13414 }
13415}
13416
d1133906 13417static const char *
d3ba0551 13418get_symbol_visibility (unsigned int visibility)
d1133906
NC
13419{
13420 switch (visibility)
13421 {
b34976b6
AM
13422 case STV_DEFAULT: return "DEFAULT";
13423 case STV_INTERNAL: return "INTERNAL";
13424 case STV_HIDDEN: return "HIDDEN";
d1133906 13425 case STV_PROTECTED: return "PROTECTED";
bee0ee85 13426 default:
27a45f42 13427 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 13428 return _("<unknown>");
d1133906
NC
13429 }
13430}
13431
2057d69d
CZ
13432static const char *
13433get_alpha_symbol_other (unsigned int other)
9abca702 13434{
2057d69d
CZ
13435 switch (other)
13436 {
13437 case STO_ALPHA_NOPV: return "NOPV";
13438 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
13439 default:
27a45f42 13440 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 13441 return _("<unknown>");
9abca702 13442 }
2057d69d
CZ
13443}
13444
fd85a6a1
NC
13445static const char *
13446get_solaris_symbol_visibility (unsigned int visibility)
13447{
13448 switch (visibility)
13449 {
13450 case 4: return "EXPORTED";
13451 case 5: return "SINGLETON";
13452 case 6: return "ELIMINATE";
13453 default: return get_symbol_visibility (visibility);
13454 }
13455}
13456
2301ed1c
SN
13457static const char *
13458get_aarch64_symbol_other (unsigned int other)
13459{
13460 static char buf[32];
13461
13462 if (other & STO_AARCH64_VARIANT_PCS)
13463 {
13464 other &= ~STO_AARCH64_VARIANT_PCS;
13465 if (other == 0)
13466 return "VARIANT_PCS";
13467 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
13468 return buf;
13469 }
13470 return NULL;
13471}
13472
5e2b0d47
NC
13473static const char *
13474get_mips_symbol_other (unsigned int other)
13475{
13476 switch (other)
13477 {
32ec8896
NC
13478 case STO_OPTIONAL: return "OPTIONAL";
13479 case STO_MIPS_PLT: return "MIPS PLT";
13480 case STO_MIPS_PIC: return "MIPS PIC";
13481 case STO_MICROMIPS: return "MICROMIPS";
13482 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
13483 case STO_MIPS16: return "MIPS16";
13484 default: return NULL;
5e2b0d47
NC
13485 }
13486}
13487
28f997cf 13488static const char *
dda8d76d 13489get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 13490{
dda8d76d 13491 if (is_ia64_vms (filedata))
28f997cf
TG
13492 {
13493 static char res[32];
13494
13495 res[0] = 0;
13496
13497 /* Function types is for images and .STB files only. */
dda8d76d 13498 switch (filedata->file_header.e_type)
28f997cf
TG
13499 {
13500 case ET_DYN:
13501 case ET_EXEC:
13502 switch (VMS_ST_FUNC_TYPE (other))
13503 {
13504 case VMS_SFT_CODE_ADDR:
13505 strcat (res, " CA");
13506 break;
13507 case VMS_SFT_SYMV_IDX:
13508 strcat (res, " VEC");
13509 break;
13510 case VMS_SFT_FD:
13511 strcat (res, " FD");
13512 break;
13513 case VMS_SFT_RESERVE:
13514 strcat (res, " RSV");
13515 break;
13516 default:
bee0ee85
NC
13517 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
13518 VMS_ST_FUNC_TYPE (other));
13519 strcat (res, " <unknown>");
13520 break;
28f997cf
TG
13521 }
13522 break;
13523 default:
13524 break;
13525 }
13526 switch (VMS_ST_LINKAGE (other))
13527 {
13528 case VMS_STL_IGNORE:
13529 strcat (res, " IGN");
13530 break;
13531 case VMS_STL_RESERVE:
13532 strcat (res, " RSV");
13533 break;
13534 case VMS_STL_STD:
13535 strcat (res, " STD");
13536 break;
13537 case VMS_STL_LNK:
13538 strcat (res, " LNK");
13539 break;
13540 default:
bee0ee85
NC
13541 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
13542 VMS_ST_LINKAGE (other));
13543 strcat (res, " <unknown>");
13544 break;
28f997cf
TG
13545 }
13546
13547 if (res[0] != 0)
13548 return res + 1;
13549 else
13550 return res;
13551 }
13552 return NULL;
13553}
13554
6911b7dc
AM
13555static const char *
13556get_ppc64_symbol_other (unsigned int other)
13557{
14732552
AM
13558 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
13559 return NULL;
13560
13561 other >>= STO_PPC64_LOCAL_BIT;
13562 if (other <= 6)
6911b7dc 13563 {
89246a0e 13564 static char buf[64];
14732552
AM
13565 if (other >= 2)
13566 other = ppc64_decode_local_entry (other);
13567 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
13568 return buf;
13569 }
13570 return NULL;
13571}
13572
8155b853
NC
13573static const char *
13574get_riscv_symbol_other (unsigned int other)
13575{
13576 static char buf[32];
13577 buf[0] = 0;
13578
13579 if (other & STO_RISCV_VARIANT_CC)
13580 {
13581 strcat (buf, _(" VARIANT_CC"));
13582 other &= ~STO_RISCV_VARIANT_CC;
13583 }
13584
13585 if (other != 0)
13586 snprintf (buf, sizeof buf, " %x", other);
13587
13588
13589 if (buf[0] != 0)
13590 return buf + 1;
13591 else
13592 return buf;
13593}
13594
5e2b0d47 13595static const char *
dda8d76d 13596get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
13597{
13598 const char * result = NULL;
89246a0e 13599 static char buff [64];
5e2b0d47
NC
13600
13601 if (other == 0)
13602 return "";
13603
dda8d76d 13604 switch (filedata->file_header.e_machine)
5e2b0d47 13605 {
2057d69d
CZ
13606 case EM_ALPHA:
13607 result = get_alpha_symbol_other (other);
13608 break;
2301ed1c
SN
13609 case EM_AARCH64:
13610 result = get_aarch64_symbol_other (other);
13611 break;
5e2b0d47
NC
13612 case EM_MIPS:
13613 result = get_mips_symbol_other (other);
28f997cf
TG
13614 break;
13615 case EM_IA_64:
dda8d76d 13616 result = get_ia64_symbol_other (filedata, other);
28f997cf 13617 break;
6911b7dc
AM
13618 case EM_PPC64:
13619 result = get_ppc64_symbol_other (other);
13620 break;
8155b853
NC
13621 case EM_RISCV:
13622 result = get_riscv_symbol_other (other);
13623 break;
5e2b0d47 13624 default:
fd85a6a1 13625 result = NULL;
5e2b0d47
NC
13626 break;
13627 }
13628
13629 if (result)
13630 return result;
13631
13632 snprintf (buff, sizeof buff, _("<other>: %x"), other);
13633 return buff;
13634}
13635
bb4d2ac2 13636static const char *
26c527e6
AM
13637get_symbol_version_string (Filedata *filedata,
13638 bool is_dynsym,
13639 const char *strtab,
13640 size_t strtab_size,
13641 unsigned int si,
13642 Elf_Internal_Sym *psym,
13643 enum versioned_symbol_info *sym_info,
13644 unsigned short *vna_other)
bb4d2ac2 13645{
ab273396
AM
13646 unsigned char data[2];
13647 unsigned short vers_data;
26c527e6 13648 uint64_t offset;
7a815dd5 13649 unsigned short max_vd_ndx;
bb4d2ac2 13650
ab273396 13651 if (!is_dynsym
978c4450 13652 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 13653 return NULL;
bb4d2ac2 13654
978c4450
AM
13655 offset = offset_from_vma (filedata,
13656 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 13657 sizeof data + si * sizeof (vers_data));
bb4d2ac2 13658
dda8d76d 13659 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
13660 sizeof (data), 1, _("version data")) == NULL)
13661 return NULL;
13662
13663 vers_data = byte_get (data, 2);
bb4d2ac2 13664
1f6f5dba 13665 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 13666 return NULL;
bb4d2ac2 13667
0b8b7609 13668 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
13669 max_vd_ndx = 0;
13670
ab273396
AM
13671 /* Usually we'd only see verdef for defined symbols, and verneed for
13672 undefined symbols. However, symbols defined by the linker in
13673 .dynbss for variables copied from a shared library in order to
13674 avoid text relocations are defined yet have verneed. We could
13675 use a heuristic to detect the special case, for example, check
13676 for verneed first on symbols defined in SHT_NOBITS sections, but
13677 it is simpler and more reliable to just look for both verdef and
13678 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 13679
ab273396
AM
13680 if (psym->st_shndx != SHN_UNDEF
13681 && vers_data != 0x8001
978c4450 13682 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
13683 {
13684 Elf_Internal_Verdef ivd;
13685 Elf_Internal_Verdaux ivda;
13686 Elf_External_Verdaux evda;
26c527e6 13687 uint64_t off;
bb4d2ac2 13688
dda8d76d 13689 off = offset_from_vma (filedata,
978c4450 13690 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
13691 sizeof (Elf_External_Verdef));
13692
13693 do
bb4d2ac2 13694 {
ab273396
AM
13695 Elf_External_Verdef evd;
13696
dda8d76d 13697 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
13698 _("version def")) == NULL)
13699 {
13700 ivd.vd_ndx = 0;
13701 ivd.vd_aux = 0;
13702 ivd.vd_next = 0;
1f6f5dba 13703 ivd.vd_flags = 0;
ab273396
AM
13704 }
13705 else
bb4d2ac2 13706 {
ab273396
AM
13707 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
13708 ivd.vd_aux = BYTE_GET (evd.vd_aux);
13709 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 13710 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 13711 }
bb4d2ac2 13712
7a815dd5
L
13713 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
13714 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
13715
ab273396
AM
13716 off += ivd.vd_next;
13717 }
13718 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 13719
ab273396
AM
13720 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
13721 {
9abca702 13722 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
13723 return NULL;
13724
ab273396
AM
13725 off -= ivd.vd_next;
13726 off += ivd.vd_aux;
bb4d2ac2 13727
dda8d76d 13728 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
13729 _("version def aux")) != NULL)
13730 {
13731 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 13732
ab273396 13733 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
13734 return (ivda.vda_name < strtab_size
13735 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
13736 }
13737 }
13738 }
bb4d2ac2 13739
978c4450 13740 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
13741 {
13742 Elf_External_Verneed evn;
13743 Elf_Internal_Verneed ivn;
13744 Elf_Internal_Vernaux ivna;
bb4d2ac2 13745
dda8d76d 13746 offset = offset_from_vma (filedata,
978c4450 13747 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
13748 sizeof evn);
13749 do
13750 {
26c527e6 13751 uint64_t vna_off;
bb4d2ac2 13752
dda8d76d 13753 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
13754 _("version need")) == NULL)
13755 {
13756 ivna.vna_next = 0;
13757 ivna.vna_other = 0;
13758 ivna.vna_name = 0;
13759 break;
13760 }
bb4d2ac2 13761
ab273396
AM
13762 ivn.vn_aux = BYTE_GET (evn.vn_aux);
13763 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 13764
ab273396 13765 vna_off = offset + ivn.vn_aux;
bb4d2ac2 13766
ab273396
AM
13767 do
13768 {
13769 Elf_External_Vernaux evna;
bb4d2ac2 13770
dda8d76d 13771 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 13772 _("version need aux (3)")) == NULL)
bb4d2ac2 13773 {
ab273396
AM
13774 ivna.vna_next = 0;
13775 ivna.vna_other = 0;
13776 ivna.vna_name = 0;
bb4d2ac2 13777 }
bb4d2ac2 13778 else
bb4d2ac2 13779 {
ab273396
AM
13780 ivna.vna_other = BYTE_GET (evna.vna_other);
13781 ivna.vna_next = BYTE_GET (evna.vna_next);
13782 ivna.vna_name = BYTE_GET (evna.vna_name);
13783 }
bb4d2ac2 13784
ab273396
AM
13785 vna_off += ivna.vna_next;
13786 }
13787 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 13788
ab273396
AM
13789 if (ivna.vna_other == vers_data)
13790 break;
bb4d2ac2 13791
ab273396
AM
13792 offset += ivn.vn_next;
13793 }
13794 while (ivn.vn_next != 0);
bb4d2ac2 13795
ab273396
AM
13796 if (ivna.vna_other == vers_data)
13797 {
13798 *sym_info = symbol_undefined;
13799 *vna_other = ivna.vna_other;
13800 return (ivna.vna_name < strtab_size
13801 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 13802 }
7a815dd5
L
13803 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
13804 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
13805 return _("<corrupt>");
bb4d2ac2 13806 }
ab273396 13807 return NULL;
bb4d2ac2
L
13808}
13809
047c3dbf
NL
13810/* Display a symbol size on stdout. Format is based on --sym-base setting. */
13811
13812static unsigned int
b6ac461a 13813print_symbol_size (uint64_t vma, int base)
047c3dbf
NL
13814{
13815 switch (base)
13816 {
13817 case 8:
13818 return print_vma (vma, OCTAL_5);
13819
13820 case 10:
13821 return print_vma (vma, UNSIGNED_5);
13822
13823 case 16:
13824 return print_vma (vma, PREFIX_HEX_5);
13825
13826 case 0:
13827 default:
13828 return print_vma (vma, DEC_5);
13829 }
13830}
13831
b6ac461a
NC
13832/* Print information on a single symbol. */
13833
10ca4b04 13834static void
b6ac461a
NC
13835print_symbol (Filedata * filedata,
13836 uint64_t symbol_index,
13837 Elf_Internal_Sym * symtab,
13838 Elf_Internal_Shdr * section,
13839 char * strtab,
13840 size_t strtab_size)
252b5132 13841{
10ca4b04
L
13842 const char *version_string;
13843 enum versioned_symbol_info sym_info;
13844 unsigned short vna_other;
23356397 13845 const char * sstr;
b6ac461a 13846 Elf_Internal_Sym *psym = symtab + symbol_index;
b9e920ec 13847
b6ac461a
NC
13848 /* FIXME: We should have a table of field widths,
13849 rather than using hard coded constants. */
13850 printf ("%6" PRId64 ": ", symbol_index);
10ca4b04
L
13851 print_vma (psym->st_value, LONG_HEX);
13852 putchar (' ');
b6ac461a 13853 print_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13854 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13855 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13856 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13857 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13858 else
252b5132 13859 {
10ca4b04 13860 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13861
10ca4b04 13862 printf (" %-7s", get_symbol_visibility (vis));
b6ac461a 13863
10ca4b04 13864 /* Check to see if any other bits in the st_other field are set.
b6ac461a
NC
13865 FIXME: Displaying this information here disrupts the layout
13866 of the table being generated. */
10ca4b04
L
13867 if (psym->st_other ^ vis)
13868 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13869 }
0942c7ab 13870
b6ac461a
NC
13871 bool is_special;
13872
13873 sstr = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
13874
13875 /* Print the symbol's section index. If the index is special
13876 then print the index's name rather than its number. */
13877 if (is_special)
13878 {
13879 int printed;
13880
13881 /* Special case: If there are no section headers, and the printable
13882 name is "<section 0x...." then just display the section number
13883 as a decimal. This happens when objcopy --strip -section-headers
13884 is used. */
13885 if (filedata->file_header.e_shnum == 0 && startswith (sstr, "<section"))
13886 printed = printf (" %4d ", psym->st_shndx);
13887 else
13888 printed = printf (" %4s ", sstr);
13889
13890 if (extra_sym_info && printed < 16)
13891 printf ("%*s", 16 - printed, "");
13892 }
13893 else
13894 {
13895 printf (" %4u ", psym->st_shndx);
13896
13897 if (extra_sym_info)
13898 {
13899 /* Display the section name referenced by the section index. */
13900 int printed = printf ("(%s) ", sstr);
13901 if (printed < 10)
13902 printf ("%*s", 10 - printed, "");
13903 }
13904 }
13905
13906 /* Get the symbol's name. For section symbols without a
13907 specific name use the (already computed) section name. */
23356397 13908 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
b6ac461a 13909 && section_index_real (filedata, psym->st_shndx)
23356397
NC
13910 && psym->st_name == 0)
13911 {
b6ac461a 13912 ;
23356397
NC
13913 }
13914 else
13915 {
b6ac461a
NC
13916 bool is_valid;
13917
84714f86 13918 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13919 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13920 }
10ca4b04
L
13921
13922 version_string
13923 = get_symbol_version_string (filedata,
13924 (section == NULL
13925 || section->sh_type == SHT_DYNSYM),
b6ac461a 13926 strtab, strtab_size, symbol_index,
10ca4b04 13927 psym, &sym_info, &vna_other);
b9e920ec 13928
0942c7ab
NC
13929 int len_avail = 21;
13930 if (! do_wide && version_string != NULL)
13931 {
ddb43bab 13932 char buffer[16];
0942c7ab 13933
ddb43bab 13934 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13935
13936 if (sym_info == symbol_undefined)
13937 len_avail -= sprintf (buffer," (%d)", vna_other);
13938 else if (sym_info != symbol_hidden)
13939 len_avail -= 1;
13940 }
13941
b6ac461a 13942 print_symbol_name (len_avail, sstr);
b9e920ec 13943
10ca4b04
L
13944 if (version_string)
13945 {
13946 if (sym_info == symbol_undefined)
13947 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13948 else
10ca4b04
L
13949 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13950 version_string);
13951 }
6bd1a22c 13952
10ca4b04 13953 putchar ('\n');
6bd1a22c 13954
10ca4b04
L
13955 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13956 && section != NULL
b6ac461a 13957 && symbol_index >= section->sh_info
10ca4b04
L
13958 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13959 && filedata->file_header.e_machine != EM_MIPS
13960 /* Solaris binaries have been found to violate this requirement as
13961 well. Not sure if this is a bug or an ABI requirement. */
13962 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
26c527e6 13963 warn (_("local symbol %" PRIu64 " found at index >= %s's sh_info value of %u\n"),
b6ac461a 13964 symbol_index, printable_section_name (filedata, section), section->sh_info);
10ca4b04 13965}
f16a9783 13966
0f03783c
NC
13967static const char *
13968get_lto_kind (unsigned int kind)
13969{
13970 switch (kind)
13971 {
13972 case 0: return "DEF";
13973 case 1: return "WEAKDEF";
13974 case 2: return "UNDEF";
13975 case 3: return "WEAKUNDEF";
13976 case 4: return "COMMON";
13977 default:
13978 break;
13979 }
13980
13981 static char buffer[30];
13982 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13983 sprintf (buffer, "<unknown: %u>", kind);
13984 return buffer;
13985}
13986
13987static const char *
13988get_lto_visibility (unsigned int visibility)
13989{
13990 switch (visibility)
13991 {
13992 case 0: return "DEFAULT";
13993 case 1: return "PROTECTED";
13994 case 2: return "INTERNAL";
13995 case 3: return "HIDDEN";
13996 default:
13997 break;
13998 }
13999
14000 static char buffer[30];
14001 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
14002 sprintf (buffer, "<unknown: %u>", visibility);
14003 return buffer;
14004}
14005
14006static const char *
14007get_lto_sym_type (unsigned int sym_type)
14008{
14009 switch (sym_type)
14010 {
14011 case 0: return "UNKNOWN";
14012 case 1: return "FUNCTION";
14013 case 2: return "VARIABLE";
14014 default:
14015 break;
14016 }
14017
14018 static char buffer[30];
14019 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
14020 sprintf (buffer, "<unknown: %u>", sym_type);
14021 return buffer;
14022}
14023
14024/* Display an LTO format symbol table.
14025 FIXME: The format of LTO symbol tables is not formalized.
14026 So this code could need changing in the future. */
14027
015dc7e1 14028static bool
0f03783c
NC
14029display_lto_symtab (Filedata * filedata,
14030 Elf_Internal_Shdr * section)
14031{
14032 if (section->sh_size == 0)
14033 {
ca0e11aa
NC
14034 if (filedata->is_separate)
14035 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
14036 printable_section_name (filedata, section),
14037 filedata->file_name);
14038 else
14039 printf (_("\nLTO Symbol table '%s' is empty!\n"),
14040 printable_section_name (filedata, section));
047c3dbf 14041
015dc7e1 14042 return true;
0f03783c
NC
14043 }
14044
14045 if (section->sh_size > filedata->file_size)
14046 {
26c527e6 14047 error (_("Section %s has an invalid sh_size of %#" PRIx64 "\n"),
0f03783c 14048 printable_section_name (filedata, section),
26c527e6 14049 section->sh_size);
015dc7e1 14050 return false;
0f03783c
NC
14051 }
14052
14053 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
14054 section->sh_size, 1, _("LTO symbols"));
14055 if (alloced_data == NULL)
015dc7e1 14056 return false;
0f03783c
NC
14057
14058 /* Look for extended data for the symbol table. */
765a0c0a 14059 Elf_Internal_Shdr * ext = NULL;
0f03783c
NC
14060 void * ext_data_orig = NULL;
14061 char * ext_data = NULL;
14062 char * ext_data_end = NULL;
14063 char * ext_name = NULL;
14064
14065 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
14066 (section_name (filedata, section)
14067 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
14068 && ext_name != NULL /* Paranoia. */
14069 && (ext = find_section (filedata, ext_name)) != NULL)
14070 {
14071 if (ext->sh_size < 3)
14072 error (_("LTO Symbol extension table '%s' is empty!\n"),
14073 printable_section_name (filedata, ext));
14074 else
14075 {
14076 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
14077 ext->sh_size, 1,
14078 _("LTO ext symbol data"));
14079 if (ext_data != NULL)
14080 {
14081 ext_data_end = ext_data + ext->sh_size;
14082 if (* ext_data++ != 1)
14083 error (_("Unexpected version number in symbol extension table\n"));
14084 }
14085 }
14086 }
b9e920ec 14087
0f03783c
NC
14088 const unsigned char * data = (const unsigned char *) alloced_data;
14089 const unsigned char * end = data + section->sh_size;
14090
ca0e11aa
NC
14091 if (filedata->is_separate)
14092 printf (_("\nIn linked file '%s': "), filedata->file_name);
14093 else
14094 printf ("\n");
14095
0f03783c
NC
14096 if (ext_data_orig != NULL)
14097 {
14098 if (do_wide)
ca0e11aa 14099 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
14100 printable_section_name (filedata, section),
14101 printable_section_name (filedata, ext));
14102 else
14103 {
ca0e11aa 14104 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
14105 printable_section_name (filedata, section));
14106 printf (_(" and extension table '%s' contain:\n"),
14107 printable_section_name (filedata, ext));
14108 }
14109 }
14110 else
ca0e11aa 14111 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 14112 printable_section_name (filedata, section));
b9e920ec 14113
0f03783c 14114 /* FIXME: Add a wide version. */
b9e920ec 14115 if (ext_data_orig != NULL)
0f03783c
NC
14116 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
14117 else
14118 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
14119
14120 /* FIXME: We do not handle style prefixes. */
14121
14122 while (data < end)
14123 {
14124 const unsigned char * sym_name = data;
14125 data += strnlen ((const char *) sym_name, end - data) + 1;
14126 if (data >= end)
14127 goto fail;
14128
14129 const unsigned char * comdat_key = data;
14130 data += strnlen ((const char *) comdat_key, end - data) + 1;
14131 if (data >= end)
14132 goto fail;
14133
14134 if (data + 2 + 8 + 4 > end)
14135 goto fail;
14136
14137 unsigned int kind = *data++;
14138 unsigned int visibility = *data++;
14139
928c411d 14140 uint64_t size = byte_get (data, 8);
0f03783c
NC
14141 data += 8;
14142
928c411d 14143 uint64_t slot = byte_get (data, 4);
0f03783c
NC
14144 data += 4;
14145
14146 if (ext_data != NULL)
14147 {
14148 if (ext_data < (ext_data_end - 1))
14149 {
14150 unsigned int sym_type = * ext_data ++;
14151 unsigned int sec_kind = * ext_data ++;
14152
31e5a3a3 14153 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " %9s %08x _",
0f03783c
NC
14154 * comdat_key == 0 ? "-" : (char *) comdat_key,
14155 get_lto_kind (kind),
14156 get_lto_visibility (visibility),
31e5a3a3
AM
14157 size,
14158 slot,
0f03783c 14159 get_lto_sym_type (sym_type),
31e5a3a3 14160 sec_kind);
b6ac461a 14161 print_symbol_name (6, (const char *) sym_name);
0f03783c
NC
14162 }
14163 else
14164 {
14165 error (_("Ran out of LTO symbol extension data\n"));
14166 ext_data = NULL;
14167 /* FIXME: return FAIL result ? */
14168 }
14169 }
14170 else
14171 {
31e5a3a3 14172 printf (" %10s %10s %11s %08" PRIx64 " %08" PRIx64 " _",
0f03783c
NC
14173 * comdat_key == 0 ? "-" : (char *) comdat_key,
14174 get_lto_kind (kind),
14175 get_lto_visibility (visibility),
31e5a3a3
AM
14176 size,
14177 slot);
b6ac461a 14178 print_symbol_name (21, (const char *) sym_name);
0f03783c
NC
14179 }
14180 putchar ('\n');
14181 }
14182
14183 if (ext_data != NULL && ext_data < ext_data_end)
14184 {
14185 error (_("Data remains in the LTO symbol extension table\n"));
14186 goto fail;
14187 }
14188
14189 free (alloced_data);
14190 free (ext_data_orig);
14191 free (ext_name);
015dc7e1 14192 return true;
b9e920ec 14193
0f03783c
NC
14194 fail:
14195 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
14196 free (alloced_data);
14197 free (ext_data_orig);
14198 free (ext_name);
015dc7e1 14199 return false;
0f03783c
NC
14200}
14201
14202/* Display LTO symbol tables. */
14203
015dc7e1 14204static bool
0f03783c
NC
14205process_lto_symbol_tables (Filedata * filedata)
14206{
14207 Elf_Internal_Shdr * section;
14208 unsigned int i;
015dc7e1 14209 bool res = true;
0f03783c
NC
14210
14211 if (!do_lto_syms)
015dc7e1 14212 return true;
0f03783c
NC
14213
14214 if (filedata->section_headers == NULL)
015dc7e1 14215 return true;
0f03783c
NC
14216
14217 for (i = 0, section = filedata->section_headers;
14218 i < filedata->file_header.e_shnum;
14219 i++, section++)
84714f86
AM
14220 if (section_name_valid (filedata, section)
14221 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
14222 res &= display_lto_symtab (filedata, section);
14223
b9e920ec 14224 return res;
0f03783c
NC
14225}
14226
b6ac461a
NC
14227static void
14228print_symbol_table_heading (void)
14229{
14230 /* FIXME: We should store the size of each field in the display in a table and
14231 then use the values inside print_symbol(), instead of that function using
14232 hard coded constants. */
14233 if (is_32bit_elf)
14234 {
14235 if (extra_sym_info)
14236 {
14237 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14238 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |---8--| |----13.....| |........... */
14239 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 (.text) get_sections */
14240 }
14241 else if (do_wide)
14242 {
14243 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14244 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14245 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14246 }
14247 else
14248 {
14249 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14250 /* |--6-|: |--8---| |-5-| |--7--| |-6--| |--7--| |-4| |------------29-------------| */
14251 /* eg: 5: 00000000 14 FUNC LOCAL DEFAULT 1 get_sections */
14252 }
14253 }
14254 else
14255 {
14256 if (extra_sym_info)
14257 {
14258 printf (_(" Num: Value Size Type Bind Vis+Other Ndx(SecName) Name [+ Version Info]\n"));
14259 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-------14---| |..... */
14260 /* eg: 2: 0000000000000000 0 FUNC LOCAL DEFAULT 1 (.text) .very_long_function_name */
14261
14262 }
14263 else if (do_wide)
14264 {
14265 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14266 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |........... */
14267 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_function_name */
14268 }
14269 else
14270 {
14271 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
14272 /* |--6-|: |------16------| |-5-| |--7--| |-6--| |--7--| |-4| |--------21---------| */
14273 /* eg: 5: 0000000000000000 14 FUNC LOCAL DEFAULT 1 very_long_functi[...] */
14274 }
14275 }
14276}
14277
8e8d0b63
NC
14278static bool
14279dump_symbol_section (Elf_Internal_Shdr * section,
14280 Filedata * filedata)
14281{
14282 if (section->sh_entsize == 0)
14283 {
14284 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
14285 printable_section_name (filedata, section));
14286 return false;
14287 }
14288
14289 uint64_t num_syms = section->sh_size / section->sh_entsize;
14290
14291 if (filedata->is_separate)
14292 printf (ngettext ("\nIn linked file '%s' symbol section '%s'"
14293 " contains %" PRIu64 " entry:\n",
14294 "\nIn linked file '%s' symbol section '%s'"
14295 " contains %" PRIu64 " entries:\n",
14296 num_syms),
14297 filedata->file_name,
14298 printable_section_name (filedata, section),
14299 num_syms);
14300 else
14301 printf (ngettext ("\nSymbol table '%s' contains %" PRIu64
14302 " entry:\n",
14303 "\nSymbol table '%s' contains %" PRIu64
14304 " entries:\n",
14305 num_syms),
14306 printable_section_name (filedata, section),
14307 num_syms);
14308
14309 print_symbol_table_heading ();
14310
14311 Elf_Internal_Sym * symtab = get_elf_symbols (filedata, section, & num_syms);
14312 if (symtab == NULL)
14313 /* An error message will have already been displayed. */
14314 return false;
14315
14316 char * strtab = NULL;
14317 uint64_t strtab_size = 0;
14318
14319 if (section->sh_link == filedata->file_header.e_shstrndx)
14320 {
14321 strtab = filedata->string_table;
14322 strtab_size = filedata->string_table_length;
14323 }
14324 else if (section->sh_link < filedata->file_header.e_shnum)
14325 {
14326 Elf_Internal_Shdr * string_sec;
14327
14328 string_sec = filedata->section_headers + section->sh_link;
14329
14330 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
14331 1, string_sec->sh_size,
14332 _("string table"));
14333 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
14334 }
14335
14336 uint64_t si;
14337
14338 for (si = 0; si < num_syms; si++)
14339 print_symbol (filedata, si, symtab, section, strtab, strtab_size);
14340
14341 free (symtab);
14342
14343 if (strtab != filedata->string_table)
14344 free (strtab);
14345
14346 return true;
14347}
14348
10ca4b04 14349/* Dump the symbol table. */
0f03783c 14350
015dc7e1 14351static bool
10ca4b04
L
14352process_symbol_table (Filedata * filedata)
14353{
14354 Elf_Internal_Shdr * section;
f16a9783 14355
10ca4b04 14356 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 14357 return true;
6bd1a22c 14358
978c4450 14359 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
14360 && do_syms
14361 && do_using_dynamic
978c4450
AM
14362 && filedata->dynamic_strings != NULL
14363 && filedata->dynamic_symbols != NULL)
6bd1a22c 14364 {
26c527e6 14365 uint64_t si;
6bd1a22c 14366
ca0e11aa
NC
14367 if (filedata->is_separate)
14368 {
26c527e6
AM
14369 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table"
14370 " contains %" PRIu64 " entry:\n",
14371 "\nIn linked file '%s' the dynamic symbol table"
14372 " contains %" PRIu64 " entries:\n",
ca0e11aa
NC
14373 filedata->num_dynamic_syms),
14374 filedata->file_name,
14375 filedata->num_dynamic_syms);
14376 }
14377 else
14378 {
26c527e6
AM
14379 printf (ngettext ("\nSymbol table for image contains %" PRIu64
14380 " entry:\n",
14381 "\nSymbol table for image contains %" PRIu64
14382 " entries:\n",
ca0e11aa
NC
14383 filedata->num_dynamic_syms),
14384 filedata->num_dynamic_syms);
14385 }
b6ac461a
NC
14386
14387 print_symbol_table_heading ();
6bd1a22c 14388
978c4450 14389 for (si = 0; si < filedata->num_dynamic_syms; si++)
b6ac461a
NC
14390 print_symbol (filedata, si, filedata->dynamic_symbols, NULL,
14391 filedata->dynamic_strings,
14392 filedata->dynamic_strings_length);
252b5132 14393 }
8b73c356 14394 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 14395 && filedata->section_headers != NULL)
252b5132 14396 {
b34976b6 14397 unsigned int i;
252b5132 14398
dda8d76d
NC
14399 for (i = 0, section = filedata->section_headers;
14400 i < filedata->file_header.e_shnum;
252b5132
RH
14401 i++, section++)
14402 {
2c610e4b
L
14403 if ((section->sh_type != SHT_SYMTAB
14404 && section->sh_type != SHT_DYNSYM)
14405 || (!do_syms
14406 && section->sh_type == SHT_SYMTAB))
252b5132
RH
14407 continue;
14408
8e8d0b63 14409 dump_symbol_section (section, filedata);
252b5132
RH
14410 }
14411 }
14412 else if (do_syms)
14413 printf
14414 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
14415
978c4450 14416 if (do_histogram && filedata->buckets != NULL)
252b5132 14417 {
26c527e6
AM
14418 uint64_t *lengths;
14419 uint64_t *counts;
14420 uint64_t hn;
625d49fc 14421 uint64_t si;
26c527e6
AM
14422 uint64_t maxlength = 0;
14423 uint64_t nzero_counts = 0;
14424 uint64_t nsyms = 0;
6bd6a03d 14425 char *visited;
252b5132 14426
d3a49aa8 14427 printf (ngettext ("\nHistogram for bucket list length "
26c527e6 14428 "(total of %" PRIu64 " bucket):\n",
d3a49aa8 14429 "\nHistogram for bucket list length "
26c527e6
AM
14430 "(total of %" PRIu64 " buckets):\n",
14431 filedata->nbuckets),
14432 filedata->nbuckets);
252b5132 14433
26c527e6 14434 lengths = calloc (filedata->nbuckets, sizeof (*lengths));
252b5132
RH
14435 if (lengths == NULL)
14436 {
8b73c356 14437 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 14438 goto err_out;
252b5132 14439 }
978c4450
AM
14440 visited = xcmalloc (filedata->nchains, 1);
14441 memset (visited, 0, filedata->nchains);
8b73c356
NC
14442
14443 printf (_(" Length Number %% of total Coverage\n"));
978c4450 14444 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 14445 {
978c4450 14446 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 14447 {
b34976b6 14448 ++nsyms;
252b5132 14449 if (maxlength < ++lengths[hn])
b34976b6 14450 ++maxlength;
978c4450 14451 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
14452 {
14453 error (_("histogram chain is corrupt\n"));
14454 break;
14455 }
14456 visited[si] = 1;
252b5132
RH
14457 }
14458 }
6bd6a03d 14459 free (visited);
252b5132 14460
26c527e6 14461 counts = calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
14462 if (counts == NULL)
14463 {
b2e951ec 14464 free (lengths);
8b73c356 14465 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 14466 goto err_out;
252b5132
RH
14467 }
14468
978c4450 14469 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 14470 ++counts[lengths[hn]];
252b5132 14471
978c4450 14472 if (filedata->nbuckets > 0)
252b5132 14473 {
26c527e6
AM
14474 uint64_t i;
14475 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14476 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 14477 for (i = 1; i <= maxlength; ++i)
103f02d3 14478 {
66543521 14479 nzero_counts += counts[i] * i;
26c527e6 14480 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14481 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
14482 (nzero_counts * 100.0) / nsyms);
14483 }
252b5132
RH
14484 }
14485
14486 free (counts);
14487 free (lengths);
14488 }
14489
978c4450
AM
14490 free (filedata->buckets);
14491 filedata->buckets = NULL;
14492 filedata->nbuckets = 0;
14493 free (filedata->chains);
14494 filedata->chains = NULL;
252b5132 14495
978c4450 14496 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 14497 {
26c527e6
AM
14498 uint64_t *lengths;
14499 uint64_t *counts;
14500 uint64_t hn;
14501 uint64_t maxlength = 0;
14502 uint64_t nzero_counts = 0;
14503 uint64_t nsyms = 0;
fdc90cb4 14504
f16a9783 14505 printf (ngettext ("\nHistogram for `%s' bucket list length "
26c527e6 14506 "(total of %" PRIu64 " bucket):\n",
f16a9783 14507 "\nHistogram for `%s' bucket list length "
26c527e6
AM
14508 "(total of %" PRIu64 " buckets):\n",
14509 filedata->ngnubuckets),
978c4450 14510 GNU_HASH_SECTION_NAME (filedata),
26c527e6 14511 filedata->ngnubuckets);
8b73c356 14512
26c527e6 14513 lengths = calloc (filedata->ngnubuckets, sizeof (*lengths));
fdc90cb4
JJ
14514 if (lengths == NULL)
14515 {
8b73c356 14516 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 14517 goto err_out;
fdc90cb4
JJ
14518 }
14519
fdc90cb4
JJ
14520 printf (_(" Length Number %% of total Coverage\n"));
14521
978c4450
AM
14522 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
14523 if (filedata->gnubuckets[hn] != 0)
fdc90cb4 14524 {
625d49fc 14525 uint64_t off, length = 1;
fdc90cb4 14526
978c4450 14527 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 14528 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
14529 off < filedata->ngnuchains
14530 && (filedata->gnuchains[off] & 1) == 0;
071436c6 14531 ++off)
fdc90cb4
JJ
14532 ++length;
14533 lengths[hn] = length;
14534 if (length > maxlength)
14535 maxlength = length;
14536 nsyms += length;
14537 }
14538
26c527e6 14539 counts = calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
14540 if (counts == NULL)
14541 {
b2e951ec 14542 free (lengths);
8b73c356 14543 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 14544 goto err_out;
fdc90cb4
JJ
14545 }
14546
978c4450 14547 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
14548 ++counts[lengths[hn]];
14549
978c4450 14550 if (filedata->ngnubuckets > 0)
fdc90cb4 14551 {
26c527e6
AM
14552 uint64_t j;
14553 printf (" 0 %-10" PRIu64 " (%5.1f%%)\n",
978c4450 14554 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
14555 for (j = 1; j <= maxlength; ++j)
14556 {
14557 nzero_counts += counts[j] * j;
26c527e6 14558 printf ("%7" PRIu64 " %-10" PRIu64 " (%5.1f%%) %5.1f%%\n",
978c4450 14559 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
14560 (nzero_counts * 100.0) / nsyms);
14561 }
14562 }
14563
14564 free (counts);
14565 free (lengths);
fdc90cb4 14566 }
978c4450
AM
14567 free (filedata->gnubuckets);
14568 filedata->gnubuckets = NULL;
14569 filedata->ngnubuckets = 0;
14570 free (filedata->gnuchains);
14571 filedata->gnuchains = NULL;
14572 filedata->ngnuchains = 0;
14573 free (filedata->mipsxlat);
14574 filedata->mipsxlat = NULL;
015dc7e1 14575 return true;
fd486f32
AM
14576
14577 err_out:
978c4450
AM
14578 free (filedata->gnubuckets);
14579 filedata->gnubuckets = NULL;
14580 filedata->ngnubuckets = 0;
14581 free (filedata->gnuchains);
14582 filedata->gnuchains = NULL;
14583 filedata->ngnuchains = 0;
14584 free (filedata->mipsxlat);
14585 filedata->mipsxlat = NULL;
14586 free (filedata->buckets);
14587 filedata->buckets = NULL;
14588 filedata->nbuckets = 0;
14589 free (filedata->chains);
14590 filedata->chains = NULL;
015dc7e1 14591 return false;
252b5132
RH
14592}
14593
015dc7e1 14594static bool
ca0e11aa 14595process_syminfo (Filedata * filedata)
252b5132 14596{
b4c96d0d 14597 unsigned int i;
252b5132 14598
978c4450 14599 if (filedata->dynamic_syminfo == NULL
252b5132
RH
14600 || !do_dynamic)
14601 /* No syminfo, this is ok. */
015dc7e1 14602 return true;
252b5132
RH
14603
14604 /* There better should be a dynamic symbol section. */
978c4450 14605 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 14606 return false;
252b5132 14607
ca0e11aa 14608 if (filedata->is_separate)
26c527e6
AM
14609 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entry:\n",
14610 "\nIn linked file '%s: the dynamic info segment at offset %#" PRIx64 " contains %d entries:\n",
ca0e11aa
NC
14611 filedata->dynamic_syminfo_nent),
14612 filedata->file_name,
14613 filedata->dynamic_syminfo_offset,
14614 filedata->dynamic_syminfo_nent);
14615 else
26c527e6
AM
14616 printf (ngettext ("\nDynamic info segment at offset %#" PRIx64
14617 " contains %d entry:\n",
14618 "\nDynamic info segment at offset %#" PRIx64
14619 " contains %d entries:\n",
978c4450 14620 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
14621 filedata->dynamic_syminfo_offset,
14622 filedata->dynamic_syminfo_nent);
252b5132
RH
14623
14624 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 14625 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 14626 {
978c4450 14627 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 14628
31104126 14629 printf ("%4d: ", i);
978c4450 14630 if (i >= filedata->num_dynamic_syms)
4082ef84 14631 printf (_("<corrupt index>"));
84714f86 14632 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
b6ac461a 14633 print_symbol_name (30, get_dynamic_name (filedata,
978c4450 14634 filedata->dynamic_symbols[i].st_name));
d79b3d50 14635 else
978c4450 14636 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 14637 putchar (' ');
252b5132 14638
978c4450 14639 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
14640 {
14641 case SYMINFO_BT_SELF:
14642 fputs ("SELF ", stdout);
14643 break;
14644 case SYMINFO_BT_PARENT:
14645 fputs ("PARENT ", stdout);
14646 break;
14647 default:
978c4450
AM
14648 if (filedata->dynamic_syminfo[i].si_boundto > 0
14649 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 14650 && valid_dynamic_name (filedata,
978c4450 14651 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 14652 {
b6ac461a 14653 print_symbol_name (10, get_dynamic_name (filedata,
978c4450 14654 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
14655 putchar (' ' );
14656 }
252b5132 14657 else
978c4450 14658 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
14659 break;
14660 }
14661
14662 if (flags & SYMINFO_FLG_DIRECT)
14663 printf (" DIRECT");
14664 if (flags & SYMINFO_FLG_PASSTHRU)
14665 printf (" PASSTHRU");
14666 if (flags & SYMINFO_FLG_COPY)
14667 printf (" COPY");
14668 if (flags & SYMINFO_FLG_LAZYLOAD)
14669 printf (" LAZYLOAD");
14670
14671 puts ("");
14672 }
14673
015dc7e1 14674 return true;
252b5132
RH
14675}
14676
75802ccb
CE
14677/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
14678 is contained by the region START .. END. The types of ADDR, START
14679 and END should all be the same. Note both ADDR + NELEM and END
14680 point to just beyond the end of the regions that are being tested. */
14681#define IN_RANGE(START,END,ADDR,NELEM) \
14682 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 14683
cf13d699
NC
14684/* Check to see if the given reloc needs to be handled in a target specific
14685 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
14686 FALSE.
14687
14688 If called with reloc == NULL, then this is a signal that reloc processing
14689 for the current section has finished, and any saved state should be
14690 discarded. */
09c11c86 14691
015dc7e1 14692static bool
26c527e6
AM
14693target_specific_reloc_handling (Filedata *filedata,
14694 Elf_Internal_Rela *reloc,
14695 unsigned char *start,
14696 unsigned char *end,
14697 Elf_Internal_Sym *symtab,
14698 uint64_t num_syms)
252b5132 14699{
f84ce13b 14700 unsigned int reloc_type = 0;
26c527e6 14701 uint64_t sym_index = 0;
f84ce13b
NC
14702
14703 if (reloc)
14704 {
dda8d76d 14705 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
14706 sym_index = get_reloc_symindex (reloc->r_info);
14707 }
252b5132 14708
dda8d76d 14709 switch (filedata->file_header.e_machine)
252b5132 14710 {
76244462 14711 case EM_LOONGARCH:
14712 {
14713 switch (reloc_type)
14714 {
14715 /* For .uleb128 .LFE1-.LFB1, loongarch write 0 to object file
14716 at assembly time. */
14717 case 107: /* R_LARCH_ADD_ULEB128. */
14718 case 108: /* R_LARCH_SUB_ULEB128. */
14719 {
d3f34076 14720 uint64_t value = 0;
76244462 14721 unsigned int reloc_size = 0;
14722 int leb_ret = 0;
14723
89c70cd3
AM
14724 if (reloc->r_offset < (size_t) (end - start))
14725 value = read_leb128 (start + reloc->r_offset, end, false,
14726 &reloc_size, &leb_ret);
76244462 14727 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
14728 error (_("LoongArch ULEB128 field at 0x%lx contains invalid "
14729 "ULEB128 value\n"),
14730 (long) reloc->r_offset);
14731
74a965d8
AM
14732 else if (sym_index >= num_syms)
14733 error (_("%s reloc contains invalid symbol index "
14734 "%" PRIu64 "\n"),
14735 (reloc_type == 107
14736 ? "R_LARCH_ADD_ULEB128"
14737 : "R_LARCH_SUB_ULEB128"),
14738 sym_index);
14739 else
76244462 14740 {
74a965d8
AM
14741 if (reloc_type == 107)
14742 value += reloc->r_addend + symtab[sym_index].st_value;
14743 else
14744 value -= reloc->r_addend + symtab[sym_index].st_value;
14745
14746 /* Write uleb128 value to p. */
14747 bfd_byte *p = start + reloc->r_offset;
14748 do
14749 {
14750 bfd_byte c = value & 0x7f;
14751 value >>= 7;
14752 if (--reloc_size != 0)
14753 c |= 0x80;
14754 *p++ = c;
14755 }
14756 while (reloc_size);
76244462 14757 }
76244462 14758
14759 return true;
14760 }
14761 }
14762 break;
14763 }
14764
13761a11
NC
14765 case EM_MSP430:
14766 case EM_MSP430_OLD:
14767 {
14768 static Elf_Internal_Sym * saved_sym = NULL;
14769
f84ce13b
NC
14770 if (reloc == NULL)
14771 {
14772 saved_sym = NULL;
015dc7e1 14773 return true;
f84ce13b
NC
14774 }
14775
13761a11
NC
14776 switch (reloc_type)
14777 {
14778 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 14779 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 14780 if (uses_msp430x_relocs (filedata))
13761a11 14781 break;
1a0670f3 14782 /* Fall through. */
13761a11 14783 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 14784 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
14785 /* PR 21139. */
14786 if (sym_index >= num_syms)
74a965d8
AM
14787 error (_("%s reloc contains invalid symbol index "
14788 "%" PRIu64 "\n"), "MSP430 SYM_DIFF", sym_index);
f84ce13b
NC
14789 else
14790 saved_sym = symtab + sym_index;
015dc7e1 14791 return true;
13761a11
NC
14792
14793 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14794 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
14795 goto handle_sym_diff;
0b4362b0 14796
13761a11
NC
14797 case 5: /* R_MSP430_16_BYTE */
14798 case 9: /* R_MSP430_8 */
7d81bc93 14799 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 14800 if (uses_msp430x_relocs (filedata))
13761a11
NC
14801 break;
14802 goto handle_sym_diff;
14803
14804 case 2: /* R_MSP430_ABS16 */
14805 case 15: /* R_MSP430X_ABS16 */
7d81bc93 14806 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 14807 if (! uses_msp430x_relocs (filedata))
13761a11
NC
14808 break;
14809 goto handle_sym_diff;
0b4362b0 14810
13761a11
NC
14811 handle_sym_diff:
14812 if (saved_sym != NULL)
14813 {
625d49fc 14814 uint64_t value;
5a805384 14815 unsigned int reloc_size = 0;
7d81bc93
JL
14816 int leb_ret = 0;
14817 switch (reloc_type)
14818 {
14819 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
14820 reloc_size = 4;
14821 break;
14822 case 11: /* R_MSP430_GNU_SET_ULEB128 */
14823 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 14824 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 14825 read_leb128 (start + reloc->r_offset, end, false,
5a805384 14826 &reloc_size, &leb_ret);
7d81bc93
JL
14827 break;
14828 default:
14829 reloc_size = 2;
14830 break;
14831 }
13761a11 14832
5a805384 14833 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
26c527e6
AM
14834 error (_("MSP430 ULEB128 field at %#" PRIx64
14835 " contains invalid ULEB128 value\n"),
14836 reloc->r_offset);
7d81bc93 14837 else if (sym_index >= num_syms)
74a965d8
AM
14838 error (_("%s reloc contains invalid symbol index "
14839 "%" PRIu64 "\n"), "MSP430", sym_index);
03f7786e 14840 else
f84ce13b
NC
14841 {
14842 value = reloc->r_addend + (symtab[sym_index].st_value
14843 - saved_sym->st_value);
14844
b32e566b 14845 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14846 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
14847 else
14848 /* PR 21137 */
26c527e6
AM
14849 error (_("MSP430 sym diff reloc contains invalid offset: "
14850 "%#" PRIx64 "\n"),
14851 reloc->r_offset);
f84ce13b 14852 }
13761a11
NC
14853
14854 saved_sym = NULL;
015dc7e1 14855 return true;
13761a11
NC
14856 }
14857 break;
14858
14859 default:
14860 if (saved_sym != NULL)
071436c6 14861 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
14862 break;
14863 }
14864 break;
14865 }
14866
cf13d699
NC
14867 case EM_MN10300:
14868 case EM_CYGNUS_MN10300:
14869 {
14870 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 14871
f84ce13b
NC
14872 if (reloc == NULL)
14873 {
14874 saved_sym = NULL;
015dc7e1 14875 return true;
f84ce13b
NC
14876 }
14877
cf13d699
NC
14878 switch (reloc_type)
14879 {
14880 case 34: /* R_MN10300_ALIGN */
015dc7e1 14881 return true;
cf13d699 14882 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b 14883 if (sym_index >= num_syms)
74a965d8
AM
14884 error (_("%s reloc contains invalid symbol index "
14885 "%" PRIu64 "\n"), "MN10300_SYM_DIFF", sym_index);
f84ce13b
NC
14886 else
14887 saved_sym = symtab + sym_index;
015dc7e1 14888 return true;
f84ce13b 14889
cf13d699
NC
14890 case 1: /* R_MN10300_32 */
14891 case 2: /* R_MN10300_16 */
14892 if (saved_sym != NULL)
14893 {
03f7786e 14894 int reloc_size = reloc_type == 1 ? 4 : 2;
625d49fc 14895 uint64_t value;
252b5132 14896
f84ce13b 14897 if (sym_index >= num_syms)
74a965d8
AM
14898 error (_("%s reloc contains invalid symbol index "
14899 "%" PRIu64 "\n"), "MN10300", sym_index);
03f7786e 14900 else
f84ce13b
NC
14901 {
14902 value = reloc->r_addend + (symtab[sym_index].st_value
14903 - saved_sym->st_value);
14904
b32e566b 14905 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 14906 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b 14907 else
26c527e6
AM
14908 error (_("MN10300 sym diff reloc contains invalid offset:"
14909 " %#" PRIx64 "\n"),
14910 reloc->r_offset);
f84ce13b 14911 }
252b5132 14912
cf13d699 14913 saved_sym = NULL;
015dc7e1 14914 return true;
cf13d699
NC
14915 }
14916 break;
14917 default:
14918 if (saved_sym != NULL)
071436c6 14919 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
14920 break;
14921 }
14922 break;
14923 }
6ff71e76
NC
14924
14925 case EM_RL78:
14926 {
625d49fc
AM
14927 static uint64_t saved_sym1 = 0;
14928 static uint64_t saved_sym2 = 0;
14929 static uint64_t value;
6ff71e76 14930
f84ce13b
NC
14931 if (reloc == NULL)
14932 {
14933 saved_sym1 = saved_sym2 = 0;
015dc7e1 14934 return true;
f84ce13b
NC
14935 }
14936
6ff71e76
NC
14937 switch (reloc_type)
14938 {
14939 case 0x80: /* R_RL78_SYM. */
14940 saved_sym1 = saved_sym2;
f84ce13b 14941 if (sym_index >= num_syms)
74a965d8
AM
14942 error (_("%s reloc contains invalid symbol index "
14943 "%" PRIu64 "\n"), "RL78_SYM", sym_index);
f84ce13b
NC
14944 else
14945 {
14946 saved_sym2 = symtab[sym_index].st_value;
14947 saved_sym2 += reloc->r_addend;
14948 }
015dc7e1 14949 return true;
6ff71e76
NC
14950
14951 case 0x83: /* R_RL78_OPsub. */
14952 value = saved_sym1 - saved_sym2;
14953 saved_sym2 = saved_sym1 = 0;
015dc7e1 14954 return true;
6ff71e76
NC
14955 break;
14956
14957 case 0x41: /* R_RL78_ABS32. */
b32e566b 14958 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 14959 byte_put (start + reloc->r_offset, value, 4);
b32e566b 14960 else
26c527e6
AM
14961 error (_("RL78 sym diff reloc contains invalid offset: "
14962 "%#" PRIx64 "\n"),
14963 reloc->r_offset);
6ff71e76 14964 value = 0;
015dc7e1 14965 return true;
6ff71e76
NC
14966
14967 case 0x43: /* R_RL78_ABS16. */
b32e566b 14968 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 14969 byte_put (start + reloc->r_offset, value, 2);
b32e566b 14970 else
26c527e6
AM
14971 error (_("RL78 sym diff reloc contains invalid offset: "
14972 "%#" PRIx64 "\n"),
14973 reloc->r_offset);
6ff71e76 14974 value = 0;
015dc7e1 14975 return true;
6ff71e76
NC
14976
14977 default:
14978 break;
14979 }
14980 break;
14981 }
252b5132
RH
14982 }
14983
015dc7e1 14984 return false;
252b5132
RH
14985}
14986
aca88567
NC
14987/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
14988 DWARF debug sections. This is a target specific test. Note - we do not
14989 go through the whole including-target-headers-multiple-times route, (as
14990 we have already done with <elf/h8.h>) because this would become very
14991 messy and even then this function would have to contain target specific
14992 information (the names of the relocs instead of their numeric values).
14993 FIXME: This is not the correct way to solve this problem. The proper way
14994 is to have target specific reloc sizing and typing functions created by
14995 the reloc-macros.h header, in the same way that it already creates the
14996 reloc naming functions. */
14997
015dc7e1 14998static bool
dda8d76d 14999is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15000{
d347c9df 15001 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15002 switch (filedata->file_header.e_machine)
aca88567 15003 {
41e92641 15004 case EM_386:
22abe556 15005 case EM_IAMCU:
41e92641 15006 return reloc_type == 1; /* R_386_32. */
aca88567
NC
15007 case EM_68K:
15008 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
15009 case EM_860:
15010 return reloc_type == 1; /* R_860_32. */
15011 case EM_960:
15012 return reloc_type == 2; /* R_960_32. */
a06ea964 15013 case EM_AARCH64:
9282b95a
JW
15014 return (reloc_type == 258
15015 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
15016 case EM_BPF:
15017 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
15018 case EM_ADAPTEVA_EPIPHANY:
15019 return reloc_type == 3;
aca88567 15020 case EM_ALPHA:
137b6b5f 15021 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
15022 case EM_ARC:
15023 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
15024 case EM_ARC_COMPACT:
15025 case EM_ARC_COMPACT2:
b5c37946
SJ
15026 case EM_ARC_COMPACT3:
15027 case EM_ARC_COMPACT3_64:
886a2506 15028 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
15029 case EM_ARM:
15030 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 15031 case EM_AVR_OLD:
aca88567
NC
15032 case EM_AVR:
15033 return reloc_type == 1;
15034 case EM_BLACKFIN:
15035 return reloc_type == 0x12; /* R_byte4_data. */
15036 case EM_CRIS:
15037 return reloc_type == 3; /* R_CRIS_32. */
15038 case EM_CR16:
15039 return reloc_type == 3; /* R_CR16_NUM32. */
15040 case EM_CRX:
15041 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
15042 case EM_CSKY:
15043 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
15044 case EM_CYGNUS_FRV:
15045 return reloc_type == 1;
41e92641
NC
15046 case EM_CYGNUS_D10V:
15047 case EM_D10V:
15048 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
15049 case EM_CYGNUS_D30V:
15050 case EM_D30V:
15051 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
15052 case EM_DLX:
15053 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
15054 case EM_CYGNUS_FR30:
15055 case EM_FR30:
15056 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
15057 case EM_FT32:
15058 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
15059 case EM_H8S:
15060 case EM_H8_300:
15061 case EM_H8_300H:
15062 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 15063 case EM_IA_64:
262cdac7
AM
15064 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
15065 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
15066 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
15067 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
15068 case EM_IP2K_OLD:
15069 case EM_IP2K:
15070 return reloc_type == 2; /* R_IP2K_32. */
15071 case EM_IQ2000:
15072 return reloc_type == 2; /* R_IQ2000_32. */
6e712424
PI
15073 case EM_KVX:
15074 return reloc_type == 2; /* R_KVX_32. */
84e94c90
NC
15075 case EM_LATTICEMICO32:
15076 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 15077 case EM_LOONGARCH:
15078 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 15079 case EM_M32C_OLD:
aca88567
NC
15080 case EM_M32C:
15081 return reloc_type == 3; /* R_M32C_32. */
15082 case EM_M32R:
15083 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
15084 case EM_68HC11:
15085 case EM_68HC12:
15086 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 15087 case EM_S12Z:
2849d19f
JD
15088 return reloc_type == 7 || /* R_S12Z_EXT32 */
15089 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
15090 case EM_MCORE:
15091 return reloc_type == 1; /* R_MCORE_ADDR32. */
15092 case EM_CYGNUS_MEP:
15093 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
15094 case EM_METAG:
15095 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
15096 case EM_MICROBLAZE:
15097 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
15098 case EM_MIPS:
15099 return reloc_type == 2; /* R_MIPS_32. */
15100 case EM_MMIX:
15101 return reloc_type == 4; /* R_MMIX_32. */
15102 case EM_CYGNUS_MN10200:
15103 case EM_MN10200:
15104 return reloc_type == 1; /* R_MN10200_32. */
15105 case EM_CYGNUS_MN10300:
15106 case EM_MN10300:
15107 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
15108 case EM_MOXIE:
15109 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
15110 case EM_MSP430_OLD:
15111 case EM_MSP430:
13761a11 15112 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
15113 case EM_MT:
15114 return reloc_type == 2; /* R_MT_32. */
35c08157 15115 case EM_NDS32:
81c5e376 15116 return reloc_type == 20; /* R_NDS32_32_RELA. */
3e0873ac 15117 case EM_ALTERA_NIOS2:
36591ba1 15118 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
15119 case EM_NIOS32:
15120 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
15121 case EM_OR1K:
15122 return reloc_type == 1; /* R_OR1K_32. */
aca88567 15123 case EM_PARISC:
9abca702 15124 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 15125 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 15126 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
15127 case EM_PJ:
15128 case EM_PJ_OLD:
15129 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
15130 case EM_PPC64:
15131 return reloc_type == 1; /* R_PPC64_ADDR32. */
15132 case EM_PPC:
15133 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
15134 case EM_TI_PRU:
15135 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
15136 case EM_RISCV:
15137 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
15138 case EM_RL78:
15139 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
15140 case EM_RX:
15141 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
15142 case EM_S370:
15143 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
15144 case EM_S390_OLD:
15145 case EM_S390:
15146 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
15147 case EM_SCORE:
15148 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
15149 case EM_SH:
15150 return reloc_type == 1; /* R_SH_DIR32. */
15151 case EM_SPARC32PLUS:
15152 case EM_SPARCV9:
15153 case EM_SPARC:
15154 return reloc_type == 3 /* R_SPARC_32. */
15155 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
15156 case EM_SPU:
15157 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
15158 case EM_TI_C6000:
15159 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
15160 case EM_TILEGX:
15161 return reloc_type == 2; /* R_TILEGX_32. */
15162 case EM_TILEPRO:
15163 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
15164 case EM_CYGNUS_V850:
15165 case EM_V850:
15166 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
15167 case EM_V800:
15168 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
15169 case EM_VAX:
15170 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
15171 case EM_VISIUM:
15172 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
15173 case EM_WEBASSEMBLY:
15174 return reloc_type == 1; /* R_WASM32_32. */
aca88567 15175 case EM_X86_64:
8a9036a4 15176 case EM_L1OM:
7a9068fe 15177 case EM_K1OM:
aca88567 15178 return reloc_type == 10; /* R_X86_64_32. */
f6c1a2d5
NC
15179 case EM_XGATE:
15180 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
15181 case EM_XSTORMY16:
15182 return reloc_type == 1; /* R_XSTROMY16_32. */
15183 case EM_XTENSA_OLD:
15184 case EM_XTENSA:
15185 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
15186 case EM_Z80:
15187 return reloc_type == 6; /* R_Z80_32. */
aca88567 15188 default:
bee0ee85
NC
15189 {
15190 static unsigned int prev_warn = 0;
15191
15192 /* Avoid repeating the same warning multiple times. */
dda8d76d 15193 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 15194 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
15195 filedata->file_header.e_machine);
15196 prev_warn = filedata->file_header.e_machine;
015dc7e1 15197 return false;
bee0ee85 15198 }
aca88567
NC
15199 }
15200}
15201
15202/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15203 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
15204
015dc7e1 15205static bool
dda8d76d 15206is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15207{
dda8d76d 15208 switch (filedata->file_header.e_machine)
d347c9df 15209 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 15210 {
41e92641 15211 case EM_386:
22abe556 15212 case EM_IAMCU:
3e0873ac 15213 return reloc_type == 2; /* R_386_PC32. */
aca88567 15214 case EM_68K:
3e0873ac 15215 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
15216 case EM_AARCH64:
15217 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
15218 case EM_ADAPTEVA_EPIPHANY:
15219 return reloc_type == 6;
aca88567
NC
15220 case EM_ALPHA:
15221 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
15222 case EM_ARC_COMPACT:
15223 case EM_ARC_COMPACT2:
b5c37946
SJ
15224 case EM_ARC_COMPACT3:
15225 case EM_ARC_COMPACT3_64:
726c18e1 15226 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 15227 case EM_ARM:
3e0873ac 15228 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
15229 case EM_AVR_OLD:
15230 case EM_AVR:
15231 return reloc_type == 36; /* R_AVR_32_PCREL. */
98011207 15232 case EM_LOONGARCH:
15233 return reloc_type == 99; /* R_LARCH_32_PCREL. */
137b6b5f
AM
15234 case EM_MICROBLAZE:
15235 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
15236 case EM_OR1K:
15237 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 15238 case EM_PARISC:
85acf597 15239 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
15240 case EM_PPC:
15241 return reloc_type == 26; /* R_PPC_REL32. */
15242 case EM_PPC64:
3e0873ac 15243 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
15244 case EM_RISCV:
15245 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
15246 case EM_S390_OLD:
15247 case EM_S390:
3e0873ac 15248 return reloc_type == 5; /* R_390_PC32. */
aca88567 15249 case EM_SH:
3e0873ac 15250 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
15251 case EM_SPARC32PLUS:
15252 case EM_SPARCV9:
15253 case EM_SPARC:
3e0873ac 15254 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
15255 case EM_SPU:
15256 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
15257 case EM_TILEGX:
15258 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
15259 case EM_TILEPRO:
15260 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
15261 case EM_VISIUM:
15262 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 15263 case EM_X86_64:
8a9036a4 15264 case EM_L1OM:
7a9068fe 15265 case EM_K1OM:
3e0873ac 15266 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
15267 case EM_VAX:
15268 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
15269 case EM_XTENSA_OLD:
15270 case EM_XTENSA:
15271 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
6e712424
PI
15272 case EM_KVX:
15273 return reloc_type == 7; /* R_KVX_32_PCREL */
aca88567
NC
15274 default:
15275 /* Do not abort or issue an error message here. Not all targets use
15276 pc-relative 32-bit relocs in their DWARF debug information and we
15277 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
15278 more helpful warning message will be generated by apply_relocations
15279 anyway, so just return. */
015dc7e1 15280 return false;
aca88567
NC
15281 }
15282}
15283
15284/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15285 a 64-bit absolute RELA relocation used in DWARF debug sections. */
15286
015dc7e1 15287static bool
dda8d76d 15288is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 15289{
dda8d76d 15290 switch (filedata->file_header.e_machine)
aca88567 15291 {
a06ea964
NC
15292 case EM_AARCH64:
15293 return reloc_type == 257; /* R_AARCH64_ABS64. */
b5c37946
SJ
15294 case EM_ARC_COMPACT3_64:
15295 return reloc_type == 5; /* R_ARC_64. */
aca88567
NC
15296 case EM_ALPHA:
15297 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 15298 case EM_IA_64:
262cdac7
AM
15299 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
15300 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 15301 case EM_LOONGARCH:
15302 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
15303 case EM_PARISC:
15304 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
15305 case EM_PPC64:
15306 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
15307 case EM_RISCV:
15308 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
15309 case EM_SPARC32PLUS:
15310 case EM_SPARCV9:
15311 case EM_SPARC:
714da62f
NC
15312 return reloc_type == 32 /* R_SPARC_64. */
15313 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 15314 case EM_X86_64:
8a9036a4 15315 case EM_L1OM:
7a9068fe 15316 case EM_K1OM:
aca88567 15317 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
15318 case EM_S390_OLD:
15319 case EM_S390:
aa137e4d
NC
15320 return reloc_type == 22; /* R_S390_64. */
15321 case EM_TILEGX:
15322 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 15323 case EM_MIPS:
aa137e4d 15324 return reloc_type == 18; /* R_MIPS_64. */
6e712424
PI
15325 case EM_KVX:
15326 return reloc_type == 3; /* R_KVX_64 */
aca88567 15327 default:
015dc7e1 15328 return false;
aca88567
NC
15329 }
15330}
15331
85acf597
RH
15332/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
15333 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
15334
015dc7e1 15335static bool
dda8d76d 15336is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 15337{
dda8d76d 15338 switch (filedata->file_header.e_machine)
85acf597 15339 {
a06ea964
NC
15340 case EM_AARCH64:
15341 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 15342 case EM_ALPHA:
aa137e4d 15343 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 15344 case EM_IA_64:
262cdac7
AM
15345 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
15346 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 15347 case EM_PARISC:
aa137e4d 15348 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 15349 case EM_PPC64:
aa137e4d 15350 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
15351 case EM_SPARC32PLUS:
15352 case EM_SPARCV9:
15353 case EM_SPARC:
aa137e4d 15354 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 15355 case EM_X86_64:
8a9036a4 15356 case EM_L1OM:
7a9068fe 15357 case EM_K1OM:
aa137e4d 15358 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
15359 case EM_S390_OLD:
15360 case EM_S390:
aa137e4d
NC
15361 return reloc_type == 23; /* R_S390_PC64. */
15362 case EM_TILEGX:
15363 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 15364 default:
015dc7e1 15365 return false;
85acf597
RH
15366 }
15367}
15368
4dc3c23d
AM
15369/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15370 a 24-bit absolute RELA relocation used in DWARF debug sections. */
15371
015dc7e1 15372static bool
dda8d76d 15373is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 15374{
dda8d76d 15375 switch (filedata->file_header.e_machine)
4dc3c23d
AM
15376 {
15377 case EM_CYGNUS_MN10200:
15378 case EM_MN10200:
15379 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
15380 case EM_FT32:
15381 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
15382 case EM_Z80:
15383 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 15384 default:
015dc7e1 15385 return false;
4dc3c23d
AM
15386 }
15387}
15388
aca88567
NC
15389/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15390 a 16-bit absolute RELA relocation used in DWARF debug sections. */
15391
015dc7e1 15392static bool
dda8d76d 15393is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 15394{
d347c9df 15395 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 15396 switch (filedata->file_header.e_machine)
4b78141a 15397 {
886a2506
NC
15398 case EM_ARC:
15399 case EM_ARC_COMPACT:
15400 case EM_ARC_COMPACT2:
b5c37946
SJ
15401 case EM_ARC_COMPACT3:
15402 case EM_ARC_COMPACT3_64:
886a2506 15403 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
15404 case EM_ADAPTEVA_EPIPHANY:
15405 return reloc_type == 5;
aca88567
NC
15406 case EM_AVR_OLD:
15407 case EM_AVR:
15408 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
15409 case EM_CYGNUS_D10V:
15410 case EM_D10V:
15411 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
15412 case EM_FT32:
15413 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
15414 case EM_H8S:
15415 case EM_H8_300:
15416 case EM_H8_300H:
aca88567
NC
15417 return reloc_type == R_H8_DIR16;
15418 case EM_IP2K_OLD:
15419 case EM_IP2K:
15420 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 15421 case EM_M32C_OLD:
f4236fe4
DD
15422 case EM_M32C:
15423 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
15424 case EM_CYGNUS_MN10200:
15425 case EM_MN10200:
15426 return reloc_type == 2; /* R_MN10200_16. */
15427 case EM_CYGNUS_MN10300:
15428 case EM_MN10300:
15429 return reloc_type == 2; /* R_MN10300_16. */
6e712424
PI
15430 case EM_KVX:
15431 return reloc_type == 1; /* R_KVX_16 */
aca88567 15432 case EM_MSP430:
dda8d76d 15433 if (uses_msp430x_relocs (filedata))
13761a11 15434 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 15435 /* Fall through. */
78c8d46c 15436 case EM_MSP430_OLD:
aca88567 15437 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157 15438 case EM_NDS32:
81c5e376 15439 return reloc_type == 19; /* R_NDS32_16_RELA. */
3e0873ac 15440 case EM_ALTERA_NIOS2:
36591ba1 15441 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
15442 case EM_NIOS32:
15443 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
15444 case EM_OR1K:
15445 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
15446 case EM_RISCV:
15447 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
15448 case EM_TI_PRU:
15449 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
15450 case EM_TI_C6000:
15451 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
15452 case EM_VISIUM:
15453 return reloc_type == 2; /* R_VISIUM_16. */
f6c1a2d5
NC
15454 case EM_XGATE:
15455 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
15456 case EM_Z80:
15457 return reloc_type == 4; /* R_Z80_16. */
4b78141a 15458 default:
015dc7e1 15459 return false;
4b78141a
NC
15460 }
15461}
15462
39e07931
AS
15463/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15464 a 8-bit absolute RELA relocation used in DWARF debug sections. */
15465
015dc7e1 15466static bool
39e07931
AS
15467is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15468{
15469 switch (filedata->file_header.e_machine)
15470 {
15471 case EM_RISCV:
15472 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
15473 case EM_Z80:
15474 return reloc_type == 1; /* R_Z80_8. */
d6053747
NF
15475 case EM_MICROBLAZE:
15476 return (reloc_type == 33 /* R_MICROBLAZE_32_NONE. */
15477 || reloc_type == 0 /* R_MICROBLAZE_NONE. */
15478 || reloc_type == 9 /* R_MICROBLAZE_64_NONE. */);
39e07931 15479 default:
015dc7e1 15480 return false;
39e07931
AS
15481 }
15482}
15483
15484/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15485 a 6-bit absolute RELA relocation used in DWARF debug sections. */
15486
015dc7e1 15487static bool
39e07931
AS
15488is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
15489{
15490 switch (filedata->file_header.e_machine)
15491 {
15492 case EM_RISCV:
15493 return reloc_type == 53; /* R_RISCV_SET6. */
15494 default:
015dc7e1 15495 return false;
39e07931
AS
15496 }
15497}
15498
03336641
JW
15499/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15500 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
15501
015dc7e1 15502static bool
03336641
JW
15503is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15504{
15505 /* Please keep this table alpha-sorted for ease of visual lookup. */
15506 switch (filedata->file_header.e_machine)
15507 {
76244462 15508 case EM_LOONGARCH:
15509 return reloc_type == 50; /* R_LARCH_ADD32. */
03336641
JW
15510 case EM_RISCV:
15511 return reloc_type == 35; /* R_RISCV_ADD32. */
15512 default:
015dc7e1 15513 return false;
03336641
JW
15514 }
15515}
15516
15517/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15518 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
15519
015dc7e1 15520static bool
03336641
JW
15521is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15522{
15523 /* Please keep this table alpha-sorted for ease of visual lookup. */
15524 switch (filedata->file_header.e_machine)
15525 {
76244462 15526 case EM_LOONGARCH:
15527 return reloc_type == 55; /* R_LARCH_SUB32. */
03336641
JW
15528 case EM_RISCV:
15529 return reloc_type == 39; /* R_RISCV_SUB32. */
15530 default:
015dc7e1 15531 return false;
03336641
JW
15532 }
15533}
15534
15535/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15536 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
15537
015dc7e1 15538static bool
03336641
JW
15539is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15540{
15541 /* Please keep this table alpha-sorted for ease of visual lookup. */
15542 switch (filedata->file_header.e_machine)
15543 {
76244462 15544 case EM_LOONGARCH:
15545 return reloc_type == 51; /* R_LARCH_ADD64. */
03336641
JW
15546 case EM_RISCV:
15547 return reloc_type == 36; /* R_RISCV_ADD64. */
15548 default:
015dc7e1 15549 return false;
03336641
JW
15550 }
15551}
15552
15553/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15554 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
15555
015dc7e1 15556static bool
03336641
JW
15557is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15558{
15559 /* Please keep this table alpha-sorted for ease of visual lookup. */
15560 switch (filedata->file_header.e_machine)
15561 {
76244462 15562 case EM_LOONGARCH:
15563 return reloc_type == 56; /* R_LARCH_SUB64. */
03336641
JW
15564 case EM_RISCV:
15565 return reloc_type == 40; /* R_RISCV_SUB64. */
15566 default:
015dc7e1 15567 return false;
03336641
JW
15568 }
15569}
15570
15571/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15572 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
15573
015dc7e1 15574static bool
03336641
JW
15575is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15576{
15577 /* Please keep this table alpha-sorted for ease of visual lookup. */
15578 switch (filedata->file_header.e_machine)
15579 {
76244462 15580 case EM_LOONGARCH:
15581 return reloc_type == 48; /* R_LARCH_ADD16. */
03336641
JW
15582 case EM_RISCV:
15583 return reloc_type == 34; /* R_RISCV_ADD16. */
15584 default:
015dc7e1 15585 return false;
03336641
JW
15586 }
15587}
15588
15589/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15590 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
15591
015dc7e1 15592static bool
03336641
JW
15593is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15594{
15595 /* Please keep this table alpha-sorted for ease of visual lookup. */
15596 switch (filedata->file_header.e_machine)
15597 {
76244462 15598 case EM_LOONGARCH:
15599 return reloc_type == 53; /* R_LARCH_SUB16. */
03336641
JW
15600 case EM_RISCV:
15601 return reloc_type == 38; /* R_RISCV_SUB16. */
15602 default:
015dc7e1 15603 return false;
03336641
JW
15604 }
15605}
15606
15607/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15608 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
15609
015dc7e1 15610static bool
03336641
JW
15611is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15612{
15613 /* Please keep this table alpha-sorted for ease of visual lookup. */
15614 switch (filedata->file_header.e_machine)
15615 {
76244462 15616 case EM_LOONGARCH:
15617 return reloc_type == 47; /* R_LARCH_ADD8. */
03336641
JW
15618 case EM_RISCV:
15619 return reloc_type == 33; /* R_RISCV_ADD8. */
15620 default:
015dc7e1 15621 return false;
03336641
JW
15622 }
15623}
15624
15625/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15626 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
15627
015dc7e1 15628static bool
03336641
JW
15629is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15630{
15631 /* Please keep this table alpha-sorted for ease of visual lookup. */
15632 switch (filedata->file_header.e_machine)
15633 {
76244462 15634 case EM_LOONGARCH:
15635 return reloc_type == 52; /* R_LARCH_SUB8. */
03336641
JW
15636 case EM_RISCV:
15637 return reloc_type == 37; /* R_RISCV_SUB8. */
15638 default:
015dc7e1 15639 return false;
03336641
JW
15640 }
15641}
15642
76244462 15643/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15644 a 6-bit inplace add RELA relocation used in DWARF debug sections. */
15645
15646static bool
15647is_6bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
15648{
15649 switch (filedata->file_header.e_machine)
15650 {
15651 case EM_LOONGARCH:
15652 return reloc_type == 105; /* R_LARCH_ADD6. */
15653 default:
15654 return false;
15655 }
15656}
15657
39e07931
AS
15658/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
15659 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
15660
015dc7e1 15661static bool
39e07931
AS
15662is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
15663{
15664 switch (filedata->file_header.e_machine)
15665 {
76244462 15666 case EM_LOONGARCH:
15667 return reloc_type == 106; /* R_LARCH_SUB6. */
39e07931
AS
15668 case EM_RISCV:
15669 return reloc_type == 52; /* R_RISCV_SUB6. */
15670 default:
015dc7e1 15671 return false;
39e07931
AS
15672 }
15673}
15674
2a7b2e88
JK
15675/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
15676 relocation entries (possibly formerly used for SHT_GROUP sections). */
15677
015dc7e1 15678static bool
dda8d76d 15679is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 15680{
dda8d76d 15681 switch (filedata->file_header.e_machine)
2a7b2e88 15682 {
cb8f3167 15683 case EM_386: /* R_386_NONE. */
d347c9df 15684 case EM_68K: /* R_68K_NONE. */
cfb8c092 15685 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
15686 case EM_ALPHA: /* R_ALPHA_NONE. */
15687 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 15688 case EM_ARC: /* R_ARC_NONE. */
886a2506 15689 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 15690 case EM_ARC_COMPACT: /* R_ARC_NONE. */
b5c37946
SJ
15691 case EM_ARC_COMPACT3: /* R_ARC_NONE. */
15692 case EM_ARC_COMPACT3_64: /* R_ARC_NONE. */
cb8f3167 15693 case EM_ARM: /* R_ARM_NONE. */
cb8f3167 15694 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
15695 case EM_FT32: /* R_FT32_NONE. */
15696 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 15697 case EM_K1OM: /* R_X86_64_NONE. */
6e712424 15698 case EM_KVX: /* R_KVX_NONE. */
d347c9df
PS
15699 case EM_L1OM: /* R_X86_64_NONE. */
15700 case EM_M32R: /* R_M32R_NONE. */
15701 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 15702 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 15703 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
15704 case EM_NIOS32: /* R_NIOS_NONE. */
15705 case EM_OR1K: /* R_OR1K_NONE. */
15706 case EM_PARISC: /* R_PARISC_NONE. */
15707 case EM_PPC64: /* R_PPC64_NONE. */
15708 case EM_PPC: /* R_PPC_NONE. */
e23eba97 15709 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
15710 case EM_S390: /* R_390_NONE. */
15711 case EM_S390_OLD:
15712 case EM_SH: /* R_SH_NONE. */
15713 case EM_SPARC32PLUS:
15714 case EM_SPARC: /* R_SPARC_NONE. */
15715 case EM_SPARCV9:
aa137e4d
NC
15716 case EM_TILEGX: /* R_TILEGX_NONE. */
15717 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
15718 case EM_TI_C6000:/* R_C6000_NONE. */
15719 case EM_X86_64: /* R_X86_64_NONE. */
6655dba2 15720 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 15721 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 15722 return reloc_type == 0;
d347c9df 15723
a06ea964
NC
15724 case EM_AARCH64:
15725 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
15726 case EM_AVR_OLD:
15727 case EM_AVR:
15728 return (reloc_type == 0 /* R_AVR_NONE. */
15729 || reloc_type == 30 /* R_AVR_DIFF8. */
15730 || reloc_type == 31 /* R_AVR_DIFF16. */
15731 || reloc_type == 32 /* R_AVR_DIFF32. */);
15732 case EM_METAG:
15733 return reloc_type == 3; /* R_METAG_NONE. */
35c08157 15734 case EM_NDS32:
81c5e376
AM
15735 return (reloc_type == 0 /* R_NDS32_NONE. */
15736 || reloc_type == 205 /* R_NDS32_DIFF8. */
15737 || reloc_type == 206 /* R_NDS32_DIFF16. */
15738 || reloc_type == 207 /* R_NDS32_DIFF32. */
15739 || reloc_type == 208 /* R_NDS32_DIFF_ULEB128. */);
2b100bb5
DD
15740 case EM_TI_PRU:
15741 return (reloc_type == 0 /* R_PRU_NONE. */
15742 || reloc_type == 65 /* R_PRU_DIFF8. */
15743 || reloc_type == 66 /* R_PRU_DIFF16. */
15744 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
15745 case EM_XTENSA_OLD:
15746 case EM_XTENSA:
4dc3c23d
AM
15747 return (reloc_type == 0 /* R_XTENSA_NONE. */
15748 || reloc_type == 17 /* R_XTENSA_DIFF8. */
15749 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
15750 || reloc_type == 19 /* R_XTENSA_DIFF32. */
15751 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
15752 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
15753 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
15754 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
15755 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
15756 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 15757 }
015dc7e1 15758 return false;
2a7b2e88
JK
15759}
15760
d1c4b12b
NC
15761/* Returns TRUE if there is a relocation against
15762 section NAME at OFFSET bytes. */
15763
015dc7e1 15764bool
31e5a3a3 15765reloc_at (struct dwarf_section * dsec, uint64_t offset)
d1c4b12b
NC
15766{
15767 Elf_Internal_Rela * relocs;
15768 Elf_Internal_Rela * rp;
15769
15770 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 15771 return false;
d1c4b12b
NC
15772
15773 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
15774
15775 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
15776 if (rp->r_offset == offset)
015dc7e1 15777 return true;
d1c4b12b 15778
015dc7e1 15779 return false;
d1c4b12b
NC
15780}
15781
cf13d699 15782/* Apply relocations to a section.
32ec8896
NC
15783 Returns TRUE upon success, FALSE otherwise.
15784 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
15785 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
15786 will be set to the number of relocs loaded.
15787
cf13d699 15788 Note: So far support has been added only for those relocations
32ec8896
NC
15789 which can be found in debug sections. FIXME: Add support for
15790 more relocations ? */
1b315056 15791
015dc7e1 15792static bool
be7d229a
AM
15793apply_relocations (Filedata *filedata,
15794 const Elf_Internal_Shdr *section,
15795 unsigned char *start,
15796 size_t size,
15797 void **relocs_return,
26c527e6 15798 uint64_t *num_relocs_return)
1b315056 15799{
cf13d699 15800 Elf_Internal_Shdr * relsec;
0d2a7a93 15801 unsigned char * end = start + size;
cb8f3167 15802
d1c4b12b
NC
15803 if (relocs_return != NULL)
15804 {
15805 * (Elf_Internal_Rela **) relocs_return = NULL;
15806 * num_relocs_return = 0;
15807 }
15808
dda8d76d 15809 if (filedata->file_header.e_type != ET_REL)
32ec8896 15810 /* No relocs to apply. */
015dc7e1 15811 return true;
1b315056 15812
cf13d699 15813 /* Find the reloc section associated with the section. */
dda8d76d
NC
15814 for (relsec = filedata->section_headers;
15815 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 15816 ++relsec)
252b5132 15817 {
015dc7e1 15818 bool is_rela;
26c527e6 15819 uint64_t num_relocs;
2cf0635d
NC
15820 Elf_Internal_Rela * relocs;
15821 Elf_Internal_Rela * rp;
15822 Elf_Internal_Shdr * symsec;
15823 Elf_Internal_Sym * symtab;
26c527e6 15824 uint64_t num_syms;
2cf0635d 15825 Elf_Internal_Sym * sym;
252b5132 15826
41e92641 15827 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15828 || relsec->sh_info >= filedata->file_header.e_shnum
15829 || filedata->section_headers + relsec->sh_info != section
c256ffe7 15830 || relsec->sh_size == 0
dda8d76d 15831 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 15832 continue;
428409d5 15833
a788aedd
AM
15834 symsec = filedata->section_headers + relsec->sh_link;
15835 if (symsec->sh_type != SHT_SYMTAB
15836 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 15837 return false;
a788aedd 15838
41e92641
NC
15839 is_rela = relsec->sh_type == SHT_RELA;
15840
15841 if (is_rela)
15842 {
dda8d76d 15843 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 15844 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15845 return false;
41e92641
NC
15846 }
15847 else
15848 {
dda8d76d 15849 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 15850 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 15851 return false;
41e92641
NC
15852 }
15853
15854 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 15855 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 15856 is_rela = false;
428409d5 15857
4de91c10 15858 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 15859
41e92641 15860 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 15861 {
625d49fc 15862 uint64_t addend;
015dc7e1
AM
15863 unsigned int reloc_type;
15864 unsigned int reloc_size;
15865 bool reloc_inplace = false;
15866 bool reloc_subtract = false;
15867 unsigned char *rloc;
26c527e6 15868 uint64_t sym_index;
4b78141a 15869
dda8d76d 15870 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 15871
dda8d76d 15872 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 15873 continue;
dda8d76d 15874 else if (is_none_reloc (filedata, reloc_type))
98fb390a 15875 continue;
dda8d76d
NC
15876 else if (is_32bit_abs_reloc (filedata, reloc_type)
15877 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 15878 reloc_size = 4;
dda8d76d
NC
15879 else if (is_64bit_abs_reloc (filedata, reloc_type)
15880 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 15881 reloc_size = 8;
dda8d76d 15882 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 15883 reloc_size = 3;
dda8d76d 15884 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 15885 reloc_size = 2;
39e07931
AS
15886 else if (is_8bit_abs_reloc (filedata, reloc_type)
15887 || is_6bit_abs_reloc (filedata, reloc_type))
15888 reloc_size = 1;
03336641
JW
15889 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
15890 reloc_type))
15891 || is_32bit_inplace_add_reloc (filedata, reloc_type))
15892 {
15893 reloc_size = 4;
015dc7e1 15894 reloc_inplace = true;
03336641
JW
15895 }
15896 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
15897 reloc_type))
15898 || is_64bit_inplace_add_reloc (filedata, reloc_type))
15899 {
15900 reloc_size = 8;
015dc7e1 15901 reloc_inplace = true;
03336641
JW
15902 }
15903 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
15904 reloc_type))
15905 || is_16bit_inplace_add_reloc (filedata, reloc_type))
15906 {
15907 reloc_size = 2;
015dc7e1 15908 reloc_inplace = true;
03336641
JW
15909 }
15910 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
15911 reloc_type))
15912 || is_8bit_inplace_add_reloc (filedata, reloc_type))
15913 {
15914 reloc_size = 1;
015dc7e1 15915 reloc_inplace = true;
03336641 15916 }
39e07931 15917 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
76244462 15918 reloc_type))
15919 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
15920 {
15921 reloc_size = 1;
015dc7e1 15922 reloc_inplace = true;
39e07931 15923 }
aca88567 15924 else
4b78141a 15925 {
bee0ee85 15926 static unsigned int prev_reloc = 0;
dda8d76d 15927
bee0ee85
NC
15928 if (reloc_type != prev_reloc)
15929 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 15930 reloc_type, printable_section_name (filedata, section));
bee0ee85 15931 prev_reloc = reloc_type;
4b78141a
NC
15932 continue;
15933 }
103f02d3 15934
91d6fa6a 15935 rloc = start + rp->r_offset;
75802ccb 15936 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7 15937 {
26c527e6
AM
15938 warn (_("skipping invalid relocation offset %#" PRIx64
15939 " in section %s\n"),
15940 rp->r_offset,
dda8d76d 15941 printable_section_name (filedata, section));
700dd8b7
L
15942 continue;
15943 }
103f02d3 15944
26c527e6 15945 sym_index = get_reloc_symindex (rp->r_info);
ba5cdace
NC
15946 if (sym_index >= num_syms)
15947 {
26c527e6
AM
15948 warn (_("skipping invalid relocation symbol index %#" PRIx64
15949 " in section %s\n"),
dda8d76d 15950 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
15951 continue;
15952 }
15953 sym = symtab + sym_index;
41e92641
NC
15954
15955 /* If the reloc has a symbol associated with it,
55f25fc3
L
15956 make sure that it is of an appropriate type.
15957
15958 Relocations against symbols without type can happen.
15959 Gcc -feliminate-dwarf2-dups may generate symbols
15960 without type for debug info.
15961
15962 Icc generates relocations against function symbols
15963 instead of local labels.
15964
15965 Relocations against object symbols can happen, eg when
15966 referencing a global array. For an example of this see
15967 the _clz.o binary in libgcc.a. */
aca88567 15968 if (sym != symtab
b8871f35 15969 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 15970 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 15971 {
26c527e6 15972 warn (_("skipping unexpected symbol type %s in section %s relocation %tu\n"),
dda8d76d
NC
15973 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
15974 printable_section_name (filedata, relsec),
26c527e6 15975 rp - relocs);
aca88567 15976 continue;
5b18a4bc 15977 }
252b5132 15978
4dc3c23d
AM
15979 addend = 0;
15980 if (is_rela)
15981 addend += rp->r_addend;
c47320c3
AM
15982 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
15983 partial_inplace. */
4dc3c23d 15984 if (!is_rela
dda8d76d 15985 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 15986 && reloc_type == 1)
dda8d76d
NC
15987 || ((filedata->file_header.e_machine == EM_PJ
15988 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 15989 && reloc_type == 1)
dda8d76d
NC
15990 || ((filedata->file_header.e_machine == EM_D30V
15991 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
15992 && reloc_type == 12)
15993 || reloc_inplace)
39e07931
AS
15994 {
15995 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
15996 addend += byte_get (rloc, reloc_size) & 0x3f;
15997 else
15998 addend += byte_get (rloc, reloc_size);
15999 }
cb8f3167 16000
dda8d76d
NC
16001 if (is_32bit_pcrel_reloc (filedata, reloc_type)
16002 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
16003 {
16004 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 16005 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 16006 addend -= 8;
91d6fa6a 16007 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
16008 reloc_size);
16009 }
39e07931 16010 else if (is_6bit_abs_reloc (filedata, reloc_type)
76244462 16011 || is_6bit_inplace_sub_reloc (filedata, reloc_type)
16012 || is_6bit_inplace_add_reloc (filedata, reloc_type))
39e07931
AS
16013 {
16014 if (reloc_subtract)
16015 addend -= sym->st_value;
16016 else
16017 addend += sym->st_value;
16018 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
16019 byte_put (rloc, addend, reloc_size);
16020 }
03336641
JW
16021 else if (reloc_subtract)
16022 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 16023 else
91d6fa6a 16024 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 16025 }
252b5132 16026
5b18a4bc 16027 free (symtab);
f84ce13b
NC
16028 /* Let the target specific reloc processing code know that
16029 we have finished with these relocs. */
dda8d76d 16030 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
16031
16032 if (relocs_return)
16033 {
16034 * (Elf_Internal_Rela **) relocs_return = relocs;
16035 * num_relocs_return = num_relocs;
16036 }
16037 else
16038 free (relocs);
16039
5b18a4bc
NC
16040 break;
16041 }
32ec8896 16042
015dc7e1 16043 return true;
5b18a4bc 16044}
103f02d3 16045
cf13d699 16046#ifdef SUPPORT_DISASSEMBLY
015dc7e1 16047static bool
dda8d76d 16048disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16049{
dda8d76d 16050 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 16051
74e1a04b 16052 /* FIXME: XXX -- to be done --- XXX */
cf13d699 16053
015dc7e1 16054 return true;
cf13d699
NC
16055}
16056#endif
16057
16058/* Reads in the contents of SECTION from FILE, returning a pointer
16059 to a malloc'ed buffer or NULL if something went wrong. */
16060
16061static char *
dda8d76d 16062get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 16063{
be7d229a 16064 uint64_t num_bytes = section->sh_size;
cf13d699
NC
16065
16066 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
16067 {
c6b78c96 16068 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 16069 printable_section_name (filedata, section));
cf13d699
NC
16070 return NULL;
16071 }
16072
dda8d76d 16073 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 16074 _("section contents"));
cf13d699
NC
16075}
16076
1f5a3546 16077/* Uncompresses a section that was compressed using zlib/zstd, in place. */
0e602686 16078
015dc7e1 16079static bool
45f5fe46
NC
16080uncompress_section_contents (bool is_zstd,
16081 unsigned char ** buffer,
16082 uint64_t uncompressed_size,
16083 uint64_t * size,
16084 uint64_t file_size)
0e602686 16085{
31e5a3a3
AM
16086 uint64_t compressed_size = *size;
16087 unsigned char *compressed_buffer = *buffer;
45f5fe46 16088 unsigned char *uncompressed_buffer = NULL;
0e602686
NC
16089 z_stream strm;
16090 int rc;
16091
f9ee45c3 16092 /* Similar to bfd_section_size_insane() in the BFD library we expect an
45f5fe46
NC
16093 upper limit of ~10x compression. Any compression larger than that is
16094 thought to be due to fuzzing of the compression header. */
16095 if (uncompressed_size > file_size * 10)
16096 {
16097 error (_("Uncompressed section size is suspiciously large: 0x%" PRIu64 "\n"),
16098 uncompressed_size);
16099 goto fail;
16100 }
16101
16102 uncompressed_buffer = xmalloc (uncompressed_size);
16103
1f5a3546
FS
16104 if (is_zstd)
16105 {
16106#ifdef HAVE_ZSTD
16107 size_t ret = ZSTD_decompress (uncompressed_buffer, uncompressed_size,
16108 compressed_buffer, compressed_size);
16109 if (ZSTD_isError (ret))
16110 goto fail;
16111#endif
16112 }
16113 else
16114 {
16115 /* It is possible the section consists of several compressed
16116 buffers concatenated together, so we uncompress in a loop. */
16117 /* PR 18313: The state field in the z_stream structure is supposed
16118 to be invisible to the user (ie us), but some compilers will
16119 still complain about it being used without initialisation. So
16120 we first zero the entire z_stream structure and then set the fields
16121 that we need. */
16122 memset (&strm, 0, sizeof strm);
16123 strm.avail_in = compressed_size;
16124 strm.next_in = (Bytef *)compressed_buffer;
16125 strm.avail_out = uncompressed_size;
16126
16127 rc = inflateInit (&strm);
16128 while (strm.avail_in > 0)
16129 {
16130 if (rc != Z_OK)
16131 break;
16132 strm.next_out = ((Bytef *)uncompressed_buffer
16133 + (uncompressed_size - strm.avail_out));
16134 rc = inflate (&strm, Z_FINISH);
16135 if (rc != Z_STREAM_END)
16136 break;
16137 rc = inflateReset (&strm);
16138 }
16139 if (inflateEnd (&strm) != Z_OK || rc != Z_OK || strm.avail_out != 0)
16140 goto fail;
16141 }
0e602686
NC
16142
16143 *buffer = uncompressed_buffer;
16144 *size = uncompressed_size;
015dc7e1 16145 return true;
0e602686
NC
16146
16147 fail:
16148 free (uncompressed_buffer);
16149 /* Indicate decompression failure. */
16150 *buffer = NULL;
015dc7e1 16151 return false;
0e602686 16152}
dd24e3da 16153
fab62191
NC
16154static uint64_t
16155maybe_expand_or_relocate_section (Elf_Internal_Shdr * section,
16156 Filedata * filedata,
16157 unsigned char ** start_ptr,
16158 bool relocate)
cf13d699 16159{
fab62191
NC
16160 uint64_t section_size = section->sh_size;
16161 unsigned char * start = * start_ptr;
16162
0e602686
NC
16163 if (decompress_dumps)
16164 {
fab62191 16165 uint64_t new_size = section_size;
31e5a3a3 16166 uint64_t uncompressed_size = 0;
1f5a3546 16167 bool is_zstd = false;
0e602686
NC
16168
16169 if ((section->sh_flags & SHF_COMPRESSED) != 0)
16170 {
16171 Elf_Internal_Chdr chdr;
16172 unsigned int compression_header_size
fab62191
NC
16173 = get_compression_header (& chdr, start, section_size);
16174
5844b465
NC
16175 if (compression_header_size == 0)
16176 /* An error message will have already been generated
16177 by get_compression_header. */
fab62191 16178 return (uint64_t) -1;
0e602686 16179
89dbeac7 16180 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16181 ;
16182#ifdef HAVE_ZSTD
89dbeac7 16183 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16184 is_zstd = true;
16185#endif
16186 else
0e602686 16187 {
813dabb9 16188 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 16189 printable_section_name (filedata, section), chdr.ch_type);
fab62191 16190 return (uint64_t) -1;
813dabb9 16191 }
fab62191 16192
813dabb9
L
16193 uncompressed_size = chdr.ch_size;
16194 start += compression_header_size;
16195 new_size -= compression_header_size;
0e602686
NC
16196 }
16197 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
16198 {
16199 /* Read the zlib header. In this case, it should be "ZLIB"
16200 followed by the uncompressed section size, 8 bytes in
16201 big-endian order. */
16202 uncompressed_size = start[4]; uncompressed_size <<= 8;
16203 uncompressed_size += start[5]; uncompressed_size <<= 8;
16204 uncompressed_size += start[6]; uncompressed_size <<= 8;
16205 uncompressed_size += start[7]; uncompressed_size <<= 8;
16206 uncompressed_size += start[8]; uncompressed_size <<= 8;
16207 uncompressed_size += start[9]; uncompressed_size <<= 8;
16208 uncompressed_size += start[10]; uncompressed_size <<= 8;
16209 uncompressed_size += start[11];
16210 start += 12;
16211 new_size -= 12;
16212 }
16213
1835f746
NC
16214 if (uncompressed_size)
16215 {
1f5a3546 16216 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16217 &new_size, filedata->file_size))
fab62191 16218 section_size = new_size;
1835f746
NC
16219 else
16220 {
16221 error (_("Unable to decompress section %s\n"),
dda8d76d 16222 printable_section_name (filedata, section));
fab62191 16223 return (uint64_t) -1;
1835f746
NC
16224 }
16225 }
bc303e5d 16226 else
fab62191
NC
16227 start = * start_ptr;
16228 }
16229 else if (((section->sh_flags & SHF_COMPRESSED) != 0)
16230 || (section_size > 12 && streq ((char *) start, "ZLIB")))
16231 {
16232 printf (_(" NOTE: This section is compressed, but its contents have NOT been expanded for this dump.\n"));
0e602686 16233 }
fd8008d8 16234
fab62191 16235 if (relocate)
cf13d699 16236 {
fab62191
NC
16237 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
16238 return (uint64_t) -1;
16239 }
16240 else
16241 {
16242 Elf_Internal_Shdr *relsec;
cf13d699 16243
fab62191
NC
16244 /* If the section being dumped has relocations against it the user might
16245 be expecting these relocations to have been applied. Check for this
16246 case and issue a warning message in order to avoid confusion.
16247 FIXME: Maybe we ought to have an option that dumps a section with
16248 relocs applied ? */
16249 for (relsec = filedata->section_headers;
16250 relsec < filedata->section_headers + filedata->file_header.e_shnum;
16251 ++relsec)
16252 {
16253 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
16254 || relsec->sh_info >= filedata->file_header.e_shnum
16255 || filedata->section_headers + relsec->sh_info != section
16256 || relsec->sh_size == 0
16257 || relsec->sh_link >= filedata->file_header.e_shnum)
16258 continue;
16259
16260 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
16261 break;
16262 }
cf13d699
NC
16263 }
16264
fab62191
NC
16265 * start_ptr = start;
16266 return section_size;
16267}
16268
16269static bool
16270dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
16271{
16272 uint64_t num_bytes;
16273 unsigned char *data;
16274 unsigned char *end;
16275 unsigned char *real_start;
16276 unsigned char *start;
16277 bool some_strings_shown;
16278
16279 real_start = start = (unsigned char *) get_section_contents (section, filedata);
16280 if (start == NULL)
16281 /* PR 21820: Do not fail if the section was empty. */
16282 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
16283
16284 num_bytes = section->sh_size;
16285
16286 if (filedata->is_separate)
16287 printf (_("\nString dump of section '%s' in linked file %s:\n"),
16288 printable_section_name (filedata, section),
16289 filedata->file_name);
16290 else
16291 printf (_("\nString dump of section '%s':\n"),
16292 printable_section_name (filedata, section));
16293
16294 num_bytes = maybe_expand_or_relocate_section (section, filedata, & start, false);
16295 if (num_bytes == (uint64_t) -1)
16296 goto error_out;
16297
cf13d699
NC
16298 data = start;
16299 end = start + num_bytes;
015dc7e1 16300 some_strings_shown = false;
cf13d699 16301
ba3265d0
NC
16302#ifdef HAVE_MBSTATE_T
16303 mbstate_t state;
16304 /* Initialise the multibyte conversion state. */
16305 memset (& state, 0, sizeof (state));
16306#endif
16307
015dc7e1 16308 bool continuing = false;
ba3265d0 16309
cf13d699
NC
16310 while (data < end)
16311 {
16312 while (!ISPRINT (* data))
16313 if (++ data >= end)
16314 break;
16315
16316 if (data < end)
16317 {
071436c6
NC
16318 size_t maxlen = end - data;
16319
ba3265d0
NC
16320 if (continuing)
16321 {
16322 printf (" ");
015dc7e1 16323 continuing = false;
ba3265d0
NC
16324 }
16325 else
16326 {
26c527e6 16327 printf (" [%6tx] ", data - start);
ba3265d0
NC
16328 }
16329
4082ef84
NC
16330 if (maxlen > 0)
16331 {
f3da8a96 16332 char c = 0;
ba3265d0
NC
16333
16334 while (maxlen)
16335 {
16336 c = *data++;
16337
16338 if (c == 0)
16339 break;
16340
16341 /* PR 25543: Treat new-lines as string-ending characters. */
16342 if (c == '\n')
16343 {
16344 printf ("\\n\n");
16345 if (*data != 0)
015dc7e1 16346 continuing = true;
ba3265d0
NC
16347 break;
16348 }
16349
16350 /* Do not print control characters directly as they can affect terminal
16351 settings. Such characters usually appear in the names generated
16352 by the assembler for local labels. */
16353 if (ISCNTRL (c))
16354 {
16355 printf ("^%c", c + 0x40);
16356 }
16357 else if (ISPRINT (c))
16358 {
16359 putchar (c);
16360 }
16361 else
16362 {
16363 size_t n;
16364#ifdef HAVE_MBSTATE_T
16365 wchar_t w;
16366#endif
16367 /* Let printf do the hard work of displaying multibyte characters. */
16368 printf ("%.1s", data - 1);
16369#ifdef HAVE_MBSTATE_T
16370 /* Try to find out how many bytes made up the character that was
16371 just printed. Advance the symbol pointer past the bytes that
16372 were displayed. */
16373 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
16374#else
16375 n = 1;
16376#endif
16377 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
16378 data += (n - 1);
16379 }
16380 }
16381
16382 if (c != '\n')
16383 putchar ('\n');
4082ef84
NC
16384 }
16385 else
16386 {
16387 printf (_("<corrupt>\n"));
16388 data = end;
16389 }
015dc7e1 16390 some_strings_shown = true;
cf13d699
NC
16391 }
16392 }
16393
16394 if (! some_strings_shown)
16395 printf (_(" No strings found in this section."));
16396
0e602686 16397 free (real_start);
cf13d699
NC
16398
16399 putchar ('\n');
015dc7e1 16400 return true;
f761cb13
AM
16401
16402error_out:
16403 free (real_start);
015dc7e1 16404 return false;
cf13d699
NC
16405}
16406
015dc7e1
AM
16407static bool
16408dump_section_as_bytes (Elf_Internal_Shdr *section,
16409 Filedata *filedata,
16410 bool relocate)
cf13d699 16411{
be7d229a
AM
16412 size_t bytes;
16413 uint64_t section_size;
625d49fc 16414 uint64_t addr;
be7d229a
AM
16415 unsigned char *data;
16416 unsigned char *real_start;
16417 unsigned char *start;
0e602686 16418
dda8d76d 16419 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 16420 if (start == NULL)
c6b78c96 16421 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 16422 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 16423
0e602686 16424 section_size = section->sh_size;
cf13d699 16425
835f2fae
NC
16426 if (filedata->is_separate)
16427 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
16428 printable_section_name (filedata, section),
16429 filedata->file_name);
16430 else
16431 printf (_("\nHex dump of section '%s':\n"),
16432 printable_section_name (filedata, section));
cf13d699 16433
fab62191
NC
16434 section_size = maybe_expand_or_relocate_section (section, filedata, & start, relocate);
16435 if (section_size == (uint64_t) -1)
16436 goto error_out;
cf13d699
NC
16437
16438 addr = section->sh_addr;
0e602686 16439 bytes = section_size;
cf13d699
NC
16440 data = start;
16441
16442 while (bytes)
16443 {
16444 int j;
16445 int k;
16446 int lbytes;
16447
16448 lbytes = (bytes > 16 ? 16 : bytes);
16449
26c527e6 16450 printf (" 0x%8.8" PRIx64 " ", addr);
cf13d699
NC
16451
16452 for (j = 0; j < 16; j++)
16453 {
16454 if (j < lbytes)
16455 printf ("%2.2x", data[j]);
16456 else
16457 printf (" ");
16458
16459 if ((j & 3) == 3)
16460 printf (" ");
16461 }
16462
16463 for (j = 0; j < lbytes; j++)
16464 {
16465 k = data[j];
16466 if (k >= ' ' && k < 0x7f)
16467 printf ("%c", k);
16468 else
16469 printf (".");
16470 }
16471
16472 putchar ('\n');
16473
16474 data += lbytes;
16475 addr += lbytes;
16476 bytes -= lbytes;
16477 }
16478
0e602686 16479 free (real_start);
cf13d699
NC
16480
16481 putchar ('\n');
015dc7e1 16482 return true;
f761cb13
AM
16483
16484 error_out:
16485 free (real_start);
015dc7e1 16486 return false;
cf13d699
NC
16487}
16488
094e34f2 16489#ifdef ENABLE_LIBCTF
7d9813f1
NA
16490static ctf_sect_t *
16491shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
16492{
b6ac461a 16493 buf->cts_name = printable_section_name (filedata, shdr);
7d9813f1
NA
16494 buf->cts_size = shdr->sh_size;
16495 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
16496
16497 return buf;
16498}
16499
16500/* Formatting callback function passed to ctf_dump. Returns either the pointer
16501 it is passed, or a pointer to newly-allocated storage, in which case
16502 dump_ctf() will free it when it no longer needs it. */
16503
2f6ecaed
NA
16504static char *
16505dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
16506 char *s, void *arg)
7d9813f1 16507{
3e50a591 16508 const char *blanks = arg;
7d9813f1
NA
16509 char *new_s;
16510
3e50a591 16511 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
16512 return s;
16513 return new_s;
16514}
16515
926c9e76
NA
16516/* Dump CTF errors/warnings. */
16517static void
139633c3 16518dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
16519{
16520 ctf_next_t *it = NULL;
16521 char *errtext;
16522 int is_warning;
16523 int err;
16524
16525 /* Dump accumulated errors and warnings. */
16526 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
16527 {
5e9b84f7 16528 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
16529 errtext);
16530 free (errtext);
16531 }
16532 if (err != ECTF_NEXT_END)
16533 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
16534}
16535
2f6ecaed
NA
16536/* Dump one CTF archive member. */
16537
80b56fad
NA
16538static void
16539dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
16540 size_t member)
2f6ecaed 16541{
2f6ecaed
NA
16542 const char *things[] = {"Header", "Labels", "Data objects",
16543 "Function objects", "Variables", "Types", "Strings",
16544 ""};
16545 const char **thing;
16546 size_t i;
16547
80b56fad
NA
16548 /* Don't print out the name of the default-named archive member if it appears
16549 first in the list. The name .ctf appears everywhere, even for things that
16550 aren't really archives, so printing it out is liable to be confusing; also,
16551 the common case by far is for only one archive member to exist, and hiding
16552 it in that case seems worthwhile. */
2f6ecaed 16553
80b56fad
NA
16554 if (strcmp (name, ".ctf") != 0 || member != 0)
16555 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 16556
80b56fad
NA
16557 if (ctf_parent_name (ctf) != NULL)
16558 ctf_import (ctf, parent);
2f6ecaed
NA
16559
16560 for (i = 0, thing = things; *thing[0]; thing++, i++)
16561 {
16562 ctf_dump_state_t *s = NULL;
16563 char *item;
16564
16565 printf ("\n %s:\n", *thing);
16566 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
16567 (void *) " ")) != NULL)
16568 {
16569 printf ("%s\n", item);
16570 free (item);
16571 }
16572
16573 if (ctf_errno (ctf))
16574 {
16575 error (_("Iteration failed: %s, %s\n"), *thing,
16576 ctf_errmsg (ctf_errno (ctf)));
80b56fad 16577 break;
2f6ecaed
NA
16578 }
16579 }
8b37e7b6 16580
926c9e76 16581 dump_ctf_errs (ctf);
2f6ecaed
NA
16582}
16583
015dc7e1 16584static bool
7d9813f1
NA
16585dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
16586{
7d9813f1
NA
16587 Elf_Internal_Shdr * symtab_sec = NULL;
16588 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
16589 void * data = NULL;
16590 void * symdata = NULL;
16591 void * strdata = NULL;
80b56fad 16592 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
16593 ctf_sect_t * symsectp = NULL;
16594 ctf_sect_t * strsectp = NULL;
2f6ecaed 16595 ctf_archive_t * ctfa = NULL;
139633c3 16596 ctf_dict_t * parent = NULL;
80b56fad 16597 ctf_dict_t * fp;
7d9813f1 16598
80b56fad
NA
16599 ctf_next_t *i = NULL;
16600 const char *name;
16601 size_t member = 0;
7d9813f1 16602 int err;
015dc7e1 16603 bool ret = false;
7d9813f1
NA
16604
16605 shdr_to_ctf_sect (&ctfsect, section, filedata);
16606 data = get_section_contents (section, filedata);
16607 ctfsect.cts_data = data;
16608
616febde 16609 if (!dump_ctf_symtab_name)
3d16b64e 16610 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
16611
16612 if (!dump_ctf_strtab_name)
3d16b64e 16613 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
16614
16615 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
16616 {
16617 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
16618 {
16619 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
16620 goto fail;
16621 }
16622 if ((symdata = (void *) get_data (NULL, filedata,
16623 symtab_sec->sh_offset, 1,
16624 symtab_sec->sh_size,
16625 _("symbols"))) == NULL)
16626 goto fail;
16627 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
16628 symsect.cts_data = symdata;
16629 }
835f2fae 16630
df16e041 16631 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
16632 {
16633 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
16634 {
16635 error (_("No string table section named %s\n"),
16636 dump_ctf_strtab_name);
16637 goto fail;
16638 }
16639 if ((strdata = (void *) get_data (NULL, filedata,
16640 strtab_sec->sh_offset, 1,
16641 strtab_sec->sh_size,
16642 _("strings"))) == NULL)
16643 goto fail;
16644 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
16645 strsect.cts_data = strdata;
16646 }
835f2fae 16647
2f6ecaed
NA
16648 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
16649 libctf papers over the difference, so we can pretend it is always an
80b56fad 16650 archive. */
7d9813f1 16651
2f6ecaed 16652 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 16653 {
926c9e76 16654 dump_ctf_errs (NULL);
7d9813f1
NA
16655 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16656 goto fail;
16657 }
16658
96c61be5
NA
16659 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
16660 != ELFDATA2MSB);
16661
80b56fad
NA
16662 /* Preload the parent dict, since it will need to be imported into every
16663 child in turn. */
16664 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 16665 {
926c9e76 16666 dump_ctf_errs (NULL);
2f6ecaed
NA
16667 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
16668 goto fail;
7d9813f1
NA
16669 }
16670
015dc7e1 16671 ret = true;
7d9813f1 16672
835f2fae
NC
16673 if (filedata->is_separate)
16674 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
16675 printable_section_name (filedata, section),
16676 filedata->file_name);
16677 else
16678 printf (_("\nDump of CTF section '%s':\n"),
16679 printable_section_name (filedata, section));
7d9813f1 16680
80b56fad
NA
16681 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
16682 dump_ctf_archive_member (fp, name, parent, member++);
16683 if (err != ECTF_NEXT_END)
16684 {
16685 dump_ctf_errs (NULL);
16686 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
16687 ret = false;
16688 }
7d9813f1
NA
16689
16690 fail:
139633c3 16691 ctf_dict_close (parent);
2f6ecaed 16692 ctf_close (ctfa);
7d9813f1
NA
16693 free (data);
16694 free (symdata);
16695 free (strdata);
16696 return ret;
16697}
094e34f2 16698#endif
7d9813f1 16699
42b6953b
IB
16700static bool
16701dump_section_as_sframe (Elf_Internal_Shdr * section, Filedata * filedata)
16702{
16703 void * data = NULL;
16704 sframe_decoder_ctx *sfd_ctx = NULL;
16705 const char *print_name = printable_section_name (filedata, section);
16706
16707 bool ret = true;
16708 size_t sf_size;
16709 int err = 0;
16710
16711 if (strcmp (print_name, "") == 0)
16712 {
16713 error (_("Section name must be provided \n"));
16714 ret = false;
16715 return ret;
16716 }
16717
16718 data = get_section_contents (section, filedata);
16719 sf_size = section->sh_size;
16720 /* Decode the contents of the section. */
16721 sfd_ctx = sframe_decode ((const char*)data, sf_size, &err);
16722 if (!sfd_ctx)
16723 {
16724 ret = false;
16725 error (_("SFrame decode failure: %s\n"), sframe_errmsg (err));
16726 goto fail;
16727 }
16728
16729 printf (_("Contents of the SFrame section %s:"), print_name);
16730 /* Dump the contents as text. */
16731 dump_sframe (sfd_ctx, section->sh_addr);
16732
16733 fail:
16734 free (data);
16735 return ret;
16736}
16737
015dc7e1 16738static bool
dda8d76d
NC
16739load_specific_debug_section (enum dwarf_section_display_enum debug,
16740 const Elf_Internal_Shdr * sec,
16741 void * data)
1007acb3 16742{
2cf0635d 16743 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 16744 char buf [64];
dda8d76d 16745 Filedata * filedata = (Filedata *) data;
9abca702 16746
19e6b90e 16747 if (section->start != NULL)
dda8d76d
NC
16748 {
16749 /* If it is already loaded, do nothing. */
16750 if (streq (section->filename, filedata->file_name))
015dc7e1 16751 return true;
dda8d76d
NC
16752 free (section->start);
16753 }
1007acb3 16754
19e6b90e
L
16755 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
16756 section->address = sec->sh_addr;
dda8d76d
NC
16757 section->filename = filedata->file_name;
16758 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
16759 sec->sh_offset, 1,
16760 sec->sh_size, buf);
59245841
NC
16761 if (section->start == NULL)
16762 section->size = 0;
16763 else
16764 {
77115a4a 16765 unsigned char *start = section->start;
31e5a3a3
AM
16766 uint64_t size = sec->sh_size;
16767 uint64_t uncompressed_size = 0;
1f5a3546 16768 bool is_zstd = false;
77115a4a
L
16769
16770 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
16771 {
16772 Elf_Internal_Chdr chdr;
d8024a91
NC
16773 unsigned int compression_header_size;
16774
f53be977
L
16775 if (size < (is_32bit_elf
16776 ? sizeof (Elf32_External_Chdr)
16777 : sizeof (Elf64_External_Chdr)))
d8024a91 16778 {
55be8fd0 16779 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 16780 section->name);
015dc7e1 16781 return false;
d8024a91
NC
16782 }
16783
ebdf1ebf 16784 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
16785 if (compression_header_size == 0)
16786 /* An error message will have already been generated
16787 by get_compression_header. */
015dc7e1 16788 return false;
d8024a91 16789
89dbeac7 16790 if (chdr.ch_type == ch_compress_zlib)
1f5a3546
FS
16791 ;
16792#ifdef HAVE_ZSTD
89dbeac7 16793 else if (chdr.ch_type == ch_compress_zstd)
1f5a3546
FS
16794 is_zstd = true;
16795#endif
16796 else
813dabb9
L
16797 {
16798 warn (_("section '%s' has unsupported compress type: %d\n"),
16799 section->name, chdr.ch_type);
015dc7e1 16800 return false;
813dabb9 16801 }
dab394de 16802 uncompressed_size = chdr.ch_size;
77115a4a
L
16803 start += compression_header_size;
16804 size -= compression_header_size;
16805 }
dab394de
L
16806 else if (size > 12 && streq ((char *) start, "ZLIB"))
16807 {
16808 /* Read the zlib header. In this case, it should be "ZLIB"
16809 followed by the uncompressed section size, 8 bytes in
16810 big-endian order. */
16811 uncompressed_size = start[4]; uncompressed_size <<= 8;
16812 uncompressed_size += start[5]; uncompressed_size <<= 8;
16813 uncompressed_size += start[6]; uncompressed_size <<= 8;
16814 uncompressed_size += start[7]; uncompressed_size <<= 8;
16815 uncompressed_size += start[8]; uncompressed_size <<= 8;
16816 uncompressed_size += start[9]; uncompressed_size <<= 8;
16817 uncompressed_size += start[10]; uncompressed_size <<= 8;
16818 uncompressed_size += start[11];
16819 start += 12;
16820 size -= 12;
16821 }
16822
1835f746 16823 if (uncompressed_size)
77115a4a 16824 {
1f5a3546 16825 if (uncompress_section_contents (is_zstd, &start, uncompressed_size,
45f5fe46 16826 &size, filedata->file_size))
1835f746
NC
16827 {
16828 /* Free the compressed buffer, update the section buffer
16829 and the section size if uncompress is successful. */
16830 free (section->start);
16831 section->start = start;
16832 }
16833 else
16834 {
16835 error (_("Unable to decompress section %s\n"),
dda8d76d 16836 printable_section_name (filedata, sec));
015dc7e1 16837 return false;
1835f746 16838 }
77115a4a 16839 }
bc303e5d 16840
77115a4a 16841 section->size = size;
59245841 16842 }
4a114e3e 16843
1b315056 16844 if (section->start == NULL)
015dc7e1 16845 return false;
1b315056 16846
19e6b90e 16847 if (debug_displays [debug].relocate)
32ec8896 16848 {
dda8d76d 16849 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 16850 & section->reloc_info, & section->num_relocs))
015dc7e1 16851 return false;
32ec8896 16852 }
d1c4b12b
NC
16853 else
16854 {
16855 section->reloc_info = NULL;
16856 section->num_relocs = 0;
16857 }
1007acb3 16858
015dc7e1 16859 return true;
1007acb3
L
16860}
16861
301a9420
AM
16862#if HAVE_LIBDEBUGINFOD
16863/* Return a hex string representation of the build-id. */
16864unsigned char *
16865get_build_id (void * data)
16866{
ca0e11aa 16867 Filedata * filedata = (Filedata *) data;
301a9420 16868 Elf_Internal_Shdr * shdr;
26c527e6 16869 size_t i;
301a9420 16870
55be8fd0
NC
16871 /* Iterate through notes to find note.gnu.build-id.
16872 FIXME: Only the first note in any note section is examined. */
301a9420
AM
16873 for (i = 0, shdr = filedata->section_headers;
16874 i < filedata->file_header.e_shnum && shdr != NULL;
16875 i++, shdr++)
16876 {
16877 if (shdr->sh_type != SHT_NOTE)
16878 continue;
16879
16880 char * next;
16881 char * end;
16882 size_t data_remaining;
16883 size_t min_notesz;
16884 Elf_External_Note * enote;
16885 Elf_Internal_Note inote;
16886
625d49fc
AM
16887 uint64_t offset = shdr->sh_offset;
16888 uint64_t align = shdr->sh_addralign;
16889 uint64_t length = shdr->sh_size;
301a9420
AM
16890
16891 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
16892 if (enote == NULL)
16893 continue;
16894
16895 if (align < 4)
16896 align = 4;
16897 else if (align != 4 && align != 8)
f761cb13
AM
16898 {
16899 free (enote);
16900 continue;
16901 }
301a9420
AM
16902
16903 end = (char *) enote + length;
16904 data_remaining = end - (char *) enote;
16905
16906 if (!is_ia64_vms (filedata))
16907 {
16908 min_notesz = offsetof (Elf_External_Note, name);
16909 if (data_remaining < min_notesz)
16910 {
55be8fd0
NC
16911 warn (_("\
16912malformed note encountered in section %s whilst scanning for build-id note\n"),
16913 printable_section_name (filedata, shdr));
f761cb13 16914 free (enote);
55be8fd0 16915 continue;
301a9420
AM
16916 }
16917 data_remaining -= min_notesz;
16918
16919 inote.type = BYTE_GET (enote->type);
16920 inote.namesz = BYTE_GET (enote->namesz);
16921 inote.namedata = enote->name;
16922 inote.descsz = BYTE_GET (enote->descsz);
16923 inote.descdata = ((char *) enote
16924 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
16925 inote.descpos = offset + (inote.descdata - (char *) enote);
16926 next = ((char *) enote
16927 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
16928 }
16929 else
16930 {
16931 Elf64_External_VMS_Note *vms_enote;
16932
16933 /* PR binutils/15191
16934 Make sure that there is enough data to read. */
16935 min_notesz = offsetof (Elf64_External_VMS_Note, name);
16936 if (data_remaining < min_notesz)
16937 {
55be8fd0
NC
16938 warn (_("\
16939malformed note encountered in section %s whilst scanning for build-id note\n"),
16940 printable_section_name (filedata, shdr));
f761cb13 16941 free (enote);
55be8fd0 16942 continue;
301a9420
AM
16943 }
16944 data_remaining -= min_notesz;
16945
16946 vms_enote = (Elf64_External_VMS_Note *) enote;
16947 inote.type = BYTE_GET (vms_enote->type);
16948 inote.namesz = BYTE_GET (vms_enote->namesz);
16949 inote.namedata = vms_enote->name;
16950 inote.descsz = BYTE_GET (vms_enote->descsz);
16951 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
16952 inote.descpos = offset + (inote.descdata - (char *) enote);
16953 next = inote.descdata + align_power (inote.descsz, 3);
16954 }
16955
16956 /* Skip malformed notes. */
16957 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
16958 || (size_t) (inote.descdata - inote.namedata) > data_remaining
16959 || (size_t) (next - inote.descdata) < inote.descsz
16960 || ((size_t) (next - inote.descdata)
16961 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
16962 {
55be8fd0
NC
16963 warn (_("\
16964malformed note encountered in section %s whilst scanning for build-id note\n"),
16965 printable_section_name (filedata, shdr));
f761cb13 16966 free (enote);
301a9420
AM
16967 continue;
16968 }
16969
16970 /* Check if this is the build-id note. If so then convert the build-id
16971 bytes to a hex string. */
16972 if (inote.namesz > 0
24d127aa 16973 && startswith (inote.namedata, "GNU")
301a9420
AM
16974 && inote.type == NT_GNU_BUILD_ID)
16975 {
26c527e6 16976 size_t j;
301a9420
AM
16977 char * build_id;
16978
16979 build_id = malloc (inote.descsz * 2 + 1);
16980 if (build_id == NULL)
f761cb13
AM
16981 {
16982 free (enote);
16983 return NULL;
16984 }
301a9420
AM
16985
16986 for (j = 0; j < inote.descsz; ++j)
16987 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
16988 build_id[inote.descsz * 2] = '\0';
f761cb13 16989 free (enote);
301a9420 16990
55be8fd0 16991 return (unsigned char *) build_id;
301a9420 16992 }
f761cb13 16993 free (enote);
301a9420
AM
16994 }
16995
16996 return NULL;
16997}
16998#endif /* HAVE_LIBDEBUGINFOD */
16999
657d0d47
CC
17000/* If this is not NULL, load_debug_section will only look for sections
17001 within the list of sections given here. */
32ec8896 17002static unsigned int * section_subset = NULL;
657d0d47 17003
015dc7e1 17004bool
dda8d76d 17005load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 17006{
2cf0635d
NC
17007 struct dwarf_section * section = &debug_displays [debug].section;
17008 Elf_Internal_Shdr * sec;
dda8d76d
NC
17009 Filedata * filedata = (Filedata *) data;
17010
e1dbfc17
L
17011 if (!dump_any_debugging)
17012 return false;
17013
f425ec66
NC
17014 /* Without section headers we cannot find any sections. */
17015 if (filedata->section_headers == NULL)
015dc7e1 17016 return false;
f425ec66 17017
9c1ce108
AM
17018 if (filedata->string_table == NULL
17019 && filedata->file_header.e_shstrndx != SHN_UNDEF
17020 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
17021 {
17022 Elf_Internal_Shdr * strs;
17023
17024 /* Read in the string table, so that we have section names to scan. */
17025 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
17026
4dff97b2 17027 if (strs != NULL && strs->sh_size != 0)
dda8d76d 17028 {
9c1ce108
AM
17029 filedata->string_table
17030 = (char *) get_data (NULL, filedata, strs->sh_offset,
17031 1, strs->sh_size, _("string table"));
dda8d76d 17032
9c1ce108
AM
17033 filedata->string_table_length
17034 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
17035 }
17036 }
d966045b
DJ
17037
17038 /* Locate the debug section. */
dda8d76d 17039 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
17040 if (sec != NULL)
17041 section->name = section->uncompressed_name;
17042 else
17043 {
dda8d76d 17044 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
17045 if (sec != NULL)
17046 section->name = section->compressed_name;
17047 }
17048 if (sec == NULL)
015dc7e1 17049 return false;
d966045b 17050
657d0d47
CC
17051 /* If we're loading from a subset of sections, and we've loaded
17052 a section matching this name before, it's likely that it's a
17053 different one. */
17054 if (section_subset != NULL)
17055 free_debug_section (debug);
17056
dda8d76d 17057 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
17058}
17059
19e6b90e
L
17060void
17061free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 17062{
2cf0635d 17063 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 17064
19e6b90e
L
17065 if (section->start == NULL)
17066 return;
1007acb3 17067
19e6b90e
L
17068 free ((char *) section->start);
17069 section->start = NULL;
17070 section->address = 0;
17071 section->size = 0;
a788aedd 17072
9db70fc3
AM
17073 free (section->reloc_info);
17074 section->reloc_info = NULL;
17075 section->num_relocs = 0;
1007acb3
L
17076}
17077
015dc7e1 17078static bool
dda8d76d 17079display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 17080{
84714f86
AM
17081 const char *name = (section_name_valid (filedata, section)
17082 ? section_name (filedata, section) : "");
17083 const char *print_name = printable_section_name (filedata, section);
be7d229a 17084 uint64_t length;
015dc7e1 17085 bool result = true;
3f5e193b 17086 int i;
1007acb3 17087
19e6b90e
L
17088 length = section->sh_size;
17089 if (length == 0)
1007acb3 17090 {
74e1a04b 17091 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 17092 return true;
1007acb3 17093 }
5dff79d8
NC
17094 if (section->sh_type == SHT_NOBITS)
17095 {
17096 /* There is no point in dumping the contents of a debugging section
17097 which has the NOBITS type - the bits in the file will be random.
17098 This can happen when a file containing a .eh_frame section is
17099 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
17100 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
17101 print_name);
015dc7e1 17102 return false;
5dff79d8 17103 }
1007acb3 17104
24d127aa 17105 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 17106 name = ".debug_info";
1007acb3 17107
19e6b90e
L
17108 /* See if we know how to display the contents of this section. */
17109 for (i = 0; i < max; i++)
d85bf2ba
NC
17110 {
17111 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
17112 struct dwarf_section_display * display = debug_displays + i;
17113 struct dwarf_section * sec = & display->section;
d966045b 17114
d85bf2ba 17115 if (streq (sec->uncompressed_name, name)
24d127aa 17116 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17117 || streq (sec->compressed_name, name))
17118 {
015dc7e1 17119 bool secondary = (section != find_section (filedata, name));
1007acb3 17120
d85bf2ba
NC
17121 if (secondary)
17122 free_debug_section (id);
dda8d76d 17123
24d127aa 17124 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
17125 sec->name = name;
17126 else if (streq (sec->uncompressed_name, name))
17127 sec->name = sec->uncompressed_name;
17128 else
17129 sec->name = sec->compressed_name;
657d0d47 17130
d85bf2ba
NC
17131 if (load_specific_debug_section (id, section, filedata))
17132 {
17133 /* If this debug section is part of a CU/TU set in a .dwp file,
17134 restrict load_debug_section to the sections in that set. */
17135 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 17136
d85bf2ba 17137 result &= display->display (sec, filedata);
657d0d47 17138
d85bf2ba 17139 section_subset = NULL;
1007acb3 17140
44266f36 17141 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
17142 free_debug_section (id);
17143 }
17144 break;
17145 }
17146 }
1007acb3 17147
19e6b90e 17148 if (i == max)
1007acb3 17149 {
74e1a04b 17150 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 17151 result = false;
1007acb3
L
17152 }
17153
19e6b90e 17154 return result;
5b18a4bc 17155}
103f02d3 17156
aef1f6d0
DJ
17157/* Set DUMP_SECTS for all sections where dumps were requested
17158 based on section name. */
17159
17160static void
dda8d76d 17161initialise_dumps_byname (Filedata * filedata)
aef1f6d0 17162{
2cf0635d 17163 struct dump_list_entry * cur;
aef1f6d0
DJ
17164
17165 for (cur = dump_sects_byname; cur; cur = cur->next)
17166 {
17167 unsigned int i;
015dc7e1 17168 bool any = false;
aef1f6d0 17169
dda8d76d 17170 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
17171 if (section_name_valid (filedata, filedata->section_headers + i)
17172 && streq (section_name (filedata, filedata->section_headers + i),
17173 cur->name))
aef1f6d0 17174 {
6431e409 17175 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 17176 any = true;
aef1f6d0
DJ
17177 }
17178
835f2fae
NC
17179 if (!any && !filedata->is_separate)
17180 warn (_("Section '%s' was not dumped because it does not exist\n"),
17181 cur->name);
aef1f6d0
DJ
17182 }
17183}
17184
015dc7e1 17185static bool
dda8d76d 17186process_section_contents (Filedata * filedata)
5b18a4bc 17187{
2cf0635d 17188 Elf_Internal_Shdr * section;
19e6b90e 17189 unsigned int i;
015dc7e1 17190 bool res = true;
103f02d3 17191
19e6b90e 17192 if (! do_dump)
015dc7e1 17193 return true;
103f02d3 17194
dda8d76d 17195 initialise_dumps_byname (filedata);
aef1f6d0 17196
dda8d76d 17197 for (i = 0, section = filedata->section_headers;
6431e409 17198 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
17199 i++, section++)
17200 {
6431e409 17201 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 17202
d6bfbc39
NC
17203 if (filedata->is_separate && ! process_links)
17204 dump &= DEBUG_DUMP;
047c3dbf 17205
8e8d0b63
NC
17206 if (dump & AUTO_DUMP)
17207 {
17208 switch (section->sh_type)
17209 {
17210 case SHT_PROGBITS:
17211 /* FIXME: There are lots of different type of section that have
17212 SHT_PROGBITS set in their header - code, debug info, etc. So
17213 we should check the section's name and interpret its contents
17214 that way, rather than just defaulting to a byte dump. */
17215#ifdef SUPPORT_DISASSEMBLY
17216 res &= disassemble_section (section, filedata);
17217#else
17218 res &= dump_section_as_bytes (section, filedata, false);
17219#endif
17220 break;
17221
17222 case SHT_DYNSYM:
17223 case SHT_SYMTAB:
17224 res &= dump_symbol_section (section, filedata);
17225 break;
17226
17227 case SHT_STRTAB:
17228 res &= dump_section_as_strings (section, filedata);
17229 break;
17230
17231 case SHT_RELA:
17232 case SHT_REL:
17233 case SHT_RELR:
17234 res &= display_relocations (section, filedata);
17235 break;
17236
17237 case SHT_NOTE:
17238 res &= process_notes_at (filedata, section, section->sh_offset,
17239 section->sh_size, section->sh_addralign);
17240 break;
17241
17242 case SHT_NULL:
17243 inform (_("Unable to display section %d - it has a NULL type\n"), i);
17244 break;
17245
17246 case SHT_NOBITS:
17247 inform (_("Unable to display section %d - it has no contents\n"), i);
17248 break;
17249
17250 case SHT_HASH:
17251 case SHT_DYNAMIC:
17252 case SHT_GROUP:
17253 case SHT_GNU_ATTRIBUTES:
17254 /* FIXME: Implement these. */
17255 /* Fall through. */
17256 default:
17257 /* FIXME: Add Proc and OS specific section types ? */
17258 warn (_("Unable to determine how to dump section %d (type %#x)\n"),
17259 i, section->sh_type);
17260 res = false;
17261 break;
17262 }
17263 }
17264
19e6b90e 17265#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
17266 if (dump & DISASS_DUMP)
17267 {
17268 if (! disassemble_section (section, filedata))
015dc7e1 17269 res = false;
dda8d76d 17270 }
19e6b90e 17271#endif
dda8d76d 17272 if (dump & HEX_DUMP)
32ec8896 17273 {
015dc7e1
AM
17274 if (! dump_section_as_bytes (section, filedata, false))
17275 res = false;
32ec8896 17276 }
103f02d3 17277
dda8d76d 17278 if (dump & RELOC_DUMP)
32ec8896 17279 {
015dc7e1
AM
17280 if (! dump_section_as_bytes (section, filedata, true))
17281 res = false;
32ec8896 17282 }
09c11c86 17283
dda8d76d 17284 if (dump & STRING_DUMP)
32ec8896 17285 {
dda8d76d 17286 if (! dump_section_as_strings (section, filedata))
015dc7e1 17287 res = false;
32ec8896 17288 }
cf13d699 17289
dda8d76d 17290 if (dump & DEBUG_DUMP)
32ec8896 17291 {
dda8d76d 17292 if (! display_debug_section (i, section, filedata))
015dc7e1 17293 res = false;
32ec8896 17294 }
7d9813f1 17295
094e34f2 17296#ifdef ENABLE_LIBCTF
7d9813f1
NA
17297 if (dump & CTF_DUMP)
17298 {
17299 if (! dump_section_as_ctf (section, filedata))
015dc7e1 17300 res = false;
7d9813f1 17301 }
094e34f2 17302#endif
42b6953b
IB
17303 if (dump & SFRAME_DUMP)
17304 {
17305 if (! dump_section_as_sframe (section, filedata))
17306 res = false;
17307 }
5b18a4bc 17308 }
103f02d3 17309
835f2fae 17310 if (! filedata->is_separate)
0ee3043f 17311 {
835f2fae
NC
17312 /* Check to see if the user requested a
17313 dump of a section that does not exist. */
17314 for (; i < filedata->dump.num_dump_sects; i++)
17315 if (filedata->dump.dump_sects[i])
17316 {
ca0e11aa 17317 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 17318 res = false;
835f2fae 17319 }
0ee3043f 17320 }
32ec8896
NC
17321
17322 return res;
5b18a4bc 17323}
103f02d3 17324
5b18a4bc 17325static void
19e6b90e 17326process_mips_fpe_exception (int mask)
5b18a4bc 17327{
19e6b90e
L
17328 if (mask)
17329 {
015dc7e1 17330 bool first = true;
32ec8896 17331
19e6b90e 17332 if (mask & OEX_FPU_INEX)
015dc7e1 17333 fputs ("INEX", stdout), first = false;
19e6b90e 17334 if (mask & OEX_FPU_UFLO)
015dc7e1 17335 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 17336 if (mask & OEX_FPU_OFLO)
015dc7e1 17337 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 17338 if (mask & OEX_FPU_DIV0)
015dc7e1 17339 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
17340 if (mask & OEX_FPU_INVAL)
17341 printf ("%sINVAL", first ? "" : "|");
17342 }
5b18a4bc 17343 else
19e6b90e 17344 fputs ("0", stdout);
5b18a4bc 17345}
103f02d3 17346
f6f0e17b
NC
17347/* Display's the value of TAG at location P. If TAG is
17348 greater than 0 it is assumed to be an unknown tag, and
17349 a message is printed to this effect. Otherwise it is
17350 assumed that a message has already been printed.
17351
17352 If the bottom bit of TAG is set it assumed to have a
17353 string value, otherwise it is assumed to have an integer
17354 value.
17355
17356 Returns an updated P pointing to the first unread byte
17357 beyond the end of TAG's value.
17358
17359 Reads at or beyond END will not be made. */
17360
17361static unsigned char *
60abdbed 17362display_tag_value (signed int tag,
f6f0e17b
NC
17363 unsigned char * p,
17364 const unsigned char * const end)
17365{
26c527e6 17366 uint64_t val;
f6f0e17b
NC
17367
17368 if (tag > 0)
17369 printf (" Tag_unknown_%d: ", tag);
17370
17371 if (p >= end)
17372 {
4082ef84 17373 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
17374 }
17375 else if (tag & 1)
17376 {
071436c6
NC
17377 /* PR 17531 file: 027-19978-0.004. */
17378 size_t maxlen = (end - p) - 1;
17379
17380 putchar ('"');
4082ef84
NC
17381 if (maxlen > 0)
17382 {
b6ac461a 17383 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17384 p += strnlen ((char *) p, maxlen) + 1;
17385 }
17386 else
17387 {
17388 printf (_("<corrupt string tag>"));
17389 p = (unsigned char *) end;
17390 }
071436c6 17391 printf ("\"\n");
f6f0e17b
NC
17392 }
17393 else
17394 {
cd30bcef 17395 READ_ULEB (val, p, end);
26c527e6 17396 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
f6f0e17b
NC
17397 }
17398
4082ef84 17399 assert (p <= end);
f6f0e17b
NC
17400 return p;
17401}
17402
53a346d8
CZ
17403/* ARC ABI attributes section. */
17404
17405static unsigned char *
17406display_arc_attribute (unsigned char * p,
17407 const unsigned char * const end)
17408{
17409 unsigned int tag;
53a346d8
CZ
17410 unsigned int val;
17411
cd30bcef 17412 READ_ULEB (tag, p, end);
53a346d8
CZ
17413
17414 switch (tag)
17415 {
17416 case Tag_ARC_PCS_config:
cd30bcef 17417 READ_ULEB (val, p, end);
53a346d8
CZ
17418 printf (" Tag_ARC_PCS_config: ");
17419 switch (val)
17420 {
17421 case 0:
17422 printf (_("Absent/Non standard\n"));
17423 break;
17424 case 1:
17425 printf (_("Bare metal/mwdt\n"));
17426 break;
17427 case 2:
17428 printf (_("Bare metal/newlib\n"));
17429 break;
17430 case 3:
17431 printf (_("Linux/uclibc\n"));
17432 break;
17433 case 4:
17434 printf (_("Linux/glibc\n"));
17435 break;
17436 default:
17437 printf (_("Unknown\n"));
17438 break;
17439 }
17440 break;
17441
17442 case Tag_ARC_CPU_base:
cd30bcef 17443 READ_ULEB (val, p, end);
53a346d8
CZ
17444 printf (" Tag_ARC_CPU_base: ");
17445 switch (val)
17446 {
17447 default:
17448 case TAG_CPU_NONE:
17449 printf (_("Absent\n"));
17450 break;
17451 case TAG_CPU_ARC6xx:
17452 printf ("ARC6xx\n");
17453 break;
17454 case TAG_CPU_ARC7xx:
17455 printf ("ARC7xx\n");
17456 break;
17457 case TAG_CPU_ARCEM:
17458 printf ("ARCEM\n");
17459 break;
17460 case TAG_CPU_ARCHS:
17461 printf ("ARCHS\n");
17462 break;
17463 }
17464 break;
17465
17466 case Tag_ARC_CPU_variation:
cd30bcef 17467 READ_ULEB (val, p, end);
53a346d8
CZ
17468 printf (" Tag_ARC_CPU_variation: ");
17469 switch (val)
17470 {
17471 default:
17472 if (val > 0 && val < 16)
53a346d8 17473 printf ("Core%d\n", val);
d8cbc93b
JL
17474 else
17475 printf ("Unknown\n");
17476 break;
17477
53a346d8
CZ
17478 case 0:
17479 printf (_("Absent\n"));
17480 break;
17481 }
17482 break;
17483
17484 case Tag_ARC_CPU_name:
17485 printf (" Tag_ARC_CPU_name: ");
17486 p = display_tag_value (-1, p, end);
17487 break;
17488
17489 case Tag_ARC_ABI_rf16:
cd30bcef 17490 READ_ULEB (val, p, end);
53a346d8
CZ
17491 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
17492 break;
17493
17494 case Tag_ARC_ABI_osver:
cd30bcef 17495 READ_ULEB (val, p, end);
53a346d8
CZ
17496 printf (" Tag_ARC_ABI_osver: v%d\n", val);
17497 break;
17498
17499 case Tag_ARC_ABI_pic:
17500 case Tag_ARC_ABI_sda:
cd30bcef 17501 READ_ULEB (val, p, end);
53a346d8
CZ
17502 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
17503 : " Tag_ARC_ABI_pic: ");
17504 switch (val)
17505 {
17506 case 0:
17507 printf (_("Absent\n"));
17508 break;
17509 case 1:
17510 printf ("MWDT\n");
17511 break;
17512 case 2:
17513 printf ("GNU\n");
17514 break;
17515 default:
17516 printf (_("Unknown\n"));
17517 break;
17518 }
17519 break;
17520
17521 case Tag_ARC_ABI_tls:
cd30bcef 17522 READ_ULEB (val, p, end);
53a346d8
CZ
17523 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
17524 break;
17525
17526 case Tag_ARC_ABI_enumsize:
cd30bcef 17527 READ_ULEB (val, p, end);
53a346d8
CZ
17528 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
17529 _("smallest"));
17530 break;
17531
17532 case Tag_ARC_ABI_exceptions:
cd30bcef 17533 READ_ULEB (val, p, end);
53a346d8
CZ
17534 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
17535 : _("default"));
17536 break;
17537
17538 case Tag_ARC_ABI_double_size:
cd30bcef 17539 READ_ULEB (val, p, end);
53a346d8
CZ
17540 printf (" Tag_ARC_ABI_double_size: %d\n", val);
17541 break;
17542
17543 case Tag_ARC_ISA_config:
17544 printf (" Tag_ARC_ISA_config: ");
17545 p = display_tag_value (-1, p, end);
17546 break;
17547
17548 case Tag_ARC_ISA_apex:
17549 printf (" Tag_ARC_ISA_apex: ");
17550 p = display_tag_value (-1, p, end);
17551 break;
17552
17553 case Tag_ARC_ISA_mpy_option:
cd30bcef 17554 READ_ULEB (val, p, end);
53a346d8
CZ
17555 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
17556 break;
17557
db1e1b45 17558 case Tag_ARC_ATR_version:
cd30bcef 17559 READ_ULEB (val, p, end);
db1e1b45 17560 printf (" Tag_ARC_ATR_version: %d\n", val);
17561 break;
17562
53a346d8
CZ
17563 default:
17564 return display_tag_value (tag & 1, p, end);
17565 }
17566
17567 return p;
17568}
17569
11c1ff18
PB
17570/* ARM EABI attributes section. */
17571typedef struct
17572{
70e99720 17573 unsigned int tag;
2cf0635d 17574 const char * name;
11c1ff18 17575 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 17576 unsigned int type;
288f0ba2 17577 const char *const *table;
11c1ff18
PB
17578} arm_attr_public_tag;
17579
288f0ba2 17580static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 17581 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 17582 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
17583 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
17584 "v8.1-M.mainline", "v9"};
288f0ba2
AM
17585static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
17586static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 17587 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 17588static const char *const arm_attr_tag_FP_arch[] =
bca38921 17589 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 17590 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
17591static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
17592static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
17593 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
17594 "NEON for ARMv8.1"};
288f0ba2 17595static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
17596 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
17597 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 17598static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 17599 {"V6", "SB", "TLS", "Unused"};
288f0ba2 17600static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 17601 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 17602static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 17603 {"Absolute", "PC-relative", "None"};
288f0ba2 17604static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 17605 {"None", "direct", "GOT-indirect"};
288f0ba2 17606static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 17607 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
17608static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
17609static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 17610 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
17611static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
17612static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
17613static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 17614 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 17615static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 17616 {"Unused", "small", "int", "forced to int"};
288f0ba2 17617static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 17618 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 17619static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 17620 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 17621static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 17622 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 17623static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
17624 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17625 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 17626static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
17627 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
17628 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
17629static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
17630static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 17631 {"Not Allowed", "Allowed"};
288f0ba2 17632static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 17633 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 17634static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 17635 {"Follow architecture", "Allowed"};
288f0ba2 17636static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 17637 {"Not Allowed", "Allowed"};
288f0ba2 17638static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 17639 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 17640 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
17641static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
17642static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 17643 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 17644 "TrustZone and Virtualization Extensions"};
288f0ba2 17645static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 17646 {"Not Allowed", "Allowed"};
11c1ff18 17647
288f0ba2 17648static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
17649 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
17650
99db83d0
AC
17651static const char * arm_attr_tag_PAC_extension[] =
17652 {"No PAC/AUT instructions",
17653 "PAC/AUT instructions permitted in the NOP space",
17654 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
17655
4b535030
AC
17656static const char * arm_attr_tag_BTI_extension[] =
17657 {"BTI instructions not permitted",
17658 "BTI instructions permitted in the NOP space",
17659 "BTI instructions permitted in the NOP and in the non-NOP space"};
17660
b81ee92f
AC
17661static const char * arm_attr_tag_BTI_use[] =
17662 {"Compiled without branch target enforcement",
17663 "Compiled with branch target enforcement"};
17664
c9fed665
AC
17665static const char * arm_attr_tag_PACRET_use[] =
17666 {"Compiled without return address signing and authentication",
17667 "Compiled with return address signing and authentication"};
17668
11c1ff18
PB
17669#define LOOKUP(id, name) \
17670 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 17671static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
17672{
17673 {4, "CPU_raw_name", 1, NULL},
17674 {5, "CPU_name", 1, NULL},
17675 LOOKUP(6, CPU_arch),
17676 {7, "CPU_arch_profile", 0, NULL},
17677 LOOKUP(8, ARM_ISA_use),
17678 LOOKUP(9, THUMB_ISA_use),
75375b3e 17679 LOOKUP(10, FP_arch),
11c1ff18 17680 LOOKUP(11, WMMX_arch),
f5f53991
AS
17681 LOOKUP(12, Advanced_SIMD_arch),
17682 LOOKUP(13, PCS_config),
11c1ff18
PB
17683 LOOKUP(14, ABI_PCS_R9_use),
17684 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 17685 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
17686 LOOKUP(17, ABI_PCS_GOT_use),
17687 LOOKUP(18, ABI_PCS_wchar_t),
17688 LOOKUP(19, ABI_FP_rounding),
17689 LOOKUP(20, ABI_FP_denormal),
17690 LOOKUP(21, ABI_FP_exceptions),
17691 LOOKUP(22, ABI_FP_user_exceptions),
17692 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
17693 {24, "ABI_align_needed", 0, NULL},
17694 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
17695 LOOKUP(26, ABI_enum_size),
17696 LOOKUP(27, ABI_HardFP_use),
17697 LOOKUP(28, ABI_VFP_args),
17698 LOOKUP(29, ABI_WMMX_args),
17699 LOOKUP(30, ABI_optimization_goals),
17700 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 17701 {32, "compatibility", 0, NULL},
f5f53991 17702 LOOKUP(34, CPU_unaligned_access),
75375b3e 17703 LOOKUP(36, FP_HP_extension),
8e79c3df 17704 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
17705 LOOKUP(42, MPextension_use),
17706 LOOKUP(44, DIV_use),
15afaa63 17707 LOOKUP(46, DSP_extension),
a7ad558c 17708 LOOKUP(48, MVE_arch),
99db83d0 17709 LOOKUP(50, PAC_extension),
4b535030 17710 LOOKUP(52, BTI_extension),
b81ee92f 17711 LOOKUP(74, BTI_use),
c9fed665 17712 LOOKUP(76, PACRET_use),
f5f53991
AS
17713 {64, "nodefaults", 0, NULL},
17714 {65, "also_compatible_with", 0, NULL},
17715 LOOKUP(66, T2EE_use),
17716 {67, "conformance", 1, NULL},
17717 LOOKUP(68, Virtualization_use),
cd21e546 17718 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
17719};
17720#undef LOOKUP
17721
11c1ff18 17722static unsigned char *
f6f0e17b
NC
17723display_arm_attribute (unsigned char * p,
17724 const unsigned char * const end)
11c1ff18 17725{
70e99720 17726 unsigned int tag;
70e99720 17727 unsigned int val;
2cf0635d 17728 arm_attr_public_tag * attr;
11c1ff18 17729 unsigned i;
70e99720 17730 unsigned int type;
11c1ff18 17731
cd30bcef 17732 READ_ULEB (tag, p, end);
11c1ff18 17733 attr = NULL;
2cf0635d 17734 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
17735 {
17736 if (arm_attr_public_tags[i].tag == tag)
17737 {
17738 attr = &arm_attr_public_tags[i];
17739 break;
17740 }
17741 }
17742
17743 if (attr)
17744 {
17745 printf (" Tag_%s: ", attr->name);
17746 switch (attr->type)
17747 {
17748 case 0:
17749 switch (tag)
17750 {
17751 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 17752 READ_ULEB (val, p, end);
11c1ff18
PB
17753 switch (val)
17754 {
2b692964
NC
17755 case 0: printf (_("None\n")); break;
17756 case 'A': printf (_("Application\n")); break;
17757 case 'R': printf (_("Realtime\n")); break;
17758 case 'M': printf (_("Microcontroller\n")); break;
17759 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
17760 default: printf ("??? (%d)\n", val); break;
17761 }
17762 break;
17763
75375b3e 17764 case 24: /* Tag_align_needed. */
cd30bcef 17765 READ_ULEB (val, p, end);
75375b3e
MGD
17766 switch (val)
17767 {
2b692964
NC
17768 case 0: printf (_("None\n")); break;
17769 case 1: printf (_("8-byte\n")); break;
17770 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
17771 case 3: printf ("??? 3\n"); break;
17772 default:
17773 if (val <= 12)
dd24e3da 17774 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17775 1 << val);
17776 else
17777 printf ("??? (%d)\n", val);
17778 break;
17779 }
17780 break;
17781
17782 case 25: /* Tag_align_preserved. */
cd30bcef 17783 READ_ULEB (val, p, end);
75375b3e
MGD
17784 switch (val)
17785 {
2b692964
NC
17786 case 0: printf (_("None\n")); break;
17787 case 1: printf (_("8-byte, except leaf SP\n")); break;
17788 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
17789 case 3: printf ("??? 3\n"); break;
17790 default:
17791 if (val <= 12)
dd24e3da 17792 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
17793 1 << val);
17794 else
17795 printf ("??? (%d)\n", val);
17796 break;
17797 }
17798 break;
17799
11c1ff18 17800 case 32: /* Tag_compatibility. */
071436c6 17801 {
cd30bcef 17802 READ_ULEB (val, p, end);
071436c6 17803 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17804 if (p < end - 1)
17805 {
17806 size_t maxlen = (end - p) - 1;
17807
b6ac461a 17808 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17809 p += strnlen ((char *) p, maxlen) + 1;
17810 }
17811 else
17812 {
17813 printf (_("<corrupt>"));
17814 p = (unsigned char *) end;
17815 }
071436c6 17816 putchar ('\n');
071436c6 17817 }
11c1ff18
PB
17818 break;
17819
f5f53991 17820 case 64: /* Tag_nodefaults. */
541a3cbd
NC
17821 /* PR 17531: file: 001-505008-0.01. */
17822 if (p < end)
17823 p++;
2b692964 17824 printf (_("True\n"));
f5f53991
AS
17825 break;
17826
17827 case 65: /* Tag_also_compatible_with. */
cd30bcef 17828 READ_ULEB (val, p, end);
f5f53991
AS
17829 if (val == 6 /* Tag_CPU_arch. */)
17830 {
cd30bcef 17831 READ_ULEB (val, p, end);
071436c6 17832 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
17833 printf ("??? (%d)\n", val);
17834 else
17835 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
17836 }
17837 else
17838 printf ("???\n");
071436c6
NC
17839 while (p < end && *(p++) != '\0' /* NUL terminator. */)
17840 ;
f5f53991
AS
17841 break;
17842
11c1ff18 17843 default:
bee0ee85
NC
17844 printf (_("<unknown: %d>\n"), tag);
17845 break;
11c1ff18
PB
17846 }
17847 return p;
17848
17849 case 1:
f6f0e17b 17850 return display_tag_value (-1, p, end);
11c1ff18 17851 case 2:
f6f0e17b 17852 return display_tag_value (0, p, end);
11c1ff18
PB
17853
17854 default:
17855 assert (attr->type & 0x80);
cd30bcef 17856 READ_ULEB (val, p, end);
11c1ff18
PB
17857 type = attr->type & 0x7f;
17858 if (val >= type)
17859 printf ("??? (%d)\n", val);
17860 else
17861 printf ("%s\n", attr->table[val]);
17862 return p;
17863 }
17864 }
11c1ff18 17865
f6f0e17b 17866 return display_tag_value (tag, p, end);
11c1ff18
PB
17867}
17868
104d59d1 17869static unsigned char *
60bca95a 17870display_gnu_attribute (unsigned char * p,
8e8d0b63
NC
17871 unsigned char * (* display_proc_gnu_attribute)
17872 (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 17873 const unsigned char * const end)
104d59d1 17874{
cd30bcef 17875 unsigned int tag;
60abdbed 17876 unsigned int val;
104d59d1 17877
cd30bcef 17878 READ_ULEB (tag, p, end);
104d59d1
JM
17879
17880 /* Tag_compatibility is the only generic GNU attribute defined at
17881 present. */
17882 if (tag == 32)
17883 {
cd30bcef 17884 READ_ULEB (val, p, end);
071436c6
NC
17885
17886 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
17887 if (p == end)
17888 {
071436c6 17889 printf (_("<corrupt>\n"));
f6f0e17b
NC
17890 warn (_("corrupt vendor attribute\n"));
17891 }
17892 else
17893 {
4082ef84
NC
17894 if (p < end - 1)
17895 {
17896 size_t maxlen = (end - p) - 1;
071436c6 17897
b6ac461a 17898 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
17899 p += strnlen ((char *) p, maxlen) + 1;
17900 }
17901 else
17902 {
17903 printf (_("<corrupt>"));
17904 p = (unsigned char *) end;
17905 }
071436c6 17906 putchar ('\n');
f6f0e17b 17907 }
104d59d1
JM
17908 return p;
17909 }
17910
17911 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 17912 return display_proc_gnu_attribute (p, tag, end);
104d59d1 17913
f6f0e17b 17914 return display_tag_value (tag, p, end);
104d59d1
JM
17915}
17916
85f7484a
PB
17917static unsigned char *
17918display_m68k_gnu_attribute (unsigned char * p,
17919 unsigned int tag,
17920 const unsigned char * const end)
17921{
17922 unsigned int val;
17923
17924 if (tag == Tag_GNU_M68K_ABI_FP)
17925 {
17926 printf (" Tag_GNU_M68K_ABI_FP: ");
17927 if (p == end)
17928 {
17929 printf (_("<corrupt>\n"));
17930 return p;
17931 }
17932 READ_ULEB (val, p, end);
17933
17934 if (val > 3)
17935 printf ("(%#x), ", val);
17936
17937 switch (val & 3)
17938 {
17939 case 0:
17940 printf (_("unspecified hard/soft float\n"));
17941 break;
17942 case 1:
17943 printf (_("hard float\n"));
17944 break;
17945 case 2:
17946 printf (_("soft float\n"));
17947 break;
17948 }
17949 return p;
17950 }
17951
17952 return display_tag_value (tag & 1, p, end);
17953}
17954
34c8bcba 17955static unsigned char *
f6f0e17b 17956display_power_gnu_attribute (unsigned char * p,
60abdbed 17957 unsigned int tag,
f6f0e17b 17958 const unsigned char * const end)
34c8bcba 17959{
005d79fd 17960 unsigned int val;
34c8bcba
JM
17961
17962 if (tag == Tag_GNU_Power_ABI_FP)
17963 {
34c8bcba 17964 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 17965 if (p == end)
005d79fd
AM
17966 {
17967 printf (_("<corrupt>\n"));
17968 return p;
17969 }
cd30bcef 17970 READ_ULEB (val, p, end);
60bca95a 17971
005d79fd
AM
17972 if (val > 15)
17973 printf ("(%#x), ", val);
17974
17975 switch (val & 3)
34c8bcba
JM
17976 {
17977 case 0:
005d79fd 17978 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
17979 break;
17980 case 1:
005d79fd 17981 printf (_("hard float, "));
34c8bcba
JM
17982 break;
17983 case 2:
005d79fd 17984 printf (_("soft float, "));
34c8bcba 17985 break;
3c7b9897 17986 case 3:
005d79fd 17987 printf (_("single-precision hard float, "));
3c7b9897 17988 break;
005d79fd
AM
17989 }
17990
17991 switch (val & 0xC)
17992 {
17993 case 0:
17994 printf (_("unspecified long double\n"));
17995 break;
17996 case 4:
17997 printf (_("128-bit IBM long double\n"));
17998 break;
17999 case 8:
18000 printf (_("64-bit long double\n"));
18001 break;
18002 case 12:
18003 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
18004 break;
18005 }
18006 return p;
005d79fd 18007 }
34c8bcba 18008
c6e65352
DJ
18009 if (tag == Tag_GNU_Power_ABI_Vector)
18010 {
c6e65352 18011 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 18012 if (p == end)
005d79fd
AM
18013 {
18014 printf (_("<corrupt>\n"));
18015 return p;
18016 }
cd30bcef 18017 READ_ULEB (val, p, end);
005d79fd
AM
18018
18019 if (val > 3)
18020 printf ("(%#x), ", val);
18021
18022 switch (val & 3)
c6e65352
DJ
18023 {
18024 case 0:
005d79fd 18025 printf (_("unspecified\n"));
c6e65352
DJ
18026 break;
18027 case 1:
005d79fd 18028 printf (_("generic\n"));
c6e65352
DJ
18029 break;
18030 case 2:
18031 printf ("AltiVec\n");
18032 break;
18033 case 3:
18034 printf ("SPE\n");
18035 break;
c6e65352
DJ
18036 }
18037 return p;
005d79fd 18038 }
c6e65352 18039
f82e0623
NF
18040 if (tag == Tag_GNU_Power_ABI_Struct_Return)
18041 {
005d79fd 18042 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 18043 if (p == end)
f6f0e17b 18044 {
005d79fd 18045 printf (_("<corrupt>\n"));
f6f0e17b
NC
18046 return p;
18047 }
cd30bcef 18048 READ_ULEB (val, p, end);
0b4362b0 18049
005d79fd
AM
18050 if (val > 2)
18051 printf ("(%#x), ", val);
18052
18053 switch (val & 3)
18054 {
18055 case 0:
18056 printf (_("unspecified\n"));
18057 break;
18058 case 1:
18059 printf ("r3/r4\n");
18060 break;
18061 case 2:
18062 printf (_("memory\n"));
18063 break;
18064 case 3:
18065 printf ("???\n");
18066 break;
18067 }
f82e0623
NF
18068 return p;
18069 }
18070
f6f0e17b 18071 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
18072}
18073
643f7afb
AK
18074static unsigned char *
18075display_s390_gnu_attribute (unsigned char * p,
60abdbed 18076 unsigned int tag,
643f7afb
AK
18077 const unsigned char * const end)
18078{
cd30bcef 18079 unsigned int val;
643f7afb
AK
18080
18081 if (tag == Tag_GNU_S390_ABI_Vector)
18082 {
643f7afb 18083 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 18084 READ_ULEB (val, p, end);
643f7afb
AK
18085
18086 switch (val)
18087 {
18088 case 0:
18089 printf (_("any\n"));
18090 break;
18091 case 1:
18092 printf (_("software\n"));
18093 break;
18094 case 2:
18095 printf (_("hardware\n"));
18096 break;
18097 default:
18098 printf ("??? (%d)\n", val);
18099 break;
18100 }
18101 return p;
18102 }
18103
18104 return display_tag_value (tag & 1, p, end);
18105}
18106
9e8c70f9 18107static void
60abdbed 18108display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
18109{
18110 if (mask)
18111 {
015dc7e1 18112 bool first = true;
071436c6 18113
9e8c70f9 18114 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 18115 fputs ("mul32", stdout), first = false;
9e8c70f9 18116 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 18117 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 18118 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 18119 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 18120 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 18121 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 18122 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 18123 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 18124 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 18125 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 18126 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 18127 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 18128 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 18129 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 18130 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 18131 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 18132 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 18133 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 18134 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 18135 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 18136 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 18137 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 18138 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 18139 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 18140 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 18141 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 18142 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 18143 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 18144 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 18145 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
18146 }
18147 else
071436c6
NC
18148 fputc ('0', stdout);
18149 fputc ('\n', stdout);
9e8c70f9
DM
18150}
18151
3d68f91c 18152static void
60abdbed 18153display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
18154{
18155 if (mask)
18156 {
015dc7e1 18157 bool first = true;
071436c6 18158
3d68f91c 18159 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 18160 fputs ("fjathplus", stdout), first = false;
3d68f91c 18161 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 18162 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 18163 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 18164 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 18165 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 18166 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 18167 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 18168 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 18169 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 18170 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 18171 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 18172 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 18173 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 18174 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 18175 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 18176 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 18177 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 18178 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 18179 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 18180 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
18181 }
18182 else
071436c6
NC
18183 fputc ('0', stdout);
18184 fputc ('\n', stdout);
3d68f91c
JM
18185}
18186
9e8c70f9 18187static unsigned char *
f6f0e17b 18188display_sparc_gnu_attribute (unsigned char * p,
60abdbed 18189 unsigned int tag,
f6f0e17b 18190 const unsigned char * const end)
9e8c70f9 18191{
cd30bcef 18192 unsigned int val;
3d68f91c 18193
9e8c70f9
DM
18194 if (tag == Tag_GNU_Sparc_HWCAPS)
18195 {
cd30bcef 18196 READ_ULEB (val, p, end);
9e8c70f9 18197 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
18198 display_sparc_hwcaps (val);
18199 return p;
3d68f91c
JM
18200 }
18201 if (tag == Tag_GNU_Sparc_HWCAPS2)
18202 {
cd30bcef 18203 READ_ULEB (val, p, end);
3d68f91c
JM
18204 printf (" Tag_GNU_Sparc_HWCAPS2: ");
18205 display_sparc_hwcaps2 (val);
18206 return p;
18207 }
9e8c70f9 18208
f6f0e17b 18209 return display_tag_value (tag, p, end);
9e8c70f9
DM
18210}
18211
351cdf24 18212static void
32ec8896 18213print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
18214{
18215 switch (val)
18216 {
18217 case Val_GNU_MIPS_ABI_FP_ANY:
18218 printf (_("Hard or soft float\n"));
18219 break;
18220 case Val_GNU_MIPS_ABI_FP_DOUBLE:
18221 printf (_("Hard float (double precision)\n"));
18222 break;
18223 case Val_GNU_MIPS_ABI_FP_SINGLE:
18224 printf (_("Hard float (single precision)\n"));
18225 break;
18226 case Val_GNU_MIPS_ABI_FP_SOFT:
18227 printf (_("Soft float\n"));
18228 break;
18229 case Val_GNU_MIPS_ABI_FP_OLD_64:
18230 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
18231 break;
18232 case Val_GNU_MIPS_ABI_FP_XX:
18233 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
18234 break;
18235 case Val_GNU_MIPS_ABI_FP_64:
18236 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
18237 break;
18238 case Val_GNU_MIPS_ABI_FP_64A:
18239 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
18240 break;
3350cc01
CM
18241 case Val_GNU_MIPS_ABI_FP_NAN2008:
18242 printf (_("NaN 2008 compatibility\n"));
18243 break;
351cdf24
MF
18244 default:
18245 printf ("??? (%d)\n", val);
18246 break;
18247 }
18248}
18249
2cf19d5c 18250static unsigned char *
f6f0e17b 18251display_mips_gnu_attribute (unsigned char * p,
60abdbed 18252 unsigned int tag,
f6f0e17b 18253 const unsigned char * const end)
2cf19d5c 18254{
2cf19d5c
JM
18255 if (tag == Tag_GNU_MIPS_ABI_FP)
18256 {
32ec8896 18257 unsigned int val;
f6f0e17b 18258
2cf19d5c 18259 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 18260 READ_ULEB (val, p, end);
351cdf24 18261 print_mips_fp_abi_value (val);
2cf19d5c
JM
18262 return p;
18263 }
18264
a9f58168
CF
18265 if (tag == Tag_GNU_MIPS_ABI_MSA)
18266 {
32ec8896 18267 unsigned int val;
a9f58168 18268
a9f58168 18269 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 18270 READ_ULEB (val, p, end);
a9f58168
CF
18271
18272 switch (val)
18273 {
18274 case Val_GNU_MIPS_ABI_MSA_ANY:
18275 printf (_("Any MSA or not\n"));
18276 break;
18277 case Val_GNU_MIPS_ABI_MSA_128:
18278 printf (_("128-bit MSA\n"));
18279 break;
18280 default:
18281 printf ("??? (%d)\n", val);
18282 break;
18283 }
18284 return p;
18285 }
18286
f6f0e17b 18287 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
18288}
18289
59e6276b 18290static unsigned char *
f6f0e17b
NC
18291display_tic6x_attribute (unsigned char * p,
18292 const unsigned char * const end)
59e6276b 18293{
60abdbed 18294 unsigned int tag;
cd30bcef 18295 unsigned int val;
59e6276b 18296
cd30bcef 18297 READ_ULEB (tag, p, end);
59e6276b
JM
18298
18299 switch (tag)
18300 {
75fa6dc1 18301 case Tag_ISA:
75fa6dc1 18302 printf (" Tag_ISA: ");
cd30bcef 18303 READ_ULEB (val, p, end);
59e6276b
JM
18304
18305 switch (val)
18306 {
75fa6dc1 18307 case C6XABI_Tag_ISA_none:
59e6276b
JM
18308 printf (_("None\n"));
18309 break;
75fa6dc1 18310 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
18311 printf ("C62x\n");
18312 break;
75fa6dc1 18313 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
18314 printf ("C67x\n");
18315 break;
75fa6dc1 18316 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
18317 printf ("C67x+\n");
18318 break;
75fa6dc1 18319 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
18320 printf ("C64x\n");
18321 break;
75fa6dc1 18322 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
18323 printf ("C64x+\n");
18324 break;
75fa6dc1 18325 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
18326 printf ("C674x\n");
18327 break;
18328 default:
18329 printf ("??? (%d)\n", val);
18330 break;
18331 }
18332 return p;
18333
87779176 18334 case Tag_ABI_wchar_t:
87779176 18335 printf (" Tag_ABI_wchar_t: ");
cd30bcef 18336 READ_ULEB (val, p, end);
87779176
JM
18337 switch (val)
18338 {
18339 case 0:
18340 printf (_("Not used\n"));
18341 break;
18342 case 1:
18343 printf (_("2 bytes\n"));
18344 break;
18345 case 2:
18346 printf (_("4 bytes\n"));
18347 break;
18348 default:
18349 printf ("??? (%d)\n", val);
18350 break;
18351 }
18352 return p;
18353
18354 case Tag_ABI_stack_align_needed:
87779176 18355 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 18356 READ_ULEB (val, p, end);
87779176
JM
18357 switch (val)
18358 {
18359 case 0:
18360 printf (_("8-byte\n"));
18361 break;
18362 case 1:
18363 printf (_("16-byte\n"));
18364 break;
18365 default:
18366 printf ("??? (%d)\n", val);
18367 break;
18368 }
18369 return p;
18370
18371 case Tag_ABI_stack_align_preserved:
cd30bcef 18372 READ_ULEB (val, p, end);
87779176
JM
18373 printf (" Tag_ABI_stack_align_preserved: ");
18374 switch (val)
18375 {
18376 case 0:
18377 printf (_("8-byte\n"));
18378 break;
18379 case 1:
18380 printf (_("16-byte\n"));
18381 break;
18382 default:
18383 printf ("??? (%d)\n", val);
18384 break;
18385 }
18386 return p;
18387
b5593623 18388 case Tag_ABI_DSBT:
cd30bcef 18389 READ_ULEB (val, p, end);
b5593623
JM
18390 printf (" Tag_ABI_DSBT: ");
18391 switch (val)
18392 {
18393 case 0:
18394 printf (_("DSBT addressing not used\n"));
18395 break;
18396 case 1:
18397 printf (_("DSBT addressing used\n"));
18398 break;
18399 default:
18400 printf ("??? (%d)\n", val);
18401 break;
18402 }
18403 return p;
18404
87779176 18405 case Tag_ABI_PID:
cd30bcef 18406 READ_ULEB (val, p, end);
87779176
JM
18407 printf (" Tag_ABI_PID: ");
18408 switch (val)
18409 {
18410 case 0:
18411 printf (_("Data addressing position-dependent\n"));
18412 break;
18413 case 1:
18414 printf (_("Data addressing position-independent, GOT near DP\n"));
18415 break;
18416 case 2:
18417 printf (_("Data addressing position-independent, GOT far from DP\n"));
18418 break;
18419 default:
18420 printf ("??? (%d)\n", val);
18421 break;
18422 }
18423 return p;
18424
18425 case Tag_ABI_PIC:
cd30bcef 18426 READ_ULEB (val, p, end);
87779176
JM
18427 printf (" Tag_ABI_PIC: ");
18428 switch (val)
18429 {
18430 case 0:
18431 printf (_("Code addressing position-dependent\n"));
18432 break;
18433 case 1:
18434 printf (_("Code addressing position-independent\n"));
18435 break;
18436 default:
18437 printf ("??? (%d)\n", val);
18438 break;
18439 }
18440 return p;
18441
18442 case Tag_ABI_array_object_alignment:
cd30bcef 18443 READ_ULEB (val, p, end);
87779176
JM
18444 printf (" Tag_ABI_array_object_alignment: ");
18445 switch (val)
18446 {
18447 case 0:
18448 printf (_("8-byte\n"));
18449 break;
18450 case 1:
18451 printf (_("4-byte\n"));
18452 break;
18453 case 2:
18454 printf (_("16-byte\n"));
18455 break;
18456 default:
18457 printf ("??? (%d)\n", val);
18458 break;
18459 }
18460 return p;
18461
18462 case Tag_ABI_array_object_align_expected:
cd30bcef 18463 READ_ULEB (val, p, end);
87779176
JM
18464 printf (" Tag_ABI_array_object_align_expected: ");
18465 switch (val)
18466 {
18467 case 0:
18468 printf (_("8-byte\n"));
18469 break;
18470 case 1:
18471 printf (_("4-byte\n"));
18472 break;
18473 case 2:
18474 printf (_("16-byte\n"));
18475 break;
18476 default:
18477 printf ("??? (%d)\n", val);
18478 break;
18479 }
18480 return p;
18481
3cbd1c06 18482 case Tag_ABI_compatibility:
071436c6 18483 {
cd30bcef 18484 READ_ULEB (val, p, end);
071436c6 18485 printf (" Tag_ABI_compatibility: ");
071436c6 18486 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
18487 if (p < end - 1)
18488 {
18489 size_t maxlen = (end - p) - 1;
18490
b6ac461a 18491 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18492 p += strnlen ((char *) p, maxlen) + 1;
18493 }
18494 else
18495 {
18496 printf (_("<corrupt>"));
18497 p = (unsigned char *) end;
18498 }
071436c6 18499 putchar ('\n');
071436c6
NC
18500 return p;
18501 }
87779176
JM
18502
18503 case Tag_ABI_conformance:
071436c6 18504 {
4082ef84
NC
18505 printf (" Tag_ABI_conformance: \"");
18506 if (p < end - 1)
18507 {
18508 size_t maxlen = (end - p) - 1;
071436c6 18509
b6ac461a 18510 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18511 p += strnlen ((char *) p, maxlen) + 1;
18512 }
18513 else
18514 {
18515 printf (_("<corrupt>"));
18516 p = (unsigned char *) end;
18517 }
071436c6 18518 printf ("\"\n");
071436c6
NC
18519 return p;
18520 }
59e6276b
JM
18521 }
18522
f6f0e17b
NC
18523 return display_tag_value (tag, p, end);
18524}
59e6276b 18525
f6f0e17b 18526static void
60abdbed 18527display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b 18528{
26c527e6 18529 uint64_t addr = 0;
f6f0e17b
NC
18530 size_t bytes = end - p;
18531
feceaa59 18532 assert (end >= p);
f6f0e17b 18533 while (bytes)
87779176 18534 {
f6f0e17b
NC
18535 int j;
18536 int k;
18537 int lbytes = (bytes > 16 ? 16 : bytes);
18538
26c527e6 18539 printf (" 0x%8.8" PRIx64 " ", addr);
f6f0e17b
NC
18540
18541 for (j = 0; j < 16; j++)
18542 {
18543 if (j < lbytes)
18544 printf ("%2.2x", p[j]);
18545 else
18546 printf (" ");
18547
18548 if ((j & 3) == 3)
18549 printf (" ");
18550 }
18551
18552 for (j = 0; j < lbytes; j++)
18553 {
18554 k = p[j];
18555 if (k >= ' ' && k < 0x7f)
18556 printf ("%c", k);
18557 else
18558 printf (".");
18559 }
18560
18561 putchar ('\n');
18562
18563 p += lbytes;
18564 bytes -= lbytes;
18565 addr += lbytes;
87779176 18566 }
59e6276b 18567
f6f0e17b 18568 putchar ('\n');
59e6276b
JM
18569}
18570
13761a11 18571static unsigned char *
b0191216 18572display_msp430_attribute (unsigned char * p,
26c527e6 18573 const unsigned char * const end)
13761a11 18574{
26c527e6
AM
18575 uint64_t val;
18576 uint64_t tag;
13761a11 18577
cd30bcef 18578 READ_ULEB (tag, p, end);
0b4362b0 18579
13761a11
NC
18580 switch (tag)
18581 {
18582 case OFBA_MSPABI_Tag_ISA:
13761a11 18583 printf (" Tag_ISA: ");
cd30bcef 18584 READ_ULEB (val, p, end);
13761a11
NC
18585 switch (val)
18586 {
18587 case 0: printf (_("None\n")); break;
18588 case 1: printf (_("MSP430\n")); break;
18589 case 2: printf (_("MSP430X\n")); break;
26c527e6 18590 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18591 }
18592 break;
18593
18594 case OFBA_MSPABI_Tag_Code_Model:
13761a11 18595 printf (" Tag_Code_Model: ");
cd30bcef 18596 READ_ULEB (val, p, end);
13761a11
NC
18597 switch (val)
18598 {
18599 case 0: printf (_("None\n")); break;
18600 case 1: printf (_("Small\n")); break;
18601 case 2: printf (_("Large\n")); break;
26c527e6 18602 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18603 }
18604 break;
18605
18606 case OFBA_MSPABI_Tag_Data_Model:
13761a11 18607 printf (" Tag_Data_Model: ");
cd30bcef 18608 READ_ULEB (val, p, end);
13761a11
NC
18609 switch (val)
18610 {
18611 case 0: printf (_("None\n")); break;
18612 case 1: printf (_("Small\n")); break;
18613 case 2: printf (_("Large\n")); break;
18614 case 3: printf (_("Restricted Large\n")); break;
26c527e6 18615 default: printf ("??? (%" PRId64 ")\n", val); break;
13761a11
NC
18616 }
18617 break;
18618
18619 default:
26c527e6 18620 printf (_(" <unknown tag %" PRId64 ">: "), tag);
13761a11
NC
18621
18622 if (tag & 1)
18623 {
071436c6 18624 putchar ('"');
4082ef84
NC
18625 if (p < end - 1)
18626 {
18627 size_t maxlen = (end - p) - 1;
18628
b6ac461a 18629 print_symbol_name ((int) maxlen, (const char *) p);
4082ef84
NC
18630 p += strnlen ((char *) p, maxlen) + 1;
18631 }
18632 else
18633 {
18634 printf (_("<corrupt>"));
18635 p = (unsigned char *) end;
18636 }
071436c6 18637 printf ("\"\n");
13761a11
NC
18638 }
18639 else
18640 {
cd30bcef 18641 READ_ULEB (val, p, end);
26c527e6 18642 printf ("%" PRId64 " (0x%" PRIx64 ")\n", val, val);
13761a11
NC
18643 }
18644 break;
18645 }
18646
4082ef84 18647 assert (p <= end);
13761a11
NC
18648 return p;
18649}
18650
c0ea7c52
JL
18651static unsigned char *
18652display_msp430_gnu_attribute (unsigned char * p,
18653 unsigned int tag,
18654 const unsigned char * const end)
18655{
18656 if (tag == Tag_GNU_MSP430_Data_Region)
18657 {
26c527e6 18658 uint64_t val;
c0ea7c52 18659
c0ea7c52 18660 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 18661 READ_ULEB (val, p, end);
c0ea7c52
JL
18662
18663 switch (val)
18664 {
18665 case Val_GNU_MSP430_Data_Region_Any:
18666 printf (_("Any Region\n"));
18667 break;
18668 case Val_GNU_MSP430_Data_Region_Lower:
18669 printf (_("Lower Region Only\n"));
18670 break;
18671 default:
26c527e6 18672 printf ("??? (%" PRIu64 ")\n", val);
c0ea7c52
JL
18673 }
18674 return p;
18675 }
18676 return display_tag_value (tag & 1, p, end);
18677}
18678
2dc8dd17
JW
18679struct riscv_attr_tag_t {
18680 const char *name;
cd30bcef 18681 unsigned int tag;
2dc8dd17
JW
18682};
18683
18684static struct riscv_attr_tag_t riscv_attr_tag[] =
18685{
18686#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
18687 T(arch),
18688 T(priv_spec),
18689 T(priv_spec_minor),
18690 T(priv_spec_revision),
18691 T(unaligned_access),
18692 T(stack_align),
18693#undef T
18694};
18695
18696static unsigned char *
18697display_riscv_attribute (unsigned char *p,
18698 const unsigned char * const end)
18699{
26c527e6
AM
18700 uint64_t val;
18701 uint64_t tag;
2dc8dd17
JW
18702 struct riscv_attr_tag_t *attr = NULL;
18703 unsigned i;
18704
cd30bcef 18705 READ_ULEB (tag, p, end);
2dc8dd17
JW
18706
18707 /* Find the name of attribute. */
18708 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
18709 {
18710 if (riscv_attr_tag[i].tag == tag)
18711 {
18712 attr = &riscv_attr_tag[i];
18713 break;
18714 }
18715 }
18716
18717 if (attr)
18718 printf (" %s: ", attr->name);
18719 else
18720 return display_tag_value (tag, p, end);
18721
18722 switch (tag)
18723 {
18724 case Tag_RISCV_priv_spec:
18725 case Tag_RISCV_priv_spec_minor:
18726 case Tag_RISCV_priv_spec_revision:
cd30bcef 18727 READ_ULEB (val, p, end);
26c527e6 18728 printf ("%" PRIu64 "\n", val);
2dc8dd17
JW
18729 break;
18730 case Tag_RISCV_unaligned_access:
cd30bcef 18731 READ_ULEB (val, p, end);
2dc8dd17
JW
18732 switch (val)
18733 {
18734 case 0:
18735 printf (_("No unaligned access\n"));
18736 break;
18737 case 1:
18738 printf (_("Unaligned access\n"));
18739 break;
18740 }
18741 break;
18742 case Tag_RISCV_stack_align:
cd30bcef 18743 READ_ULEB (val, p, end);
26c527e6 18744 printf (_("%" PRIu64 "-bytes\n"), val);
2dc8dd17
JW
18745 break;
18746 case Tag_RISCV_arch:
18747 p = display_tag_value (-1, p, end);
18748 break;
18749 default:
18750 return display_tag_value (tag, p, end);
18751 }
18752
18753 return p;
18754}
18755
0861f561
CQ
18756static unsigned char *
18757display_csky_attribute (unsigned char * p,
18758 const unsigned char * const end)
18759{
26c527e6
AM
18760 uint64_t tag;
18761 uint64_t val;
0861f561
CQ
18762 READ_ULEB (tag, p, end);
18763
18764 if (tag >= Tag_CSKY_MAX)
18765 {
18766 return display_tag_value (-1, p, end);
18767 }
18768
18769 switch (tag)
18770 {
18771 case Tag_CSKY_ARCH_NAME:
18772 printf (" Tag_CSKY_ARCH_NAME:\t\t");
18773 return display_tag_value (-1, p, end);
18774 case Tag_CSKY_CPU_NAME:
18775 printf (" Tag_CSKY_CPU_NAME:\t\t");
18776 return display_tag_value (-1, p, end);
18777
18778 case Tag_CSKY_ISA_FLAGS:
18779 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
18780 return display_tag_value (0, p, end);
18781 case Tag_CSKY_ISA_EXT_FLAGS:
18782 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
18783 return display_tag_value (0, p, end);
18784
18785 case Tag_CSKY_DSP_VERSION:
18786 printf (" Tag_CSKY_DSP_VERSION:\t\t");
18787 READ_ULEB (val, p, end);
18788 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
18789 printf ("DSP Extension\n");
18790 else if (val == VAL_CSKY_DSP_VERSION_2)
18791 printf ("DSP 2.0\n");
18792 break;
18793
18794 case Tag_CSKY_VDSP_VERSION:
18795 printf (" Tag_CSKY_VDSP_VERSION:\t");
18796 READ_ULEB (val, p, end);
26c527e6 18797 printf ("VDSP Version %" PRId64 "\n", val);
0861f561
CQ
18798 break;
18799
18800 case Tag_CSKY_FPU_VERSION:
18801 printf (" Tag_CSKY_FPU_VERSION:\t\t");
18802 READ_ULEB (val, p, end);
18803 if (val == VAL_CSKY_FPU_VERSION_1)
18804 printf ("ABIV1 FPU Version 1\n");
18805 else if (val == VAL_CSKY_FPU_VERSION_2)
18806 printf ("FPU Version 2\n");
18807 break;
18808
18809 case Tag_CSKY_FPU_ABI:
18810 printf (" Tag_CSKY_FPU_ABI:\t\t");
18811 READ_ULEB (val, p, end);
18812 if (val == VAL_CSKY_FPU_ABI_HARD)
18813 printf ("Hard\n");
18814 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
18815 printf ("SoftFP\n");
18816 else if (val == VAL_CSKY_FPU_ABI_SOFT)
18817 printf ("Soft\n");
18818 break;
18819 case Tag_CSKY_FPU_ROUNDING:
18820 READ_ULEB (val, p, end);
f253158f
NC
18821 if (val == 1)
18822 {
18823 printf (" Tag_CSKY_FPU_ROUNDING:\t");
18824 printf ("Needed\n");
18825 }
0861f561
CQ
18826 break;
18827 case Tag_CSKY_FPU_DENORMAL:
18828 READ_ULEB (val, p, end);
f253158f
NC
18829 if (val == 1)
18830 {
18831 printf (" Tag_CSKY_FPU_DENORMAL:\t");
18832 printf ("Needed\n");
18833 }
0861f561
CQ
18834 break;
18835 case Tag_CSKY_FPU_Exception:
18836 READ_ULEB (val, p, end);
f253158f
NC
18837 if (val == 1)
18838 {
18839 printf (" Tag_CSKY_FPU_Exception:\t");
18840 printf ("Needed\n");
18841 }
0861f561
CQ
18842 break;
18843 case Tag_CSKY_FPU_NUMBER_MODULE:
18844 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
18845 return display_tag_value (-1, p, end);
18846 case Tag_CSKY_FPU_HARDFP:
18847 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
18848 READ_ULEB (val, p, end);
18849 if (val & VAL_CSKY_FPU_HARDFP_HALF)
18850 printf (" Half");
18851 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
18852 printf (" Single");
18853 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
18854 printf (" Double");
18855 printf ("\n");
18856 break;
18857 default:
18858 return display_tag_value (tag, p, end);
18859 }
18860 return p;
18861}
18862
015dc7e1 18863static bool
dda8d76d 18864process_attributes (Filedata * filedata,
60bca95a 18865 const char * public_name,
104d59d1 18866 unsigned int proc_type,
f6f0e17b 18867 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 18868 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 18869{
2cf0635d 18870 Elf_Internal_Shdr * sect;
11c1ff18 18871 unsigned i;
015dc7e1 18872 bool res = true;
11c1ff18
PB
18873
18874 /* Find the section header so that we get the size. */
dda8d76d
NC
18875 for (i = 0, sect = filedata->section_headers;
18876 i < filedata->file_header.e_shnum;
11c1ff18
PB
18877 i++, sect++)
18878 {
071436c6
NC
18879 unsigned char * contents;
18880 unsigned char * p;
18881
104d59d1 18882 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
18883 continue;
18884
dda8d76d 18885 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 18886 sect->sh_size, _("attributes"));
60bca95a 18887 if (contents == NULL)
32ec8896 18888 {
015dc7e1 18889 res = false;
32ec8896
NC
18890 continue;
18891 }
60bca95a 18892
11c1ff18 18893 p = contents;
60abdbed
NC
18894 /* The first character is the version of the attributes.
18895 Currently only version 1, (aka 'A') is recognised here. */
18896 if (*p != 'A')
32ec8896
NC
18897 {
18898 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 18899 res = false;
32ec8896 18900 }
60abdbed 18901 else
11c1ff18 18902 {
625d49fc 18903 uint64_t section_len;
071436c6
NC
18904
18905 section_len = sect->sh_size - 1;
11c1ff18 18906 p++;
60bca95a 18907
071436c6 18908 while (section_len > 0)
11c1ff18 18909 {
625d49fc 18910 uint64_t attr_len;
e9847026 18911 unsigned int namelen;
015dc7e1
AM
18912 bool public_section;
18913 bool gnu_section;
11c1ff18 18914
071436c6 18915 if (section_len <= 4)
e0a31db1
NC
18916 {
18917 error (_("Tag section ends prematurely\n"));
015dc7e1 18918 res = false;
e0a31db1
NC
18919 break;
18920 }
071436c6 18921 attr_len = byte_get (p, 4);
11c1ff18 18922 p += 4;
60bca95a 18923
071436c6 18924 if (attr_len > section_len)
11c1ff18 18925 {
071436c6
NC
18926 error (_("Bad attribute length (%u > %u)\n"),
18927 (unsigned) attr_len, (unsigned) section_len);
18928 attr_len = section_len;
015dc7e1 18929 res = false;
11c1ff18 18930 }
74e1a04b 18931 /* PR 17531: file: 001-101425-0.004 */
071436c6 18932 else if (attr_len < 5)
74e1a04b 18933 {
071436c6 18934 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 18935 res = false;
74e1a04b
NC
18936 break;
18937 }
e9847026 18938
071436c6
NC
18939 section_len -= attr_len;
18940 attr_len -= 4;
18941
18942 namelen = strnlen ((char *) p, attr_len) + 1;
18943 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
18944 {
18945 error (_("Corrupt attribute section name\n"));
015dc7e1 18946 res = false;
e9847026
NC
18947 break;
18948 }
18949
071436c6 18950 printf (_("Attribute Section: "));
b6ac461a 18951 print_symbol_name (INT_MAX, (const char *) p);
071436c6 18952 putchar ('\n');
60bca95a
NC
18953
18954 if (public_name && streq ((char *) p, public_name))
015dc7e1 18955 public_section = true;
11c1ff18 18956 else
015dc7e1 18957 public_section = false;
60bca95a
NC
18958
18959 if (streq ((char *) p, "gnu"))
015dc7e1 18960 gnu_section = true;
104d59d1 18961 else
015dc7e1 18962 gnu_section = false;
60bca95a 18963
11c1ff18 18964 p += namelen;
071436c6 18965 attr_len -= namelen;
e0a31db1 18966
071436c6 18967 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 18968 {
e0a31db1 18969 int tag;
cd30bcef 18970 unsigned int val;
625d49fc 18971 uint64_t size;
071436c6 18972 unsigned char * end;
60bca95a 18973
e0a31db1 18974 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 18975 if (attr_len < 6)
e0a31db1
NC
18976 {
18977 error (_("Unused bytes at end of section\n"));
015dc7e1 18978 res = false;
e0a31db1
NC
18979 section_len = 0;
18980 break;
18981 }
18982
18983 tag = *(p++);
11c1ff18 18984 size = byte_get (p, 4);
071436c6 18985 if (size > attr_len)
11c1ff18 18986 {
e9847026 18987 error (_("Bad subsection length (%u > %u)\n"),
071436c6 18988 (unsigned) size, (unsigned) attr_len);
015dc7e1 18989 res = false;
071436c6 18990 size = attr_len;
11c1ff18 18991 }
e0a31db1
NC
18992 /* PR binutils/17531: Safe handling of corrupt files. */
18993 if (size < 6)
18994 {
18995 error (_("Bad subsection length (%u < 6)\n"),
18996 (unsigned) size);
015dc7e1 18997 res = false;
e0a31db1
NC
18998 section_len = 0;
18999 break;
19000 }
60bca95a 19001
071436c6 19002 attr_len -= size;
11c1ff18 19003 end = p + size - 1;
071436c6 19004 assert (end <= contents + sect->sh_size);
11c1ff18 19005 p += 4;
60bca95a 19006
11c1ff18
PB
19007 switch (tag)
19008 {
19009 case 1:
2b692964 19010 printf (_("File Attributes\n"));
11c1ff18
PB
19011 break;
19012 case 2:
2b692964 19013 printf (_("Section Attributes:"));
11c1ff18
PB
19014 goto do_numlist;
19015 case 3:
2b692964 19016 printf (_("Symbol Attributes:"));
1a0670f3 19017 /* Fall through. */
11c1ff18
PB
19018 do_numlist:
19019 for (;;)
19020 {
cd30bcef 19021 READ_ULEB (val, p, end);
11c1ff18
PB
19022 if (val == 0)
19023 break;
19024 printf (" %d", val);
19025 }
19026 printf ("\n");
19027 break;
19028 default:
2b692964 19029 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 19030 public_section = false;
11c1ff18
PB
19031 break;
19032 }
60bca95a 19033
071436c6 19034 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
19035 {
19036 while (p < end)
f6f0e17b 19037 p = display_pub_attribute (p, end);
60abdbed 19038 assert (p == end);
104d59d1 19039 }
071436c6 19040 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
19041 {
19042 while (p < end)
19043 p = display_gnu_attribute (p,
f6f0e17b
NC
19044 display_proc_gnu_attribute,
19045 end);
60abdbed 19046 assert (p == end);
11c1ff18 19047 }
071436c6 19048 else if (p < end)
11c1ff18 19049 {
071436c6 19050 printf (_(" Unknown attribute:\n"));
f6f0e17b 19051 display_raw_attribute (p, end);
11c1ff18
PB
19052 p = end;
19053 }
071436c6
NC
19054 else
19055 attr_len = 0;
11c1ff18
PB
19056 }
19057 }
19058 }
d70c5fc7 19059
60bca95a 19060 free (contents);
11c1ff18 19061 }
32ec8896
NC
19062
19063 return res;
11c1ff18
PB
19064}
19065
ccb4c951
RS
19066/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
19067 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
19068 and return the VMA of the next entry, or -1 if there was a problem.
19069 Does not read from DATA_END or beyond. */
ccb4c951 19070
625d49fc
AM
19071static uint64_t
19072print_mips_got_entry (unsigned char * data, uint64_t pltgot, uint64_t addr,
82b1b41b 19073 unsigned char * data_end)
ccb4c951
RS
19074{
19075 printf (" ");
19076 print_vma (addr, LONG_HEX);
19077 printf (" ");
19078 if (addr < pltgot + 0xfff0)
19079 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
19080 else
19081 printf ("%10s", "");
19082 printf (" ");
19083 if (data == NULL)
2b692964 19084 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
19085 else
19086 {
625d49fc 19087 uint64_t entry;
82b1b41b 19088 unsigned char * from = data + addr - pltgot;
ccb4c951 19089
82b1b41b
NC
19090 if (from + (is_32bit_elf ? 4 : 8) > data_end)
19091 {
19092 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
19093 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
625d49fc 19094 return (uint64_t) -1;
82b1b41b
NC
19095 }
19096 else
19097 {
19098 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19099 print_vma (entry, LONG_HEX);
19100 }
ccb4c951
RS
19101 }
19102 return addr + (is_32bit_elf ? 4 : 8);
19103}
19104
861fb55a
DJ
19105/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
19106 PLTGOT. Print the Address and Initial fields of an entry at VMA
19107 ADDR and return the VMA of the next entry. */
19108
625d49fc
AM
19109static uint64_t
19110print_mips_pltgot_entry (unsigned char * data, uint64_t pltgot, uint64_t addr)
861fb55a
DJ
19111{
19112 printf (" ");
19113 print_vma (addr, LONG_HEX);
19114 printf (" ");
19115 if (data == NULL)
2b692964 19116 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
19117 else
19118 {
625d49fc 19119 uint64_t entry;
861fb55a
DJ
19120
19121 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
19122 print_vma (entry, LONG_HEX);
19123 }
19124 return addr + (is_32bit_elf ? 4 : 8);
19125}
19126
351cdf24
MF
19127static void
19128print_mips_ases (unsigned int mask)
19129{
19130 if (mask & AFL_ASE_DSP)
19131 fputs ("\n\tDSP ASE", stdout);
19132 if (mask & AFL_ASE_DSPR2)
19133 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
19134 if (mask & AFL_ASE_DSPR3)
19135 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
19136 if (mask & AFL_ASE_EVA)
19137 fputs ("\n\tEnhanced VA Scheme", stdout);
19138 if (mask & AFL_ASE_MCU)
19139 fputs ("\n\tMCU (MicroController) ASE", stdout);
19140 if (mask & AFL_ASE_MDMX)
19141 fputs ("\n\tMDMX ASE", stdout);
19142 if (mask & AFL_ASE_MIPS3D)
19143 fputs ("\n\tMIPS-3D ASE", stdout);
19144 if (mask & AFL_ASE_MT)
19145 fputs ("\n\tMT ASE", stdout);
19146 if (mask & AFL_ASE_SMARTMIPS)
19147 fputs ("\n\tSmartMIPS ASE", stdout);
19148 if (mask & AFL_ASE_VIRT)
19149 fputs ("\n\tVZ ASE", stdout);
19150 if (mask & AFL_ASE_MSA)
19151 fputs ("\n\tMSA ASE", stdout);
19152 if (mask & AFL_ASE_MIPS16)
19153 fputs ("\n\tMIPS16 ASE", stdout);
19154 if (mask & AFL_ASE_MICROMIPS)
19155 fputs ("\n\tMICROMIPS ASE", stdout);
19156 if (mask & AFL_ASE_XPA)
19157 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
19158 if (mask & AFL_ASE_MIPS16E2)
19159 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
19160 if (mask & AFL_ASE_CRC)
19161 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
19162 if (mask & AFL_ASE_GINV)
19163 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
19164 if (mask & AFL_ASE_LOONGSON_MMI)
19165 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
19166 if (mask & AFL_ASE_LOONGSON_CAM)
19167 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
19168 if (mask & AFL_ASE_LOONGSON_EXT)
19169 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
19170 if (mask & AFL_ASE_LOONGSON_EXT2)
19171 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
19172 if (mask == 0)
19173 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
19174 else if ((mask & ~AFL_ASE_MASK) != 0)
19175 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
19176}
19177
19178static void
19179print_mips_isa_ext (unsigned int isa_ext)
19180{
19181 switch (isa_ext)
19182 {
19183 case 0:
19184 fputs (_("None"), stdout);
19185 break;
19186 case AFL_EXT_XLR:
19187 fputs ("RMI XLR", stdout);
19188 break;
2c629856
N
19189 case AFL_EXT_OCTEON3:
19190 fputs ("Cavium Networks Octeon3", stdout);
19191 break;
351cdf24
MF
19192 case AFL_EXT_OCTEON2:
19193 fputs ("Cavium Networks Octeon2", stdout);
19194 break;
19195 case AFL_EXT_OCTEONP:
19196 fputs ("Cavium Networks OcteonP", stdout);
19197 break;
351cdf24
MF
19198 case AFL_EXT_OCTEON:
19199 fputs ("Cavium Networks Octeon", stdout);
19200 break;
19201 case AFL_EXT_5900:
19202 fputs ("Toshiba R5900", stdout);
19203 break;
19204 case AFL_EXT_4650:
19205 fputs ("MIPS R4650", stdout);
19206 break;
19207 case AFL_EXT_4010:
19208 fputs ("LSI R4010", stdout);
19209 break;
19210 case AFL_EXT_4100:
19211 fputs ("NEC VR4100", stdout);
19212 break;
19213 case AFL_EXT_3900:
19214 fputs ("Toshiba R3900", stdout);
19215 break;
19216 case AFL_EXT_10000:
19217 fputs ("MIPS R10000", stdout);
19218 break;
19219 case AFL_EXT_SB1:
19220 fputs ("Broadcom SB-1", stdout);
19221 break;
19222 case AFL_EXT_4111:
19223 fputs ("NEC VR4111/VR4181", stdout);
19224 break;
19225 case AFL_EXT_4120:
19226 fputs ("NEC VR4120", stdout);
19227 break;
19228 case AFL_EXT_5400:
19229 fputs ("NEC VR5400", stdout);
19230 break;
19231 case AFL_EXT_5500:
19232 fputs ("NEC VR5500", stdout);
19233 break;
19234 case AFL_EXT_LOONGSON_2E:
19235 fputs ("ST Microelectronics Loongson 2E", stdout);
19236 break;
19237 case AFL_EXT_LOONGSON_2F:
19238 fputs ("ST Microelectronics Loongson 2F", stdout);
19239 break;
38bf472a
MR
19240 case AFL_EXT_INTERAPTIV_MR2:
19241 fputs ("Imagination interAptiv MR2", stdout);
19242 break;
351cdf24 19243 default:
00ac7aa0 19244 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
19245 }
19246}
19247
32ec8896 19248static signed int
351cdf24
MF
19249get_mips_reg_size (int reg_size)
19250{
19251 return (reg_size == AFL_REG_NONE) ? 0
19252 : (reg_size == AFL_REG_32) ? 32
19253 : (reg_size == AFL_REG_64) ? 64
19254 : (reg_size == AFL_REG_128) ? 128
19255 : -1;
19256}
19257
015dc7e1 19258static bool
dda8d76d 19259process_mips_specific (Filedata * filedata)
5b18a4bc 19260{
2cf0635d 19261 Elf_Internal_Dyn * entry;
351cdf24 19262 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
19263 size_t liblist_offset = 0;
19264 size_t liblistno = 0;
19265 size_t conflictsno = 0;
19266 size_t options_offset = 0;
19267 size_t conflicts_offset = 0;
861fb55a
DJ
19268 size_t pltrelsz = 0;
19269 size_t pltrel = 0;
625d49fc
AM
19270 uint64_t pltgot = 0;
19271 uint64_t mips_pltgot = 0;
19272 uint64_t jmprel = 0;
19273 uint64_t local_gotno = 0;
19274 uint64_t gotsym = 0;
19275 uint64_t symtabno = 0;
015dc7e1 19276 bool res = true;
103f02d3 19277
dda8d76d 19278 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 19279 display_mips_gnu_attribute))
015dc7e1 19280 res = false;
2cf19d5c 19281
dda8d76d 19282 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
19283
19284 if (sect != NULL)
19285 {
19286 Elf_External_ABIFlags_v0 *abiflags_ext;
19287 Elf_Internal_ABIFlags_v0 abiflags_in;
19288
19289 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
19290 {
19291 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 19292 res = false;
32ec8896 19293 }
351cdf24
MF
19294 else
19295 {
dda8d76d 19296 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
19297 sect->sh_size, _("MIPS ABI Flags section"));
19298 if (abiflags_ext)
19299 {
19300 abiflags_in.version = BYTE_GET (abiflags_ext->version);
19301 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
19302 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
19303 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
19304 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
19305 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
19306 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
19307 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
19308 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
19309 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
19310 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
19311
19312 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
19313 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
19314 if (abiflags_in.isa_rev > 1)
19315 printf ("r%d", abiflags_in.isa_rev);
19316 printf ("\nGPR size: %d",
19317 get_mips_reg_size (abiflags_in.gpr_size));
19318 printf ("\nCPR1 size: %d",
19319 get_mips_reg_size (abiflags_in.cpr1_size));
19320 printf ("\nCPR2 size: %d",
19321 get_mips_reg_size (abiflags_in.cpr2_size));
19322 fputs ("\nFP ABI: ", stdout);
19323 print_mips_fp_abi_value (abiflags_in.fp_abi);
19324 fputs ("ISA Extension: ", stdout);
19325 print_mips_isa_ext (abiflags_in.isa_ext);
19326 fputs ("\nASEs:", stdout);
19327 print_mips_ases (abiflags_in.ases);
19328 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
19329 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
19330 fputc ('\n', stdout);
19331 free (abiflags_ext);
19332 }
19333 }
19334 }
19335
19e6b90e 19336 /* We have a lot of special sections. Thanks SGI! */
978c4450 19337 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
19338 {
19339 /* No dynamic information available. See if there is static GOT. */
dda8d76d 19340 sect = find_section (filedata, ".got");
bbdd9a68
MR
19341 if (sect != NULL)
19342 {
19343 unsigned char *data_end;
19344 unsigned char *data;
625d49fc 19345 uint64_t ent, end;
bbdd9a68
MR
19346 int addr_size;
19347
19348 pltgot = sect->sh_addr;
19349
19350 ent = pltgot;
19351 addr_size = (is_32bit_elf ? 4 : 8);
19352 end = pltgot + sect->sh_size;
19353
dda8d76d 19354 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
19355 end - pltgot, 1,
19356 _("Global Offset Table data"));
19357 /* PR 12855: Null data is handled gracefully throughout. */
19358 data_end = data + (end - pltgot);
19359
19360 printf (_("\nStatic GOT:\n"));
19361 printf (_(" Canonical gp value: "));
19362 print_vma (ent + 0x7ff0, LONG_HEX);
19363 printf ("\n\n");
19364
19365 /* In a dynamic binary GOT[0] is reserved for the dynamic
19366 loader to store the lazy resolver pointer, however in
19367 a static binary it may well have been omitted and GOT
19368 reduced to a table of addresses.
19369 PR 21344: Check for the entry being fully available
19370 before fetching it. */
19371 if (data
19372 && data + ent - pltgot + addr_size <= data_end
19373 && byte_get (data + ent - pltgot, addr_size) == 0)
19374 {
19375 printf (_(" Reserved entries:\n"));
19376 printf (_(" %*s %10s %*s\n"),
19377 addr_size * 2, _("Address"), _("Access"),
19378 addr_size * 2, _("Value"));
19379 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19380 printf ("\n");
625d49fc 19381 if (ent == (uint64_t) -1)
bbdd9a68
MR
19382 goto sgot_print_fail;
19383
19384 /* Check for the MSB of GOT[1] being set, identifying a
19385 GNU object. This entry will be used by some runtime
19386 loaders, to store the module pointer. Otherwise this
19387 is an ordinary local entry.
19388 PR 21344: Check for the entry being fully available
19389 before fetching it. */
19390 if (data
19391 && data + ent - pltgot + addr_size <= data_end
19392 && (byte_get (data + ent - pltgot, addr_size)
19393 >> (addr_size * 8 - 1)) != 0)
19394 {
19395 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19396 printf ("\n");
625d49fc 19397 if (ent == (uint64_t) -1)
bbdd9a68
MR
19398 goto sgot_print_fail;
19399 }
19400 printf ("\n");
19401 }
19402
f17e9d8a 19403 if (data != NULL && ent < end)
bbdd9a68
MR
19404 {
19405 printf (_(" Local entries:\n"));
19406 printf (" %*s %10s %*s\n",
19407 addr_size * 2, _("Address"), _("Access"),
19408 addr_size * 2, _("Value"));
19409 while (ent < end)
19410 {
19411 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19412 printf ("\n");
625d49fc 19413 if (ent == (uint64_t) -1)
bbdd9a68
MR
19414 goto sgot_print_fail;
19415 }
19416 printf ("\n");
19417 }
19418
19419 sgot_print_fail:
9db70fc3 19420 free (data);
bbdd9a68
MR
19421 }
19422 return res;
19423 }
252b5132 19424
978c4450 19425 for (entry = filedata->dynamic_section;
071436c6 19426 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
19427 (entry < filedata->dynamic_section + filedata->dynamic_nent
19428 && entry->d_tag != DT_NULL);
071436c6 19429 ++entry)
252b5132
RH
19430 switch (entry->d_tag)
19431 {
19432 case DT_MIPS_LIBLIST:
d93f0186 19433 liblist_offset
dda8d76d 19434 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19435 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
19436 break;
19437 case DT_MIPS_LIBLISTNO:
19438 liblistno = entry->d_un.d_val;
19439 break;
19440 case DT_MIPS_OPTIONS:
dda8d76d 19441 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
19442 break;
19443 case DT_MIPS_CONFLICT:
d93f0186 19444 conflicts_offset
dda8d76d 19445 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 19446 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
19447 break;
19448 case DT_MIPS_CONFLICTNO:
19449 conflictsno = entry->d_un.d_val;
19450 break;
ccb4c951 19451 case DT_PLTGOT:
861fb55a
DJ
19452 pltgot = entry->d_un.d_ptr;
19453 break;
ccb4c951
RS
19454 case DT_MIPS_LOCAL_GOTNO:
19455 local_gotno = entry->d_un.d_val;
19456 break;
19457 case DT_MIPS_GOTSYM:
19458 gotsym = entry->d_un.d_val;
19459 break;
19460 case DT_MIPS_SYMTABNO:
19461 symtabno = entry->d_un.d_val;
19462 break;
861fb55a
DJ
19463 case DT_MIPS_PLTGOT:
19464 mips_pltgot = entry->d_un.d_ptr;
19465 break;
19466 case DT_PLTREL:
19467 pltrel = entry->d_un.d_val;
19468 break;
19469 case DT_PLTRELSZ:
19470 pltrelsz = entry->d_un.d_val;
19471 break;
19472 case DT_JMPREL:
19473 jmprel = entry->d_un.d_ptr;
19474 break;
252b5132
RH
19475 default:
19476 break;
19477 }
19478
19479 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
19480 {
2cf0635d 19481 Elf32_External_Lib * elib;
252b5132
RH
19482 size_t cnt;
19483
dda8d76d 19484 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
19485 sizeof (Elf32_External_Lib),
19486 liblistno,
19487 _("liblist section data"));
a6e9f9df 19488 if (elib)
252b5132 19489 {
26c527e6
AM
19490 printf (ngettext ("\nSection '.liblist' contains %zu entry:\n",
19491 "\nSection '.liblist' contains %zu entries:\n",
19492 liblistno),
19493 liblistno);
2b692964 19494 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
19495 stdout);
19496
19497 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 19498 {
a6e9f9df 19499 Elf32_Lib liblist;
91d6fa6a 19500 time_t atime;
d5b07ef4 19501 char timebuf[128];
2cf0635d 19502 struct tm * tmp;
a6e9f9df
AM
19503
19504 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19505 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
19506 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19507 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19508 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19509
91d6fa6a 19510 tmp = gmtime (&atime);
e9e44622
JJ
19511 snprintf (timebuf, sizeof (timebuf),
19512 "%04u-%02u-%02uT%02u:%02u:%02u",
19513 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19514 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 19515
26c527e6 19516 printf ("%3zu: ", cnt);
84714f86 19517 if (valid_dynamic_name (filedata, liblist.l_name))
b6ac461a 19518 print_symbol_name (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 19519 else
2b692964 19520 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
19521 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
19522 liblist.l_version);
a6e9f9df
AM
19523
19524 if (liblist.l_flags == 0)
2b692964 19525 puts (_(" NONE"));
a6e9f9df
AM
19526 else
19527 {
19528 static const struct
252b5132 19529 {
2cf0635d 19530 const char * name;
a6e9f9df 19531 int bit;
252b5132 19532 }
a6e9f9df
AM
19533 l_flags_vals[] =
19534 {
19535 { " EXACT_MATCH", LL_EXACT_MATCH },
19536 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
19537 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
19538 { " EXPORTS", LL_EXPORTS },
19539 { " DELAY_LOAD", LL_DELAY_LOAD },
19540 { " DELTA", LL_DELTA }
19541 };
19542 int flags = liblist.l_flags;
19543 size_t fcnt;
19544
60bca95a 19545 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
19546 if ((flags & l_flags_vals[fcnt].bit) != 0)
19547 {
19548 fputs (l_flags_vals[fcnt].name, stdout);
19549 flags ^= l_flags_vals[fcnt].bit;
19550 }
19551 if (flags != 0)
19552 printf (" %#x", (unsigned int) flags);
252b5132 19553
a6e9f9df
AM
19554 puts ("");
19555 }
252b5132 19556 }
252b5132 19557
a6e9f9df
AM
19558 free (elib);
19559 }
32ec8896 19560 else
015dc7e1 19561 res = false;
252b5132
RH
19562 }
19563
19564 if (options_offset != 0)
19565 {
2cf0635d 19566 Elf_External_Options * eopt;
252b5132
RH
19567 size_t offset;
19568 int cnt;
19569
19570 /* Find the section header so that we get the size. */
dda8d76d 19571 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 19572 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
19573 if (sect == NULL)
19574 {
19575 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 19576 return false;
071436c6 19577 }
7fc0c668
NC
19578 /* PR 24243 */
19579 if (sect->sh_size < sizeof (* eopt))
19580 {
19581 error (_("The MIPS options section is too small.\n"));
015dc7e1 19582 return false;
7fc0c668 19583 }
252b5132 19584
dda8d76d 19585 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 19586 sect->sh_size, _("options"));
a6e9f9df 19587 if (eopt)
252b5132 19588 {
fd17d1e6 19589 Elf_Internal_Options option;
76da6bbe 19590
a6e9f9df 19591 offset = cnt = 0;
82b1b41b 19592 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 19593 {
2cf0635d 19594 Elf_External_Options * eoption;
fd17d1e6 19595 unsigned int optsize;
252b5132 19596
a6e9f9df 19597 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 19598
fd17d1e6 19599 optsize = BYTE_GET (eoption->size);
76da6bbe 19600
82b1b41b 19601 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
19602 if (optsize < sizeof (* eopt)
19603 || optsize > sect->sh_size - offset)
82b1b41b 19604 {
645f43a8 19605 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 19606 optsize);
645f43a8 19607 free (eopt);
015dc7e1 19608 return false;
82b1b41b 19609 }
fd17d1e6 19610 offset += optsize;
a6e9f9df
AM
19611 ++cnt;
19612 }
252b5132 19613
d3a49aa8
AM
19614 printf (ngettext ("\nSection '%s' contains %d entry:\n",
19615 "\nSection '%s' contains %d entries:\n",
19616 cnt),
dda8d76d 19617 printable_section_name (filedata, sect), cnt);
76da6bbe 19618
82b1b41b 19619 offset = 0;
a6e9f9df 19620 while (cnt-- > 0)
252b5132 19621 {
a6e9f9df 19622 size_t len;
fd17d1e6
AM
19623 Elf_External_Options * eoption;
19624
19625 eoption = (Elf_External_Options *) ((char *) eopt + offset);
19626
19627 option.kind = BYTE_GET (eoption->kind);
19628 option.size = BYTE_GET (eoption->size);
19629 option.section = BYTE_GET (eoption->section);
19630 option.info = BYTE_GET (eoption->info);
a6e9f9df 19631
fd17d1e6 19632 switch (option.kind)
252b5132 19633 {
a6e9f9df
AM
19634 case ODK_NULL:
19635 /* This shouldn't happen. */
d0c4e780 19636 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 19637 option.section, option.info);
a6e9f9df 19638 break;
2e6be59c 19639
a6e9f9df
AM
19640 case ODK_REGINFO:
19641 printf (" REGINFO ");
dda8d76d 19642 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 19643 {
2cf0635d 19644 Elf32_External_RegInfo * ereg;
b34976b6 19645 Elf32_RegInfo reginfo;
a6e9f9df 19646
2e6be59c 19647 /* 32bit form. */
fd17d1e6
AM
19648 if (option.size < (sizeof (Elf_External_Options)
19649 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
19650 {
19651 printf (_("<corrupt>\n"));
19652 error (_("Truncated MIPS REGINFO option\n"));
19653 cnt = 0;
19654 break;
19655 }
19656
fd17d1e6 19657 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 19658
a6e9f9df
AM
19659 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19660 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19661 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19662 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19663 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
19664 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
19665
d0c4e780
AM
19666 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
19667 reginfo.ri_gprmask, reginfo.ri_gp_value);
19668 printf (" "
19669 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19670 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19671 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19672 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19673 }
19674 else
19675 {
19676 /* 64 bit form. */
2cf0635d 19677 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
19678 Elf64_Internal_RegInfo reginfo;
19679
fd17d1e6
AM
19680 if (option.size < (sizeof (Elf_External_Options)
19681 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
19682 {
19683 printf (_("<corrupt>\n"));
19684 error (_("Truncated MIPS REGINFO option\n"));
19685 cnt = 0;
19686 break;
19687 }
19688
fd17d1e6 19689 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
19690 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
19691 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
19692 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
19693 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
19694 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 19695 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 19696
d0c4e780
AM
19697 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
19698 reginfo.ri_gprmask, reginfo.ri_gp_value);
19699 printf (" "
19700 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
19701 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
19702 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
19703 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
19704 }
fd17d1e6 19705 offset += option.size;
a6e9f9df 19706 continue;
2e6be59c 19707
a6e9f9df
AM
19708 case ODK_EXCEPTIONS:
19709 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 19710 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 19711 fputs (") fpe_max(", stdout);
fd17d1e6 19712 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
19713 fputs (")", stdout);
19714
fd17d1e6 19715 if (option.info & OEX_PAGE0)
a6e9f9df 19716 fputs (" PAGE0", stdout);
fd17d1e6 19717 if (option.info & OEX_SMM)
a6e9f9df 19718 fputs (" SMM", stdout);
fd17d1e6 19719 if (option.info & OEX_FPDBUG)
a6e9f9df 19720 fputs (" FPDBUG", stdout);
fd17d1e6 19721 if (option.info & OEX_DISMISS)
a6e9f9df
AM
19722 fputs (" DISMISS", stdout);
19723 break;
2e6be59c 19724
a6e9f9df
AM
19725 case ODK_PAD:
19726 fputs (" PAD ", stdout);
fd17d1e6 19727 if (option.info & OPAD_PREFIX)
a6e9f9df 19728 fputs (" PREFIX", stdout);
fd17d1e6 19729 if (option.info & OPAD_POSTFIX)
a6e9f9df 19730 fputs (" POSTFIX", stdout);
fd17d1e6 19731 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
19732 fputs (" SYMBOL", stdout);
19733 break;
2e6be59c 19734
a6e9f9df
AM
19735 case ODK_HWPATCH:
19736 fputs (" HWPATCH ", stdout);
fd17d1e6 19737 if (option.info & OHW_R4KEOP)
a6e9f9df 19738 fputs (" R4KEOP", stdout);
fd17d1e6 19739 if (option.info & OHW_R8KPFETCH)
a6e9f9df 19740 fputs (" R8KPFETCH", stdout);
fd17d1e6 19741 if (option.info & OHW_R5KEOP)
a6e9f9df 19742 fputs (" R5KEOP", stdout);
fd17d1e6 19743 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
19744 fputs (" R5KCVTL", stdout);
19745 break;
2e6be59c 19746
a6e9f9df
AM
19747 case ODK_FILL:
19748 fputs (" FILL ", stdout);
19749 /* XXX Print content of info word? */
19750 break;
2e6be59c 19751
a6e9f9df
AM
19752 case ODK_TAGS:
19753 fputs (" TAGS ", stdout);
19754 /* XXX Print content of info word? */
19755 break;
2e6be59c 19756
a6e9f9df
AM
19757 case ODK_HWAND:
19758 fputs (" HWAND ", stdout);
fd17d1e6 19759 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19760 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19761 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19762 fputs (" R4KEOP_CLEAN", stdout);
19763 break;
2e6be59c 19764
a6e9f9df
AM
19765 case ODK_HWOR:
19766 fputs (" HWOR ", stdout);
fd17d1e6 19767 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 19768 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 19769 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
19770 fputs (" R4KEOP_CLEAN", stdout);
19771 break;
2e6be59c 19772
a6e9f9df 19773 case ODK_GP_GROUP:
d0c4e780 19774 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
19775 option.info & OGP_GROUP,
19776 (option.info & OGP_SELF) >> 16);
a6e9f9df 19777 break;
2e6be59c 19778
a6e9f9df 19779 case ODK_IDENT:
d0c4e780 19780 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
19781 option.info & OGP_GROUP,
19782 (option.info & OGP_SELF) >> 16);
a6e9f9df 19783 break;
2e6be59c 19784
a6e9f9df
AM
19785 default:
19786 /* This shouldn't happen. */
d0c4e780 19787 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 19788 option.kind, option.section, option.info);
a6e9f9df 19789 break;
252b5132 19790 }
a6e9f9df 19791
2cf0635d 19792 len = sizeof (* eopt);
fd17d1e6 19793 while (len < option.size)
82b1b41b 19794 {
fd17d1e6 19795 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 19796
82b1b41b
NC
19797 if (ISPRINT (datum))
19798 printf ("%c", datum);
19799 else
19800 printf ("\\%03o", datum);
19801 len ++;
19802 }
a6e9f9df 19803 fputs ("\n", stdout);
82b1b41b 19804
fd17d1e6 19805 offset += option.size;
252b5132 19806 }
a6e9f9df 19807 free (eopt);
252b5132 19808 }
32ec8896 19809 else
015dc7e1 19810 res = false;
252b5132
RH
19811 }
19812
19813 if (conflicts_offset != 0 && conflictsno != 0)
19814 {
2cf0635d 19815 Elf32_Conflict * iconf;
252b5132
RH
19816 size_t cnt;
19817
978c4450 19818 if (filedata->dynamic_symbols == NULL)
252b5132 19819 {
591a748a 19820 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 19821 return false;
252b5132
RH
19822 }
19823
7296a62a
NC
19824 /* PR 21345 - print a slightly more helpful error message
19825 if we are sure that the cmalloc will fail. */
645f43a8 19826 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a 19827 {
26c527e6
AM
19828 error (_("Overlarge number of conflicts detected: %zx\n"),
19829 conflictsno);
015dc7e1 19830 return false;
7296a62a
NC
19831 }
19832
3f5e193b 19833 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
19834 if (iconf == NULL)
19835 {
8b73c356 19836 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 19837 return false;
252b5132
RH
19838 }
19839
9ea033b2 19840 if (is_32bit_elf)
252b5132 19841 {
2cf0635d 19842 Elf32_External_Conflict * econf32;
a6e9f9df 19843
3f5e193b 19844 econf32 = (Elf32_External_Conflict *)
95099889
AM
19845 get_data (NULL, filedata, conflicts_offset,
19846 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 19847 if (!econf32)
5a814d6d
AM
19848 {
19849 free (iconf);
015dc7e1 19850 return false;
5a814d6d 19851 }
252b5132
RH
19852
19853 for (cnt = 0; cnt < conflictsno; ++cnt)
19854 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
19855
19856 free (econf32);
252b5132
RH
19857 }
19858 else
19859 {
2cf0635d 19860 Elf64_External_Conflict * econf64;
a6e9f9df 19861
3f5e193b 19862 econf64 = (Elf64_External_Conflict *)
95099889
AM
19863 get_data (NULL, filedata, conflicts_offset,
19864 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 19865 if (!econf64)
5a814d6d
AM
19866 {
19867 free (iconf);
015dc7e1 19868 return false;
5a814d6d 19869 }
252b5132
RH
19870
19871 for (cnt = 0; cnt < conflictsno; ++cnt)
19872 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
19873
19874 free (econf64);
252b5132
RH
19875 }
19876
26c527e6
AM
19877 printf (ngettext ("\nSection '.conflict' contains %zu entry:\n",
19878 "\nSection '.conflict' contains %zu entries:\n",
19879 conflictsno),
19880 conflictsno);
252b5132
RH
19881 puts (_(" Num: Index Value Name"));
19882
19883 for (cnt = 0; cnt < conflictsno; ++cnt)
19884 {
26c527e6 19885 printf ("%5zu: %8lu ", cnt, iconf[cnt]);
e0a31db1 19886
978c4450 19887 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 19888 printf (_("<corrupt symbol index>"));
d79b3d50 19889 else
e0a31db1
NC
19890 {
19891 Elf_Internal_Sym * psym;
19892
978c4450 19893 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
19894 print_vma (psym->st_value, FULL_HEX);
19895 putchar (' ');
84714f86 19896 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 19897 print_symbol_name (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
19898 else
19899 printf (_("<corrupt: %14ld>"), psym->st_name);
19900 }
31104126 19901 putchar ('\n');
252b5132
RH
19902 }
19903
252b5132
RH
19904 free (iconf);
19905 }
19906
ccb4c951
RS
19907 if (pltgot != 0 && local_gotno != 0)
19908 {
625d49fc 19909 uint64_t ent, local_end, global_end;
bbeee7ea 19910 size_t i, offset;
2cf0635d 19911 unsigned char * data;
82b1b41b 19912 unsigned char * data_end;
bbeee7ea 19913 int addr_size;
ccb4c951 19914
91d6fa6a 19915 ent = pltgot;
ccb4c951
RS
19916 addr_size = (is_32bit_elf ? 4 : 8);
19917 local_end = pltgot + local_gotno * addr_size;
ccb4c951 19918
74e1a04b
NC
19919 /* PR binutils/17533 file: 012-111227-0.004 */
19920 if (symtabno < gotsym)
19921 {
26c527e6
AM
19922 error (_("The GOT symbol offset (%" PRIu64
19923 ") is greater than the symbol table size (%" PRIu64 ")\n"),
19924 gotsym, symtabno);
015dc7e1 19925 return false;
74e1a04b 19926 }
82b1b41b 19927
74e1a04b 19928 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
19929 /* PR 17531: file: 54c91a34. */
19930 if (global_end < local_end)
19931 {
26c527e6 19932 error (_("Too many GOT symbols: %" PRIu64 "\n"), symtabno);
015dc7e1 19933 return false;
82b1b41b 19934 }
948f632f 19935
dda8d76d
NC
19936 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
19937 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
19938 global_end - pltgot, 1,
19939 _("Global Offset Table data"));
919383ac 19940 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 19941 data_end = data + (global_end - pltgot);
59245841 19942
ccb4c951
RS
19943 printf (_("\nPrimary GOT:\n"));
19944 printf (_(" Canonical gp value: "));
19945 print_vma (pltgot + 0x7ff0, LONG_HEX);
19946 printf ("\n\n");
19947
19948 printf (_(" Reserved entries:\n"));
19949 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
19950 addr_size * 2, _("Address"), _("Access"),
19951 addr_size * 2, _("Initial"));
82b1b41b 19952 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 19953 printf (_(" Lazy resolver\n"));
625d49fc 19954 if (ent == (uint64_t) -1)
82b1b41b 19955 goto got_print_fail;
75ec1fdb 19956
c4ab9505
MR
19957 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
19958 This entry will be used by some runtime loaders, to store the
19959 module pointer. Otherwise this is an ordinary local entry.
19960 PR 21344: Check for the entry being fully available before
19961 fetching it. */
19962 if (data
19963 && data + ent - pltgot + addr_size <= data_end
19964 && (byte_get (data + ent - pltgot, addr_size)
19965 >> (addr_size * 8 - 1)) != 0)
19966 {
19967 ent = print_mips_got_entry (data, pltgot, ent, data_end);
19968 printf (_(" Module pointer (GNU extension)\n"));
625d49fc 19969 if (ent == (uint64_t) -1)
c4ab9505 19970 goto got_print_fail;
ccb4c951
RS
19971 }
19972 printf ("\n");
19973
f17e9d8a 19974 if (data != NULL && ent < local_end)
ccb4c951
RS
19975 {
19976 printf (_(" Local entries:\n"));
cc5914eb 19977 printf (" %*s %10s %*s\n",
2b692964
NC
19978 addr_size * 2, _("Address"), _("Access"),
19979 addr_size * 2, _("Initial"));
91d6fa6a 19980 while (ent < local_end)
ccb4c951 19981 {
82b1b41b 19982 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 19983 printf ("\n");
625d49fc 19984 if (ent == (uint64_t) -1)
82b1b41b 19985 goto got_print_fail;
ccb4c951
RS
19986 }
19987 printf ("\n");
19988 }
19989
f17e9d8a 19990 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
19991 {
19992 int sym_width;
19993
19994 printf (_(" Global entries:\n"));
cc5914eb 19995 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
19996 addr_size * 2, _("Address"),
19997 _("Access"),
2b692964 19998 addr_size * 2, _("Initial"),
9cf03b7e
NC
19999 addr_size * 2, _("Sym.Val."),
20000 _("Type"),
20001 /* Note for translators: "Ndx" = abbreviated form of "Index". */
20002 _("Ndx"), _("Name"));
0b4362b0 20003
ccb4c951 20004 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 20005
ccb4c951
RS
20006 for (i = gotsym; i < symtabno; i++)
20007 {
82b1b41b 20008 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 20009 printf (" ");
e0a31db1 20010
978c4450 20011 if (filedata->dynamic_symbols == NULL)
e0a31db1 20012 printf (_("<no dynamic symbols>"));
978c4450 20013 else if (i < filedata->num_dynamic_syms)
e0a31db1 20014 {
978c4450 20015 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
20016
20017 print_vma (psym->st_value, LONG_HEX);
b6ac461a
NC
20018 printf (" %-7s ", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
20019
20020 bool is_special;
20021 const char * s = printable_section_name_from_index (filedata, psym->st_shndx, & is_special);
20022 if (is_special)
20023 printf ("%3s ", s);
20024 else
20025 printf ("%3u ", psym->st_shndx);
e0a31db1 20026
84714f86 20027 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20028 print_symbol_name (sym_width,
84714f86 20029 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20030 else
20031 printf (_("<corrupt: %14ld>"), psym->st_name);
20032 }
ccb4c951 20033 else
26c527e6
AM
20034 printf (_("<symbol index %zu exceeds number of dynamic symbols>"),
20035 i);
e0a31db1 20036
ccb4c951 20037 printf ("\n");
625d49fc 20038 if (ent == (uint64_t) -1)
82b1b41b 20039 break;
ccb4c951
RS
20040 }
20041 printf ("\n");
20042 }
20043
82b1b41b 20044 got_print_fail:
9db70fc3 20045 free (data);
ccb4c951
RS
20046 }
20047
861fb55a
DJ
20048 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
20049 {
625d49fc 20050 uint64_t ent, end;
26c527e6
AM
20051 uint64_t offset, rel_offset;
20052 uint64_t count, i;
2cf0635d 20053 unsigned char * data;
861fb55a 20054 int addr_size, sym_width;
2cf0635d 20055 Elf_Internal_Rela * rels;
861fb55a 20056
dda8d76d 20057 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
20058 if (pltrel == DT_RELA)
20059 {
dda8d76d 20060 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20061 return false;
861fb55a
DJ
20062 }
20063 else
20064 {
dda8d76d 20065 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 20066 return false;
861fb55a
DJ
20067 }
20068
91d6fa6a 20069 ent = mips_pltgot;
861fb55a
DJ
20070 addr_size = (is_32bit_elf ? 4 : 8);
20071 end = mips_pltgot + (2 + count) * addr_size;
20072
dda8d76d
NC
20073 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
20074 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 20075 1, _("Procedure Linkage Table data"));
59245841 20076 if (data == NULL)
288f0ba2
AM
20077 {
20078 free (rels);
015dc7e1 20079 return false;
288f0ba2 20080 }
59245841 20081
9cf03b7e 20082 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
20083 printf (_(" Reserved entries:\n"));
20084 printf (_(" %*s %*s Purpose\n"),
2b692964 20085 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 20086 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20087 printf (_(" PLT lazy resolver\n"));
91d6fa6a 20088 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 20089 printf (_(" Module pointer\n"));
861fb55a
DJ
20090 printf ("\n");
20091
20092 printf (_(" Entries:\n"));
cc5914eb 20093 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
20094 addr_size * 2, _("Address"),
20095 addr_size * 2, _("Initial"),
20096 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
20097 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
20098 for (i = 0; i < count; i++)
20099 {
26c527e6 20100 uint64_t idx = get_reloc_symindex (rels[i].r_info);
861fb55a 20101
91d6fa6a 20102 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 20103 printf (" ");
e0a31db1 20104
978c4450 20105 if (idx >= filedata->num_dynamic_syms)
26c527e6 20106 printf (_("<corrupt symbol index: %" PRIu64 ">"), idx);
861fb55a 20107 else
e0a31db1 20108 {
978c4450 20109 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
20110
20111 print_vma (psym->st_value, LONG_HEX);
20112 printf (" %-7s %3s ",
dda8d76d 20113 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
b6ac461a 20114 printable_section_name_from_index (filedata, psym->st_shndx, NULL));
84714f86 20115 if (valid_dynamic_name (filedata, psym->st_name))
b6ac461a 20116 print_symbol_name (sym_width,
84714f86 20117 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
20118 else
20119 printf (_("<corrupt: %14ld>"), psym->st_name);
20120 }
861fb55a
DJ
20121 printf ("\n");
20122 }
20123 printf ("\n");
20124
9db70fc3 20125 free (data);
861fb55a
DJ
20126 free (rels);
20127 }
20128
32ec8896 20129 return res;
252b5132
RH
20130}
20131
015dc7e1 20132static bool
dda8d76d 20133process_nds32_specific (Filedata * filedata)
35c08157
KLC
20134{
20135 Elf_Internal_Shdr *sect = NULL;
20136
dda8d76d 20137 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 20138 if (sect != NULL && sect->sh_size >= 4)
35c08157 20139 {
9c7b8e9b
AM
20140 unsigned char *buf;
20141 unsigned int flag;
35c08157
KLC
20142
20143 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
20144 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
20145 _("NDS32 elf flags section"));
35c08157 20146
9c7b8e9b 20147 if (buf == NULL)
015dc7e1 20148 return false;
32ec8896 20149
9c7b8e9b
AM
20150 flag = byte_get (buf, 4);
20151 free (buf);
20152 switch (flag & 0x3)
35c08157
KLC
20153 {
20154 case 0:
20155 printf ("(VEC_SIZE):\tNo entry.\n");
20156 break;
20157 case 1:
20158 printf ("(VEC_SIZE):\t4 bytes\n");
20159 break;
20160 case 2:
20161 printf ("(VEC_SIZE):\t16 bytes\n");
20162 break;
20163 case 3:
20164 printf ("(VEC_SIZE):\treserved\n");
20165 break;
20166 }
20167 }
20168
015dc7e1 20169 return true;
35c08157
KLC
20170}
20171
015dc7e1 20172static bool
dda8d76d 20173process_gnu_liblist (Filedata * filedata)
047b2264 20174{
2cf0635d
NC
20175 Elf_Internal_Shdr * section;
20176 Elf_Internal_Shdr * string_sec;
20177 Elf32_External_Lib * elib;
20178 char * strtab;
c256ffe7 20179 size_t strtab_size;
047b2264 20180 size_t cnt;
26c527e6 20181 uint64_t num_liblist;
047b2264 20182 unsigned i;
015dc7e1 20183 bool res = true;
047b2264
JJ
20184
20185 if (! do_arch)
015dc7e1 20186 return true;
047b2264 20187
dda8d76d
NC
20188 for (i = 0, section = filedata->section_headers;
20189 i < filedata->file_header.e_shnum;
b34976b6 20190 i++, section++)
047b2264
JJ
20191 {
20192 switch (section->sh_type)
20193 {
20194 case SHT_GNU_LIBLIST:
dda8d76d 20195 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
20196 break;
20197
3f5e193b 20198 elib = (Elf32_External_Lib *)
dda8d76d 20199 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 20200 _("liblist section data"));
047b2264
JJ
20201
20202 if (elib == NULL)
32ec8896 20203 {
015dc7e1 20204 res = false;
32ec8896
NC
20205 break;
20206 }
047b2264 20207
dda8d76d
NC
20208 string_sec = filedata->section_headers + section->sh_link;
20209 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
20210 string_sec->sh_size,
20211 _("liblist string table"));
047b2264
JJ
20212 if (strtab == NULL
20213 || section->sh_entsize != sizeof (Elf32_External_Lib))
20214 {
20215 free (elib);
2842702f 20216 free (strtab);
015dc7e1 20217 res = false;
047b2264
JJ
20218 break;
20219 }
59245841 20220 strtab_size = string_sec->sh_size;
047b2264 20221
d3a49aa8 20222 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
26c527e6
AM
20223 printf (ngettext ("\nLibrary list section '%s' contains %" PRIu64
20224 " entries:\n",
20225 "\nLibrary list section '%s' contains %" PRIu64
20226 " entries:\n",
d3a49aa8 20227 num_liblist),
dda8d76d 20228 printable_section_name (filedata, section),
d3a49aa8 20229 num_liblist);
047b2264 20230
2b692964 20231 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
20232
20233 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
20234 ++cnt)
20235 {
20236 Elf32_Lib liblist;
91d6fa6a 20237 time_t atime;
d5b07ef4 20238 char timebuf[128];
2cf0635d 20239 struct tm * tmp;
047b2264
JJ
20240
20241 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 20242 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
20243 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
20244 liblist.l_version = BYTE_GET (elib[cnt].l_version);
20245 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
20246
91d6fa6a 20247 tmp = gmtime (&atime);
e9e44622
JJ
20248 snprintf (timebuf, sizeof (timebuf),
20249 "%04u-%02u-%02uT%02u:%02u:%02u",
20250 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
20251 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264 20252
26c527e6 20253 printf ("%3zu: ", cnt);
047b2264 20254 if (do_wide)
c256ffe7 20255 printf ("%-20s", liblist.l_name < strtab_size
2b692964 20256 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 20257 else
c256ffe7 20258 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 20259 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
20260 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
20261 liblist.l_version, liblist.l_flags);
20262 }
20263
20264 free (elib);
2842702f 20265 free (strtab);
047b2264
JJ
20266 }
20267 }
20268
32ec8896 20269 return res;
047b2264
JJ
20270}
20271
9437c45b 20272static const char *
dda8d76d 20273get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
20274{
20275 static char buff[64];
103f02d3 20276
dda8d76d 20277 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
20278 switch (e_type)
20279 {
57346661 20280 case NT_AUXV:
1ec5cd37 20281 return _("NT_AUXV (auxiliary vector)");
57346661 20282 case NT_PRSTATUS:
1ec5cd37 20283 return _("NT_PRSTATUS (prstatus structure)");
57346661 20284 case NT_FPREGSET:
1ec5cd37 20285 return _("NT_FPREGSET (floating point registers)");
57346661 20286 case NT_PRPSINFO:
1ec5cd37 20287 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 20288 case NT_TASKSTRUCT:
1ec5cd37 20289 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
20290 case NT_GDB_TDESC:
20291 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 20292 case NT_PRXFPREG:
1ec5cd37 20293 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
20294 case NT_PPC_VMX:
20295 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
20296 case NT_PPC_VSX:
20297 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
20298 case NT_PPC_TAR:
20299 return _("NT_PPC_TAR (ppc TAR register)");
20300 case NT_PPC_PPR:
20301 return _("NT_PPC_PPR (ppc PPR register)");
20302 case NT_PPC_DSCR:
20303 return _("NT_PPC_DSCR (ppc DSCR register)");
20304 case NT_PPC_EBB:
20305 return _("NT_PPC_EBB (ppc EBB registers)");
20306 case NT_PPC_PMU:
20307 return _("NT_PPC_PMU (ppc PMU registers)");
20308 case NT_PPC_TM_CGPR:
20309 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
20310 case NT_PPC_TM_CFPR:
20311 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
20312 case NT_PPC_TM_CVMX:
20313 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
20314 case NT_PPC_TM_CVSX:
3fd21718 20315 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
20316 case NT_PPC_TM_SPR:
20317 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
20318 case NT_PPC_TM_CTAR:
20319 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
20320 case NT_PPC_TM_CPPR:
20321 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
20322 case NT_PPC_TM_CDSCR:
20323 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
20324 case NT_386_TLS:
20325 return _("NT_386_TLS (x86 TLS information)");
20326 case NT_386_IOPERM:
20327 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
20328 case NT_X86_XSTATE:
20329 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
20330 case NT_X86_CET:
20331 return _("NT_X86_CET (x86 CET state)");
eccdc733
SC
20332 case NT_X86_SHSTK:
20333 return _("NT_X86_SHSTK (x86 SHSTK state)");
0675e188
UW
20334 case NT_S390_HIGH_GPRS:
20335 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
20336 case NT_S390_TIMER:
20337 return _("NT_S390_TIMER (s390 timer register)");
20338 case NT_S390_TODCMP:
20339 return _("NT_S390_TODCMP (s390 TOD comparator register)");
20340 case NT_S390_TODPREG:
20341 return _("NT_S390_TODPREG (s390 TOD programmable register)");
20342 case NT_S390_CTRS:
20343 return _("NT_S390_CTRS (s390 control registers)");
20344 case NT_S390_PREFIX:
20345 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
20346 case NT_S390_LAST_BREAK:
20347 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
20348 case NT_S390_SYSTEM_CALL:
20349 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
20350 case NT_S390_TDB:
20351 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
20352 case NT_S390_VXRS_LOW:
20353 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
20354 case NT_S390_VXRS_HIGH:
20355 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
20356 case NT_S390_GS_CB:
20357 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
20358 case NT_S390_GS_BC:
20359 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
20360 case NT_ARM_VFP:
20361 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
20362 case NT_ARM_TLS:
20363 return _("NT_ARM_TLS (AArch TLS registers)");
20364 case NT_ARM_HW_BREAK:
20365 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
20366 case NT_ARM_HW_WATCH:
20367 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
eb33f697
LM
20368 case NT_ARM_SYSTEM_CALL:
20369 return _("NT_ARM_SYSTEM_CALL (AArch system call number)");
3b2bef8b
LM
20370 case NT_ARM_SVE:
20371 return _("NT_ARM_SVE (AArch SVE registers)");
20372 case NT_ARM_PAC_MASK:
20373 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
20374 case NT_ARM_PACA_KEYS:
20375 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
20376 case NT_ARM_PACG_KEYS:
20377 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
20378 case NT_ARM_TAGGED_ADDR_CTRL:
20379 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
a8f175d9
LM
20380 case NT_ARM_SSVE:
20381 return _("NT_ARM_SSVE (AArch64 streaming SVE registers)");
20382 case NT_ARM_ZA:
20383 return _("NT_ARM_ZA (AArch64 SME ZA register)");
11e3488d
LM
20384 case NT_ARM_ZT:
20385 return _("NT_ARM_ZT (AArch64 SME2 ZT registers)");
3af2785c
LM
20386 case NT_ARM_PAC_ENABLED_KEYS:
20387 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
20388 case NT_ARC_V2:
20389 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
20390 case NT_RISCV_CSR:
20391 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 20392 case NT_PSTATUS:
1ec5cd37 20393 return _("NT_PSTATUS (pstatus structure)");
57346661 20394 case NT_FPREGS:
1ec5cd37 20395 return _("NT_FPREGS (floating point registers)");
57346661 20396 case NT_PSINFO:
1ec5cd37 20397 return _("NT_PSINFO (psinfo structure)");
57346661 20398 case NT_LWPSTATUS:
1ec5cd37 20399 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 20400 case NT_LWPSINFO:
1ec5cd37 20401 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 20402 case NT_WIN32PSTATUS:
1ec5cd37 20403 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
20404 case NT_SIGINFO:
20405 return _("NT_SIGINFO (siginfo_t data)");
20406 case NT_FILE:
20407 return _("NT_FILE (mapped files)");
1ec5cd37
NC
20408 default:
20409 break;
20410 }
20411 else
20412 switch (e_type)
20413 {
20414 case NT_VERSION:
20415 return _("NT_VERSION (version)");
20416 case NT_ARCH:
20417 return _("NT_ARCH (architecture)");
9ef920e9 20418 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 20419 return _("OPEN");
9ef920e9 20420 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 20421 return _("func");
c8795e1f
NC
20422 case NT_GO_BUILDID:
20423 return _("GO BUILDID");
3ac925fc
LB
20424 case FDO_PACKAGING_METADATA:
20425 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
20426 default:
20427 break;
20428 }
20429
e9e44622 20430 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 20431 return buff;
779fe533
NC
20432}
20433
015dc7e1 20434static bool
9ece1fa9
TT
20435print_core_note (Elf_Internal_Note *pnote)
20436{
20437 unsigned int addr_size = is_32bit_elf ? 4 : 8;
625d49fc 20438 uint64_t count, page_size;
9ece1fa9
TT
20439 unsigned char *descdata, *filenames, *descend;
20440
20441 if (pnote->type != NT_FILE)
04ac15ab
AS
20442 {
20443 if (do_wide)
20444 printf ("\n");
015dc7e1 20445 return true;
04ac15ab 20446 }
9ece1fa9 20447
9ece1fa9
TT
20448 if (pnote->descsz < 2 * addr_size)
20449 {
32ec8896 20450 error (_(" Malformed note - too short for header\n"));
015dc7e1 20451 return false;
9ece1fa9
TT
20452 }
20453
20454 descdata = (unsigned char *) pnote->descdata;
20455 descend = descdata + pnote->descsz;
20456
20457 if (descdata[pnote->descsz - 1] != '\0')
20458 {
32ec8896 20459 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 20460 return false;
9ece1fa9
TT
20461 }
20462
20463 count = byte_get (descdata, addr_size);
20464 descdata += addr_size;
20465
20466 page_size = byte_get (descdata, addr_size);
20467 descdata += addr_size;
20468
625d49fc 20469 if (count > ((uint64_t) -1 - 2 * addr_size) / (3 * addr_size)
5396a86e 20470 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 20471 {
32ec8896 20472 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 20473 return false;
9ece1fa9
TT
20474 }
20475
20476 printf (_(" Page size: "));
20477 print_vma (page_size, DEC);
20478 printf ("\n");
20479
20480 printf (_(" %*s%*s%*s\n"),
20481 (int) (2 + 2 * addr_size), _("Start"),
20482 (int) (4 + 2 * addr_size), _("End"),
20483 (int) (4 + 2 * addr_size), _("Page Offset"));
20484 filenames = descdata + count * 3 * addr_size;
595712bb 20485 while (count-- > 0)
9ece1fa9 20486 {
625d49fc 20487 uint64_t start, end, file_ofs;
9ece1fa9
TT
20488
20489 if (filenames == descend)
20490 {
32ec8896 20491 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 20492 return false;
9ece1fa9
TT
20493 }
20494
20495 start = byte_get (descdata, addr_size);
20496 descdata += addr_size;
20497 end = byte_get (descdata, addr_size);
20498 descdata += addr_size;
20499 file_ofs = byte_get (descdata, addr_size);
20500 descdata += addr_size;
20501
20502 printf (" ");
20503 print_vma (start, FULL_HEX);
20504 printf (" ");
20505 print_vma (end, FULL_HEX);
20506 printf (" ");
20507 print_vma (file_ofs, FULL_HEX);
20508 printf ("\n %s\n", filenames);
20509
20510 filenames += 1 + strlen ((char *) filenames);
20511 }
20512
015dc7e1 20513 return true;
9ece1fa9
TT
20514}
20515
1118d252
RM
20516static const char *
20517get_gnu_elf_note_type (unsigned e_type)
20518{
1449284b 20519 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
20520 switch (e_type)
20521 {
20522 case NT_GNU_ABI_TAG:
20523 return _("NT_GNU_ABI_TAG (ABI version tag)");
20524 case NT_GNU_HWCAP:
20525 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
20526 case NT_GNU_BUILD_ID:
20527 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
20528 case NT_GNU_GOLD_VERSION:
20529 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
20530 case NT_GNU_PROPERTY_TYPE_0:
20531 return _("NT_GNU_PROPERTY_TYPE_0");
20532 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
20533 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
20534 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
20535 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 20536 default:
1449284b
NC
20537 {
20538 static char buff[64];
1118d252 20539
1449284b
NC
20540 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20541 return buff;
20542 }
20543 }
1118d252
RM
20544}
20545
a9eafb08
L
20546static void
20547decode_x86_compat_isa (unsigned int bitmask)
20548{
20549 while (bitmask)
20550 {
20551 unsigned int bit = bitmask & (- bitmask);
20552
20553 bitmask &= ~ bit;
20554 switch (bit)
20555 {
20556 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
20557 printf ("i486");
20558 break;
20559 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
20560 printf ("586");
20561 break;
20562 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
20563 printf ("686");
20564 break;
20565 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
20566 printf ("SSE");
20567 break;
20568 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
20569 printf ("SSE2");
20570 break;
20571 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
20572 printf ("SSE3");
20573 break;
20574 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
20575 printf ("SSSE3");
20576 break;
20577 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
20578 printf ("SSE4_1");
20579 break;
20580 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
20581 printf ("SSE4_2");
20582 break;
20583 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
20584 printf ("AVX");
20585 break;
20586 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
20587 printf ("AVX2");
20588 break;
20589 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
20590 printf ("AVX512F");
20591 break;
20592 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
20593 printf ("AVX512CD");
20594 break;
20595 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
20596 printf ("AVX512ER");
20597 break;
20598 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
20599 printf ("AVX512PF");
20600 break;
20601 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
20602 printf ("AVX512VL");
20603 break;
20604 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
20605 printf ("AVX512DQ");
20606 break;
20607 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
20608 printf ("AVX512BW");
20609 break;
65b3d26e
L
20610 default:
20611 printf (_("<unknown: %x>"), bit);
20612 break;
a9eafb08
L
20613 }
20614 if (bitmask)
20615 printf (", ");
20616 }
20617}
20618
9ef920e9 20619static void
32930e4e 20620decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 20621{
0a59decb 20622 if (!bitmask)
90c745dc
L
20623 {
20624 printf (_("<None>"));
20625 return;
20626 }
90c745dc 20627
9ef920e9
NC
20628 while (bitmask)
20629 {
1fc87489 20630 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
20631
20632 bitmask &= ~ bit;
20633 switch (bit)
20634 {
32930e4e 20635 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
20636 printf ("CMOV");
20637 break;
32930e4e 20638 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
20639 printf ("SSE");
20640 break;
32930e4e 20641 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
20642 printf ("SSE2");
20643 break;
32930e4e 20644 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
20645 printf ("SSE3");
20646 break;
32930e4e 20647 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
20648 printf ("SSSE3");
20649 break;
32930e4e 20650 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
20651 printf ("SSE4_1");
20652 break;
32930e4e 20653 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
20654 printf ("SSE4_2");
20655 break;
32930e4e 20656 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
20657 printf ("AVX");
20658 break;
32930e4e 20659 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
20660 printf ("AVX2");
20661 break;
32930e4e 20662 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
20663 printf ("FMA");
20664 break;
32930e4e 20665 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
20666 printf ("AVX512F");
20667 break;
32930e4e 20668 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
20669 printf ("AVX512CD");
20670 break;
32930e4e 20671 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
20672 printf ("AVX512ER");
20673 break;
32930e4e 20674 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
20675 printf ("AVX512PF");
20676 break;
32930e4e 20677 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
20678 printf ("AVX512VL");
20679 break;
32930e4e 20680 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
20681 printf ("AVX512DQ");
20682 break;
32930e4e 20683 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
20684 printf ("AVX512BW");
20685 break;
32930e4e 20686 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
20687 printf ("AVX512_4FMAPS");
20688 break;
32930e4e 20689 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
20690 printf ("AVX512_4VNNIW");
20691 break;
32930e4e 20692 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
20693 printf ("AVX512_BITALG");
20694 break;
32930e4e 20695 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
20696 printf ("AVX512_IFMA");
20697 break;
32930e4e 20698 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
20699 printf ("AVX512_VBMI");
20700 break;
32930e4e 20701 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
20702 printf ("AVX512_VBMI2");
20703 break;
32930e4e 20704 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
20705 printf ("AVX512_VNNI");
20706 break;
32930e4e 20707 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
20708 printf ("AVX512_BF16");
20709 break;
65b3d26e
L
20710 default:
20711 printf (_("<unknown: %x>"), bit);
20712 break;
9ef920e9
NC
20713 }
20714 if (bitmask)
20715 printf (", ");
20716 }
20717}
20718
28cdbb18
SM
20719static const char *
20720get_amdgpu_elf_note_type (unsigned int e_type)
20721{
20722 switch (e_type)
20723 {
20724 case NT_AMDGPU_METADATA:
20725 return _("NT_AMDGPU_METADATA (code object metadata)");
20726 default:
20727 {
20728 static char buf[64];
20729 snprintf (buf, sizeof (buf), _("Unknown note type: (0x%08x)"), e_type);
20730 return buf;
20731 }
20732 }
20733}
20734
32930e4e
L
20735static void
20736decode_x86_isa (unsigned int bitmask)
20737{
32930e4e
L
20738 while (bitmask)
20739 {
20740 unsigned int bit = bitmask & (- bitmask);
20741
20742 bitmask &= ~ bit;
20743 switch (bit)
20744 {
b0ab0693
L
20745 case GNU_PROPERTY_X86_ISA_1_BASELINE:
20746 printf ("x86-64-baseline");
20747 break;
32930e4e
L
20748 case GNU_PROPERTY_X86_ISA_1_V2:
20749 printf ("x86-64-v2");
20750 break;
20751 case GNU_PROPERTY_X86_ISA_1_V3:
20752 printf ("x86-64-v3");
20753 break;
20754 case GNU_PROPERTY_X86_ISA_1_V4:
20755 printf ("x86-64-v4");
20756 break;
20757 default:
20758 printf (_("<unknown: %x>"), bit);
20759 break;
20760 }
20761 if (bitmask)
20762 printf (", ");
20763 }
20764}
20765
ee2fdd6f 20766static void
a9eafb08 20767decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 20768{
0a59decb 20769 if (!bitmask)
90c745dc
L
20770 {
20771 printf (_("<None>"));
20772 return;
20773 }
90c745dc 20774
ee2fdd6f
L
20775 while (bitmask)
20776 {
20777 unsigned int bit = bitmask & (- bitmask);
20778
20779 bitmask &= ~ bit;
20780 switch (bit)
20781 {
20782 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 20783 printf ("IBT");
ee2fdd6f 20784 break;
48580982 20785 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 20786 printf ("SHSTK");
48580982 20787 break;
279d901e
L
20788 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
20789 printf ("LAM_U48");
20790 break;
20791 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
20792 printf ("LAM_U57");
20793 break;
ee2fdd6f
L
20794 default:
20795 printf (_("<unknown: %x>"), bit);
20796 break;
20797 }
20798 if (bitmask)
20799 printf (", ");
20800 }
20801}
20802
a9eafb08
L
20803static void
20804decode_x86_feature_2 (unsigned int bitmask)
20805{
0a59decb 20806 if (!bitmask)
90c745dc
L
20807 {
20808 printf (_("<None>"));
20809 return;
20810 }
90c745dc 20811
a9eafb08
L
20812 while (bitmask)
20813 {
20814 unsigned int bit = bitmask & (- bitmask);
20815
20816 bitmask &= ~ bit;
20817 switch (bit)
20818 {
20819 case GNU_PROPERTY_X86_FEATURE_2_X86:
20820 printf ("x86");
20821 break;
20822 case GNU_PROPERTY_X86_FEATURE_2_X87:
20823 printf ("x87");
20824 break;
20825 case GNU_PROPERTY_X86_FEATURE_2_MMX:
20826 printf ("MMX");
20827 break;
20828 case GNU_PROPERTY_X86_FEATURE_2_XMM:
20829 printf ("XMM");
20830 break;
20831 case GNU_PROPERTY_X86_FEATURE_2_YMM:
20832 printf ("YMM");
20833 break;
20834 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
20835 printf ("ZMM");
20836 break;
a308b89d
L
20837 case GNU_PROPERTY_X86_FEATURE_2_TMM:
20838 printf ("TMM");
20839 break;
32930e4e
L
20840 case GNU_PROPERTY_X86_FEATURE_2_MASK:
20841 printf ("MASK");
20842 break;
a9eafb08
L
20843 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
20844 printf ("FXSR");
20845 break;
20846 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
20847 printf ("XSAVE");
20848 break;
20849 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
20850 printf ("XSAVEOPT");
20851 break;
20852 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
20853 printf ("XSAVEC");
20854 break;
65b3d26e
L
20855 default:
20856 printf (_("<unknown: %x>"), bit);
20857 break;
a9eafb08
L
20858 }
20859 if (bitmask)
20860 printf (", ");
20861 }
20862}
20863
cd702818
SD
20864static void
20865decode_aarch64_feature_1_and (unsigned int bitmask)
20866{
20867 while (bitmask)
20868 {
20869 unsigned int bit = bitmask & (- bitmask);
20870
20871 bitmask &= ~ bit;
20872 switch (bit)
20873 {
20874 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
20875 printf ("BTI");
20876 break;
20877
20878 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
20879 printf ("PAC");
20880 break;
20881
20882 default:
20883 printf (_("<unknown: %x>"), bit);
20884 break;
20885 }
20886 if (bitmask)
20887 printf (", ");
20888 }
20889}
20890
6320fd00
L
20891static void
20892decode_1_needed (unsigned int bitmask)
20893{
20894 while (bitmask)
20895 {
20896 unsigned int bit = bitmask & (- bitmask);
20897
20898 bitmask &= ~ bit;
20899 switch (bit)
20900 {
20901 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
20902 printf ("indirect external access");
20903 break;
20904 default:
20905 printf (_("<unknown: %x>"), bit);
20906 break;
20907 }
20908 if (bitmask)
20909 printf (", ");
20910 }
20911}
20912
9ef920e9 20913static void
dda8d76d 20914print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
20915{
20916 unsigned char * ptr = (unsigned char *) pnote->descdata;
20917 unsigned char * ptr_end = ptr + pnote->descsz;
20918 unsigned int size = is_32bit_elf ? 4 : 8;
20919
20920 printf (_(" Properties: "));
20921
1fc87489 20922 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
20923 {
20924 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
20925 return;
20926 }
20927
6ab2c4ed 20928 while (ptr < ptr_end)
9ef920e9 20929 {
1fc87489 20930 unsigned int j;
6ab2c4ed
MC
20931 unsigned int type;
20932 unsigned int datasz;
20933
20934 if ((size_t) (ptr_end - ptr) < 8)
20935 {
20936 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
20937 break;
20938 }
20939
20940 type = byte_get (ptr, 4);
20941 datasz = byte_get (ptr + 4, 4);
9ef920e9 20942
1fc87489 20943 ptr += 8;
9ef920e9 20944
6ab2c4ed 20945 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 20946 {
1fc87489
L
20947 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
20948 type, datasz);
9ef920e9 20949 break;
1fc87489 20950 }
9ef920e9 20951
1fc87489
L
20952 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
20953 {
dda8d76d
NC
20954 if (filedata->file_header.e_machine == EM_X86_64
20955 || filedata->file_header.e_machine == EM_IAMCU
20956 || filedata->file_header.e_machine == EM_386)
1fc87489 20957 {
aa7bca9b
L
20958 unsigned int bitmask;
20959
20960 if (datasz == 4)
0a59decb 20961 bitmask = byte_get (ptr, 4);
aa7bca9b
L
20962 else
20963 bitmask = 0;
20964
1fc87489
L
20965 switch (type)
20966 {
20967 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 20968 if (datasz != 4)
aa7bca9b
L
20969 printf (_("x86 ISA used: <corrupt length: %#x> "),
20970 datasz);
1fc87489 20971 else
aa7bca9b
L
20972 {
20973 printf ("x86 ISA used: ");
20974 decode_x86_isa (bitmask);
20975 }
1fc87489 20976 goto next;
9ef920e9 20977
1fc87489 20978 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 20979 if (datasz != 4)
aa7bca9b
L
20980 printf (_("x86 ISA needed: <corrupt length: %#x> "),
20981 datasz);
1fc87489 20982 else
aa7bca9b
L
20983 {
20984 printf ("x86 ISA needed: ");
20985 decode_x86_isa (bitmask);
20986 }
1fc87489 20987 goto next;
9ef920e9 20988
ee2fdd6f 20989 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 20990 if (datasz != 4)
aa7bca9b
L
20991 printf (_("x86 feature: <corrupt length: %#x> "),
20992 datasz);
ee2fdd6f 20993 else
aa7bca9b
L
20994 {
20995 printf ("x86 feature: ");
a9eafb08
L
20996 decode_x86_feature_1 (bitmask);
20997 }
20998 goto next;
20999
21000 case GNU_PROPERTY_X86_FEATURE_2_USED:
21001 if (datasz != 4)
21002 printf (_("x86 feature used: <corrupt length: %#x> "),
21003 datasz);
21004 else
21005 {
21006 printf ("x86 feature used: ");
21007 decode_x86_feature_2 (bitmask);
21008 }
21009 goto next;
21010
21011 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
21012 if (datasz != 4)
21013 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
21014 else
21015 {
21016 printf ("x86 feature needed: ");
21017 decode_x86_feature_2 (bitmask);
21018 }
21019 goto next;
21020
21021 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
21022 if (datasz != 4)
21023 printf (_("x86 ISA used: <corrupt length: %#x> "),
21024 datasz);
21025 else
21026 {
21027 printf ("x86 ISA used: ");
21028 decode_x86_compat_isa (bitmask);
21029 }
21030 goto next;
21031
21032 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
21033 if (datasz != 4)
21034 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21035 datasz);
21036 else
21037 {
21038 printf ("x86 ISA needed: ");
21039 decode_x86_compat_isa (bitmask);
aa7bca9b 21040 }
ee2fdd6f
L
21041 goto next;
21042
32930e4e
L
21043 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
21044 if (datasz != 4)
21045 printf (_("x86 ISA used: <corrupt length: %#x> "),
21046 datasz);
21047 else
21048 {
21049 printf ("x86 ISA used: ");
21050 decode_x86_compat_2_isa (bitmask);
21051 }
21052 goto next;
21053
21054 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
21055 if (datasz != 4)
21056 printf (_("x86 ISA needed: <corrupt length: %#x> "),
21057 datasz);
21058 else
21059 {
21060 printf ("x86 ISA needed: ");
21061 decode_x86_compat_2_isa (bitmask);
21062 }
21063 goto next;
21064
1fc87489
L
21065 default:
21066 break;
21067 }
21068 }
cd702818
SD
21069 else if (filedata->file_header.e_machine == EM_AARCH64)
21070 {
21071 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
21072 {
21073 printf ("AArch64 feature: ");
21074 if (datasz != 4)
21075 printf (_("<corrupt length: %#x> "), datasz);
21076 else
21077 decode_aarch64_feature_1_and (byte_get (ptr, 4));
21078 goto next;
21079 }
21080 }
1fc87489
L
21081 }
21082 else
21083 {
21084 switch (type)
9ef920e9 21085 {
1fc87489
L
21086 case GNU_PROPERTY_STACK_SIZE:
21087 printf (_("stack size: "));
21088 if (datasz != size)
21089 printf (_("<corrupt length: %#x> "), datasz);
21090 else
26c527e6 21091 printf ("%#" PRIx64, byte_get (ptr, size));
1fc87489
L
21092 goto next;
21093
21094 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
21095 printf ("no copy on protected ");
21096 if (datasz)
21097 printf (_("<corrupt length: %#x> "), datasz);
21098 goto next;
21099
21100 default:
5a767724
L
21101 if ((type >= GNU_PROPERTY_UINT32_AND_LO
21102 && type <= GNU_PROPERTY_UINT32_AND_HI)
21103 || (type >= GNU_PROPERTY_UINT32_OR_LO
21104 && type <= GNU_PROPERTY_UINT32_OR_HI))
21105 {
6320fd00
L
21106 switch (type)
21107 {
21108 case GNU_PROPERTY_1_NEEDED:
21109 if (datasz != 4)
21110 printf (_("1_needed: <corrupt length: %#x> "),
21111 datasz);
21112 else
21113 {
21114 unsigned int bitmask = byte_get (ptr, 4);
21115 printf ("1_needed: ");
21116 decode_1_needed (bitmask);
21117 }
21118 goto next;
21119
21120 default:
21121 break;
21122 }
5a767724
L
21123 if (type <= GNU_PROPERTY_UINT32_AND_HI)
21124 printf (_("UINT32_AND (%#x): "), type);
21125 else
21126 printf (_("UINT32_OR (%#x): "), type);
21127 if (datasz != 4)
21128 printf (_("<corrupt length: %#x> "), datasz);
21129 else
21130 printf ("%#x", (unsigned int) byte_get (ptr, 4));
21131 goto next;
21132 }
9ef920e9
NC
21133 break;
21134 }
9ef920e9
NC
21135 }
21136
1fc87489
L
21137 if (type < GNU_PROPERTY_LOPROC)
21138 printf (_("<unknown type %#x data: "), type);
21139 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 21140 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
21141 else
21142 printf (_("<application-specific type %#x data: "), type);
21143 for (j = 0; j < datasz; ++j)
21144 printf ("%02x ", ptr[j] & 0xff);
21145 printf (">");
21146
dc1e8a47 21147 next:
9ef920e9 21148 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
21149 if (ptr == ptr_end)
21150 break;
1fc87489 21151
6ab2c4ed
MC
21152 if (do_wide)
21153 printf (", ");
21154 else
21155 printf ("\n\t");
9ef920e9
NC
21156 }
21157
21158 printf ("\n");
21159}
21160
015dc7e1 21161static bool
dda8d76d 21162print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 21163{
1449284b 21164 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
21165 switch (pnote->type)
21166 {
21167 case NT_GNU_BUILD_ID:
21168 {
26c527e6 21169 size_t i;
664f90a3
TT
21170
21171 printf (_(" Build ID: "));
21172 for (i = 0; i < pnote->descsz; ++i)
21173 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 21174 printf ("\n");
664f90a3
TT
21175 }
21176 break;
21177
21178 case NT_GNU_ABI_TAG:
21179 {
26c527e6 21180 unsigned int os, major, minor, subminor;
664f90a3
TT
21181 const char *osname;
21182
3102e897
NC
21183 /* PR 17531: file: 030-599401-0.004. */
21184 if (pnote->descsz < 16)
21185 {
21186 printf (_(" <corrupt GNU_ABI_TAG>\n"));
21187 break;
21188 }
21189
664f90a3
TT
21190 os = byte_get ((unsigned char *) pnote->descdata, 4);
21191 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
21192 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
21193 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
21194
21195 switch (os)
21196 {
21197 case GNU_ABI_TAG_LINUX:
21198 osname = "Linux";
21199 break;
21200 case GNU_ABI_TAG_HURD:
21201 osname = "Hurd";
21202 break;
21203 case GNU_ABI_TAG_SOLARIS:
21204 osname = "Solaris";
21205 break;
21206 case GNU_ABI_TAG_FREEBSD:
21207 osname = "FreeBSD";
21208 break;
21209 case GNU_ABI_TAG_NETBSD:
21210 osname = "NetBSD";
21211 break;
14ae95f2
RM
21212 case GNU_ABI_TAG_SYLLABLE:
21213 osname = "Syllable";
21214 break;
21215 case GNU_ABI_TAG_NACL:
21216 osname = "NaCl";
21217 break;
664f90a3
TT
21218 default:
21219 osname = "Unknown";
21220 break;
21221 }
21222
26c527e6 21223 printf (_(" OS: %s, ABI: %d.%d.%d\n"), osname,
664f90a3
TT
21224 major, minor, subminor);
21225 }
21226 break;
926c5385
CC
21227
21228 case NT_GNU_GOLD_VERSION:
21229 {
26c527e6 21230 size_t i;
926c5385
CC
21231
21232 printf (_(" Version: "));
21233 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
21234 printf ("%c", pnote->descdata[i]);
21235 printf ("\n");
21236 }
21237 break;
1449284b
NC
21238
21239 case NT_GNU_HWCAP:
21240 {
26c527e6 21241 unsigned int num_entries, mask;
1449284b
NC
21242
21243 /* Hardware capabilities information. Word 0 is the number of entries.
21244 Word 1 is a bitmask of enabled entries. The rest of the descriptor
21245 is a series of entries, where each entry is a single byte followed
21246 by a nul terminated string. The byte gives the bit number to test
21247 if enabled in the bitmask. */
21248 printf (_(" Hardware Capabilities: "));
21249 if (pnote->descsz < 8)
21250 {
32ec8896 21251 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 21252 return false;
1449284b
NC
21253 }
21254 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
21255 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
26c527e6 21256 printf (_("num entries: %d, enabled mask: %x\n"), num_entries, mask);
1449284b
NC
21257 /* FIXME: Add code to display the entries... */
21258 }
21259 break;
21260
9ef920e9 21261 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 21262 print_gnu_property_note (filedata, pnote);
9ef920e9 21263 break;
9abca702 21264
1449284b
NC
21265 default:
21266 /* Handle unrecognised types. An error message should have already been
21267 created by get_gnu_elf_note_type(), so all that we need to do is to
21268 display the data. */
21269 {
26c527e6 21270 size_t i;
1449284b
NC
21271
21272 printf (_(" Description data: "));
21273 for (i = 0; i < pnote->descsz; ++i)
21274 printf ("%02x ", pnote->descdata[i] & 0xff);
21275 printf ("\n");
21276 }
21277 break;
664f90a3
TT
21278 }
21279
015dc7e1 21280 return true;
664f90a3
TT
21281}
21282
685080f2
NC
21283static const char *
21284get_v850_elf_note_type (enum v850_notes n_type)
21285{
21286 static char buff[64];
21287
21288 switch (n_type)
21289 {
21290 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
21291 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
21292 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
21293 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
21294 case V850_NOTE_CACHE_INFO: return _("Use of cache");
21295 case V850_NOTE_MMU_INFO: return _("Use of MMU");
21296 default:
21297 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
21298 return buff;
21299 }
21300}
21301
015dc7e1 21302static bool
685080f2
NC
21303print_v850_note (Elf_Internal_Note * pnote)
21304{
21305 unsigned int val;
21306
21307 if (pnote->descsz != 4)
015dc7e1 21308 return false;
32ec8896 21309
685080f2
NC
21310 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
21311
21312 if (val == 0)
21313 {
21314 printf (_("not set\n"));
015dc7e1 21315 return true;
685080f2
NC
21316 }
21317
21318 switch (pnote->type)
21319 {
21320 case V850_NOTE_ALIGNMENT:
21321 switch (val)
21322 {
015dc7e1
AM
21323 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
21324 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
21325 }
21326 break;
14ae95f2 21327
685080f2
NC
21328 case V850_NOTE_DATA_SIZE:
21329 switch (val)
21330 {
015dc7e1
AM
21331 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
21332 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
21333 }
21334 break;
14ae95f2 21335
685080f2
NC
21336 case V850_NOTE_FPU_INFO:
21337 switch (val)
21338 {
015dc7e1
AM
21339 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
21340 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
21341 }
21342 break;
14ae95f2 21343
685080f2
NC
21344 case V850_NOTE_MMU_INFO:
21345 case V850_NOTE_CACHE_INFO:
21346 case V850_NOTE_SIMD_INFO:
21347 if (val == EF_RH850_SIMD)
21348 {
21349 printf (_("yes\n"));
015dc7e1 21350 return true;
685080f2
NC
21351 }
21352 break;
21353
21354 default:
21355 /* An 'unknown note type' message will already have been displayed. */
21356 break;
21357 }
21358
21359 printf (_("unknown value: %x\n"), val);
015dc7e1 21360 return false;
685080f2
NC
21361}
21362
015dc7e1 21363static bool
c6056a74
SF
21364process_netbsd_elf_note (Elf_Internal_Note * pnote)
21365{
21366 unsigned int version;
21367
21368 switch (pnote->type)
21369 {
21370 case NT_NETBSD_IDENT:
b966f55f
AM
21371 if (pnote->descsz < 1)
21372 break;
c6056a74
SF
21373 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21374 if ((version / 10000) % 100)
b966f55f 21375 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
21376 version, version / 100000000, (version / 1000000) % 100,
21377 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 21378 'A' + (version / 10000) % 26);
c6056a74
SF
21379 else
21380 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 21381 version, version / 100000000, (version / 1000000) % 100,
15f205b1 21382 (version / 100) % 100);
015dc7e1 21383 return true;
c6056a74
SF
21384
21385 case NT_NETBSD_MARCH:
9abca702 21386 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 21387 pnote->descdata);
015dc7e1 21388 return true;
c6056a74 21389
9abca702 21390 case NT_NETBSD_PAX:
b966f55f
AM
21391 if (pnote->descsz < 1)
21392 break;
9abca702
CZ
21393 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
21394 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
21395 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
21396 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
21397 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
21398 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
21399 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
21400 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 21401 return true;
c6056a74 21402 }
b966f55f
AM
21403
21404 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
21405 pnote->descsz, pnote->type);
015dc7e1 21406 return false;
c6056a74
SF
21407}
21408
f4ddf30f 21409static const char *
dda8d76d 21410get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 21411{
f4ddf30f
JB
21412 switch (e_type)
21413 {
21414 case NT_FREEBSD_THRMISC:
21415 return _("NT_THRMISC (thrmisc structure)");
21416 case NT_FREEBSD_PROCSTAT_PROC:
21417 return _("NT_PROCSTAT_PROC (proc data)");
21418 case NT_FREEBSD_PROCSTAT_FILES:
21419 return _("NT_PROCSTAT_FILES (files data)");
21420 case NT_FREEBSD_PROCSTAT_VMMAP:
21421 return _("NT_PROCSTAT_VMMAP (vmmap data)");
21422 case NT_FREEBSD_PROCSTAT_GROUPS:
21423 return _("NT_PROCSTAT_GROUPS (groups data)");
21424 case NT_FREEBSD_PROCSTAT_UMASK:
21425 return _("NT_PROCSTAT_UMASK (umask data)");
21426 case NT_FREEBSD_PROCSTAT_RLIMIT:
21427 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
21428 case NT_FREEBSD_PROCSTAT_OSREL:
21429 return _("NT_PROCSTAT_OSREL (osreldate data)");
21430 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
21431 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
21432 case NT_FREEBSD_PROCSTAT_AUXV:
21433 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
21434 case NT_FREEBSD_PTLWPINFO:
21435 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
a171378a
JB
21436 case NT_FREEBSD_X86_SEGBASES:
21437 return _("NT_X86_SEGBASES (x86 segment base registers)");
f4ddf30f 21438 }
dda8d76d 21439 return get_note_type (filedata, e_type);
f4ddf30f
JB
21440}
21441
9437c45b 21442static const char *
dda8d76d 21443get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
21444{
21445 static char buff[64];
21446
540e6170
CZ
21447 switch (e_type)
21448 {
21449 case NT_NETBSDCORE_PROCINFO:
21450 /* NetBSD core "procinfo" structure. */
21451 return _("NetBSD procinfo structure");
9437c45b 21452
540e6170
CZ
21453 case NT_NETBSDCORE_AUXV:
21454 return _("NetBSD ELF auxiliary vector data");
9437c45b 21455
06d949ec
KR
21456 case NT_NETBSDCORE_LWPSTATUS:
21457 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 21458
540e6170 21459 default:
06d949ec 21460 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
21461 defined for NetBSD core files. If the note type is less
21462 than the start of the machine-dependent note types, we don't
21463 understand it. */
21464
21465 if (e_type < NT_NETBSDCORE_FIRSTMACH)
21466 {
21467 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21468 return buff;
21469 }
21470 break;
9437c45b
JT
21471 }
21472
dda8d76d 21473 switch (filedata->file_header.e_machine)
9437c45b
JT
21474 {
21475 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
21476 and PT_GETFPREGS == mach+2. */
21477
21478 case EM_OLD_ALPHA:
21479 case EM_ALPHA:
21480 case EM_SPARC:
21481 case EM_SPARC32PLUS:
21482 case EM_SPARCV9:
21483 switch (e_type)
21484 {
2b692964 21485 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 21486 return _("PT_GETREGS (reg structure)");
2b692964 21487 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 21488 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21489 default:
21490 break;
21491 }
21492 break;
21493
c0d38b0e
CZ
21494 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
21495 There's also old PT___GETREGS40 == mach + 1 for old reg
21496 structure which lacks GBR. */
21497 case EM_SH:
21498 switch (e_type)
21499 {
21500 case NT_NETBSDCORE_FIRSTMACH + 1:
21501 return _("PT___GETREGS40 (old reg structure)");
21502 case NT_NETBSDCORE_FIRSTMACH + 3:
21503 return _("PT_GETREGS (reg structure)");
21504 case NT_NETBSDCORE_FIRSTMACH + 5:
21505 return _("PT_GETFPREGS (fpreg structure)");
21506 default:
21507 break;
21508 }
21509 break;
21510
9437c45b
JT
21511 /* On all other arch's, PT_GETREGS == mach+1 and
21512 PT_GETFPREGS == mach+3. */
21513 default:
21514 switch (e_type)
21515 {
2b692964 21516 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 21517 return _("PT_GETREGS (reg structure)");
2b692964 21518 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 21519 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
21520 default:
21521 break;
21522 }
21523 }
21524
9cf03b7e 21525 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 21526 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
21527 return buff;
21528}
21529
98ca73af
FC
21530static const char *
21531get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
21532{
21533 switch (e_type)
21534 {
21535 case NT_OPENBSD_PROCINFO:
21536 return _("OpenBSD procinfo structure");
21537 case NT_OPENBSD_AUXV:
21538 return _("OpenBSD ELF auxiliary vector data");
21539 case NT_OPENBSD_REGS:
21540 return _("OpenBSD regular registers");
21541 case NT_OPENBSD_FPREGS:
21542 return _("OpenBSD floating point registers");
21543 case NT_OPENBSD_WCOOKIE:
21544 return _("OpenBSD window cookie");
21545 }
21546
21547 return get_note_type (filedata, e_type);
21548}
21549
e263a66b
CC
21550static const char *
21551get_qnx_elfcore_note_type (Filedata * filedata, unsigned e_type)
21552{
21553 switch (e_type)
21554 {
21555 case QNT_DEBUG_FULLPATH:
21556 return _("QNX debug fullpath");
21557 case QNT_DEBUG_RELOC:
21558 return _("QNX debug relocation");
21559 case QNT_STACK:
21560 return _("QNX stack");
21561 case QNT_GENERATOR:
21562 return _("QNX generator");
21563 case QNT_DEFAULT_LIB:
21564 return _("QNX default library");
21565 case QNT_CORE_SYSINFO:
21566 return _("QNX core sysinfo");
21567 case QNT_CORE_INFO:
21568 return _("QNX core info");
21569 case QNT_CORE_STATUS:
21570 return _("QNX core status");
21571 case QNT_CORE_GREG:
21572 return _("QNX general registers");
21573 case QNT_CORE_FPREG:
21574 return _("QNX floating point registers");
21575 case QNT_LINK_MAP:
21576 return _("QNX link map");
21577 }
21578
21579 return get_note_type (filedata, e_type);
21580}
21581
70616151
TT
21582static const char *
21583get_stapsdt_note_type (unsigned e_type)
21584{
21585 static char buff[64];
21586
21587 switch (e_type)
21588 {
21589 case NT_STAPSDT:
21590 return _("NT_STAPSDT (SystemTap probe descriptors)");
21591
21592 default:
21593 break;
21594 }
21595
21596 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21597 return buff;
21598}
21599
015dc7e1 21600static bool
c6a9fc58
TT
21601print_stapsdt_note (Elf_Internal_Note *pnote)
21602{
3ca60c57 21603 size_t len, maxlen;
26c527e6 21604 size_t addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
21605 char *data = pnote->descdata;
21606 char *data_end = pnote->descdata + pnote->descsz;
625d49fc 21607 uint64_t pc, base_addr, semaphore;
c6a9fc58
TT
21608 char *provider, *probe, *arg_fmt;
21609
3ca60c57
NC
21610 if (pnote->descsz < (addr_size * 3))
21611 goto stapdt_note_too_small;
21612
c6a9fc58
TT
21613 pc = byte_get ((unsigned char *) data, addr_size);
21614 data += addr_size;
3ca60c57 21615
c6a9fc58
TT
21616 base_addr = byte_get ((unsigned char *) data, addr_size);
21617 data += addr_size;
3ca60c57 21618
c6a9fc58
TT
21619 semaphore = byte_get ((unsigned char *) data, addr_size);
21620 data += addr_size;
21621
3ca60c57
NC
21622 if (data >= data_end)
21623 goto stapdt_note_too_small;
21624 maxlen = data_end - data;
21625 len = strnlen (data, maxlen);
21626 if (len < maxlen)
21627 {
21628 provider = data;
21629 data += len + 1;
21630 }
21631 else
21632 goto stapdt_note_too_small;
21633
21634 if (data >= data_end)
21635 goto stapdt_note_too_small;
21636 maxlen = data_end - data;
21637 len = strnlen (data, maxlen);
21638 if (len < maxlen)
21639 {
21640 probe = data;
21641 data += len + 1;
21642 }
21643 else
21644 goto stapdt_note_too_small;
9abca702 21645
3ca60c57
NC
21646 if (data >= data_end)
21647 goto stapdt_note_too_small;
21648 maxlen = data_end - data;
21649 len = strnlen (data, maxlen);
21650 if (len < maxlen)
21651 {
21652 arg_fmt = data;
21653 data += len + 1;
21654 }
21655 else
21656 goto stapdt_note_too_small;
c6a9fc58
TT
21657
21658 printf (_(" Provider: %s\n"), provider);
21659 printf (_(" Name: %s\n"), probe);
21660 printf (_(" Location: "));
21661 print_vma (pc, FULL_HEX);
21662 printf (_(", Base: "));
21663 print_vma (base_addr, FULL_HEX);
21664 printf (_(", Semaphore: "));
21665 print_vma (semaphore, FULL_HEX);
9cf03b7e 21666 printf ("\n");
c6a9fc58
TT
21667 printf (_(" Arguments: %s\n"), arg_fmt);
21668
21669 return data == data_end;
3ca60c57
NC
21670
21671 stapdt_note_too_small:
21672 printf (_(" <corrupt - note is too small>\n"));
21673 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 21674 return false;
c6a9fc58
TT
21675}
21676
e5382207
LB
21677static bool
21678print_fdo_note (Elf_Internal_Note * pnote)
21679{
21680 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
21681 {
21682 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
21683 return true;
21684 }
21685 return false;
21686}
21687
00e98fc7
TG
21688static const char *
21689get_ia64_vms_note_type (unsigned e_type)
21690{
21691 static char buff[64];
21692
21693 switch (e_type)
21694 {
21695 case NT_VMS_MHD:
21696 return _("NT_VMS_MHD (module header)");
21697 case NT_VMS_LNM:
21698 return _("NT_VMS_LNM (language name)");
21699 case NT_VMS_SRC:
21700 return _("NT_VMS_SRC (source files)");
21701 case NT_VMS_TITLE:
9cf03b7e 21702 return "NT_VMS_TITLE";
00e98fc7
TG
21703 case NT_VMS_EIDC:
21704 return _("NT_VMS_EIDC (consistency check)");
21705 case NT_VMS_FPMODE:
21706 return _("NT_VMS_FPMODE (FP mode)");
21707 case NT_VMS_LINKTIME:
9cf03b7e 21708 return "NT_VMS_LINKTIME";
00e98fc7
TG
21709 case NT_VMS_IMGNAM:
21710 return _("NT_VMS_IMGNAM (image name)");
21711 case NT_VMS_IMGID:
21712 return _("NT_VMS_IMGID (image id)");
21713 case NT_VMS_LINKID:
21714 return _("NT_VMS_LINKID (link id)");
21715 case NT_VMS_IMGBID:
21716 return _("NT_VMS_IMGBID (build id)");
21717 case NT_VMS_GSTNAM:
21718 return _("NT_VMS_GSTNAM (sym table name)");
21719 case NT_VMS_ORIG_DYN:
9cf03b7e 21720 return "NT_VMS_ORIG_DYN";
00e98fc7 21721 case NT_VMS_PATCHTIME:
9cf03b7e 21722 return "NT_VMS_PATCHTIME";
00e98fc7
TG
21723 default:
21724 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
21725 return buff;
21726 }
21727}
21728
015dc7e1 21729static bool
00e98fc7
TG
21730print_ia64_vms_note (Elf_Internal_Note * pnote)
21731{
26c527e6 21732 unsigned int maxlen = pnote->descsz;
8d18bf79 21733
26c527e6 21734 if (maxlen < 2 || maxlen != pnote->descsz)
8d18bf79
NC
21735 goto desc_size_fail;
21736
00e98fc7
TG
21737 switch (pnote->type)
21738 {
21739 case NT_VMS_MHD:
8d18bf79
NC
21740 if (maxlen <= 36)
21741 goto desc_size_fail;
21742
26c527e6 21743 size_t l = strnlen (pnote->descdata + 34, maxlen - 34);
8d18bf79
NC
21744
21745 printf (_(" Creation date : %.17s\n"), pnote->descdata);
21746 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
21747 if (l + 34 < maxlen)
21748 {
21749 printf (_(" Module name : %s\n"), pnote->descdata + 34);
21750 if (l + 35 < maxlen)
21751 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
21752 else
21753 printf (_(" Module version : <missing>\n"));
21754 }
00e98fc7 21755 else
8d18bf79
NC
21756 {
21757 printf (_(" Module name : <missing>\n"));
21758 printf (_(" Module version : <missing>\n"));
21759 }
00e98fc7 21760 break;
8d18bf79 21761
00e98fc7 21762 case NT_VMS_LNM:
8d18bf79 21763 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21764 break;
8d18bf79 21765
00e98fc7 21766 case NT_VMS_FPMODE:
9cf03b7e 21767 printf (_(" Floating Point mode: "));
8d18bf79
NC
21768 if (maxlen < 8)
21769 goto desc_size_fail;
21770 /* FIXME: Generate an error if descsz > 8 ? */
21771
b8281767 21772 printf ("0x%016" PRIx64 "\n",
625d49fc 21773 byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7 21774 break;
8d18bf79 21775
00e98fc7
TG
21776 case NT_VMS_LINKTIME:
21777 printf (_(" Link time: "));
8d18bf79
NC
21778 if (maxlen < 8)
21779 goto desc_size_fail;
21780 /* FIXME: Generate an error if descsz > 8 ? */
21781
0e3c1eeb 21782 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21783 printf ("\n");
21784 break;
8d18bf79 21785
00e98fc7
TG
21786 case NT_VMS_PATCHTIME:
21787 printf (_(" Patch time: "));
8d18bf79
NC
21788 if (maxlen < 8)
21789 goto desc_size_fail;
21790 /* FIXME: Generate an error if descsz > 8 ? */
21791
0e3c1eeb 21792 print_vms_time (byte_get ((unsigned char *) pnote->descdata, 8));
00e98fc7
TG
21793 printf ("\n");
21794 break;
8d18bf79 21795
00e98fc7 21796 case NT_VMS_ORIG_DYN:
8d18bf79
NC
21797 if (maxlen < 34)
21798 goto desc_size_fail;
21799
00e98fc7 21800 printf (_(" Major id: %u, minor id: %u\n"),
0e3c1eeb
AM
21801 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4),
21802 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
9cf03b7e 21803 printf (_(" Last modified : "));
0e3c1eeb 21804 print_vms_time (byte_get ((unsigned char *) pnote->descdata + 8, 8));
9cf03b7e 21805 printf (_("\n Link flags : "));
b8281767 21806 printf ("0x%016" PRIx64 "\n",
625d49fc 21807 byte_get ((unsigned char *) pnote->descdata + 16, 8));
00e98fc7 21808 printf (_(" Header flags: 0x%08x\n"),
0e3c1eeb 21809 (unsigned) byte_get ((unsigned char *) pnote->descdata + 24, 4));
8d18bf79 21810 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7 21811 break;
8d18bf79 21812
00e98fc7 21813 case NT_VMS_IMGNAM:
8d18bf79 21814 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21815 break;
8d18bf79 21816
00e98fc7 21817 case NT_VMS_GSTNAM:
8d18bf79 21818 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21819 break;
8d18bf79 21820
00e98fc7 21821 case NT_VMS_IMGID:
8d18bf79 21822 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21823 break;
8d18bf79 21824
00e98fc7 21825 case NT_VMS_LINKID:
8d18bf79 21826 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 21827 break;
8d18bf79 21828
00e98fc7 21829 default:
015dc7e1 21830 return false;
00e98fc7 21831 }
8d18bf79 21832
015dc7e1 21833 return true;
8d18bf79
NC
21834
21835 desc_size_fail:
21836 printf (_(" <corrupt - data size is too small>\n"));
21837 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 21838 return false;
00e98fc7
TG
21839}
21840
fd486f32
AM
21841struct build_attr_cache {
21842 Filedata *filedata;
21843 char *strtab;
26c527e6 21844 uint64_t strtablen;
fd486f32 21845 Elf_Internal_Sym *symtab;
26c527e6 21846 uint64_t nsyms;
fd486f32
AM
21847} ba_cache;
21848
6f156d7a
NC
21849/* Find the symbol associated with a build attribute that is attached
21850 to address OFFSET. If PNAME is non-NULL then store the name of
21851 the symbol (if found) in the provided pointer, Returns NULL if a
21852 symbol could not be found. */
c799a79d 21853
6f156d7a 21854static Elf_Internal_Sym *
015dc7e1 21855get_symbol_for_build_attribute (Filedata *filedata,
26c527e6 21856 uint64_t offset,
015dc7e1
AM
21857 bool is_open_attr,
21858 const char **pname)
9ef920e9 21859{
fd486f32
AM
21860 Elf_Internal_Sym *saved_sym = NULL;
21861 Elf_Internal_Sym *sym;
9ef920e9 21862
dda8d76d 21863 if (filedata->section_headers != NULL
fd486f32 21864 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 21865 {
c799a79d 21866 Elf_Internal_Shdr * symsec;
9ef920e9 21867
fd486f32
AM
21868 free (ba_cache.strtab);
21869 ba_cache.strtab = NULL;
21870 free (ba_cache.symtab);
21871 ba_cache.symtab = NULL;
21872
c799a79d 21873 /* Load the symbol and string sections. */
dda8d76d
NC
21874 for (symsec = filedata->section_headers;
21875 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 21876 symsec ++)
9ef920e9 21877 {
28d13567
AM
21878 if (symsec->sh_type == SHT_SYMTAB
21879 && get_symtab (filedata, symsec,
21880 &ba_cache.symtab, &ba_cache.nsyms,
21881 &ba_cache.strtab, &ba_cache.strtablen))
21882 break;
9ef920e9 21883 }
fd486f32 21884 ba_cache.filedata = filedata;
9ef920e9
NC
21885 }
21886
fd486f32 21887 if (ba_cache.symtab == NULL)
6f156d7a 21888 return NULL;
9ef920e9 21889
c799a79d 21890 /* Find a symbol whose value matches offset. */
fd486f32 21891 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
21892 if (sym->st_value == offset)
21893 {
fd486f32 21894 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
21895 /* Huh ? This should not happen. */
21896 continue;
9ef920e9 21897
fd486f32 21898 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 21899 continue;
9ef920e9 21900
9b9b1092 21901 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 21902 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
21903 if (ba_cache.strtab[sym->st_name] == '$'
21904 && ba_cache.strtab[sym->st_name + 1] != 0
21905 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
21906 continue;
21907
c799a79d
NC
21908 if (is_open_attr)
21909 {
21910 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
21911 and FILE or OBJECT symbols over NOTYPE symbols. We skip
21912 FUNC symbols entirely. */
21913 switch (ELF_ST_TYPE (sym->st_info))
21914 {
c799a79d 21915 case STT_OBJECT:
6f156d7a 21916 case STT_FILE:
c799a79d 21917 saved_sym = sym;
6f156d7a
NC
21918 if (sym->st_size)
21919 {
21920 /* If the symbol has a size associated
21921 with it then we can stop searching. */
fd486f32 21922 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 21923 }
c799a79d 21924 continue;
9ef920e9 21925
c799a79d
NC
21926 case STT_FUNC:
21927 /* Ignore function symbols. */
21928 continue;
21929
21930 default:
21931 break;
21932 }
21933
21934 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 21935 {
c799a79d
NC
21936 case STB_GLOBAL:
21937 if (saved_sym == NULL
21938 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
21939 saved_sym = sym;
21940 break;
c871dade 21941
c799a79d
NC
21942 case STB_LOCAL:
21943 if (saved_sym == NULL)
21944 saved_sym = sym;
21945 break;
21946
21947 default:
9ef920e9
NC
21948 break;
21949 }
21950 }
c799a79d
NC
21951 else
21952 {
21953 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
21954 continue;
21955
21956 saved_sym = sym;
21957 break;
21958 }
21959 }
21960
6f156d7a 21961 if (saved_sym && pname)
fd486f32 21962 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
21963
21964 return saved_sym;
c799a79d
NC
21965}
21966
d20e98ab
NC
21967/* Returns true iff addr1 and addr2 are in the same section. */
21968
015dc7e1 21969static bool
26c527e6 21970same_section (Filedata * filedata, uint64_t addr1, uint64_t addr2)
d20e98ab
NC
21971{
21972 Elf_Internal_Shdr * a1;
21973 Elf_Internal_Shdr * a2;
21974
21975 a1 = find_section_by_address (filedata, addr1);
21976 a2 = find_section_by_address (filedata, addr2);
9abca702 21977
d20e98ab
NC
21978 return a1 == a2 && a1 != NULL;
21979}
21980
015dc7e1 21981static bool
dda8d76d
NC
21982print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
21983 Filedata * filedata)
c799a79d 21984{
26c527e6
AM
21985 static uint64_t global_offset = 0;
21986 static uint64_t global_end = 0;
21987 static uint64_t func_offset = 0;
21988 static uint64_t func_end = 0;
c871dade 21989
015dc7e1
AM
21990 Elf_Internal_Sym *sym;
21991 const char *name;
26c527e6
AM
21992 uint64_t start;
21993 uint64_t end;
015dc7e1 21994 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
21995
21996 switch (pnote->descsz)
c799a79d 21997 {
6f156d7a
NC
21998 case 0:
21999 /* A zero-length description means that the range of
22000 the previous note of the same type should be used. */
c799a79d 22001 if (is_open_attr)
c871dade 22002 {
6f156d7a 22003 if (global_end > global_offset)
26c527e6
AM
22004 printf (_(" Applies to region from %#" PRIx64
22005 " to %#" PRIx64 "\n"), global_offset, global_end);
6f156d7a 22006 else
26c527e6
AM
22007 printf (_(" Applies to region from %#" PRIx64
22008 "\n"), global_offset);
c799a79d
NC
22009 }
22010 else
22011 {
6f156d7a 22012 if (func_end > func_offset)
26c527e6
AM
22013 printf (_(" Applies to region from %#" PRIx64
22014 " to %#" PRIx64 "\n"), func_offset, func_end);
6f156d7a 22015 else
26c527e6
AM
22016 printf (_(" Applies to region from %#" PRIx64
22017 "\n"), func_offset);
c871dade 22018 }
015dc7e1 22019 return true;
9ef920e9 22020
6f156d7a
NC
22021 case 4:
22022 start = byte_get ((unsigned char *) pnote->descdata, 4);
22023 end = 0;
22024 break;
22025
22026 case 8:
c74147bb
NC
22027 start = byte_get ((unsigned char *) pnote->descdata, 4);
22028 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
22029 break;
22030
22031 case 16:
22032 start = byte_get ((unsigned char *) pnote->descdata, 8);
22033 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
22034 break;
9abca702 22035
6f156d7a 22036 default:
c799a79d
NC
22037 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
22038 printf (_(" <invalid descsz>"));
015dc7e1 22039 return false;
c799a79d
NC
22040 }
22041
6f156d7a
NC
22042 name = NULL;
22043 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
22044 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
22045 in order to avoid them being confused with the start address of the
22046 first function in the file... */
22047 if (sym == NULL && is_open_attr)
22048 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
22049 & name);
6f156d7a
NC
22050
22051 if (end == 0 && sym != NULL && sym->st_size > 0)
22052 end = start + sym->st_size;
c799a79d
NC
22053
22054 if (is_open_attr)
22055 {
d20e98ab
NC
22056 /* FIXME: Need to properly allow for section alignment.
22057 16 is just the alignment used on x86_64. */
22058 if (global_end > 0
22059 && start > BFD_ALIGN (global_end, 16)
22060 /* Build notes are not guaranteed to be organised in order of
22061 increasing address, but we should find the all of the notes
22062 for one section in the same place. */
22063 && same_section (filedata, start, global_end))
26c527e6
AM
22064 warn (_("Gap in build notes detected from %#" PRIx64
22065 " to %#" PRIx64 "\n"),
6f156d7a
NC
22066 global_end + 1, start - 1);
22067
26c527e6 22068 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22069 global_offset = start;
22070
22071 if (end)
22072 {
26c527e6 22073 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22074 global_end = end;
22075 }
c799a79d
NC
22076 }
22077 else
22078 {
26c527e6 22079 printf (_(" Applies to region from %#" PRIx64), start);
6f156d7a
NC
22080 func_offset = start;
22081
22082 if (end)
22083 {
26c527e6 22084 printf (_(" to %#" PRIx64), end);
6f156d7a
NC
22085 func_end = end;
22086 }
c799a79d
NC
22087 }
22088
6f156d7a
NC
22089 if (sym && name)
22090 printf (_(" (%s)"), name);
22091
22092 printf ("\n");
015dc7e1 22093 return true;
9ef920e9
NC
22094}
22095
015dc7e1 22096static bool
9ef920e9
NC
22097print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
22098{
1d15e434
NC
22099 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
22100 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
22101 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
22102 char name_type;
22103 char name_attribute;
1d15e434 22104 const char * expected_types;
9ef920e9
NC
22105 const char * name = pnote->namedata;
22106 const char * text;
88305e1b 22107 signed int left;
9ef920e9
NC
22108
22109 if (name == NULL || pnote->namesz < 2)
22110 {
22111 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22112 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22113 return false;
9ef920e9
NC
22114 }
22115
6f156d7a
NC
22116 if (do_wide)
22117 left = 28;
22118 else
22119 left = 20;
88305e1b
NC
22120
22121 /* Version 2 of the spec adds a "GA" prefix to the name field. */
22122 if (name[0] == 'G' && name[1] == 'A')
22123 {
6f156d7a
NC
22124 if (pnote->namesz < 4)
22125 {
22126 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
b6ac461a 22127 print_symbol_name (-20, _(" <corrupt name>"));
015dc7e1 22128 return false;
6f156d7a
NC
22129 }
22130
88305e1b
NC
22131 printf ("GA");
22132 name += 2;
22133 left -= 2;
22134 }
22135
9ef920e9
NC
22136 switch ((name_type = * name))
22137 {
22138 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22139 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
22140 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
22141 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
22142 printf ("%c", * name);
88305e1b 22143 left --;
9ef920e9
NC
22144 break;
22145 default:
22146 error (_("unrecognised attribute type in name field: %d\n"), name_type);
b6ac461a 22147 print_symbol_name (-20, _("<unknown name type>"));
015dc7e1 22148 return false;
9ef920e9
NC
22149 }
22150
9ef920e9
NC
22151 ++ name;
22152 text = NULL;
22153
22154 switch ((name_attribute = * name))
22155 {
22156 case GNU_BUILD_ATTRIBUTE_VERSION:
22157 text = _("<version>");
1d15e434 22158 expected_types = string_expected;
9ef920e9
NC
22159 ++ name;
22160 break;
22161 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22162 text = _("<stack prot>");
75d7d298 22163 expected_types = "!+*";
9ef920e9
NC
22164 ++ name;
22165 break;
22166 case GNU_BUILD_ATTRIBUTE_RELRO:
22167 text = _("<relro>");
1d15e434 22168 expected_types = bool_expected;
9ef920e9
NC
22169 ++ name;
22170 break;
22171 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
22172 text = _("<stack size>");
1d15e434 22173 expected_types = number_expected;
9ef920e9
NC
22174 ++ name;
22175 break;
22176 case GNU_BUILD_ATTRIBUTE_TOOL:
22177 text = _("<tool>");
1d15e434 22178 expected_types = string_expected;
9ef920e9
NC
22179 ++ name;
22180 break;
22181 case GNU_BUILD_ATTRIBUTE_ABI:
22182 text = _("<ABI>");
22183 expected_types = "$*";
22184 ++ name;
22185 break;
22186 case GNU_BUILD_ATTRIBUTE_PIC:
22187 text = _("<PIC>");
1d15e434 22188 expected_types = number_expected;
9ef920e9
NC
22189 ++ name;
22190 break;
a8be5506
NC
22191 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
22192 text = _("<short enum>");
1d15e434 22193 expected_types = bool_expected;
a8be5506
NC
22194 ++ name;
22195 break;
9ef920e9
NC
22196 default:
22197 if (ISPRINT (* name))
22198 {
22199 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
22200
22201 if (len > left && ! do_wide)
22202 len = left;
75d7d298 22203 printf ("%.*s:", len, name);
9ef920e9 22204 left -= len;
0dd6ae21 22205 name += len;
9ef920e9
NC
22206 }
22207 else
22208 {
3e6b6445 22209 static char tmpbuf [128];
88305e1b 22210
3e6b6445
NC
22211 error (_("unrecognised byte in name field: %d\n"), * name);
22212 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
22213 text = tmpbuf;
22214 name ++;
9ef920e9
NC
22215 }
22216 expected_types = "*$!+";
22217 break;
22218 }
22219
22220 if (text)
88305e1b 22221 left -= printf ("%s", text);
9ef920e9
NC
22222
22223 if (strchr (expected_types, name_type) == NULL)
75d7d298 22224 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9 22225
26c527e6 22226 if ((size_t) (name - pnote->namedata) > pnote->namesz)
9ef920e9 22227 {
26c527e6
AM
22228 error (_("corrupt name field: namesz: %lu but parsing gets to %td\n"),
22229 pnote->namesz,
22230 name - pnote->namedata);
015dc7e1 22231 return false;
9ef920e9
NC
22232 }
22233
22234 if (left < 1 && ! do_wide)
015dc7e1 22235 return true;
9ef920e9
NC
22236
22237 switch (name_type)
22238 {
22239 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
22240 {
26c527e6
AM
22241 unsigned int bytes;
22242 uint64_t val = 0;
22243 unsigned int shift = 0;
22244 char *decoded = NULL;
ddef72cd 22245
b06b2c92
NC
22246 bytes = pnote->namesz - (name - pnote->namedata);
22247 if (bytes > 0)
22248 /* The -1 is because the name field is always 0 terminated, and we
22249 want to be able to ensure that the shift in the while loop below
22250 will not overflow. */
22251 -- bytes;
22252
ddef72cd
NC
22253 if (bytes > sizeof (val))
22254 {
3e6b6445
NC
22255 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
22256 bytes);
22257 bytes = sizeof (val);
ddef72cd 22258 }
3e6b6445
NC
22259 /* We do not bother to warn if bytes == 0 as this can
22260 happen with some early versions of the gcc plugin. */
9ef920e9
NC
22261
22262 while (bytes --)
22263 {
26c527e6 22264 uint64_t byte = *name++ & 0xff;
79a964dc
NC
22265
22266 val |= byte << shift;
9ef920e9
NC
22267 shift += 8;
22268 }
22269
75d7d298 22270 switch (name_attribute)
9ef920e9 22271 {
75d7d298 22272 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
22273 switch (val)
22274 {
75d7d298
NC
22275 case 0: decoded = "static"; break;
22276 case 1: decoded = "pic"; break;
22277 case 2: decoded = "PIC"; break;
22278 case 3: decoded = "pie"; break;
22279 case 4: decoded = "PIE"; break;
22280 default: break;
9ef920e9 22281 }
75d7d298
NC
22282 break;
22283 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
22284 switch (val)
9ef920e9 22285 {
75d7d298
NC
22286 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
22287 case 0: decoded = "off"; break;
22288 case 1: decoded = "on"; break;
22289 case 2: decoded = "all"; break;
22290 case 3: decoded = "strong"; break;
22291 case 4: decoded = "explicit"; break;
22292 default: break;
9ef920e9 22293 }
75d7d298
NC
22294 break;
22295 default:
22296 break;
9ef920e9
NC
22297 }
22298
75d7d298 22299 if (decoded != NULL)
3e6b6445 22300 {
b6ac461a 22301 print_symbol_name (-left, decoded);
3e6b6445
NC
22302 left = 0;
22303 }
22304 else if (val == 0)
22305 {
22306 printf ("0x0");
22307 left -= 3;
22308 }
9ef920e9 22309 else
75d7d298
NC
22310 {
22311 if (do_wide)
26c527e6 22312 left -= printf ("0x%" PRIx64, val);
75d7d298 22313 else
26c527e6 22314 left -= printf ("0x%-.*" PRIx64, left, val);
75d7d298 22315 }
9ef920e9
NC
22316 }
22317 break;
22318 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
b6ac461a 22319 left -= print_symbol_name (- left, name);
9ef920e9
NC
22320 break;
22321 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
b6ac461a 22322 left -= print_symbol_name (- left, "true");
9ef920e9
NC
22323 break;
22324 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
b6ac461a 22325 left -= print_symbol_name (- left, "false");
9ef920e9
NC
22326 break;
22327 }
22328
22329 if (do_wide && left > 0)
22330 printf ("%-*s", left, " ");
9abca702 22331
015dc7e1 22332 return true;
9ef920e9
NC
22333}
22334
2952f10c
SM
22335/* Print the contents of PNOTE as hex. */
22336
22337static void
22338print_note_contents_hex (Elf_Internal_Note *pnote)
22339{
22340 if (pnote->descsz)
22341 {
26c527e6 22342 size_t i;
2952f10c
SM
22343
22344 printf (_(" description data: "));
22345 for (i = 0; i < pnote->descsz; i++)
22346 printf ("%02x ", pnote->descdata[i] & 0xff);
22347 if (!do_wide)
22348 printf ("\n");
22349 }
22350
22351 if (do_wide)
22352 printf ("\n");
22353}
22354
22355#if defined HAVE_MSGPACK
22356
22357static void
22358print_indents (int n)
22359{
22360 printf (" ");
22361
22362 for (int i = 0; i < n; i++)
22363 printf (" ");
22364}
22365
22366/* Print OBJ in human-readable form. */
22367
22368static void
22369dump_msgpack_obj (const msgpack_object *obj, int indent)
22370{
22371 switch (obj->type)
22372 {
22373 case MSGPACK_OBJECT_NIL:
22374 printf ("(nil)");
22375 break;
22376
22377 case MSGPACK_OBJECT_BOOLEAN:
22378 printf ("%s", obj->via.boolean ? "true" : "false");
22379 break;
22380
22381 case MSGPACK_OBJECT_POSITIVE_INTEGER:
22382 printf ("%" PRIu64, obj->via.u64);
22383 break;
22384
22385 case MSGPACK_OBJECT_NEGATIVE_INTEGER:
22386 printf ("%" PRIi64, obj->via.i64);
22387 break;
22388
22389 case MSGPACK_OBJECT_FLOAT32:
22390 case MSGPACK_OBJECT_FLOAT64:
22391 printf ("%f", obj->via.f64);
22392 break;
22393
22394 case MSGPACK_OBJECT_STR:
22395 printf ("\"%.*s\"", obj->via.str.size, obj->via.str.ptr);
22396 break;
22397
22398 case MSGPACK_OBJECT_ARRAY:
22399 {
22400 const msgpack_object_array *array = &obj->via.array;
22401
22402 printf ("[\n");
22403 ++indent;
22404
22405 for (uint32_t i = 0; i < array->size; ++i)
22406 {
22407 const msgpack_object *item = &array->ptr[i];
22408
22409 print_indents (indent);
22410 dump_msgpack_obj (item, indent);
22411 printf (",\n");
22412 }
22413
22414 --indent;
22415 print_indents (indent);
22416 printf ("]");
22417 break;
22418 }
22419 break;
22420
22421 case MSGPACK_OBJECT_MAP:
22422 {
22423 const msgpack_object_map *map = &obj->via.map;
22424
22425 printf ("{\n");
22426 ++indent;
22427
22428 for (uint32_t i = 0; i < map->size; ++i)
22429 {
22430 const msgpack_object_kv *kv = &map->ptr[i];
22431 const msgpack_object *key = &kv->key;
22432 const msgpack_object *val = &kv->val;
22433
22434 print_indents (indent);
22435 dump_msgpack_obj (key, indent);
22436 printf (": ");
22437 dump_msgpack_obj (val, indent);
22438
22439 printf (",\n");
22440 }
22441
22442 --indent;
22443 print_indents (indent);
22444 printf ("}");
22445
22446 break;
22447 }
22448
22449 case MSGPACK_OBJECT_BIN:
22450 printf ("(bin)");
22451 break;
22452
22453 case MSGPACK_OBJECT_EXT:
22454 printf ("(ext)");
22455 break;
22456 }
22457}
22458
22459static void
22460dump_msgpack (const msgpack_unpacked *msg)
22461{
22462 print_indents (0);
22463 dump_msgpack_obj (&msg->data, 0);
22464 printf ("\n");
22465}
22466
22467#endif /* defined HAVE_MSGPACK */
22468
22469static bool
22470print_amdgpu_note (Elf_Internal_Note *pnote)
22471{
22472#if defined HAVE_MSGPACK
22473 /* If msgpack is available, decode and dump the note's content. */
22474 bool ret;
22475 msgpack_unpacked msg;
22476 msgpack_unpack_return msgpack_ret;
22477
22478 assert (pnote->type == NT_AMDGPU_METADATA);
22479
22480 msgpack_unpacked_init (&msg);
22481 msgpack_ret = msgpack_unpack_next (&msg, pnote->descdata, pnote->descsz,
22482 NULL);
22483
22484 switch (msgpack_ret)
22485 {
22486 case MSGPACK_UNPACK_SUCCESS:
22487 dump_msgpack (&msg);
22488 ret = true;
22489 break;
22490
22491 default:
22492 error (_("failed to unpack msgpack contents in NT_AMDGPU_METADATA note"));
22493 ret = false;
22494 break;
22495 }
22496
22497 msgpack_unpacked_destroy (&msg);
22498 return ret;
22499#else
22500 /* msgpack is not available, dump contents as hex. */
22501 print_note_contents_hex (pnote);
22502 return true;
22503#endif
22504}
22505
e263a66b
CC
22506static bool
22507print_qnx_note (Elf_Internal_Note *pnote)
22508{
22509 switch (pnote->type)
22510 {
22511 case QNT_STACK:
22512 if (pnote->descsz != 12)
22513 goto desc_size_fail;
22514
22515 printf (_(" Stack Size: 0x%" PRIx32 "\n"),
22516 (unsigned) byte_get ((unsigned char *) pnote->descdata, 4));
22517 printf (_(" Stack allocated: %" PRIx32 "\n"),
22518 (unsigned) byte_get ((unsigned char *) pnote->descdata + 4, 4));
22519 printf (_(" Executable: %s\n"),
22520 ((unsigned) byte_get ((unsigned char *) pnote->descdata + 8, 1)) ? "no": "yes");
22521 break;
22522
22523 default:
22524 print_note_contents_hex(pnote);
22525 }
22526 return true;
22527
22528desc_size_fail:
22529 printf (_(" <corrupt - data size is too small>\n"));
22530 error (_("corrupt QNX note: data size is too small\n"));
22531 return false;
22532}
22533
22534
6d118b09
NC
22535/* Note that by the ELF standard, the name field is already null byte
22536 terminated, and namesz includes the terminating null byte.
22537 I.E. the value of namesz for the name "FSF" is 4.
22538
e3c8793a 22539 If the value of namesz is zero, there is no name present. */
9ef920e9 22540
015dc7e1 22541static bool
9ef920e9 22542process_note (Elf_Internal_Note * pnote,
dda8d76d 22543 Filedata * filedata)
779fe533 22544{
2cf0635d
NC
22545 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
22546 const char * nt;
9437c45b
JT
22547
22548 if (pnote->namesz == 0)
1ec5cd37
NC
22549 /* If there is no note name, then use the default set of
22550 note type strings. */
dda8d76d 22551 nt = get_note_type (filedata, pnote->type);
1ec5cd37 22552
24d127aa 22553 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
22554 /* GNU-specific object file notes. */
22555 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 22556
28cdbb18
SM
22557 else if (startswith (pnote->namedata, "AMDGPU"))
22558 /* AMDGPU-specific object file notes. */
22559 nt = get_amdgpu_elf_note_type (pnote->type);
22560
24d127aa 22561 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 22562 /* FreeBSD-specific core file notes. */
dda8d76d 22563 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 22564
24d127aa 22565 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 22566 /* NetBSD-specific core file notes. */
dda8d76d 22567 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 22568
24d127aa 22569 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
22570 /* NetBSD-specific core file notes. */
22571 return process_netbsd_elf_note (pnote);
22572
24d127aa 22573 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
22574 /* NetBSD-specific core file notes. */
22575 return process_netbsd_elf_note (pnote);
22576
98ca73af
FC
22577 else if (startswith (pnote->namedata, "OpenBSD"))
22578 /* OpenBSD-specific core file notes. */
22579 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
22580
e263a66b
CC
22581 else if (startswith (pnote->namedata, "QNX"))
22582 /* QNX-specific core file notes. */
22583 nt = get_qnx_elfcore_note_type (filedata, pnote->type);
22584
e9b095a5 22585 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
22586 {
22587 /* SPU-specific core file notes. */
22588 nt = pnote->namedata + 4;
22589 name = "SPU";
22590 }
22591
24d127aa 22592 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
22593 /* VMS/ia64-specific file notes. */
22594 nt = get_ia64_vms_note_type (pnote->type);
22595
24d127aa 22596 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
22597 nt = get_stapsdt_note_type (pnote->type);
22598
9437c45b 22599 else
1ec5cd37
NC
22600 /* Don't recognize this note name; just use the default set of
22601 note type strings. */
dda8d76d 22602 nt = get_note_type (filedata, pnote->type);
9437c45b 22603
1449284b 22604 printf (" ");
9ef920e9 22605
24d127aa 22606 if (((startswith (pnote->namedata, "GA")
483767a3
AM
22607 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22608 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22609 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22610 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
22611 print_gnu_build_attribute_name (pnote);
22612 else
b6ac461a 22613 print_symbol_name (-20, name);
9ef920e9
NC
22614
22615 if (do_wide)
22616 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
22617 else
22618 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 22619
24d127aa 22620 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 22621 return print_ia64_vms_note (pnote);
24d127aa 22622 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 22623 return print_gnu_note (filedata, pnote);
24d127aa 22624 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 22625 return print_stapsdt_note (pnote);
24d127aa 22626 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 22627 return print_core_note (pnote);
e5382207
LB
22628 else if (startswith (pnote->namedata, "FDO"))
22629 return print_fdo_note (pnote);
24d127aa 22630 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
22631 && strchr ("*$!+", pnote->namedata[2]) != NULL)
22632 || strchr ("*$!+", pnote->namedata[0]) != NULL)
22633 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
22634 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 22635 return print_gnu_build_attribute_description (pnote, filedata);
2952f10c
SM
22636 else if (startswith (pnote->namedata, "AMDGPU")
22637 && pnote->type == NT_AMDGPU_METADATA)
22638 return print_amdgpu_note (pnote);
e263a66b
CC
22639 else if (startswith (pnote->namedata, "QNX"))
22640 return print_qnx_note (pnote);
779fe533 22641
2952f10c 22642 print_note_contents_hex (pnote);
015dc7e1 22643 return true;
1449284b 22644}
6d118b09 22645
015dc7e1 22646static bool
dda8d76d
NC
22647process_notes_at (Filedata * filedata,
22648 Elf_Internal_Shdr * section,
625d49fc
AM
22649 uint64_t offset,
22650 uint64_t length,
22651 uint64_t align)
779fe533 22652{
015dc7e1
AM
22653 Elf_External_Note *pnotes;
22654 Elf_External_Note *external;
22655 char *end;
22656 bool res = true;
103f02d3 22657
779fe533 22658 if (length <= 0)
015dc7e1 22659 return false;
103f02d3 22660
1449284b
NC
22661 if (section)
22662 {
dda8d76d 22663 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 22664 if (pnotes)
32ec8896 22665 {
dda8d76d 22666 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
22667 {
22668 free (pnotes);
015dc7e1 22669 return false;
f761cb13 22670 }
32ec8896 22671 }
1449284b
NC
22672 }
22673 else
82ed9683 22674 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 22675 _("notes"));
4dff97b2 22676
dd24e3da 22677 if (pnotes == NULL)
015dc7e1 22678 return false;
779fe533 22679
103f02d3 22680 external = pnotes;
103f02d3 22681
ca0e11aa
NC
22682 if (filedata->is_separate)
22683 printf (_("In linked file '%s': "), filedata->file_name);
22684 else
22685 printf ("\n");
1449284b 22686 if (section)
ca0e11aa 22687 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 22688 else
26c527e6
AM
22689 printf (_("Displaying notes found at file offset 0x%08" PRIx64
22690 " with length 0x%08" PRIx64 ":\n"),
22691 offset, length);
1449284b 22692
82ed9683
L
22693 /* NB: Some note sections may have alignment value of 0 or 1. gABI
22694 specifies that notes should be aligned to 4 bytes in 32-bit
22695 objects and to 8 bytes in 64-bit objects. As a Linux extension,
22696 we also support 4 byte alignment in 64-bit objects. If section
22697 alignment is less than 4, we treate alignment as 4 bytes. */
22698 if (align < 4)
22699 align = 4;
22700 else if (align != 4 && align != 8)
22701 {
26c527e6
AM
22702 warn (_("Corrupt note: alignment %" PRId64 ", expecting 4 or 8\n"),
22703 align);
a788aedd 22704 free (pnotes);
015dc7e1 22705 return false;
82ed9683
L
22706 }
22707
dbe15e4e 22708 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 22709
c8071705
NC
22710 end = (char *) pnotes + length;
22711 while ((char *) external < end)
779fe533 22712 {
b34976b6 22713 Elf_Internal_Note inote;
15b42fb0 22714 size_t min_notesz;
4dff97b2 22715 char * next;
2cf0635d 22716 char * temp = NULL;
c8071705 22717 size_t data_remaining = end - (char *) external;
6d118b09 22718
dda8d76d 22719 if (!is_ia64_vms (filedata))
15b42fb0 22720 {
9dd3a467
NC
22721 /* PR binutils/15191
22722 Make sure that there is enough data to read. */
15b42fb0
AM
22723 min_notesz = offsetof (Elf_External_Note, name);
22724 if (data_remaining < min_notesz)
9dd3a467 22725 {
26c527e6 22726 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22727 "not enough for a full note\n",
26c527e6 22728 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22729 "not enough for a full note\n",
22730 data_remaining),
26c527e6 22731 data_remaining);
9dd3a467
NC
22732 break;
22733 }
5396a86e
AM
22734 data_remaining -= min_notesz;
22735
15b42fb0
AM
22736 inote.type = BYTE_GET (external->type);
22737 inote.namesz = BYTE_GET (external->namesz);
22738 inote.namedata = external->name;
22739 inote.descsz = BYTE_GET (external->descsz);
276da9b3 22740 inote.descdata = ((char *) external
4dff97b2 22741 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 22742 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 22743 next = ((char *) external
4dff97b2 22744 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 22745 }
00e98fc7 22746 else
15b42fb0
AM
22747 {
22748 Elf64_External_VMS_Note *vms_external;
00e98fc7 22749
9dd3a467
NC
22750 /* PR binutils/15191
22751 Make sure that there is enough data to read. */
15b42fb0
AM
22752 min_notesz = offsetof (Elf64_External_VMS_Note, name);
22753 if (data_remaining < min_notesz)
9dd3a467 22754 {
26c527e6 22755 warn (ngettext ("Corrupt note: only %zd byte remains, "
d3a49aa8 22756 "not enough for a full note\n",
26c527e6 22757 "Corrupt note: only %zd bytes remain, "
d3a49aa8
AM
22758 "not enough for a full note\n",
22759 data_remaining),
26c527e6 22760 data_remaining);
9dd3a467
NC
22761 break;
22762 }
5396a86e 22763 data_remaining -= min_notesz;
3e55a963 22764
15b42fb0
AM
22765 vms_external = (Elf64_External_VMS_Note *) external;
22766 inote.type = BYTE_GET (vms_external->type);
22767 inote.namesz = BYTE_GET (vms_external->namesz);
22768 inote.namedata = vms_external->name;
22769 inote.descsz = BYTE_GET (vms_external->descsz);
22770 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
22771 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22772 next = inote.descdata + align_power (inote.descsz, 3);
22773 }
22774
5396a86e
AM
22775 /* PR 17531: file: 3443835e. */
22776 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
22777 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
22778 || (size_t) (inote.descdata - inote.namedata) > data_remaining
22779 || (size_t) (next - inote.descdata) < inote.descsz
22780 || ((size_t) (next - inote.descdata)
22781 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 22782 {
26c527e6
AM
22783 warn (_("note with invalid namesz and/or descsz found at offset %#tx\n"),
22784 (char *) external - (char *) pnotes);
22785 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx, alignment: %u\n"),
4dff97b2 22786 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
22787 break;
22788 }
22789
15b42fb0 22790 external = (Elf_External_Note *) next;
dd24e3da 22791
6d118b09
NC
22792 /* Verify that name is null terminated. It appears that at least
22793 one version of Linux (RedHat 6.0) generates corefiles that don't
22794 comply with the ELF spec by failing to include the null byte in
22795 namesz. */
18344509 22796 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 22797 {
5396a86e 22798 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 22799 {
5396a86e
AM
22800 temp = (char *) malloc (inote.namesz + 1);
22801 if (temp == NULL)
22802 {
22803 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 22804 res = false;
5396a86e
AM
22805 break;
22806 }
76da6bbe 22807
5396a86e
AM
22808 memcpy (temp, inote.namedata, inote.namesz);
22809 inote.namedata = temp;
22810 }
22811 inote.namedata[inote.namesz] = 0;
6d118b09
NC
22812 }
22813
dda8d76d 22814 if (! process_note (& inote, filedata))
015dc7e1 22815 res = false;
103f02d3 22816
9db70fc3
AM
22817 free (temp);
22818 temp = NULL;
779fe533
NC
22819 }
22820
22821 free (pnotes);
103f02d3 22822
779fe533
NC
22823 return res;
22824}
22825
015dc7e1 22826static bool
dda8d76d 22827process_corefile_note_segments (Filedata * filedata)
779fe533 22828{
015dc7e1 22829 Elf_Internal_Phdr *segment;
b34976b6 22830 unsigned int i;
015dc7e1 22831 bool res = true;
103f02d3 22832
dda8d76d 22833 if (! get_program_headers (filedata))
015dc7e1 22834 return true;
103f02d3 22835
dda8d76d
NC
22836 for (i = 0, segment = filedata->program_headers;
22837 i < filedata->file_header.e_phnum;
b34976b6 22838 i++, segment++)
779fe533
NC
22839 {
22840 if (segment->p_type == PT_NOTE)
625d49fc
AM
22841 if (! process_notes_at (filedata, NULL, segment->p_offset,
22842 segment->p_filesz, segment->p_align))
015dc7e1 22843 res = false;
779fe533 22844 }
103f02d3 22845
779fe533
NC
22846 return res;
22847}
22848
015dc7e1 22849static bool
625d49fc 22850process_v850_notes (Filedata * filedata, uint64_t offset, uint64_t length)
685080f2
NC
22851{
22852 Elf_External_Note * pnotes;
22853 Elf_External_Note * external;
c8071705 22854 char * end;
015dc7e1 22855 bool res = true;
685080f2
NC
22856
22857 if (length <= 0)
015dc7e1 22858 return false;
685080f2 22859
dda8d76d 22860 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
22861 _("v850 notes"));
22862 if (pnotes == NULL)
015dc7e1 22863 return false;
685080f2
NC
22864
22865 external = pnotes;
c8071705 22866 end = (char*) pnotes + length;
685080f2 22867
26c527e6
AM
22868 printf (_("\nDisplaying contents of Renesas V850 notes section at offset"
22869 " %#" PRIx64 " with length %#" PRIx64 ":\n"),
22870 offset, length);
685080f2 22871
c8071705 22872 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
22873 {
22874 Elf_External_Note * next;
22875 Elf_Internal_Note inote;
22876
22877 inote.type = BYTE_GET (external->type);
22878 inote.namesz = BYTE_GET (external->namesz);
22879 inote.namedata = external->name;
22880 inote.descsz = BYTE_GET (external->descsz);
22881 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
22882 inote.descpos = offset + (inote.descdata - (char *) pnotes);
22883
c8071705
NC
22884 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
22885 {
22886 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
22887 inote.descdata = inote.namedata;
22888 inote.namesz = 0;
22889 }
22890
685080f2
NC
22891 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
22892
c8071705 22893 if ( ((char *) next > end)
685080f2
NC
22894 || ((char *) next < (char *) pnotes))
22895 {
26c527e6
AM
22896 warn (_("corrupt descsz found in note at offset %#tx\n"),
22897 (char *) external - (char *) pnotes);
22898 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22899 inote.type, inote.namesz, inote.descsz);
22900 break;
22901 }
22902
22903 external = next;
22904
22905 /* Prevent out-of-bounds indexing. */
c8071705 22906 if ( inote.namedata + inote.namesz > end
685080f2
NC
22907 || inote.namedata + inote.namesz < inote.namedata)
22908 {
26c527e6
AM
22909 warn (_("corrupt namesz found in note at offset %#zx\n"),
22910 (char *) external - (char *) pnotes);
22911 warn (_(" type: %#lx, namesize: %#lx, descsize: %#lx\n"),
685080f2
NC
22912 inote.type, inote.namesz, inote.descsz);
22913 break;
22914 }
22915
22916 printf (" %s: ", get_v850_elf_note_type (inote.type));
22917
22918 if (! print_v850_note (& inote))
22919 {
015dc7e1 22920 res = false;
26c527e6 22921 printf ("<corrupt sizes: namesz: %#lx, descsz: %#lx>\n",
685080f2
NC
22922 inote.namesz, inote.descsz);
22923 }
22924 }
22925
22926 free (pnotes);
22927
22928 return res;
22929}
22930
015dc7e1 22931static bool
dda8d76d 22932process_note_sections (Filedata * filedata)
1ec5cd37 22933{
015dc7e1 22934 Elf_Internal_Shdr *section;
26c527e6 22935 size_t i;
32ec8896 22936 unsigned int n = 0;
015dc7e1 22937 bool res = true;
1ec5cd37 22938
dda8d76d
NC
22939 for (i = 0, section = filedata->section_headers;
22940 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 22941 i++, section++)
685080f2
NC
22942 {
22943 if (section->sh_type == SHT_NOTE)
22944 {
625d49fc
AM
22945 if (! process_notes_at (filedata, section, section->sh_offset,
22946 section->sh_size, section->sh_addralign))
015dc7e1 22947 res = false;
685080f2
NC
22948 n++;
22949 }
22950
dda8d76d
NC
22951 if (( filedata->file_header.e_machine == EM_V800
22952 || filedata->file_header.e_machine == EM_V850
22953 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
22954 && section->sh_type == SHT_RENESAS_INFO)
22955 {
625d49fc
AM
22956 if (! process_v850_notes (filedata, section->sh_offset,
22957 section->sh_size))
015dc7e1 22958 res = false;
685080f2
NC
22959 n++;
22960 }
22961 }
df565f32
NC
22962
22963 if (n == 0)
22964 /* Try processing NOTE segments instead. */
dda8d76d 22965 return process_corefile_note_segments (filedata);
1ec5cd37
NC
22966
22967 return res;
22968}
22969
015dc7e1 22970static bool
dda8d76d 22971process_notes (Filedata * filedata)
779fe533
NC
22972{
22973 /* If we have not been asked to display the notes then do nothing. */
22974 if (! do_notes)
015dc7e1 22975 return true;
103f02d3 22976
dda8d76d
NC
22977 if (filedata->file_header.e_type != ET_CORE)
22978 return process_note_sections (filedata);
103f02d3 22979
779fe533 22980 /* No program headers means no NOTE segment. */
dda8d76d
NC
22981 if (filedata->file_header.e_phnum > 0)
22982 return process_corefile_note_segments (filedata);
779fe533 22983
ca0e11aa
NC
22984 if (filedata->is_separate)
22985 printf (_("No notes found in linked file '%s'.\n"),
22986 filedata->file_name);
22987 else
22988 printf (_("No notes found file.\n"));
22989
015dc7e1 22990 return true;
779fe533
NC
22991}
22992
60abdbed
NC
22993static unsigned char *
22994display_public_gnu_attributes (unsigned char * start,
22995 const unsigned char * const end)
22996{
22997 printf (_(" Unknown GNU attribute: %s\n"), start);
22998
22999 start += strnlen ((char *) start, end - start);
23000 display_raw_attribute (start, end);
23001
23002 return (unsigned char *) end;
23003}
23004
23005static unsigned char *
23006display_generic_attribute (unsigned char * start,
23007 unsigned int tag,
23008 const unsigned char * const end)
23009{
23010 if (tag == 0)
23011 return (unsigned char *) end;
23012
23013 return display_tag_value (tag, start, end);
23014}
23015
015dc7e1 23016static bool
dda8d76d 23017process_arch_specific (Filedata * filedata)
252b5132 23018{
a952a375 23019 if (! do_arch)
015dc7e1 23020 return true;
a952a375 23021
dda8d76d 23022 switch (filedata->file_header.e_machine)
252b5132 23023 {
53a346d8
CZ
23024 case EM_ARC:
23025 case EM_ARC_COMPACT:
23026 case EM_ARC_COMPACT2:
b5c37946
SJ
23027 case EM_ARC_COMPACT3:
23028 case EM_ARC_COMPACT3_64:
dda8d76d 23029 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
23030 display_arc_attribute,
23031 display_generic_attribute);
11c1ff18 23032 case EM_ARM:
dda8d76d 23033 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
23034 display_arm_attribute,
23035 display_generic_attribute);
23036
252b5132 23037 case EM_MIPS:
4fe85591 23038 case EM_MIPS_RS3_LE:
dda8d76d 23039 return process_mips_specific (filedata);
60abdbed
NC
23040
23041 case EM_MSP430:
dda8d76d 23042 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 23043 display_msp430_attribute,
c0ea7c52 23044 display_msp430_gnu_attribute);
60abdbed 23045
2dc8dd17
JW
23046 case EM_RISCV:
23047 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
23048 display_riscv_attribute,
23049 display_generic_attribute);
23050
35c08157 23051 case EM_NDS32:
dda8d76d 23052 return process_nds32_specific (filedata);
60abdbed 23053
85f7484a
PB
23054 case EM_68K:
23055 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
23056 display_m68k_gnu_attribute);
23057
34c8bcba 23058 case EM_PPC:
b82317dd 23059 case EM_PPC64:
dda8d76d 23060 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23061 display_power_gnu_attribute);
23062
643f7afb
AK
23063 case EM_S390:
23064 case EM_S390_OLD:
dda8d76d 23065 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23066 display_s390_gnu_attribute);
23067
9e8c70f9
DM
23068 case EM_SPARC:
23069 case EM_SPARC32PLUS:
23070 case EM_SPARCV9:
dda8d76d 23071 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
23072 display_sparc_gnu_attribute);
23073
59e6276b 23074 case EM_TI_C6000:
dda8d76d 23075 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
23076 display_tic6x_attribute,
23077 display_generic_attribute);
23078
0861f561
CQ
23079 case EM_CSKY:
23080 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
23081 display_csky_attribute, NULL);
23082
252b5132 23083 default:
dda8d76d 23084 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
23085 display_public_gnu_attributes,
23086 display_generic_attribute);
252b5132 23087 }
252b5132
RH
23088}
23089
015dc7e1 23090static bool
dda8d76d 23091get_file_header (Filedata * filedata)
252b5132 23092{
9ea033b2 23093 /* Read in the identity array. */
dda8d76d 23094 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23095 return false;
252b5132 23096
9ea033b2 23097 /* Determine how to read the rest of the header. */
dda8d76d 23098 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 23099 {
1a0670f3
AM
23100 default:
23101 case ELFDATANONE:
adab8cdc
AO
23102 case ELFDATA2LSB:
23103 byte_get = byte_get_little_endian;
23104 byte_put = byte_put_little_endian;
23105 break;
23106 case ELFDATA2MSB:
23107 byte_get = byte_get_big_endian;
23108 byte_put = byte_put_big_endian;
23109 break;
9ea033b2
NC
23110 }
23111
23112 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 23113 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
23114
23115 /* Read in the rest of the header. */
23116 if (is_32bit_elf)
23117 {
23118 Elf32_External_Ehdr ehdr32;
252b5132 23119
dda8d76d 23120 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23121 return false;
103f02d3 23122
dda8d76d
NC
23123 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
23124 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
23125 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
23126 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
23127 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
23128 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
23129 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
23130 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
23131 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
23132 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
23133 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
23134 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
23135 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 23136 }
252b5132 23137 else
9ea033b2
NC
23138 {
23139 Elf64_External_Ehdr ehdr64;
a952a375 23140
dda8d76d 23141 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 23142 return false;
103f02d3 23143
dda8d76d
NC
23144 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
23145 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
23146 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
23147 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
23148 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
23149 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
23150 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
23151 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
23152 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
23153 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
23154 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
23155 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
23156 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 23157 }
252b5132 23158
015dc7e1 23159 return true;
252b5132
RH
23160}
23161
13acb58d
AM
23162static void
23163free_filedata (Filedata *filedata)
23164{
23165 free (filedata->program_interpreter);
13acb58d 23166 free (filedata->program_headers);
13acb58d 23167 free (filedata->section_headers);
13acb58d 23168 free (filedata->string_table);
13acb58d 23169 free (filedata->dump.dump_sects);
13acb58d 23170 free (filedata->dynamic_strings);
13acb58d 23171 free (filedata->dynamic_symbols);
13acb58d 23172 free (filedata->dynamic_syminfo);
13acb58d 23173 free (filedata->dynamic_section);
13acb58d
AM
23174
23175 while (filedata->symtab_shndx_list != NULL)
23176 {
23177 elf_section_list *next = filedata->symtab_shndx_list->next;
23178 free (filedata->symtab_shndx_list);
23179 filedata->symtab_shndx_list = next;
23180 }
23181
23182 free (filedata->section_headers_groups);
13acb58d
AM
23183
23184 if (filedata->section_groups)
23185 {
23186 size_t i;
23187 struct group_list * g;
23188 struct group_list * next;
23189
23190 for (i = 0; i < filedata->group_count; i++)
23191 {
23192 for (g = filedata->section_groups [i].root; g != NULL; g = next)
23193 {
23194 next = g->next;
23195 free (g);
23196 }
23197 }
23198
23199 free (filedata->section_groups);
13acb58d 23200 }
066f8fbe
AM
23201 memset (&filedata->section_headers, 0,
23202 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
23203}
23204
dda8d76d
NC
23205static void
23206close_file (Filedata * filedata)
23207{
23208 if (filedata)
23209 {
23210 if (filedata->handle)
23211 fclose (filedata->handle);
23212 free (filedata);
23213 }
23214}
23215
23216void
23217close_debug_file (void * data)
23218{
13acb58d 23219 free_filedata ((Filedata *) data);
dda8d76d
NC
23220 close_file ((Filedata *) data);
23221}
23222
23223static Filedata *
015dc7e1 23224open_file (const char * pathname, bool is_separate)
dda8d76d
NC
23225{
23226 struct stat statbuf;
23227 Filedata * filedata = NULL;
23228
23229 if (stat (pathname, & statbuf) < 0
23230 || ! S_ISREG (statbuf.st_mode))
23231 goto fail;
23232
23233 filedata = calloc (1, sizeof * filedata);
23234 if (filedata == NULL)
23235 goto fail;
23236
23237 filedata->handle = fopen (pathname, "rb");
23238 if (filedata->handle == NULL)
23239 goto fail;
23240
be7d229a 23241 filedata->file_size = statbuf.st_size;
dda8d76d 23242 filedata->file_name = pathname;
ca0e11aa 23243 filedata->is_separate = is_separate;
dda8d76d
NC
23244
23245 if (! get_file_header (filedata))
23246 goto fail;
23247
4de91c10
AM
23248 if (!get_section_headers (filedata, false))
23249 goto fail;
dda8d76d
NC
23250
23251 return filedata;
23252
23253 fail:
23254 if (filedata)
23255 {
23256 if (filedata->handle)
23257 fclose (filedata->handle);
23258 free (filedata);
23259 }
23260 return NULL;
23261}
23262
23263void *
23264open_debug_file (const char * pathname)
23265{
015dc7e1 23266 return open_file (pathname, true);
dda8d76d
NC
23267}
23268
835f2fae
NC
23269static void
23270initialise_dump_sects (Filedata * filedata)
23271{
23272 /* Initialise the dump_sects array from the cmdline_dump_sects array.
23273 Note we do this even if cmdline_dump_sects is empty because we
23274 must make sure that the dump_sets array is zeroed out before each
23275 object file is processed. */
23276 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
23277 memset (filedata->dump.dump_sects, 0,
23278 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23279
23280 if (cmdline.num_dump_sects > 0)
23281 {
23282 if (filedata->dump.num_dump_sects == 0)
23283 /* A sneaky way of allocating the dump_sects array. */
23284 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
23285
23286 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
23287 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
23288 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
23289 }
23290}
23291
94585d6d
NC
23292static bool
23293might_need_separate_debug_info (Filedata * filedata)
23294{
23295 /* Debuginfo files do not need further separate file loading. */
23296 if (filedata->file_header.e_shstrndx == SHN_UNDEF)
23297 return false;
23298
23299 /* Since do_follow_links might be enabled by default, only treat it as an
23300 indication that separate files should be loaded if setting it was a
23301 deliberate user action. */
23302 if (DEFAULT_FOR_FOLLOW_LINKS == 0 && do_follow_links)
23303 return true;
23304
23305 if (process_links || do_syms || do_unwind
23306 || dump_any_debugging || do_dump || do_debugging)
23307 return true;
23308
23309 return false;
23310}
23311
fb52b2f4
NC
23312/* Process one ELF object file according to the command line options.
23313 This file may actually be stored in an archive. The file is
32ec8896
NC
23314 positioned at the start of the ELF object. Returns TRUE if no
23315 problems were encountered, FALSE otherwise. */
fb52b2f4 23316
015dc7e1 23317static bool
dda8d76d 23318process_object (Filedata * filedata)
252b5132 23319{
015dc7e1 23320 bool have_separate_files;
252b5132 23321 unsigned int i;
015dc7e1 23322 bool res;
252b5132 23323
dda8d76d 23324 if (! get_file_header (filedata))
252b5132 23325 {
dda8d76d 23326 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 23327 return false;
252b5132
RH
23328 }
23329
23330 /* Initialise per file variables. */
978c4450
AM
23331 for (i = ARRAY_SIZE (filedata->version_info); i--;)
23332 filedata->version_info[i] = 0;
252b5132 23333
978c4450
AM
23334 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
23335 filedata->dynamic_info[i] = 0;
23336 filedata->dynamic_info_DT_GNU_HASH = 0;
23337 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
23338
23339 /* Process the file. */
23340 if (show_name)
dda8d76d 23341 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 23342
835f2fae 23343 initialise_dump_sects (filedata);
d70c5fc7 23344
4de91c10
AM
23345 /* There may be some extensions in the first section header. Don't
23346 bomb if we can't read it. */
23347 get_section_headers (filedata, true);
23348
dda8d76d 23349 if (! process_file_header (filedata))
4de91c10
AM
23350 {
23351 res = false;
23352 goto out;
23353 }
252b5132 23354
e331b18d
AM
23355 /* Throw away the single section header read above, so that we
23356 re-read the entire set. */
23357 free (filedata->section_headers);
23358 filedata->section_headers = NULL;
23359
dda8d76d 23360 if (! process_section_headers (filedata))
2f62977e 23361 {
32ec8896 23362 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 23363 do_unwind = do_version = do_dump = do_arch = false;
252b5132 23364
2f62977e 23365 if (! do_using_dynamic)
015dc7e1 23366 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 23367 }
252b5132 23368
dda8d76d 23369 if (! process_section_groups (filedata))
32ec8896 23370 /* Without loaded section groups we cannot process unwind. */
015dc7e1 23371 do_unwind = false;
d1f5c6e3 23372
93df3340
AM
23373 process_program_headers (filedata);
23374
23375 res = process_dynamic_section (filedata);
252b5132 23376
dda8d76d 23377 if (! process_relocs (filedata))
015dc7e1 23378 res = false;
252b5132 23379
dda8d76d 23380 if (! process_unwind (filedata))
015dc7e1 23381 res = false;
4d6ed7c8 23382
dda8d76d 23383 if (! process_symbol_table (filedata))
015dc7e1 23384 res = false;
252b5132 23385
0f03783c 23386 if (! process_lto_symbol_tables (filedata))
015dc7e1 23387 res = false;
b9e920ec 23388
dda8d76d 23389 if (! process_syminfo (filedata))
015dc7e1 23390 res = false;
252b5132 23391
dda8d76d 23392 if (! process_version_sections (filedata))
015dc7e1 23393 res = false;
252b5132 23394
94585d6d 23395 if (might_need_separate_debug_info (filedata))
24841daa 23396 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 23397 else
015dc7e1 23398 have_separate_files = false;
dda8d76d
NC
23399
23400 if (! process_section_contents (filedata))
015dc7e1 23401 res = false;
f5842774 23402
24841daa 23403 if (have_separate_files)
dda8d76d 23404 {
24841daa
NC
23405 separate_info * d;
23406
23407 for (d = first_separate_info; d != NULL; d = d->next)
23408 {
835f2fae
NC
23409 initialise_dump_sects (d->handle);
23410
ca0e11aa 23411 if (process_links && ! process_file_header (d->handle))
015dc7e1 23412 res = false;
ca0e11aa 23413 else if (! process_section_headers (d->handle))
015dc7e1 23414 res = false;
d6bfbc39 23415 else if (! process_section_contents (d->handle))
015dc7e1 23416 res = false;
ca0e11aa
NC
23417 else if (process_links)
23418 {
ca0e11aa 23419 if (! process_section_groups (d->handle))
015dc7e1 23420 res = false;
93df3340 23421 process_program_headers (d->handle);
ca0e11aa 23422 if (! process_dynamic_section (d->handle))
015dc7e1 23423 res = false;
ca0e11aa 23424 if (! process_relocs (d->handle))
015dc7e1 23425 res = false;
ca0e11aa 23426 if (! process_unwind (d->handle))
015dc7e1 23427 res = false;
ca0e11aa 23428 if (! process_symbol_table (d->handle))
015dc7e1 23429 res = false;
ca0e11aa 23430 if (! process_lto_symbol_tables (d->handle))
015dc7e1 23431 res = false;
ca0e11aa 23432 if (! process_syminfo (d->handle))
015dc7e1 23433 res = false;
ca0e11aa 23434 if (! process_version_sections (d->handle))
015dc7e1 23435 res = false;
ca0e11aa 23436 if (! process_notes (d->handle))
015dc7e1 23437 res = false;
ca0e11aa 23438 }
24841daa
NC
23439 }
23440
23441 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
23442 }
23443
23444 if (! process_notes (filedata))
015dc7e1 23445 res = false;
103f02d3 23446
dda8d76d 23447 if (! process_gnu_liblist (filedata))
015dc7e1 23448 res = false;
047b2264 23449
dda8d76d 23450 if (! process_arch_specific (filedata))
015dc7e1 23451 res = false;
252b5132 23452
4de91c10 23453 out:
13acb58d 23454 free_filedata (filedata);
e4b17d5c 23455
19e6b90e 23456 free_debug_memory ();
18bd398b 23457
32ec8896 23458 return res;
252b5132
RH
23459}
23460
2cf0635d 23461/* Process an ELF archive.
32ec8896
NC
23462 On entry the file is positioned just after the ARMAG string.
23463 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 23464
015dc7e1
AM
23465static bool
23466process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
23467{
23468 struct archive_info arch;
23469 struct archive_info nested_arch;
23470 size_t got;
015dc7e1 23471 bool ret = true;
2cf0635d 23472
015dc7e1 23473 show_name = true;
2cf0635d
NC
23474
23475 /* The ARCH structure is used to hold information about this archive. */
23476 arch.file_name = NULL;
23477 arch.file = NULL;
23478 arch.index_array = NULL;
23479 arch.sym_table = NULL;
23480 arch.longnames = NULL;
23481
23482 /* The NESTED_ARCH structure is used as a single-item cache of information
23483 about a nested archive (when members of a thin archive reside within
23484 another regular archive file). */
23485 nested_arch.file_name = NULL;
23486 nested_arch.file = NULL;
23487 nested_arch.index_array = NULL;
23488 nested_arch.sym_table = NULL;
23489 nested_arch.longnames = NULL;
23490
dda8d76d 23491 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
23492 filedata->file_size, is_thin_archive,
23493 do_archive_index) != 0)
2cf0635d 23494 {
015dc7e1 23495 ret = false;
2cf0635d 23496 goto out;
4145f1d5 23497 }
fb52b2f4 23498
4145f1d5
NC
23499 if (do_archive_index)
23500 {
2cf0635d 23501 if (arch.sym_table == NULL)
1cb7d8b1
AM
23502 error (_("%s: unable to dump the index as none was found\n"),
23503 filedata->file_name);
4145f1d5
NC
23504 else
23505 {
26c527e6
AM
23506 uint64_t i, l;
23507 uint64_t current_pos;
4145f1d5 23508
26c527e6
AM
23509 printf (_("Index of archive %s: (%" PRIu64 " entries,"
23510 " %#" PRIx64 " bytes in the symbol table)\n"),
23511 filedata->file_name, arch.index_num,
1cb7d8b1 23512 arch.sym_size);
dda8d76d
NC
23513
23514 current_pos = ftell (filedata->handle);
4145f1d5 23515
2cf0635d 23516 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 23517 {
1cb7d8b1
AM
23518 if (i == 0
23519 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
23520 {
23521 char * member_name
23522 = get_archive_member_name_at (&arch, arch.index_array[i],
23523 &nested_arch);
2cf0635d 23524
1cb7d8b1
AM
23525 if (member_name != NULL)
23526 {
23527 char * qualified_name
23528 = make_qualified_name (&arch, &nested_arch,
23529 member_name);
2cf0635d 23530
1cb7d8b1
AM
23531 if (qualified_name != NULL)
23532 {
23533 printf (_("Contents of binary %s at offset "),
23534 qualified_name);
c2a7d3f5
NC
23535 (void) print_vma (arch.index_array[i], PREFIX_HEX);
23536 putchar ('\n');
1cb7d8b1
AM
23537 free (qualified_name);
23538 }
fd486f32 23539 free (member_name);
4145f1d5
NC
23540 }
23541 }
2cf0635d
NC
23542
23543 if (l >= arch.sym_size)
4145f1d5 23544 {
1cb7d8b1
AM
23545 error (_("%s: end of the symbol table reached "
23546 "before the end of the index\n"),
dda8d76d 23547 filedata->file_name);
015dc7e1 23548 ret = false;
cb8f3167 23549 break;
4145f1d5 23550 }
591f7597 23551 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
23552 printf ("\t%.*s\n",
23553 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 23554 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
23555 }
23556
67ce483b 23557 if (arch.uses_64bit_indices)
c2a7d3f5
NC
23558 l = (l + 7) & ~ 7;
23559 else
23560 l += l & 1;
23561
2cf0635d 23562 if (l < arch.sym_size)
32ec8896 23563 {
26c527e6 23564 error (ngettext ("%s: %" PRId64 " byte remains in the symbol table, "
d3a49aa8
AM
23565 "but without corresponding entries in "
23566 "the index table\n",
26c527e6 23567 "%s: %" PRId64 " bytes remain in the symbol table, "
d3a49aa8
AM
23568 "but without corresponding entries in "
23569 "the index table\n",
23570 arch.sym_size - l),
dda8d76d 23571 filedata->file_name, arch.sym_size - l);
015dc7e1 23572 ret = false;
32ec8896 23573 }
4145f1d5 23574
63cf857e 23575 if (fseek64 (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 23576 {
1cb7d8b1
AM
23577 error (_("%s: failed to seek back to start of object files "
23578 "in the archive\n"),
dda8d76d 23579 filedata->file_name);
015dc7e1 23580 ret = false;
2cf0635d 23581 goto out;
4145f1d5 23582 }
fb52b2f4 23583 }
4145f1d5
NC
23584
23585 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
23586 && !do_segments && !do_header && !do_dump && !do_version
23587 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 23588 && !do_section_groups && !do_dyn_syms)
2cf0635d 23589 {
015dc7e1 23590 ret = true; /* Archive index only. */
2cf0635d
NC
23591 goto out;
23592 }
fb52b2f4
NC
23593 }
23594
fb52b2f4
NC
23595 while (1)
23596 {
2cf0635d
NC
23597 char * name;
23598 size_t namelen;
23599 char * qualified_name;
23600
23601 /* Read the next archive header. */
63cf857e 23602 if (fseek64 (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
23603 {
23604 error (_("%s: failed to seek to next archive header\n"),
23605 arch.file_name);
015dc7e1 23606 ret = false;
1cb7d8b1
AM
23607 break;
23608 }
dda8d76d 23609 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 23610 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
23611 {
23612 if (got == 0)
2cf0635d 23613 break;
28e817cc
NC
23614 /* PR 24049 - we cannot use filedata->file_name as this will
23615 have already been freed. */
23616 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 23617
015dc7e1 23618 ret = false;
1cb7d8b1
AM
23619 break;
23620 }
2cf0635d 23621 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
23622 {
23623 error (_("%s: did not find a valid archive header\n"),
23624 arch.file_name);
015dc7e1 23625 ret = false;
1cb7d8b1
AM
23626 break;
23627 }
2cf0635d
NC
23628
23629 arch.next_arhdr_offset += sizeof arch.arhdr;
23630
978c4450 23631 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
23632
23633 name = get_archive_member_name (&arch, &nested_arch);
23634 if (name == NULL)
fb52b2f4 23635 {
28e817cc 23636 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 23637 ret = false;
d989285c 23638 break;
fb52b2f4 23639 }
2cf0635d 23640 namelen = strlen (name);
fb52b2f4 23641
2cf0635d
NC
23642 qualified_name = make_qualified_name (&arch, &nested_arch, name);
23643 if (qualified_name == NULL)
fb52b2f4 23644 {
28e817cc 23645 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 23646 free (name);
015dc7e1 23647 ret = false;
d989285c 23648 break;
fb52b2f4
NC
23649 }
23650
2cf0635d 23651 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
23652 {
23653 /* This is a proxy for an external member of a thin archive. */
23654 Filedata * member_filedata;
23655 char * member_file_name = adjust_relative_path
dda8d76d 23656 (filedata->file_name, name, namelen);
32ec8896 23657
fd486f32 23658 free (name);
1cb7d8b1
AM
23659 if (member_file_name == NULL)
23660 {
fd486f32 23661 free (qualified_name);
015dc7e1 23662 ret = false;
1cb7d8b1
AM
23663 break;
23664 }
2cf0635d 23665
015dc7e1 23666 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
23667 if (member_filedata == NULL)
23668 {
23669 error (_("Input file '%s' is not readable.\n"), member_file_name);
23670 free (member_file_name);
fd486f32 23671 free (qualified_name);
015dc7e1 23672 ret = false;
1cb7d8b1
AM
23673 break;
23674 }
2cf0635d 23675
978c4450 23676 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 23677 member_filedata->file_name = qualified_name;
2cf0635d 23678
75a2da57
AH
23679 /* The call to process_object() expects the file to be at the beginning. */
23680 rewind (member_filedata->handle);
23681
1cb7d8b1 23682 if (! process_object (member_filedata))
015dc7e1 23683 ret = false;
2cf0635d 23684
1cb7d8b1
AM
23685 close_file (member_filedata);
23686 free (member_file_name);
1cb7d8b1 23687 }
2cf0635d 23688 else if (is_thin_archive)
1cb7d8b1
AM
23689 {
23690 Filedata thin_filedata;
eb02c04d 23691
1cb7d8b1 23692 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 23693
a043396b
NC
23694 /* PR 15140: Allow for corrupt thin archives. */
23695 if (nested_arch.file == NULL)
23696 {
23697 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 23698 qualified_name, name);
fd486f32
AM
23699 free (qualified_name);
23700 free (name);
015dc7e1 23701 ret = false;
a043396b
NC
23702 break;
23703 }
fd486f32 23704 free (name);
a043396b 23705
1cb7d8b1 23706 /* This is a proxy for a member of a nested archive. */
978c4450
AM
23707 filedata->archive_file_offset
23708 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 23709
1cb7d8b1
AM
23710 /* The nested archive file will have been opened and setup by
23711 get_archive_member_name. */
63cf857e
AM
23712 if (fseek64 (nested_arch.file, filedata->archive_file_offset,
23713 SEEK_SET) != 0)
1cb7d8b1
AM
23714 {
23715 error (_("%s: failed to seek to archive member.\n"),
23716 nested_arch.file_name);
fd486f32 23717 free (qualified_name);
015dc7e1 23718 ret = false;
1cb7d8b1
AM
23719 break;
23720 }
2cf0635d 23721
dda8d76d
NC
23722 thin_filedata.handle = nested_arch.file;
23723 thin_filedata.file_name = qualified_name;
9abca702 23724
1cb7d8b1 23725 if (! process_object (& thin_filedata))
015dc7e1 23726 ret = false;
1cb7d8b1 23727 }
2cf0635d 23728 else
1cb7d8b1 23729 {
fd486f32 23730 free (name);
978c4450 23731 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 23732 filedata->file_name = qualified_name;
1cb7d8b1 23733 if (! process_object (filedata))
015dc7e1 23734 ret = false;
237877b8 23735 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 23736 /* Stop looping with "negative" archive_file_size. */
978c4450 23737 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 23738 arch.next_arhdr_offset = -1ul;
1cb7d8b1 23739 }
fb52b2f4 23740
2cf0635d 23741 free (qualified_name);
fb52b2f4
NC
23742 }
23743
4145f1d5 23744 out:
2cf0635d
NC
23745 if (nested_arch.file != NULL)
23746 fclose (nested_arch.file);
23747 release_archive (&nested_arch);
23748 release_archive (&arch);
fb52b2f4 23749
d989285c 23750 return ret;
fb52b2f4
NC
23751}
23752
015dc7e1 23753static bool
2cf0635d 23754process_file (char * file_name)
fb52b2f4 23755{
dda8d76d 23756 Filedata * filedata = NULL;
fb52b2f4
NC
23757 struct stat statbuf;
23758 char armag[SARMAG];
015dc7e1 23759 bool ret = true;
fb52b2f4
NC
23760
23761 if (stat (file_name, &statbuf) < 0)
23762 {
f24ddbdd
NC
23763 if (errno == ENOENT)
23764 error (_("'%s': No such file\n"), file_name);
23765 else
23766 error (_("Could not locate '%s'. System error message: %s\n"),
23767 file_name, strerror (errno));
015dc7e1 23768 return false;
f24ddbdd
NC
23769 }
23770
23771 if (! S_ISREG (statbuf.st_mode))
23772 {
23773 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 23774 return false;
fb52b2f4
NC
23775 }
23776
dda8d76d
NC
23777 filedata = calloc (1, sizeof * filedata);
23778 if (filedata == NULL)
23779 {
23780 error (_("Out of memory allocating file data structure\n"));
015dc7e1 23781 return false;
dda8d76d
NC
23782 }
23783
23784 filedata->file_name = file_name;
23785 filedata->handle = fopen (file_name, "rb");
23786 if (filedata->handle == NULL)
fb52b2f4 23787 {
f24ddbdd 23788 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 23789 free (filedata);
015dc7e1 23790 return false;
fb52b2f4
NC
23791 }
23792
dda8d76d 23793 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 23794 {
4145f1d5 23795 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
23796 fclose (filedata->handle);
23797 free (filedata);
015dc7e1 23798 return false;
fb52b2f4
NC
23799 }
23800
be7d229a 23801 filedata->file_size = statbuf.st_size;
015dc7e1 23802 filedata->is_separate = false;
f54498b4 23803
fb52b2f4 23804 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 23805 {
015dc7e1
AM
23806 if (! process_archive (filedata, false))
23807 ret = false;
32ec8896 23808 }
2cf0635d 23809 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 23810 {
015dc7e1
AM
23811 if ( ! process_archive (filedata, true))
23812 ret = false;
32ec8896 23813 }
fb52b2f4
NC
23814 else
23815 {
1b513401 23816 if (do_archive_index && !check_all)
4145f1d5
NC
23817 error (_("File %s is not an archive so its index cannot be displayed.\n"),
23818 file_name);
23819
dda8d76d 23820 rewind (filedata->handle);
978c4450 23821 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 23822
dda8d76d 23823 if (! process_object (filedata))
015dc7e1 23824 ret = false;
fb52b2f4
NC
23825 }
23826
dda8d76d 23827 fclose (filedata->handle);
8fb879cd
AM
23828 free (filedata->section_headers);
23829 free (filedata->program_headers);
23830 free (filedata->string_table);
6431e409 23831 free (filedata->dump.dump_sects);
dda8d76d 23832 free (filedata);
32ec8896 23833
fd486f32 23834 free (ba_cache.strtab);
1bd6175a 23835 ba_cache.strtab = NULL;
fd486f32 23836 free (ba_cache.symtab);
1bd6175a 23837 ba_cache.symtab = NULL;
fd486f32
AM
23838 ba_cache.filedata = NULL;
23839
fb52b2f4
NC
23840 return ret;
23841}
23842
252b5132
RH
23843#ifdef SUPPORT_DISASSEMBLY
23844/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 23845 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 23846 symbols. */
252b5132
RH
23847
23848void
2cf0635d 23849print_address (unsigned int addr, FILE * outfile)
252b5132
RH
23850{
23851 fprintf (outfile,"0x%8.8x", addr);
23852}
23853
e3c8793a 23854/* Needed by the i386 disassembler. */
dda8d76d 23855
252b5132
RH
23856void
23857db_task_printsym (unsigned int addr)
23858{
23859 print_address (addr, stderr);
23860}
23861#endif
23862
23863int
2cf0635d 23864main (int argc, char ** argv)
252b5132 23865{
ff78d6d6
L
23866 int err;
23867
87b9f255 23868#ifdef HAVE_LC_MESSAGES
252b5132 23869 setlocale (LC_MESSAGES, "");
3882b010 23870#endif
3882b010 23871 setlocale (LC_CTYPE, "");
252b5132
RH
23872 bindtextdomain (PACKAGE, LOCALEDIR);
23873 textdomain (PACKAGE);
23874
869b9d07
MM
23875 expandargv (&argc, &argv);
23876
dda8d76d 23877 parse_args (& cmdline, argc, argv);
59f14fc0 23878
18bd398b 23879 if (optind < (argc - 1))
1b513401
NC
23880 /* When displaying information for more than one file,
23881 prefix the information with the file name. */
015dc7e1 23882 show_name = true;
5656ba2c
L
23883 else if (optind >= argc)
23884 {
1b513401 23885 /* Ensure that the warning is always displayed. */
015dc7e1 23886 do_checks = true;
1b513401 23887
5656ba2c
L
23888 warn (_("Nothing to do.\n"));
23889 usage (stderr);
23890 }
18bd398b 23891
015dc7e1 23892 err = false;
252b5132 23893 while (optind < argc)
32ec8896 23894 if (! process_file (argv[optind++]))
015dc7e1 23895 err = true;
252b5132 23896
9db70fc3 23897 free (cmdline.dump_sects);
252b5132 23898
7d9813f1
NA
23899 free (dump_ctf_symtab_name);
23900 free (dump_ctf_strtab_name);
23901 free (dump_ctf_parent_name);
23902
32ec8896 23903 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 23904}