]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
binutils: make objdump/readelf --ctf-parent actually useful
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
7bfd842d 47#include <wchar.h>
252b5132 48
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
19e6b90e 60#include "dwarf.h"
7d9813f1 61#include "ctf-api.h"
79bc120c 62#include "demangle.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
aca4efc7 105#include "elf/bpf.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
f954747f
AM
113#include "elf/i370.h"
114#include "elf/i860.h"
115#include "elf/i960.h"
3b16e843 116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
7b4ae824 124#include "elf/s12z.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
a3c62988 127#include "elf/metag.h"
7ba29e2a 128#include "elf/microblaze.h"
3b16e843 129#include "elf/mips.h"
3c3bdf30 130#include "elf/mmix.h"
3b16e843
NC
131#include "elf/mn10200.h"
132#include "elf/mn10300.h"
5506d11a 133#include "elf/moxie.h"
4970f871 134#include "elf/mt.h"
2469cfa2 135#include "elf/msp430.h"
35c08157 136#include "elf/nds32.h"
fe944acf 137#include "elf/nfp.h"
13761a11 138#include "elf/nios2.h"
73589c9d 139#include "elf/or1k.h"
7d466069 140#include "elf/pj.h"
3b16e843 141#include "elf/ppc.h"
c833c019 142#include "elf/ppc64.h"
2b100bb5 143#include "elf/pru.h"
03336641 144#include "elf/riscv.h"
99c513f6 145#include "elf/rl78.h"
c7927a3c 146#include "elf/rx.h"
a85d7ed0 147#include "elf/s390.h"
1c0d3aa6 148#include "elf/score.h"
3b16e843
NC
149#include "elf/sh.h"
150#include "elf/sparc.h"
e9f53129 151#include "elf/spu.h"
40b36596 152#include "elf/tic6x.h"
aa137e4d
NC
153#include "elf/tilegx.h"
154#include "elf/tilepro.h"
3b16e843 155#include "elf/v850.h"
179d3252 156#include "elf/vax.h"
619ed720 157#include "elf/visium.h"
f96bd6c2 158#include "elf/wasm32.h"
3b16e843 159#include "elf/x86-64.h"
c29aca4a 160#include "elf/xc16x.h"
f6c1a2d5 161#include "elf/xgate.h"
93fbbb04 162#include "elf/xstormy16.h"
88da6820 163#include "elf/xtensa.h"
6655dba2 164#include "elf/z80.h"
e9a0721f 165#include "elf/loongarch.h"
252b5132 166
252b5132 167#include "getopt.h"
566b0d53 168#include "libiberty.h"
09c11c86 169#include "safe-ctype.h"
2cf0635d 170#include "filenames.h"
252b5132 171
15b42fb0
AM
172#ifndef offsetof
173#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
174#endif
175
6a40cf0c
NC
176typedef struct elf_section_list
177{
dda8d76d
NC
178 Elf_Internal_Shdr * hdr;
179 struct elf_section_list * next;
6a40cf0c
NC
180} elf_section_list;
181
dda8d76d
NC
182/* Flag bits indicating particular types of dump. */
183#define HEX_DUMP (1 << 0) /* The -x command line switch. */
184#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
185#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
186#define STRING_DUMP (1 << 3) /* The -p command line switch. */
187#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 188#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
189
190typedef unsigned char dump_type;
191
192/* A linked list of the section names for which dumps were requested. */
193struct dump_list_entry
194{
195 char * name;
196 dump_type type;
197 struct dump_list_entry * next;
198};
199
6431e409
AM
200/* A dynamic array of flags indicating for which sections a dump
201 has been requested via command line switches. */
1b513401
NC
202struct dump_data
203{
6431e409
AM
204 dump_type * dump_sects;
205 unsigned int num_dump_sects;
206};
207
208static struct dump_data cmdline;
209
210static struct dump_list_entry * dump_sects_byname;
211
2cf0635d 212char * program_name = "readelf";
dda8d76d 213
015dc7e1
AM
214static bool show_name = false;
215static bool do_dynamic = false;
216static bool do_syms = false;
217static bool do_dyn_syms = false;
218static bool do_lto_syms = false;
219static bool do_reloc = false;
220static bool do_sections = false;
221static bool do_section_groups = false;
222static bool do_section_details = false;
223static bool do_segments = false;
224static bool do_unwind = false;
225static bool do_using_dynamic = false;
226static bool do_header = false;
227static bool do_dump = false;
228static bool do_version = false;
229static bool do_histogram = false;
230static bool do_debugging = false;
231static bool do_ctf = false;
232static bool do_arch = false;
233static bool do_notes = false;
234static bool do_archive_index = false;
235static bool check_all = false;
236static bool is_32bit_elf = false;
237static bool decompress_dumps = false;
238static bool do_not_show_symbol_truncation = false;
239static bool do_demangle = false; /* Pretty print C++ symbol names. */
240static bool process_links = false;
79bc120c 241static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 242static int sym_base = 0;
252b5132 243
7d9813f1
NA
244static char *dump_ctf_parent_name;
245static char *dump_ctf_symtab_name;
246static char *dump_ctf_strtab_name;
247
e4b17d5c
L
248struct group_list
249{
dda8d76d
NC
250 struct group_list * next;
251 unsigned int section_index;
e4b17d5c
L
252};
253
254struct group
255{
dda8d76d
NC
256 struct group_list * root;
257 unsigned int group_index;
e4b17d5c
L
258};
259
978c4450
AM
260typedef struct filedata
261{
262 const char * file_name;
015dc7e1 263 bool is_separate;
978c4450
AM
264 FILE * handle;
265 bfd_size_type file_size;
266 Elf_Internal_Ehdr file_header;
066f8fbe
AM
267 unsigned long archive_file_offset;
268 unsigned long archive_file_size;
269 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
270 Elf_Internal_Shdr * section_headers;
271 Elf_Internal_Phdr * program_headers;
272 char * string_table;
273 unsigned long string_table_length;
978c4450
AM
274 unsigned long dynamic_addr;
275 bfd_size_type dynamic_size;
276 size_t dynamic_nent;
277 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 278 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
279 char * dynamic_strings;
280 unsigned long dynamic_strings_length;
8ac10c5b 281 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
282 unsigned long num_dynamic_syms;
283 Elf_Internal_Sym * dynamic_symbols;
284 bfd_vma version_info[16];
285 unsigned int dynamic_syminfo_nent;
286 Elf_Internal_Syminfo * dynamic_syminfo;
287 unsigned long dynamic_syminfo_offset;
288 bfd_size_type nbuckets;
289 bfd_size_type nchains;
290 bfd_vma * buckets;
291 bfd_vma * chains;
292 bfd_size_type ngnubuckets;
293 bfd_size_type ngnuchains;
294 bfd_vma * gnubuckets;
295 bfd_vma * gnuchains;
296 bfd_vma * mipsxlat;
297 bfd_vma gnusymidx;
13acb58d 298 char * program_interpreter;
978c4450
AM
299 bfd_vma dynamic_info[DT_ENCODING];
300 bfd_vma dynamic_info_DT_GNU_HASH;
301 bfd_vma dynamic_info_DT_MIPS_XHASH;
302 elf_section_list * symtab_shndx_list;
303 size_t group_count;
304 struct group * section_groups;
305 struct group ** section_headers_groups;
306 /* A dynamic array of flags indicating for which sections a dump of
307 some kind has been requested. It is reset on a per-object file
308 basis and then initialised from the cmdline_dump_sects array,
309 the results of interpreting the -w switch, and the
310 dump_sects_byname list. */
311 struct dump_data dump;
312} Filedata;
aef1f6d0 313
c256ffe7 314/* How to print a vma value. */
843dd992
NC
315typedef enum print_mode
316{
317 HEX,
047c3dbf 318 HEX_5,
843dd992
NC
319 DEC,
320 DEC_5,
321 UNSIGNED,
047c3dbf 322 UNSIGNED_5,
843dd992 323 PREFIX_HEX,
047c3dbf 324 PREFIX_HEX_5,
843dd992 325 FULL_HEX,
047c3dbf
NL
326 LONG_HEX,
327 OCTAL,
328 OCTAL_5
843dd992
NC
329}
330print_mode;
331
bb4d2ac2
L
332/* Versioned symbol info. */
333enum versioned_symbol_info
334{
335 symbol_undefined,
336 symbol_hidden,
337 symbol_public
338};
339
32ec8896 340static const char * get_symbol_version_string
015dc7e1 341 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 342 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 343
9c19a809
NC
344#define UNKNOWN -1
345
84714f86
AM
346static inline const char *
347section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
348{
349 return filedata->string_table + hdr->sh_name;
350}
b9e920ec 351
84714f86
AM
352static inline bool
353section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
354{
355 return (hdr != NULL
356 && filedata->string_table != NULL
357 && hdr->sh_name < filedata->string_table_length);
358}
b9e920ec 359
84714f86
AM
360static inline const char *
361section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
362{
363 if (hdr == NULL)
364 return _("<none>");
365 if (filedata->string_table == NULL)
366 return _("<no-strings>");
367 if (hdr->sh_name >= filedata->string_table_length)
368 return _("<corrupt>");
369 return section_name (filedata, hdr);
370}
252b5132 371
ee42cf8c 372#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 373
84714f86
AM
374static inline bool
375valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
376{
377 return strtab != NULL && offset < strtab_size;
378}
379
380static inline bool
381valid_dynamic_name (const Filedata *filedata, uint64_t offset)
382{
383 return valid_symbol_name (filedata->dynamic_strings,
384 filedata->dynamic_strings_length, offset);
385}
386
d79b3d50
NC
387/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
388 already been called and verified that the string exists. */
84714f86
AM
389static inline const char *
390get_dynamic_name (const Filedata *filedata, size_t offset)
391{
392 return filedata->dynamic_strings + offset;
393}
18bd398b 394
61865e30
NC
395#define REMOVE_ARCH_BITS(ADDR) \
396 do \
397 { \
dda8d76d 398 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
399 (ADDR) &= ~1; \
400 } \
401 while (0)
f16a9783
MS
402
403/* Get the correct GNU hash section name. */
978c4450
AM
404#define GNU_HASH_SECTION_NAME(filedata) \
405 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 406\f
66cfc0fd
AM
407/* Print a BFD_VMA to an internal buffer, for use in error messages.
408 BFD_FMA_FMT can't be used in translated strings. */
409
410static const char *
411bfd_vmatoa (char *fmtch, bfd_vma value)
412{
413 /* bfd_vmatoa is used more then once in a printf call for output.
414 Cycle through an array of buffers. */
415 static int buf_pos = 0;
416 static struct bfd_vmatoa_buf
417 {
418 char place[64];
419 } buf[4];
420 char *ret;
421 char fmt[32];
422
423 ret = buf[buf_pos++].place;
424 buf_pos %= ARRAY_SIZE (buf);
425
426 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
427 snprintf (ret, sizeof (buf[0].place), fmt, value);
428 return ret;
429}
430
dda8d76d
NC
431/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
432 OFFSET + the offset of the current archive member, if we are examining an
433 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
434 allocate a buffer using malloc and fill that. In either case return the
435 pointer to the start of the retrieved data or NULL if something went wrong.
436 If something does go wrong and REASON is not NULL then emit an error
437 message using REASON as part of the context. */
59245841 438
c256ffe7 439static void *
dda8d76d
NC
440get_data (void * var,
441 Filedata * filedata,
442 unsigned long offset,
443 bfd_size_type size,
444 bfd_size_type nmemb,
445 const char * reason)
a6e9f9df 446{
2cf0635d 447 void * mvar;
57028622 448 bfd_size_type amt = size * nmemb;
a6e9f9df 449
c256ffe7 450 if (size == 0 || nmemb == 0)
a6e9f9df
AM
451 return NULL;
452
57028622
NC
453 /* If the size_t type is smaller than the bfd_size_type, eg because
454 you are building a 32-bit tool on a 64-bit host, then make sure
455 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
456 if ((size_t) size != size
457 || (size_t) nmemb != nmemb
458 || (size_t) amt != amt)
57028622
NC
459 {
460 if (reason)
66cfc0fd
AM
461 error (_("Size truncation prevents reading %s"
462 " elements of size %s for %s\n"),
463 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
464 return NULL;
465 }
466
467 /* Check for size overflow. */
7c1c1904 468 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
469 {
470 if (reason)
66cfc0fd
AM
471 error (_("Size overflow prevents reading %s"
472 " elements of size %s for %s\n"),
473 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
474 return NULL;
475 }
476
c22b42ce 477 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 478 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
479 if (filedata->archive_file_offset > filedata->file_size
480 || offset > filedata->file_size - filedata->archive_file_offset
481 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 482 {
049b0c3a 483 if (reason)
66cfc0fd
AM
484 error (_("Reading %s bytes extends past end of file for %s\n"),
485 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
486 return NULL;
487 }
488
978c4450
AM
489 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
490 SEEK_SET))
071436c6
NC
491 {
492 if (reason)
c9c1d674 493 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 494 filedata->archive_file_offset + offset, reason);
071436c6
NC
495 return NULL;
496 }
497
a6e9f9df
AM
498 mvar = var;
499 if (mvar == NULL)
500 {
7c1c1904
AM
501 /* + 1 so that we can '\0' terminate invalid string table sections. */
502 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
503
504 if (mvar == NULL)
505 {
049b0c3a 506 if (reason)
66cfc0fd
AM
507 error (_("Out of memory allocating %s bytes for %s\n"),
508 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
509 return NULL;
510 }
c256ffe7 511
c9c1d674 512 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
513 }
514
dda8d76d 515 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 516 {
049b0c3a 517 if (reason)
66cfc0fd
AM
518 error (_("Unable to read in %s bytes of %s\n"),
519 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
520 if (mvar != var)
521 free (mvar);
522 return NULL;
523 }
524
525 return mvar;
526}
527
32ec8896
NC
528/* Print a VMA value in the MODE specified.
529 Returns the number of characters displayed. */
cb8f3167 530
32ec8896 531static unsigned int
14a91970 532print_vma (bfd_vma vma, print_mode mode)
66543521 533{
32ec8896 534 unsigned int nc = 0;
66543521 535
14a91970 536 switch (mode)
66543521 537 {
14a91970
AM
538 case FULL_HEX:
539 nc = printf ("0x");
1a0670f3 540 /* Fall through. */
14a91970 541 case LONG_HEX:
f7a99963 542#ifdef BFD64
14a91970 543 if (is_32bit_elf)
437c2fb7 544 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 545#endif
14a91970
AM
546 printf_vma (vma);
547 return nc + 16;
b19aac67 548
14a91970
AM
549 case DEC_5:
550 if (vma <= 99999)
551 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 552 /* Fall through. */
14a91970
AM
553 case PREFIX_HEX:
554 nc = printf ("0x");
1a0670f3 555 /* Fall through. */
14a91970
AM
556 case HEX:
557 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 558
047c3dbf
NL
559 case PREFIX_HEX_5:
560 nc = printf ("0x");
561 /* Fall through. */
562 case HEX_5:
563 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
564
14a91970
AM
565 case DEC:
566 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 567
14a91970
AM
568 case UNSIGNED:
569 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 570
047c3dbf
NL
571 case UNSIGNED_5:
572 return printf ("%5" BFD_VMA_FMT "u", vma);
573
574 case OCTAL:
575 return printf ("%" BFD_VMA_FMT "o", vma);
576
577 case OCTAL_5:
578 return printf ("%5" BFD_VMA_FMT "o", vma);
579
32ec8896
NC
580 default:
581 /* FIXME: Report unrecognised mode ? */
582 return 0;
f7a99963 583 }
f7a99963
NC
584}
585
047c3dbf 586
7bfd842d 587/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 588 multibye characters (assuming the host environment supports them).
31104126 589
7bfd842d
NC
590 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
591
0942c7ab
NC
592 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
593 abs(WIDTH) - 5 characters followed by "[...]".
594
7bfd842d
NC
595 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
596 padding as necessary.
171191ba
NC
597
598 Returns the number of emitted characters. */
599
600static unsigned int
0942c7ab 601print_symbol (signed int width, const char * symbol)
31104126 602{
015dc7e1
AM
603 bool extra_padding = false;
604 bool do_dots = false;
32ec8896 605 signed int num_printed = 0;
3bfcb652 606#ifdef HAVE_MBSTATE_T
7bfd842d 607 mbstate_t state;
3bfcb652 608#endif
32ec8896 609 unsigned int width_remaining;
79bc120c 610 const void * alloced_symbol = NULL;
961c521f 611
7bfd842d 612 if (width < 0)
961c521f 613 {
88305e1b 614 /* Keep the width positive. This helps the code below. */
961c521f 615 width = - width;
015dc7e1 616 extra_padding = true;
0b4362b0 617 }
56d8f8a9
NC
618 else if (width == 0)
619 return 0;
961c521f 620
7bfd842d
NC
621 if (do_wide)
622 /* Set the remaining width to a very large value.
623 This simplifies the code below. */
624 width_remaining = INT_MAX;
625 else
0942c7ab
NC
626 {
627 width_remaining = width;
628 if (! do_not_show_symbol_truncation
629 && (int) strlen (symbol) > width)
630 {
631 width_remaining -= 5;
632 if ((int) width_remaining < 0)
633 width_remaining = 0;
015dc7e1 634 do_dots = true;
0942c7ab
NC
635 }
636 }
cb8f3167 637
3bfcb652 638#ifdef HAVE_MBSTATE_T
7bfd842d
NC
639 /* Initialise the multibyte conversion state. */
640 memset (& state, 0, sizeof (state));
3bfcb652 641#endif
961c521f 642
79bc120c
NC
643 if (do_demangle && *symbol)
644 {
645 const char * res = cplus_demangle (symbol, demangle_flags);
646
647 if (res != NULL)
648 alloced_symbol = symbol = res;
649 }
650
7bfd842d
NC
651 while (width_remaining)
652 {
653 size_t n;
7bfd842d 654 const char c = *symbol++;
961c521f 655
7bfd842d 656 if (c == 0)
961c521f
NC
657 break;
658
7bfd842d
NC
659 /* Do not print control characters directly as they can affect terminal
660 settings. Such characters usually appear in the names generated
661 by the assembler for local labels. */
662 if (ISCNTRL (c))
961c521f 663 {
7bfd842d 664 if (width_remaining < 2)
961c521f
NC
665 break;
666
7bfd842d
NC
667 printf ("^%c", c + 0x40);
668 width_remaining -= 2;
171191ba 669 num_printed += 2;
961c521f 670 }
7bfd842d
NC
671 else if (ISPRINT (c))
672 {
673 putchar (c);
674 width_remaining --;
675 num_printed ++;
676 }
961c521f
NC
677 else
678 {
3bfcb652
NC
679#ifdef HAVE_MBSTATE_T
680 wchar_t w;
681#endif
7bfd842d
NC
682 /* Let printf do the hard work of displaying multibyte characters. */
683 printf ("%.1s", symbol - 1);
684 width_remaining --;
685 num_printed ++;
686
3bfcb652 687#ifdef HAVE_MBSTATE_T
7bfd842d
NC
688 /* Try to find out how many bytes made up the character that was
689 just printed. Advance the symbol pointer past the bytes that
690 were displayed. */
691 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
692#else
693 n = 1;
694#endif
7bfd842d
NC
695 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
696 symbol += (n - 1);
961c521f 697 }
961c521f 698 }
171191ba 699
0942c7ab
NC
700 if (do_dots)
701 num_printed += printf ("[...]");
702
7bfd842d 703 if (extra_padding && num_printed < width)
171191ba
NC
704 {
705 /* Fill in the remaining spaces. */
7bfd842d
NC
706 printf ("%-*s", width - num_printed, " ");
707 num_printed = width;
171191ba
NC
708 }
709
79bc120c 710 free ((void *) alloced_symbol);
171191ba 711 return num_printed;
31104126
NC
712}
713
1449284b 714/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
715 the given section's name. Like print_symbol, except that it does not try
716 to print multibyte characters, it just interprets them as hex values. */
717
718static const char *
dda8d76d 719printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 720{
ca0e11aa 721#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 722 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 723 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
724 char * buf = sec_name_buf;
725 char c;
726 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
727
728 while ((c = * name ++) != 0)
729 {
730 if (ISCNTRL (c))
731 {
732 if (remaining < 2)
733 break;
948f632f 734
74e1a04b
NC
735 * buf ++ = '^';
736 * buf ++ = c + 0x40;
737 remaining -= 2;
738 }
739 else if (ISPRINT (c))
740 {
741 * buf ++ = c;
742 remaining -= 1;
743 }
744 else
745 {
746 static char hex[17] = "0123456789ABCDEF";
747
748 if (remaining < 4)
749 break;
750 * buf ++ = '<';
751 * buf ++ = hex[(c & 0xf0) >> 4];
752 * buf ++ = hex[c & 0x0f];
753 * buf ++ = '>';
754 remaining -= 4;
755 }
756
757 if (remaining == 0)
758 break;
759 }
760
761 * buf = 0;
762 return sec_name_buf;
763}
764
765static const char *
dda8d76d 766printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 767{
dda8d76d 768 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
769 return _("<corrupt>");
770
dda8d76d 771 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
772}
773
89fac5e3
RS
774/* Return a pointer to section NAME, or NULL if no such section exists. */
775
776static Elf_Internal_Shdr *
dda8d76d 777find_section (Filedata * filedata, const char * name)
89fac5e3
RS
778{
779 unsigned int i;
780
68807c3c
NC
781 if (filedata->section_headers == NULL)
782 return NULL;
dda8d76d
NC
783
784 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
785 if (section_name_valid (filedata, filedata->section_headers + i)
786 && streq (section_name (filedata, filedata->section_headers + i),
787 name))
dda8d76d 788 return filedata->section_headers + i;
89fac5e3
RS
789
790 return NULL;
791}
792
0b6ae522
DJ
793/* Return a pointer to a section containing ADDR, or NULL if no such
794 section exists. */
795
796static Elf_Internal_Shdr *
dda8d76d 797find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
798{
799 unsigned int i;
800
68807c3c
NC
801 if (filedata->section_headers == NULL)
802 return NULL;
803
dda8d76d 804 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 805 {
dda8d76d
NC
806 Elf_Internal_Shdr *sec = filedata->section_headers + i;
807
0b6ae522
DJ
808 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
809 return sec;
810 }
811
812 return NULL;
813}
814
071436c6 815static Elf_Internal_Shdr *
dda8d76d 816find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
817{
818 unsigned int i;
819
68807c3c
NC
820 if (filedata->section_headers == NULL)
821 return NULL;
822
dda8d76d 823 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 824 {
dda8d76d
NC
825 Elf_Internal_Shdr *sec = filedata->section_headers + i;
826
071436c6
NC
827 if (sec->sh_type == type)
828 return sec;
829 }
830
831 return NULL;
832}
833
657d0d47
CC
834/* Return a pointer to section NAME, or NULL if no such section exists,
835 restricted to the list of sections given in SET. */
836
837static Elf_Internal_Shdr *
dda8d76d 838find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
839{
840 unsigned int i;
841
68807c3c
NC
842 if (filedata->section_headers == NULL)
843 return NULL;
844
657d0d47
CC
845 if (set != NULL)
846 {
847 while ((i = *set++) > 0)
b814a36d
NC
848 {
849 /* See PR 21156 for a reproducer. */
dda8d76d 850 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
851 continue; /* FIXME: Should we issue an error message ? */
852
84714f86
AM
853 if (section_name_valid (filedata, filedata->section_headers + i)
854 && streq (section_name (filedata, filedata->section_headers + i),
855 name))
dda8d76d 856 return filedata->section_headers + i;
b814a36d 857 }
657d0d47
CC
858 }
859
dda8d76d 860 return find_section (filedata, name);
657d0d47
CC
861}
862
32ec8896 863/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
864 This OS has so many departures from the ELF standard that we test it at
865 many places. */
866
015dc7e1 867static inline bool
dda8d76d 868is_ia64_vms (Filedata * filedata)
28f997cf 869{
dda8d76d
NC
870 return filedata->file_header.e_machine == EM_IA_64
871 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
872}
873
bcedfee6 874/* Guess the relocation size commonly used by the specific machines. */
252b5132 875
015dc7e1 876static bool
2dc4cec1 877guess_is_rela (unsigned int e_machine)
252b5132 878{
9c19a809 879 switch (e_machine)
252b5132
RH
880 {
881 /* Targets that use REL relocations. */
252b5132 882 case EM_386:
22abe556 883 case EM_IAMCU:
f954747f 884 case EM_960:
e9f53129 885 case EM_ARM:
2b0337b0 886 case EM_D10V:
252b5132 887 case EM_CYGNUS_D10V:
e9f53129 888 case EM_DLX:
252b5132 889 case EM_MIPS:
4fe85591 890 case EM_MIPS_RS3_LE:
e9f53129 891 case EM_CYGNUS_M32R:
1c0d3aa6 892 case EM_SCORE:
f6c1a2d5 893 case EM_XGATE:
fe944acf 894 case EM_NFP:
aca4efc7 895 case EM_BPF:
015dc7e1 896 return false;
103f02d3 897
252b5132
RH
898 /* Targets that use RELA relocations. */
899 case EM_68K:
f954747f 900 case EM_860:
a06ea964 901 case EM_AARCH64:
cfb8c092 902 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
903 case EM_ALPHA:
904 case EM_ALTERA_NIOS2:
886a2506
NC
905 case EM_ARC:
906 case EM_ARC_COMPACT:
907 case EM_ARC_COMPACT2:
e9f53129
AM
908 case EM_AVR:
909 case EM_AVR_OLD:
910 case EM_BLACKFIN:
60bca95a 911 case EM_CR16:
e9f53129
AM
912 case EM_CRIS:
913 case EM_CRX:
b8891f8d 914 case EM_CSKY:
2b0337b0 915 case EM_D30V:
252b5132 916 case EM_CYGNUS_D30V:
2b0337b0 917 case EM_FR30:
3f8107ab 918 case EM_FT32:
252b5132 919 case EM_CYGNUS_FR30:
5c70f934 920 case EM_CYGNUS_FRV:
e9f53129
AM
921 case EM_H8S:
922 case EM_H8_300:
923 case EM_H8_300H:
800eeca4 924 case EM_IA_64:
1e4cf259
NC
925 case EM_IP2K:
926 case EM_IP2K_OLD:
3b36097d 927 case EM_IQ2000:
84e94c90 928 case EM_LATTICEMICO32:
ff7eeb89 929 case EM_M32C_OLD:
49f58d10 930 case EM_M32C:
e9f53129
AM
931 case EM_M32R:
932 case EM_MCORE:
15ab5209 933 case EM_CYGNUS_MEP:
a3c62988 934 case EM_METAG:
e9f53129
AM
935 case EM_MMIX:
936 case EM_MN10200:
937 case EM_CYGNUS_MN10200:
938 case EM_MN10300:
939 case EM_CYGNUS_MN10300:
5506d11a 940 case EM_MOXIE:
e9f53129
AM
941 case EM_MSP430:
942 case EM_MSP430_OLD:
d031aafb 943 case EM_MT:
35c08157 944 case EM_NDS32:
64fd6348 945 case EM_NIOS32:
73589c9d 946 case EM_OR1K:
e9f53129
AM
947 case EM_PPC64:
948 case EM_PPC:
2b100bb5 949 case EM_TI_PRU:
e23eba97 950 case EM_RISCV:
99c513f6 951 case EM_RL78:
c7927a3c 952 case EM_RX:
e9f53129
AM
953 case EM_S390:
954 case EM_S390_OLD:
955 case EM_SH:
956 case EM_SPARC:
957 case EM_SPARC32PLUS:
958 case EM_SPARCV9:
959 case EM_SPU:
40b36596 960 case EM_TI_C6000:
aa137e4d
NC
961 case EM_TILEGX:
962 case EM_TILEPRO:
708e2187 963 case EM_V800:
e9f53129
AM
964 case EM_V850:
965 case EM_CYGNUS_V850:
966 case EM_VAX:
619ed720 967 case EM_VISIUM:
e9f53129 968 case EM_X86_64:
8a9036a4 969 case EM_L1OM:
7a9068fe 970 case EM_K1OM:
e9f53129
AM
971 case EM_XSTORMY16:
972 case EM_XTENSA:
973 case EM_XTENSA_OLD:
7ba29e2a
NC
974 case EM_MICROBLAZE:
975 case EM_MICROBLAZE_OLD:
f96bd6c2 976 case EM_WEBASSEMBLY:
015dc7e1 977 return true;
103f02d3 978
e9f53129
AM
979 case EM_68HC05:
980 case EM_68HC08:
981 case EM_68HC11:
982 case EM_68HC16:
983 case EM_FX66:
984 case EM_ME16:
d1133906 985 case EM_MMA:
d1133906
NC
986 case EM_NCPU:
987 case EM_NDR1:
e9f53129 988 case EM_PCP:
d1133906 989 case EM_ST100:
e9f53129 990 case EM_ST19:
d1133906 991 case EM_ST7:
e9f53129
AM
992 case EM_ST9PLUS:
993 case EM_STARCORE:
d1133906 994 case EM_SVX:
e9f53129 995 case EM_TINYJ:
9c19a809
NC
996 default:
997 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 998 return false;
9c19a809
NC
999 }
1000}
252b5132 1001
dda8d76d 1002/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1003 Returns TRUE upon success, FALSE otherwise. If successful then a
1004 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1005 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1006 responsibility to free the allocated buffer. */
1007
015dc7e1 1008static bool
dda8d76d
NC
1009slurp_rela_relocs (Filedata * filedata,
1010 unsigned long rel_offset,
1011 unsigned long rel_size,
1012 Elf_Internal_Rela ** relasp,
1013 unsigned long * nrelasp)
9c19a809 1014{
2cf0635d 1015 Elf_Internal_Rela * relas;
8b73c356 1016 size_t nrelas;
4d6ed7c8 1017 unsigned int i;
252b5132 1018
4d6ed7c8
NC
1019 if (is_32bit_elf)
1020 {
2cf0635d 1021 Elf32_External_Rela * erelas;
103f02d3 1022
dda8d76d 1023 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1024 rel_size, _("32-bit relocation data"));
a6e9f9df 1025 if (!erelas)
015dc7e1 1026 return false;
252b5132 1027
4d6ed7c8 1028 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1029
3f5e193b
NC
1030 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1031 sizeof (Elf_Internal_Rela));
103f02d3 1032
4d6ed7c8
NC
1033 if (relas == NULL)
1034 {
c256ffe7 1035 free (erelas);
591a748a 1036 error (_("out of memory parsing relocs\n"));
015dc7e1 1037 return false;
4d6ed7c8 1038 }
103f02d3 1039
4d6ed7c8
NC
1040 for (i = 0; i < nrelas; i++)
1041 {
1042 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1043 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1044 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1045 }
103f02d3 1046
4d6ed7c8
NC
1047 free (erelas);
1048 }
1049 else
1050 {
2cf0635d 1051 Elf64_External_Rela * erelas;
103f02d3 1052
dda8d76d 1053 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1054 rel_size, _("64-bit relocation data"));
a6e9f9df 1055 if (!erelas)
015dc7e1 1056 return false;
4d6ed7c8
NC
1057
1058 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1059
3f5e193b
NC
1060 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1061 sizeof (Elf_Internal_Rela));
103f02d3 1062
4d6ed7c8
NC
1063 if (relas == NULL)
1064 {
c256ffe7 1065 free (erelas);
591a748a 1066 error (_("out of memory parsing relocs\n"));
015dc7e1 1067 return false;
9c19a809 1068 }
4d6ed7c8
NC
1069
1070 for (i = 0; i < nrelas; i++)
9c19a809 1071 {
66543521
AM
1072 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1073 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1074 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1075
1076 /* The #ifdef BFD64 below is to prevent a compile time
1077 warning. We know that if we do not have a 64 bit data
1078 type that we will never execute this code anyway. */
1079#ifdef BFD64
dda8d76d
NC
1080 if (filedata->file_header.e_machine == EM_MIPS
1081 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1082 {
1083 /* In little-endian objects, r_info isn't really a
1084 64-bit little-endian value: it has a 32-bit
1085 little-endian symbol index followed by four
1086 individual byte fields. Reorder INFO
1087 accordingly. */
91d6fa6a
NC
1088 bfd_vma inf = relas[i].r_info;
1089 inf = (((inf & 0xffffffff) << 32)
1090 | ((inf >> 56) & 0xff)
1091 | ((inf >> 40) & 0xff00)
1092 | ((inf >> 24) & 0xff0000)
1093 | ((inf >> 8) & 0xff000000));
1094 relas[i].r_info = inf;
861fb55a
DJ
1095 }
1096#endif /* BFD64 */
4d6ed7c8 1097 }
103f02d3 1098
4d6ed7c8
NC
1099 free (erelas);
1100 }
32ec8896 1101
4d6ed7c8
NC
1102 *relasp = relas;
1103 *nrelasp = nrelas;
015dc7e1 1104 return true;
4d6ed7c8 1105}
103f02d3 1106
dda8d76d 1107/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1108 Returns TRUE upon success, FALSE otherwise. If successful then a
1109 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1110 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1111 responsibility to free the allocated buffer. */
1112
015dc7e1 1113static bool
dda8d76d
NC
1114slurp_rel_relocs (Filedata * filedata,
1115 unsigned long rel_offset,
1116 unsigned long rel_size,
1117 Elf_Internal_Rela ** relsp,
1118 unsigned long * nrelsp)
4d6ed7c8 1119{
2cf0635d 1120 Elf_Internal_Rela * rels;
8b73c356 1121 size_t nrels;
4d6ed7c8 1122 unsigned int i;
103f02d3 1123
4d6ed7c8
NC
1124 if (is_32bit_elf)
1125 {
2cf0635d 1126 Elf32_External_Rel * erels;
103f02d3 1127
dda8d76d 1128 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1129 rel_size, _("32-bit relocation data"));
a6e9f9df 1130 if (!erels)
015dc7e1 1131 return false;
103f02d3 1132
4d6ed7c8 1133 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1134
3f5e193b 1135 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1136
4d6ed7c8
NC
1137 if (rels == NULL)
1138 {
c256ffe7 1139 free (erels);
591a748a 1140 error (_("out of memory parsing relocs\n"));
015dc7e1 1141 return false;
4d6ed7c8
NC
1142 }
1143
1144 for (i = 0; i < nrels; i++)
1145 {
1146 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1147 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1148 rels[i].r_addend = 0;
9ea033b2 1149 }
4d6ed7c8
NC
1150
1151 free (erels);
9c19a809
NC
1152 }
1153 else
1154 {
2cf0635d 1155 Elf64_External_Rel * erels;
9ea033b2 1156
dda8d76d 1157 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1158 rel_size, _("64-bit relocation data"));
a6e9f9df 1159 if (!erels)
015dc7e1 1160 return false;
103f02d3 1161
4d6ed7c8 1162 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1163
3f5e193b 1164 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1165
4d6ed7c8 1166 if (rels == NULL)
9c19a809 1167 {
c256ffe7 1168 free (erels);
591a748a 1169 error (_("out of memory parsing relocs\n"));
015dc7e1 1170 return false;
4d6ed7c8 1171 }
103f02d3 1172
4d6ed7c8
NC
1173 for (i = 0; i < nrels; i++)
1174 {
66543521
AM
1175 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1176 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1177 rels[i].r_addend = 0;
861fb55a
DJ
1178
1179 /* The #ifdef BFD64 below is to prevent a compile time
1180 warning. We know that if we do not have a 64 bit data
1181 type that we will never execute this code anyway. */
1182#ifdef BFD64
dda8d76d
NC
1183 if (filedata->file_header.e_machine == EM_MIPS
1184 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1185 {
1186 /* In little-endian objects, r_info isn't really a
1187 64-bit little-endian value: it has a 32-bit
1188 little-endian symbol index followed by four
1189 individual byte fields. Reorder INFO
1190 accordingly. */
91d6fa6a
NC
1191 bfd_vma inf = rels[i].r_info;
1192 inf = (((inf & 0xffffffff) << 32)
1193 | ((inf >> 56) & 0xff)
1194 | ((inf >> 40) & 0xff00)
1195 | ((inf >> 24) & 0xff0000)
1196 | ((inf >> 8) & 0xff000000));
1197 rels[i].r_info = inf;
861fb55a
DJ
1198 }
1199#endif /* BFD64 */
4d6ed7c8 1200 }
103f02d3 1201
4d6ed7c8
NC
1202 free (erels);
1203 }
32ec8896 1204
4d6ed7c8
NC
1205 *relsp = rels;
1206 *nrelsp = nrels;
015dc7e1 1207 return true;
4d6ed7c8 1208}
103f02d3 1209
aca88567
NC
1210/* Returns the reloc type extracted from the reloc info field. */
1211
1212static unsigned int
dda8d76d 1213get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1214{
1215 if (is_32bit_elf)
1216 return ELF32_R_TYPE (reloc_info);
1217
dda8d76d 1218 switch (filedata->file_header.e_machine)
aca88567
NC
1219 {
1220 case EM_MIPS:
1221 /* Note: We assume that reloc_info has already been adjusted for us. */
1222 return ELF64_MIPS_R_TYPE (reloc_info);
1223
1224 case EM_SPARCV9:
1225 return ELF64_R_TYPE_ID (reloc_info);
1226
1227 default:
1228 return ELF64_R_TYPE (reloc_info);
1229 }
1230}
1231
1232/* Return the symbol index extracted from the reloc info field. */
1233
1234static bfd_vma
1235get_reloc_symindex (bfd_vma reloc_info)
1236{
1237 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1238}
1239
015dc7e1 1240static inline bool
dda8d76d 1241uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1242{
1243 return
dda8d76d 1244 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1245 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1246 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1247 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1248 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1249}
1250
d3ba0551
AM
1251/* Display the contents of the relocation data found at the specified
1252 offset. */
ee42cf8c 1253
015dc7e1 1254static bool
dda8d76d
NC
1255dump_relocations (Filedata * filedata,
1256 unsigned long rel_offset,
1257 unsigned long rel_size,
1258 Elf_Internal_Sym * symtab,
1259 unsigned long nsyms,
1260 char * strtab,
1261 unsigned long strtablen,
1262 int is_rela,
015dc7e1 1263 bool is_dynsym)
4d6ed7c8 1264{
32ec8896 1265 unsigned long i;
2cf0635d 1266 Elf_Internal_Rela * rels;
015dc7e1 1267 bool res = true;
103f02d3 1268
4d6ed7c8 1269 if (is_rela == UNKNOWN)
dda8d76d 1270 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1271
4d6ed7c8
NC
1272 if (is_rela)
1273 {
dda8d76d 1274 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1275 return false;
4d6ed7c8
NC
1276 }
1277 else
1278 {
dda8d76d 1279 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1280 return false;
252b5132
RH
1281 }
1282
410f7a12
L
1283 if (is_32bit_elf)
1284 {
1285 if (is_rela)
2c71103e
NC
1286 {
1287 if (do_wide)
1288 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1289 else
1290 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1291 }
410f7a12 1292 else
2c71103e
NC
1293 {
1294 if (do_wide)
1295 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1296 else
1297 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1298 }
410f7a12 1299 }
252b5132 1300 else
410f7a12
L
1301 {
1302 if (is_rela)
2c71103e
NC
1303 {
1304 if (do_wide)
8beeaeb7 1305 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1306 else
1307 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1308 }
410f7a12 1309 else
2c71103e
NC
1310 {
1311 if (do_wide)
8beeaeb7 1312 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1313 else
1314 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1315 }
410f7a12 1316 }
252b5132
RH
1317
1318 for (i = 0; i < rel_size; i++)
1319 {
2cf0635d 1320 const char * rtype;
b34976b6 1321 bfd_vma offset;
91d6fa6a 1322 bfd_vma inf;
b34976b6
AM
1323 bfd_vma symtab_index;
1324 bfd_vma type;
103f02d3 1325
b34976b6 1326 offset = rels[i].r_offset;
91d6fa6a 1327 inf = rels[i].r_info;
103f02d3 1328
dda8d76d 1329 type = get_reloc_type (filedata, inf);
91d6fa6a 1330 symtab_index = get_reloc_symindex (inf);
252b5132 1331
410f7a12
L
1332 if (is_32bit_elf)
1333 {
39dbeff8
AM
1334 printf ("%8.8lx %8.8lx ",
1335 (unsigned long) offset & 0xffffffff,
91d6fa6a 1336 (unsigned long) inf & 0xffffffff);
410f7a12
L
1337 }
1338 else
1339 {
39dbeff8 1340 printf (do_wide
d1ce973e
AM
1341 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1342 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1343 offset, inf);
410f7a12 1344 }
103f02d3 1345
dda8d76d 1346 switch (filedata->file_header.e_machine)
252b5132
RH
1347 {
1348 default:
1349 rtype = NULL;
1350 break;
1351
a06ea964
NC
1352 case EM_AARCH64:
1353 rtype = elf_aarch64_reloc_type (type);
1354 break;
1355
2b0337b0 1356 case EM_M32R:
252b5132 1357 case EM_CYGNUS_M32R:
9ea033b2 1358 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1359 break;
1360
1361 case EM_386:
22abe556 1362 case EM_IAMCU:
9ea033b2 1363 rtype = elf_i386_reloc_type (type);
252b5132
RH
1364 break;
1365
ba2685cc
AM
1366 case EM_68HC11:
1367 case EM_68HC12:
1368 rtype = elf_m68hc11_reloc_type (type);
1369 break;
75751cd9 1370
7b4ae824
JD
1371 case EM_S12Z:
1372 rtype = elf_s12z_reloc_type (type);
1373 break;
1374
252b5132 1375 case EM_68K:
9ea033b2 1376 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1377 break;
1378
f954747f
AM
1379 case EM_960:
1380 rtype = elf_i960_reloc_type (type);
1381 break;
1382
adde6300 1383 case EM_AVR:
2b0337b0 1384 case EM_AVR_OLD:
adde6300
AM
1385 rtype = elf_avr_reloc_type (type);
1386 break;
1387
9ea033b2
NC
1388 case EM_OLD_SPARCV9:
1389 case EM_SPARC32PLUS:
1390 case EM_SPARCV9:
252b5132 1391 case EM_SPARC:
9ea033b2 1392 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1393 break;
1394
e9f53129
AM
1395 case EM_SPU:
1396 rtype = elf_spu_reloc_type (type);
1397 break;
1398
708e2187
NC
1399 case EM_V800:
1400 rtype = v800_reloc_type (type);
1401 break;
2b0337b0 1402 case EM_V850:
252b5132 1403 case EM_CYGNUS_V850:
9ea033b2 1404 rtype = v850_reloc_type (type);
252b5132
RH
1405 break;
1406
2b0337b0 1407 case EM_D10V:
252b5132 1408 case EM_CYGNUS_D10V:
9ea033b2 1409 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1410 break;
1411
2b0337b0 1412 case EM_D30V:
252b5132 1413 case EM_CYGNUS_D30V:
9ea033b2 1414 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1415 break;
1416
d172d4ba
NC
1417 case EM_DLX:
1418 rtype = elf_dlx_reloc_type (type);
1419 break;
1420
252b5132 1421 case EM_SH:
9ea033b2 1422 rtype = elf_sh_reloc_type (type);
252b5132
RH
1423 break;
1424
2b0337b0 1425 case EM_MN10300:
252b5132 1426 case EM_CYGNUS_MN10300:
9ea033b2 1427 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1428 break;
1429
2b0337b0 1430 case EM_MN10200:
252b5132 1431 case EM_CYGNUS_MN10200:
9ea033b2 1432 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1433 break;
1434
2b0337b0 1435 case EM_FR30:
252b5132 1436 case EM_CYGNUS_FR30:
9ea033b2 1437 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1438 break;
1439
ba2685cc
AM
1440 case EM_CYGNUS_FRV:
1441 rtype = elf_frv_reloc_type (type);
1442 break;
5c70f934 1443
b8891f8d
AJ
1444 case EM_CSKY:
1445 rtype = elf_csky_reloc_type (type);
1446 break;
1447
3f8107ab
AM
1448 case EM_FT32:
1449 rtype = elf_ft32_reloc_type (type);
1450 break;
1451
252b5132 1452 case EM_MCORE:
9ea033b2 1453 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1454 break;
1455
3c3bdf30
NC
1456 case EM_MMIX:
1457 rtype = elf_mmix_reloc_type (type);
1458 break;
1459
5506d11a
AM
1460 case EM_MOXIE:
1461 rtype = elf_moxie_reloc_type (type);
1462 break;
1463
2469cfa2 1464 case EM_MSP430:
dda8d76d 1465 if (uses_msp430x_relocs (filedata))
13761a11
NC
1466 {
1467 rtype = elf_msp430x_reloc_type (type);
1468 break;
1469 }
1a0670f3 1470 /* Fall through. */
2469cfa2
NC
1471 case EM_MSP430_OLD:
1472 rtype = elf_msp430_reloc_type (type);
1473 break;
1474
35c08157
KLC
1475 case EM_NDS32:
1476 rtype = elf_nds32_reloc_type (type);
1477 break;
1478
252b5132 1479 case EM_PPC:
9ea033b2 1480 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1481 break;
1482
c833c019
AM
1483 case EM_PPC64:
1484 rtype = elf_ppc64_reloc_type (type);
1485 break;
1486
252b5132 1487 case EM_MIPS:
4fe85591 1488 case EM_MIPS_RS3_LE:
9ea033b2 1489 rtype = elf_mips_reloc_type (type);
252b5132
RH
1490 break;
1491
e23eba97
NC
1492 case EM_RISCV:
1493 rtype = elf_riscv_reloc_type (type);
1494 break;
1495
252b5132 1496 case EM_ALPHA:
9ea033b2 1497 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1498 break;
1499
1500 case EM_ARM:
9ea033b2 1501 rtype = elf_arm_reloc_type (type);
252b5132
RH
1502 break;
1503
584da044 1504 case EM_ARC:
886a2506
NC
1505 case EM_ARC_COMPACT:
1506 case EM_ARC_COMPACT2:
9ea033b2 1507 rtype = elf_arc_reloc_type (type);
252b5132
RH
1508 break;
1509
1510 case EM_PARISC:
69e617ca 1511 rtype = elf_hppa_reloc_type (type);
252b5132 1512 break;
7d466069 1513
b8720f9d
JL
1514 case EM_H8_300:
1515 case EM_H8_300H:
1516 case EM_H8S:
1517 rtype = elf_h8_reloc_type (type);
1518 break;
1519
73589c9d
CS
1520 case EM_OR1K:
1521 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1522 break;
1523
7d466069 1524 case EM_PJ:
2b0337b0 1525 case EM_PJ_OLD:
7d466069
ILT
1526 rtype = elf_pj_reloc_type (type);
1527 break;
800eeca4
JW
1528 case EM_IA_64:
1529 rtype = elf_ia64_reloc_type (type);
1530 break;
1b61cf92
HPN
1531
1532 case EM_CRIS:
1533 rtype = elf_cris_reloc_type (type);
1534 break;
535c37ff 1535
f954747f
AM
1536 case EM_860:
1537 rtype = elf_i860_reloc_type (type);
1538 break;
1539
bcedfee6 1540 case EM_X86_64:
8a9036a4 1541 case EM_L1OM:
7a9068fe 1542 case EM_K1OM:
bcedfee6
NC
1543 rtype = elf_x86_64_reloc_type (type);
1544 break;
a85d7ed0 1545
f954747f
AM
1546 case EM_S370:
1547 rtype = i370_reloc_type (type);
1548 break;
1549
53c7db4b
KH
1550 case EM_S390_OLD:
1551 case EM_S390:
1552 rtype = elf_s390_reloc_type (type);
1553 break;
93fbbb04 1554
1c0d3aa6
NC
1555 case EM_SCORE:
1556 rtype = elf_score_reloc_type (type);
1557 break;
1558
93fbbb04
GK
1559 case EM_XSTORMY16:
1560 rtype = elf_xstormy16_reloc_type (type);
1561 break;
179d3252 1562
1fe1f39c
NC
1563 case EM_CRX:
1564 rtype = elf_crx_reloc_type (type);
1565 break;
1566
179d3252
JT
1567 case EM_VAX:
1568 rtype = elf_vax_reloc_type (type);
1569 break;
1e4cf259 1570
619ed720
EB
1571 case EM_VISIUM:
1572 rtype = elf_visium_reloc_type (type);
1573 break;
1574
aca4efc7
JM
1575 case EM_BPF:
1576 rtype = elf_bpf_reloc_type (type);
1577 break;
1578
cfb8c092
NC
1579 case EM_ADAPTEVA_EPIPHANY:
1580 rtype = elf_epiphany_reloc_type (type);
1581 break;
1582
1e4cf259
NC
1583 case EM_IP2K:
1584 case EM_IP2K_OLD:
1585 rtype = elf_ip2k_reloc_type (type);
1586 break;
3b36097d
SC
1587
1588 case EM_IQ2000:
1589 rtype = elf_iq2000_reloc_type (type);
1590 break;
88da6820
NC
1591
1592 case EM_XTENSA_OLD:
1593 case EM_XTENSA:
1594 rtype = elf_xtensa_reloc_type (type);
1595 break;
a34e3ecb 1596
84e94c90
NC
1597 case EM_LATTICEMICO32:
1598 rtype = elf_lm32_reloc_type (type);
1599 break;
1600
ff7eeb89 1601 case EM_M32C_OLD:
49f58d10
JB
1602 case EM_M32C:
1603 rtype = elf_m32c_reloc_type (type);
1604 break;
1605
d031aafb
NS
1606 case EM_MT:
1607 rtype = elf_mt_reloc_type (type);
a34e3ecb 1608 break;
1d65ded4
CM
1609
1610 case EM_BLACKFIN:
1611 rtype = elf_bfin_reloc_type (type);
1612 break;
15ab5209
DB
1613
1614 case EM_CYGNUS_MEP:
1615 rtype = elf_mep_reloc_type (type);
1616 break;
60bca95a
NC
1617
1618 case EM_CR16:
1619 rtype = elf_cr16_reloc_type (type);
1620 break;
dd24e3da 1621
7ba29e2a
NC
1622 case EM_MICROBLAZE:
1623 case EM_MICROBLAZE_OLD:
1624 rtype = elf_microblaze_reloc_type (type);
1625 break;
c7927a3c 1626
99c513f6
DD
1627 case EM_RL78:
1628 rtype = elf_rl78_reloc_type (type);
1629 break;
1630
c7927a3c
NC
1631 case EM_RX:
1632 rtype = elf_rx_reloc_type (type);
1633 break;
c29aca4a 1634
a3c62988
NC
1635 case EM_METAG:
1636 rtype = elf_metag_reloc_type (type);
1637 break;
1638
c29aca4a
NC
1639 case EM_XC16X:
1640 case EM_C166:
1641 rtype = elf_xc16x_reloc_type (type);
1642 break;
40b36596
JM
1643
1644 case EM_TI_C6000:
1645 rtype = elf_tic6x_reloc_type (type);
1646 break;
aa137e4d
NC
1647
1648 case EM_TILEGX:
1649 rtype = elf_tilegx_reloc_type (type);
1650 break;
1651
1652 case EM_TILEPRO:
1653 rtype = elf_tilepro_reloc_type (type);
1654 break;
f6c1a2d5 1655
f96bd6c2
PC
1656 case EM_WEBASSEMBLY:
1657 rtype = elf_wasm32_reloc_type (type);
1658 break;
1659
f6c1a2d5
NC
1660 case EM_XGATE:
1661 rtype = elf_xgate_reloc_type (type);
1662 break;
36591ba1
SL
1663
1664 case EM_ALTERA_NIOS2:
1665 rtype = elf_nios2_reloc_type (type);
1666 break;
2b100bb5
DD
1667
1668 case EM_TI_PRU:
1669 rtype = elf_pru_reloc_type (type);
1670 break;
fe944acf
FT
1671
1672 case EM_NFP:
1673 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1674 rtype = elf_nfp3200_reloc_type (type);
1675 else
1676 rtype = elf_nfp_reloc_type (type);
1677 break;
6655dba2
SB
1678
1679 case EM_Z80:
1680 rtype = elf_z80_reloc_type (type);
1681 break;
e9a0721f 1682
1683 case EM_LOONGARCH:
1684 rtype = elf_loongarch_reloc_type (type);
1685 break;
1686
252b5132
RH
1687 }
1688
1689 if (rtype == NULL)
39dbeff8 1690 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1691 else
5c144731 1692 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1693
dda8d76d 1694 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1695 && rtype != NULL
7ace3541
RH
1696 && streq (rtype, "R_ALPHA_LITUSE")
1697 && is_rela)
1698 {
1699 switch (rels[i].r_addend)
1700 {
1701 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1702 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1703 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1704 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1705 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1706 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1707 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1708 default: rtype = NULL;
1709 }
32ec8896 1710
7ace3541
RH
1711 if (rtype)
1712 printf (" (%s)", rtype);
1713 else
1714 {
1715 putchar (' ');
1716 printf (_("<unknown addend: %lx>"),
1717 (unsigned long) rels[i].r_addend);
015dc7e1 1718 res = false;
7ace3541
RH
1719 }
1720 }
1721 else if (symtab_index)
252b5132 1722 {
af3fc3bc 1723 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1724 {
27a45f42
AS
1725 error (_(" bad symbol index: %08lx in reloc\n"),
1726 (unsigned long) symtab_index);
015dc7e1 1727 res = false;
32ec8896 1728 }
af3fc3bc 1729 else
19936277 1730 {
2cf0635d 1731 Elf_Internal_Sym * psym;
bb4d2ac2
L
1732 const char * version_string;
1733 enum versioned_symbol_info sym_info;
1734 unsigned short vna_other;
19936277 1735
af3fc3bc 1736 psym = symtab + symtab_index;
103f02d3 1737
bb4d2ac2 1738 version_string
dda8d76d 1739 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1740 strtab, strtablen,
1741 symtab_index,
1742 psym,
1743 &sym_info,
1744 &vna_other);
1745
af3fc3bc 1746 printf (" ");
171191ba 1747
d8045f23
NC
1748 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1749 {
1750 const char * name;
1751 unsigned int len;
1752 unsigned int width = is_32bit_elf ? 8 : 14;
1753
1754 /* Relocations against GNU_IFUNC symbols do not use the value
1755 of the symbol as the address to relocate against. Instead
1756 they invoke the function named by the symbol and use its
1757 result as the address for relocation.
1758
1759 To indicate this to the user, do not display the value of
1760 the symbol in the "Symbols's Value" field. Instead show
1761 its name followed by () as a hint that the symbol is
1762 invoked. */
1763
1764 if (strtab == NULL
1765 || psym->st_name == 0
1766 || psym->st_name >= strtablen)
1767 name = "??";
1768 else
1769 name = strtab + psym->st_name;
1770
1771 len = print_symbol (width, name);
bb4d2ac2
L
1772 if (version_string)
1773 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1774 version_string);
d8045f23
NC
1775 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1776 }
1777 else
1778 {
1779 print_vma (psym->st_value, LONG_HEX);
171191ba 1780
d8045f23
NC
1781 printf (is_32bit_elf ? " " : " ");
1782 }
103f02d3 1783
af3fc3bc 1784 if (psym->st_name == 0)
f1ef08cb 1785 {
2cf0635d 1786 const char * sec_name = "<null>";
f1ef08cb
AM
1787 char name_buf[40];
1788
1789 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1790 {
dda8d76d 1791 if (psym->st_shndx < filedata->file_header.e_shnum)
84714f86
AM
1792 sec_name = section_name_print (filedata,
1793 filedata->section_headers
b9e920ec 1794 + psym->st_shndx);
f1ef08cb
AM
1795 else if (psym->st_shndx == SHN_ABS)
1796 sec_name = "ABS";
1797 else if (psym->st_shndx == SHN_COMMON)
1798 sec_name = "COMMON";
dda8d76d 1799 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1800 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1801 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1802 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1803 sec_name = "SCOMMON";
dda8d76d 1804 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1805 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1806 sec_name = "SUNDEF";
dda8d76d
NC
1807 else if ((filedata->file_header.e_machine == EM_X86_64
1808 || filedata->file_header.e_machine == EM_L1OM
1809 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1810 && psym->st_shndx == SHN_X86_64_LCOMMON)
1811 sec_name = "LARGE_COMMON";
dda8d76d
NC
1812 else if (filedata->file_header.e_machine == EM_IA_64
1813 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1814 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1815 sec_name = "ANSI_COM";
dda8d76d 1816 else if (is_ia64_vms (filedata)
148b93f2
NC
1817 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1818 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1819 else
1820 {
1821 sprintf (name_buf, "<section 0x%x>",
1822 (unsigned int) psym->st_shndx);
1823 sec_name = name_buf;
1824 }
1825 }
1826 print_symbol (22, sec_name);
1827 }
af3fc3bc 1828 else if (strtab == NULL)
d79b3d50 1829 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1830 else if (psym->st_name >= strtablen)
32ec8896 1831 {
27a45f42
AS
1832 error (_("<corrupt string table index: %3ld>\n"),
1833 psym->st_name);
015dc7e1 1834 res = false;
32ec8896 1835 }
af3fc3bc 1836 else
bb4d2ac2
L
1837 {
1838 print_symbol (22, strtab + psym->st_name);
1839 if (version_string)
1840 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1841 version_string);
1842 }
103f02d3 1843
af3fc3bc 1844 if (is_rela)
171191ba 1845 {
7360e63f 1846 bfd_vma off = rels[i].r_addend;
171191ba 1847
7360e63f 1848 if ((bfd_signed_vma) off < 0)
598aaa76 1849 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1850 else
598aaa76 1851 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1852 }
19936277 1853 }
252b5132 1854 }
1b228002 1855 else if (is_rela)
f7a99963 1856 {
7360e63f 1857 bfd_vma off = rels[i].r_addend;
e04d7088
L
1858
1859 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1860 if ((bfd_signed_vma) off < 0)
e04d7088
L
1861 printf ("-%" BFD_VMA_FMT "x", - off);
1862 else
1863 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1864 }
252b5132 1865
dda8d76d 1866 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1867 && rtype != NULL
1868 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1869 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1870
252b5132 1871 putchar ('\n');
2c71103e 1872
aca88567 1873#ifdef BFD64
dda8d76d 1874 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1875 {
91d6fa6a
NC
1876 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1877 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1878 const char * rtype2 = elf_mips_reloc_type (type2);
1879 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1880
2c71103e
NC
1881 printf (" Type2: ");
1882
1883 if (rtype2 == NULL)
39dbeff8
AM
1884 printf (_("unrecognized: %-7lx"),
1885 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1886 else
1887 printf ("%-17.17s", rtype2);
1888
18bd398b 1889 printf ("\n Type3: ");
2c71103e
NC
1890
1891 if (rtype3 == NULL)
39dbeff8
AM
1892 printf (_("unrecognized: %-7lx"),
1893 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1894 else
1895 printf ("%-17.17s", rtype3);
1896
53c7db4b 1897 putchar ('\n');
2c71103e 1898 }
aca88567 1899#endif /* BFD64 */
252b5132
RH
1900 }
1901
c8286bd1 1902 free (rels);
32ec8896
NC
1903
1904 return res;
252b5132
RH
1905}
1906
37c18eed
SD
1907static const char *
1908get_aarch64_dynamic_type (unsigned long type)
1909{
1910 switch (type)
1911 {
1912 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1913 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1914 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1915 default:
1916 return NULL;
1917 }
1918}
1919
252b5132 1920static const char *
d3ba0551 1921get_mips_dynamic_type (unsigned long type)
252b5132
RH
1922{
1923 switch (type)
1924 {
1925 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1926 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1927 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1928 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1929 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1930 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1931 case DT_MIPS_MSYM: return "MIPS_MSYM";
1932 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1933 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1934 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1935 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1936 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1937 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1938 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1939 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1940 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1941 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1942 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1943 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1944 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1945 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1946 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1947 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1948 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1949 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1950 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1951 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1952 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1953 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1954 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1955 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1956 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1957 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1958 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1959 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1960 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1961 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1962 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1963 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1964 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1965 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1966 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1967 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1968 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1969 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1970 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1971 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1972 default:
1973 return NULL;
1974 }
1975}
1976
9a097730 1977static const char *
d3ba0551 1978get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1979{
1980 switch (type)
1981 {
1982 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1983 default:
1984 return NULL;
1985 }
103f02d3
UD
1986}
1987
7490d522
AM
1988static const char *
1989get_ppc_dynamic_type (unsigned long type)
1990{
1991 switch (type)
1992 {
a7f2871e 1993 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1994 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1995 default:
1996 return NULL;
1997 }
1998}
1999
f1cb7e17 2000static const char *
d3ba0551 2001get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2002{
2003 switch (type)
2004 {
a7f2871e
AM
2005 case DT_PPC64_GLINK: return "PPC64_GLINK";
2006 case DT_PPC64_OPD: return "PPC64_OPD";
2007 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2008 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2009 default:
2010 return NULL;
2011 }
2012}
2013
103f02d3 2014static const char *
d3ba0551 2015get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2016{
2017 switch (type)
2018 {
2019 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2020 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2021 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2022 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2023 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2024 case DT_HP_PREINIT: return "HP_PREINIT";
2025 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2026 case DT_HP_NEEDED: return "HP_NEEDED";
2027 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2028 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2029 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2030 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2031 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2032 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2033 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2034 case DT_HP_FILTERED: return "HP_FILTERED";
2035 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2036 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2037 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2038 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2039 case DT_PLT: return "PLT";
2040 case DT_PLT_SIZE: return "PLT_SIZE";
2041 case DT_DLT: return "DLT";
2042 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2043 default:
2044 return NULL;
2045 }
2046}
9a097730 2047
ecc51f48 2048static const char *
d3ba0551 2049get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2050{
2051 switch (type)
2052 {
148b93f2
NC
2053 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2054 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2055 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2056 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2057 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2058 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2059 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2060 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2061 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2062 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2063 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2064 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2065 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2066 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2067 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2068 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2069 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2070 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2071 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2072 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2073 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2074 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2075 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2076 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2077 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2078 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2079 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2080 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2081 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2082 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2083 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2084 default:
2085 return NULL;
2086 }
2087}
2088
fd85a6a1
NC
2089static const char *
2090get_solaris_section_type (unsigned long type)
2091{
2092 switch (type)
2093 {
2094 case 0x6fffffee: return "SUNW_ancillary";
2095 case 0x6fffffef: return "SUNW_capchain";
2096 case 0x6ffffff0: return "SUNW_capinfo";
2097 case 0x6ffffff1: return "SUNW_symsort";
2098 case 0x6ffffff2: return "SUNW_tlssort";
2099 case 0x6ffffff3: return "SUNW_LDYNSYM";
2100 case 0x6ffffff4: return "SUNW_dof";
2101 case 0x6ffffff5: return "SUNW_cap";
2102 case 0x6ffffff6: return "SUNW_SIGNATURE";
2103 case 0x6ffffff7: return "SUNW_ANNOTATE";
2104 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2105 case 0x6ffffff9: return "SUNW_DEBUG";
2106 case 0x6ffffffa: return "SUNW_move";
2107 case 0x6ffffffb: return "SUNW_COMDAT";
2108 case 0x6ffffffc: return "SUNW_syminfo";
2109 case 0x6ffffffd: return "SUNW_verdef";
2110 case 0x6ffffffe: return "SUNW_verneed";
2111 case 0x6fffffff: return "SUNW_versym";
2112 case 0x70000000: return "SPARC_GOTDATA";
2113 default: return NULL;
2114 }
2115}
2116
fabcb361
RH
2117static const char *
2118get_alpha_dynamic_type (unsigned long type)
2119{
2120 switch (type)
2121 {
2122 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2123 default: return NULL;
fabcb361
RH
2124 }
2125}
2126
1c0d3aa6
NC
2127static const char *
2128get_score_dynamic_type (unsigned long type)
2129{
2130 switch (type)
2131 {
2132 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2133 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2134 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2135 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2136 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2137 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2138 default: return NULL;
1c0d3aa6
NC
2139 }
2140}
2141
40b36596
JM
2142static const char *
2143get_tic6x_dynamic_type (unsigned long type)
2144{
2145 switch (type)
2146 {
2147 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2148 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2149 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2150 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2151 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2152 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2153 default: return NULL;
40b36596
JM
2154 }
2155}
1c0d3aa6 2156
36591ba1
SL
2157static const char *
2158get_nios2_dynamic_type (unsigned long type)
2159{
2160 switch (type)
2161 {
2162 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2163 default: return NULL;
36591ba1
SL
2164 }
2165}
2166
fd85a6a1
NC
2167static const char *
2168get_solaris_dynamic_type (unsigned long type)
2169{
2170 switch (type)
2171 {
2172 case 0x6000000d: return "SUNW_AUXILIARY";
2173 case 0x6000000e: return "SUNW_RTLDINF";
2174 case 0x6000000f: return "SUNW_FILTER";
2175 case 0x60000010: return "SUNW_CAP";
2176 case 0x60000011: return "SUNW_SYMTAB";
2177 case 0x60000012: return "SUNW_SYMSZ";
2178 case 0x60000013: return "SUNW_SORTENT";
2179 case 0x60000014: return "SUNW_SYMSORT";
2180 case 0x60000015: return "SUNW_SYMSORTSZ";
2181 case 0x60000016: return "SUNW_TLSSORT";
2182 case 0x60000017: return "SUNW_TLSSORTSZ";
2183 case 0x60000018: return "SUNW_CAPINFO";
2184 case 0x60000019: return "SUNW_STRPAD";
2185 case 0x6000001a: return "SUNW_CAPCHAIN";
2186 case 0x6000001b: return "SUNW_LDMACH";
2187 case 0x6000001d: return "SUNW_CAPCHAINENT";
2188 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2189 case 0x60000021: return "SUNW_PARENT";
2190 case 0x60000023: return "SUNW_ASLR";
2191 case 0x60000025: return "SUNW_RELAX";
2192 case 0x60000029: return "SUNW_NXHEAP";
2193 case 0x6000002b: return "SUNW_NXSTACK";
2194
2195 case 0x70000001: return "SPARC_REGISTER";
2196 case 0x7ffffffd: return "AUXILIARY";
2197 case 0x7ffffffe: return "USED";
2198 case 0x7fffffff: return "FILTER";
2199
15f205b1 2200 default: return NULL;
fd85a6a1
NC
2201 }
2202}
2203
252b5132 2204static const char *
dda8d76d 2205get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2206{
e9e44622 2207 static char buff[64];
252b5132
RH
2208
2209 switch (type)
2210 {
2211 case DT_NULL: return "NULL";
2212 case DT_NEEDED: return "NEEDED";
2213 case DT_PLTRELSZ: return "PLTRELSZ";
2214 case DT_PLTGOT: return "PLTGOT";
2215 case DT_HASH: return "HASH";
2216 case DT_STRTAB: return "STRTAB";
2217 case DT_SYMTAB: return "SYMTAB";
2218 case DT_RELA: return "RELA";
2219 case DT_RELASZ: return "RELASZ";
2220 case DT_RELAENT: return "RELAENT";
2221 case DT_STRSZ: return "STRSZ";
2222 case DT_SYMENT: return "SYMENT";
2223 case DT_INIT: return "INIT";
2224 case DT_FINI: return "FINI";
2225 case DT_SONAME: return "SONAME";
2226 case DT_RPATH: return "RPATH";
2227 case DT_SYMBOLIC: return "SYMBOLIC";
2228 case DT_REL: return "REL";
2229 case DT_RELSZ: return "RELSZ";
2230 case DT_RELENT: return "RELENT";
2231 case DT_PLTREL: return "PLTREL";
2232 case DT_DEBUG: return "DEBUG";
2233 case DT_TEXTREL: return "TEXTREL";
2234 case DT_JMPREL: return "JMPREL";
2235 case DT_BIND_NOW: return "BIND_NOW";
2236 case DT_INIT_ARRAY: return "INIT_ARRAY";
2237 case DT_FINI_ARRAY: return "FINI_ARRAY";
2238 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2239 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2240 case DT_RUNPATH: return "RUNPATH";
2241 case DT_FLAGS: return "FLAGS";
2d0e6f43 2242
d1133906
NC
2243 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2244 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2245 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2246
05107a46 2247 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2248 case DT_PLTPADSZ: return "PLTPADSZ";
2249 case DT_MOVEENT: return "MOVEENT";
2250 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2251 case DT_FEATURE: return "FEATURE";
252b5132
RH
2252 case DT_POSFLAG_1: return "POSFLAG_1";
2253 case DT_SYMINSZ: return "SYMINSZ";
2254 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2255
252b5132 2256 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2257 case DT_CONFIG: return "CONFIG";
2258 case DT_DEPAUDIT: return "DEPAUDIT";
2259 case DT_AUDIT: return "AUDIT";
2260 case DT_PLTPAD: return "PLTPAD";
2261 case DT_MOVETAB: return "MOVETAB";
252b5132 2262 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2263
252b5132 2264 case DT_VERSYM: return "VERSYM";
103f02d3 2265
67a4f2b7
AO
2266 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2267 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2268 case DT_RELACOUNT: return "RELACOUNT";
2269 case DT_RELCOUNT: return "RELCOUNT";
2270 case DT_FLAGS_1: return "FLAGS_1";
2271 case DT_VERDEF: return "VERDEF";
2272 case DT_VERDEFNUM: return "VERDEFNUM";
2273 case DT_VERNEED: return "VERNEED";
2274 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2275
019148e4 2276 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2277 case DT_USED: return "USED";
2278 case DT_FILTER: return "FILTER";
103f02d3 2279
047b2264
JJ
2280 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2281 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2282 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2283 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2284 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2285 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2286 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2287
252b5132
RH
2288 default:
2289 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2290 {
2cf0635d 2291 const char * result;
103f02d3 2292
dda8d76d 2293 switch (filedata->file_header.e_machine)
252b5132 2294 {
37c18eed
SD
2295 case EM_AARCH64:
2296 result = get_aarch64_dynamic_type (type);
2297 break;
252b5132 2298 case EM_MIPS:
4fe85591 2299 case EM_MIPS_RS3_LE:
252b5132
RH
2300 result = get_mips_dynamic_type (type);
2301 break;
9a097730
RH
2302 case EM_SPARCV9:
2303 result = get_sparc64_dynamic_type (type);
2304 break;
7490d522
AM
2305 case EM_PPC:
2306 result = get_ppc_dynamic_type (type);
2307 break;
f1cb7e17
AM
2308 case EM_PPC64:
2309 result = get_ppc64_dynamic_type (type);
2310 break;
ecc51f48
NC
2311 case EM_IA_64:
2312 result = get_ia64_dynamic_type (type);
2313 break;
fabcb361
RH
2314 case EM_ALPHA:
2315 result = get_alpha_dynamic_type (type);
2316 break;
1c0d3aa6
NC
2317 case EM_SCORE:
2318 result = get_score_dynamic_type (type);
2319 break;
40b36596
JM
2320 case EM_TI_C6000:
2321 result = get_tic6x_dynamic_type (type);
2322 break;
36591ba1
SL
2323 case EM_ALTERA_NIOS2:
2324 result = get_nios2_dynamic_type (type);
2325 break;
252b5132 2326 default:
dda8d76d 2327 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2328 result = get_solaris_dynamic_type (type);
2329 else
2330 result = NULL;
252b5132
RH
2331 break;
2332 }
2333
2334 if (result != NULL)
2335 return result;
2336
e9e44622 2337 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2338 }
eec8f817 2339 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2340 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2341 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2342 {
2cf0635d 2343 const char * result;
103f02d3 2344
dda8d76d 2345 switch (filedata->file_header.e_machine)
103f02d3
UD
2346 {
2347 case EM_PARISC:
2348 result = get_parisc_dynamic_type (type);
2349 break;
148b93f2
NC
2350 case EM_IA_64:
2351 result = get_ia64_dynamic_type (type);
2352 break;
103f02d3 2353 default:
dda8d76d 2354 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2355 result = get_solaris_dynamic_type (type);
2356 else
2357 result = NULL;
103f02d3
UD
2358 break;
2359 }
2360
2361 if (result != NULL)
2362 return result;
2363
e9e44622
JJ
2364 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2365 type);
103f02d3 2366 }
252b5132 2367 else
e9e44622 2368 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2369
252b5132
RH
2370 return buff;
2371 }
2372}
2373
93df3340
AM
2374static bool get_program_headers (Filedata *);
2375static bool get_dynamic_section (Filedata *);
2376
2377static void
2378locate_dynamic_section (Filedata *filedata)
2379{
2380 unsigned long dynamic_addr = 0;
2381 bfd_size_type dynamic_size = 0;
2382
2383 if (filedata->file_header.e_phnum != 0
2384 && get_program_headers (filedata))
2385 {
2386 Elf_Internal_Phdr *segment;
2387 unsigned int i;
2388
2389 for (i = 0, segment = filedata->program_headers;
2390 i < filedata->file_header.e_phnum;
2391 i++, segment++)
2392 {
2393 if (segment->p_type == PT_DYNAMIC)
2394 {
2395 dynamic_addr = segment->p_offset;
2396 dynamic_size = segment->p_filesz;
2397
2398 if (filedata->section_headers != NULL)
2399 {
2400 Elf_Internal_Shdr *sec;
2401
2402 sec = find_section (filedata, ".dynamic");
2403 if (sec != NULL)
2404 {
2405 if (sec->sh_size == 0
2406 || sec->sh_type == SHT_NOBITS)
2407 {
2408 dynamic_addr = 0;
2409 dynamic_size = 0;
2410 }
2411 else
2412 {
2413 dynamic_addr = sec->sh_offset;
2414 dynamic_size = sec->sh_size;
2415 }
2416 }
2417 }
2418
2419 if (dynamic_addr > filedata->file_size
2420 || (dynamic_size > filedata->file_size - dynamic_addr))
2421 {
2422 dynamic_addr = 0;
2423 dynamic_size = 0;
2424 }
2425 break;
2426 }
2427 }
2428 }
2429 filedata->dynamic_addr = dynamic_addr;
2430 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2431}
2432
2433static bool
2434is_pie (Filedata *filedata)
2435{
2436 Elf_Internal_Dyn *entry;
2437
2438 if (filedata->dynamic_size == 0)
2439 locate_dynamic_section (filedata);
2440 if (filedata->dynamic_size <= 1)
2441 return false;
2442
2443 if (!get_dynamic_section (filedata))
2444 return false;
2445
2446 for (entry = filedata->dynamic_section;
2447 entry < filedata->dynamic_section + filedata->dynamic_nent;
2448 entry++)
2449 {
2450 if (entry->d_tag == DT_FLAGS_1)
2451 {
2452 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2453 return true;
2454 break;
2455 }
2456 }
2457 return false;
2458}
2459
252b5132 2460static char *
93df3340 2461get_file_type (Filedata *filedata)
252b5132 2462{
93df3340 2463 unsigned e_type = filedata->file_header.e_type;
89246a0e 2464 static char buff[64];
252b5132
RH
2465
2466 switch (e_type)
2467 {
32ec8896
NC
2468 case ET_NONE: return _("NONE (None)");
2469 case ET_REL: return _("REL (Relocatable file)");
2470 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2471 case ET_DYN:
2472 if (is_pie (filedata))
2473 return _("DYN (Position-Independent Executable file)");
2474 else
2475 return _("DYN (Shared object file)");
32ec8896 2476 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2477
2478 default:
2479 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2480 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2481 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2482 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2483 else
e9e44622 2484 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2485 return buff;
2486 }
2487}
2488
2489static char *
d3ba0551 2490get_machine_name (unsigned e_machine)
252b5132 2491{
b34976b6 2492 static char buff[64]; /* XXX */
252b5132
RH
2493
2494 switch (e_machine)
2495 {
55e22ca8
NC
2496 /* Please keep this switch table sorted by increasing EM_ value. */
2497 /* 0 */
c45021f2
NC
2498 case EM_NONE: return _("None");
2499 case EM_M32: return "WE32100";
2500 case EM_SPARC: return "Sparc";
2501 case EM_386: return "Intel 80386";
2502 case EM_68K: return "MC68000";
2503 case EM_88K: return "MC88000";
22abe556 2504 case EM_IAMCU: return "Intel MCU";
fb70ec17 2505 case EM_860: return "Intel 80860";
c45021f2
NC
2506 case EM_MIPS: return "MIPS R3000";
2507 case EM_S370: return "IBM System/370";
55e22ca8 2508 /* 10 */
7036c0e1 2509 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2510 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2511 case EM_PARISC: return "HPPA";
55e22ca8 2512 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2513 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2514 case EM_960: return "Intel 80960";
c45021f2 2515 case EM_PPC: return "PowerPC";
55e22ca8 2516 /* 20 */
285d1771 2517 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2518 case EM_S390_OLD:
2519 case EM_S390: return "IBM S/390";
2520 case EM_SPU: return "SPU";
2521 /* 30 */
2522 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2523 case EM_FR20: return "Fujitsu FR20";
2524 case EM_RH32: return "TRW RH32";
b34976b6 2525 case EM_MCORE: return "MCORE";
55e22ca8 2526 /* 40 */
7036c0e1
AJ
2527 case EM_ARM: return "ARM";
2528 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2529 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2530 case EM_SPARCV9: return "Sparc v9";
2531 case EM_TRICORE: return "Siemens Tricore";
584da044 2532 case EM_ARC: return "ARC";
c2dcd04e
NC
2533 case EM_H8_300: return "Renesas H8/300";
2534 case EM_H8_300H: return "Renesas H8/300H";
2535 case EM_H8S: return "Renesas H8S";
2536 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2537 /* 50 */
30800947 2538 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2539 case EM_MIPS_X: return "Stanford MIPS-X";
2540 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2541 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2542 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2543 case EM_PCP: return "Siemens PCP";
2544 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2545 case EM_NDR1: return "Denso NDR1 microprocesspr";
2546 case EM_STARCORE: return "Motorola Star*Core processor";
2547 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2548 /* 60 */
7036c0e1
AJ
2549 case EM_ST100: return "STMicroelectronics ST100 processor";
2550 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2551 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2552 case EM_PDSP: return "Sony DSP processor";
2553 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2554 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2555 case EM_FX66: return "Siemens FX66 microcontroller";
2556 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2557 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2558 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2559 /* 70 */
7036c0e1
AJ
2560 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2561 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2562 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2563 case EM_SVX: return "Silicon Graphics SVx";
2564 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2565 case EM_VAX: return "Digital VAX";
1b61cf92 2566 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2567 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2568 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2569 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2570 /* 80 */
b34976b6 2571 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2572 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2573 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2574 case EM_AVR_OLD:
2575 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2576 case EM_CYGNUS_FR30:
2577 case EM_FR30: return "Fujitsu FR30";
2578 case EM_CYGNUS_D10V:
2579 case EM_D10V: return "d10v";
2580 case EM_CYGNUS_D30V:
2581 case EM_D30V: return "d30v";
2582 case EM_CYGNUS_V850:
2583 case EM_V850: return "Renesas V850";
2584 case EM_CYGNUS_M32R:
2585 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2586 case EM_CYGNUS_MN10300:
2587 case EM_MN10300: return "mn10300";
2588 /* 90 */
2589 case EM_CYGNUS_MN10200:
2590 case EM_MN10200: return "mn10200";
2591 case EM_PJ: return "picoJava";
73589c9d 2592 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2593 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2594 case EM_XTENSA_OLD:
2595 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2596 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2597 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2598 case EM_NS32K: return "National Semiconductor 32000 series";
2599 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2600 case EM_SNP1K: return "Trebia SNP 1000 processor";
2601 /* 100 */
9abca702 2602 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2603 case EM_IP2K_OLD:
2604 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2605 case EM_MAX: return "MAX Processor";
2606 case EM_CR: return "National Semiconductor CompactRISC";
2607 case EM_F2MC16: return "Fujitsu F2MC16";
2608 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2609 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2610 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2611 case EM_SEP: return "Sharp embedded microprocessor";
2612 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2613 /* 110 */
11636f9e
JM
2614 case EM_UNICORE: return "Unicore";
2615 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2616 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2617 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2618 case EM_CRX: return "National Semiconductor CRX microprocessor";
2619 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2620 case EM_C166:
d70c5fc7 2621 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2622 case EM_M16C: return "Renesas M16C series microprocessors";
2623 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2624 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2625 /* 120 */
2626 case EM_M32C: return "Renesas M32c";
2627 /* 130 */
11636f9e
JM
2628 case EM_TSK3000: return "Altium TSK3000 core";
2629 case EM_RS08: return "Freescale RS08 embedded processor";
2630 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2631 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2632 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2633 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2634 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2635 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2636 /* 140 */
11636f9e
JM
2637 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2638 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2639 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2640 case EM_TI_PRU: return "TI PRU I/O processor";
2641 /* 160 */
11636f9e
JM
2642 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2643 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2644 case EM_R32C: return "Renesas R32C series microprocessors";
2645 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2646 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2647 case EM_8051: return "Intel 8051 and variants";
2648 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2649 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2650 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2651 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2652 /* 170 */
11636f9e
JM
2653 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2654 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2655 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2656 case EM_RX: return "Renesas RX";
a3c62988 2657 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2658 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2659 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2660 case EM_CR16:
2661 case EM_MICROBLAZE:
2662 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2663 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2664 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2665 /* 180 */
2666 case EM_L1OM: return "Intel L1OM";
2667 case EM_K1OM: return "Intel K1OM";
2668 case EM_INTEL182: return "Intel (reserved)";
2669 case EM_AARCH64: return "AArch64";
2670 case EM_ARM184: return "ARM (reserved)";
2671 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2672 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2673 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2674 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2675 /* 190 */
11636f9e 2676 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2677 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2678 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2679 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2680 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2681 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2682 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2683 case EM_RL78: return "Renesas RL78";
6d913794 2684 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2685 case EM_78K0R: return "Renesas 78K0R";
2686 /* 200 */
6d913794 2687 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2688 case EM_BA1: return "Beyond BA1 CPU architecture";
2689 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2690 case EM_XCORE: return "XMOS xCORE processor family";
2691 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2692 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2693 /* 210 */
6d913794
NC
2694 case EM_KM32: return "KM211 KM32 32-bit processor";
2695 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2696 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2697 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2698 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2699 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2700 case EM_COGE: return "Cognitive Smart Memory Processor";
2701 case EM_COOL: return "Bluechip Systems CoolEngine";
2702 case EM_NORC: return "Nanoradio Optimized RISC";
2703 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2704 /* 220 */
15f205b1 2705 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2706 case EM_VISIUM: return "CDS VISIUMcore processor";
2707 case EM_FT32: return "FTDI Chip FT32";
2708 case EM_MOXIE: return "Moxie";
2709 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2710 /* 230 (all reserved) */
2711 /* 240 */
55e22ca8
NC
2712 case EM_RISCV: return "RISC-V";
2713 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2714 case EM_CEVA: return "CEVA Processor Architecture Family";
2715 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2716 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2717 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2718 case EM_IMG1: return "Imagination Technologies";
2719 /* 250 */
fe944acf 2720 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2721 case EM_VE: return "NEC Vector Engine";
2722 case EM_CSKY: return "C-SKY";
2723 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2724 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2725 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2726 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2727 case EM_65816: return "WDC 65816/65C816";
01a8c731 2728 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2729 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2730
2731 /* Large numbers... */
2732 case EM_MT: return "Morpho Techologies MT processor";
2733 case EM_ALPHA: return "Alpha";
2734 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2735 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2736 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2737 case EM_IQ2000: return "Vitesse IQ2000";
2738 case EM_M32C_OLD:
2739 case EM_NIOS32: return "Altera Nios";
2740 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2741 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2742 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2743 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2744
252b5132 2745 default:
35d9dd2f 2746 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2747 return buff;
2748 }
2749}
2750
a9522a21
AB
2751static void
2752decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2753{
2754 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2755 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2756 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2757 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2758 architectures.
2759
2760 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2761 but also sets a specific architecture type in the e_flags field.
2762
2763 However, when decoding the flags we don't worry if we see an
2764 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2765 ARCEM architecture type. */
2766
2767 switch (e_flags & EF_ARC_MACH_MSK)
2768 {
2769 /* We only expect these to occur for EM_ARC_COMPACT2. */
2770 case EF_ARC_CPU_ARCV2EM:
2771 strcat (buf, ", ARC EM");
2772 break;
2773 case EF_ARC_CPU_ARCV2HS:
2774 strcat (buf, ", ARC HS");
2775 break;
2776
2777 /* We only expect these to occur for EM_ARC_COMPACT. */
2778 case E_ARC_MACH_ARC600:
2779 strcat (buf, ", ARC600");
2780 break;
2781 case E_ARC_MACH_ARC601:
2782 strcat (buf, ", ARC601");
2783 break;
2784 case E_ARC_MACH_ARC700:
2785 strcat (buf, ", ARC700");
2786 break;
2787
2788 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2789 new ELF with new architecture being read by an old version of
2790 readelf, or (c) An ELF built with non-GNU compiler that does not
2791 set the architecture in the e_flags. */
2792 default:
2793 if (e_machine == EM_ARC_COMPACT)
2794 strcat (buf, ", Unknown ARCompact");
2795 else
2796 strcat (buf, ", Unknown ARC");
2797 break;
2798 }
2799
2800 switch (e_flags & EF_ARC_OSABI_MSK)
2801 {
2802 case E_ARC_OSABI_ORIG:
2803 strcat (buf, ", (ABI:legacy)");
2804 break;
2805 case E_ARC_OSABI_V2:
2806 strcat (buf, ", (ABI:v2)");
2807 break;
2808 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2809 case E_ARC_OSABI_V3:
2810 strcat (buf, ", v3 no-legacy-syscalls ABI");
2811 break;
53a346d8
CZ
2812 case E_ARC_OSABI_V4:
2813 strcat (buf, ", v4 ABI");
2814 break;
a9522a21
AB
2815 default:
2816 strcat (buf, ", unrecognised ARC OSABI flag");
2817 break;
2818 }
2819}
2820
f3485b74 2821static void
d3ba0551 2822decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2823{
2824 unsigned eabi;
015dc7e1 2825 bool unknown = false;
f3485b74
NC
2826
2827 eabi = EF_ARM_EABI_VERSION (e_flags);
2828 e_flags &= ~ EF_ARM_EABIMASK;
2829
2830 /* Handle "generic" ARM flags. */
2831 if (e_flags & EF_ARM_RELEXEC)
2832 {
2833 strcat (buf, ", relocatable executable");
2834 e_flags &= ~ EF_ARM_RELEXEC;
2835 }
76da6bbe 2836
18a20338
CL
2837 if (e_flags & EF_ARM_PIC)
2838 {
2839 strcat (buf, ", position independent");
2840 e_flags &= ~ EF_ARM_PIC;
2841 }
2842
f3485b74
NC
2843 /* Now handle EABI specific flags. */
2844 switch (eabi)
2845 {
2846 default:
2c71103e 2847 strcat (buf, ", <unrecognized EABI>");
f3485b74 2848 if (e_flags)
015dc7e1 2849 unknown = true;
f3485b74
NC
2850 break;
2851
2852 case EF_ARM_EABI_VER1:
a5bcd848 2853 strcat (buf, ", Version1 EABI");
f3485b74
NC
2854 while (e_flags)
2855 {
2856 unsigned flag;
76da6bbe 2857
f3485b74
NC
2858 /* Process flags one bit at a time. */
2859 flag = e_flags & - e_flags;
2860 e_flags &= ~ flag;
76da6bbe 2861
f3485b74
NC
2862 switch (flag)
2863 {
a5bcd848 2864 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2865 strcat (buf, ", sorted symbol tables");
2866 break;
76da6bbe 2867
f3485b74 2868 default:
015dc7e1 2869 unknown = true;
f3485b74
NC
2870 break;
2871 }
2872 }
2873 break;
76da6bbe 2874
a5bcd848
PB
2875 case EF_ARM_EABI_VER2:
2876 strcat (buf, ", Version2 EABI");
2877 while (e_flags)
2878 {
2879 unsigned flag;
2880
2881 /* Process flags one bit at a time. */
2882 flag = e_flags & - e_flags;
2883 e_flags &= ~ flag;
2884
2885 switch (flag)
2886 {
2887 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2888 strcat (buf, ", sorted symbol tables");
2889 break;
2890
2891 case EF_ARM_DYNSYMSUSESEGIDX:
2892 strcat (buf, ", dynamic symbols use segment index");
2893 break;
2894
2895 case EF_ARM_MAPSYMSFIRST:
2896 strcat (buf, ", mapping symbols precede others");
2897 break;
2898
2899 default:
015dc7e1 2900 unknown = true;
a5bcd848
PB
2901 break;
2902 }
2903 }
2904 break;
2905
d507cf36
PB
2906 case EF_ARM_EABI_VER3:
2907 strcat (buf, ", Version3 EABI");
8cb51566
PB
2908 break;
2909
2910 case EF_ARM_EABI_VER4:
2911 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2912 while (e_flags)
2913 {
2914 unsigned flag;
2915
2916 /* Process flags one bit at a time. */
2917 flag = e_flags & - e_flags;
2918 e_flags &= ~ flag;
2919
2920 switch (flag)
2921 {
2922 case EF_ARM_BE8:
2923 strcat (buf, ", BE8");
2924 break;
2925
2926 case EF_ARM_LE8:
2927 strcat (buf, ", LE8");
2928 break;
2929
2930 default:
015dc7e1 2931 unknown = true;
3bfcb652
NC
2932 break;
2933 }
3bfcb652
NC
2934 }
2935 break;
3a4a14e9
PB
2936
2937 case EF_ARM_EABI_VER5:
2938 strcat (buf, ", Version5 EABI");
d507cf36
PB
2939 while (e_flags)
2940 {
2941 unsigned flag;
2942
2943 /* Process flags one bit at a time. */
2944 flag = e_flags & - e_flags;
2945 e_flags &= ~ flag;
2946
2947 switch (flag)
2948 {
2949 case EF_ARM_BE8:
2950 strcat (buf, ", BE8");
2951 break;
2952
2953 case EF_ARM_LE8:
2954 strcat (buf, ", LE8");
2955 break;
2956
3bfcb652
NC
2957 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2958 strcat (buf, ", soft-float ABI");
2959 break;
2960
2961 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2962 strcat (buf, ", hard-float ABI");
2963 break;
2964
d507cf36 2965 default:
015dc7e1 2966 unknown = true;
d507cf36
PB
2967 break;
2968 }
2969 }
2970 break;
2971
f3485b74 2972 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2973 strcat (buf, ", GNU EABI");
f3485b74
NC
2974 while (e_flags)
2975 {
2976 unsigned flag;
76da6bbe 2977
f3485b74
NC
2978 /* Process flags one bit at a time. */
2979 flag = e_flags & - e_flags;
2980 e_flags &= ~ flag;
76da6bbe 2981
f3485b74
NC
2982 switch (flag)
2983 {
a5bcd848 2984 case EF_ARM_INTERWORK:
f3485b74
NC
2985 strcat (buf, ", interworking enabled");
2986 break;
76da6bbe 2987
a5bcd848 2988 case EF_ARM_APCS_26:
f3485b74
NC
2989 strcat (buf, ", uses APCS/26");
2990 break;
76da6bbe 2991
a5bcd848 2992 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2993 strcat (buf, ", uses APCS/float");
2994 break;
76da6bbe 2995
a5bcd848 2996 case EF_ARM_PIC:
f3485b74
NC
2997 strcat (buf, ", position independent");
2998 break;
76da6bbe 2999
a5bcd848 3000 case EF_ARM_ALIGN8:
f3485b74
NC
3001 strcat (buf, ", 8 bit structure alignment");
3002 break;
76da6bbe 3003
a5bcd848 3004 case EF_ARM_NEW_ABI:
f3485b74
NC
3005 strcat (buf, ", uses new ABI");
3006 break;
76da6bbe 3007
a5bcd848 3008 case EF_ARM_OLD_ABI:
f3485b74
NC
3009 strcat (buf, ", uses old ABI");
3010 break;
76da6bbe 3011
a5bcd848 3012 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3013 strcat (buf, ", software FP");
3014 break;
76da6bbe 3015
90e01f86
ILT
3016 case EF_ARM_VFP_FLOAT:
3017 strcat (buf, ", VFP");
3018 break;
3019
fde78edd
NC
3020 case EF_ARM_MAVERICK_FLOAT:
3021 strcat (buf, ", Maverick FP");
3022 break;
3023
f3485b74 3024 default:
015dc7e1 3025 unknown = true;
f3485b74
NC
3026 break;
3027 }
3028 }
3029 }
f3485b74
NC
3030
3031 if (unknown)
2b692964 3032 strcat (buf,_(", <unknown>"));
f3485b74
NC
3033}
3034
343433df
AB
3035static void
3036decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3037{
3038 --size; /* Leave space for null terminator. */
3039
3040 switch (e_flags & EF_AVR_MACH)
3041 {
3042 case E_AVR_MACH_AVR1:
3043 strncat (buf, ", avr:1", size);
3044 break;
3045 case E_AVR_MACH_AVR2:
3046 strncat (buf, ", avr:2", size);
3047 break;
3048 case E_AVR_MACH_AVR25:
3049 strncat (buf, ", avr:25", size);
3050 break;
3051 case E_AVR_MACH_AVR3:
3052 strncat (buf, ", avr:3", size);
3053 break;
3054 case E_AVR_MACH_AVR31:
3055 strncat (buf, ", avr:31", size);
3056 break;
3057 case E_AVR_MACH_AVR35:
3058 strncat (buf, ", avr:35", size);
3059 break;
3060 case E_AVR_MACH_AVR4:
3061 strncat (buf, ", avr:4", size);
3062 break;
3063 case E_AVR_MACH_AVR5:
3064 strncat (buf, ", avr:5", size);
3065 break;
3066 case E_AVR_MACH_AVR51:
3067 strncat (buf, ", avr:51", size);
3068 break;
3069 case E_AVR_MACH_AVR6:
3070 strncat (buf, ", avr:6", size);
3071 break;
3072 case E_AVR_MACH_AVRTINY:
3073 strncat (buf, ", avr:100", size);
3074 break;
3075 case E_AVR_MACH_XMEGA1:
3076 strncat (buf, ", avr:101", size);
3077 break;
3078 case E_AVR_MACH_XMEGA2:
3079 strncat (buf, ", avr:102", size);
3080 break;
3081 case E_AVR_MACH_XMEGA3:
3082 strncat (buf, ", avr:103", size);
3083 break;
3084 case E_AVR_MACH_XMEGA4:
3085 strncat (buf, ", avr:104", size);
3086 break;
3087 case E_AVR_MACH_XMEGA5:
3088 strncat (buf, ", avr:105", size);
3089 break;
3090 case E_AVR_MACH_XMEGA6:
3091 strncat (buf, ", avr:106", size);
3092 break;
3093 case E_AVR_MACH_XMEGA7:
3094 strncat (buf, ", avr:107", size);
3095 break;
3096 default:
3097 strncat (buf, ", avr:<unknown>", size);
3098 break;
3099 }
3100
3101 size -= strlen (buf);
3102 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3103 strncat (buf, ", link-relax", size);
3104}
3105
35c08157
KLC
3106static void
3107decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3108{
3109 unsigned abi;
3110 unsigned arch;
3111 unsigned config;
3112 unsigned version;
015dc7e1 3113 bool has_fpu = false;
32ec8896 3114 unsigned int r = 0;
35c08157
KLC
3115
3116 static const char *ABI_STRINGS[] =
3117 {
3118 "ABI v0", /* use r5 as return register; only used in N1213HC */
3119 "ABI v1", /* use r0 as return register */
3120 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3121 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3122 "AABI",
3123 "ABI2 FP+"
35c08157
KLC
3124 };
3125 static const char *VER_STRINGS[] =
3126 {
3127 "Andes ELF V1.3 or older",
3128 "Andes ELF V1.3.1",
3129 "Andes ELF V1.4"
3130 };
3131 static const char *ARCH_STRINGS[] =
3132 {
3133 "",
3134 "Andes Star v1.0",
3135 "Andes Star v2.0",
3136 "Andes Star v3.0",
3137 "Andes Star v3.0m"
3138 };
3139
3140 abi = EF_NDS_ABI & e_flags;
3141 arch = EF_NDS_ARCH & e_flags;
3142 config = EF_NDS_INST & e_flags;
3143 version = EF_NDS32_ELF_VERSION & e_flags;
3144
3145 memset (buf, 0, size);
3146
3147 switch (abi)
3148 {
3149 case E_NDS_ABI_V0:
3150 case E_NDS_ABI_V1:
3151 case E_NDS_ABI_V2:
3152 case E_NDS_ABI_V2FP:
3153 case E_NDS_ABI_AABI:
40c7a7cb 3154 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3155 /* In case there are holes in the array. */
3156 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3157 break;
3158
3159 default:
3160 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3161 break;
3162 }
3163
3164 switch (version)
3165 {
3166 case E_NDS32_ELF_VER_1_2:
3167 case E_NDS32_ELF_VER_1_3:
3168 case E_NDS32_ELF_VER_1_4:
3169 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3170 break;
3171
3172 default:
3173 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3174 break;
3175 }
3176
3177 if (E_NDS_ABI_V0 == abi)
3178 {
3179 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3180 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3181 if (arch == E_NDS_ARCH_STAR_V1_0)
3182 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3183 return;
3184 }
3185
3186 switch (arch)
3187 {
3188 case E_NDS_ARCH_STAR_V1_0:
3189 case E_NDS_ARCH_STAR_V2_0:
3190 case E_NDS_ARCH_STAR_V3_0:
3191 case E_NDS_ARCH_STAR_V3_M:
3192 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3193 break;
3194
3195 default:
3196 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3197 /* ARCH version determines how the e_flags are interpreted.
3198 If it is unknown, we cannot proceed. */
3199 return;
3200 }
3201
3202 /* Newer ABI; Now handle architecture specific flags. */
3203 if (arch == E_NDS_ARCH_STAR_V1_0)
3204 {
3205 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3206 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3207
3208 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3209 r += snprintf (buf + r, size -r, ", MAC");
3210
3211 if (config & E_NDS32_HAS_DIV_INST)
3212 r += snprintf (buf + r, size -r, ", DIV");
3213
3214 if (config & E_NDS32_HAS_16BIT_INST)
3215 r += snprintf (buf + r, size -r, ", 16b");
3216 }
3217 else
3218 {
3219 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3220 {
3221 if (version <= E_NDS32_ELF_VER_1_3)
3222 r += snprintf (buf + r, size -r, ", [B8]");
3223 else
3224 r += snprintf (buf + r, size -r, ", EX9");
3225 }
3226
3227 if (config & E_NDS32_HAS_MAC_DX_INST)
3228 r += snprintf (buf + r, size -r, ", MAC_DX");
3229
3230 if (config & E_NDS32_HAS_DIV_DX_INST)
3231 r += snprintf (buf + r, size -r, ", DIV_DX");
3232
3233 if (config & E_NDS32_HAS_16BIT_INST)
3234 {
3235 if (version <= E_NDS32_ELF_VER_1_3)
3236 r += snprintf (buf + r, size -r, ", 16b");
3237 else
3238 r += snprintf (buf + r, size -r, ", IFC");
3239 }
3240 }
3241
3242 if (config & E_NDS32_HAS_EXT_INST)
3243 r += snprintf (buf + r, size -r, ", PERF1");
3244
3245 if (config & E_NDS32_HAS_EXT2_INST)
3246 r += snprintf (buf + r, size -r, ", PERF2");
3247
3248 if (config & E_NDS32_HAS_FPU_INST)
3249 {
015dc7e1 3250 has_fpu = true;
35c08157
KLC
3251 r += snprintf (buf + r, size -r, ", FPU_SP");
3252 }
3253
3254 if (config & E_NDS32_HAS_FPU_DP_INST)
3255 {
015dc7e1 3256 has_fpu = true;
35c08157
KLC
3257 r += snprintf (buf + r, size -r, ", FPU_DP");
3258 }
3259
3260 if (config & E_NDS32_HAS_FPU_MAC_INST)
3261 {
015dc7e1 3262 has_fpu = true;
35c08157
KLC
3263 r += snprintf (buf + r, size -r, ", FPU_MAC");
3264 }
3265
3266 if (has_fpu)
3267 {
3268 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3269 {
3270 case E_NDS32_FPU_REG_8SP_4DP:
3271 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3272 break;
3273 case E_NDS32_FPU_REG_16SP_8DP:
3274 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3275 break;
3276 case E_NDS32_FPU_REG_32SP_16DP:
3277 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3278 break;
3279 case E_NDS32_FPU_REG_32SP_32DP:
3280 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3281 break;
3282 }
3283 }
3284
3285 if (config & E_NDS32_HAS_AUDIO_INST)
3286 r += snprintf (buf + r, size -r, ", AUDIO");
3287
3288 if (config & E_NDS32_HAS_STRING_INST)
3289 r += snprintf (buf + r, size -r, ", STR");
3290
3291 if (config & E_NDS32_HAS_REDUCED_REGS)
3292 r += snprintf (buf + r, size -r, ", 16REG");
3293
3294 if (config & E_NDS32_HAS_VIDEO_INST)
3295 {
3296 if (version <= E_NDS32_ELF_VER_1_3)
3297 r += snprintf (buf + r, size -r, ", VIDEO");
3298 else
3299 r += snprintf (buf + r, size -r, ", SATURATION");
3300 }
3301
3302 if (config & E_NDS32_HAS_ENCRIPT_INST)
3303 r += snprintf (buf + r, size -r, ", ENCRP");
3304
3305 if (config & E_NDS32_HAS_L2C_INST)
3306 r += snprintf (buf + r, size -r, ", L2C");
3307}
3308
252b5132 3309static char *
dda8d76d 3310get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3311{
b34976b6 3312 static char buf[1024];
252b5132
RH
3313
3314 buf[0] = '\0';
76da6bbe 3315
252b5132
RH
3316 if (e_flags)
3317 {
3318 switch (e_machine)
3319 {
3320 default:
3321 break;
3322
886a2506 3323 case EM_ARC_COMPACT2:
886a2506 3324 case EM_ARC_COMPACT:
a9522a21
AB
3325 decode_ARC_machine_flags (e_flags, e_machine, buf);
3326 break;
886a2506 3327
f3485b74
NC
3328 case EM_ARM:
3329 decode_ARM_machine_flags (e_flags, buf);
3330 break;
76da6bbe 3331
343433df
AB
3332 case EM_AVR:
3333 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3334 break;
3335
781303ce
MF
3336 case EM_BLACKFIN:
3337 if (e_flags & EF_BFIN_PIC)
3338 strcat (buf, ", PIC");
3339
3340 if (e_flags & EF_BFIN_FDPIC)
3341 strcat (buf, ", FDPIC");
3342
3343 if (e_flags & EF_BFIN_CODE_IN_L1)
3344 strcat (buf, ", code in L1");
3345
3346 if (e_flags & EF_BFIN_DATA_IN_L1)
3347 strcat (buf, ", data in L1");
3348
3349 break;
3350
ec2dfb42
AO
3351 case EM_CYGNUS_FRV:
3352 switch (e_flags & EF_FRV_CPU_MASK)
3353 {
3354 case EF_FRV_CPU_GENERIC:
3355 break;
3356
3357 default:
3358 strcat (buf, ", fr???");
3359 break;
57346661 3360
ec2dfb42
AO
3361 case EF_FRV_CPU_FR300:
3362 strcat (buf, ", fr300");
3363 break;
3364
3365 case EF_FRV_CPU_FR400:
3366 strcat (buf, ", fr400");
3367 break;
3368 case EF_FRV_CPU_FR405:
3369 strcat (buf, ", fr405");
3370 break;
3371
3372 case EF_FRV_CPU_FR450:
3373 strcat (buf, ", fr450");
3374 break;
3375
3376 case EF_FRV_CPU_FR500:
3377 strcat (buf, ", fr500");
3378 break;
3379 case EF_FRV_CPU_FR550:
3380 strcat (buf, ", fr550");
3381 break;
3382
3383 case EF_FRV_CPU_SIMPLE:
3384 strcat (buf, ", simple");
3385 break;
3386 case EF_FRV_CPU_TOMCAT:
3387 strcat (buf, ", tomcat");
3388 break;
3389 }
1c877e87 3390 break;
ec2dfb42 3391
53c7db4b 3392 case EM_68K:
425c6cb0 3393 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3394 strcat (buf, ", m68000");
425c6cb0 3395 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3396 strcat (buf, ", cpu32");
3397 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3398 strcat (buf, ", fido_a");
425c6cb0 3399 else
266abb8f 3400 {
2cf0635d
NC
3401 char const * isa = _("unknown");
3402 char const * mac = _("unknown mac");
3403 char const * additional = NULL;
0112cd26 3404
c694fd50 3405 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3406 {
c694fd50 3407 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3408 isa = "A";
3409 additional = ", nodiv";
3410 break;
c694fd50 3411 case EF_M68K_CF_ISA_A:
266abb8f
NS
3412 isa = "A";
3413 break;
c694fd50 3414 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3415 isa = "A+";
3416 break;
c694fd50 3417 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3418 isa = "B";
3419 additional = ", nousp";
3420 break;
c694fd50 3421 case EF_M68K_CF_ISA_B:
266abb8f
NS
3422 isa = "B";
3423 break;
f608cd77
NS
3424 case EF_M68K_CF_ISA_C:
3425 isa = "C";
3426 break;
3427 case EF_M68K_CF_ISA_C_NODIV:
3428 isa = "C";
3429 additional = ", nodiv";
3430 break;
266abb8f
NS
3431 }
3432 strcat (buf, ", cf, isa ");
3433 strcat (buf, isa);
0b2e31dc
NS
3434 if (additional)
3435 strcat (buf, additional);
c694fd50 3436 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3437 strcat (buf, ", float");
c694fd50 3438 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3439 {
3440 case 0:
3441 mac = NULL;
3442 break;
c694fd50 3443 case EF_M68K_CF_MAC:
266abb8f
NS
3444 mac = "mac";
3445 break;
c694fd50 3446 case EF_M68K_CF_EMAC:
266abb8f
NS
3447 mac = "emac";
3448 break;
f608cd77
NS
3449 case EF_M68K_CF_EMAC_B:
3450 mac = "emac_b";
3451 break;
266abb8f
NS
3452 }
3453 if (mac)
3454 {
3455 strcat (buf, ", ");
3456 strcat (buf, mac);
3457 }
266abb8f 3458 }
53c7db4b 3459 break;
33c63f9d 3460
153a2776
NC
3461 case EM_CYGNUS_MEP:
3462 switch (e_flags & EF_MEP_CPU_MASK)
3463 {
3464 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3465 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3466 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3467 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3468 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3469 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3470 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3471 }
3472
3473 switch (e_flags & EF_MEP_COP_MASK)
3474 {
3475 case EF_MEP_COP_NONE: break;
3476 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3477 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3478 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3479 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3480 default: strcat (buf, _("<unknown MeP copro type>")); break;
3481 }
3482
3483 if (e_flags & EF_MEP_LIBRARY)
3484 strcat (buf, ", Built for Library");
3485
3486 if (e_flags & EF_MEP_INDEX_MASK)
3487 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3488 e_flags & EF_MEP_INDEX_MASK);
3489
3490 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3491 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3492 e_flags & ~ EF_MEP_ALL_FLAGS);
3493 break;
3494
252b5132
RH
3495 case EM_PPC:
3496 if (e_flags & EF_PPC_EMB)
3497 strcat (buf, ", emb");
3498
3499 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3500 strcat (buf, _(", relocatable"));
252b5132
RH
3501
3502 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3503 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3504 break;
3505
ee67d69a
AM
3506 case EM_PPC64:
3507 if (e_flags & EF_PPC64_ABI)
3508 {
3509 char abi[] = ", abiv0";
3510
3511 abi[6] += e_flags & EF_PPC64_ABI;
3512 strcat (buf, abi);
3513 }
3514 break;
3515
708e2187
NC
3516 case EM_V800:
3517 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3518 strcat (buf, ", RH850 ABI");
0b4362b0 3519
708e2187
NC
3520 if (e_flags & EF_V800_850E3)
3521 strcat (buf, ", V3 architecture");
3522
3523 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3524 strcat (buf, ", FPU not used");
3525
3526 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3527 strcat (buf, ", regmode: COMMON");
3528
3529 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3530 strcat (buf, ", r4 not used");
3531
3532 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3533 strcat (buf, ", r30 not used");
3534
3535 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3536 strcat (buf, ", r5 not used");
3537
3538 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3539 strcat (buf, ", r2 not used");
3540
3541 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3542 {
3543 switch (e_flags & - e_flags)
3544 {
3545 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3546 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3547 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3548 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3549 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3550 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3551 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3552 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3553 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3554 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3555 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3556 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3557 default: break;
3558 }
3559 }
3560 break;
3561
2b0337b0 3562 case EM_V850:
252b5132
RH
3563 case EM_CYGNUS_V850:
3564 switch (e_flags & EF_V850_ARCH)
3565 {
78c8d46c
NC
3566 case E_V850E3V5_ARCH:
3567 strcat (buf, ", v850e3v5");
3568 break;
1cd986c5
NC
3569 case E_V850E2V3_ARCH:
3570 strcat (buf, ", v850e2v3");
3571 break;
3572 case E_V850E2_ARCH:
3573 strcat (buf, ", v850e2");
3574 break;
3575 case E_V850E1_ARCH:
3576 strcat (buf, ", v850e1");
8ad30312 3577 break;
252b5132
RH
3578 case E_V850E_ARCH:
3579 strcat (buf, ", v850e");
3580 break;
252b5132
RH
3581 case E_V850_ARCH:
3582 strcat (buf, ", v850");
3583 break;
3584 default:
2b692964 3585 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3586 break;
3587 }
3588 break;
3589
2b0337b0 3590 case EM_M32R:
252b5132
RH
3591 case EM_CYGNUS_M32R:
3592 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3593 strcat (buf, ", m32r");
252b5132
RH
3594 break;
3595
3596 case EM_MIPS:
4fe85591 3597 case EM_MIPS_RS3_LE:
252b5132
RH
3598 if (e_flags & EF_MIPS_NOREORDER)
3599 strcat (buf, ", noreorder");
3600
3601 if (e_flags & EF_MIPS_PIC)
3602 strcat (buf, ", pic");
3603
3604 if (e_flags & EF_MIPS_CPIC)
3605 strcat (buf, ", cpic");
3606
d1bdd336
TS
3607 if (e_flags & EF_MIPS_UCODE)
3608 strcat (buf, ", ugen_reserved");
3609
252b5132
RH
3610 if (e_flags & EF_MIPS_ABI2)
3611 strcat (buf, ", abi2");
3612
43521d43
TS
3613 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3614 strcat (buf, ", odk first");
3615
a5d22d2a
TS
3616 if (e_flags & EF_MIPS_32BITMODE)
3617 strcat (buf, ", 32bitmode");
3618
ba92f887
MR
3619 if (e_flags & EF_MIPS_NAN2008)
3620 strcat (buf, ", nan2008");
3621
fef1b0b3
SE
3622 if (e_flags & EF_MIPS_FP64)
3623 strcat (buf, ", fp64");
3624
156c2f8b
NC
3625 switch ((e_flags & EF_MIPS_MACH))
3626 {
3627 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3628 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3629 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3630 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3631 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3632 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3633 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3634 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3635 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3636 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3637 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3638 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3639 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3640 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3641 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3642 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3643 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3644 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3645 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3646 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3647 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3648 case 0:
3649 /* We simply ignore the field in this case to avoid confusion:
3650 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3651 extension. */
3652 break;
2b692964 3653 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3654 }
43521d43
TS
3655
3656 switch ((e_flags & EF_MIPS_ABI))
3657 {
3658 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3659 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3660 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3661 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3662 case 0:
3663 /* We simply ignore the field in this case to avoid confusion:
3664 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3665 This means it is likely to be an o32 file, but not for
3666 sure. */
3667 break;
2b692964 3668 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3669 }
3670
3671 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3672 strcat (buf, ", mdmx");
3673
3674 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3675 strcat (buf, ", mips16");
3676
df58fc94
RS
3677 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3678 strcat (buf, ", micromips");
3679
43521d43
TS
3680 switch ((e_flags & EF_MIPS_ARCH))
3681 {
3682 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3683 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3684 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3685 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3686 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3687 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3688 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3689 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3690 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3691 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3692 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3693 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3694 }
252b5132 3695 break;
351b4b40 3696
35c08157
KLC
3697 case EM_NDS32:
3698 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3699 break;
3700
fe944acf
FT
3701 case EM_NFP:
3702 switch (EF_NFP_MACH (e_flags))
3703 {
3704 case E_NFP_MACH_3200:
3705 strcat (buf, ", NFP-32xx");
3706 break;
3707 case E_NFP_MACH_6000:
3708 strcat (buf, ", NFP-6xxx");
3709 break;
3710 }
3711 break;
3712
e23eba97
NC
3713 case EM_RISCV:
3714 if (e_flags & EF_RISCV_RVC)
3715 strcat (buf, ", RVC");
2922d21d 3716
7f999549
JW
3717 if (e_flags & EF_RISCV_RVE)
3718 strcat (buf, ", RVE");
3719
2922d21d
AW
3720 switch (e_flags & EF_RISCV_FLOAT_ABI)
3721 {
3722 case EF_RISCV_FLOAT_ABI_SOFT:
3723 strcat (buf, ", soft-float ABI");
3724 break;
3725
3726 case EF_RISCV_FLOAT_ABI_SINGLE:
3727 strcat (buf, ", single-float ABI");
3728 break;
3729
3730 case EF_RISCV_FLOAT_ABI_DOUBLE:
3731 strcat (buf, ", double-float ABI");
3732 break;
3733
3734 case EF_RISCV_FLOAT_ABI_QUAD:
3735 strcat (buf, ", quad-float ABI");
3736 break;
3737 }
e23eba97
NC
3738 break;
3739
ccde1100
AO
3740 case EM_SH:
3741 switch ((e_flags & EF_SH_MACH_MASK))
3742 {
3743 case EF_SH1: strcat (buf, ", sh1"); break;
3744 case EF_SH2: strcat (buf, ", sh2"); break;
3745 case EF_SH3: strcat (buf, ", sh3"); break;
3746 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3747 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3748 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3749 case EF_SH3E: strcat (buf, ", sh3e"); break;
3750 case EF_SH4: strcat (buf, ", sh4"); break;
3751 case EF_SH5: strcat (buf, ", sh5"); break;
3752 case EF_SH2E: strcat (buf, ", sh2e"); break;
3753 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3754 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3755 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3756 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3757 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3758 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3759 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3760 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3761 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3762 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3763 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3764 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3765 }
3766
cec6a5b8
MR
3767 if (e_flags & EF_SH_PIC)
3768 strcat (buf, ", pic");
3769
3770 if (e_flags & EF_SH_FDPIC)
3771 strcat (buf, ", fdpic");
ccde1100 3772 break;
948f632f 3773
73589c9d
CS
3774 case EM_OR1K:
3775 if (e_flags & EF_OR1K_NODELAY)
3776 strcat (buf, ", no delay");
3777 break;
57346661 3778
351b4b40
RH
3779 case EM_SPARCV9:
3780 if (e_flags & EF_SPARC_32PLUS)
3781 strcat (buf, ", v8+");
3782
3783 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3784 strcat (buf, ", ultrasparcI");
3785
3786 if (e_flags & EF_SPARC_SUN_US3)
3787 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3788
3789 if (e_flags & EF_SPARC_HAL_R1)
3790 strcat (buf, ", halr1");
3791
3792 if (e_flags & EF_SPARC_LEDATA)
3793 strcat (buf, ", ledata");
3794
3795 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3796 strcat (buf, ", tso");
3797
3798 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3799 strcat (buf, ", pso");
3800
3801 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3802 strcat (buf, ", rmo");
3803 break;
7d466069 3804
103f02d3
UD
3805 case EM_PARISC:
3806 switch (e_flags & EF_PARISC_ARCH)
3807 {
3808 case EFA_PARISC_1_0:
3809 strcpy (buf, ", PA-RISC 1.0");
3810 break;
3811 case EFA_PARISC_1_1:
3812 strcpy (buf, ", PA-RISC 1.1");
3813 break;
3814 case EFA_PARISC_2_0:
3815 strcpy (buf, ", PA-RISC 2.0");
3816 break;
3817 default:
3818 break;
3819 }
3820 if (e_flags & EF_PARISC_TRAPNIL)
3821 strcat (buf, ", trapnil");
3822 if (e_flags & EF_PARISC_EXT)
3823 strcat (buf, ", ext");
3824 if (e_flags & EF_PARISC_LSB)
3825 strcat (buf, ", lsb");
3826 if (e_flags & EF_PARISC_WIDE)
3827 strcat (buf, ", wide");
3828 if (e_flags & EF_PARISC_NO_KABP)
3829 strcat (buf, ", no kabp");
3830 if (e_flags & EF_PARISC_LAZYSWAP)
3831 strcat (buf, ", lazyswap");
30800947 3832 break;
76da6bbe 3833
7d466069 3834 case EM_PJ:
2b0337b0 3835 case EM_PJ_OLD:
7d466069
ILT
3836 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3837 strcat (buf, ", new calling convention");
3838
3839 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3840 strcat (buf, ", gnu calling convention");
3841 break;
4d6ed7c8
NC
3842
3843 case EM_IA_64:
3844 if ((e_flags & EF_IA_64_ABI64))
3845 strcat (buf, ", 64-bit");
3846 else
3847 strcat (buf, ", 32-bit");
3848 if ((e_flags & EF_IA_64_REDUCEDFP))
3849 strcat (buf, ", reduced fp model");
3850 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3851 strcat (buf, ", no function descriptors, constant gp");
3852 else if ((e_flags & EF_IA_64_CONS_GP))
3853 strcat (buf, ", constant gp");
3854 if ((e_flags & EF_IA_64_ABSOLUTE))
3855 strcat (buf, ", absolute");
dda8d76d 3856 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3857 {
3858 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3859 strcat (buf, ", vms_linkages");
3860 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3861 {
3862 case EF_IA_64_VMS_COMCOD_SUCCESS:
3863 break;
3864 case EF_IA_64_VMS_COMCOD_WARNING:
3865 strcat (buf, ", warning");
3866 break;
3867 case EF_IA_64_VMS_COMCOD_ERROR:
3868 strcat (buf, ", error");
3869 break;
3870 case EF_IA_64_VMS_COMCOD_ABORT:
3871 strcat (buf, ", abort");
3872 break;
3873 default:
bee0ee85
NC
3874 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3875 e_flags & EF_IA_64_VMS_COMCOD);
3876 strcat (buf, ", <unknown>");
28f997cf
TG
3877 }
3878 }
4d6ed7c8 3879 break;
179d3252
JT
3880
3881 case EM_VAX:
3882 if ((e_flags & EF_VAX_NONPIC))
3883 strcat (buf, ", non-PIC");
3884 if ((e_flags & EF_VAX_DFLOAT))
3885 strcat (buf, ", D-Float");
3886 if ((e_flags & EF_VAX_GFLOAT))
3887 strcat (buf, ", G-Float");
3888 break;
c7927a3c 3889
619ed720
EB
3890 case EM_VISIUM:
3891 if (e_flags & EF_VISIUM_ARCH_MCM)
3892 strcat (buf, ", mcm");
3893 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3894 strcat (buf, ", mcm24");
3895 if (e_flags & EF_VISIUM_ARCH_GR6)
3896 strcat (buf, ", gr6");
3897 break;
3898
4046d87a 3899 case EM_RL78:
1740ba0c
NC
3900 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3901 {
3902 case E_FLAG_RL78_ANY_CPU: break;
3903 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3904 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3905 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3906 }
856ea05c
KP
3907 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3908 strcat (buf, ", 64-bit doubles");
4046d87a 3909 break;
0b4362b0 3910
c7927a3c
NC
3911 case EM_RX:
3912 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3913 strcat (buf, ", 64-bit doubles");
3914 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3915 strcat (buf, ", dsp");
d4cb0ea0 3916 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3917 strcat (buf, ", pid");
708e2187
NC
3918 if (e_flags & E_FLAG_RX_ABI)
3919 strcat (buf, ", RX ABI");
3525236c
NC
3920 if (e_flags & E_FLAG_RX_SINSNS_SET)
3921 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3922 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3923 if (e_flags & E_FLAG_RX_V2)
3924 strcat (buf, ", V2");
f87673e0
YS
3925 if (e_flags & E_FLAG_RX_V3)
3926 strcat (buf, ", V3");
d4cb0ea0 3927 break;
55786da2
AK
3928
3929 case EM_S390:
3930 if (e_flags & EF_S390_HIGH_GPRS)
3931 strcat (buf, ", highgprs");
d4cb0ea0 3932 break;
40b36596
JM
3933
3934 case EM_TI_C6000:
3935 if ((e_flags & EF_C6000_REL))
3936 strcat (buf, ", relocatable module");
d4cb0ea0 3937 break;
13761a11
NC
3938
3939 case EM_MSP430:
3940 strcat (buf, _(": architecture variant: "));
3941 switch (e_flags & EF_MSP430_MACH)
3942 {
3943 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3944 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3945 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3946 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3947 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3948 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3949 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3950 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3951 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3952 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3953 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3954 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3955 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3956 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3957 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3958 default:
3959 strcat (buf, _(": unknown")); break;
3960 }
3961
3962 if (e_flags & ~ EF_MSP430_MACH)
3963 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3964 break;
3965
3966 case EM_Z80:
3967 switch (e_flags & EF_Z80_MACH_MSK)
3968 {
3969 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3970 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3971 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3972 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3973 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3974 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3975 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3976 default:
3977 strcat (buf, _(", unknown")); break;
3978 }
3979 break;
e9a0721f 3980 case EM_LOONGARCH:
3981 if (EF_LOONGARCH_IS_LP64 (e_flags))
3982 strcat (buf, ", LP64");
3983 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
3984 strcat (buf, ", ILP32");
3985
3986 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
3987 strcat (buf, ", SOFT-FLOAT");
3988 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
3989 strcat (buf, ", SINGLE-FLOAT");
3990 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
3991 strcat (buf, ", DOUBLE-FLOAT");
3992
3993 break;
252b5132
RH
3994 }
3995 }
3996
3997 return buf;
3998}
3999
252b5132 4000static const char *
dda8d76d 4001get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4002{
4003 static char buff[32];
4004
4005 switch (osabi)
4006 {
4007 case ELFOSABI_NONE: return "UNIX - System V";
4008 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4009 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4010 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4011 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4012 case ELFOSABI_AIX: return "UNIX - AIX";
4013 case ELFOSABI_IRIX: return "UNIX - IRIX";
4014 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4015 case ELFOSABI_TRU64: return "UNIX - TRU64";
4016 case ELFOSABI_MODESTO: return "Novell - Modesto";
4017 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4018 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4019 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4020 case ELFOSABI_AROS: return "AROS";
11636f9e 4021 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4022 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4023 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4024 default:
40b36596 4025 if (osabi >= 64)
dda8d76d 4026 switch (filedata->file_header.e_machine)
40b36596
JM
4027 {
4028 case EM_ARM:
4029 switch (osabi)
4030 {
4031 case ELFOSABI_ARM: return "ARM";
18a20338 4032 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4033 default:
4034 break;
4035 }
4036 break;
4037
4038 case EM_MSP430:
4039 case EM_MSP430_OLD:
619ed720 4040 case EM_VISIUM:
40b36596
JM
4041 switch (osabi)
4042 {
4043 case ELFOSABI_STANDALONE: return _("Standalone App");
4044 default:
4045 break;
4046 }
4047 break;
4048
4049 case EM_TI_C6000:
4050 switch (osabi)
4051 {
4052 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4053 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4054 default:
4055 break;
4056 }
4057 break;
4058
4059 default:
4060 break;
4061 }
e9e44622 4062 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4063 return buff;
4064 }
4065}
4066
a06ea964
NC
4067static const char *
4068get_aarch64_segment_type (unsigned long type)
4069{
4070 switch (type)
4071 {
32ec8896
NC
4072 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4073 default: return NULL;
a06ea964 4074 }
a06ea964
NC
4075}
4076
b294bdf8
MM
4077static const char *
4078get_arm_segment_type (unsigned long type)
4079{
4080 switch (type)
4081 {
32ec8896
NC
4082 case PT_ARM_EXIDX: return "EXIDX";
4083 default: return NULL;
b294bdf8 4084 }
b294bdf8
MM
4085}
4086
b4cbbe8f
AK
4087static const char *
4088get_s390_segment_type (unsigned long type)
4089{
4090 switch (type)
4091 {
4092 case PT_S390_PGSTE: return "S390_PGSTE";
4093 default: return NULL;
4094 }
4095}
4096
d3ba0551
AM
4097static const char *
4098get_mips_segment_type (unsigned long type)
252b5132
RH
4099{
4100 switch (type)
4101 {
32ec8896
NC
4102 case PT_MIPS_REGINFO: return "REGINFO";
4103 case PT_MIPS_RTPROC: return "RTPROC";
4104 case PT_MIPS_OPTIONS: return "OPTIONS";
4105 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4106 default: return NULL;
252b5132 4107 }
252b5132
RH
4108}
4109
103f02d3 4110static const char *
d3ba0551 4111get_parisc_segment_type (unsigned long type)
103f02d3
UD
4112{
4113 switch (type)
4114 {
103f02d3
UD
4115 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4116 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4117 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4118 default: return NULL;
103f02d3 4119 }
103f02d3
UD
4120}
4121
4d6ed7c8 4122static const char *
d3ba0551 4123get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4124{
4125 switch (type)
4126 {
4127 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4128 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4129 default: return NULL;
4d6ed7c8 4130 }
4d6ed7c8
NC
4131}
4132
40b36596
JM
4133static const char *
4134get_tic6x_segment_type (unsigned long type)
4135{
4136 switch (type)
4137 {
32ec8896
NC
4138 case PT_C6000_PHATTR: return "C6000_PHATTR";
4139 default: return NULL;
40b36596 4140 }
40b36596
JM
4141}
4142
fbc95f1e
KC
4143static const char *
4144get_riscv_segment_type (unsigned long type)
4145{
4146 switch (type)
4147 {
4148 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4149 default: return NULL;
4150 }
4151}
4152
df3a023b
AM
4153static const char *
4154get_hpux_segment_type (unsigned long type, unsigned e_machine)
4155{
4156 if (e_machine == EM_PARISC)
4157 switch (type)
4158 {
4159 case PT_HP_TLS: return "HP_TLS";
4160 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4161 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4162 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4163 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4164 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4165 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4166 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4167 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4168 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4169 case PT_HP_PARALLEL: return "HP_PARALLEL";
4170 case PT_HP_FASTBIND: return "HP_FASTBIND";
4171 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4172 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4173 case PT_HP_STACK: return "HP_STACK";
4174 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4175 default: return NULL;
4176 }
4177
4178 if (e_machine == EM_IA_64)
4179 switch (type)
4180 {
4181 case PT_HP_TLS: return "HP_TLS";
4182 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4183 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4184 case PT_IA_64_HP_STACK: return "HP_STACK";
4185 default: return NULL;
4186 }
4187
4188 return NULL;
4189}
4190
5522f910
NC
4191static const char *
4192get_solaris_segment_type (unsigned long type)
4193{
4194 switch (type)
4195 {
4196 case 0x6464e550: return "PT_SUNW_UNWIND";
4197 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4198 case 0x6ffffff7: return "PT_LOSUNW";
4199 case 0x6ffffffa: return "PT_SUNWBSS";
4200 case 0x6ffffffb: return "PT_SUNWSTACK";
4201 case 0x6ffffffc: return "PT_SUNWDTRACE";
4202 case 0x6ffffffd: return "PT_SUNWCAP";
4203 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4204 default: return NULL;
5522f910
NC
4205 }
4206}
4207
252b5132 4208static const char *
dda8d76d 4209get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4210{
b34976b6 4211 static char buff[32];
252b5132
RH
4212
4213 switch (p_type)
4214 {
b34976b6
AM
4215 case PT_NULL: return "NULL";
4216 case PT_LOAD: return "LOAD";
252b5132 4217 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4218 case PT_INTERP: return "INTERP";
4219 case PT_NOTE: return "NOTE";
4220 case PT_SHLIB: return "SHLIB";
4221 case PT_PHDR: return "PHDR";
13ae64f3 4222 case PT_TLS: return "TLS";
32ec8896 4223 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4224 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4225 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4226 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4227
3eba3ef3
NC
4228 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4229 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4230 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4231
252b5132 4232 default:
df3a023b 4233 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4234 {
2cf0635d 4235 const char * result;
103f02d3 4236
dda8d76d 4237 switch (filedata->file_header.e_machine)
252b5132 4238 {
a06ea964
NC
4239 case EM_AARCH64:
4240 result = get_aarch64_segment_type (p_type);
4241 break;
b294bdf8
MM
4242 case EM_ARM:
4243 result = get_arm_segment_type (p_type);
4244 break;
252b5132 4245 case EM_MIPS:
4fe85591 4246 case EM_MIPS_RS3_LE:
252b5132
RH
4247 result = get_mips_segment_type (p_type);
4248 break;
103f02d3
UD
4249 case EM_PARISC:
4250 result = get_parisc_segment_type (p_type);
4251 break;
4d6ed7c8
NC
4252 case EM_IA_64:
4253 result = get_ia64_segment_type (p_type);
4254 break;
40b36596
JM
4255 case EM_TI_C6000:
4256 result = get_tic6x_segment_type (p_type);
4257 break;
b4cbbe8f
AK
4258 case EM_S390:
4259 case EM_S390_OLD:
4260 result = get_s390_segment_type (p_type);
4261 break;
fbc95f1e
KC
4262 case EM_RISCV:
4263 result = get_riscv_segment_type (p_type);
4264 break;
252b5132
RH
4265 default:
4266 result = NULL;
4267 break;
4268 }
103f02d3 4269
252b5132
RH
4270 if (result != NULL)
4271 return result;
103f02d3 4272
1a9ccd70 4273 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4274 }
4275 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4276 {
df3a023b 4277 const char * result = NULL;
103f02d3 4278
df3a023b 4279 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4280 {
df3a023b
AM
4281 case ELFOSABI_GNU:
4282 case ELFOSABI_FREEBSD:
4283 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4284 {
4285 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4286 result = buff;
4287 }
103f02d3 4288 break;
df3a023b
AM
4289 case ELFOSABI_HPUX:
4290 result = get_hpux_segment_type (p_type,
4291 filedata->file_header.e_machine);
4292 break;
4293 case ELFOSABI_SOLARIS:
4294 result = get_solaris_segment_type (p_type);
00428cca 4295 break;
103f02d3 4296 default:
103f02d3
UD
4297 break;
4298 }
103f02d3
UD
4299 if (result != NULL)
4300 return result;
4301
1a9ccd70 4302 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4303 }
252b5132 4304 else
e9e44622 4305 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4306
4307 return buff;
4308 }
4309}
4310
53a346d8
CZ
4311static const char *
4312get_arc_section_type_name (unsigned int sh_type)
4313{
4314 switch (sh_type)
4315 {
4316 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4317 default:
4318 break;
4319 }
4320 return NULL;
4321}
4322
252b5132 4323static const char *
d3ba0551 4324get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4325{
4326 switch (sh_type)
4327 {
b34976b6
AM
4328 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4329 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4330 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4331 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4332 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4333 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4334 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4335 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4336 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4337 case SHT_MIPS_RELD: return "MIPS_RELD";
4338 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4339 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4340 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4341 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4342 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4343 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4344 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4345 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4346 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4347 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4348 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4349 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4350 case SHT_MIPS_LINE: return "MIPS_LINE";
4351 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4352 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4353 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4354 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4355 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4356 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4357 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4358 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4359 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4360 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4361 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4362 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4363 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4364 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4365 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4366 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4367 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4368 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4369 default:
4370 break;
4371 }
4372 return NULL;
4373}
4374
103f02d3 4375static const char *
d3ba0551 4376get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4377{
4378 switch (sh_type)
4379 {
4380 case SHT_PARISC_EXT: return "PARISC_EXT";
4381 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4382 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4383 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4384 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4385 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4386 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4387 default: return NULL;
103f02d3 4388 }
103f02d3
UD
4389}
4390
4d6ed7c8 4391static const char *
dda8d76d 4392get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4393{
18bd398b 4394 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4395 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4396 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4397
4d6ed7c8
NC
4398 switch (sh_type)
4399 {
148b93f2
NC
4400 case SHT_IA_64_EXT: return "IA_64_EXT";
4401 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4402 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4403 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4404 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4405 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4406 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4407 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4408 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4409 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4410 default:
4411 break;
4412 }
4413 return NULL;
4414}
4415
d2b2c203
DJ
4416static const char *
4417get_x86_64_section_type_name (unsigned int sh_type)
4418{
4419 switch (sh_type)
4420 {
4421 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4422 default: return NULL;
d2b2c203 4423 }
d2b2c203
DJ
4424}
4425
a06ea964
NC
4426static const char *
4427get_aarch64_section_type_name (unsigned int sh_type)
4428{
4429 switch (sh_type)
4430 {
32ec8896
NC
4431 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4432 default: return NULL;
a06ea964 4433 }
a06ea964
NC
4434}
4435
40a18ebd
NC
4436static const char *
4437get_arm_section_type_name (unsigned int sh_type)
4438{
4439 switch (sh_type)
4440 {
7f6fed87
NC
4441 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4442 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4443 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4444 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4445 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4446 default: return NULL;
40a18ebd 4447 }
40a18ebd
NC
4448}
4449
40b36596
JM
4450static const char *
4451get_tic6x_section_type_name (unsigned int sh_type)
4452{
4453 switch (sh_type)
4454 {
32ec8896
NC
4455 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4456 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4457 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4458 case SHT_TI_ICODE: return "TI_ICODE";
4459 case SHT_TI_XREF: return "TI_XREF";
4460 case SHT_TI_HANDLER: return "TI_HANDLER";
4461 case SHT_TI_INITINFO: return "TI_INITINFO";
4462 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4463 default: return NULL;
40b36596 4464 }
40b36596
JM
4465}
4466
13761a11 4467static const char *
b0191216 4468get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4469{
4470 switch (sh_type)
4471 {
32ec8896
NC
4472 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4473 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4474 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4475 default: return NULL;
13761a11
NC
4476 }
4477}
4478
fe944acf
FT
4479static const char *
4480get_nfp_section_type_name (unsigned int sh_type)
4481{
4482 switch (sh_type)
4483 {
4484 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4485 case SHT_NFP_INITREG: return "NFP_INITREG";
4486 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4487 default: return NULL;
4488 }
4489}
4490
685080f2
NC
4491static const char *
4492get_v850_section_type_name (unsigned int sh_type)
4493{
4494 switch (sh_type)
4495 {
32ec8896
NC
4496 case SHT_V850_SCOMMON: return "V850 Small Common";
4497 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4498 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4499 case SHT_RENESAS_IOP: return "RENESAS IOP";
4500 case SHT_RENESAS_INFO: return "RENESAS INFO";
4501 default: return NULL;
685080f2
NC
4502 }
4503}
4504
2dc8dd17
JW
4505static const char *
4506get_riscv_section_type_name (unsigned int sh_type)
4507{
4508 switch (sh_type)
4509 {
4510 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4511 default: return NULL;
4512 }
4513}
4514
0861f561
CQ
4515static const char *
4516get_csky_section_type_name (unsigned int sh_type)
4517{
4518 switch (sh_type)
4519 {
4520 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4521 default: return NULL;
4522 }
4523}
4524
252b5132 4525static const char *
dda8d76d 4526get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4527{
b34976b6 4528 static char buff[32];
9fb71ee4 4529 const char * result;
252b5132
RH
4530
4531 switch (sh_type)
4532 {
4533 case SHT_NULL: return "NULL";
4534 case SHT_PROGBITS: return "PROGBITS";
4535 case SHT_SYMTAB: return "SYMTAB";
4536 case SHT_STRTAB: return "STRTAB";
4537 case SHT_RELA: return "RELA";
4538 case SHT_HASH: return "HASH";
4539 case SHT_DYNAMIC: return "DYNAMIC";
4540 case SHT_NOTE: return "NOTE";
4541 case SHT_NOBITS: return "NOBITS";
4542 case SHT_REL: return "REL";
4543 case SHT_SHLIB: return "SHLIB";
4544 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4545 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4546 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4547 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4548 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4549 case SHT_GROUP: return "GROUP";
67ce483b 4550 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4551 case SHT_GNU_verdef: return "VERDEF";
4552 case SHT_GNU_verneed: return "VERNEED";
4553 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4554 case 0x6ffffff0: return "VERSYM";
4555 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4556 case 0x7ffffffd: return "AUXILIARY";
4557 case 0x7fffffff: return "FILTER";
047b2264 4558 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4559
4560 default:
4561 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4562 {
dda8d76d 4563 switch (filedata->file_header.e_machine)
252b5132 4564 {
53a346d8
CZ
4565 case EM_ARC:
4566 case EM_ARC_COMPACT:
4567 case EM_ARC_COMPACT2:
4568 result = get_arc_section_type_name (sh_type);
4569 break;
252b5132 4570 case EM_MIPS:
4fe85591 4571 case EM_MIPS_RS3_LE:
252b5132
RH
4572 result = get_mips_section_type_name (sh_type);
4573 break;
103f02d3
UD
4574 case EM_PARISC:
4575 result = get_parisc_section_type_name (sh_type);
4576 break;
4d6ed7c8 4577 case EM_IA_64:
dda8d76d 4578 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4579 break;
d2b2c203 4580 case EM_X86_64:
8a9036a4 4581 case EM_L1OM:
7a9068fe 4582 case EM_K1OM:
d2b2c203
DJ
4583 result = get_x86_64_section_type_name (sh_type);
4584 break;
a06ea964
NC
4585 case EM_AARCH64:
4586 result = get_aarch64_section_type_name (sh_type);
4587 break;
40a18ebd
NC
4588 case EM_ARM:
4589 result = get_arm_section_type_name (sh_type);
4590 break;
40b36596
JM
4591 case EM_TI_C6000:
4592 result = get_tic6x_section_type_name (sh_type);
4593 break;
13761a11 4594 case EM_MSP430:
b0191216 4595 result = get_msp430_section_type_name (sh_type);
13761a11 4596 break;
fe944acf
FT
4597 case EM_NFP:
4598 result = get_nfp_section_type_name (sh_type);
4599 break;
685080f2
NC
4600 case EM_V800:
4601 case EM_V850:
4602 case EM_CYGNUS_V850:
4603 result = get_v850_section_type_name (sh_type);
4604 break;
2dc8dd17
JW
4605 case EM_RISCV:
4606 result = get_riscv_section_type_name (sh_type);
4607 break;
0861f561
CQ
4608 case EM_CSKY:
4609 result = get_csky_section_type_name (sh_type);
4610 break;
252b5132
RH
4611 default:
4612 result = NULL;
4613 break;
4614 }
4615
4616 if (result != NULL)
4617 return result;
4618
9fb71ee4 4619 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4620 }
4621 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4622 {
dda8d76d 4623 switch (filedata->file_header.e_machine)
148b93f2
NC
4624 {
4625 case EM_IA_64:
dda8d76d 4626 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4627 break;
4628 default:
dda8d76d 4629 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4630 result = get_solaris_section_type (sh_type);
4631 else
1b4b80bf
NC
4632 {
4633 switch (sh_type)
4634 {
4635 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4636 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4637 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4638 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4639 default:
4640 result = NULL;
4641 break;
4642 }
4643 }
148b93f2
NC
4644 break;
4645 }
4646
4647 if (result != NULL)
4648 return result;
4649
9fb71ee4 4650 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4651 }
252b5132 4652 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4653 {
dda8d76d 4654 switch (filedata->file_header.e_machine)
685080f2
NC
4655 {
4656 case EM_V800:
4657 case EM_V850:
4658 case EM_CYGNUS_V850:
9fb71ee4 4659 result = get_v850_section_type_name (sh_type);
a9fb83be 4660 break;
685080f2 4661 default:
9fb71ee4 4662 result = NULL;
685080f2
NC
4663 break;
4664 }
4665
9fb71ee4
NC
4666 if (result != NULL)
4667 return result;
4668
4669 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4670 }
252b5132 4671 else
a7dbfd1c
NC
4672 /* This message is probably going to be displayed in a 15
4673 character wide field, so put the hex value first. */
4674 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4675
252b5132
RH
4676 return buff;
4677 }
4678}
4679
79bc120c
NC
4680enum long_option_values
4681{
4682 OPTION_DEBUG_DUMP = 512,
4683 OPTION_DYN_SYMS,
0f03783c 4684 OPTION_LTO_SYMS,
79bc120c
NC
4685 OPTION_DWARF_DEPTH,
4686 OPTION_DWARF_START,
4687 OPTION_DWARF_CHECK,
4688 OPTION_CTF_DUMP,
4689 OPTION_CTF_PARENT,
4690 OPTION_CTF_SYMBOLS,
4691 OPTION_CTF_STRINGS,
4692 OPTION_WITH_SYMBOL_VERSIONS,
4693 OPTION_RECURSE_LIMIT,
4694 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4695 OPTION_NO_DEMANGLING,
4696 OPTION_SYM_BASE
79bc120c 4697};
2979dc34 4698
85b1c36d 4699static struct option options[] =
252b5132 4700{
79bc120c
NC
4701 /* Note - This table is alpha-sorted on the 'val'
4702 field in order to make adding new options easier. */
4703 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4704 {"all", no_argument, 0, 'a'},
79bc120c
NC
4705 {"demangle", optional_argument, 0, 'C'},
4706 {"archive-index", no_argument, 0, 'c'},
4707 {"use-dynamic", no_argument, 0, 'D'},
4708 {"dynamic", no_argument, 0, 'd'},
b34976b6 4709 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4710 {"section-groups", no_argument, 0, 'g'},
4711 {"help", no_argument, 0, 'H'},
4712 {"file-header", no_argument, 0, 'h'},
b34976b6 4713 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4714 {"lint", no_argument, 0, 'L'},
4715 {"enable-checks", no_argument, 0, 'L'},
4716 {"program-headers", no_argument, 0, 'l'},
b34976b6 4717 {"segments", no_argument, 0, 'l'},
595cf52e 4718 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4719 {"notes", no_argument, 0, 'n'},
ca0e11aa 4720 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4721 {"string-dump", required_argument, 0, 'p'},
4722 {"relocated-dump", required_argument, 0, 'R'},
4723 {"relocs", no_argument, 0, 'r'},
4724 {"section-headers", no_argument, 0, 'S'},
4725 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4726 {"symbols", no_argument, 0, 's'},
4727 {"syms", no_argument, 0, 's'},
79bc120c
NC
4728 {"silent-truncation",no_argument, 0, 'T'},
4729 {"section-details", no_argument, 0, 't'},
09c11c86 4730 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4731 {"version-info", no_argument, 0, 'V'},
4732 {"version", no_argument, 0, 'v'},
4733 {"wide", no_argument, 0, 'W'},
b34976b6 4734 {"hex-dump", required_argument, 0, 'x'},
0e602686 4735 {"decompress", no_argument, 0, 'z'},
252b5132 4736
79bc120c
NC
4737 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4738 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4739 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4740 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4741 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4742 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4743 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4744 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4745 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4746 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4747#ifdef ENABLE_LIBCTF
d344b407 4748 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4749 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4750 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4751 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4752#endif
047c3dbf 4753 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4754
b34976b6 4755 {0, no_argument, 0, 0}
252b5132
RH
4756};
4757
4758static void
2cf0635d 4759usage (FILE * stream)
252b5132 4760{
92f01d61
JM
4761 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4762 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
4763 fprintf (stream, _(" Options are:\n"));
4764 fprintf (stream, _("\
4765 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
4766 fprintf (stream, _("\
4767 -h --file-header Display the ELF file header\n"));
4768 fprintf (stream, _("\
4769 -l --program-headers Display the program headers\n"));
4770 fprintf (stream, _("\
4771 --segments An alias for --program-headers\n"));
4772 fprintf (stream, _("\
4773 -S --section-headers Display the sections' header\n"));
4774 fprintf (stream, _("\
4775 --sections An alias for --section-headers\n"));
4776 fprintf (stream, _("\
4777 -g --section-groups Display the section groups\n"));
4778 fprintf (stream, _("\
4779 -t --section-details Display the section details\n"));
4780 fprintf (stream, _("\
4781 -e --headers Equivalent to: -h -l -S\n"));
4782 fprintf (stream, _("\
4783 -s --syms Display the symbol table\n"));
4784 fprintf (stream, _("\
4785 --symbols An alias for --syms\n"));
4786 fprintf (stream, _("\
4787 --dyn-syms Display the dynamic symbol table\n"));
4788 fprintf (stream, _("\
4789 --lto-syms Display LTO symbol tables\n"));
4790 fprintf (stream, _("\
047c3dbf
NL
4791 --sym-base=[0|8|10|16] \n\
4792 Force base for symbol sizes. The options are \n\
d6249f5f
AM
4793 mixed (the default), octal, decimal, hexadecimal.\n"));
4794 fprintf (stream, _("\
79bc120c
NC
4795 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4796 The STYLE, if specified, can be `auto' (the default),\n\
4797 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
d6249f5f
AM
4798 or `gnat'\n"));
4799 fprintf (stream, _("\
4800 --no-demangle Do not demangle low-level symbol names. (default)\n"));
4801 fprintf (stream, _("\
4802 --recurse-limit Enable a demangling recursion limit. (default)\n"));
4803 fprintf (stream, _("\
4804 --no-recurse-limit Disable a demangling recursion limit\n"));
4805 fprintf (stream, _("\
4806 -n --notes Display the core notes (if present)\n"));
4807 fprintf (stream, _("\
4808 -r --relocs Display the relocations (if present)\n"));
4809 fprintf (stream, _("\
4810 -u --unwind Display the unwind info (if present)\n"));
4811 fprintf (stream, _("\
4812 -d --dynamic Display the dynamic section (if present)\n"));
4813 fprintf (stream, _("\
4814 -V --version-info Display the version sections (if present)\n"));
4815 fprintf (stream, _("\
4816 -A --arch-specific Display architecture specific information (if any)\n"));
4817 fprintf (stream, _("\
4818 -c --archive-index Display the symbol/file index in an archive\n"));
4819 fprintf (stream, _("\
4820 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
4821 fprintf (stream, _("\
4822 -L --lint|--enable-checks\n\
4823 Display warning messages for possible problems\n"));
4824 fprintf (stream, _("\
09c11c86 4825 -x --hex-dump=<number|name>\n\
d6249f5f
AM
4826 Dump the contents of section <number|name> as bytes\n"));
4827 fprintf (stream, _("\
09c11c86 4828 -p --string-dump=<number|name>\n\
d6249f5f
AM
4829 Dump the contents of section <number|name> as strings\n"));
4830 fprintf (stream, _("\
cf13d699 4831 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
4832 Dump the relocated contents of section <number|name>\n"));
4833 fprintf (stream, _("\
4834 -z --decompress Decompress section before dumping it\n"));
4835 fprintf (stream, _("\
4836 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
4837 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
4838 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
4839 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
4840 U/=trace_info]\n\
4841 Display the contents of DWARF debug sections\n"));
4842 fprintf (stream, _("\
4843 -wk --debug-dump=links Display the contents of sections that link to separate\n\
4844 debuginfo files\n"));
4845 fprintf (stream, _("\
4846 -P --process-links Display the contents of non-debug sections in separate\n\
4847 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4848#if DEFAULT_FOR_FOLLOW_LINKS
4849 fprintf (stream, _("\
d6249f5f
AM
4850 -wK --debug-dump=follow-links\n\
4851 Follow links to separate debug info files (default)\n"));
4852 fprintf (stream, _("\
4853 -wN --debug-dump=no-follow-links\n\
4854 Do not follow links to separate debug info files\n"));
c46b7066
NC
4855#else
4856 fprintf (stream, _("\
d6249f5f
AM
4857 -wK --debug-dump=follow-links\n\
4858 Follow links to separate debug info files\n"));
4859 fprintf (stream, _("\
4860 -wN --debug-dump=no-follow-links\n\
4861 Do not follow links to separate debug info files\n\
4862 (default)\n"));
c46b7066 4863#endif
fd2f0033 4864 fprintf (stream, _("\
d6249f5f
AM
4865 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
4866 fprintf (stream, _("\
4867 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 4868#ifdef ENABLE_LIBCTF
7d9813f1 4869 fprintf (stream, _("\
d6249f5f
AM
4870 --ctf=<number|name> Display CTF info from section <number|name>\n"));
4871 fprintf (stream, _("\
80b56fad 4872 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 4873 fprintf (stream, _("\
7d9813f1 4874 --ctf-symbols=<number|name>\n\
d6249f5f
AM
4875 Use section <number|name> as the CTF external symtab\n"));
4876 fprintf (stream, _("\
7d9813f1 4877 --ctf-strings=<number|name>\n\
d6249f5f 4878 Use section <number|name> as the CTF external strtab\n"));
094e34f2 4879#endif
7d9813f1 4880
252b5132 4881#ifdef SUPPORT_DISASSEMBLY
92f01d61 4882 fprintf (stream, _("\
09c11c86
NC
4883 -i --instruction-dump=<number|name>\n\
4884 Disassemble the contents of section <number|name>\n"));
252b5132 4885#endif
92f01d61 4886 fprintf (stream, _("\
d6249f5f
AM
4887 -I --histogram Display histogram of bucket list lengths\n"));
4888 fprintf (stream, _("\
4889 -W --wide Allow output width to exceed 80 characters\n"));
4890 fprintf (stream, _("\
4891 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
4892 fprintf (stream, _("\
4893 @<file> Read options from <file>\n"));
4894 fprintf (stream, _("\
4895 -H --help Display this information\n"));
4896 fprintf (stream, _("\
8b53311e 4897 -v --version Display the version number of readelf\n"));
1118d252 4898
92f01d61
JM
4899 if (REPORT_BUGS_TO[0] && stream == stdout)
4900 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4901
92f01d61 4902 exit (stream == stdout ? 0 : 1);
252b5132
RH
4903}
4904
18bd398b
NC
4905/* Record the fact that the user wants the contents of section number
4906 SECTION to be displayed using the method(s) encoded as flags bits
4907 in TYPE. Note, TYPE can be zero if we are creating the array for
4908 the first time. */
4909
252b5132 4910static void
6431e409
AM
4911request_dump_bynumber (struct dump_data *dumpdata,
4912 unsigned int section, dump_type type)
252b5132 4913{
6431e409 4914 if (section >= dumpdata->num_dump_sects)
252b5132 4915 {
2cf0635d 4916 dump_type * new_dump_sects;
252b5132 4917
3f5e193b 4918 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4919 sizeof (* new_dump_sects));
252b5132
RH
4920
4921 if (new_dump_sects == NULL)
591a748a 4922 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4923 else
4924 {
6431e409 4925 if (dumpdata->dump_sects)
21b65bac
NC
4926 {
4927 /* Copy current flag settings. */
6431e409
AM
4928 memcpy (new_dump_sects, dumpdata->dump_sects,
4929 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4930
6431e409 4931 free (dumpdata->dump_sects);
21b65bac 4932 }
252b5132 4933
6431e409
AM
4934 dumpdata->dump_sects = new_dump_sects;
4935 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4936 }
4937 }
4938
6431e409
AM
4939 if (dumpdata->dump_sects)
4940 dumpdata->dump_sects[section] |= type;
252b5132
RH
4941}
4942
aef1f6d0
DJ
4943/* Request a dump by section name. */
4944
4945static void
2cf0635d 4946request_dump_byname (const char * section, dump_type type)
aef1f6d0 4947{
2cf0635d 4948 struct dump_list_entry * new_request;
aef1f6d0 4949
3f5e193b
NC
4950 new_request = (struct dump_list_entry *)
4951 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4952 if (!new_request)
591a748a 4953 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4954
4955 new_request->name = strdup (section);
4956 if (!new_request->name)
591a748a 4957 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4958
4959 new_request->type = type;
4960
4961 new_request->next = dump_sects_byname;
4962 dump_sects_byname = new_request;
4963}
4964
cf13d699 4965static inline void
6431e409 4966request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4967{
4968 int section;
4969 char * cp;
4970
015dc7e1 4971 do_dump = true;
cf13d699
NC
4972 section = strtoul (optarg, & cp, 0);
4973
4974 if (! *cp && section >= 0)
6431e409 4975 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4976 else
4977 request_dump_byname (optarg, type);
4978}
4979
252b5132 4980static void
6431e409 4981parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4982{
4983 int c;
4984
4985 if (argc < 2)
92f01d61 4986 usage (stderr);
252b5132
RH
4987
4988 while ((c = getopt_long
ca0e11aa 4989 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4990 {
252b5132
RH
4991 switch (c)
4992 {
4993 case 0:
4994 /* Long options. */
4995 break;
4996 case 'H':
92f01d61 4997 usage (stdout);
252b5132
RH
4998 break;
4999
5000 case 'a':
015dc7e1
AM
5001 do_syms = true;
5002 do_reloc = true;
5003 do_unwind = true;
5004 do_dynamic = true;
5005 do_header = true;
5006 do_sections = true;
5007 do_section_groups = true;
5008 do_segments = true;
5009 do_version = true;
5010 do_histogram = true;
5011 do_arch = true;
5012 do_notes = true;
252b5132 5013 break;
79bc120c 5014
f5842774 5015 case 'g':
015dc7e1 5016 do_section_groups = true;
f5842774 5017 break;
5477e8a0 5018 case 't':
595cf52e 5019 case 'N':
015dc7e1
AM
5020 do_sections = true;
5021 do_section_details = true;
595cf52e 5022 break;
252b5132 5023 case 'e':
015dc7e1
AM
5024 do_header = true;
5025 do_sections = true;
5026 do_segments = true;
252b5132 5027 break;
a952a375 5028 case 'A':
015dc7e1 5029 do_arch = true;
a952a375 5030 break;
252b5132 5031 case 'D':
015dc7e1 5032 do_using_dynamic = true;
252b5132
RH
5033 break;
5034 case 'r':
015dc7e1 5035 do_reloc = true;
252b5132 5036 break;
4d6ed7c8 5037 case 'u':
015dc7e1 5038 do_unwind = true;
4d6ed7c8 5039 break;
252b5132 5040 case 'h':
015dc7e1 5041 do_header = true;
252b5132
RH
5042 break;
5043 case 'l':
015dc7e1 5044 do_segments = true;
252b5132
RH
5045 break;
5046 case 's':
015dc7e1 5047 do_syms = true;
252b5132
RH
5048 break;
5049 case 'S':
015dc7e1 5050 do_sections = true;
252b5132
RH
5051 break;
5052 case 'd':
015dc7e1 5053 do_dynamic = true;
252b5132 5054 break;
a952a375 5055 case 'I':
015dc7e1 5056 do_histogram = true;
a952a375 5057 break;
779fe533 5058 case 'n':
015dc7e1 5059 do_notes = true;
779fe533 5060 break;
4145f1d5 5061 case 'c':
015dc7e1 5062 do_archive_index = true;
4145f1d5 5063 break;
1b513401 5064 case 'L':
015dc7e1 5065 do_checks = true;
1b513401 5066 break;
ca0e11aa 5067 case 'P':
015dc7e1
AM
5068 process_links = true;
5069 do_follow_links = true;
ca0e11aa 5070 break;
252b5132 5071 case 'x':
6431e409 5072 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5073 break;
09c11c86 5074 case 'p':
6431e409 5075 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5076 break;
5077 case 'R':
6431e409 5078 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5079 break;
0e602686 5080 case 'z':
015dc7e1 5081 decompress_dumps = true;
0e602686 5082 break;
252b5132 5083 case 'w':
015dc7e1 5084 do_dump = true;
0f03783c 5085 if (optarg == NULL)
613ff48b 5086 {
015dc7e1 5087 do_debugging = true;
613ff48b
CC
5088 dwarf_select_sections_all ();
5089 }
252b5132
RH
5090 else
5091 {
015dc7e1 5092 do_debugging = false;
4cb93e3b 5093 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5094 }
5095 break;
2979dc34 5096 case OPTION_DEBUG_DUMP:
015dc7e1 5097 do_dump = true;
0f03783c 5098 if (optarg == NULL)
d6249f5f
AM
5099 {
5100 do_debugging = true;
5101 dwarf_select_sections_all ();
5102 }
2979dc34
JJ
5103 else
5104 {
015dc7e1 5105 do_debugging = false;
4cb93e3b 5106 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5107 }
5108 break;
fd2f0033
TT
5109 case OPTION_DWARF_DEPTH:
5110 {
5111 char *cp;
5112
5113 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5114 }
5115 break;
5116 case OPTION_DWARF_START:
5117 {
5118 char *cp;
5119
5120 dwarf_start_die = strtoul (optarg, & cp, 0);
5121 }
5122 break;
4723351a 5123 case OPTION_DWARF_CHECK:
015dc7e1 5124 dwarf_check = true;
4723351a 5125 break;
7d9813f1 5126 case OPTION_CTF_DUMP:
015dc7e1 5127 do_ctf = true;
6431e409 5128 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5129 break;
5130 case OPTION_CTF_SYMBOLS:
df16e041 5131 free (dump_ctf_symtab_name);
7d9813f1
NA
5132 dump_ctf_symtab_name = strdup (optarg);
5133 break;
5134 case OPTION_CTF_STRINGS:
df16e041 5135 free (dump_ctf_strtab_name);
7d9813f1
NA
5136 dump_ctf_strtab_name = strdup (optarg);
5137 break;
5138 case OPTION_CTF_PARENT:
df16e041 5139 free (dump_ctf_parent_name);
7d9813f1
NA
5140 dump_ctf_parent_name = strdup (optarg);
5141 break;
2c610e4b 5142 case OPTION_DYN_SYMS:
015dc7e1 5143 do_dyn_syms = true;
2c610e4b 5144 break;
0f03783c 5145 case OPTION_LTO_SYMS:
015dc7e1 5146 do_lto_syms = true;
0f03783c 5147 break;
252b5132
RH
5148#ifdef SUPPORT_DISASSEMBLY
5149 case 'i':
6431e409 5150 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5151 break;
252b5132
RH
5152#endif
5153 case 'v':
5154 print_version (program_name);
5155 break;
5156 case 'V':
015dc7e1 5157 do_version = true;
252b5132 5158 break;
d974e256 5159 case 'W':
015dc7e1 5160 do_wide = true;
d974e256 5161 break;
0942c7ab 5162 case 'T':
015dc7e1 5163 do_not_show_symbol_truncation = true;
0942c7ab 5164 break;
79bc120c 5165 case 'C':
015dc7e1 5166 do_demangle = true;
79bc120c
NC
5167 if (optarg != NULL)
5168 {
5169 enum demangling_styles style;
5170
5171 style = cplus_demangle_name_to_style (optarg);
5172 if (style == unknown_demangling)
5173 error (_("unknown demangling style `%s'"), optarg);
5174
5175 cplus_demangle_set_style (style);
5176 }
5177 break;
5178 case OPTION_NO_DEMANGLING:
015dc7e1 5179 do_demangle = false;
79bc120c
NC
5180 break;
5181 case OPTION_RECURSE_LIMIT:
5182 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5183 break;
5184 case OPTION_NO_RECURSE_LIMIT:
5185 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5186 break;
5187 case OPTION_WITH_SYMBOL_VERSIONS:
5188 /* Ignored for backward compatibility. */
5189 break;
b9e920ec 5190
047c3dbf
NL
5191 case OPTION_SYM_BASE:
5192 sym_base = 0;
5193 if (optarg != NULL)
5194 {
5195 sym_base = strtoul (optarg, NULL, 0);
5196 switch (sym_base)
5197 {
5198 case 0:
5199 case 8:
5200 case 10:
5201 case 16:
5202 break;
5203
5204 default:
5205 sym_base = 0;
5206 break;
5207 }
5208 }
5209 break;
5210
252b5132 5211 default:
252b5132
RH
5212 /* xgettext:c-format */
5213 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5214 /* Fall through. */
252b5132 5215 case '?':
92f01d61 5216 usage (stderr);
252b5132
RH
5217 }
5218 }
5219
4d6ed7c8 5220 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5221 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5222 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5223 && !do_section_groups && !do_archive_index
0f03783c 5224 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5225 {
5226 if (do_checks)
5227 {
015dc7e1
AM
5228 check_all = true;
5229 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5230 do_segments = do_header = do_dump = do_version = true;
5231 do_histogram = do_debugging = do_arch = do_notes = true;
5232 do_section_groups = do_archive_index = do_dyn_syms = true;
5233 do_lto_syms = true;
1b513401
NC
5234 }
5235 else
5236 usage (stderr);
5237 }
252b5132
RH
5238}
5239
5240static const char *
d3ba0551 5241get_elf_class (unsigned int elf_class)
252b5132 5242{
b34976b6 5243 static char buff[32];
103f02d3 5244
252b5132
RH
5245 switch (elf_class)
5246 {
5247 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5248 case ELFCLASS32: return "ELF32";
5249 case ELFCLASS64: return "ELF64";
ab5e7794 5250 default:
e9e44622 5251 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5252 return buff;
252b5132
RH
5253 }
5254}
5255
5256static const char *
d3ba0551 5257get_data_encoding (unsigned int encoding)
252b5132 5258{
b34976b6 5259 static char buff[32];
103f02d3 5260
252b5132
RH
5261 switch (encoding)
5262 {
5263 case ELFDATANONE: return _("none");
33c63f9d
CM
5264 case ELFDATA2LSB: return _("2's complement, little endian");
5265 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5266 default:
e9e44622 5267 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5268 return buff;
252b5132
RH
5269 }
5270}
5271
dda8d76d 5272/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5273
015dc7e1 5274static bool
dda8d76d 5275process_file_header (Filedata * filedata)
252b5132 5276{
dda8d76d
NC
5277 Elf_Internal_Ehdr * header = & filedata->file_header;
5278
5279 if ( header->e_ident[EI_MAG0] != ELFMAG0
5280 || header->e_ident[EI_MAG1] != ELFMAG1
5281 || header->e_ident[EI_MAG2] != ELFMAG2
5282 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5283 {
5284 error
5285 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5286 return false;
252b5132
RH
5287 }
5288
ca0e11aa
NC
5289 if (! filedata->is_separate)
5290 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5291
252b5132
RH
5292 if (do_header)
5293 {
32ec8896 5294 unsigned i;
252b5132 5295
ca0e11aa
NC
5296 if (filedata->is_separate)
5297 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5298 else
5299 printf (_("ELF Header:\n"));
252b5132 5300 printf (_(" Magic: "));
b34976b6 5301 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5302 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5303 printf ("\n");
5304 printf (_(" Class: %s\n"),
dda8d76d 5305 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5306 printf (_(" Data: %s\n"),
dda8d76d 5307 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5308 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5309 header->e_ident[EI_VERSION],
5310 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5311 ? _(" (current)")
dda8d76d 5312 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5313 ? _(" <unknown>")
789be9f7 5314 : "")));
252b5132 5315 printf (_(" OS/ABI: %s\n"),
dda8d76d 5316 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5317 printf (_(" ABI Version: %d\n"),
dda8d76d 5318 header->e_ident[EI_ABIVERSION]);
252b5132 5319 printf (_(" Type: %s\n"),
93df3340 5320 get_file_type (filedata));
252b5132 5321 printf (_(" Machine: %s\n"),
dda8d76d 5322 get_machine_name (header->e_machine));
252b5132 5323 printf (_(" Version: 0x%lx\n"),
e8a64888 5324 header->e_version);
76da6bbe 5325
f7a99963 5326 printf (_(" Entry point address: "));
e8a64888 5327 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5328 printf (_("\n Start of program headers: "));
e8a64888 5329 print_vma (header->e_phoff, DEC);
f7a99963 5330 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5331 print_vma (header->e_shoff, DEC);
f7a99963 5332 printf (_(" (bytes into file)\n"));
76da6bbe 5333
252b5132 5334 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5335 header->e_flags,
dda8d76d 5336 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5337 printf (_(" Size of this header: %u (bytes)\n"),
5338 header->e_ehsize);
5339 printf (_(" Size of program headers: %u (bytes)\n"),
5340 header->e_phentsize);
5341 printf (_(" Number of program headers: %u"),
5342 header->e_phnum);
dda8d76d
NC
5343 if (filedata->section_headers != NULL
5344 && header->e_phnum == PN_XNUM
5345 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5346 {
5347 header->e_phnum = filedata->section_headers[0].sh_info;
5348 printf (" (%u)", header->e_phnum);
5349 }
2046a35d 5350 putc ('\n', stdout);
e8a64888
AM
5351 printf (_(" Size of section headers: %u (bytes)\n"),
5352 header->e_shentsize);
5353 printf (_(" Number of section headers: %u"),
5354 header->e_shnum);
dda8d76d 5355 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5356 {
5357 header->e_shnum = filedata->section_headers[0].sh_size;
5358 printf (" (%u)", header->e_shnum);
5359 }
560f3c1c 5360 putc ('\n', stdout);
e8a64888
AM
5361 printf (_(" Section header string table index: %u"),
5362 header->e_shstrndx);
dda8d76d
NC
5363 if (filedata->section_headers != NULL
5364 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5365 {
5366 header->e_shstrndx = filedata->section_headers[0].sh_link;
5367 printf (" (%u)", header->e_shstrndx);
5368 }
5369 if (header->e_shstrndx != SHN_UNDEF
5370 && header->e_shstrndx >= header->e_shnum)
5371 {
5372 header->e_shstrndx = SHN_UNDEF;
5373 printf (_(" <corrupt: out of range>"));
5374 }
560f3c1c
AM
5375 putc ('\n', stdout);
5376 }
5377
dda8d76d 5378 if (filedata->section_headers != NULL)
560f3c1c 5379 {
dda8d76d
NC
5380 if (header->e_phnum == PN_XNUM
5381 && filedata->section_headers[0].sh_info != 0)
5382 header->e_phnum = filedata->section_headers[0].sh_info;
5383 if (header->e_shnum == SHN_UNDEF)
5384 header->e_shnum = filedata->section_headers[0].sh_size;
5385 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5386 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5387 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5388 header->e_shstrndx = SHN_UNDEF;
252b5132 5389 }
103f02d3 5390
015dc7e1 5391 return true;
9ea033b2
NC
5392}
5393
dda8d76d
NC
5394/* Read in the program headers from FILEDATA and store them in PHEADERS.
5395 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5396
015dc7e1 5397static bool
dda8d76d 5398get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5399{
2cf0635d
NC
5400 Elf32_External_Phdr * phdrs;
5401 Elf32_External_Phdr * external;
5402 Elf_Internal_Phdr * internal;
b34976b6 5403 unsigned int i;
dda8d76d
NC
5404 unsigned int size = filedata->file_header.e_phentsize;
5405 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5406
5407 /* PR binutils/17531: Cope with unexpected section header sizes. */
5408 if (size == 0 || num == 0)
015dc7e1 5409 return false;
e0a31db1
NC
5410 if (size < sizeof * phdrs)
5411 {
5412 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5413 return false;
e0a31db1
NC
5414 }
5415 if (size > sizeof * phdrs)
5416 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5417
dda8d76d 5418 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5419 size, num, _("program headers"));
5420 if (phdrs == NULL)
015dc7e1 5421 return false;
9ea033b2 5422
91d6fa6a 5423 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5424 i < filedata->file_header.e_phnum;
b34976b6 5425 i++, internal++, external++)
252b5132 5426 {
9ea033b2
NC
5427 internal->p_type = BYTE_GET (external->p_type);
5428 internal->p_offset = BYTE_GET (external->p_offset);
5429 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5430 internal->p_paddr = BYTE_GET (external->p_paddr);
5431 internal->p_filesz = BYTE_GET (external->p_filesz);
5432 internal->p_memsz = BYTE_GET (external->p_memsz);
5433 internal->p_flags = BYTE_GET (external->p_flags);
5434 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5435 }
5436
9ea033b2 5437 free (phdrs);
015dc7e1 5438 return true;
252b5132
RH
5439}
5440
dda8d76d
NC
5441/* Read in the program headers from FILEDATA and store them in PHEADERS.
5442 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5443
015dc7e1 5444static bool
dda8d76d 5445get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5446{
2cf0635d
NC
5447 Elf64_External_Phdr * phdrs;
5448 Elf64_External_Phdr * external;
5449 Elf_Internal_Phdr * internal;
b34976b6 5450 unsigned int i;
dda8d76d
NC
5451 unsigned int size = filedata->file_header.e_phentsize;
5452 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5453
5454 /* PR binutils/17531: Cope with unexpected section header sizes. */
5455 if (size == 0 || num == 0)
015dc7e1 5456 return false;
e0a31db1
NC
5457 if (size < sizeof * phdrs)
5458 {
5459 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5460 return false;
e0a31db1
NC
5461 }
5462 if (size > sizeof * phdrs)
5463 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5464
dda8d76d 5465 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5466 size, num, _("program headers"));
a6e9f9df 5467 if (!phdrs)
015dc7e1 5468 return false;
9ea033b2 5469
91d6fa6a 5470 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5471 i < filedata->file_header.e_phnum;
b34976b6 5472 i++, internal++, external++)
9ea033b2
NC
5473 {
5474 internal->p_type = BYTE_GET (external->p_type);
5475 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5476 internal->p_offset = BYTE_GET (external->p_offset);
5477 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5478 internal->p_paddr = BYTE_GET (external->p_paddr);
5479 internal->p_filesz = BYTE_GET (external->p_filesz);
5480 internal->p_memsz = BYTE_GET (external->p_memsz);
5481 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5482 }
5483
5484 free (phdrs);
015dc7e1 5485 return true;
9ea033b2 5486}
252b5132 5487
32ec8896 5488/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5489
015dc7e1 5490static bool
dda8d76d 5491get_program_headers (Filedata * filedata)
d93f0186 5492{
2cf0635d 5493 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5494
5495 /* Check cache of prior read. */
dda8d76d 5496 if (filedata->program_headers != NULL)
015dc7e1 5497 return true;
d93f0186 5498
82156ab7
NC
5499 /* Be kind to memory checkers by looking for
5500 e_phnum values which we know must be invalid. */
dda8d76d 5501 if (filedata->file_header.e_phnum
82156ab7 5502 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5503 >= filedata->file_size)
82156ab7
NC
5504 {
5505 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5506 filedata->file_header.e_phnum);
015dc7e1 5507 return false;
82156ab7 5508 }
d93f0186 5509
dda8d76d 5510 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5511 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5512 if (phdrs == NULL)
5513 {
8b73c356 5514 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5515 filedata->file_header.e_phnum);
015dc7e1 5516 return false;
d93f0186
NC
5517 }
5518
5519 if (is_32bit_elf
dda8d76d
NC
5520 ? get_32bit_program_headers (filedata, phdrs)
5521 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5522 {
dda8d76d 5523 filedata->program_headers = phdrs;
015dc7e1 5524 return true;
d93f0186
NC
5525 }
5526
5527 free (phdrs);
015dc7e1 5528 return false;
d93f0186
NC
5529}
5530
93df3340 5531/* Print program header info and locate dynamic section. */
2f62977e 5532
93df3340 5533static void
dda8d76d 5534process_program_headers (Filedata * filedata)
252b5132 5535{
2cf0635d 5536 Elf_Internal_Phdr * segment;
b34976b6 5537 unsigned int i;
1a9ccd70 5538 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5539
dda8d76d 5540 if (filedata->file_header.e_phnum == 0)
252b5132 5541 {
82f2dbf7 5542 /* PR binutils/12467. */
dda8d76d 5543 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5544 warn (_("possibly corrupt ELF header - it has a non-zero program"
5545 " header offset, but no program headers\n"));
82f2dbf7 5546 else if (do_segments)
ca0e11aa
NC
5547 {
5548 if (filedata->is_separate)
5549 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5550 filedata->file_name);
5551 else
5552 printf (_("\nThere are no program headers in this file.\n"));
5553 }
93df3340 5554 goto no_headers;
252b5132
RH
5555 }
5556
5557 if (do_segments && !do_header)
5558 {
ca0e11aa
NC
5559 if (filedata->is_separate)
5560 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5561 filedata->file_name, get_file_type (filedata));
ca0e11aa 5562 else
93df3340 5563 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5564 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5565 printf (ngettext ("There is %d program header, starting at offset %s\n",
5566 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5567 filedata->file_header.e_phnum),
5568 filedata->file_header.e_phnum,
5569 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5570 }
5571
dda8d76d 5572 if (! get_program_headers (filedata))
93df3340 5573 goto no_headers;
103f02d3 5574
252b5132
RH
5575 if (do_segments)
5576 {
dda8d76d 5577 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5578 printf (_("\nProgram Headers:\n"));
5579 else
5580 printf (_("\nProgram Headers:\n"));
76da6bbe 5581
f7a99963
NC
5582 if (is_32bit_elf)
5583 printf
5584 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5585 else if (do_wide)
5586 printf
5587 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5588 else
5589 {
5590 printf
5591 (_(" Type Offset VirtAddr PhysAddr\n"));
5592 printf
5593 (_(" FileSiz MemSiz Flags Align\n"));
5594 }
252b5132
RH
5595 }
5596
93df3340
AM
5597 unsigned long dynamic_addr = 0;
5598 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5599 for (i = 0, segment = filedata->program_headers;
5600 i < filedata->file_header.e_phnum;
b34976b6 5601 i++, segment++)
252b5132
RH
5602 {
5603 if (do_segments)
5604 {
dda8d76d 5605 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5606
5607 if (is_32bit_elf)
5608 {
5609 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5610 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5611 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5612 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5613 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5614 printf ("%c%c%c ",
5615 (segment->p_flags & PF_R ? 'R' : ' '),
5616 (segment->p_flags & PF_W ? 'W' : ' '),
5617 (segment->p_flags & PF_X ? 'E' : ' '));
5618 printf ("%#lx", (unsigned long) segment->p_align);
5619 }
d974e256
JJ
5620 else if (do_wide)
5621 {
5622 if ((unsigned long) segment->p_offset == segment->p_offset)
5623 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5624 else
5625 {
5626 print_vma (segment->p_offset, FULL_HEX);
5627 putchar (' ');
5628 }
5629
5630 print_vma (segment->p_vaddr, FULL_HEX);
5631 putchar (' ');
5632 print_vma (segment->p_paddr, FULL_HEX);
5633 putchar (' ');
5634
5635 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5636 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5637 else
5638 {
5639 print_vma (segment->p_filesz, FULL_HEX);
5640 putchar (' ');
5641 }
5642
5643 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5644 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5645 else
5646 {
f48e6c45 5647 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5648 }
5649
5650 printf (" %c%c%c ",
5651 (segment->p_flags & PF_R ? 'R' : ' '),
5652 (segment->p_flags & PF_W ? 'W' : ' '),
5653 (segment->p_flags & PF_X ? 'E' : ' '));
5654
5655 if ((unsigned long) segment->p_align == segment->p_align)
5656 printf ("%#lx", (unsigned long) segment->p_align);
5657 else
5658 {
5659 print_vma (segment->p_align, PREFIX_HEX);
5660 }
5661 }
f7a99963
NC
5662 else
5663 {
5664 print_vma (segment->p_offset, FULL_HEX);
5665 putchar (' ');
5666 print_vma (segment->p_vaddr, FULL_HEX);
5667 putchar (' ');
5668 print_vma (segment->p_paddr, FULL_HEX);
5669 printf ("\n ");
5670 print_vma (segment->p_filesz, FULL_HEX);
5671 putchar (' ');
5672 print_vma (segment->p_memsz, FULL_HEX);
5673 printf (" %c%c%c ",
5674 (segment->p_flags & PF_R ? 'R' : ' '),
5675 (segment->p_flags & PF_W ? 'W' : ' '),
5676 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5677 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5678 }
252b5132 5679
1a9ccd70
NC
5680 putc ('\n', stdout);
5681 }
f54498b4 5682
252b5132
RH
5683 switch (segment->p_type)
5684 {
1a9ccd70 5685 case PT_LOAD:
502d895c
NC
5686#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5687 required by the ELF standard, several programs, including the Linux
5688 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5689 if (previous_load
5690 && previous_load->p_vaddr > segment->p_vaddr)
5691 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5692#endif
1a9ccd70
NC
5693 if (segment->p_memsz < segment->p_filesz)
5694 error (_("the segment's file size is larger than its memory size\n"));
5695 previous_load = segment;
5696 break;
5697
5698 case PT_PHDR:
5699 /* PR 20815 - Verify that the program header is loaded into memory. */
5700 if (i > 0 && previous_load != NULL)
5701 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5702 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5703 {
5704 unsigned int j;
5705
dda8d76d 5706 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5707 {
5708 Elf_Internal_Phdr *load = filedata->program_headers + j;
5709 if (load->p_type == PT_LOAD
5710 && load->p_offset <= segment->p_offset
5711 && (load->p_offset + load->p_filesz
5712 >= segment->p_offset + segment->p_filesz)
5713 && load->p_vaddr <= segment->p_vaddr
5714 && (load->p_vaddr + load->p_filesz
5715 >= segment->p_vaddr + segment->p_filesz))
5716 break;
5717 }
dda8d76d 5718 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5719 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5720 }
5721 break;
5722
252b5132 5723 case PT_DYNAMIC:
93df3340 5724 if (dynamic_addr)
252b5132
RH
5725 error (_("more than one dynamic segment\n"));
5726
20737c13
AM
5727 /* By default, assume that the .dynamic section is the first
5728 section in the DYNAMIC segment. */
93df3340
AM
5729 dynamic_addr = segment->p_offset;
5730 dynamic_size = segment->p_filesz;
20737c13 5731
b2d38a17
NC
5732 /* Try to locate the .dynamic section. If there is
5733 a section header table, we can easily locate it. */
dda8d76d 5734 if (filedata->section_headers != NULL)
b2d38a17 5735 {
2cf0635d 5736 Elf_Internal_Shdr * sec;
b2d38a17 5737
dda8d76d 5738 sec = find_section (filedata, ".dynamic");
89fac5e3 5739 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5740 {
93df3340
AM
5741 /* A corresponding .dynamic section is expected, but on
5742 IA-64/OpenVMS it is OK for it to be missing. */
5743 if (!is_ia64_vms (filedata))
5744 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5745 break;
5746 }
5747
42bb2e33 5748 if (sec->sh_type == SHT_NOBITS)
20737c13 5749 {
93df3340
AM
5750 dynamic_addr = 0;
5751 dynamic_size = 0;
20737c13
AM
5752 break;
5753 }
42bb2e33 5754
93df3340
AM
5755 dynamic_addr = sec->sh_offset;
5756 dynamic_size = sec->sh_size;
b2d38a17 5757
8ac10c5b
L
5758 /* The PT_DYNAMIC segment, which is used by the run-time
5759 loader, should exactly match the .dynamic section. */
5760 if (do_checks
93df3340
AM
5761 && (dynamic_addr != segment->p_offset
5762 || dynamic_size != segment->p_filesz))
8ac10c5b
L
5763 warn (_("\
5764the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5765 }
39e224f6
MW
5766
5767 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5768 segment. Check this after matching against the section headers
5769 so we don't warn on debuginfo file (which have NOBITS .dynamic
5770 sections). */
93df3340
AM
5771 if (dynamic_addr > filedata->file_size
5772 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
5773 {
5774 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
5775 dynamic_addr = 0;
5776 dynamic_size = 0;
39e224f6 5777 }
252b5132
RH
5778 break;
5779
5780 case PT_INTERP:
13acb58d
AM
5781 if (segment->p_offset >= filedata->file_size
5782 || segment->p_filesz > filedata->file_size - segment->p_offset
5783 || segment->p_filesz - 1 >= (size_t) -2
5784 || fseek (filedata->handle,
5785 filedata->archive_file_offset + (long) segment->p_offset,
5786 SEEK_SET))
252b5132
RH
5787 error (_("Unable to find program interpreter name\n"));
5788 else
5789 {
13acb58d
AM
5790 size_t len = segment->p_filesz;
5791 free (filedata->program_interpreter);
5792 filedata->program_interpreter = xmalloc (len + 1);
5793 len = fread (filedata->program_interpreter, 1, len,
5794 filedata->handle);
5795 filedata->program_interpreter[len] = 0;
252b5132
RH
5796
5797 if (do_segments)
f54498b4 5798 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5799 filedata->program_interpreter);
252b5132
RH
5800 }
5801 break;
5802 }
252b5132
RH
5803 }
5804
dda8d76d
NC
5805 if (do_segments
5806 && filedata->section_headers != NULL
5807 && filedata->string_table != NULL)
252b5132
RH
5808 {
5809 printf (_("\n Section to Segment mapping:\n"));
5810 printf (_(" Segment Sections...\n"));
5811
dda8d76d 5812 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5813 {
9ad5cbcf 5814 unsigned int j;
2cf0635d 5815 Elf_Internal_Shdr * section;
252b5132 5816
dda8d76d
NC
5817 segment = filedata->program_headers + i;
5818 section = filedata->section_headers + 1;
252b5132
RH
5819
5820 printf (" %2.2d ", i);
5821
dda8d76d 5822 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5823 {
f4638467
AM
5824 if (!ELF_TBSS_SPECIAL (section, segment)
5825 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5826 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5827 }
5828
5829 putc ('\n',stdout);
5830 }
5831 }
5832
93df3340
AM
5833 filedata->dynamic_addr = dynamic_addr;
5834 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
5835 return;
5836
5837 no_headers:
5838 filedata->dynamic_addr = 0;
5839 filedata->dynamic_size = 1;
252b5132
RH
5840}
5841
5842
d93f0186
NC
5843/* Find the file offset corresponding to VMA by using the program headers. */
5844
5845static long
dda8d76d 5846offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5847{
2cf0635d 5848 Elf_Internal_Phdr * seg;
d93f0186 5849
dda8d76d 5850 if (! get_program_headers (filedata))
d93f0186
NC
5851 {
5852 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5853 return (long) vma;
5854 }
5855
dda8d76d
NC
5856 for (seg = filedata->program_headers;
5857 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5858 ++seg)
5859 {
5860 if (seg->p_type != PT_LOAD)
5861 continue;
5862
5863 if (vma >= (seg->p_vaddr & -seg->p_align)
5864 && vma + size <= seg->p_vaddr + seg->p_filesz)
5865 return vma - seg->p_vaddr + seg->p_offset;
5866 }
5867
5868 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5869 (unsigned long) vma);
d93f0186
NC
5870 return (long) vma;
5871}
5872
5873
dda8d76d
NC
5874/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5875 If PROBE is true, this is just a probe and we do not generate any error
5876 messages if the load fails. */
049b0c3a 5877
015dc7e1
AM
5878static bool
5879get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5880{
2cf0635d
NC
5881 Elf32_External_Shdr * shdrs;
5882 Elf_Internal_Shdr * internal;
dda8d76d
NC
5883 unsigned int i;
5884 unsigned int size = filedata->file_header.e_shentsize;
5885 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5886
5887 /* PR binutils/17531: Cope with unexpected section header sizes. */
5888 if (size == 0 || num == 0)
015dc7e1 5889 return false;
049b0c3a
NC
5890 if (size < sizeof * shdrs)
5891 {
5892 if (! probe)
5893 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5894 return false;
049b0c3a
NC
5895 }
5896 if (!probe && size > sizeof * shdrs)
5897 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5898
dda8d76d 5899 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5900 size, num,
5901 probe ? NULL : _("section headers"));
5902 if (shdrs == NULL)
015dc7e1 5903 return false;
252b5132 5904
dda8d76d
NC
5905 filedata->section_headers = (Elf_Internal_Shdr *)
5906 cmalloc (num, sizeof (Elf_Internal_Shdr));
5907 if (filedata->section_headers == NULL)
252b5132 5908 {
049b0c3a 5909 if (!probe)
8b73c356 5910 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5911 free (shdrs);
015dc7e1 5912 return false;
252b5132
RH
5913 }
5914
dda8d76d 5915 for (i = 0, internal = filedata->section_headers;
560f3c1c 5916 i < num;
b34976b6 5917 i++, internal++)
252b5132
RH
5918 {
5919 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5920 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5921 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5922 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5923 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5924 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5925 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5926 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5927 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5928 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5929 if (!probe && internal->sh_link > num)
5930 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5931 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5932 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5933 }
5934
5935 free (shdrs);
015dc7e1 5936 return true;
252b5132
RH
5937}
5938
dda8d76d
NC
5939/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5940
015dc7e1
AM
5941static bool
5942get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5943{
dda8d76d
NC
5944 Elf64_External_Shdr * shdrs;
5945 Elf_Internal_Shdr * internal;
5946 unsigned int i;
5947 unsigned int size = filedata->file_header.e_shentsize;
5948 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5949
5950 /* PR binutils/17531: Cope with unexpected section header sizes. */
5951 if (size == 0 || num == 0)
015dc7e1 5952 return false;
dda8d76d 5953
049b0c3a
NC
5954 if (size < sizeof * shdrs)
5955 {
5956 if (! probe)
5957 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5958 return false;
049b0c3a 5959 }
dda8d76d 5960
049b0c3a
NC
5961 if (! probe && size > sizeof * shdrs)
5962 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5963
dda8d76d
NC
5964 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5965 filedata->file_header.e_shoff,
049b0c3a
NC
5966 size, num,
5967 probe ? NULL : _("section headers"));
5968 if (shdrs == NULL)
015dc7e1 5969 return false;
9ea033b2 5970
dda8d76d
NC
5971 filedata->section_headers = (Elf_Internal_Shdr *)
5972 cmalloc (num, sizeof (Elf_Internal_Shdr));
5973 if (filedata->section_headers == NULL)
9ea033b2 5974 {
049b0c3a 5975 if (! probe)
8b73c356 5976 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5977 free (shdrs);
015dc7e1 5978 return false;
9ea033b2
NC
5979 }
5980
dda8d76d 5981 for (i = 0, internal = filedata->section_headers;
560f3c1c 5982 i < num;
b34976b6 5983 i++, internal++)
9ea033b2
NC
5984 {
5985 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5986 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5987 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5988 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5989 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5990 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5991 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5992 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5993 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5994 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5995 if (!probe && internal->sh_link > num)
5996 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5997 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5998 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5999 }
6000
6001 free (shdrs);
015dc7e1 6002 return true;
9ea033b2
NC
6003}
6004
4de91c10
AM
6005static bool
6006get_section_headers (Filedata *filedata, bool probe)
6007{
6008 if (filedata->section_headers != NULL)
6009 return true;
6010
4de91c10
AM
6011 if (is_32bit_elf)
6012 return get_32bit_section_headers (filedata, probe);
6013 else
6014 return get_64bit_section_headers (filedata, probe);
6015}
6016
252b5132 6017static Elf_Internal_Sym *
dda8d76d
NC
6018get_32bit_elf_symbols (Filedata * filedata,
6019 Elf_Internal_Shdr * section,
6020 unsigned long * num_syms_return)
252b5132 6021{
ba5cdace 6022 unsigned long number = 0;
dd24e3da 6023 Elf32_External_Sym * esyms = NULL;
ba5cdace 6024 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6025 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6026 Elf_Internal_Sym * psym;
b34976b6 6027 unsigned int j;
e3d39609 6028 elf_section_list * entry;
252b5132 6029
c9c1d674
EG
6030 if (section->sh_size == 0)
6031 {
6032 if (num_syms_return != NULL)
6033 * num_syms_return = 0;
6034 return NULL;
6035 }
6036
dd24e3da 6037 /* Run some sanity checks first. */
c9c1d674 6038 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6039 {
c9c1d674 6040 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6041 printable_section_name (filedata, section),
6042 (unsigned long) section->sh_entsize);
ba5cdace 6043 goto exit_point;
dd24e3da
NC
6044 }
6045
dda8d76d 6046 if (section->sh_size > filedata->file_size)
f54498b4
NC
6047 {
6048 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6049 printable_section_name (filedata, section),
6050 (unsigned long) section->sh_size);
f54498b4
NC
6051 goto exit_point;
6052 }
6053
dd24e3da
NC
6054 number = section->sh_size / section->sh_entsize;
6055
6056 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6057 {
c9c1d674 6058 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6059 (unsigned long) section->sh_size,
dda8d76d 6060 printable_section_name (filedata, section),
8066deb1 6061 (unsigned long) section->sh_entsize);
ba5cdace 6062 goto exit_point;
dd24e3da
NC
6063 }
6064
dda8d76d 6065 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6066 section->sh_size, _("symbols"));
dd24e3da 6067 if (esyms == NULL)
ba5cdace 6068 goto exit_point;
252b5132 6069
e3d39609 6070 shndx = NULL;
978c4450 6071 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6072 {
6073 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6074 continue;
6075
6076 if (shndx != NULL)
6077 {
6078 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6079 free (shndx);
6080 }
6081
6082 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6083 entry->hdr->sh_offset,
6084 1, entry->hdr->sh_size,
6085 _("symbol table section indices"));
6086 if (shndx == NULL)
6087 goto exit_point;
6088
6089 /* PR17531: file: heap-buffer-overflow */
6090 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6091 {
6092 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6093 printable_section_name (filedata, entry->hdr),
6094 (unsigned long) entry->hdr->sh_size,
6095 (unsigned long) section->sh_size);
6096 goto exit_point;
c9c1d674 6097 }
e3d39609 6098 }
9ad5cbcf 6099
3f5e193b 6100 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6101
6102 if (isyms == NULL)
6103 {
8b73c356
NC
6104 error (_("Out of memory reading %lu symbols\n"),
6105 (unsigned long) number);
dd24e3da 6106 goto exit_point;
252b5132
RH
6107 }
6108
dd24e3da 6109 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6110 {
6111 psym->st_name = BYTE_GET (esyms[j].st_name);
6112 psym->st_value = BYTE_GET (esyms[j].st_value);
6113 psym->st_size = BYTE_GET (esyms[j].st_size);
6114 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6115 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6116 psym->st_shndx
6117 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6118 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6119 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6120 psym->st_info = BYTE_GET (esyms[j].st_info);
6121 psym->st_other = BYTE_GET (esyms[j].st_other);
6122 }
6123
dd24e3da 6124 exit_point:
e3d39609
NC
6125 free (shndx);
6126 free (esyms);
252b5132 6127
ba5cdace
NC
6128 if (num_syms_return != NULL)
6129 * num_syms_return = isyms == NULL ? 0 : number;
6130
252b5132
RH
6131 return isyms;
6132}
6133
9ea033b2 6134static Elf_Internal_Sym *
dda8d76d
NC
6135get_64bit_elf_symbols (Filedata * filedata,
6136 Elf_Internal_Shdr * section,
6137 unsigned long * num_syms_return)
9ea033b2 6138{
ba5cdace
NC
6139 unsigned long number = 0;
6140 Elf64_External_Sym * esyms = NULL;
6141 Elf_External_Sym_Shndx * shndx = NULL;
6142 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6143 Elf_Internal_Sym * psym;
b34976b6 6144 unsigned int j;
e3d39609 6145 elf_section_list * entry;
9ea033b2 6146
c9c1d674
EG
6147 if (section->sh_size == 0)
6148 {
6149 if (num_syms_return != NULL)
6150 * num_syms_return = 0;
6151 return NULL;
6152 }
6153
dd24e3da 6154 /* Run some sanity checks first. */
c9c1d674 6155 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6156 {
c9c1d674 6157 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6158 printable_section_name (filedata, section),
8066deb1 6159 (unsigned long) section->sh_entsize);
ba5cdace 6160 goto exit_point;
dd24e3da
NC
6161 }
6162
dda8d76d 6163 if (section->sh_size > filedata->file_size)
f54498b4
NC
6164 {
6165 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6166 printable_section_name (filedata, section),
8066deb1 6167 (unsigned long) section->sh_size);
f54498b4
NC
6168 goto exit_point;
6169 }
6170
dd24e3da
NC
6171 number = section->sh_size / section->sh_entsize;
6172
6173 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6174 {
c9c1d674 6175 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6176 (unsigned long) section->sh_size,
dda8d76d 6177 printable_section_name (filedata, section),
8066deb1 6178 (unsigned long) section->sh_entsize);
ba5cdace 6179 goto exit_point;
dd24e3da
NC
6180 }
6181
dda8d76d 6182 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6183 section->sh_size, _("symbols"));
a6e9f9df 6184 if (!esyms)
ba5cdace 6185 goto exit_point;
9ea033b2 6186
e3d39609 6187 shndx = NULL;
978c4450 6188 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6189 {
6190 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6191 continue;
6192
6193 if (shndx != NULL)
6194 {
6195 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6196 free (shndx);
c9c1d674 6197 }
e3d39609
NC
6198
6199 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6200 entry->hdr->sh_offset,
6201 1, entry->hdr->sh_size,
6202 _("symbol table section indices"));
6203 if (shndx == NULL)
6204 goto exit_point;
6205
6206 /* PR17531: file: heap-buffer-overflow */
6207 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6208 {
6209 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6210 printable_section_name (filedata, entry->hdr),
6211 (unsigned long) entry->hdr->sh_size,
6212 (unsigned long) section->sh_size);
6213 goto exit_point;
6214 }
6215 }
9ad5cbcf 6216
3f5e193b 6217 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6218
6219 if (isyms == NULL)
6220 {
8b73c356
NC
6221 error (_("Out of memory reading %lu symbols\n"),
6222 (unsigned long) number);
ba5cdace 6223 goto exit_point;
9ea033b2
NC
6224 }
6225
ba5cdace 6226 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6227 {
6228 psym->st_name = BYTE_GET (esyms[j].st_name);
6229 psym->st_info = BYTE_GET (esyms[j].st_info);
6230 psym->st_other = BYTE_GET (esyms[j].st_other);
6231 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6232
4fbb74a6 6233 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6234 psym->st_shndx
6235 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6236 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6237 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6238
66543521
AM
6239 psym->st_value = BYTE_GET (esyms[j].st_value);
6240 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6241 }
6242
ba5cdace 6243 exit_point:
e3d39609
NC
6244 free (shndx);
6245 free (esyms);
ba5cdace
NC
6246
6247 if (num_syms_return != NULL)
6248 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6249
6250 return isyms;
6251}
6252
4de91c10
AM
6253static Elf_Internal_Sym *
6254get_elf_symbols (Filedata *filedata,
6255 Elf_Internal_Shdr *section,
6256 unsigned long *num_syms_return)
6257{
6258 if (is_32bit_elf)
6259 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6260 else
6261 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6262}
6263
d1133906 6264static const char *
dda8d76d 6265get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6266{
5477e8a0 6267 static char buff[1024];
2cf0635d 6268 char * p = buff;
32ec8896
NC
6269 unsigned int field_size = is_32bit_elf ? 8 : 16;
6270 signed int sindex;
6271 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6272 bfd_vma os_flags = 0;
6273 bfd_vma proc_flags = 0;
6274 bfd_vma unknown_flags = 0;
148b93f2 6275 static const struct
5477e8a0 6276 {
2cf0635d 6277 const char * str;
32ec8896 6278 unsigned int len;
5477e8a0
L
6279 }
6280 flags [] =
6281 {
cfcac11d
NC
6282 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6283 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6284 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6285 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6286 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6287 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6288 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6289 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6290 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6291 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6292 /* IA-64 specific. */
6293 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6294 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6295 /* IA-64 OpenVMS specific. */
6296 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6297 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6298 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6299 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6300 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6301 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6302 /* Generic. */
cfcac11d 6303 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6304 /* SPARC specific. */
77115a4a 6305 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6306 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6307 /* ARM specific. */
6308 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6309 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6310 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6311 /* GNU specific. */
6312 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6313 /* VLE specific. */
6314 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6315 /* GNU specific. */
6316 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6317 };
6318
6319 if (do_section_details)
6320 {
8d5ff12c
L
6321 sprintf (buff, "[%*.*lx]: ",
6322 field_size, field_size, (unsigned long) sh_flags);
6323 p += field_size + 4;
5477e8a0 6324 }
76da6bbe 6325
d1133906
NC
6326 while (sh_flags)
6327 {
6328 bfd_vma flag;
6329
6330 flag = sh_flags & - sh_flags;
6331 sh_flags &= ~ flag;
76da6bbe 6332
5477e8a0 6333 if (do_section_details)
d1133906 6334 {
5477e8a0
L
6335 switch (flag)
6336 {
91d6fa6a
NC
6337 case SHF_WRITE: sindex = 0; break;
6338 case SHF_ALLOC: sindex = 1; break;
6339 case SHF_EXECINSTR: sindex = 2; break;
6340 case SHF_MERGE: sindex = 3; break;
6341 case SHF_STRINGS: sindex = 4; break;
6342 case SHF_INFO_LINK: sindex = 5; break;
6343 case SHF_LINK_ORDER: sindex = 6; break;
6344 case SHF_OS_NONCONFORMING: sindex = 7; break;
6345 case SHF_GROUP: sindex = 8; break;
6346 case SHF_TLS: sindex = 9; break;
18ae9cc1 6347 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6348 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6349
5477e8a0 6350 default:
91d6fa6a 6351 sindex = -1;
dda8d76d 6352 switch (filedata->file_header.e_machine)
148b93f2 6353 {
cfcac11d 6354 case EM_IA_64:
148b93f2 6355 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6356 sindex = 10;
148b93f2 6357 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6358 sindex = 11;
148b93f2 6359#ifdef BFD64
dda8d76d 6360 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6361 switch (flag)
6362 {
91d6fa6a
NC
6363 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6364 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6365 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6366 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6367 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6368 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6369 default: break;
6370 }
6371#endif
cfcac11d
NC
6372 break;
6373
caa83f8b 6374 case EM_386:
22abe556 6375 case EM_IAMCU:
caa83f8b 6376 case EM_X86_64:
7f502d6c 6377 case EM_L1OM:
7a9068fe 6378 case EM_K1OM:
cfcac11d
NC
6379 case EM_OLD_SPARCV9:
6380 case EM_SPARC32PLUS:
6381 case EM_SPARCV9:
6382 case EM_SPARC:
18ae9cc1 6383 if (flag == SHF_ORDERED)
91d6fa6a 6384 sindex = 19;
cfcac11d 6385 break;
ac4c9b04
MG
6386
6387 case EM_ARM:
6388 switch (flag)
6389 {
6390 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6391 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6392 case SHF_COMDEF: sindex = 23; break;
6393 default: break;
6394 }
6395 break;
83eef883
AFB
6396 case EM_PPC:
6397 if (flag == SHF_PPC_VLE)
6398 sindex = 25;
6399 break;
99fabbc9
JL
6400 default:
6401 break;
6402 }
ac4c9b04 6403
99fabbc9
JL
6404 switch (filedata->file_header.e_ident[EI_OSABI])
6405 {
6406 case ELFOSABI_GNU:
6407 case ELFOSABI_FREEBSD:
6408 if (flag == SHF_GNU_RETAIN)
6409 sindex = 26;
6410 /* Fall through */
6411 case ELFOSABI_NONE:
6412 if (flag == SHF_GNU_MBIND)
6413 /* We should not recognize SHF_GNU_MBIND for
6414 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6415 not set the EI_OSABI header byte. */
6416 sindex = 24;
6417 break;
cfcac11d
NC
6418 default:
6419 break;
148b93f2 6420 }
99fabbc9 6421 break;
5477e8a0
L
6422 }
6423
91d6fa6a 6424 if (sindex != -1)
5477e8a0 6425 {
8d5ff12c
L
6426 if (p != buff + field_size + 4)
6427 {
6428 if (size < (10 + 2))
bee0ee85
NC
6429 {
6430 warn (_("Internal error: not enough buffer room for section flag info"));
6431 return _("<unknown>");
6432 }
8d5ff12c
L
6433 size -= 2;
6434 *p++ = ',';
6435 *p++ = ' ';
6436 }
6437
91d6fa6a
NC
6438 size -= flags [sindex].len;
6439 p = stpcpy (p, flags [sindex].str);
5477e8a0 6440 }
3b22753a 6441 else if (flag & SHF_MASKOS)
8d5ff12c 6442 os_flags |= flag;
d1133906 6443 else if (flag & SHF_MASKPROC)
8d5ff12c 6444 proc_flags |= flag;
d1133906 6445 else
8d5ff12c 6446 unknown_flags |= flag;
5477e8a0
L
6447 }
6448 else
6449 {
6450 switch (flag)
6451 {
6452 case SHF_WRITE: *p = 'W'; break;
6453 case SHF_ALLOC: *p = 'A'; break;
6454 case SHF_EXECINSTR: *p = 'X'; break;
6455 case SHF_MERGE: *p = 'M'; break;
6456 case SHF_STRINGS: *p = 'S'; break;
6457 case SHF_INFO_LINK: *p = 'I'; break;
6458 case SHF_LINK_ORDER: *p = 'L'; break;
6459 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6460 case SHF_GROUP: *p = 'G'; break;
6461 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6462 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6463 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6464
6465 default:
dda8d76d
NC
6466 if ((filedata->file_header.e_machine == EM_X86_64
6467 || filedata->file_header.e_machine == EM_L1OM
6468 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6469 && flag == SHF_X86_64_LARGE)
6470 *p = 'l';
dda8d76d 6471 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6472 && flag == SHF_ARM_PURECODE)
99fabbc9 6473 *p = 'y';
dda8d76d 6474 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6475 && flag == SHF_PPC_VLE)
99fabbc9 6476 *p = 'v';
5477e8a0
L
6477 else if (flag & SHF_MASKOS)
6478 {
99fabbc9
JL
6479 switch (filedata->file_header.e_ident[EI_OSABI])
6480 {
6481 case ELFOSABI_GNU:
6482 case ELFOSABI_FREEBSD:
6483 if (flag == SHF_GNU_RETAIN)
6484 {
6485 *p = 'R';
6486 break;
6487 }
6488 /* Fall through */
6489 case ELFOSABI_NONE:
6490 if (flag == SHF_GNU_MBIND)
6491 {
6492 /* We should not recognize SHF_GNU_MBIND for
6493 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6494 not set the EI_OSABI header byte. */
6495 *p = 'D';
6496 break;
6497 }
6498 /* Fall through */
6499 default:
6500 *p = 'o';
6501 sh_flags &= ~SHF_MASKOS;
6502 break;
6503 }
5477e8a0
L
6504 }
6505 else if (flag & SHF_MASKPROC)
6506 {
6507 *p = 'p';
6508 sh_flags &= ~ SHF_MASKPROC;
6509 }
6510 else
6511 *p = 'x';
6512 break;
6513 }
6514 p++;
d1133906
NC
6515 }
6516 }
76da6bbe 6517
8d5ff12c
L
6518 if (do_section_details)
6519 {
6520 if (os_flags)
6521 {
6522 size -= 5 + field_size;
6523 if (p != buff + field_size + 4)
6524 {
6525 if (size < (2 + 1))
bee0ee85
NC
6526 {
6527 warn (_("Internal error: not enough buffer room for section flag info"));
6528 return _("<unknown>");
6529 }
8d5ff12c
L
6530 size -= 2;
6531 *p++ = ',';
6532 *p++ = ' ';
6533 }
6534 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6535 (unsigned long) os_flags);
6536 p += 5 + field_size;
6537 }
6538 if (proc_flags)
6539 {
6540 size -= 7 + field_size;
6541 if (p != buff + field_size + 4)
6542 {
6543 if (size < (2 + 1))
bee0ee85
NC
6544 {
6545 warn (_("Internal error: not enough buffer room for section flag info"));
6546 return _("<unknown>");
6547 }
8d5ff12c
L
6548 size -= 2;
6549 *p++ = ',';
6550 *p++ = ' ';
6551 }
6552 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6553 (unsigned long) proc_flags);
6554 p += 7 + field_size;
6555 }
6556 if (unknown_flags)
6557 {
6558 size -= 10 + field_size;
6559 if (p != buff + field_size + 4)
6560 {
6561 if (size < (2 + 1))
bee0ee85
NC
6562 {
6563 warn (_("Internal error: not enough buffer room for section flag info"));
6564 return _("<unknown>");
6565 }
8d5ff12c
L
6566 size -= 2;
6567 *p++ = ',';
6568 *p++ = ' ';
6569 }
2b692964 6570 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6571 (unsigned long) unknown_flags);
6572 p += 10 + field_size;
6573 }
6574 }
6575
e9e44622 6576 *p = '\0';
d1133906
NC
6577 return buff;
6578}
6579
5844b465 6580static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6581get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6582{
6583 if (is_32bit_elf)
6584 {
6585 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6586
ebdf1ebf
NC
6587 if (size < sizeof (* echdr))
6588 {
6589 error (_("Compressed section is too small even for a compression header\n"));
6590 return 0;
6591 }
6592
77115a4a
L
6593 chdr->ch_type = BYTE_GET (echdr->ch_type);
6594 chdr->ch_size = BYTE_GET (echdr->ch_size);
6595 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6596 return sizeof (*echdr);
6597 }
6598 else
6599 {
6600 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6601
ebdf1ebf
NC
6602 if (size < sizeof (* echdr))
6603 {
6604 error (_("Compressed section is too small even for a compression header\n"));
6605 return 0;
6606 }
6607
77115a4a
L
6608 chdr->ch_type = BYTE_GET (echdr->ch_type);
6609 chdr->ch_size = BYTE_GET (echdr->ch_size);
6610 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6611 return sizeof (*echdr);
6612 }
6613}
6614
015dc7e1 6615static bool
dda8d76d 6616process_section_headers (Filedata * filedata)
252b5132 6617{
2cf0635d 6618 Elf_Internal_Shdr * section;
b34976b6 6619 unsigned int i;
252b5132 6620
dda8d76d 6621 if (filedata->file_header.e_shnum == 0)
252b5132 6622 {
82f2dbf7 6623 /* PR binutils/12467. */
dda8d76d 6624 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6625 {
6626 warn (_("possibly corrupt ELF file header - it has a non-zero"
6627 " section header offset, but no section headers\n"));
015dc7e1 6628 return false;
32ec8896 6629 }
82f2dbf7 6630 else if (do_sections)
252b5132
RH
6631 printf (_("\nThere are no sections in this file.\n"));
6632
015dc7e1 6633 return true;
252b5132
RH
6634 }
6635
6636 if (do_sections && !do_header)
ca0e11aa
NC
6637 {
6638 if (filedata->is_separate && process_links)
6639 printf (_("In linked file '%s': "), filedata->file_name);
6640 if (! filedata->is_separate || process_links)
6641 printf (ngettext ("There is %d section header, "
6642 "starting at offset 0x%lx:\n",
6643 "There are %d section headers, "
6644 "starting at offset 0x%lx:\n",
6645 filedata->file_header.e_shnum),
6646 filedata->file_header.e_shnum,
6647 (unsigned long) filedata->file_header.e_shoff);
6648 }
252b5132 6649
4de91c10
AM
6650 if (!get_section_headers (filedata, false))
6651 return false;
252b5132
RH
6652
6653 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6654 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6655 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6656 {
dda8d76d 6657 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6658
c256ffe7
JJ
6659 if (section->sh_size != 0)
6660 {
dda8d76d
NC
6661 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6662 1, section->sh_size,
6663 _("string table"));
0de14b54 6664
dda8d76d 6665 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6666 }
252b5132
RH
6667 }
6668
6669 /* Scan the sections for the dynamic symbol table
e3c8793a 6670 and dynamic string table and debug sections. */
89fac5e3 6671 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6672 switch (filedata->file_header.e_machine)
89fac5e3
RS
6673 {
6674 case EM_MIPS:
6675 case EM_MIPS_RS3_LE:
6676 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6677 FDE addresses. However, the ABI also has a semi-official ILP32
6678 variant for which the normal FDE address size rules apply.
6679
6680 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6681 section, where XX is the size of longs in bits. Unfortunately,
6682 earlier compilers provided no way of distinguishing ILP32 objects
6683 from LP64 objects, so if there's any doubt, we should assume that
6684 the official LP64 form is being used. */
dda8d76d
NC
6685 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6686 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6687 eh_addr_size = 8;
6688 break;
0f56a26a
DD
6689
6690 case EM_H8_300:
6691 case EM_H8_300H:
dda8d76d 6692 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6693 {
6694 case E_H8_MACH_H8300:
6695 case E_H8_MACH_H8300HN:
6696 case E_H8_MACH_H8300SN:
6697 case E_H8_MACH_H8300SXN:
6698 eh_addr_size = 2;
6699 break;
6700 case E_H8_MACH_H8300H:
6701 case E_H8_MACH_H8300S:
6702 case E_H8_MACH_H8300SX:
6703 eh_addr_size = 4;
6704 break;
6705 }
f4236fe4
DD
6706 break;
6707
ff7eeb89 6708 case EM_M32C_OLD:
f4236fe4 6709 case EM_M32C:
dda8d76d 6710 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6711 {
6712 case EF_M32C_CPU_M16C:
6713 eh_addr_size = 2;
6714 break;
6715 }
6716 break;
89fac5e3
RS
6717 }
6718
76ca31c0
NC
6719#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6720 do \
6721 { \
6722 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6723 if (section->sh_entsize != expected_entsize) \
9dd3a467 6724 { \
76ca31c0
NC
6725 char buf[40]; \
6726 sprintf_vma (buf, section->sh_entsize); \
6727 /* Note: coded this way so that there is a single string for \
6728 translation. */ \
6729 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6730 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6731 (unsigned) expected_entsize); \
9dd3a467 6732 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6733 } \
6734 } \
08d8fa11 6735 while (0)
9dd3a467
NC
6736
6737#define CHECK_ENTSIZE(section, i, type) \
1b513401 6738 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6739 sizeof (Elf64_External_##type))
6740
dda8d76d
NC
6741 for (i = 0, section = filedata->section_headers;
6742 i < filedata->file_header.e_shnum;
b34976b6 6743 i++, section++)
252b5132 6744 {
84714f86 6745 const char *name = section_name_print (filedata, section);
252b5132 6746
1b513401
NC
6747 /* Run some sanity checks on the headers and
6748 possibly fill in some file data as well. */
6749 switch (section->sh_type)
252b5132 6750 {
1b513401 6751 case SHT_DYNSYM:
978c4450 6752 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6753 {
6754 error (_("File contains multiple dynamic symbol tables\n"));
6755 continue;
6756 }
6757
08d8fa11 6758 CHECK_ENTSIZE (section, i, Sym);
978c4450 6759 filedata->dynamic_symbols
4de91c10 6760 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6761 filedata->dynamic_symtab_section = section;
1b513401
NC
6762 break;
6763
6764 case SHT_STRTAB:
6765 if (streq (name, ".dynstr"))
252b5132 6766 {
1b513401
NC
6767 if (filedata->dynamic_strings != NULL)
6768 {
6769 error (_("File contains multiple dynamic string tables\n"));
6770 continue;
6771 }
6772
6773 filedata->dynamic_strings
6774 = (char *) get_data (NULL, filedata, section->sh_offset,
6775 1, section->sh_size, _("dynamic strings"));
6776 filedata->dynamic_strings_length
6777 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6778 filedata->dynamic_strtab_section = section;
252b5132 6779 }
1b513401
NC
6780 break;
6781
6782 case SHT_SYMTAB_SHNDX:
6783 {
6784 elf_section_list * entry = xmalloc (sizeof * entry);
6785
6786 entry->hdr = section;
6787 entry->next = filedata->symtab_shndx_list;
6788 filedata->symtab_shndx_list = entry;
6789 }
6790 break;
6791
6792 case SHT_SYMTAB:
6793 CHECK_ENTSIZE (section, i, Sym);
6794 break;
6795
6796 case SHT_GROUP:
6797 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6798 break;
252b5132 6799
1b513401
NC
6800 case SHT_REL:
6801 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6802 if (do_checks && section->sh_size == 0)
1b513401
NC
6803 warn (_("Section '%s': zero-sized relocation section\n"), name);
6804 break;
6805
6806 case SHT_RELA:
6807 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6808 if (do_checks && section->sh_size == 0)
1b513401
NC
6809 warn (_("Section '%s': zero-sized relocation section\n"), name);
6810 break;
6811
6812 case SHT_NOTE:
6813 case SHT_PROGBITS:
546cb2d8
NC
6814 /* Having a zero sized section is not illegal according to the
6815 ELF standard, but it might be an indication that something
6816 is wrong. So issue a warning if we are running in lint mode. */
6817 if (do_checks && section->sh_size == 0)
1b513401
NC
6818 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6819 break;
6820
6821 default:
6822 break;
6823 }
6824
6825 if ((do_debugging || do_debug_info || do_debug_abbrevs
6826 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6827 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6828 || do_debug_str || do_debug_str_offsets || do_debug_loc
6829 || do_debug_ranges
1b513401 6830 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6831 && (startswith (name, ".debug_")
6832 || startswith (name, ".zdebug_")))
252b5132 6833 {
1b315056
CS
6834 if (name[1] == 'z')
6835 name += sizeof (".zdebug_") - 1;
6836 else
6837 name += sizeof (".debug_") - 1;
252b5132
RH
6838
6839 if (do_debugging
24d127aa
ML
6840 || (do_debug_info && startswith (name, "info"))
6841 || (do_debug_info && startswith (name, "types"))
6842 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6843 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6844 || (do_debug_lines && startswith (name, "line."))
6845 || (do_debug_pubnames && startswith (name, "pubnames"))
6846 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6847 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6848 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6849 || (do_debug_aranges && startswith (name, "aranges"))
6850 || (do_debug_ranges && startswith (name, "ranges"))
6851 || (do_debug_ranges && startswith (name, "rnglists"))
6852 || (do_debug_frames && startswith (name, "frame"))
6853 || (do_debug_macinfo && startswith (name, "macinfo"))
6854 || (do_debug_macinfo && startswith (name, "macro"))
6855 || (do_debug_str && startswith (name, "str"))
6856 || (do_debug_links && startswith (name, "sup"))
6857 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6858 || (do_debug_loc && startswith (name, "loc"))
6859 || (do_debug_loc && startswith (name, "loclists"))
6860 || (do_debug_addr && startswith (name, "addr"))
6861 || (do_debug_cu_index && startswith (name, "cu_index"))
6862 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6863 )
6431e409 6864 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6865 }
a262ae96 6866 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6867 else if ((do_debugging || do_debug_info)
24d127aa 6868 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6869 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6870 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6871 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6872 else if (do_gdb_index && (streq (name, ".gdb_index")
6873 || streq (name, ".debug_names")))
6431e409 6874 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6875 /* Trace sections for Itanium VMS. */
6876 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6877 || do_trace_aranges)
24d127aa 6878 && startswith (name, ".trace_"))
6f875884
TG
6879 {
6880 name += sizeof (".trace_") - 1;
6881
6882 if (do_debugging
6883 || (do_trace_info && streq (name, "info"))
6884 || (do_trace_abbrevs && streq (name, "abbrev"))
6885 || (do_trace_aranges && streq (name, "aranges"))
6886 )
6431e409 6887 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6888 }
dda8d76d 6889 else if ((do_debugging || do_debug_links)
24d127aa
ML
6890 && (startswith (name, ".gnu_debuglink")
6891 || startswith (name, ".gnu_debugaltlink")))
6431e409 6892 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6893 }
6894
6895 if (! do_sections)
015dc7e1 6896 return true;
252b5132 6897
ca0e11aa 6898 if (filedata->is_separate && ! process_links)
015dc7e1 6899 return true;
ca0e11aa
NC
6900
6901 if (filedata->is_separate)
6902 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6903 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6904 printf (_("\nSection Headers:\n"));
6905 else
6906 printf (_("\nSection Header:\n"));
76da6bbe 6907
f7a99963 6908 if (is_32bit_elf)
595cf52e 6909 {
5477e8a0 6910 if (do_section_details)
595cf52e
L
6911 {
6912 printf (_(" [Nr] Name\n"));
5477e8a0 6913 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6914 }
6915 else
6916 printf
6917 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6918 }
d974e256 6919 else if (do_wide)
595cf52e 6920 {
5477e8a0 6921 if (do_section_details)
595cf52e
L
6922 {
6923 printf (_(" [Nr] Name\n"));
5477e8a0 6924 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6925 }
6926 else
6927 printf
6928 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6929 }
f7a99963
NC
6930 else
6931 {
5477e8a0 6932 if (do_section_details)
595cf52e
L
6933 {
6934 printf (_(" [Nr] Name\n"));
5477e8a0
L
6935 printf (_(" Type Address Offset Link\n"));
6936 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6937 }
6938 else
6939 {
6940 printf (_(" [Nr] Name Type Address Offset\n"));
6941 printf (_(" Size EntSize Flags Link Info Align\n"));
6942 }
f7a99963 6943 }
252b5132 6944
5477e8a0
L
6945 if (do_section_details)
6946 printf (_(" Flags\n"));
6947
dda8d76d
NC
6948 for (i = 0, section = filedata->section_headers;
6949 i < filedata->file_header.e_shnum;
b34976b6 6950 i++, section++)
252b5132 6951 {
dd905818
NC
6952 /* Run some sanity checks on the section header. */
6953
6954 /* Check the sh_link field. */
6955 switch (section->sh_type)
6956 {
285e3f99
AM
6957 case SHT_REL:
6958 case SHT_RELA:
6959 if (section->sh_link == 0
6960 && (filedata->file_header.e_type == ET_EXEC
6961 || filedata->file_header.e_type == ET_DYN))
6962 /* A dynamic relocation section where all entries use a
6963 zero symbol index need not specify a symtab section. */
6964 break;
6965 /* Fall through. */
dd905818
NC
6966 case SHT_SYMTAB_SHNDX:
6967 case SHT_GROUP:
6968 case SHT_HASH:
6969 case SHT_GNU_HASH:
6970 case SHT_GNU_versym:
285e3f99 6971 if (section->sh_link == 0
dda8d76d
NC
6972 || section->sh_link >= filedata->file_header.e_shnum
6973 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6974 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6975 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6976 i, section->sh_link);
6977 break;
6978
6979 case SHT_DYNAMIC:
6980 case SHT_SYMTAB:
6981 case SHT_DYNSYM:
6982 case SHT_GNU_verneed:
6983 case SHT_GNU_verdef:
6984 case SHT_GNU_LIBLIST:
285e3f99 6985 if (section->sh_link == 0
dda8d76d
NC
6986 || section->sh_link >= filedata->file_header.e_shnum
6987 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6988 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6989 i, section->sh_link);
6990 break;
6991
6992 case SHT_INIT_ARRAY:
6993 case SHT_FINI_ARRAY:
6994 case SHT_PREINIT_ARRAY:
6995 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6996 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6997 i, section->sh_link);
6998 break;
6999
7000 default:
7001 /* FIXME: Add support for target specific section types. */
7002#if 0 /* Currently we do not check other section types as there are too
7003 many special cases. Stab sections for example have a type
7004 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7005 section. */
7006 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7007 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7008 i, section->sh_link);
7009#endif
7010 break;
7011 }
7012
7013 /* Check the sh_info field. */
7014 switch (section->sh_type)
7015 {
7016 case SHT_REL:
7017 case SHT_RELA:
285e3f99
AM
7018 if (section->sh_info == 0
7019 && (filedata->file_header.e_type == ET_EXEC
7020 || filedata->file_header.e_type == ET_DYN))
7021 /* Dynamic relocations apply to segments, so they do not
7022 need to specify the section they relocate. */
7023 break;
7024 if (section->sh_info == 0
dda8d76d
NC
7025 || section->sh_info >= filedata->file_header.e_shnum
7026 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7027 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7028 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7029 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7030 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7031 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7032 /* FIXME: Are other section types valid ? */
dda8d76d 7033 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7034 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7035 i, section->sh_info);
dd905818
NC
7036 break;
7037
7038 case SHT_DYNAMIC:
7039 case SHT_HASH:
7040 case SHT_SYMTAB_SHNDX:
7041 case SHT_INIT_ARRAY:
7042 case SHT_FINI_ARRAY:
7043 case SHT_PREINIT_ARRAY:
7044 if (section->sh_info != 0)
7045 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7046 i, section->sh_info);
7047 break;
7048
7049 case SHT_GROUP:
7050 case SHT_SYMTAB:
7051 case SHT_DYNSYM:
7052 /* A symbol index - we assume that it is valid. */
7053 break;
7054
7055 default:
7056 /* FIXME: Add support for target specific section types. */
7057 if (section->sh_type == SHT_NOBITS)
7058 /* NOBITS section headers with non-zero sh_info fields can be
7059 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7060 information. The stripped sections have their headers
7061 preserved but their types set to SHT_NOBITS. So do not check
7062 this type of section. */
dd905818
NC
7063 ;
7064 else if (section->sh_flags & SHF_INFO_LINK)
7065 {
dda8d76d 7066 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7067 warn (_("[%2u]: Expected link to another section in info field"), i);
7068 }
a91e1603
L
7069 else if (section->sh_type < SHT_LOOS
7070 && (section->sh_flags & SHF_GNU_MBIND) == 0
7071 && section->sh_info != 0)
dd905818
NC
7072 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7073 i, section->sh_info);
7074 break;
7075 }
7076
3e6b6445 7077 /* Check the sh_size field. */
dda8d76d 7078 if (section->sh_size > filedata->file_size
3e6b6445
NC
7079 && section->sh_type != SHT_NOBITS
7080 && section->sh_type != SHT_NULL
7081 && section->sh_type < SHT_LOOS)
7082 warn (_("Size of section %u is larger than the entire file!\n"), i);
7083
7bfd842d 7084 printf (" [%2u] ", i);
5477e8a0 7085 if (do_section_details)
dda8d76d 7086 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7087 else
84714f86 7088 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7089
ea52a088 7090 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7091 get_section_type_name (filedata, section->sh_type));
0b4362b0 7092
f7a99963
NC
7093 if (is_32bit_elf)
7094 {
cfcac11d
NC
7095 const char * link_too_big = NULL;
7096
f7a99963 7097 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7098
f7a99963
NC
7099 printf ( " %6.6lx %6.6lx %2.2lx",
7100 (unsigned long) section->sh_offset,
7101 (unsigned long) section->sh_size,
7102 (unsigned long) section->sh_entsize);
d1133906 7103
5477e8a0
L
7104 if (do_section_details)
7105 fputs (" ", stdout);
7106 else
dda8d76d 7107 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7108
dda8d76d 7109 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7110 {
7111 link_too_big = "";
7112 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7113 an error but it can have special values in Solaris binaries. */
dda8d76d 7114 switch (filedata->file_header.e_machine)
cfcac11d 7115 {
caa83f8b 7116 case EM_386:
22abe556 7117 case EM_IAMCU:
caa83f8b 7118 case EM_X86_64:
7f502d6c 7119 case EM_L1OM:
7a9068fe 7120 case EM_K1OM:
cfcac11d
NC
7121 case EM_OLD_SPARCV9:
7122 case EM_SPARC32PLUS:
7123 case EM_SPARCV9:
7124 case EM_SPARC:
7125 if (section->sh_link == (SHN_BEFORE & 0xffff))
7126 link_too_big = "BEFORE";
7127 else if (section->sh_link == (SHN_AFTER & 0xffff))
7128 link_too_big = "AFTER";
7129 break;
7130 default:
7131 break;
7132 }
7133 }
7134
7135 if (do_section_details)
7136 {
7137 if (link_too_big != NULL && * link_too_big)
7138 printf ("<%s> ", link_too_big);
7139 else
7140 printf ("%2u ", section->sh_link);
7141 printf ("%3u %2lu\n", section->sh_info,
7142 (unsigned long) section->sh_addralign);
7143 }
7144 else
7145 printf ("%2u %3u %2lu\n",
7146 section->sh_link,
7147 section->sh_info,
7148 (unsigned long) section->sh_addralign);
7149
7150 if (link_too_big && ! * link_too_big)
7151 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7152 i, section->sh_link);
f7a99963 7153 }
d974e256
JJ
7154 else if (do_wide)
7155 {
7156 print_vma (section->sh_addr, LONG_HEX);
7157
7158 if ((long) section->sh_offset == section->sh_offset)
7159 printf (" %6.6lx", (unsigned long) section->sh_offset);
7160 else
7161 {
7162 putchar (' ');
7163 print_vma (section->sh_offset, LONG_HEX);
7164 }
7165
7166 if ((unsigned long) section->sh_size == section->sh_size)
7167 printf (" %6.6lx", (unsigned long) section->sh_size);
7168 else
7169 {
7170 putchar (' ');
7171 print_vma (section->sh_size, LONG_HEX);
7172 }
7173
7174 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7175 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7176 else
7177 {
7178 putchar (' ');
7179 print_vma (section->sh_entsize, LONG_HEX);
7180 }
7181
5477e8a0
L
7182 if (do_section_details)
7183 fputs (" ", stdout);
7184 else
dda8d76d 7185 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7186
72de5009 7187 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7188
7189 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7190 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7191 else
7192 {
7193 print_vma (section->sh_addralign, DEC);
7194 putchar ('\n');
7195 }
7196 }
5477e8a0 7197 else if (do_section_details)
595cf52e 7198 {
55cc53e9 7199 putchar (' ');
595cf52e
L
7200 print_vma (section->sh_addr, LONG_HEX);
7201 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7202 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7203 else
7204 {
7205 printf (" ");
7206 print_vma (section->sh_offset, LONG_HEX);
7207 }
72de5009 7208 printf (" %u\n ", section->sh_link);
595cf52e 7209 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7210 putchar (' ');
595cf52e
L
7211 print_vma (section->sh_entsize, LONG_HEX);
7212
72de5009
AM
7213 printf (" %-16u %lu\n",
7214 section->sh_info,
595cf52e
L
7215 (unsigned long) section->sh_addralign);
7216 }
f7a99963
NC
7217 else
7218 {
7219 putchar (' ');
7220 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7221 if ((long) section->sh_offset == section->sh_offset)
7222 printf (" %8.8lx", (unsigned long) section->sh_offset);
7223 else
7224 {
7225 printf (" ");
7226 print_vma (section->sh_offset, LONG_HEX);
7227 }
f7a99963
NC
7228 printf ("\n ");
7229 print_vma (section->sh_size, LONG_HEX);
7230 printf (" ");
7231 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7232
dda8d76d 7233 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7234
72de5009
AM
7235 printf (" %2u %3u %lu\n",
7236 section->sh_link,
7237 section->sh_info,
f7a99963
NC
7238 (unsigned long) section->sh_addralign);
7239 }
5477e8a0
L
7240
7241 if (do_section_details)
77115a4a 7242 {
dda8d76d 7243 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7244 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7245 {
7246 /* Minimum section size is 12 bytes for 32-bit compression
7247 header + 12 bytes for compressed data header. */
7248 unsigned char buf[24];
d8024a91 7249
77115a4a 7250 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7251 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7252 sizeof (buf), _("compression header")))
7253 {
7254 Elf_Internal_Chdr chdr;
d8024a91 7255
5844b465
NC
7256 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7257 printf (_(" [<corrupt>]\n"));
77115a4a 7258 else
5844b465
NC
7259 {
7260 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7261 printf (" ZLIB, ");
7262 else
7263 printf (_(" [<unknown>: 0x%x], "),
7264 chdr.ch_type);
7265 print_vma (chdr.ch_size, LONG_HEX);
7266 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7267 }
77115a4a
L
7268 }
7269 }
7270 }
252b5132
RH
7271 }
7272
5477e8a0 7273 if (!do_section_details)
3dbcc61d 7274 {
9fb71ee4
NC
7275 /* The ordering of the letters shown here matches the ordering of the
7276 corresponding SHF_xxx values, and hence the order in which these
7277 letters will be displayed to the user. */
7278 printf (_("Key to Flags:\n\
7279 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7280 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7281 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7282 switch (filedata->file_header.e_ident[EI_OSABI])
7283 {
7284 case ELFOSABI_GNU:
7285 case ELFOSABI_FREEBSD:
7286 printf (_("R (retain), "));
7287 /* Fall through */
7288 case ELFOSABI_NONE:
7289 printf (_("D (mbind), "));
7290 break;
7291 default:
7292 break;
7293 }
dda8d76d
NC
7294 if (filedata->file_header.e_machine == EM_X86_64
7295 || filedata->file_header.e_machine == EM_L1OM
7296 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7297 printf (_("l (large), "));
dda8d76d 7298 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7299 printf (_("y (purecode), "));
dda8d76d 7300 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7301 printf (_("v (VLE), "));
9fb71ee4 7302 printf ("p (processor specific)\n");
0b4362b0 7303 }
d1133906 7304
015dc7e1 7305 return true;
252b5132
RH
7306}
7307
015dc7e1 7308static bool
28d13567
AM
7309get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7310 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7311 char **strtab, unsigned long *strtablen)
7312{
7313 *strtab = NULL;
7314 *strtablen = 0;
4de91c10 7315 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7316
7317 if (*symtab == NULL)
015dc7e1 7318 return false;
28d13567
AM
7319
7320 if (symsec->sh_link != 0)
7321 {
7322 Elf_Internal_Shdr *strsec;
7323
7324 if (symsec->sh_link >= filedata->file_header.e_shnum)
7325 {
7326 error (_("Bad sh_link in symbol table section\n"));
7327 free (*symtab);
7328 *symtab = NULL;
7329 *nsyms = 0;
015dc7e1 7330 return false;
28d13567
AM
7331 }
7332
7333 strsec = filedata->section_headers + symsec->sh_link;
7334
7335 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7336 1, strsec->sh_size, _("string table"));
7337 if (*strtab == NULL)
7338 {
7339 free (*symtab);
7340 *symtab = NULL;
7341 *nsyms = 0;
015dc7e1 7342 return false;
28d13567
AM
7343 }
7344 *strtablen = strsec->sh_size;
7345 }
015dc7e1 7346 return true;
28d13567
AM
7347}
7348
f5842774
L
7349static const char *
7350get_group_flags (unsigned int flags)
7351{
1449284b 7352 static char buff[128];
220453ec 7353
6d913794
NC
7354 if (flags == 0)
7355 return "";
7356 else if (flags == GRP_COMDAT)
7357 return "COMDAT ";
f5842774 7358
89246a0e
AM
7359 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7360 flags,
7361 flags & GRP_MASKOS ? _("<OS specific>") : "",
7362 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7363 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7364 ? _("<unknown>") : ""));
6d913794 7365
f5842774
L
7366 return buff;
7367}
7368
015dc7e1 7369static bool
dda8d76d 7370process_section_groups (Filedata * filedata)
f5842774 7371{
2cf0635d 7372 Elf_Internal_Shdr * section;
f5842774 7373 unsigned int i;
2cf0635d
NC
7374 struct group * group;
7375 Elf_Internal_Shdr * symtab_sec;
7376 Elf_Internal_Shdr * strtab_sec;
7377 Elf_Internal_Sym * symtab;
ba5cdace 7378 unsigned long num_syms;
2cf0635d 7379 char * strtab;
c256ffe7 7380 size_t strtab_size;
d1f5c6e3
L
7381
7382 /* Don't process section groups unless needed. */
7383 if (!do_unwind && !do_section_groups)
015dc7e1 7384 return true;
f5842774 7385
dda8d76d 7386 if (filedata->file_header.e_shnum == 0)
f5842774
L
7387 {
7388 if (do_section_groups)
ca0e11aa
NC
7389 {
7390 if (filedata->is_separate)
7391 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7392 filedata->file_name);
7393 else
7394 printf (_("\nThere are no section groups in this file.\n"));
7395 }
015dc7e1 7396 return true;
f5842774
L
7397 }
7398
dda8d76d 7399 if (filedata->section_headers == NULL)
f5842774
L
7400 {
7401 error (_("Section headers are not available!\n"));
fa1908fd 7402 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7403 return false;
f5842774
L
7404 }
7405
978c4450
AM
7406 filedata->section_headers_groups
7407 = (struct group **) calloc (filedata->file_header.e_shnum,
7408 sizeof (struct group *));
e4b17d5c 7409
978c4450 7410 if (filedata->section_headers_groups == NULL)
e4b17d5c 7411 {
8b73c356 7412 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7413 filedata->file_header.e_shnum);
015dc7e1 7414 return false;
e4b17d5c
L
7415 }
7416
f5842774 7417 /* Scan the sections for the group section. */
978c4450 7418 filedata->group_count = 0;
dda8d76d
NC
7419 for (i = 0, section = filedata->section_headers;
7420 i < filedata->file_header.e_shnum;
f5842774 7421 i++, section++)
e4b17d5c 7422 if (section->sh_type == SHT_GROUP)
978c4450 7423 filedata->group_count++;
e4b17d5c 7424
978c4450 7425 if (filedata->group_count == 0)
d1f5c6e3
L
7426 {
7427 if (do_section_groups)
ca0e11aa
NC
7428 {
7429 if (filedata->is_separate)
7430 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7431 filedata->file_name);
7432 else
7433 printf (_("\nThere are no section groups in this file.\n"));
7434 }
d1f5c6e3 7435
015dc7e1 7436 return true;
d1f5c6e3
L
7437 }
7438
978c4450
AM
7439 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7440 sizeof (struct group));
e4b17d5c 7441
978c4450 7442 if (filedata->section_groups == NULL)
e4b17d5c 7443 {
8b73c356 7444 error (_("Out of memory reading %lu groups\n"),
978c4450 7445 (unsigned long) filedata->group_count);
015dc7e1 7446 return false;
e4b17d5c
L
7447 }
7448
d1f5c6e3
L
7449 symtab_sec = NULL;
7450 strtab_sec = NULL;
7451 symtab = NULL;
ba5cdace 7452 num_syms = 0;
d1f5c6e3 7453 strtab = NULL;
c256ffe7 7454 strtab_size = 0;
ca0e11aa
NC
7455
7456 if (filedata->is_separate)
7457 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7458
978c4450 7459 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7460 i < filedata->file_header.e_shnum;
e4b17d5c 7461 i++, section++)
f5842774
L
7462 {
7463 if (section->sh_type == SHT_GROUP)
7464 {
dda8d76d 7465 const char * name = printable_section_name (filedata, section);
74e1a04b 7466 const char * group_name;
2cf0635d
NC
7467 unsigned char * start;
7468 unsigned char * indices;
f5842774 7469 unsigned int entry, j, size;
2cf0635d
NC
7470 Elf_Internal_Shdr * sec;
7471 Elf_Internal_Sym * sym;
f5842774
L
7472
7473 /* Get the symbol table. */
dda8d76d
NC
7474 if (section->sh_link >= filedata->file_header.e_shnum
7475 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7476 != SHT_SYMTAB))
f5842774
L
7477 {
7478 error (_("Bad sh_link in group section `%s'\n"), name);
7479 continue;
7480 }
d1f5c6e3
L
7481
7482 if (symtab_sec != sec)
7483 {
7484 symtab_sec = sec;
9db70fc3 7485 free (symtab);
4de91c10 7486 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7487 }
f5842774 7488
dd24e3da
NC
7489 if (symtab == NULL)
7490 {
7491 error (_("Corrupt header in group section `%s'\n"), name);
7492 continue;
7493 }
7494
ba5cdace
NC
7495 if (section->sh_info >= num_syms)
7496 {
7497 error (_("Bad sh_info in group section `%s'\n"), name);
7498 continue;
7499 }
7500
f5842774
L
7501 sym = symtab + section->sh_info;
7502
7503 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7504 {
4fbb74a6 7505 if (sym->st_shndx == 0
dda8d76d 7506 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7507 {
7508 error (_("Bad sh_info in group section `%s'\n"), name);
7509 continue;
7510 }
ba2685cc 7511
84714f86
AM
7512 group_name = section_name_print (filedata,
7513 filedata->section_headers
b9e920ec 7514 + sym->st_shndx);
c256ffe7 7515 strtab_sec = NULL;
9db70fc3 7516 free (strtab);
f5842774 7517 strtab = NULL;
c256ffe7 7518 strtab_size = 0;
f5842774
L
7519 }
7520 else
7521 {
7522 /* Get the string table. */
dda8d76d 7523 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7524 {
7525 strtab_sec = NULL;
9db70fc3 7526 free (strtab);
c256ffe7
JJ
7527 strtab = NULL;
7528 strtab_size = 0;
7529 }
7530 else if (strtab_sec
dda8d76d 7531 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7532 {
7533 strtab_sec = sec;
9db70fc3 7534 free (strtab);
071436c6 7535
dda8d76d 7536 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7537 1, strtab_sec->sh_size,
7538 _("string table"));
c256ffe7 7539 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7540 }
c256ffe7 7541 group_name = sym->st_name < strtab_size
2b692964 7542 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7543 }
7544
c9c1d674
EG
7545 /* PR 17531: file: loop. */
7546 if (section->sh_entsize > section->sh_size)
7547 {
7548 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7549 printable_section_name (filedata, section),
8066deb1
AM
7550 (unsigned long) section->sh_entsize,
7551 (unsigned long) section->sh_size);
61dd8e19 7552 continue;
c9c1d674
EG
7553 }
7554
dda8d76d 7555 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7556 1, section->sh_size,
7557 _("section data"));
59245841
NC
7558 if (start == NULL)
7559 continue;
f5842774
L
7560
7561 indices = start;
7562 size = (section->sh_size / section->sh_entsize) - 1;
7563 entry = byte_get (indices, 4);
7564 indices += 4;
e4b17d5c
L
7565
7566 if (do_section_groups)
7567 {
2b692964 7568 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7569 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7570
e4b17d5c
L
7571 printf (_(" [Index] Name\n"));
7572 }
7573
7574 group->group_index = i;
7575
f5842774
L
7576 for (j = 0; j < size; j++)
7577 {
2cf0635d 7578 struct group_list * g;
e4b17d5c 7579
f5842774
L
7580 entry = byte_get (indices, 4);
7581 indices += 4;
7582
dda8d76d 7583 if (entry >= filedata->file_header.e_shnum)
391cb864 7584 {
57028622
NC
7585 static unsigned num_group_errors = 0;
7586
7587 if (num_group_errors ++ < 10)
7588 {
7589 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7590 entry, i, filedata->file_header.e_shnum - 1);
57028622 7591 if (num_group_errors == 10)
67ce483b 7592 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7593 }
391cb864
L
7594 continue;
7595 }
391cb864 7596
978c4450 7597 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7598 {
d1f5c6e3
L
7599 if (entry)
7600 {
57028622
NC
7601 static unsigned num_errs = 0;
7602
7603 if (num_errs ++ < 10)
7604 {
7605 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7606 entry, i,
978c4450 7607 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7608 if (num_errs == 10)
7609 warn (_("Further error messages about already contained group sections suppressed\n"));
7610 }
d1f5c6e3
L
7611 continue;
7612 }
7613 else
7614 {
7615 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7616 section group. We just warn it the first time
d1f5c6e3 7617 and ignore it afterwards. */
015dc7e1 7618 static bool warned = false;
d1f5c6e3
L
7619 if (!warned)
7620 {
7621 error (_("section 0 in group section [%5u]\n"),
978c4450 7622 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7623 warned = true;
d1f5c6e3
L
7624 }
7625 }
e4b17d5c
L
7626 }
7627
978c4450 7628 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7629
7630 if (do_section_groups)
7631 {
dda8d76d
NC
7632 sec = filedata->section_headers + entry;
7633 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7634 }
7635
3f5e193b 7636 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7637 g->section_index = entry;
7638 g->next = group->root;
7639 group->root = g;
f5842774
L
7640 }
7641
9db70fc3 7642 free (start);
e4b17d5c
L
7643
7644 group++;
f5842774
L
7645 }
7646 }
7647
9db70fc3
AM
7648 free (symtab);
7649 free (strtab);
015dc7e1 7650 return true;
f5842774
L
7651}
7652
28f997cf
TG
7653/* Data used to display dynamic fixups. */
7654
7655struct ia64_vms_dynfixup
7656{
7657 bfd_vma needed_ident; /* Library ident number. */
7658 bfd_vma needed; /* Index in the dstrtab of the library name. */
7659 bfd_vma fixup_needed; /* Index of the library. */
7660 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7661 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7662};
7663
7664/* Data used to display dynamic relocations. */
7665
7666struct ia64_vms_dynimgrela
7667{
7668 bfd_vma img_rela_cnt; /* Number of relocations. */
7669 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7670};
7671
7672/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7673 library). */
7674
015dc7e1 7675static bool
dda8d76d
NC
7676dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7677 struct ia64_vms_dynfixup * fixup,
7678 const char * strtab,
7679 unsigned int strtab_sz)
28f997cf 7680{
32ec8896 7681 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7682 long i;
32ec8896 7683 const char * lib_name;
28f997cf 7684
978c4450
AM
7685 imfs = get_data (NULL, filedata,
7686 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7687 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7688 _("dynamic section image fixups"));
7689 if (!imfs)
015dc7e1 7690 return false;
28f997cf
TG
7691
7692 if (fixup->needed < strtab_sz)
7693 lib_name = strtab + fixup->needed;
7694 else
7695 {
32ec8896 7696 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7697 (unsigned long) fixup->needed);
28f997cf
TG
7698 lib_name = "???";
7699 }
736990c4 7700
28f997cf
TG
7701 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7702 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7703 printf
7704 (_("Seg Offset Type SymVec DataType\n"));
7705
7706 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7707 {
7708 unsigned int type;
7709 const char *rtype;
7710
7711 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7712 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7713 type = BYTE_GET (imfs [i].type);
7714 rtype = elf_ia64_reloc_type (type);
7715 if (rtype == NULL)
7716 printf (" 0x%08x ", type);
7717 else
7718 printf (" %-32s ", rtype);
7719 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7720 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7721 }
7722
7723 free (imfs);
015dc7e1 7724 return true;
28f997cf
TG
7725}
7726
7727/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7728
015dc7e1 7729static bool
dda8d76d 7730dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7731{
7732 Elf64_External_VMS_IMAGE_RELA *imrs;
7733 long i;
7734
978c4450
AM
7735 imrs = get_data (NULL, filedata,
7736 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7737 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7738 _("dynamic section image relocations"));
28f997cf 7739 if (!imrs)
015dc7e1 7740 return false;
28f997cf
TG
7741
7742 printf (_("\nImage relocs\n"));
7743 printf
7744 (_("Seg Offset Type Addend Seg Sym Off\n"));
7745
7746 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7747 {
7748 unsigned int type;
7749 const char *rtype;
7750
7751 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7752 printf ("%08" BFD_VMA_FMT "x ",
7753 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7754 type = BYTE_GET (imrs [i].type);
7755 rtype = elf_ia64_reloc_type (type);
7756 if (rtype == NULL)
7757 printf ("0x%08x ", type);
7758 else
7759 printf ("%-31s ", rtype);
7760 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7761 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7762 printf ("%08" BFD_VMA_FMT "x\n",
7763 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7764 }
7765
7766 free (imrs);
015dc7e1 7767 return true;
28f997cf
TG
7768}
7769
7770/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7771
015dc7e1 7772static bool
dda8d76d 7773process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7774{
7775 struct ia64_vms_dynfixup fixup;
7776 struct ia64_vms_dynimgrela imgrela;
7777 Elf_Internal_Dyn *entry;
28f997cf
TG
7778 bfd_vma strtab_off = 0;
7779 bfd_vma strtab_sz = 0;
7780 char *strtab = NULL;
015dc7e1 7781 bool res = true;
28f997cf
TG
7782
7783 memset (&fixup, 0, sizeof (fixup));
7784 memset (&imgrela, 0, sizeof (imgrela));
7785
7786 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7787 for (entry = filedata->dynamic_section;
7788 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7789 entry++)
7790 {
7791 switch (entry->d_tag)
7792 {
7793 case DT_IA_64_VMS_STRTAB_OFFSET:
7794 strtab_off = entry->d_un.d_val;
7795 break;
7796 case DT_STRSZ:
7797 strtab_sz = entry->d_un.d_val;
7798 if (strtab == NULL)
978c4450
AM
7799 strtab = get_data (NULL, filedata,
7800 filedata->dynamic_addr + strtab_off,
28f997cf 7801 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7802 if (strtab == NULL)
7803 strtab_sz = 0;
28f997cf
TG
7804 break;
7805
7806 case DT_IA_64_VMS_NEEDED_IDENT:
7807 fixup.needed_ident = entry->d_un.d_val;
7808 break;
7809 case DT_NEEDED:
7810 fixup.needed = entry->d_un.d_val;
7811 break;
7812 case DT_IA_64_VMS_FIXUP_NEEDED:
7813 fixup.fixup_needed = entry->d_un.d_val;
7814 break;
7815 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7816 fixup.fixup_rela_cnt = entry->d_un.d_val;
7817 break;
7818 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7819 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7820 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7821 res = false;
28f997cf 7822 break;
28f997cf
TG
7823 case DT_IA_64_VMS_IMG_RELA_CNT:
7824 imgrela.img_rela_cnt = entry->d_un.d_val;
7825 break;
7826 case DT_IA_64_VMS_IMG_RELA_OFF:
7827 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7828 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7829 res = false;
28f997cf
TG
7830 break;
7831
7832 default:
7833 break;
7834 }
7835 }
7836
9db70fc3 7837 free (strtab);
28f997cf
TG
7838
7839 return res;
7840}
7841
85b1c36d 7842static struct
566b0d53 7843{
2cf0635d 7844 const char * name;
566b0d53
L
7845 int reloc;
7846 int size;
7847 int rela;
32ec8896
NC
7848}
7849 dynamic_relocations [] =
566b0d53 7850{
015dc7e1
AM
7851 { "REL", DT_REL, DT_RELSZ, false },
7852 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7853 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7854};
7855
252b5132 7856/* Process the reloc section. */
18bd398b 7857
015dc7e1 7858static bool
dda8d76d 7859process_relocs (Filedata * filedata)
252b5132 7860{
b34976b6
AM
7861 unsigned long rel_size;
7862 unsigned long rel_offset;
252b5132 7863
252b5132 7864 if (!do_reloc)
015dc7e1 7865 return true;
252b5132
RH
7866
7867 if (do_using_dynamic)
7868 {
32ec8896 7869 int is_rela;
2cf0635d 7870 const char * name;
015dc7e1 7871 bool has_dynamic_reloc;
566b0d53 7872 unsigned int i;
0de14b54 7873
015dc7e1 7874 has_dynamic_reloc = false;
252b5132 7875
566b0d53 7876 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7877 {
566b0d53
L
7878 is_rela = dynamic_relocations [i].rela;
7879 name = dynamic_relocations [i].name;
978c4450
AM
7880 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7881 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7882
32ec8896 7883 if (rel_size)
015dc7e1 7884 has_dynamic_reloc = true;
566b0d53
L
7885
7886 if (is_rela == UNKNOWN)
aa903cfb 7887 {
566b0d53 7888 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7889 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7890 {
7891 case DT_REL:
015dc7e1 7892 is_rela = false;
566b0d53
L
7893 break;
7894 case DT_RELA:
015dc7e1 7895 is_rela = true;
566b0d53
L
7896 break;
7897 }
aa903cfb 7898 }
252b5132 7899
566b0d53
L
7900 if (rel_size)
7901 {
ca0e11aa
NC
7902 if (filedata->is_separate)
7903 printf
7904 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7905 filedata->file_name, name, rel_offset, rel_size);
7906 else
7907 printf
7908 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7909 name, rel_offset, rel_size);
252b5132 7910
dda8d76d
NC
7911 dump_relocations (filedata,
7912 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7913 rel_size,
978c4450
AM
7914 filedata->dynamic_symbols,
7915 filedata->num_dynamic_syms,
7916 filedata->dynamic_strings,
7917 filedata->dynamic_strings_length,
015dc7e1 7918 is_rela, true /* is_dynamic */);
566b0d53 7919 }
252b5132 7920 }
566b0d53 7921
dda8d76d
NC
7922 if (is_ia64_vms (filedata))
7923 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7924 has_dynamic_reloc = true;
28f997cf 7925
566b0d53 7926 if (! has_dynamic_reloc)
ca0e11aa
NC
7927 {
7928 if (filedata->is_separate)
7929 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7930 filedata->file_name);
7931 else
7932 printf (_("\nThere are no dynamic relocations in this file.\n"));
7933 }
252b5132
RH
7934 }
7935 else
7936 {
2cf0635d 7937 Elf_Internal_Shdr * section;
b34976b6 7938 unsigned long i;
015dc7e1 7939 bool found = false;
252b5132 7940
dda8d76d
NC
7941 for (i = 0, section = filedata->section_headers;
7942 i < filedata->file_header.e_shnum;
b34976b6 7943 i++, section++)
252b5132
RH
7944 {
7945 if ( section->sh_type != SHT_RELA
7946 && section->sh_type != SHT_REL)
7947 continue;
7948
7949 rel_offset = section->sh_offset;
7950 rel_size = section->sh_size;
7951
7952 if (rel_size)
7953 {
b34976b6 7954 int is_rela;
d3a49aa8 7955 unsigned long num_rela;
103f02d3 7956
ca0e11aa
NC
7957 if (filedata->is_separate)
7958 printf (_("\nIn linked file '%s' relocation section "),
7959 filedata->file_name);
7960 else
7961 printf (_("\nRelocation section "));
252b5132 7962
dda8d76d 7963 if (filedata->string_table == NULL)
19936277 7964 printf ("%d", section->sh_name);
252b5132 7965 else
dda8d76d 7966 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7967
d3a49aa8
AM
7968 num_rela = rel_size / section->sh_entsize;
7969 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7970 " at offset 0x%lx contains %lu entries:\n",
7971 num_rela),
7972 rel_offset, num_rela);
252b5132 7973
d79b3d50
NC
7974 is_rela = section->sh_type == SHT_RELA;
7975
4fbb74a6 7976 if (section->sh_link != 0
dda8d76d 7977 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7978 {
2cf0635d
NC
7979 Elf_Internal_Shdr * symsec;
7980 Elf_Internal_Sym * symtab;
d79b3d50 7981 unsigned long nsyms;
c256ffe7 7982 unsigned long strtablen = 0;
2cf0635d 7983 char * strtab = NULL;
57346661 7984
dda8d76d 7985 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7986 if (symsec->sh_type != SHT_SYMTAB
7987 && symsec->sh_type != SHT_DYNSYM)
7988 continue;
7989
28d13567
AM
7990 if (!get_symtab (filedata, symsec,
7991 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7992 continue;
252b5132 7993
dda8d76d 7994 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7995 symtab, nsyms, strtab, strtablen,
7996 is_rela,
7997 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7998 free (strtab);
d79b3d50
NC
7999 free (symtab);
8000 }
8001 else
dda8d76d 8002 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 8003 NULL, 0, NULL, 0, is_rela,
015dc7e1 8004 false /* is_dynamic */);
252b5132 8005
015dc7e1 8006 found = true;
252b5132
RH
8007 }
8008 }
8009
8010 if (! found)
45ac8f4f
NC
8011 {
8012 /* Users sometimes forget the -D option, so try to be helpful. */
8013 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8014 {
978c4450 8015 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8016 {
ca0e11aa
NC
8017 if (filedata->is_separate)
8018 printf (_("\nThere are no static relocations in linked file '%s'."),
8019 filedata->file_name);
8020 else
8021 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8022 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8023
8024 break;
8025 }
8026 }
8027 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8028 {
8029 if (filedata->is_separate)
8030 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8031 filedata->file_name);
8032 else
8033 printf (_("\nThere are no relocations in this file.\n"));
8034 }
45ac8f4f 8035 }
252b5132
RH
8036 }
8037
015dc7e1 8038 return true;
252b5132
RH
8039}
8040
4d6ed7c8
NC
8041/* An absolute address consists of a section and an offset. If the
8042 section is NULL, the offset itself is the address, otherwise, the
8043 address equals to LOAD_ADDRESS(section) + offset. */
8044
8045struct absaddr
948f632f
DA
8046{
8047 unsigned short section;
8048 bfd_vma offset;
8049};
4d6ed7c8 8050
948f632f
DA
8051/* Find the nearest symbol at or below ADDR. Returns the symbol
8052 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8053
4d6ed7c8 8054static void
dda8d76d
NC
8055find_symbol_for_address (Filedata * filedata,
8056 Elf_Internal_Sym * symtab,
8057 unsigned long nsyms,
8058 const char * strtab,
8059 unsigned long strtab_size,
8060 struct absaddr addr,
8061 const char ** symname,
8062 bfd_vma * offset)
4d6ed7c8 8063{
d3ba0551 8064 bfd_vma dist = 0x100000;
2cf0635d 8065 Elf_Internal_Sym * sym;
948f632f
DA
8066 Elf_Internal_Sym * beg;
8067 Elf_Internal_Sym * end;
2cf0635d 8068 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8069
0b6ae522 8070 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8071 beg = symtab;
8072 end = symtab + nsyms;
0b6ae522 8073
948f632f 8074 while (beg < end)
4d6ed7c8 8075 {
948f632f
DA
8076 bfd_vma value;
8077
8078 sym = beg + (end - beg) / 2;
0b6ae522 8079
948f632f 8080 value = sym->st_value;
0b6ae522
DJ
8081 REMOVE_ARCH_BITS (value);
8082
948f632f 8083 if (sym->st_name != 0
4d6ed7c8 8084 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8085 && addr.offset >= value
8086 && addr.offset - value < dist)
4d6ed7c8
NC
8087 {
8088 best = sym;
0b6ae522 8089 dist = addr.offset - value;
4d6ed7c8
NC
8090 if (!dist)
8091 break;
8092 }
948f632f
DA
8093
8094 if (addr.offset < value)
8095 end = sym;
8096 else
8097 beg = sym + 1;
4d6ed7c8 8098 }
1b31d05e 8099
4d6ed7c8
NC
8100 if (best)
8101 {
57346661 8102 *symname = (best->st_name >= strtab_size
2b692964 8103 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8104 *offset = dist;
8105 return;
8106 }
1b31d05e 8107
4d6ed7c8
NC
8108 *symname = NULL;
8109 *offset = addr.offset;
8110}
8111
32ec8896 8112static /* signed */ int
948f632f
DA
8113symcmp (const void *p, const void *q)
8114{
8115 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8116 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8117
8118 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8119}
8120
8121/* Process the unwind section. */
8122
8123#include "unwind-ia64.h"
8124
8125struct ia64_unw_table_entry
8126{
8127 struct absaddr start;
8128 struct absaddr end;
8129 struct absaddr info;
8130};
8131
8132struct ia64_unw_aux_info
8133{
32ec8896
NC
8134 struct ia64_unw_table_entry * table; /* Unwind table. */
8135 unsigned long table_len; /* Length of unwind table. */
8136 unsigned char * info; /* Unwind info. */
8137 unsigned long info_size; /* Size of unwind info. */
8138 bfd_vma info_addr; /* Starting address of unwind info. */
8139 bfd_vma seg_base; /* Starting address of segment. */
8140 Elf_Internal_Sym * symtab; /* The symbol table. */
8141 unsigned long nsyms; /* Number of symbols. */
8142 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8143 unsigned long nfuns; /* Number of entries in funtab. */
8144 char * strtab; /* The string table. */
8145 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8146};
8147
015dc7e1 8148static bool
dda8d76d 8149dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8150{
2cf0635d 8151 struct ia64_unw_table_entry * tp;
948f632f 8152 unsigned long j, nfuns;
4d6ed7c8 8153 int in_body;
015dc7e1 8154 bool res = true;
7036c0e1 8155
948f632f
DA
8156 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8157 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8158 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8159 aux->funtab[nfuns++] = aux->symtab[j];
8160 aux->nfuns = nfuns;
8161 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8162
4d6ed7c8
NC
8163 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8164 {
8165 bfd_vma stamp;
8166 bfd_vma offset;
2cf0635d
NC
8167 const unsigned char * dp;
8168 const unsigned char * head;
53774b7e 8169 const unsigned char * end;
2cf0635d 8170 const char * procname;
4d6ed7c8 8171
dda8d76d 8172 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8173 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8174
8175 fputs ("\n<", stdout);
8176
8177 if (procname)
8178 {
8179 fputs (procname, stdout);
8180
8181 if (offset)
8182 printf ("+%lx", (unsigned long) offset);
8183 }
8184
8185 fputs (">: [", stdout);
8186 print_vma (tp->start.offset, PREFIX_HEX);
8187 fputc ('-', stdout);
8188 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8189 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8190 (unsigned long) (tp->info.offset - aux->seg_base));
8191
53774b7e
NC
8192 /* PR 17531: file: 86232b32. */
8193 if (aux->info == NULL)
8194 continue;
8195
97c0a079
AM
8196 offset = tp->info.offset;
8197 if (tp->info.section)
8198 {
8199 if (tp->info.section >= filedata->file_header.e_shnum)
8200 {
8201 warn (_("Invalid section %u in table entry %ld\n"),
8202 tp->info.section, (long) (tp - aux->table));
015dc7e1 8203 res = false;
97c0a079
AM
8204 continue;
8205 }
8206 offset += filedata->section_headers[tp->info.section].sh_addr;
8207 }
8208 offset -= aux->info_addr;
53774b7e 8209 /* PR 17531: file: 0997b4d1. */
90679903
AM
8210 if (offset >= aux->info_size
8211 || aux->info_size - offset < 8)
53774b7e
NC
8212 {
8213 warn (_("Invalid offset %lx in table entry %ld\n"),
8214 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8215 res = false;
53774b7e
NC
8216 continue;
8217 }
8218
97c0a079 8219 head = aux->info + offset;
a4a00738 8220 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8221
86f55779 8222 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8223 (unsigned) UNW_VER (stamp),
8224 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8225 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8226 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8227 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8228
8229 if (UNW_VER (stamp) != 1)
8230 {
2b692964 8231 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8232 continue;
8233 }
8234
8235 in_body = 0;
53774b7e
NC
8236 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8237 /* PR 17531: file: 16ceda89. */
8238 if (end > aux->info + aux->info_size)
8239 end = aux->info + aux->info_size;
8240 for (dp = head + 8; dp < end;)
b4477bc8 8241 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8242 }
948f632f
DA
8243
8244 free (aux->funtab);
32ec8896
NC
8245
8246 return res;
4d6ed7c8
NC
8247}
8248
015dc7e1 8249static bool
dda8d76d
NC
8250slurp_ia64_unwind_table (Filedata * filedata,
8251 struct ia64_unw_aux_info * aux,
8252 Elf_Internal_Shdr * sec)
4d6ed7c8 8253{
89fac5e3 8254 unsigned long size, nrelas, i;
2cf0635d
NC
8255 Elf_Internal_Phdr * seg;
8256 struct ia64_unw_table_entry * tep;
8257 Elf_Internal_Shdr * relsec;
8258 Elf_Internal_Rela * rela;
8259 Elf_Internal_Rela * rp;
8260 unsigned char * table;
8261 unsigned char * tp;
8262 Elf_Internal_Sym * sym;
8263 const char * relname;
4d6ed7c8 8264
53774b7e
NC
8265 aux->table_len = 0;
8266
4d6ed7c8
NC
8267 /* First, find the starting address of the segment that includes
8268 this section: */
8269
dda8d76d 8270 if (filedata->file_header.e_phnum)
4d6ed7c8 8271 {
dda8d76d 8272 if (! get_program_headers (filedata))
015dc7e1 8273 return false;
4d6ed7c8 8274
dda8d76d
NC
8275 for (seg = filedata->program_headers;
8276 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8277 ++seg)
4d6ed7c8
NC
8278 {
8279 if (seg->p_type != PT_LOAD)
8280 continue;
8281
8282 if (sec->sh_addr >= seg->p_vaddr
8283 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8284 {
8285 aux->seg_base = seg->p_vaddr;
8286 break;
8287 }
8288 }
4d6ed7c8
NC
8289 }
8290
8291 /* Second, build the unwind table from the contents of the unwind section: */
8292 size = sec->sh_size;
dda8d76d 8293 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8294 _("unwind table"));
a6e9f9df 8295 if (!table)
015dc7e1 8296 return false;
4d6ed7c8 8297
53774b7e 8298 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8299 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8300 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8301 tep = aux->table;
53774b7e
NC
8302
8303 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8304 {
8305 tep->start.section = SHN_UNDEF;
8306 tep->end.section = SHN_UNDEF;
8307 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8308 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8309 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8310 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8311 tep->start.offset += aux->seg_base;
8312 tep->end.offset += aux->seg_base;
8313 tep->info.offset += aux->seg_base;
8314 }
8315 free (table);
8316
41e92641 8317 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8318 for (relsec = filedata->section_headers;
8319 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8320 ++relsec)
8321 {
8322 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8323 || relsec->sh_info >= filedata->file_header.e_shnum
8324 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8325 continue;
8326
dda8d76d 8327 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8328 & rela, & nrelas))
53774b7e
NC
8329 {
8330 free (aux->table);
8331 aux->table = NULL;
8332 aux->table_len = 0;
015dc7e1 8333 return false;
53774b7e 8334 }
4d6ed7c8
NC
8335
8336 for (rp = rela; rp < rela + nrelas; ++rp)
8337 {
4770fb94 8338 unsigned int sym_ndx;
726bd37d
AM
8339 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8340 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8341
82b1b41b
NC
8342 /* PR 17531: file: 9fa67536. */
8343 if (relname == NULL)
8344 {
726bd37d 8345 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8346 continue;
8347 }
948f632f 8348
24d127aa 8349 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8350 {
82b1b41b 8351 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8352 continue;
8353 }
8354
89fac5e3 8355 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8356
53774b7e
NC
8357 /* PR 17531: file: 5bc8d9bf. */
8358 if (i >= aux->table_len)
8359 {
8360 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8361 continue;
8362 }
8363
4770fb94
AM
8364 sym_ndx = get_reloc_symindex (rp->r_info);
8365 if (sym_ndx >= aux->nsyms)
8366 {
8367 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8368 sym_ndx);
8369 continue;
8370 }
8371 sym = aux->symtab + sym_ndx;
8372
53774b7e 8373 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8374 {
8375 case 0:
8376 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8377 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8378 break;
8379 case 1:
8380 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8381 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8382 break;
8383 case 2:
8384 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8385 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8386 break;
8387 default:
8388 break;
8389 }
8390 }
8391
8392 free (rela);
8393 }
8394
015dc7e1 8395 return true;
4d6ed7c8
NC
8396}
8397
015dc7e1 8398static bool
dda8d76d 8399ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8400{
2cf0635d
NC
8401 Elf_Internal_Shdr * sec;
8402 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8403 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8404 struct ia64_unw_aux_info aux;
015dc7e1 8405 bool res = true;
f1467e33 8406
4d6ed7c8
NC
8407 memset (& aux, 0, sizeof (aux));
8408
dda8d76d 8409 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8410 {
28d13567 8411 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8412 {
28d13567 8413 if (aux.symtab)
4082ef84 8414 {
28d13567
AM
8415 error (_("Multiple symbol tables encountered\n"));
8416 free (aux.symtab);
8417 aux.symtab = NULL;
4082ef84 8418 free (aux.strtab);
28d13567 8419 aux.strtab = NULL;
4082ef84 8420 }
28d13567
AM
8421 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8422 &aux.strtab, &aux.strtab_size))
015dc7e1 8423 return false;
4d6ed7c8
NC
8424 }
8425 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8426 unwcount++;
8427 }
8428
8429 if (!unwcount)
8430 printf (_("\nThere are no unwind sections in this file.\n"));
8431
8432 while (unwcount-- > 0)
8433 {
84714f86 8434 const char *suffix;
579f31ac
JJ
8435 size_t len, len2;
8436
dda8d76d
NC
8437 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8438 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8439 if (sec->sh_type == SHT_IA_64_UNWIND)
8440 {
8441 unwsec = sec;
8442 break;
8443 }
4082ef84
NC
8444 /* We have already counted the number of SHT_IA64_UNWIND
8445 sections so the loop above should never fail. */
8446 assert (unwsec != NULL);
579f31ac
JJ
8447
8448 unwstart = i + 1;
8449 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8450
e4b17d5c
L
8451 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8452 {
8453 /* We need to find which section group it is in. */
4082ef84 8454 struct group_list * g;
e4b17d5c 8455
978c4450
AM
8456 if (filedata->section_headers_groups == NULL
8457 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8458 i = filedata->file_header.e_shnum;
4082ef84 8459 else
e4b17d5c 8460 {
978c4450 8461 g = filedata->section_headers_groups[i]->root;
18bd398b 8462
4082ef84
NC
8463 for (; g != NULL; g = g->next)
8464 {
dda8d76d 8465 sec = filedata->section_headers + g->section_index;
e4b17d5c 8466
84714f86
AM
8467 if (section_name_valid (filedata, sec)
8468 && streq (section_name (filedata, sec),
8469 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8470 break;
8471 }
8472
8473 if (g == NULL)
dda8d76d 8474 i = filedata->file_header.e_shnum;
4082ef84 8475 }
e4b17d5c 8476 }
84714f86
AM
8477 else if (section_name_valid (filedata, unwsec)
8478 && startswith (section_name (filedata, unwsec),
e9b095a5 8479 ELF_STRING_ia64_unwind_once))
579f31ac 8480 {
18bd398b 8481 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8482 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8483 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8484 for (i = 0, sec = filedata->section_headers;
8485 i < filedata->file_header.e_shnum;
579f31ac 8486 ++i, ++sec)
84714f86
AM
8487 if (section_name_valid (filedata, sec)
8488 && startswith (section_name (filedata, sec),
e9b095a5 8489 ELF_STRING_ia64_unwind_info_once)
84714f86 8490 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8491 break;
8492 }
8493 else
8494 {
8495 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8496 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8497 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8498 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8499 suffix = "";
84714f86
AM
8500 if (section_name_valid (filedata, unwsec)
8501 && startswith (section_name (filedata, unwsec),
8502 ELF_STRING_ia64_unwind))
8503 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8504 for (i = 0, sec = filedata->section_headers;
8505 i < filedata->file_header.e_shnum;
579f31ac 8506 ++i, ++sec)
84714f86
AM
8507 if (section_name_valid (filedata, sec)
8508 && startswith (section_name (filedata, sec),
8509 ELF_STRING_ia64_unwind_info)
8510 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8511 break;
8512 }
8513
dda8d76d 8514 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8515 {
8516 printf (_("\nCould not find unwind info section for "));
8517
dda8d76d 8518 if (filedata->string_table == NULL)
579f31ac
JJ
8519 printf ("%d", unwsec->sh_name);
8520 else
dda8d76d 8521 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8522 }
8523 else
4d6ed7c8 8524 {
4d6ed7c8 8525 aux.info_addr = sec->sh_addr;
dda8d76d 8526 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8527 sec->sh_size,
8528 _("unwind info"));
59245841 8529 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8530
579f31ac 8531 printf (_("\nUnwind section "));
4d6ed7c8 8532
dda8d76d 8533 if (filedata->string_table == NULL)
579f31ac
JJ
8534 printf ("%d", unwsec->sh_name);
8535 else
dda8d76d 8536 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8537
579f31ac 8538 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8539 (unsigned long) unwsec->sh_offset,
89fac5e3 8540 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8541
dda8d76d 8542 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8543 && aux.table_len > 0)
dda8d76d 8544 dump_ia64_unwind (filedata, & aux);
579f31ac 8545
9db70fc3
AM
8546 free ((char *) aux.table);
8547 free ((char *) aux.info);
579f31ac
JJ
8548 aux.table = NULL;
8549 aux.info = NULL;
8550 }
4d6ed7c8 8551 }
4d6ed7c8 8552
9db70fc3
AM
8553 free (aux.symtab);
8554 free ((char *) aux.strtab);
32ec8896
NC
8555
8556 return res;
4d6ed7c8
NC
8557}
8558
3f5e193b 8559struct hppa_unw_table_entry
32ec8896
NC
8560{
8561 struct absaddr start;
8562 struct absaddr end;
8563 unsigned int Cannot_unwind:1; /* 0 */
8564 unsigned int Millicode:1; /* 1 */
8565 unsigned int Millicode_save_sr0:1; /* 2 */
8566 unsigned int Region_description:2; /* 3..4 */
8567 unsigned int reserved1:1; /* 5 */
8568 unsigned int Entry_SR:1; /* 6 */
8569 unsigned int Entry_FR:4; /* Number saved 7..10 */
8570 unsigned int Entry_GR:5; /* Number saved 11..15 */
8571 unsigned int Args_stored:1; /* 16 */
8572 unsigned int Variable_Frame:1; /* 17 */
8573 unsigned int Separate_Package_Body:1; /* 18 */
8574 unsigned int Frame_Extension_Millicode:1; /* 19 */
8575 unsigned int Stack_Overflow_Check:1; /* 20 */
8576 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8577 unsigned int Ada_Region:1; /* 22 */
8578 unsigned int cxx_info:1; /* 23 */
8579 unsigned int cxx_try_catch:1; /* 24 */
8580 unsigned int sched_entry_seq:1; /* 25 */
8581 unsigned int reserved2:1; /* 26 */
8582 unsigned int Save_SP:1; /* 27 */
8583 unsigned int Save_RP:1; /* 28 */
8584 unsigned int Save_MRP_in_frame:1; /* 29 */
8585 unsigned int extn_ptr_defined:1; /* 30 */
8586 unsigned int Cleanup_defined:1; /* 31 */
8587
8588 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8589 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8590 unsigned int Large_frame:1; /* 2 */
8591 unsigned int Pseudo_SP_Set:1; /* 3 */
8592 unsigned int reserved4:1; /* 4 */
8593 unsigned int Total_frame_size:27; /* 5..31 */
8594};
3f5e193b 8595
57346661 8596struct hppa_unw_aux_info
948f632f 8597{
32ec8896
NC
8598 struct hppa_unw_table_entry * table; /* Unwind table. */
8599 unsigned long table_len; /* Length of unwind table. */
8600 bfd_vma seg_base; /* Starting address of segment. */
8601 Elf_Internal_Sym * symtab; /* The symbol table. */
8602 unsigned long nsyms; /* Number of symbols. */
8603 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8604 unsigned long nfuns; /* Number of entries in funtab. */
8605 char * strtab; /* The string table. */
8606 unsigned long strtab_size; /* Size of string table. */
948f632f 8607};
57346661 8608
015dc7e1 8609static bool
dda8d76d 8610dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8611{
2cf0635d 8612 struct hppa_unw_table_entry * tp;
948f632f 8613 unsigned long j, nfuns;
015dc7e1 8614 bool res = true;
948f632f
DA
8615
8616 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8617 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8618 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8619 aux->funtab[nfuns++] = aux->symtab[j];
8620 aux->nfuns = nfuns;
8621 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8622
57346661
AM
8623 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8624 {
8625 bfd_vma offset;
2cf0635d 8626 const char * procname;
57346661 8627
dda8d76d 8628 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8629 aux->strtab_size, tp->start, &procname,
8630 &offset);
8631
8632 fputs ("\n<", stdout);
8633
8634 if (procname)
8635 {
8636 fputs (procname, stdout);
8637
8638 if (offset)
8639 printf ("+%lx", (unsigned long) offset);
8640 }
8641
8642 fputs (">: [", stdout);
8643 print_vma (tp->start.offset, PREFIX_HEX);
8644 fputc ('-', stdout);
8645 print_vma (tp->end.offset, PREFIX_HEX);
8646 printf ("]\n\t");
8647
18bd398b
NC
8648#define PF(_m) if (tp->_m) printf (#_m " ");
8649#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8650 PF(Cannot_unwind);
8651 PF(Millicode);
8652 PF(Millicode_save_sr0);
18bd398b 8653 /* PV(Region_description); */
57346661
AM
8654 PF(Entry_SR);
8655 PV(Entry_FR);
8656 PV(Entry_GR);
8657 PF(Args_stored);
8658 PF(Variable_Frame);
8659 PF(Separate_Package_Body);
8660 PF(Frame_Extension_Millicode);
8661 PF(Stack_Overflow_Check);
8662 PF(Two_Instruction_SP_Increment);
8663 PF(Ada_Region);
8664 PF(cxx_info);
8665 PF(cxx_try_catch);
8666 PF(sched_entry_seq);
8667 PF(Save_SP);
8668 PF(Save_RP);
8669 PF(Save_MRP_in_frame);
8670 PF(extn_ptr_defined);
8671 PF(Cleanup_defined);
8672 PF(MPE_XL_interrupt_marker);
8673 PF(HP_UX_interrupt_marker);
8674 PF(Large_frame);
8675 PF(Pseudo_SP_Set);
8676 PV(Total_frame_size);
8677#undef PF
8678#undef PV
8679 }
8680
18bd398b 8681 printf ("\n");
948f632f
DA
8682
8683 free (aux->funtab);
32ec8896
NC
8684
8685 return res;
57346661
AM
8686}
8687
015dc7e1 8688static bool
dda8d76d
NC
8689slurp_hppa_unwind_table (Filedata * filedata,
8690 struct hppa_unw_aux_info * aux,
8691 Elf_Internal_Shdr * sec)
57346661 8692{
1c0751b2 8693 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8694 Elf_Internal_Phdr * seg;
8695 struct hppa_unw_table_entry * tep;
8696 Elf_Internal_Shdr * relsec;
8697 Elf_Internal_Rela * rela;
8698 Elf_Internal_Rela * rp;
8699 unsigned char * table;
8700 unsigned char * tp;
8701 Elf_Internal_Sym * sym;
8702 const char * relname;
57346661 8703
57346661
AM
8704 /* First, find the starting address of the segment that includes
8705 this section. */
dda8d76d 8706 if (filedata->file_header.e_phnum)
57346661 8707 {
dda8d76d 8708 if (! get_program_headers (filedata))
015dc7e1 8709 return false;
57346661 8710
dda8d76d
NC
8711 for (seg = filedata->program_headers;
8712 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8713 ++seg)
8714 {
8715 if (seg->p_type != PT_LOAD)
8716 continue;
8717
8718 if (sec->sh_addr >= seg->p_vaddr
8719 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8720 {
8721 aux->seg_base = seg->p_vaddr;
8722 break;
8723 }
8724 }
8725 }
8726
8727 /* Second, build the unwind table from the contents of the unwind
8728 section. */
8729 size = sec->sh_size;
dda8d76d 8730 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8731 _("unwind table"));
57346661 8732 if (!table)
015dc7e1 8733 return false;
57346661 8734
1c0751b2
DA
8735 unw_ent_size = 16;
8736 nentries = size / unw_ent_size;
8737 size = unw_ent_size * nentries;
57346661 8738
e3fdc001 8739 aux->table_len = nentries;
3f5e193b
NC
8740 tep = aux->table = (struct hppa_unw_table_entry *)
8741 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8742
1c0751b2 8743 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8744 {
8745 unsigned int tmp1, tmp2;
8746
8747 tep->start.section = SHN_UNDEF;
8748 tep->end.section = SHN_UNDEF;
8749
1c0751b2
DA
8750 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8751 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8752 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8753 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8754
8755 tep->start.offset += aux->seg_base;
8756 tep->end.offset += aux->seg_base;
57346661
AM
8757
8758 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8759 tep->Millicode = (tmp1 >> 30) & 0x1;
8760 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8761 tep->Region_description = (tmp1 >> 27) & 0x3;
8762 tep->reserved1 = (tmp1 >> 26) & 0x1;
8763 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8764 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8765 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8766 tep->Args_stored = (tmp1 >> 15) & 0x1;
8767 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8768 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8769 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8770 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8771 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8772 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8773 tep->cxx_info = (tmp1 >> 8) & 0x1;
8774 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8775 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8776 tep->reserved2 = (tmp1 >> 5) & 0x1;
8777 tep->Save_SP = (tmp1 >> 4) & 0x1;
8778 tep->Save_RP = (tmp1 >> 3) & 0x1;
8779 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8780 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8781 tep->Cleanup_defined = tmp1 & 0x1;
8782
8783 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8784 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8785 tep->Large_frame = (tmp2 >> 29) & 0x1;
8786 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8787 tep->reserved4 = (tmp2 >> 27) & 0x1;
8788 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8789 }
8790 free (table);
8791
8792 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8793 for (relsec = filedata->section_headers;
8794 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8795 ++relsec)
8796 {
8797 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8798 || relsec->sh_info >= filedata->file_header.e_shnum
8799 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8800 continue;
8801
dda8d76d 8802 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8803 & rela, & nrelas))
015dc7e1 8804 return false;
57346661
AM
8805
8806 for (rp = rela; rp < rela + nrelas; ++rp)
8807 {
4770fb94 8808 unsigned int sym_ndx;
726bd37d
AM
8809 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8810 relname = elf_hppa_reloc_type (r_type);
57346661 8811
726bd37d
AM
8812 if (relname == NULL)
8813 {
8814 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8815 continue;
8816 }
8817
57346661 8818 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8819 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8820 {
726bd37d 8821 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8822 continue;
8823 }
8824
8825 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8826 if (i >= aux->table_len)
8827 {
8828 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8829 continue;
8830 }
57346661 8831
4770fb94
AM
8832 sym_ndx = get_reloc_symindex (rp->r_info);
8833 if (sym_ndx >= aux->nsyms)
8834 {
8835 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8836 sym_ndx);
8837 continue;
8838 }
8839 sym = aux->symtab + sym_ndx;
8840
43f6cd05 8841 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8842 {
8843 case 0:
8844 aux->table[i].start.section = sym->st_shndx;
1e456d54 8845 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8846 break;
8847 case 1:
8848 aux->table[i].end.section = sym->st_shndx;
1e456d54 8849 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8850 break;
8851 default:
8852 break;
8853 }
8854 }
8855
8856 free (rela);
8857 }
8858
015dc7e1 8859 return true;
57346661
AM
8860}
8861
015dc7e1 8862static bool
dda8d76d 8863hppa_process_unwind (Filedata * filedata)
57346661 8864{
57346661 8865 struct hppa_unw_aux_info aux;
2cf0635d 8866 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8867 Elf_Internal_Shdr * sec;
18bd398b 8868 unsigned long i;
015dc7e1 8869 bool res = true;
57346661 8870
dda8d76d 8871 if (filedata->string_table == NULL)
015dc7e1 8872 return false;
1b31d05e
NC
8873
8874 memset (& aux, 0, sizeof (aux));
57346661 8875
dda8d76d 8876 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8877 {
28d13567 8878 if (sec->sh_type == SHT_SYMTAB)
57346661 8879 {
28d13567 8880 if (aux.symtab)
4082ef84 8881 {
28d13567
AM
8882 error (_("Multiple symbol tables encountered\n"));
8883 free (aux.symtab);
8884 aux.symtab = NULL;
4082ef84 8885 free (aux.strtab);
28d13567 8886 aux.strtab = NULL;
4082ef84 8887 }
28d13567
AM
8888 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8889 &aux.strtab, &aux.strtab_size))
015dc7e1 8890 return false;
57346661 8891 }
84714f86
AM
8892 else if (section_name_valid (filedata, sec)
8893 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
8894 unwsec = sec;
8895 }
8896
8897 if (!unwsec)
8898 printf (_("\nThere are no unwind sections in this file.\n"));
8899
dda8d76d 8900 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8901 {
84714f86
AM
8902 if (section_name_valid (filedata, sec)
8903 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 8904 {
43f6cd05 8905 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8906
d3a49aa8
AM
8907 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8908 "contains %lu entry:\n",
8909 "\nUnwind section '%s' at offset 0x%lx "
8910 "contains %lu entries:\n",
8911 num_unwind),
dda8d76d 8912 printable_section_name (filedata, sec),
57346661 8913 (unsigned long) sec->sh_offset,
d3a49aa8 8914 num_unwind);
57346661 8915
dda8d76d 8916 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8917 res = false;
66b09c7e
S
8918
8919 if (res && aux.table_len > 0)
32ec8896 8920 {
dda8d76d 8921 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8922 res = false;
32ec8896 8923 }
57346661 8924
9db70fc3 8925 free ((char *) aux.table);
57346661
AM
8926 aux.table = NULL;
8927 }
8928 }
8929
9db70fc3
AM
8930 free (aux.symtab);
8931 free ((char *) aux.strtab);
32ec8896
NC
8932
8933 return res;
57346661
AM
8934}
8935
0b6ae522
DJ
8936struct arm_section
8937{
a734115a
NC
8938 unsigned char * data; /* The unwind data. */
8939 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8940 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8941 unsigned long nrelas; /* The number of relocations. */
8942 unsigned int rel_type; /* REL or RELA ? */
8943 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8944};
8945
8946struct arm_unw_aux_info
8947{
dda8d76d 8948 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8949 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8950 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8951 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8952 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8953 char * strtab; /* The file's string table. */
8954 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8955};
8956
8957static const char *
dda8d76d
NC
8958arm_print_vma_and_name (Filedata * filedata,
8959 struct arm_unw_aux_info * aux,
8960 bfd_vma fn,
8961 struct absaddr addr)
0b6ae522
DJ
8962{
8963 const char *procname;
8964 bfd_vma sym_offset;
8965
8966 if (addr.section == SHN_UNDEF)
8967 addr.offset = fn;
8968
dda8d76d 8969 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8970 aux->strtab_size, addr, &procname,
8971 &sym_offset);
8972
8973 print_vma (fn, PREFIX_HEX);
8974
8975 if (procname)
8976 {
8977 fputs (" <", stdout);
8978 fputs (procname, stdout);
8979
8980 if (sym_offset)
8981 printf ("+0x%lx", (unsigned long) sym_offset);
8982 fputc ('>', stdout);
8983 }
8984
8985 return procname;
8986}
8987
8988static void
8989arm_free_section (struct arm_section *arm_sec)
8990{
9db70fc3
AM
8991 free (arm_sec->data);
8992 free (arm_sec->rela);
0b6ae522
DJ
8993}
8994
a734115a
NC
8995/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8996 cached section and install SEC instead.
8997 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8998 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8999 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9000 relocation's offset in ADDR.
1b31d05e
NC
9001 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9002 into the string table of the symbol associated with the reloc. If no
9003 reloc was applied store -1 there.
9004 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9005
015dc7e1 9006static bool
dda8d76d
NC
9007get_unwind_section_word (Filedata * filedata,
9008 struct arm_unw_aux_info * aux,
1b31d05e
NC
9009 struct arm_section * arm_sec,
9010 Elf_Internal_Shdr * sec,
9011 bfd_vma word_offset,
9012 unsigned int * wordp,
9013 struct absaddr * addr,
9014 bfd_vma * sym_name)
0b6ae522
DJ
9015{
9016 Elf_Internal_Rela *rp;
9017 Elf_Internal_Sym *sym;
9018 const char * relname;
9019 unsigned int word;
015dc7e1 9020 bool wrapped;
0b6ae522 9021
e0a31db1 9022 if (sec == NULL || arm_sec == NULL)
015dc7e1 9023 return false;
e0a31db1 9024
0b6ae522
DJ
9025 addr->section = SHN_UNDEF;
9026 addr->offset = 0;
9027
1b31d05e
NC
9028 if (sym_name != NULL)
9029 *sym_name = (bfd_vma) -1;
9030
a734115a 9031 /* If necessary, update the section cache. */
0b6ae522
DJ
9032 if (sec != arm_sec->sec)
9033 {
9034 Elf_Internal_Shdr *relsec;
9035
9036 arm_free_section (arm_sec);
9037
9038 arm_sec->sec = sec;
dda8d76d 9039 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9040 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9041 arm_sec->rela = NULL;
9042 arm_sec->nrelas = 0;
9043
dda8d76d
NC
9044 for (relsec = filedata->section_headers;
9045 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9046 ++relsec)
9047 {
dda8d76d
NC
9048 if (relsec->sh_info >= filedata->file_header.e_shnum
9049 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9050 /* PR 15745: Check the section type as well. */
9051 || (relsec->sh_type != SHT_REL
9052 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9053 continue;
9054
a734115a 9055 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9056 if (relsec->sh_type == SHT_REL)
9057 {
dda8d76d 9058 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9059 relsec->sh_size,
9060 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9061 return false;
0b6ae522 9062 }
1ae40aa4 9063 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9064 {
dda8d76d 9065 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9066 relsec->sh_size,
9067 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9068 return false;
0b6ae522 9069 }
1ae40aa4 9070 break;
0b6ae522
DJ
9071 }
9072
9073 arm_sec->next_rela = arm_sec->rela;
9074 }
9075
a734115a 9076 /* If there is no unwind data we can do nothing. */
0b6ae522 9077 if (arm_sec->data == NULL)
015dc7e1 9078 return false;
0b6ae522 9079
e0a31db1 9080 /* If the offset is invalid then fail. */
f32ba729
NC
9081 if (/* PR 21343 *//* PR 18879 */
9082 sec->sh_size < 4
9083 || word_offset > (sec->sh_size - 4)
1a915552 9084 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9085 return false;
e0a31db1 9086
a734115a 9087 /* Get the word at the required offset. */
0b6ae522
DJ
9088 word = byte_get (arm_sec->data + word_offset, 4);
9089
0eff7165
NC
9090 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9091 if (arm_sec->rela == NULL)
9092 {
9093 * wordp = word;
015dc7e1 9094 return true;
0eff7165
NC
9095 }
9096
a734115a 9097 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9098 wrapped = false;
0b6ae522
DJ
9099 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9100 {
9101 bfd_vma prelval, offset;
9102
9103 if (rp->r_offset > word_offset && !wrapped)
9104 {
9105 rp = arm_sec->rela;
015dc7e1 9106 wrapped = true;
0b6ae522
DJ
9107 }
9108 if (rp->r_offset > word_offset)
9109 break;
9110
9111 if (rp->r_offset & 3)
9112 {
9113 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9114 (unsigned long) rp->r_offset);
9115 continue;
9116 }
9117
9118 if (rp->r_offset < word_offset)
9119 continue;
9120
74e1a04b
NC
9121 /* PR 17531: file: 027-161405-0.004 */
9122 if (aux->symtab == NULL)
9123 continue;
9124
0b6ae522
DJ
9125 if (arm_sec->rel_type == SHT_REL)
9126 {
9127 offset = word & 0x7fffffff;
9128 if (offset & 0x40000000)
9129 offset |= ~ (bfd_vma) 0x7fffffff;
9130 }
a734115a 9131 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9132 offset = rp->r_addend;
a734115a 9133 else
74e1a04b
NC
9134 {
9135 error (_("Unknown section relocation type %d encountered\n"),
9136 arm_sec->rel_type);
9137 break;
9138 }
0b6ae522 9139
071436c6
NC
9140 /* PR 17531 file: 027-1241568-0.004. */
9141 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9142 {
9143 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9144 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9145 break;
9146 }
9147
9148 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9149 offset += sym->st_value;
9150 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9151
a734115a 9152 /* Check that we are processing the expected reloc type. */
dda8d76d 9153 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9154 {
9155 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9156 if (relname == NULL)
9157 {
9158 warn (_("Skipping unknown ARM relocation type: %d\n"),
9159 (int) ELF32_R_TYPE (rp->r_info));
9160 continue;
9161 }
a734115a
NC
9162
9163 if (streq (relname, "R_ARM_NONE"))
9164 continue;
0b4362b0 9165
a734115a
NC
9166 if (! streq (relname, "R_ARM_PREL31"))
9167 {
071436c6 9168 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9169 continue;
9170 }
9171 }
dda8d76d 9172 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9173 {
9174 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9175 if (relname == NULL)
9176 {
9177 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9178 (int) ELF32_R_TYPE (rp->r_info));
9179 continue;
9180 }
0b4362b0 9181
a734115a
NC
9182 if (streq (relname, "R_C6000_NONE"))
9183 continue;
9184
9185 if (! streq (relname, "R_C6000_PREL31"))
9186 {
071436c6 9187 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9188 continue;
9189 }
9190
9191 prelval >>= 1;
9192 }
9193 else
74e1a04b
NC
9194 {
9195 /* This function currently only supports ARM and TI unwinders. */
9196 warn (_("Only TI and ARM unwinders are currently supported\n"));
9197 break;
9198 }
fa197c1c 9199
0b6ae522
DJ
9200 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9201 addr->section = sym->st_shndx;
9202 addr->offset = offset;
74e1a04b 9203
1b31d05e
NC
9204 if (sym_name)
9205 * sym_name = sym->st_name;
0b6ae522
DJ
9206 break;
9207 }
9208
9209 *wordp = word;
9210 arm_sec->next_rela = rp;
9211
015dc7e1 9212 return true;
0b6ae522
DJ
9213}
9214
a734115a
NC
9215static const char *tic6x_unwind_regnames[16] =
9216{
0b4362b0
RM
9217 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9218 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9219 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9220};
fa197c1c 9221
0b6ae522 9222static void
fa197c1c 9223decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9224{
fa197c1c
PB
9225 int i;
9226
9227 for (i = 12; mask; mask >>= 1, i--)
9228 {
9229 if (mask & 1)
9230 {
9231 fputs (tic6x_unwind_regnames[i], stdout);
9232 if (mask > 1)
9233 fputs (", ", stdout);
9234 }
9235 }
9236}
0b6ae522
DJ
9237
9238#define ADVANCE \
9239 if (remaining == 0 && more_words) \
9240 { \
9241 data_offset += 4; \
dda8d76d 9242 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9243 data_offset, & word, & addr, NULL)) \
015dc7e1 9244 return false; \
0b6ae522
DJ
9245 remaining = 4; \
9246 more_words--; \
9247 } \
9248
9249#define GET_OP(OP) \
9250 ADVANCE; \
9251 if (remaining) \
9252 { \
9253 remaining--; \
9254 (OP) = word >> 24; \
9255 word <<= 8; \
9256 } \
9257 else \
9258 { \
2b692964 9259 printf (_("[Truncated opcode]\n")); \
015dc7e1 9260 return false; \
0b6ae522 9261 } \
cc5914eb 9262 printf ("0x%02x ", OP)
0b6ae522 9263
015dc7e1 9264static bool
dda8d76d
NC
9265decode_arm_unwind_bytecode (Filedata * filedata,
9266 struct arm_unw_aux_info * aux,
948f632f
DA
9267 unsigned int word,
9268 unsigned int remaining,
9269 unsigned int more_words,
9270 bfd_vma data_offset,
9271 Elf_Internal_Shdr * data_sec,
9272 struct arm_section * data_arm_sec)
fa197c1c
PB
9273{
9274 struct absaddr addr;
015dc7e1 9275 bool res = true;
0b6ae522
DJ
9276
9277 /* Decode the unwinding instructions. */
9278 while (1)
9279 {
9280 unsigned int op, op2;
9281
9282 ADVANCE;
9283 if (remaining == 0)
9284 break;
9285 remaining--;
9286 op = word >> 24;
9287 word <<= 8;
9288
cc5914eb 9289 printf (" 0x%02x ", op);
0b6ae522
DJ
9290
9291 if ((op & 0xc0) == 0x00)
9292 {
9293 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9294
cc5914eb 9295 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9296 }
9297 else if ((op & 0xc0) == 0x40)
9298 {
9299 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9300
cc5914eb 9301 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9302 }
9303 else if ((op & 0xf0) == 0x80)
9304 {
9305 GET_OP (op2);
9306 if (op == 0x80 && op2 == 0)
9307 printf (_("Refuse to unwind"));
9308 else
9309 {
9310 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9311 bool first = true;
0b6ae522 9312 int i;
2b692964 9313
0b6ae522
DJ
9314 printf ("pop {");
9315 for (i = 0; i < 12; i++)
9316 if (mask & (1 << i))
9317 {
9318 if (first)
015dc7e1 9319 first = false;
0b6ae522
DJ
9320 else
9321 printf (", ");
9322 printf ("r%d", 4 + i);
9323 }
9324 printf ("}");
9325 }
9326 }
9327 else if ((op & 0xf0) == 0x90)
9328 {
9329 if (op == 0x9d || op == 0x9f)
9330 printf (_(" [Reserved]"));
9331 else
cc5914eb 9332 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9333 }
9334 else if ((op & 0xf0) == 0xa0)
9335 {
9336 int end = 4 + (op & 0x07);
015dc7e1 9337 bool first = true;
0b6ae522 9338 int i;
61865e30 9339
0b6ae522
DJ
9340 printf (" pop {");
9341 for (i = 4; i <= end; i++)
9342 {
9343 if (first)
015dc7e1 9344 first = false;
0b6ae522
DJ
9345 else
9346 printf (", ");
9347 printf ("r%d", i);
9348 }
9349 if (op & 0x08)
9350 {
1b31d05e 9351 if (!first)
0b6ae522
DJ
9352 printf (", ");
9353 printf ("r14");
9354 }
9355 printf ("}");
9356 }
9357 else if (op == 0xb0)
9358 printf (_(" finish"));
9359 else if (op == 0xb1)
9360 {
9361 GET_OP (op2);
9362 if (op2 == 0 || (op2 & 0xf0) != 0)
9363 printf (_("[Spare]"));
9364 else
9365 {
9366 unsigned int mask = op2 & 0x0f;
015dc7e1 9367 bool first = true;
0b6ae522 9368 int i;
61865e30 9369
0b6ae522
DJ
9370 printf ("pop {");
9371 for (i = 0; i < 12; i++)
9372 if (mask & (1 << i))
9373 {
9374 if (first)
015dc7e1 9375 first = false;
0b6ae522
DJ
9376 else
9377 printf (", ");
9378 printf ("r%d", i);
9379 }
9380 printf ("}");
9381 }
9382 }
9383 else if (op == 0xb2)
9384 {
b115cf96 9385 unsigned char buf[9];
0b6ae522
DJ
9386 unsigned int i, len;
9387 unsigned long offset;
61865e30 9388
b115cf96 9389 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9390 {
9391 GET_OP (buf[i]);
9392 if ((buf[i] & 0x80) == 0)
9393 break;
9394 }
4082ef84 9395 if (i == sizeof (buf))
32ec8896 9396 {
27a45f42 9397 error (_("corrupt change to vsp\n"));
015dc7e1 9398 res = false;
32ec8896 9399 }
4082ef84
NC
9400 else
9401 {
015dc7e1 9402 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9403 assert (len == i + 1);
9404 offset = offset * 4 + 0x204;
9405 printf ("vsp = vsp + %ld", offset);
9406 }
0b6ae522 9407 }
61865e30 9408 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9409 {
61865e30
NC
9410 unsigned int first, last;
9411
9412 GET_OP (op2);
9413 first = op2 >> 4;
9414 last = op2 & 0x0f;
9415 if (op == 0xc8)
9416 first = first + 16;
9417 printf ("pop {D%d", first);
9418 if (last)
9419 printf ("-D%d", first + last);
9420 printf ("}");
9421 }
9422 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9423 {
9424 unsigned int count = op & 0x07;
9425
9426 printf ("pop {D8");
9427 if (count)
9428 printf ("-D%d", 8 + count);
9429 printf ("}");
9430 }
9431 else if (op >= 0xc0 && op <= 0xc5)
9432 {
9433 unsigned int count = op & 0x07;
9434
9435 printf (" pop {wR10");
9436 if (count)
9437 printf ("-wR%d", 10 + count);
9438 printf ("}");
9439 }
9440 else if (op == 0xc6)
9441 {
9442 unsigned int first, last;
9443
9444 GET_OP (op2);
9445 first = op2 >> 4;
9446 last = op2 & 0x0f;
9447 printf ("pop {wR%d", first);
9448 if (last)
9449 printf ("-wR%d", first + last);
9450 printf ("}");
9451 }
9452 else if (op == 0xc7)
9453 {
9454 GET_OP (op2);
9455 if (op2 == 0 || (op2 & 0xf0) != 0)
9456 printf (_("[Spare]"));
0b6ae522
DJ
9457 else
9458 {
61865e30 9459 unsigned int mask = op2 & 0x0f;
015dc7e1 9460 bool first = true;
61865e30
NC
9461 int i;
9462
9463 printf ("pop {");
9464 for (i = 0; i < 4; i++)
9465 if (mask & (1 << i))
9466 {
9467 if (first)
015dc7e1 9468 first = false;
61865e30
NC
9469 else
9470 printf (", ");
9471 printf ("wCGR%d", i);
9472 }
9473 printf ("}");
0b6ae522
DJ
9474 }
9475 }
61865e30 9476 else
32ec8896
NC
9477 {
9478 printf (_(" [unsupported opcode]"));
015dc7e1 9479 res = false;
32ec8896
NC
9480 }
9481
0b6ae522
DJ
9482 printf ("\n");
9483 }
32ec8896
NC
9484
9485 return res;
fa197c1c
PB
9486}
9487
015dc7e1 9488static bool
dda8d76d
NC
9489decode_tic6x_unwind_bytecode (Filedata * filedata,
9490 struct arm_unw_aux_info * aux,
948f632f
DA
9491 unsigned int word,
9492 unsigned int remaining,
9493 unsigned int more_words,
9494 bfd_vma data_offset,
9495 Elf_Internal_Shdr * data_sec,
9496 struct arm_section * data_arm_sec)
fa197c1c
PB
9497{
9498 struct absaddr addr;
9499
9500 /* Decode the unwinding instructions. */
9501 while (1)
9502 {
9503 unsigned int op, op2;
9504
9505 ADVANCE;
9506 if (remaining == 0)
9507 break;
9508 remaining--;
9509 op = word >> 24;
9510 word <<= 8;
9511
9cf03b7e 9512 printf (" 0x%02x ", op);
fa197c1c
PB
9513
9514 if ((op & 0xc0) == 0x00)
9515 {
9516 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9517 printf (" sp = sp + %d", offset);
fa197c1c
PB
9518 }
9519 else if ((op & 0xc0) == 0x80)
9520 {
9521 GET_OP (op2);
9522 if (op == 0x80 && op2 == 0)
9523 printf (_("Refuse to unwind"));
9524 else
9525 {
9526 unsigned int mask = ((op & 0x1f) << 8) | op2;
9527 if (op & 0x20)
9528 printf ("pop compact {");
9529 else
9530 printf ("pop {");
9531
9532 decode_tic6x_unwind_regmask (mask);
9533 printf("}");
9534 }
9535 }
9536 else if ((op & 0xf0) == 0xc0)
9537 {
9538 unsigned int reg;
9539 unsigned int nregs;
9540 unsigned int i;
9541 const char *name;
a734115a
NC
9542 struct
9543 {
32ec8896
NC
9544 unsigned int offset;
9545 unsigned int reg;
fa197c1c
PB
9546 } regpos[16];
9547
9548 /* Scan entire instruction first so that GET_OP output is not
9549 interleaved with disassembly. */
9550 nregs = 0;
9551 for (i = 0; nregs < (op & 0xf); i++)
9552 {
9553 GET_OP (op2);
9554 reg = op2 >> 4;
9555 if (reg != 0xf)
9556 {
9557 regpos[nregs].offset = i * 2;
9558 regpos[nregs].reg = reg;
9559 nregs++;
9560 }
9561
9562 reg = op2 & 0xf;
9563 if (reg != 0xf)
9564 {
9565 regpos[nregs].offset = i * 2 + 1;
9566 regpos[nregs].reg = reg;
9567 nregs++;
9568 }
9569 }
9570
9571 printf (_("pop frame {"));
18344509 9572 if (nregs == 0)
fa197c1c 9573 {
18344509
NC
9574 printf (_("*corrupt* - no registers specified"));
9575 }
9576 else
9577 {
9578 reg = nregs - 1;
9579 for (i = i * 2; i > 0; i--)
fa197c1c 9580 {
18344509
NC
9581 if (regpos[reg].offset == i - 1)
9582 {
9583 name = tic6x_unwind_regnames[regpos[reg].reg];
9584 if (reg > 0)
9585 reg--;
9586 }
9587 else
9588 name = _("[pad]");
fa197c1c 9589
18344509
NC
9590 fputs (name, stdout);
9591 if (i > 1)
9592 printf (", ");
9593 }
fa197c1c
PB
9594 }
9595
9596 printf ("}");
9597 }
9598 else if (op == 0xd0)
9599 printf (" MOV FP, SP");
9600 else if (op == 0xd1)
9601 printf (" __c6xabi_pop_rts");
9602 else if (op == 0xd2)
9603 {
9604 unsigned char buf[9];
9605 unsigned int i, len;
9606 unsigned long offset;
a734115a 9607
fa197c1c
PB
9608 for (i = 0; i < sizeof (buf); i++)
9609 {
9610 GET_OP (buf[i]);
9611 if ((buf[i] & 0x80) == 0)
9612 break;
9613 }
0eff7165
NC
9614 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9615 if (i == sizeof (buf))
9616 {
0eff7165 9617 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9618 return false;
0eff7165 9619 }
948f632f 9620
015dc7e1 9621 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9622 assert (len == i + 1);
9623 offset = offset * 8 + 0x408;
9624 printf (_("sp = sp + %ld"), offset);
9625 }
9626 else if ((op & 0xf0) == 0xe0)
9627 {
9628 if ((op & 0x0f) == 7)
9629 printf (" RETURN");
9630 else
9631 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9632 }
9633 else
9634 {
9635 printf (_(" [unsupported opcode]"));
9636 }
9637 putchar ('\n');
9638 }
32ec8896 9639
015dc7e1 9640 return true;
fa197c1c
PB
9641}
9642
9643static bfd_vma
dda8d76d 9644arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9645{
9646 bfd_vma offset;
9647
9648 offset = word & 0x7fffffff;
9649 if (offset & 0x40000000)
9650 offset |= ~ (bfd_vma) 0x7fffffff;
9651
dda8d76d 9652 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9653 offset <<= 1;
9654
9655 return offset + where;
9656}
9657
015dc7e1 9658static bool
dda8d76d
NC
9659decode_arm_unwind (Filedata * filedata,
9660 struct arm_unw_aux_info * aux,
1b31d05e
NC
9661 unsigned int word,
9662 unsigned int remaining,
9663 bfd_vma data_offset,
9664 Elf_Internal_Shdr * data_sec,
9665 struct arm_section * data_arm_sec)
fa197c1c
PB
9666{
9667 int per_index;
9668 unsigned int more_words = 0;
37e14bc3 9669 struct absaddr addr;
1b31d05e 9670 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9671 bool res = true;
fa197c1c
PB
9672
9673 if (remaining == 0)
9674 {
1b31d05e
NC
9675 /* Fetch the first word.
9676 Note - when decoding an object file the address extracted
9677 here will always be 0. So we also pass in the sym_name
9678 parameter so that we can find the symbol associated with
9679 the personality routine. */
dda8d76d 9680 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9681 & word, & addr, & sym_name))
015dc7e1 9682 return false;
1b31d05e 9683
fa197c1c
PB
9684 remaining = 4;
9685 }
c93dbb25
CZ
9686 else
9687 {
9688 addr.section = SHN_UNDEF;
9689 addr.offset = 0;
9690 }
fa197c1c
PB
9691
9692 if ((word & 0x80000000) == 0)
9693 {
9694 /* Expand prel31 for personality routine. */
9695 bfd_vma fn;
9696 const char *procname;
9697
dda8d76d 9698 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9699 printf (_(" Personality routine: "));
1b31d05e
NC
9700 if (fn == 0
9701 && addr.section == SHN_UNDEF && addr.offset == 0
9702 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9703 {
9704 procname = aux->strtab + sym_name;
9705 print_vma (fn, PREFIX_HEX);
9706 if (procname)
9707 {
9708 fputs (" <", stdout);
9709 fputs (procname, stdout);
9710 fputc ('>', stdout);
9711 }
9712 }
9713 else
dda8d76d 9714 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9715 fputc ('\n', stdout);
9716
9717 /* The GCC personality routines use the standard compact
9718 encoding, starting with one byte giving the number of
9719 words. */
9720 if (procname != NULL
24d127aa
ML
9721 && (startswith (procname, "__gcc_personality_v0")
9722 || startswith (procname, "__gxx_personality_v0")
9723 || startswith (procname, "__gcj_personality_v0")
9724 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9725 {
9726 remaining = 0;
9727 more_words = 1;
9728 ADVANCE;
9729 if (!remaining)
9730 {
9731 printf (_(" [Truncated data]\n"));
015dc7e1 9732 return false;
fa197c1c
PB
9733 }
9734 more_words = word >> 24;
9735 word <<= 8;
9736 remaining--;
9737 per_index = -1;
9738 }
9739 else
015dc7e1 9740 return true;
fa197c1c
PB
9741 }
9742 else
9743 {
1b31d05e 9744 /* ARM EHABI Section 6.3:
0b4362b0 9745
1b31d05e 9746 An exception-handling table entry for the compact model looks like:
0b4362b0 9747
1b31d05e
NC
9748 31 30-28 27-24 23-0
9749 -- ----- ----- ----
9750 1 0 index Data for personalityRoutine[index] */
9751
dda8d76d 9752 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9753 && (word & 0x70000000))
32ec8896
NC
9754 {
9755 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9756 res = false;
32ec8896 9757 }
1b31d05e 9758
fa197c1c 9759 per_index = (word >> 24) & 0x7f;
1b31d05e 9760 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9761 if (per_index == 0)
9762 {
9763 more_words = 0;
9764 word <<= 8;
9765 remaining--;
9766 }
9767 else if (per_index < 3)
9768 {
9769 more_words = (word >> 16) & 0xff;
9770 word <<= 16;
9771 remaining -= 2;
9772 }
9773 }
9774
dda8d76d 9775 switch (filedata->file_header.e_machine)
fa197c1c
PB
9776 {
9777 case EM_ARM:
9778 if (per_index < 3)
9779 {
dda8d76d 9780 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9781 data_offset, data_sec, data_arm_sec))
015dc7e1 9782 res = false;
fa197c1c
PB
9783 }
9784 else
1b31d05e
NC
9785 {
9786 warn (_("Unknown ARM compact model index encountered\n"));
9787 printf (_(" [reserved]\n"));
015dc7e1 9788 res = false;
1b31d05e 9789 }
fa197c1c
PB
9790 break;
9791
9792 case EM_TI_C6000:
9793 if (per_index < 3)
9794 {
dda8d76d 9795 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9796 data_offset, data_sec, data_arm_sec))
015dc7e1 9797 res = false;
fa197c1c
PB
9798 }
9799 else if (per_index < 5)
9800 {
9801 if (((word >> 17) & 0x7f) == 0x7f)
9802 printf (_(" Restore stack from frame pointer\n"));
9803 else
9804 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9805 printf (_(" Registers restored: "));
9806 if (per_index == 4)
9807 printf (" (compact) ");
9808 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9809 putchar ('\n');
9810 printf (_(" Return register: %s\n"),
9811 tic6x_unwind_regnames[word & 0xf]);
9812 }
9813 else
1b31d05e 9814 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9815 break;
9816
9817 default:
74e1a04b 9818 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9819 filedata->file_header.e_machine);
015dc7e1 9820 res = false;
fa197c1c 9821 }
0b6ae522
DJ
9822
9823 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9824
9825 return res;
0b6ae522
DJ
9826}
9827
015dc7e1 9828static bool
dda8d76d
NC
9829dump_arm_unwind (Filedata * filedata,
9830 struct arm_unw_aux_info * aux,
9831 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9832{
9833 struct arm_section exidx_arm_sec, extab_arm_sec;
9834 unsigned int i, exidx_len;
948f632f 9835 unsigned long j, nfuns;
015dc7e1 9836 bool res = true;
0b6ae522
DJ
9837
9838 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9839 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9840 exidx_len = exidx_sec->sh_size / 8;
9841
948f632f
DA
9842 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9843 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9844 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9845 aux->funtab[nfuns++] = aux->symtab[j];
9846 aux->nfuns = nfuns;
9847 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9848
0b6ae522
DJ
9849 for (i = 0; i < exidx_len; i++)
9850 {
9851 unsigned int exidx_fn, exidx_entry;
9852 struct absaddr fn_addr, entry_addr;
9853 bfd_vma fn;
9854
9855 fputc ('\n', stdout);
9856
dda8d76d 9857 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9858 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9859 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9860 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9861 {
948f632f 9862 free (aux->funtab);
1b31d05e
NC
9863 arm_free_section (& exidx_arm_sec);
9864 arm_free_section (& extab_arm_sec);
015dc7e1 9865 return false;
0b6ae522
DJ
9866 }
9867
83c257ca
NC
9868 /* ARM EHABI, Section 5:
9869 An index table entry consists of 2 words.
9870 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9871 if (exidx_fn & 0x80000000)
32ec8896
NC
9872 {
9873 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9874 res = false;
32ec8896 9875 }
83c257ca 9876
dda8d76d 9877 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9878
dda8d76d 9879 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9880 fputs (": ", stdout);
9881
9882 if (exidx_entry == 1)
9883 {
9884 print_vma (exidx_entry, PREFIX_HEX);
9885 fputs (" [cantunwind]\n", stdout);
9886 }
9887 else if (exidx_entry & 0x80000000)
9888 {
9889 print_vma (exidx_entry, PREFIX_HEX);
9890 fputc ('\n', stdout);
dda8d76d 9891 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9892 }
9893 else
9894 {
8f73510c 9895 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9896 Elf_Internal_Shdr *table_sec;
9897
9898 fputs ("@", stdout);
dda8d76d 9899 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9900 print_vma (table, PREFIX_HEX);
9901 printf ("\n");
9902
9903 /* Locate the matching .ARM.extab. */
9904 if (entry_addr.section != SHN_UNDEF
dda8d76d 9905 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9906 {
dda8d76d 9907 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9908 table_offset = entry_addr.offset;
1a915552
NC
9909 /* PR 18879 */
9910 if (table_offset > table_sec->sh_size
9911 || ((bfd_signed_vma) table_offset) < 0)
9912 {
9913 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9914 (unsigned long) table_offset,
dda8d76d 9915 printable_section_name (filedata, table_sec));
015dc7e1 9916 res = false;
1a915552
NC
9917 continue;
9918 }
0b6ae522
DJ
9919 }
9920 else
9921 {
dda8d76d 9922 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9923 if (table_sec != NULL)
9924 table_offset = table - table_sec->sh_addr;
9925 }
32ec8896 9926
0b6ae522
DJ
9927 if (table_sec == NULL)
9928 {
9929 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9930 (unsigned long) table);
015dc7e1 9931 res = false;
0b6ae522
DJ
9932 continue;
9933 }
32ec8896 9934
dda8d76d 9935 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9936 &extab_arm_sec))
015dc7e1 9937 res = false;
0b6ae522
DJ
9938 }
9939 }
9940
9941 printf ("\n");
9942
948f632f 9943 free (aux->funtab);
0b6ae522
DJ
9944 arm_free_section (&exidx_arm_sec);
9945 arm_free_section (&extab_arm_sec);
32ec8896
NC
9946
9947 return res;
0b6ae522
DJ
9948}
9949
fa197c1c 9950/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9951
015dc7e1 9952static bool
dda8d76d 9953arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9954{
9955 struct arm_unw_aux_info aux;
9956 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9957 Elf_Internal_Shdr *sec;
9958 unsigned long i;
fa197c1c 9959 unsigned int sec_type;
015dc7e1 9960 bool res = true;
0b6ae522 9961
dda8d76d 9962 switch (filedata->file_header.e_machine)
fa197c1c
PB
9963 {
9964 case EM_ARM:
9965 sec_type = SHT_ARM_EXIDX;
9966 break;
9967
9968 case EM_TI_C6000:
9969 sec_type = SHT_C6000_UNWIND;
9970 break;
9971
0b4362b0 9972 default:
74e1a04b 9973 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9974 filedata->file_header.e_machine);
015dc7e1 9975 return false;
fa197c1c
PB
9976 }
9977
dda8d76d 9978 if (filedata->string_table == NULL)
015dc7e1 9979 return false;
1b31d05e
NC
9980
9981 memset (& aux, 0, sizeof (aux));
dda8d76d 9982 aux.filedata = filedata;
0b6ae522 9983
dda8d76d 9984 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9985 {
28d13567 9986 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9987 {
28d13567 9988 if (aux.symtab)
74e1a04b 9989 {
28d13567
AM
9990 error (_("Multiple symbol tables encountered\n"));
9991 free (aux.symtab);
9992 aux.symtab = NULL;
74e1a04b 9993 free (aux.strtab);
28d13567 9994 aux.strtab = NULL;
74e1a04b 9995 }
28d13567
AM
9996 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9997 &aux.strtab, &aux.strtab_size))
015dc7e1 9998 return false;
0b6ae522 9999 }
fa197c1c 10000 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10001 unwsec = sec;
10002 }
10003
1b31d05e 10004 if (unwsec == NULL)
0b6ae522 10005 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10006 else
dda8d76d 10007 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10008 {
10009 if (sec->sh_type == sec_type)
10010 {
d3a49aa8
AM
10011 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10012 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10013 "contains %lu entry:\n",
10014 "\nUnwind section '%s' at offset 0x%lx "
10015 "contains %lu entries:\n",
10016 num_unwind),
dda8d76d 10017 printable_section_name (filedata, sec),
1b31d05e 10018 (unsigned long) sec->sh_offset,
d3a49aa8 10019 num_unwind);
0b6ae522 10020
dda8d76d 10021 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10022 res = false;
1b31d05e
NC
10023 }
10024 }
0b6ae522 10025
9db70fc3
AM
10026 free (aux.symtab);
10027 free ((char *) aux.strtab);
32ec8896
NC
10028
10029 return res;
0b6ae522
DJ
10030}
10031
3ecc00ec
NC
10032static bool
10033no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10034{
10035 printf (_("No processor specific unwind information to decode\n"));
10036 return true;
10037}
10038
015dc7e1 10039static bool
dda8d76d 10040process_unwind (Filedata * filedata)
57346661 10041{
2cf0635d
NC
10042 struct unwind_handler
10043 {
32ec8896 10044 unsigned int machtype;
015dc7e1 10045 bool (* handler)(Filedata *);
2cf0635d
NC
10046 } handlers[] =
10047 {
0b6ae522 10048 { EM_ARM, arm_process_unwind },
57346661
AM
10049 { EM_IA_64, ia64_process_unwind },
10050 { EM_PARISC, hppa_process_unwind },
fa197c1c 10051 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10052 { EM_386, no_processor_specific_unwind },
10053 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10054 { 0, NULL }
57346661
AM
10055 };
10056 int i;
10057
10058 if (!do_unwind)
015dc7e1 10059 return true;
57346661
AM
10060
10061 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10062 if (filedata->file_header.e_machine == handlers[i].machtype)
10063 return handlers[i].handler (filedata);
57346661 10064
1b31d05e 10065 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10066 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10067 return true;
57346661
AM
10068}
10069
37c18eed
SD
10070static void
10071dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10072{
10073 switch (entry->d_tag)
10074 {
10075 case DT_AARCH64_BTI_PLT:
1dbade74 10076 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10077 break;
10078 default:
10079 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10080 break;
10081 }
10082 putchar ('\n');
10083}
10084
252b5132 10085static void
978c4450 10086dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10087{
10088 switch (entry->d_tag)
10089 {
10090 case DT_MIPS_FLAGS:
10091 if (entry->d_un.d_val == 0)
4b68bca3 10092 printf (_("NONE"));
252b5132
RH
10093 else
10094 {
10095 static const char * opts[] =
10096 {
10097 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10098 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10099 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10100 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10101 "RLD_ORDER_SAFE"
10102 };
10103 unsigned int cnt;
015dc7e1 10104 bool first = true;
2b692964 10105
60bca95a 10106 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10107 if (entry->d_un.d_val & (1 << cnt))
10108 {
10109 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10110 first = false;
252b5132 10111 }
252b5132
RH
10112 }
10113 break;
103f02d3 10114
252b5132 10115 case DT_MIPS_IVERSION:
84714f86 10116 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10117 printf (_("Interface Version: %s"),
84714f86 10118 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10119 else
76ca31c0
NC
10120 {
10121 char buf[40];
10122 sprintf_vma (buf, entry->d_un.d_ptr);
10123 /* Note: coded this way so that there is a single string for translation. */
10124 printf (_("<corrupt: %s>"), buf);
10125 }
252b5132 10126 break;
103f02d3 10127
252b5132
RH
10128 case DT_MIPS_TIME_STAMP:
10129 {
d5b07ef4 10130 char timebuf[128];
2cf0635d 10131 struct tm * tmp;
91d6fa6a 10132 time_t atime = entry->d_un.d_val;
82b1b41b 10133
91d6fa6a 10134 tmp = gmtime (&atime);
82b1b41b
NC
10135 /* PR 17531: file: 6accc532. */
10136 if (tmp == NULL)
10137 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10138 else
10139 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10140 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10141 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10142 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10143 }
10144 break;
103f02d3 10145
252b5132
RH
10146 case DT_MIPS_RLD_VERSION:
10147 case DT_MIPS_LOCAL_GOTNO:
10148 case DT_MIPS_CONFLICTNO:
10149 case DT_MIPS_LIBLISTNO:
10150 case DT_MIPS_SYMTABNO:
10151 case DT_MIPS_UNREFEXTNO:
10152 case DT_MIPS_HIPAGENO:
10153 case DT_MIPS_DELTA_CLASS_NO:
10154 case DT_MIPS_DELTA_INSTANCE_NO:
10155 case DT_MIPS_DELTA_RELOC_NO:
10156 case DT_MIPS_DELTA_SYM_NO:
10157 case DT_MIPS_DELTA_CLASSSYM_NO:
10158 case DT_MIPS_COMPACT_SIZE:
c69075ac 10159 print_vma (entry->d_un.d_val, DEC);
252b5132 10160 break;
103f02d3 10161
f16a9783 10162 case DT_MIPS_XHASH:
978c4450
AM
10163 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10164 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10165 /* Falls through. */
10166
103f02d3 10167 default:
4b68bca3 10168 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10169 }
4b68bca3 10170 putchar ('\n');
103f02d3
UD
10171}
10172
103f02d3 10173static void
2cf0635d 10174dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10175{
10176 switch (entry->d_tag)
10177 {
10178 case DT_HP_DLD_FLAGS:
10179 {
10180 static struct
10181 {
10182 long int bit;
2cf0635d 10183 const char * str;
5e220199
NC
10184 }
10185 flags[] =
10186 {
10187 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10188 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10189 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10190 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10191 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10192 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10193 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10194 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10195 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10196 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10197 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10198 { DT_HP_GST, "HP_GST" },
10199 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10200 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10201 { DT_HP_NODELETE, "HP_NODELETE" },
10202 { DT_HP_GROUP, "HP_GROUP" },
10203 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10204 };
015dc7e1 10205 bool first = true;
5e220199 10206 size_t cnt;
f7a99963 10207 bfd_vma val = entry->d_un.d_val;
103f02d3 10208
60bca95a 10209 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10210 if (val & flags[cnt].bit)
30800947
NC
10211 {
10212 if (! first)
10213 putchar (' ');
10214 fputs (flags[cnt].str, stdout);
015dc7e1 10215 first = false;
30800947
NC
10216 val ^= flags[cnt].bit;
10217 }
76da6bbe 10218
103f02d3 10219 if (val != 0 || first)
f7a99963
NC
10220 {
10221 if (! first)
10222 putchar (' ');
10223 print_vma (val, HEX);
10224 }
103f02d3
UD
10225 }
10226 break;
76da6bbe 10227
252b5132 10228 default:
f7a99963
NC
10229 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10230 break;
252b5132 10231 }
35b1837e 10232 putchar ('\n');
252b5132
RH
10233}
10234
28f997cf
TG
10235#ifdef BFD64
10236
10237/* VMS vs Unix time offset and factor. */
10238
10239#define VMS_EPOCH_OFFSET 35067168000000000LL
10240#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10241#ifndef INT64_MIN
10242#define INT64_MIN (-9223372036854775807LL - 1)
10243#endif
28f997cf
TG
10244
10245/* Display a VMS time in a human readable format. */
10246
10247static void
10248print_vms_time (bfd_int64_t vmstime)
10249{
dccc31de 10250 struct tm *tm = NULL;
28f997cf
TG
10251 time_t unxtime;
10252
dccc31de
AM
10253 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10254 {
10255 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10256 unxtime = vmstime;
10257 if (unxtime == vmstime)
10258 tm = gmtime (&unxtime);
10259 }
10260 if (tm != NULL)
10261 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10262 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10263 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10264}
10265#endif /* BFD64 */
10266
ecc51f48 10267static void
2cf0635d 10268dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10269{
10270 switch (entry->d_tag)
10271 {
0de14b54 10272 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10273 /* First 3 slots reserved. */
ecc51f48
NC
10274 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10275 printf (" -- ");
10276 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10277 break;
10278
28f997cf
TG
10279 case DT_IA_64_VMS_LINKTIME:
10280#ifdef BFD64
10281 print_vms_time (entry->d_un.d_val);
10282#endif
10283 break;
10284
10285 case DT_IA_64_VMS_LNKFLAGS:
10286 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10287 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10288 printf (" CALL_DEBUG");
10289 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10290 printf (" NOP0BUFS");
10291 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10292 printf (" P0IMAGE");
10293 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10294 printf (" MKTHREADS");
10295 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10296 printf (" UPCALLS");
10297 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10298 printf (" IMGSTA");
10299 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10300 printf (" INITIALIZE");
10301 if (entry->d_un.d_val & VMS_LF_MAIN)
10302 printf (" MAIN");
10303 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10304 printf (" EXE_INIT");
10305 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10306 printf (" TBK_IN_IMG");
10307 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10308 printf (" DBG_IN_IMG");
10309 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10310 printf (" TBK_IN_DSF");
10311 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10312 printf (" DBG_IN_DSF");
10313 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10314 printf (" SIGNATURES");
10315 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10316 printf (" REL_SEG_OFF");
10317 break;
10318
bdf4d63a
JJ
10319 default:
10320 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10321 break;
ecc51f48 10322 }
bdf4d63a 10323 putchar ('\n');
ecc51f48
NC
10324}
10325
015dc7e1 10326static bool
dda8d76d 10327get_32bit_dynamic_section (Filedata * filedata)
252b5132 10328{
2cf0635d
NC
10329 Elf32_External_Dyn * edyn;
10330 Elf32_External_Dyn * ext;
10331 Elf_Internal_Dyn * entry;
103f02d3 10332
978c4450
AM
10333 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10334 filedata->dynamic_addr, 1,
10335 filedata->dynamic_size,
10336 _("dynamic section"));
a6e9f9df 10337 if (!edyn)
015dc7e1 10338 return false;
103f02d3 10339
071436c6
NC
10340 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10341 might not have the luxury of section headers. Look for the DT_NULL
10342 terminator to determine the number of entries. */
978c4450
AM
10343 for (ext = edyn, filedata->dynamic_nent = 0;
10344 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10345 ext++)
10346 {
978c4450 10347 filedata->dynamic_nent++;
ba2685cc
AM
10348 if (BYTE_GET (ext->d_tag) == DT_NULL)
10349 break;
10350 }
252b5132 10351
978c4450
AM
10352 filedata->dynamic_section
10353 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10354 if (filedata->dynamic_section == NULL)
252b5132 10355 {
8b73c356 10356 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10357 (unsigned long) filedata->dynamic_nent);
9ea033b2 10358 free (edyn);
015dc7e1 10359 return false;
9ea033b2 10360 }
252b5132 10361
978c4450
AM
10362 for (ext = edyn, entry = filedata->dynamic_section;
10363 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10364 ext++, entry++)
9ea033b2 10365 {
fb514b26
AM
10366 entry->d_tag = BYTE_GET (ext->d_tag);
10367 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10368 }
10369
9ea033b2
NC
10370 free (edyn);
10371
015dc7e1 10372 return true;
9ea033b2
NC
10373}
10374
015dc7e1 10375static bool
dda8d76d 10376get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10377{
2cf0635d
NC
10378 Elf64_External_Dyn * edyn;
10379 Elf64_External_Dyn * ext;
10380 Elf_Internal_Dyn * entry;
103f02d3 10381
071436c6 10382 /* Read in the data. */
978c4450
AM
10383 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10384 filedata->dynamic_addr, 1,
10385 filedata->dynamic_size,
10386 _("dynamic section"));
a6e9f9df 10387 if (!edyn)
015dc7e1 10388 return false;
103f02d3 10389
071436c6
NC
10390 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10391 might not have the luxury of section headers. Look for the DT_NULL
10392 terminator to determine the number of entries. */
978c4450 10393 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10394 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10395 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10396 ext++)
10397 {
978c4450 10398 filedata->dynamic_nent++;
66543521 10399 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10400 break;
10401 }
252b5132 10402
978c4450
AM
10403 filedata->dynamic_section
10404 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10405 if (filedata->dynamic_section == NULL)
252b5132 10406 {
8b73c356 10407 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10408 (unsigned long) filedata->dynamic_nent);
252b5132 10409 free (edyn);
015dc7e1 10410 return false;
252b5132
RH
10411 }
10412
071436c6 10413 /* Convert from external to internal formats. */
978c4450
AM
10414 for (ext = edyn, entry = filedata->dynamic_section;
10415 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10416 ext++, entry++)
252b5132 10417 {
66543521
AM
10418 entry->d_tag = BYTE_GET (ext->d_tag);
10419 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10420 }
10421
10422 free (edyn);
10423
015dc7e1 10424 return true;
9ea033b2
NC
10425}
10426
4de91c10
AM
10427static bool
10428get_dynamic_section (Filedata *filedata)
10429{
10430 if (filedata->dynamic_section)
10431 return true;
10432
10433 if (is_32bit_elf)
10434 return get_32bit_dynamic_section (filedata);
10435 else
10436 return get_64bit_dynamic_section (filedata);
10437}
10438
e9e44622
JJ
10439static void
10440print_dynamic_flags (bfd_vma flags)
d1133906 10441{
015dc7e1 10442 bool first = true;
13ae64f3 10443
d1133906
NC
10444 while (flags)
10445 {
10446 bfd_vma flag;
10447
10448 flag = flags & - flags;
10449 flags &= ~ flag;
10450
e9e44622 10451 if (first)
015dc7e1 10452 first = false;
e9e44622
JJ
10453 else
10454 putc (' ', stdout);
13ae64f3 10455
d1133906
NC
10456 switch (flag)
10457 {
e9e44622
JJ
10458 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10459 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10460 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10461 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10462 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10463 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10464 }
10465 }
e9e44622 10466 puts ("");
d1133906
NC
10467}
10468
10ca4b04
L
10469static bfd_vma *
10470get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10471{
10472 unsigned char * e_data;
10473 bfd_vma * i_data;
10474
10475 /* If the size_t type is smaller than the bfd_size_type, eg because
10476 you are building a 32-bit tool on a 64-bit host, then make sure
10477 that when (number) is cast to (size_t) no information is lost. */
10478 if (sizeof (size_t) < sizeof (bfd_size_type)
10479 && (bfd_size_type) ((size_t) number) != number)
10480 {
10481 error (_("Size truncation prevents reading %s elements of size %u\n"),
10482 bfd_vmatoa ("u", number), ent_size);
10483 return NULL;
10484 }
10485
10486 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10487 attempting to allocate memory when the read is bound to fail. */
10488 if (ent_size * number > filedata->file_size)
10489 {
10490 error (_("Invalid number of dynamic entries: %s\n"),
10491 bfd_vmatoa ("u", number));
10492 return NULL;
10493 }
10494
10495 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10496 if (e_data == NULL)
10497 {
10498 error (_("Out of memory reading %s dynamic entries\n"),
10499 bfd_vmatoa ("u", number));
10500 return NULL;
10501 }
10502
10503 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10504 {
10505 error (_("Unable to read in %s bytes of dynamic data\n"),
10506 bfd_vmatoa ("u", number * ent_size));
10507 free (e_data);
10508 return NULL;
10509 }
10510
10511 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10512 if (i_data == NULL)
10513 {
10514 error (_("Out of memory allocating space for %s dynamic entries\n"),
10515 bfd_vmatoa ("u", number));
10516 free (e_data);
10517 return NULL;
10518 }
10519
10520 while (number--)
10521 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10522
10523 free (e_data);
10524
10525 return i_data;
10526}
10527
10528static unsigned long
10529get_num_dynamic_syms (Filedata * filedata)
10530{
10531 unsigned long num_of_syms = 0;
10532
10533 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10534 return num_of_syms;
10535
978c4450 10536 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10537 {
10538 unsigned char nb[8];
10539 unsigned char nc[8];
10540 unsigned int hash_ent_size = 4;
10541
10542 if ((filedata->file_header.e_machine == EM_ALPHA
10543 || filedata->file_header.e_machine == EM_S390
10544 || filedata->file_header.e_machine == EM_S390_OLD)
10545 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10546 hash_ent_size = 8;
10547
10548 if (fseek (filedata->handle,
978c4450
AM
10549 (filedata->archive_file_offset
10550 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10551 sizeof nb + sizeof nc)),
10552 SEEK_SET))
10553 {
10554 error (_("Unable to seek to start of dynamic information\n"));
10555 goto no_hash;
10556 }
10557
10558 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10559 {
10560 error (_("Failed to read in number of buckets\n"));
10561 goto no_hash;
10562 }
10563
10564 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10565 {
10566 error (_("Failed to read in number of chains\n"));
10567 goto no_hash;
10568 }
10569
978c4450
AM
10570 filedata->nbuckets = byte_get (nb, hash_ent_size);
10571 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10572
2482f306
AM
10573 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10574 {
10575 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10576 hash_ent_size);
10577 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10578 hash_ent_size);
001890e1 10579
2482f306
AM
10580 if (filedata->buckets != NULL && filedata->chains != NULL)
10581 num_of_syms = filedata->nchains;
10582 }
ceb9bf11 10583 no_hash:
10ca4b04
L
10584 if (num_of_syms == 0)
10585 {
9db70fc3
AM
10586 free (filedata->buckets);
10587 filedata->buckets = NULL;
10588 free (filedata->chains);
10589 filedata->chains = NULL;
978c4450 10590 filedata->nbuckets = 0;
10ca4b04
L
10591 }
10592 }
10593
978c4450 10594 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10595 {
10596 unsigned char nb[16];
10597 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10598 bfd_vma buckets_vma;
10599 unsigned long hn;
10ca4b04
L
10600
10601 if (fseek (filedata->handle,
978c4450
AM
10602 (filedata->archive_file_offset
10603 + offset_from_vma (filedata,
10604 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10605 sizeof nb)),
10606 SEEK_SET))
10607 {
10608 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10609 goto no_gnu_hash;
10610 }
10611
10612 if (fread (nb, 16, 1, filedata->handle) != 1)
10613 {
10614 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10615 goto no_gnu_hash;
10616 }
10617
978c4450
AM
10618 filedata->ngnubuckets = byte_get (nb, 4);
10619 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10620 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10621 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10622 if (is_32bit_elf)
10623 buckets_vma += bitmaskwords * 4;
10624 else
10625 buckets_vma += bitmaskwords * 8;
10626
10627 if (fseek (filedata->handle,
978c4450 10628 (filedata->archive_file_offset
10ca4b04
L
10629 + offset_from_vma (filedata, buckets_vma, 4)),
10630 SEEK_SET))
10631 {
10632 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10633 goto no_gnu_hash;
10634 }
10635
978c4450
AM
10636 filedata->gnubuckets
10637 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10638
978c4450 10639 if (filedata->gnubuckets == NULL)
90837ea7 10640 goto no_gnu_hash;
10ca4b04 10641
978c4450
AM
10642 for (i = 0; i < filedata->ngnubuckets; i++)
10643 if (filedata->gnubuckets[i] != 0)
10ca4b04 10644 {
978c4450 10645 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10646 goto no_gnu_hash;
10ca4b04 10647
978c4450
AM
10648 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10649 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10650 }
10651
10652 if (maxchain == 0xffffffff)
90837ea7 10653 goto no_gnu_hash;
10ca4b04 10654
978c4450 10655 maxchain -= filedata->gnusymidx;
10ca4b04
L
10656
10657 if (fseek (filedata->handle,
978c4450
AM
10658 (filedata->archive_file_offset
10659 + offset_from_vma (filedata,
10660 buckets_vma + 4 * (filedata->ngnubuckets
10661 + maxchain),
10662 4)),
10ca4b04
L
10663 SEEK_SET))
10664 {
10665 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10666 goto no_gnu_hash;
10667 }
10668
10669 do
10670 {
10671 if (fread (nb, 4, 1, filedata->handle) != 1)
10672 {
10673 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10674 goto no_gnu_hash;
10675 }
10676
10677 if (maxchain + 1 == 0)
90837ea7 10678 goto no_gnu_hash;
10ca4b04
L
10679
10680 ++maxchain;
10681 }
10682 while ((byte_get (nb, 4) & 1) == 0);
10683
10684 if (fseek (filedata->handle,
978c4450
AM
10685 (filedata->archive_file_offset
10686 + offset_from_vma (filedata, (buckets_vma
10687 + 4 * filedata->ngnubuckets),
10688 4)),
10ca4b04
L
10689 SEEK_SET))
10690 {
10691 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10692 goto no_gnu_hash;
10693 }
10694
978c4450
AM
10695 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10696 filedata->ngnuchains = maxchain;
10ca4b04 10697
978c4450 10698 if (filedata->gnuchains == NULL)
90837ea7 10699 goto no_gnu_hash;
10ca4b04 10700
978c4450 10701 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10702 {
10703 if (fseek (filedata->handle,
978c4450 10704 (filedata->archive_file_offset
10ca4b04 10705 + offset_from_vma (filedata, (buckets_vma
978c4450 10706 + 4 * (filedata->ngnubuckets
10ca4b04
L
10707 + maxchain)), 4)),
10708 SEEK_SET))
10709 {
10710 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10711 goto no_gnu_hash;
10712 }
10713
978c4450 10714 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10715 if (filedata->mipsxlat == NULL)
10716 goto no_gnu_hash;
10ca4b04
L
10717 }
10718
978c4450
AM
10719 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10720 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10721 {
978c4450
AM
10722 bfd_vma si = filedata->gnubuckets[hn];
10723 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10724
10725 do
10726 {
978c4450 10727 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10728 {
c31ab5a0
AM
10729 if (off < filedata->ngnuchains
10730 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10731 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10732 }
10733 else
10734 {
10735 if (si >= num_of_syms)
10736 num_of_syms = si + 1;
10737 }
10738 si++;
10739 }
978c4450
AM
10740 while (off < filedata->ngnuchains
10741 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10742 }
10743
90837ea7 10744 if (num_of_syms == 0)
10ca4b04 10745 {
90837ea7 10746 no_gnu_hash:
9db70fc3
AM
10747 free (filedata->mipsxlat);
10748 filedata->mipsxlat = NULL;
10749 free (filedata->gnuchains);
10750 filedata->gnuchains = NULL;
10751 free (filedata->gnubuckets);
10752 filedata->gnubuckets = NULL;
978c4450
AM
10753 filedata->ngnubuckets = 0;
10754 filedata->ngnuchains = 0;
10ca4b04
L
10755 }
10756 }
10757
10758 return num_of_syms;
10759}
10760
b2d38a17
NC
10761/* Parse and display the contents of the dynamic section. */
10762
015dc7e1 10763static bool
dda8d76d 10764process_dynamic_section (Filedata * filedata)
9ea033b2 10765{
2cf0635d 10766 Elf_Internal_Dyn * entry;
9ea033b2 10767
93df3340 10768 if (filedata->dynamic_size <= 1)
9ea033b2
NC
10769 {
10770 if (do_dynamic)
ca0e11aa
NC
10771 {
10772 if (filedata->is_separate)
10773 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10774 filedata->file_name);
10775 else
10776 printf (_("\nThere is no dynamic section in this file.\n"));
10777 }
9ea033b2 10778
015dc7e1 10779 return true;
9ea033b2
NC
10780 }
10781
4de91c10
AM
10782 if (!get_dynamic_section (filedata))
10783 return false;
9ea033b2 10784
252b5132 10785 /* Find the appropriate symbol table. */
978c4450 10786 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10787 {
2482f306
AM
10788 unsigned long num_of_syms;
10789
978c4450
AM
10790 for (entry = filedata->dynamic_section;
10791 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10792 ++entry)
10ca4b04 10793 if (entry->d_tag == DT_SYMTAB)
978c4450 10794 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10795 else if (entry->d_tag == DT_SYMENT)
978c4450 10796 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10797 else if (entry->d_tag == DT_HASH)
978c4450 10798 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10799 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10800 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10801 else if ((filedata->file_header.e_machine == EM_MIPS
10802 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10803 && entry->d_tag == DT_MIPS_XHASH)
10804 {
978c4450
AM
10805 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10806 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10807 }
252b5132 10808
2482f306
AM
10809 num_of_syms = get_num_dynamic_syms (filedata);
10810
10811 if (num_of_syms != 0
10812 && filedata->dynamic_symbols == NULL
10813 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10814 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10815 {
10816 Elf_Internal_Phdr *seg;
2482f306 10817 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10818
2482f306
AM
10819 if (! get_program_headers (filedata))
10820 {
10821 error (_("Cannot interpret virtual addresses "
10822 "without program headers.\n"));
015dc7e1 10823 return false;
2482f306 10824 }
252b5132 10825
2482f306
AM
10826 for (seg = filedata->program_headers;
10827 seg < filedata->program_headers + filedata->file_header.e_phnum;
10828 ++seg)
10829 {
10830 if (seg->p_type != PT_LOAD)
10831 continue;
252b5132 10832
2482f306
AM
10833 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10834 {
10835 /* See PR 21379 for a reproducer. */
10836 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10837 return false;
2482f306 10838 }
252b5132 10839
2482f306
AM
10840 if (vma >= (seg->p_vaddr & -seg->p_align)
10841 && vma < seg->p_vaddr + seg->p_filesz)
10842 {
10843 /* Since we do not know how big the symbol table is,
10844 we default to reading in up to the end of PT_LOAD
10845 segment and processing that. This is overkill, I
10846 know, but it should work. */
10847 Elf_Internal_Shdr section;
10848 section.sh_offset = (vma - seg->p_vaddr
10849 + seg->p_offset);
10850 section.sh_size = (num_of_syms
10851 * filedata->dynamic_info[DT_SYMENT]);
10852 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10853
10854 if (do_checks
10855 && filedata->dynamic_symtab_section != NULL
10856 && ((filedata->dynamic_symtab_section->sh_offset
10857 != section.sh_offset)
10858 || (filedata->dynamic_symtab_section->sh_size
10859 != section.sh_size)
10860 || (filedata->dynamic_symtab_section->sh_entsize
10861 != section.sh_entsize)))
10862 warn (_("\
10863the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10864
2482f306
AM
10865 section.sh_name = filedata->string_table_length;
10866 filedata->dynamic_symbols
4de91c10 10867 = get_elf_symbols (filedata, &section,
2482f306
AM
10868 &filedata->num_dynamic_syms);
10869 if (filedata->dynamic_symbols == NULL
10870 || filedata->num_dynamic_syms != num_of_syms)
10871 {
10872 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10873 return false;
2482f306
AM
10874 }
10875 break;
10876 }
10877 }
10878 }
10879 }
252b5132
RH
10880
10881 /* Similarly find a string table. */
978c4450
AM
10882 if (filedata->dynamic_strings == NULL)
10883 for (entry = filedata->dynamic_section;
10884 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10885 ++entry)
10886 {
10887 if (entry->d_tag == DT_STRTAB)
978c4450 10888 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10889
10ca4b04 10890 if (entry->d_tag == DT_STRSZ)
978c4450 10891 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10892
978c4450
AM
10893 if (filedata->dynamic_info[DT_STRTAB]
10894 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10895 {
10896 unsigned long offset;
978c4450 10897 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10898
10899 offset = offset_from_vma (filedata,
978c4450 10900 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10901 str_tab_len);
8ac10c5b
L
10902 if (do_checks
10903 && filedata->dynamic_strtab_section
10904 && ((filedata->dynamic_strtab_section->sh_offset
10905 != (file_ptr) offset)
10906 || (filedata->dynamic_strtab_section->sh_size
10907 != str_tab_len)))
10908 warn (_("\
10909the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10910
978c4450
AM
10911 filedata->dynamic_strings
10912 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10913 _("dynamic string table"));
10914 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10915 {
10916 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10917 break;
10918 }
e3d39609 10919
978c4450 10920 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10921 break;
10922 }
10923 }
252b5132
RH
10924
10925 /* And find the syminfo section if available. */
978c4450 10926 if (filedata->dynamic_syminfo == NULL)
252b5132 10927 {
3e8bba36 10928 unsigned long syminsz = 0;
252b5132 10929
978c4450
AM
10930 for (entry = filedata->dynamic_section;
10931 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10932 ++entry)
252b5132
RH
10933 {
10934 if (entry->d_tag == DT_SYMINENT)
10935 {
10936 /* Note: these braces are necessary to avoid a syntax
10937 error from the SunOS4 C compiler. */
049b0c3a
NC
10938 /* PR binutils/17531: A corrupt file can trigger this test.
10939 So do not use an assert, instead generate an error message. */
10940 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10941 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10942 (int) entry->d_un.d_val);
252b5132
RH
10943 }
10944 else if (entry->d_tag == DT_SYMINSZ)
10945 syminsz = entry->d_un.d_val;
10946 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10947 filedata->dynamic_syminfo_offset
10948 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10949 }
10950
978c4450 10951 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10952 {
2cf0635d
NC
10953 Elf_External_Syminfo * extsyminfo;
10954 Elf_External_Syminfo * extsym;
10955 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10956
10957 /* There is a syminfo section. Read the data. */
3f5e193b 10958 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10959 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10960 1, syminsz, _("symbol information"));
a6e9f9df 10961 if (!extsyminfo)
015dc7e1 10962 return false;
252b5132 10963
978c4450 10964 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10965 {
10966 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10967 free (filedata->dynamic_syminfo);
e3d39609 10968 }
978c4450
AM
10969 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10970 if (filedata->dynamic_syminfo == NULL)
252b5132 10971 {
2482f306
AM
10972 error (_("Out of memory allocating %lu bytes "
10973 "for dynamic symbol info\n"),
8b73c356 10974 (unsigned long) syminsz);
015dc7e1 10975 return false;
252b5132
RH
10976 }
10977
2482f306
AM
10978 filedata->dynamic_syminfo_nent
10979 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10980 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10981 syminfo < (filedata->dynamic_syminfo
10982 + filedata->dynamic_syminfo_nent);
86dba8ee 10983 ++syminfo, ++extsym)
252b5132 10984 {
86dba8ee
AM
10985 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10986 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10987 }
10988
10989 free (extsyminfo);
10990 }
10991 }
10992
978c4450 10993 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 10994 {
f253158f
NC
10995 if (filedata->is_separate)
10996 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
10997 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
10998 (unsigned long) filedata->dynamic_nent),
10999 filedata->file_name,
11000 filedata->dynamic_addr,
11001 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11002 else
f253158f
NC
11003 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11004 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11005 (unsigned long) filedata->dynamic_nent),
ca0e11aa
NC
11006 filedata->dynamic_addr,
11007 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11008 }
252b5132
RH
11009 if (do_dynamic)
11010 printf (_(" Tag Type Name/Value\n"));
11011
978c4450
AM
11012 for (entry = filedata->dynamic_section;
11013 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11014 entry++)
252b5132
RH
11015 {
11016 if (do_dynamic)
f7a99963 11017 {
2cf0635d 11018 const char * dtype;
e699b9ff 11019
f7a99963
NC
11020 putchar (' ');
11021 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11022 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11023 printf (" (%s)%*s", dtype,
32ec8896 11024 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11025 }
252b5132
RH
11026
11027 switch (entry->d_tag)
11028 {
d1133906
NC
11029 case DT_FLAGS:
11030 if (do_dynamic)
e9e44622 11031 print_dynamic_flags (entry->d_un.d_val);
d1133906 11032 break;
76da6bbe 11033
252b5132
RH
11034 case DT_AUXILIARY:
11035 case DT_FILTER:
019148e4
L
11036 case DT_CONFIG:
11037 case DT_DEPAUDIT:
11038 case DT_AUDIT:
252b5132
RH
11039 if (do_dynamic)
11040 {
019148e4 11041 switch (entry->d_tag)
b34976b6 11042 {
019148e4
L
11043 case DT_AUXILIARY:
11044 printf (_("Auxiliary library"));
11045 break;
11046
11047 case DT_FILTER:
11048 printf (_("Filter library"));
11049 break;
11050
b34976b6 11051 case DT_CONFIG:
019148e4
L
11052 printf (_("Configuration file"));
11053 break;
11054
11055 case DT_DEPAUDIT:
11056 printf (_("Dependency audit library"));
11057 break;
11058
11059 case DT_AUDIT:
11060 printf (_("Audit library"));
11061 break;
11062 }
252b5132 11063
84714f86 11064 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11065 printf (": [%s]\n",
84714f86 11066 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11067 else
f7a99963
NC
11068 {
11069 printf (": ");
11070 print_vma (entry->d_un.d_val, PREFIX_HEX);
11071 putchar ('\n');
11072 }
252b5132
RH
11073 }
11074 break;
11075
dcefbbbd 11076 case DT_FEATURE:
252b5132
RH
11077 if (do_dynamic)
11078 {
11079 printf (_("Flags:"));
86f55779 11080
252b5132
RH
11081 if (entry->d_un.d_val == 0)
11082 printf (_(" None\n"));
11083 else
11084 {
11085 unsigned long int val = entry->d_un.d_val;
86f55779 11086
252b5132
RH
11087 if (val & DTF_1_PARINIT)
11088 {
11089 printf (" PARINIT");
11090 val ^= DTF_1_PARINIT;
11091 }
dcefbbbd
L
11092 if (val & DTF_1_CONFEXP)
11093 {
11094 printf (" CONFEXP");
11095 val ^= DTF_1_CONFEXP;
11096 }
252b5132
RH
11097 if (val != 0)
11098 printf (" %lx", val);
11099 puts ("");
11100 }
11101 }
11102 break;
11103
11104 case DT_POSFLAG_1:
11105 if (do_dynamic)
11106 {
11107 printf (_("Flags:"));
86f55779 11108
252b5132
RH
11109 if (entry->d_un.d_val == 0)
11110 printf (_(" None\n"));
11111 else
11112 {
11113 unsigned long int val = entry->d_un.d_val;
86f55779 11114
252b5132
RH
11115 if (val & DF_P1_LAZYLOAD)
11116 {
11117 printf (" LAZYLOAD");
11118 val ^= DF_P1_LAZYLOAD;
11119 }
11120 if (val & DF_P1_GROUPPERM)
11121 {
11122 printf (" GROUPPERM");
11123 val ^= DF_P1_GROUPPERM;
11124 }
11125 if (val != 0)
11126 printf (" %lx", val);
11127 puts ("");
11128 }
11129 }
11130 break;
11131
11132 case DT_FLAGS_1:
11133 if (do_dynamic)
11134 {
11135 printf (_("Flags:"));
11136 if (entry->d_un.d_val == 0)
11137 printf (_(" None\n"));
11138 else
11139 {
11140 unsigned long int val = entry->d_un.d_val;
86f55779 11141
252b5132
RH
11142 if (val & DF_1_NOW)
11143 {
11144 printf (" NOW");
11145 val ^= DF_1_NOW;
11146 }
11147 if (val & DF_1_GLOBAL)
11148 {
11149 printf (" GLOBAL");
11150 val ^= DF_1_GLOBAL;
11151 }
11152 if (val & DF_1_GROUP)
11153 {
11154 printf (" GROUP");
11155 val ^= DF_1_GROUP;
11156 }
11157 if (val & DF_1_NODELETE)
11158 {
11159 printf (" NODELETE");
11160 val ^= DF_1_NODELETE;
11161 }
11162 if (val & DF_1_LOADFLTR)
11163 {
11164 printf (" LOADFLTR");
11165 val ^= DF_1_LOADFLTR;
11166 }
11167 if (val & DF_1_INITFIRST)
11168 {
11169 printf (" INITFIRST");
11170 val ^= DF_1_INITFIRST;
11171 }
11172 if (val & DF_1_NOOPEN)
11173 {
11174 printf (" NOOPEN");
11175 val ^= DF_1_NOOPEN;
11176 }
11177 if (val & DF_1_ORIGIN)
11178 {
11179 printf (" ORIGIN");
11180 val ^= DF_1_ORIGIN;
11181 }
11182 if (val & DF_1_DIRECT)
11183 {
11184 printf (" DIRECT");
11185 val ^= DF_1_DIRECT;
11186 }
11187 if (val & DF_1_TRANS)
11188 {
11189 printf (" TRANS");
11190 val ^= DF_1_TRANS;
11191 }
11192 if (val & DF_1_INTERPOSE)
11193 {
11194 printf (" INTERPOSE");
11195 val ^= DF_1_INTERPOSE;
11196 }
f7db6139 11197 if (val & DF_1_NODEFLIB)
dcefbbbd 11198 {
f7db6139
L
11199 printf (" NODEFLIB");
11200 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11201 }
11202 if (val & DF_1_NODUMP)
11203 {
11204 printf (" NODUMP");
11205 val ^= DF_1_NODUMP;
11206 }
34b60028 11207 if (val & DF_1_CONFALT)
dcefbbbd 11208 {
34b60028
L
11209 printf (" CONFALT");
11210 val ^= DF_1_CONFALT;
11211 }
11212 if (val & DF_1_ENDFILTEE)
11213 {
11214 printf (" ENDFILTEE");
11215 val ^= DF_1_ENDFILTEE;
11216 }
11217 if (val & DF_1_DISPRELDNE)
11218 {
11219 printf (" DISPRELDNE");
11220 val ^= DF_1_DISPRELDNE;
11221 }
11222 if (val & DF_1_DISPRELPND)
11223 {
11224 printf (" DISPRELPND");
11225 val ^= DF_1_DISPRELPND;
11226 }
11227 if (val & DF_1_NODIRECT)
11228 {
11229 printf (" NODIRECT");
11230 val ^= DF_1_NODIRECT;
11231 }
11232 if (val & DF_1_IGNMULDEF)
11233 {
11234 printf (" IGNMULDEF");
11235 val ^= DF_1_IGNMULDEF;
11236 }
11237 if (val & DF_1_NOKSYMS)
11238 {
11239 printf (" NOKSYMS");
11240 val ^= DF_1_NOKSYMS;
11241 }
11242 if (val & DF_1_NOHDR)
11243 {
11244 printf (" NOHDR");
11245 val ^= DF_1_NOHDR;
11246 }
11247 if (val & DF_1_EDITED)
11248 {
11249 printf (" EDITED");
11250 val ^= DF_1_EDITED;
11251 }
11252 if (val & DF_1_NORELOC)
11253 {
11254 printf (" NORELOC");
11255 val ^= DF_1_NORELOC;
11256 }
11257 if (val & DF_1_SYMINTPOSE)
11258 {
11259 printf (" SYMINTPOSE");
11260 val ^= DF_1_SYMINTPOSE;
11261 }
11262 if (val & DF_1_GLOBAUDIT)
11263 {
11264 printf (" GLOBAUDIT");
11265 val ^= DF_1_GLOBAUDIT;
11266 }
11267 if (val & DF_1_SINGLETON)
11268 {
11269 printf (" SINGLETON");
11270 val ^= DF_1_SINGLETON;
dcefbbbd 11271 }
5c383f02
RO
11272 if (val & DF_1_STUB)
11273 {
11274 printf (" STUB");
11275 val ^= DF_1_STUB;
11276 }
11277 if (val & DF_1_PIE)
11278 {
11279 printf (" PIE");
11280 val ^= DF_1_PIE;
11281 }
b1202ffa
L
11282 if (val & DF_1_KMOD)
11283 {
11284 printf (" KMOD");
11285 val ^= DF_1_KMOD;
11286 }
11287 if (val & DF_1_WEAKFILTER)
11288 {
11289 printf (" WEAKFILTER");
11290 val ^= DF_1_WEAKFILTER;
11291 }
11292 if (val & DF_1_NOCOMMON)
11293 {
11294 printf (" NOCOMMON");
11295 val ^= DF_1_NOCOMMON;
11296 }
252b5132
RH
11297 if (val != 0)
11298 printf (" %lx", val);
11299 puts ("");
11300 }
11301 }
11302 break;
11303
11304 case DT_PLTREL:
978c4450 11305 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11306 if (do_dynamic)
dda8d76d 11307 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11308 break;
11309
11310 case DT_NULL :
11311 case DT_NEEDED :
11312 case DT_PLTGOT :
11313 case DT_HASH :
11314 case DT_STRTAB :
11315 case DT_SYMTAB :
11316 case DT_RELA :
11317 case DT_INIT :
11318 case DT_FINI :
11319 case DT_SONAME :
11320 case DT_RPATH :
11321 case DT_SYMBOLIC:
11322 case DT_REL :
11323 case DT_DEBUG :
11324 case DT_TEXTREL :
11325 case DT_JMPREL :
019148e4 11326 case DT_RUNPATH :
978c4450 11327 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11328
11329 if (do_dynamic)
11330 {
84714f86 11331 const char *name;
252b5132 11332
84714f86
AM
11333 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11334 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11335 else
d79b3d50 11336 name = NULL;
252b5132
RH
11337
11338 if (name)
11339 {
11340 switch (entry->d_tag)
11341 {
11342 case DT_NEEDED:
11343 printf (_("Shared library: [%s]"), name);
11344
13acb58d
AM
11345 if (filedata->program_interpreter
11346 && streq (name, filedata->program_interpreter))
f7a99963 11347 printf (_(" program interpreter"));
252b5132
RH
11348 break;
11349
11350 case DT_SONAME:
f7a99963 11351 printf (_("Library soname: [%s]"), name);
252b5132
RH
11352 break;
11353
11354 case DT_RPATH:
f7a99963 11355 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11356 break;
11357
019148e4
L
11358 case DT_RUNPATH:
11359 printf (_("Library runpath: [%s]"), name);
11360 break;
11361
252b5132 11362 default:
f7a99963
NC
11363 print_vma (entry->d_un.d_val, PREFIX_HEX);
11364 break;
252b5132
RH
11365 }
11366 }
11367 else
f7a99963
NC
11368 print_vma (entry->d_un.d_val, PREFIX_HEX);
11369
11370 putchar ('\n');
252b5132
RH
11371 }
11372 break;
11373
11374 case DT_PLTRELSZ:
11375 case DT_RELASZ :
11376 case DT_STRSZ :
11377 case DT_RELSZ :
11378 case DT_RELAENT :
11379 case DT_SYMENT :
11380 case DT_RELENT :
978c4450 11381 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11382 /* Fall through. */
252b5132
RH
11383 case DT_PLTPADSZ:
11384 case DT_MOVEENT :
11385 case DT_MOVESZ :
11386 case DT_INIT_ARRAYSZ:
11387 case DT_FINI_ARRAYSZ:
047b2264
JJ
11388 case DT_GNU_CONFLICTSZ:
11389 case DT_GNU_LIBLISTSZ:
252b5132 11390 if (do_dynamic)
f7a99963
NC
11391 {
11392 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11393 printf (_(" (bytes)\n"));
f7a99963 11394 }
252b5132
RH
11395 break;
11396
11397 case DT_VERDEFNUM:
11398 case DT_VERNEEDNUM:
11399 case DT_RELACOUNT:
11400 case DT_RELCOUNT:
11401 if (do_dynamic)
f7a99963
NC
11402 {
11403 print_vma (entry->d_un.d_val, UNSIGNED);
11404 putchar ('\n');
11405 }
252b5132
RH
11406 break;
11407
11408 case DT_SYMINSZ:
11409 case DT_SYMINENT:
11410 case DT_SYMINFO:
11411 case DT_USED:
11412 case DT_INIT_ARRAY:
11413 case DT_FINI_ARRAY:
11414 if (do_dynamic)
11415 {
d79b3d50 11416 if (entry->d_tag == DT_USED
84714f86 11417 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11418 {
84714f86
AM
11419 const char *name
11420 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11421
b34976b6 11422 if (*name)
252b5132
RH
11423 {
11424 printf (_("Not needed object: [%s]\n"), name);
11425 break;
11426 }
11427 }
103f02d3 11428
f7a99963
NC
11429 print_vma (entry->d_un.d_val, PREFIX_HEX);
11430 putchar ('\n');
252b5132
RH
11431 }
11432 break;
11433
11434 case DT_BIND_NOW:
11435 /* The value of this entry is ignored. */
35b1837e
AM
11436 if (do_dynamic)
11437 putchar ('\n');
252b5132 11438 break;
103f02d3 11439
047b2264
JJ
11440 case DT_GNU_PRELINKED:
11441 if (do_dynamic)
11442 {
2cf0635d 11443 struct tm * tmp;
91d6fa6a 11444 time_t atime = entry->d_un.d_val;
047b2264 11445
91d6fa6a 11446 tmp = gmtime (&atime);
071436c6
NC
11447 /* PR 17533 file: 041-1244816-0.004. */
11448 if (tmp == NULL)
5a2cbcf4
L
11449 printf (_("<corrupt time val: %lx"),
11450 (unsigned long) atime);
071436c6
NC
11451 else
11452 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11453 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11454 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11455
11456 }
11457 break;
11458
fdc90cb4 11459 case DT_GNU_HASH:
978c4450 11460 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11461 if (do_dynamic)
11462 {
11463 print_vma (entry->d_un.d_val, PREFIX_HEX);
11464 putchar ('\n');
11465 }
11466 break;
11467
a5da3dee
VDM
11468 case DT_GNU_FLAGS_1:
11469 if (do_dynamic)
11470 {
11471 printf (_("Flags:"));
11472 if (entry->d_un.d_val == 0)
11473 printf (_(" None\n"));
11474 else
11475 {
11476 unsigned long int val = entry->d_un.d_val;
11477
11478 if (val & DF_GNU_1_UNIQUE)
11479 {
11480 printf (" UNIQUE");
11481 val ^= DF_GNU_1_UNIQUE;
11482 }
11483 if (val != 0)
11484 printf (" %lx", val);
11485 puts ("");
11486 }
11487 }
11488 break;
11489
252b5132
RH
11490 default:
11491 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11492 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11493 = entry->d_un.d_val;
252b5132
RH
11494
11495 if (do_dynamic)
11496 {
dda8d76d 11497 switch (filedata->file_header.e_machine)
252b5132 11498 {
37c18eed
SD
11499 case EM_AARCH64:
11500 dynamic_section_aarch64_val (entry);
11501 break;
252b5132 11502 case EM_MIPS:
4fe85591 11503 case EM_MIPS_RS3_LE:
978c4450 11504 dynamic_section_mips_val (filedata, entry);
252b5132 11505 break;
103f02d3 11506 case EM_PARISC:
b2d38a17 11507 dynamic_section_parisc_val (entry);
103f02d3 11508 break;
ecc51f48 11509 case EM_IA_64:
b2d38a17 11510 dynamic_section_ia64_val (entry);
ecc51f48 11511 break;
252b5132 11512 default:
f7a99963
NC
11513 print_vma (entry->d_un.d_val, PREFIX_HEX);
11514 putchar ('\n');
252b5132
RH
11515 }
11516 }
11517 break;
11518 }
11519 }
11520
015dc7e1 11521 return true;
252b5132
RH
11522}
11523
11524static char *
d3ba0551 11525get_ver_flags (unsigned int flags)
252b5132 11526{
6d4f21f6 11527 static char buff[128];
252b5132
RH
11528
11529 buff[0] = 0;
11530
11531 if (flags == 0)
11532 return _("none");
11533
11534 if (flags & VER_FLG_BASE)
7bb1ad17 11535 strcat (buff, "BASE");
252b5132
RH
11536
11537 if (flags & VER_FLG_WEAK)
11538 {
11539 if (flags & VER_FLG_BASE)
7bb1ad17 11540 strcat (buff, " | ");
252b5132 11541
7bb1ad17 11542 strcat (buff, "WEAK");
252b5132
RH
11543 }
11544
44ec90b9
RO
11545 if (flags & VER_FLG_INFO)
11546 {
11547 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11548 strcat (buff, " | ");
44ec90b9 11549
7bb1ad17 11550 strcat (buff, "INFO");
44ec90b9
RO
11551 }
11552
11553 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11554 {
11555 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11556 strcat (buff, " | ");
11557
11558 strcat (buff, _("<unknown>"));
11559 }
252b5132
RH
11560
11561 return buff;
11562}
11563
11564/* Display the contents of the version sections. */
98fb390a 11565
015dc7e1 11566static bool
dda8d76d 11567process_version_sections (Filedata * filedata)
252b5132 11568{
2cf0635d 11569 Elf_Internal_Shdr * section;
b34976b6 11570 unsigned i;
015dc7e1 11571 bool found = false;
252b5132
RH
11572
11573 if (! do_version)
015dc7e1 11574 return true;
252b5132 11575
dda8d76d
NC
11576 for (i = 0, section = filedata->section_headers;
11577 i < filedata->file_header.e_shnum;
b34976b6 11578 i++, section++)
252b5132
RH
11579 {
11580 switch (section->sh_type)
11581 {
11582 case SHT_GNU_verdef:
11583 {
2cf0635d 11584 Elf_External_Verdef * edefs;
452bf675
AM
11585 unsigned long idx;
11586 unsigned long cnt;
2cf0635d 11587 char * endbuf;
252b5132 11588
015dc7e1 11589 found = true;
252b5132 11590
ca0e11aa
NC
11591 if (filedata->is_separate)
11592 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11593 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11594 section->sh_info),
11595 filedata->file_name,
11596 printable_section_name (filedata, section),
11597 section->sh_info);
11598 else
11599 printf (ngettext ("\nVersion definition section '%s' "
11600 "contains %u entry:\n",
11601 "\nVersion definition section '%s' "
11602 "contains %u entries:\n",
11603 section->sh_info),
11604 printable_section_name (filedata, section),
11605 section->sh_info);
047c3dbf 11606
ae9ac79e 11607 printf (_(" Addr: 0x"));
252b5132 11608 printf_vma (section->sh_addr);
233f82cf 11609 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11610 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11611 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11612
3f5e193b 11613 edefs = (Elf_External_Verdef *)
dda8d76d 11614 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11615 _("version definition section"));
a6e9f9df
AM
11616 if (!edefs)
11617 break;
59245841 11618 endbuf = (char *) edefs + section->sh_size;
252b5132 11619
1445030f 11620 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11621 {
2cf0635d
NC
11622 char * vstart;
11623 Elf_External_Verdef * edef;
b34976b6 11624 Elf_Internal_Verdef ent;
2cf0635d 11625 Elf_External_Verdaux * eaux;
b34976b6 11626 Elf_Internal_Verdaux aux;
452bf675 11627 unsigned long isum;
b34976b6 11628 int j;
103f02d3 11629
252b5132 11630 vstart = ((char *) edefs) + idx;
54806181
AM
11631 if (vstart + sizeof (*edef) > endbuf)
11632 break;
252b5132
RH
11633
11634 edef = (Elf_External_Verdef *) vstart;
11635
11636 ent.vd_version = BYTE_GET (edef->vd_version);
11637 ent.vd_flags = BYTE_GET (edef->vd_flags);
11638 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11639 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11640 ent.vd_hash = BYTE_GET (edef->vd_hash);
11641 ent.vd_aux = BYTE_GET (edef->vd_aux);
11642 ent.vd_next = BYTE_GET (edef->vd_next);
11643
452bf675 11644 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11645 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11646
11647 printf (_(" Index: %d Cnt: %d "),
11648 ent.vd_ndx, ent.vd_cnt);
11649
452bf675 11650 /* Check for overflow. */
1445030f 11651 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11652 break;
11653
252b5132
RH
11654 vstart += ent.vd_aux;
11655
1445030f
AM
11656 if (vstart + sizeof (*eaux) > endbuf)
11657 break;
252b5132
RH
11658 eaux = (Elf_External_Verdaux *) vstart;
11659
11660 aux.vda_name = BYTE_GET (eaux->vda_name);
11661 aux.vda_next = BYTE_GET (eaux->vda_next);
11662
84714f86 11663 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 11664 printf (_("Name: %s\n"),
84714f86 11665 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
11666 else
11667 printf (_("Name index: %ld\n"), aux.vda_name);
11668
11669 isum = idx + ent.vd_aux;
11670
b34976b6 11671 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11672 {
1445030f
AM
11673 if (aux.vda_next < sizeof (*eaux)
11674 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11675 {
11676 warn (_("Invalid vda_next field of %lx\n"),
11677 aux.vda_next);
11678 j = ent.vd_cnt;
11679 break;
11680 }
dd24e3da 11681 /* Check for overflow. */
7e26601c 11682 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11683 break;
11684
252b5132
RH
11685 isum += aux.vda_next;
11686 vstart += aux.vda_next;
11687
54806181
AM
11688 if (vstart + sizeof (*eaux) > endbuf)
11689 break;
1445030f 11690 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11691
11692 aux.vda_name = BYTE_GET (eaux->vda_name);
11693 aux.vda_next = BYTE_GET (eaux->vda_next);
11694
84714f86 11695 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 11696 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 11697 isum, j,
84714f86 11698 get_dynamic_name (filedata, aux.vda_name));
252b5132 11699 else
452bf675 11700 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11701 isum, j, aux.vda_name);
11702 }
dd24e3da 11703
54806181
AM
11704 if (j < ent.vd_cnt)
11705 printf (_(" Version def aux past end of section\n"));
252b5132 11706
c9f02c3e
MR
11707 /* PR 17531:
11708 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11709 if (ent.vd_next < sizeof (*edef)
11710 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11711 {
11712 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11713 cnt = section->sh_info;
11714 break;
11715 }
452bf675 11716 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11717 break;
11718
252b5132
RH
11719 idx += ent.vd_next;
11720 }
dd24e3da 11721
54806181
AM
11722 if (cnt < section->sh_info)
11723 printf (_(" Version definition past end of section\n"));
252b5132
RH
11724
11725 free (edefs);
11726 }
11727 break;
103f02d3 11728
252b5132
RH
11729 case SHT_GNU_verneed:
11730 {
2cf0635d 11731 Elf_External_Verneed * eneed;
452bf675
AM
11732 unsigned long idx;
11733 unsigned long cnt;
2cf0635d 11734 char * endbuf;
252b5132 11735
015dc7e1 11736 found = true;
252b5132 11737
ca0e11aa
NC
11738 if (filedata->is_separate)
11739 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11740 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11741 section->sh_info),
11742 filedata->file_name,
11743 printable_section_name (filedata, section),
11744 section->sh_info);
11745 else
11746 printf (ngettext ("\nVersion needs section '%s' "
11747 "contains %u entry:\n",
11748 "\nVersion needs section '%s' "
11749 "contains %u entries:\n",
11750 section->sh_info),
11751 printable_section_name (filedata, section),
11752 section->sh_info);
047c3dbf 11753
252b5132
RH
11754 printf (_(" Addr: 0x"));
11755 printf_vma (section->sh_addr);
72de5009 11756 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11757 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11758 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11759
dda8d76d 11760 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11761 section->sh_offset, 1,
11762 section->sh_size,
9cf03b7e 11763 _("Version Needs section"));
a6e9f9df
AM
11764 if (!eneed)
11765 break;
59245841 11766 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11767
11768 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11769 {
2cf0635d 11770 Elf_External_Verneed * entry;
b34976b6 11771 Elf_Internal_Verneed ent;
452bf675 11772 unsigned long isum;
b34976b6 11773 int j;
2cf0635d 11774 char * vstart;
252b5132
RH
11775
11776 vstart = ((char *) eneed) + idx;
54806181
AM
11777 if (vstart + sizeof (*entry) > endbuf)
11778 break;
252b5132
RH
11779
11780 entry = (Elf_External_Verneed *) vstart;
11781
11782 ent.vn_version = BYTE_GET (entry->vn_version);
11783 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11784 ent.vn_file = BYTE_GET (entry->vn_file);
11785 ent.vn_aux = BYTE_GET (entry->vn_aux);
11786 ent.vn_next = BYTE_GET (entry->vn_next);
11787
452bf675 11788 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11789
84714f86 11790 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 11791 printf (_(" File: %s"),
84714f86 11792 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
11793 else
11794 printf (_(" File: %lx"), ent.vn_file);
11795
11796 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11797
dd24e3da 11798 /* Check for overflow. */
7e26601c 11799 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11800 break;
252b5132
RH
11801 vstart += ent.vn_aux;
11802
11803 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11804 {
2cf0635d 11805 Elf_External_Vernaux * eaux;
b34976b6 11806 Elf_Internal_Vernaux aux;
252b5132 11807
54806181
AM
11808 if (vstart + sizeof (*eaux) > endbuf)
11809 break;
252b5132
RH
11810 eaux = (Elf_External_Vernaux *) vstart;
11811
11812 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11813 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11814 aux.vna_other = BYTE_GET (eaux->vna_other);
11815 aux.vna_name = BYTE_GET (eaux->vna_name);
11816 aux.vna_next = BYTE_GET (eaux->vna_next);
11817
84714f86 11818 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 11819 printf (_(" %#06lx: Name: %s"),
84714f86 11820 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 11821 else
452bf675 11822 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11823 isum, aux.vna_name);
11824
11825 printf (_(" Flags: %s Version: %d\n"),
11826 get_ver_flags (aux.vna_flags), aux.vna_other);
11827
1445030f
AM
11828 if (aux.vna_next < sizeof (*eaux)
11829 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11830 {
11831 warn (_("Invalid vna_next field of %lx\n"),
11832 aux.vna_next);
11833 j = ent.vn_cnt;
11834 break;
11835 }
1445030f
AM
11836 /* Check for overflow. */
11837 if (aux.vna_next > (size_t) (endbuf - vstart))
11838 break;
252b5132
RH
11839 isum += aux.vna_next;
11840 vstart += aux.vna_next;
11841 }
9cf03b7e 11842
54806181 11843 if (j < ent.vn_cnt)
f9a6a8f0 11844 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11845
1445030f
AM
11846 if (ent.vn_next < sizeof (*entry)
11847 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11848 {
452bf675 11849 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11850 cnt = section->sh_info;
11851 break;
11852 }
1445030f
AM
11853 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11854 break;
252b5132
RH
11855 idx += ent.vn_next;
11856 }
9cf03b7e 11857
54806181 11858 if (cnt < section->sh_info)
9cf03b7e 11859 warn (_("Missing Version Needs information\n"));
103f02d3 11860
252b5132
RH
11861 free (eneed);
11862 }
11863 break;
11864
11865 case SHT_GNU_versym:
11866 {
2cf0635d 11867 Elf_Internal_Shdr * link_section;
8b73c356
NC
11868 size_t total;
11869 unsigned int cnt;
2cf0635d
NC
11870 unsigned char * edata;
11871 unsigned short * data;
11872 char * strtab;
11873 Elf_Internal_Sym * symbols;
11874 Elf_Internal_Shdr * string_sec;
ba5cdace 11875 unsigned long num_syms;
d3ba0551 11876 long off;
252b5132 11877
dda8d76d 11878 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11879 break;
11880
dda8d76d 11881 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11882 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11883
dda8d76d 11884 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11885 break;
11886
015dc7e1 11887 found = true;
252b5132 11888
4de91c10 11889 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
11890 if (symbols == NULL)
11891 break;
252b5132 11892
dda8d76d 11893 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11894
dda8d76d 11895 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11896 string_sec->sh_size,
11897 _("version string table"));
a6e9f9df 11898 if (!strtab)
0429c154
MS
11899 {
11900 free (symbols);
11901 break;
11902 }
252b5132 11903
ca0e11aa
NC
11904 if (filedata->is_separate)
11905 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11906 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11907 total),
11908 filedata->file_name,
11909 printable_section_name (filedata, section),
11910 (unsigned long) total);
11911 else
11912 printf (ngettext ("\nVersion symbols section '%s' "
11913 "contains %lu entry:\n",
11914 "\nVersion symbols section '%s' "
11915 "contains %lu entries:\n",
11916 total),
11917 printable_section_name (filedata, section),
11918 (unsigned long) total);
252b5132 11919
ae9ac79e 11920 printf (_(" Addr: 0x"));
252b5132 11921 printf_vma (section->sh_addr);
72de5009 11922 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11923 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11924 printable_section_name (filedata, link_section));
252b5132 11925
dda8d76d 11926 off = offset_from_vma (filedata,
978c4450 11927 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11928 total * sizeof (short));
95099889
AM
11929 edata = (unsigned char *) get_data (NULL, filedata, off,
11930 sizeof (short), total,
11931 _("version symbol data"));
a6e9f9df
AM
11932 if (!edata)
11933 {
11934 free (strtab);
0429c154 11935 free (symbols);
a6e9f9df
AM
11936 break;
11937 }
252b5132 11938
3f5e193b 11939 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11940
11941 for (cnt = total; cnt --;)
b34976b6
AM
11942 data[cnt] = byte_get (edata + cnt * sizeof (short),
11943 sizeof (short));
252b5132
RH
11944
11945 free (edata);
11946
11947 for (cnt = 0; cnt < total; cnt += 4)
11948 {
11949 int j, nn;
ab273396
AM
11950 char *name;
11951 char *invalid = _("*invalid*");
252b5132
RH
11952
11953 printf (" %03x:", cnt);
11954
11955 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11956 switch (data[cnt + j])
252b5132
RH
11957 {
11958 case 0:
11959 fputs (_(" 0 (*local*) "), stdout);
11960 break;
11961
11962 case 1:
11963 fputs (_(" 1 (*global*) "), stdout);
11964 break;
11965
11966 default:
c244d050
NC
11967 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11968 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11969
dd24e3da 11970 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11971 array, break to avoid an out-of-bounds read. */
11972 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11973 {
11974 warn (_("invalid index into symbol array\n"));
11975 break;
11976 }
11977
ab273396 11978 name = NULL;
978c4450 11979 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11980 {
b34976b6
AM
11981 Elf_Internal_Verneed ivn;
11982 unsigned long offset;
252b5132 11983
d93f0186 11984 offset = offset_from_vma
978c4450
AM
11985 (filedata,
11986 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11987 sizeof (Elf_External_Verneed));
252b5132 11988
b34976b6 11989 do
252b5132 11990 {
b34976b6
AM
11991 Elf_Internal_Vernaux ivna;
11992 Elf_External_Verneed evn;
11993 Elf_External_Vernaux evna;
11994 unsigned long a_off;
252b5132 11995
dda8d76d 11996 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11997 _("version need")) == NULL)
11998 break;
0b4362b0 11999
252b5132
RH
12000 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12001 ivn.vn_next = BYTE_GET (evn.vn_next);
12002
12003 a_off = offset + ivn.vn_aux;
12004
12005 do
12006 {
dda8d76d 12007 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12008 1, _("version need aux (2)")) == NULL)
12009 {
12010 ivna.vna_next = 0;
12011 ivna.vna_other = 0;
12012 }
12013 else
12014 {
12015 ivna.vna_next = BYTE_GET (evna.vna_next);
12016 ivna.vna_other = BYTE_GET (evna.vna_other);
12017 }
252b5132
RH
12018
12019 a_off += ivna.vna_next;
12020 }
b34976b6 12021 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12022 && ivna.vna_next != 0);
12023
b34976b6 12024 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12025 {
12026 ivna.vna_name = BYTE_GET (evna.vna_name);
12027
54806181 12028 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12029 name = invalid;
54806181
AM
12030 else
12031 name = strtab + ivna.vna_name;
252b5132
RH
12032 break;
12033 }
12034
12035 offset += ivn.vn_next;
12036 }
12037 while (ivn.vn_next);
12038 }
00d93f34 12039
ab273396 12040 if (data[cnt + j] != 0x8001
978c4450 12041 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12042 {
b34976b6
AM
12043 Elf_Internal_Verdef ivd;
12044 Elf_External_Verdef evd;
12045 unsigned long offset;
252b5132 12046
d93f0186 12047 offset = offset_from_vma
978c4450
AM
12048 (filedata,
12049 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12050 sizeof evd);
252b5132
RH
12051
12052 do
12053 {
dda8d76d 12054 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12055 _("version def")) == NULL)
12056 {
12057 ivd.vd_next = 0;
948f632f 12058 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12059 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12060 break;
59245841
NC
12061 }
12062 else
12063 {
12064 ivd.vd_next = BYTE_GET (evd.vd_next);
12065 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12066 }
252b5132
RH
12067
12068 offset += ivd.vd_next;
12069 }
c244d050 12070 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12071 && ivd.vd_next != 0);
12072
c244d050 12073 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12074 {
b34976b6
AM
12075 Elf_External_Verdaux evda;
12076 Elf_Internal_Verdaux ivda;
252b5132
RH
12077
12078 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12079
dda8d76d 12080 if (get_data (&evda, filedata,
59245841
NC
12081 offset - ivd.vd_next + ivd.vd_aux,
12082 sizeof (evda), 1,
12083 _("version def aux")) == NULL)
12084 break;
252b5132
RH
12085
12086 ivda.vda_name = BYTE_GET (evda.vda_name);
12087
54806181 12088 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12089 name = invalid;
12090 else if (name != NULL && name != invalid)
12091 name = _("*both*");
54806181
AM
12092 else
12093 name = strtab + ivda.vda_name;
252b5132
RH
12094 }
12095 }
ab273396
AM
12096 if (name != NULL)
12097 nn += printf ("(%s%-*s",
12098 name,
12099 12 - (int) strlen (name),
12100 ")");
252b5132
RH
12101
12102 if (nn < 18)
12103 printf ("%*c", 18 - nn, ' ');
12104 }
12105
12106 putchar ('\n');
12107 }
12108
12109 free (data);
12110 free (strtab);
12111 free (symbols);
12112 }
12113 break;
103f02d3 12114
252b5132
RH
12115 default:
12116 break;
12117 }
12118 }
12119
12120 if (! found)
ca0e11aa
NC
12121 {
12122 if (filedata->is_separate)
12123 printf (_("\nNo version information found in linked file '%s'.\n"),
12124 filedata->file_name);
12125 else
12126 printf (_("\nNo version information found in this file.\n"));
12127 }
252b5132 12128
015dc7e1 12129 return true;
252b5132
RH
12130}
12131
d1133906 12132static const char *
dda8d76d 12133get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12134{
89246a0e 12135 static char buff[64];
252b5132
RH
12136
12137 switch (binding)
12138 {
b34976b6
AM
12139 case STB_LOCAL: return "LOCAL";
12140 case STB_GLOBAL: return "GLOBAL";
12141 case STB_WEAK: return "WEAK";
252b5132
RH
12142 default:
12143 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12144 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12145 binding);
252b5132 12146 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12147 {
12148 if (binding == STB_GNU_UNIQUE
df3a023b 12149 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12150 return "UNIQUE";
12151 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12152 }
252b5132 12153 else
e9e44622 12154 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12155 return buff;
12156 }
12157}
12158
d1133906 12159static const char *
dda8d76d 12160get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12161{
89246a0e 12162 static char buff[64];
252b5132
RH
12163
12164 switch (type)
12165 {
b34976b6
AM
12166 case STT_NOTYPE: return "NOTYPE";
12167 case STT_OBJECT: return "OBJECT";
12168 case STT_FUNC: return "FUNC";
12169 case STT_SECTION: return "SECTION";
12170 case STT_FILE: return "FILE";
12171 case STT_COMMON: return "COMMON";
12172 case STT_TLS: return "TLS";
15ab5209
DB
12173 case STT_RELC: return "RELC";
12174 case STT_SRELC: return "SRELC";
252b5132
RH
12175 default:
12176 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12177 {
dda8d76d 12178 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12179 return "THUMB_FUNC";
103f02d3 12180
dda8d76d 12181 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12182 return "REGISTER";
12183
dda8d76d 12184 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12185 return "PARISC_MILLI";
12186
e9e44622 12187 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12188 }
252b5132 12189 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12190 {
dda8d76d 12191 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12192 {
12193 if (type == STT_HP_OPAQUE)
12194 return "HP_OPAQUE";
12195 if (type == STT_HP_STUB)
12196 return "HP_STUB";
12197 }
12198
d8045f23 12199 if (type == STT_GNU_IFUNC
dda8d76d 12200 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12201 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12202 return "IFUNC";
12203
e9e44622 12204 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12205 }
252b5132 12206 else
e9e44622 12207 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12208 return buff;
12209 }
12210}
12211
d1133906 12212static const char *
d3ba0551 12213get_symbol_visibility (unsigned int visibility)
d1133906
NC
12214{
12215 switch (visibility)
12216 {
b34976b6
AM
12217 case STV_DEFAULT: return "DEFAULT";
12218 case STV_INTERNAL: return "INTERNAL";
12219 case STV_HIDDEN: return "HIDDEN";
d1133906 12220 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12221 default:
27a45f42 12222 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12223 return _("<unknown>");
d1133906
NC
12224 }
12225}
12226
2057d69d
CZ
12227static const char *
12228get_alpha_symbol_other (unsigned int other)
9abca702 12229{
2057d69d
CZ
12230 switch (other)
12231 {
12232 case STO_ALPHA_NOPV: return "NOPV";
12233 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12234 default:
27a45f42 12235 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12236 return _("<unknown>");
9abca702 12237 }
2057d69d
CZ
12238}
12239
fd85a6a1
NC
12240static const char *
12241get_solaris_symbol_visibility (unsigned int visibility)
12242{
12243 switch (visibility)
12244 {
12245 case 4: return "EXPORTED";
12246 case 5: return "SINGLETON";
12247 case 6: return "ELIMINATE";
12248 default: return get_symbol_visibility (visibility);
12249 }
12250}
12251
2301ed1c
SN
12252static const char *
12253get_aarch64_symbol_other (unsigned int other)
12254{
12255 static char buf[32];
12256
12257 if (other & STO_AARCH64_VARIANT_PCS)
12258 {
12259 other &= ~STO_AARCH64_VARIANT_PCS;
12260 if (other == 0)
12261 return "VARIANT_PCS";
12262 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12263 return buf;
12264 }
12265 return NULL;
12266}
12267
5e2b0d47
NC
12268static const char *
12269get_mips_symbol_other (unsigned int other)
12270{
12271 switch (other)
12272 {
32ec8896
NC
12273 case STO_OPTIONAL: return "OPTIONAL";
12274 case STO_MIPS_PLT: return "MIPS PLT";
12275 case STO_MIPS_PIC: return "MIPS PIC";
12276 case STO_MICROMIPS: return "MICROMIPS";
12277 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12278 case STO_MIPS16: return "MIPS16";
12279 default: return NULL;
5e2b0d47
NC
12280 }
12281}
12282
28f997cf 12283static const char *
dda8d76d 12284get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12285{
dda8d76d 12286 if (is_ia64_vms (filedata))
28f997cf
TG
12287 {
12288 static char res[32];
12289
12290 res[0] = 0;
12291
12292 /* Function types is for images and .STB files only. */
dda8d76d 12293 switch (filedata->file_header.e_type)
28f997cf
TG
12294 {
12295 case ET_DYN:
12296 case ET_EXEC:
12297 switch (VMS_ST_FUNC_TYPE (other))
12298 {
12299 case VMS_SFT_CODE_ADDR:
12300 strcat (res, " CA");
12301 break;
12302 case VMS_SFT_SYMV_IDX:
12303 strcat (res, " VEC");
12304 break;
12305 case VMS_SFT_FD:
12306 strcat (res, " FD");
12307 break;
12308 case VMS_SFT_RESERVE:
12309 strcat (res, " RSV");
12310 break;
12311 default:
bee0ee85
NC
12312 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12313 VMS_ST_FUNC_TYPE (other));
12314 strcat (res, " <unknown>");
12315 break;
28f997cf
TG
12316 }
12317 break;
12318 default:
12319 break;
12320 }
12321 switch (VMS_ST_LINKAGE (other))
12322 {
12323 case VMS_STL_IGNORE:
12324 strcat (res, " IGN");
12325 break;
12326 case VMS_STL_RESERVE:
12327 strcat (res, " RSV");
12328 break;
12329 case VMS_STL_STD:
12330 strcat (res, " STD");
12331 break;
12332 case VMS_STL_LNK:
12333 strcat (res, " LNK");
12334 break;
12335 default:
bee0ee85
NC
12336 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12337 VMS_ST_LINKAGE (other));
12338 strcat (res, " <unknown>");
12339 break;
28f997cf
TG
12340 }
12341
12342 if (res[0] != 0)
12343 return res + 1;
12344 else
12345 return res;
12346 }
12347 return NULL;
12348}
12349
6911b7dc
AM
12350static const char *
12351get_ppc64_symbol_other (unsigned int other)
12352{
14732552
AM
12353 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12354 return NULL;
12355
12356 other >>= STO_PPC64_LOCAL_BIT;
12357 if (other <= 6)
6911b7dc 12358 {
89246a0e 12359 static char buf[64];
14732552
AM
12360 if (other >= 2)
12361 other = ppc64_decode_local_entry (other);
12362 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12363 return buf;
12364 }
12365 return NULL;
12366}
12367
5e2b0d47 12368static const char *
dda8d76d 12369get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12370{
12371 const char * result = NULL;
89246a0e 12372 static char buff [64];
5e2b0d47
NC
12373
12374 if (other == 0)
12375 return "";
12376
dda8d76d 12377 switch (filedata->file_header.e_machine)
5e2b0d47 12378 {
2057d69d
CZ
12379 case EM_ALPHA:
12380 result = get_alpha_symbol_other (other);
12381 break;
2301ed1c
SN
12382 case EM_AARCH64:
12383 result = get_aarch64_symbol_other (other);
12384 break;
5e2b0d47
NC
12385 case EM_MIPS:
12386 result = get_mips_symbol_other (other);
28f997cf
TG
12387 break;
12388 case EM_IA_64:
dda8d76d 12389 result = get_ia64_symbol_other (filedata, other);
28f997cf 12390 break;
6911b7dc
AM
12391 case EM_PPC64:
12392 result = get_ppc64_symbol_other (other);
12393 break;
5e2b0d47 12394 default:
fd85a6a1 12395 result = NULL;
5e2b0d47
NC
12396 break;
12397 }
12398
12399 if (result)
12400 return result;
12401
12402 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12403 return buff;
12404}
12405
d1133906 12406static const char *
dda8d76d 12407get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12408{
b34976b6 12409 static char buff[32];
5cf1065c 12410
252b5132
RH
12411 switch (type)
12412 {
b34976b6
AM
12413 case SHN_UNDEF: return "UND";
12414 case SHN_ABS: return "ABS";
12415 case SHN_COMMON: return "COM";
252b5132 12416 default:
9ce701e2 12417 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12418 && filedata->file_header.e_machine == EM_IA_64
12419 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12420 return "ANSI_COM";
12421 else if ((filedata->file_header.e_machine == EM_X86_64
12422 || filedata->file_header.e_machine == EM_L1OM
12423 || filedata->file_header.e_machine == EM_K1OM)
12424 && type == SHN_X86_64_LCOMMON)
12425 return "LARGE_COM";
12426 else if ((type == SHN_MIPS_SCOMMON
12427 && filedata->file_header.e_machine == EM_MIPS)
12428 || (type == SHN_TIC6X_SCOMMON
12429 && filedata->file_header.e_machine == EM_TI_C6000))
12430 return "SCOM";
12431 else if (type == SHN_MIPS_SUNDEFINED
12432 && filedata->file_header.e_machine == EM_MIPS)
12433 return "SUND";
12434 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12435 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12436 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12437 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12438 else if (type >= SHN_LORESERVE)
12439 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12440 else if (filedata->file_header.e_shnum != 0
12441 && type >= filedata->file_header.e_shnum)
12442 sprintf (buff, _("bad section index[%3d]"), type);
12443 else
12444 sprintf (buff, "%3d", type);
12445 break;
fd85a6a1
NC
12446 }
12447
10ca4b04 12448 return buff;
6bd1a22c
L
12449}
12450
bb4d2ac2 12451static const char *
dda8d76d 12452get_symbol_version_string (Filedata * filedata,
015dc7e1 12453 bool is_dynsym,
1449284b
NC
12454 const char * strtab,
12455 unsigned long int strtab_size,
12456 unsigned int si,
12457 Elf_Internal_Sym * psym,
12458 enum versioned_symbol_info * sym_info,
12459 unsigned short * vna_other)
bb4d2ac2 12460{
ab273396
AM
12461 unsigned char data[2];
12462 unsigned short vers_data;
12463 unsigned long offset;
7a815dd5 12464 unsigned short max_vd_ndx;
bb4d2ac2 12465
ab273396 12466 if (!is_dynsym
978c4450 12467 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12468 return NULL;
bb4d2ac2 12469
978c4450
AM
12470 offset = offset_from_vma (filedata,
12471 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12472 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12473
dda8d76d 12474 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12475 sizeof (data), 1, _("version data")) == NULL)
12476 return NULL;
12477
12478 vers_data = byte_get (data, 2);
bb4d2ac2 12479
1f6f5dba 12480 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12481 return NULL;
bb4d2ac2 12482
0b8b7609 12483 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12484 max_vd_ndx = 0;
12485
ab273396
AM
12486 /* Usually we'd only see verdef for defined symbols, and verneed for
12487 undefined symbols. However, symbols defined by the linker in
12488 .dynbss for variables copied from a shared library in order to
12489 avoid text relocations are defined yet have verneed. We could
12490 use a heuristic to detect the special case, for example, check
12491 for verneed first on symbols defined in SHT_NOBITS sections, but
12492 it is simpler and more reliable to just look for both verdef and
12493 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12494
ab273396
AM
12495 if (psym->st_shndx != SHN_UNDEF
12496 && vers_data != 0x8001
978c4450 12497 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12498 {
12499 Elf_Internal_Verdef ivd;
12500 Elf_Internal_Verdaux ivda;
12501 Elf_External_Verdaux evda;
12502 unsigned long off;
bb4d2ac2 12503
dda8d76d 12504 off = offset_from_vma (filedata,
978c4450 12505 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12506 sizeof (Elf_External_Verdef));
12507
12508 do
bb4d2ac2 12509 {
ab273396
AM
12510 Elf_External_Verdef evd;
12511
dda8d76d 12512 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12513 _("version def")) == NULL)
12514 {
12515 ivd.vd_ndx = 0;
12516 ivd.vd_aux = 0;
12517 ivd.vd_next = 0;
1f6f5dba 12518 ivd.vd_flags = 0;
ab273396
AM
12519 }
12520 else
bb4d2ac2 12521 {
ab273396
AM
12522 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12523 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12524 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12525 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12526 }
bb4d2ac2 12527
7a815dd5
L
12528 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12529 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12530
ab273396
AM
12531 off += ivd.vd_next;
12532 }
12533 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12534
ab273396
AM
12535 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12536 {
9abca702 12537 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12538 return NULL;
12539
ab273396
AM
12540 off -= ivd.vd_next;
12541 off += ivd.vd_aux;
bb4d2ac2 12542
dda8d76d 12543 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12544 _("version def aux")) != NULL)
12545 {
12546 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12547
ab273396 12548 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12549 return (ivda.vda_name < strtab_size
12550 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12551 }
12552 }
12553 }
bb4d2ac2 12554
978c4450 12555 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12556 {
12557 Elf_External_Verneed evn;
12558 Elf_Internal_Verneed ivn;
12559 Elf_Internal_Vernaux ivna;
bb4d2ac2 12560
dda8d76d 12561 offset = offset_from_vma (filedata,
978c4450 12562 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12563 sizeof evn);
12564 do
12565 {
12566 unsigned long vna_off;
bb4d2ac2 12567
dda8d76d 12568 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12569 _("version need")) == NULL)
12570 {
12571 ivna.vna_next = 0;
12572 ivna.vna_other = 0;
12573 ivna.vna_name = 0;
12574 break;
12575 }
bb4d2ac2 12576
ab273396
AM
12577 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12578 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12579
ab273396 12580 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12581
ab273396
AM
12582 do
12583 {
12584 Elf_External_Vernaux evna;
bb4d2ac2 12585
dda8d76d 12586 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12587 _("version need aux (3)")) == NULL)
bb4d2ac2 12588 {
ab273396
AM
12589 ivna.vna_next = 0;
12590 ivna.vna_other = 0;
12591 ivna.vna_name = 0;
bb4d2ac2 12592 }
bb4d2ac2 12593 else
bb4d2ac2 12594 {
ab273396
AM
12595 ivna.vna_other = BYTE_GET (evna.vna_other);
12596 ivna.vna_next = BYTE_GET (evna.vna_next);
12597 ivna.vna_name = BYTE_GET (evna.vna_name);
12598 }
bb4d2ac2 12599
ab273396
AM
12600 vna_off += ivna.vna_next;
12601 }
12602 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12603
ab273396
AM
12604 if (ivna.vna_other == vers_data)
12605 break;
bb4d2ac2 12606
ab273396
AM
12607 offset += ivn.vn_next;
12608 }
12609 while (ivn.vn_next != 0);
bb4d2ac2 12610
ab273396
AM
12611 if (ivna.vna_other == vers_data)
12612 {
12613 *sym_info = symbol_undefined;
12614 *vna_other = ivna.vna_other;
12615 return (ivna.vna_name < strtab_size
12616 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12617 }
7a815dd5
L
12618 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12619 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12620 return _("<corrupt>");
bb4d2ac2 12621 }
ab273396 12622 return NULL;
bb4d2ac2
L
12623}
12624
047c3dbf
NL
12625/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12626
12627static unsigned int
12628print_dynamic_symbol_size (bfd_vma vma, int base)
12629{
12630 switch (base)
12631 {
12632 case 8:
12633 return print_vma (vma, OCTAL_5);
12634
12635 case 10:
12636 return print_vma (vma, UNSIGNED_5);
12637
12638 case 16:
12639 return print_vma (vma, PREFIX_HEX_5);
12640
12641 case 0:
12642 default:
12643 return print_vma (vma, DEC_5);
12644 }
12645}
12646
10ca4b04
L
12647static void
12648print_dynamic_symbol (Filedata *filedata, unsigned long si,
12649 Elf_Internal_Sym *symtab,
12650 Elf_Internal_Shdr *section,
12651 char *strtab, size_t strtab_size)
252b5132 12652{
10ca4b04
L
12653 const char *version_string;
12654 enum versioned_symbol_info sym_info;
12655 unsigned short vna_other;
23356397
NC
12656 bool is_valid;
12657 const char * sstr;
10ca4b04 12658 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12659
10ca4b04
L
12660 printf ("%6ld: ", si);
12661 print_vma (psym->st_value, LONG_HEX);
12662 putchar (' ');
047c3dbf 12663 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12664 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12665 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12666 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12667 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12668 else
252b5132 12669 {
10ca4b04 12670 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12671
10ca4b04
L
12672 printf (" %-7s", get_symbol_visibility (vis));
12673 /* Check to see if any other bits in the st_other field are set.
12674 Note - displaying this information disrupts the layout of the
12675 table being generated, but for the moment this case is very rare. */
12676 if (psym->st_other ^ vis)
12677 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12678 }
10ca4b04 12679 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12680
23356397
NC
12681 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12682 && psym->st_shndx < filedata->file_header.e_shnum
12683 && psym->st_name == 0)
12684 {
84714f86
AM
12685 is_valid
12686 = section_name_valid (filedata,
12687 filedata->section_headers + psym->st_shndx);
23356397 12688 sstr = is_valid ?
84714f86
AM
12689 section_name_print (filedata,
12690 filedata->section_headers + psym->st_shndx)
23356397
NC
12691 : _("<corrupt>");
12692 }
12693 else
12694 {
84714f86 12695 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
12696 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12697 }
10ca4b04
L
12698
12699 version_string
12700 = get_symbol_version_string (filedata,
12701 (section == NULL
12702 || section->sh_type == SHT_DYNSYM),
12703 strtab, strtab_size, si,
12704 psym, &sym_info, &vna_other);
b9e920ec 12705
0942c7ab
NC
12706 int len_avail = 21;
12707 if (! do_wide && version_string != NULL)
12708 {
ddb43bab 12709 char buffer[16];
0942c7ab 12710
ddb43bab 12711 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12712
12713 if (sym_info == symbol_undefined)
12714 len_avail -= sprintf (buffer," (%d)", vna_other);
12715 else if (sym_info != symbol_hidden)
12716 len_avail -= 1;
12717 }
12718
12719 print_symbol (len_avail, sstr);
b9e920ec 12720
10ca4b04
L
12721 if (version_string)
12722 {
12723 if (sym_info == symbol_undefined)
12724 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12725 else
10ca4b04
L
12726 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12727 version_string);
12728 }
6bd1a22c 12729
10ca4b04 12730 putchar ('\n');
6bd1a22c 12731
10ca4b04
L
12732 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12733 && section != NULL
12734 && si >= section->sh_info
12735 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12736 && filedata->file_header.e_machine != EM_MIPS
12737 /* Solaris binaries have been found to violate this requirement as
12738 well. Not sure if this is a bug or an ABI requirement. */
12739 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12740 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12741 si, printable_section_name (filedata, section), section->sh_info);
12742}
f16a9783 12743
0f03783c
NC
12744static const char *
12745get_lto_kind (unsigned int kind)
12746{
12747 switch (kind)
12748 {
12749 case 0: return "DEF";
12750 case 1: return "WEAKDEF";
12751 case 2: return "UNDEF";
12752 case 3: return "WEAKUNDEF";
12753 case 4: return "COMMON";
12754 default:
12755 break;
12756 }
12757
12758 static char buffer[30];
12759 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12760 sprintf (buffer, "<unknown: %u>", kind);
12761 return buffer;
12762}
12763
12764static const char *
12765get_lto_visibility (unsigned int visibility)
12766{
12767 switch (visibility)
12768 {
12769 case 0: return "DEFAULT";
12770 case 1: return "PROTECTED";
12771 case 2: return "INTERNAL";
12772 case 3: return "HIDDEN";
12773 default:
12774 break;
12775 }
12776
12777 static char buffer[30];
12778 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12779 sprintf (buffer, "<unknown: %u>", visibility);
12780 return buffer;
12781}
12782
12783static const char *
12784get_lto_sym_type (unsigned int sym_type)
12785{
12786 switch (sym_type)
12787 {
12788 case 0: return "UNKNOWN";
12789 case 1: return "FUNCTION";
12790 case 2: return "VARIABLE";
12791 default:
12792 break;
12793 }
12794
12795 static char buffer[30];
12796 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12797 sprintf (buffer, "<unknown: %u>", sym_type);
12798 return buffer;
12799}
12800
12801/* Display an LTO format symbol table.
12802 FIXME: The format of LTO symbol tables is not formalized.
12803 So this code could need changing in the future. */
12804
015dc7e1 12805static bool
0f03783c
NC
12806display_lto_symtab (Filedata * filedata,
12807 Elf_Internal_Shdr * section)
12808{
12809 if (section->sh_size == 0)
12810 {
ca0e11aa
NC
12811 if (filedata->is_separate)
12812 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12813 printable_section_name (filedata, section),
12814 filedata->file_name);
12815 else
12816 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12817 printable_section_name (filedata, section));
047c3dbf 12818
015dc7e1 12819 return true;
0f03783c
NC
12820 }
12821
12822 if (section->sh_size > filedata->file_size)
12823 {
12824 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12825 printable_section_name (filedata, section),
12826 (unsigned long) section->sh_size);
015dc7e1 12827 return false;
0f03783c
NC
12828 }
12829
12830 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12831 section->sh_size, 1, _("LTO symbols"));
12832 if (alloced_data == NULL)
015dc7e1 12833 return false;
0f03783c
NC
12834
12835 /* Look for extended data for the symbol table. */
12836 Elf_Internal_Shdr * ext;
12837 void * ext_data_orig = NULL;
12838 char * ext_data = NULL;
12839 char * ext_data_end = NULL;
12840 char * ext_name = NULL;
12841
12842 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
12843 (section_name (filedata, section)
12844 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
12845 && ext_name != NULL /* Paranoia. */
12846 && (ext = find_section (filedata, ext_name)) != NULL)
12847 {
12848 if (ext->sh_size < 3)
12849 error (_("LTO Symbol extension table '%s' is empty!\n"),
12850 printable_section_name (filedata, ext));
12851 else
12852 {
12853 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12854 ext->sh_size, 1,
12855 _("LTO ext symbol data"));
12856 if (ext_data != NULL)
12857 {
12858 ext_data_end = ext_data + ext->sh_size;
12859 if (* ext_data++ != 1)
12860 error (_("Unexpected version number in symbol extension table\n"));
12861 }
12862 }
12863 }
b9e920ec 12864
0f03783c
NC
12865 const unsigned char * data = (const unsigned char *) alloced_data;
12866 const unsigned char * end = data + section->sh_size;
12867
ca0e11aa
NC
12868 if (filedata->is_separate)
12869 printf (_("\nIn linked file '%s': "), filedata->file_name);
12870 else
12871 printf ("\n");
12872
0f03783c
NC
12873 if (ext_data_orig != NULL)
12874 {
12875 if (do_wide)
ca0e11aa 12876 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12877 printable_section_name (filedata, section),
12878 printable_section_name (filedata, ext));
12879 else
12880 {
ca0e11aa 12881 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12882 printable_section_name (filedata, section));
12883 printf (_(" and extension table '%s' contain:\n"),
12884 printable_section_name (filedata, ext));
12885 }
12886 }
12887 else
ca0e11aa 12888 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12889 printable_section_name (filedata, section));
b9e920ec 12890
0f03783c 12891 /* FIXME: Add a wide version. */
b9e920ec 12892 if (ext_data_orig != NULL)
0f03783c
NC
12893 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12894 else
12895 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12896
12897 /* FIXME: We do not handle style prefixes. */
12898
12899 while (data < end)
12900 {
12901 const unsigned char * sym_name = data;
12902 data += strnlen ((const char *) sym_name, end - data) + 1;
12903 if (data >= end)
12904 goto fail;
12905
12906 const unsigned char * comdat_key = data;
12907 data += strnlen ((const char *) comdat_key, end - data) + 1;
12908 if (data >= end)
12909 goto fail;
12910
12911 if (data + 2 + 8 + 4 > end)
12912 goto fail;
12913
12914 unsigned int kind = *data++;
12915 unsigned int visibility = *data++;
12916
12917 elf_vma size = byte_get (data, 8);
12918 data += 8;
12919
12920 elf_vma slot = byte_get (data, 4);
12921 data += 4;
12922
12923 if (ext_data != NULL)
12924 {
12925 if (ext_data < (ext_data_end - 1))
12926 {
12927 unsigned int sym_type = * ext_data ++;
12928 unsigned int sec_kind = * ext_data ++;
12929
12930 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12931 * comdat_key == 0 ? "-" : (char *) comdat_key,
12932 get_lto_kind (kind),
12933 get_lto_visibility (visibility),
12934 (long) size,
12935 (long) slot,
12936 get_lto_sym_type (sym_type),
12937 (long) sec_kind);
12938 print_symbol (6, (const char *) sym_name);
12939 }
12940 else
12941 {
12942 error (_("Ran out of LTO symbol extension data\n"));
12943 ext_data = NULL;
12944 /* FIXME: return FAIL result ? */
12945 }
12946 }
12947 else
12948 {
12949 printf (" %10s %10s %11s %08lx %08lx _",
12950 * comdat_key == 0 ? "-" : (char *) comdat_key,
12951 get_lto_kind (kind),
12952 get_lto_visibility (visibility),
12953 (long) size,
12954 (long) slot);
12955 print_symbol (21, (const char *) sym_name);
12956 }
12957 putchar ('\n');
12958 }
12959
12960 if (ext_data != NULL && ext_data < ext_data_end)
12961 {
12962 error (_("Data remains in the LTO symbol extension table\n"));
12963 goto fail;
12964 }
12965
12966 free (alloced_data);
12967 free (ext_data_orig);
12968 free (ext_name);
015dc7e1 12969 return true;
b9e920ec 12970
0f03783c
NC
12971 fail:
12972 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12973 free (alloced_data);
12974 free (ext_data_orig);
12975 free (ext_name);
015dc7e1 12976 return false;
0f03783c
NC
12977}
12978
12979/* Display LTO symbol tables. */
12980
015dc7e1 12981static bool
0f03783c
NC
12982process_lto_symbol_tables (Filedata * filedata)
12983{
12984 Elf_Internal_Shdr * section;
12985 unsigned int i;
015dc7e1 12986 bool res = true;
0f03783c
NC
12987
12988 if (!do_lto_syms)
015dc7e1 12989 return true;
0f03783c
NC
12990
12991 if (filedata->section_headers == NULL)
015dc7e1 12992 return true;
0f03783c
NC
12993
12994 for (i = 0, section = filedata->section_headers;
12995 i < filedata->file_header.e_shnum;
12996 i++, section++)
84714f86
AM
12997 if (section_name_valid (filedata, section)
12998 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
12999 res &= display_lto_symtab (filedata, section);
13000
b9e920ec 13001 return res;
0f03783c
NC
13002}
13003
10ca4b04 13004/* Dump the symbol table. */
0f03783c 13005
015dc7e1 13006static bool
10ca4b04
L
13007process_symbol_table (Filedata * filedata)
13008{
13009 Elf_Internal_Shdr * section;
f16a9783 13010
10ca4b04 13011 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13012 return true;
6bd1a22c 13013
978c4450 13014 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13015 && do_syms
13016 && do_using_dynamic
978c4450
AM
13017 && filedata->dynamic_strings != NULL
13018 && filedata->dynamic_symbols != NULL)
6bd1a22c 13019 {
10ca4b04 13020 unsigned long si;
6bd1a22c 13021
ca0e11aa
NC
13022 if (filedata->is_separate)
13023 {
13024 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13025 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13026 filedata->num_dynamic_syms),
13027 filedata->file_name,
13028 filedata->num_dynamic_syms);
13029 }
13030 else
13031 {
13032 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13033 "\nSymbol table for image contains %lu entries:\n",
13034 filedata->num_dynamic_syms),
13035 filedata->num_dynamic_syms);
13036 }
10ca4b04
L
13037 if (is_32bit_elf)
13038 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13039 else
13040 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13041
978c4450
AM
13042 for (si = 0; si < filedata->num_dynamic_syms; si++)
13043 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13044 filedata->dynamic_strings,
13045 filedata->dynamic_strings_length);
252b5132 13046 }
8b73c356 13047 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13048 && filedata->section_headers != NULL)
252b5132 13049 {
b34976b6 13050 unsigned int i;
252b5132 13051
dda8d76d
NC
13052 for (i = 0, section = filedata->section_headers;
13053 i < filedata->file_header.e_shnum;
252b5132
RH
13054 i++, section++)
13055 {
2cf0635d 13056 char * strtab = NULL;
c256ffe7 13057 unsigned long int strtab_size = 0;
2cf0635d 13058 Elf_Internal_Sym * symtab;
ef3df110 13059 unsigned long si, num_syms;
252b5132 13060
2c610e4b
L
13061 if ((section->sh_type != SHT_SYMTAB
13062 && section->sh_type != SHT_DYNSYM)
13063 || (!do_syms
13064 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13065 continue;
13066
dd24e3da
NC
13067 if (section->sh_entsize == 0)
13068 {
13069 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13070 printable_section_name (filedata, section));
dd24e3da
NC
13071 continue;
13072 }
13073
d3a49aa8 13074 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13075
13076 if (filedata->is_separate)
13077 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13078 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13079 num_syms),
13080 filedata->file_name,
13081 printable_section_name (filedata, section),
13082 num_syms);
13083 else
13084 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13085 "\nSymbol table '%s' contains %lu entries:\n",
13086 num_syms),
13087 printable_section_name (filedata, section),
13088 num_syms);
dd24e3da 13089
f7a99963 13090 if (is_32bit_elf)
ca47b30c 13091 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13092 else
ca47b30c 13093 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13094
4de91c10 13095 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13096 if (symtab == NULL)
13097 continue;
13098
dda8d76d 13099 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13100 {
dda8d76d
NC
13101 strtab = filedata->string_table;
13102 strtab_size = filedata->string_table_length;
c256ffe7 13103 }
dda8d76d 13104 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13105 {
2cf0635d 13106 Elf_Internal_Shdr * string_sec;
252b5132 13107
dda8d76d 13108 string_sec = filedata->section_headers + section->sh_link;
252b5132 13109
dda8d76d 13110 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13111 1, string_sec->sh_size,
13112 _("string table"));
c256ffe7 13113 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13114 }
13115
10ca4b04
L
13116 for (si = 0; si < num_syms; si++)
13117 print_dynamic_symbol (filedata, si, symtab, section,
13118 strtab, strtab_size);
252b5132
RH
13119
13120 free (symtab);
dda8d76d 13121 if (strtab != filedata->string_table)
252b5132
RH
13122 free (strtab);
13123 }
13124 }
13125 else if (do_syms)
13126 printf
13127 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13128
978c4450 13129 if (do_histogram && filedata->buckets != NULL)
252b5132 13130 {
2cf0635d
NC
13131 unsigned long * lengths;
13132 unsigned long * counts;
66543521
AM
13133 unsigned long hn;
13134 bfd_vma si;
13135 unsigned long maxlength = 0;
13136 unsigned long nzero_counts = 0;
13137 unsigned long nsyms = 0;
6bd6a03d 13138 char *visited;
252b5132 13139
d3a49aa8
AM
13140 printf (ngettext ("\nHistogram for bucket list length "
13141 "(total of %lu bucket):\n",
13142 "\nHistogram for bucket list length "
13143 "(total of %lu buckets):\n",
978c4450
AM
13144 (unsigned long) filedata->nbuckets),
13145 (unsigned long) filedata->nbuckets);
252b5132 13146
978c4450
AM
13147 lengths = (unsigned long *) calloc (filedata->nbuckets,
13148 sizeof (*lengths));
252b5132
RH
13149 if (lengths == NULL)
13150 {
8b73c356 13151 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13152 goto err_out;
252b5132 13153 }
978c4450
AM
13154 visited = xcmalloc (filedata->nchains, 1);
13155 memset (visited, 0, filedata->nchains);
8b73c356
NC
13156
13157 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13158 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13159 {
978c4450 13160 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13161 {
b34976b6 13162 ++nsyms;
252b5132 13163 if (maxlength < ++lengths[hn])
b34976b6 13164 ++maxlength;
978c4450 13165 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13166 {
13167 error (_("histogram chain is corrupt\n"));
13168 break;
13169 }
13170 visited[si] = 1;
252b5132
RH
13171 }
13172 }
6bd6a03d 13173 free (visited);
252b5132 13174
3f5e193b 13175 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13176 if (counts == NULL)
13177 {
b2e951ec 13178 free (lengths);
8b73c356 13179 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13180 goto err_out;
252b5132
RH
13181 }
13182
978c4450 13183 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13184 ++counts[lengths[hn]];
252b5132 13185
978c4450 13186 if (filedata->nbuckets > 0)
252b5132 13187 {
66543521
AM
13188 unsigned long i;
13189 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13190 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13191 for (i = 1; i <= maxlength; ++i)
103f02d3 13192 {
66543521
AM
13193 nzero_counts += counts[i] * i;
13194 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13195 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13196 (nzero_counts * 100.0) / nsyms);
13197 }
252b5132
RH
13198 }
13199
13200 free (counts);
13201 free (lengths);
13202 }
13203
978c4450
AM
13204 free (filedata->buckets);
13205 filedata->buckets = NULL;
13206 filedata->nbuckets = 0;
13207 free (filedata->chains);
13208 filedata->chains = NULL;
252b5132 13209
978c4450 13210 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13211 {
2cf0635d
NC
13212 unsigned long * lengths;
13213 unsigned long * counts;
fdc90cb4
JJ
13214 unsigned long hn;
13215 unsigned long maxlength = 0;
13216 unsigned long nzero_counts = 0;
13217 unsigned long nsyms = 0;
fdc90cb4 13218
f16a9783 13219 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13220 "(total of %lu bucket):\n",
f16a9783 13221 "\nHistogram for `%s' bucket list length "
d3a49aa8 13222 "(total of %lu buckets):\n",
978c4450
AM
13223 (unsigned long) filedata->ngnubuckets),
13224 GNU_HASH_SECTION_NAME (filedata),
13225 (unsigned long) filedata->ngnubuckets);
8b73c356 13226
978c4450
AM
13227 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13228 sizeof (*lengths));
fdc90cb4
JJ
13229 if (lengths == NULL)
13230 {
8b73c356 13231 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13232 goto err_out;
fdc90cb4
JJ
13233 }
13234
fdc90cb4
JJ
13235 printf (_(" Length Number %% of total Coverage\n"));
13236
978c4450
AM
13237 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13238 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13239 {
13240 bfd_vma off, length = 1;
13241
978c4450 13242 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13243 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13244 off < filedata->ngnuchains
13245 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13246 ++off)
fdc90cb4
JJ
13247 ++length;
13248 lengths[hn] = length;
13249 if (length > maxlength)
13250 maxlength = length;
13251 nsyms += length;
13252 }
13253
3f5e193b 13254 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13255 if (counts == NULL)
13256 {
b2e951ec 13257 free (lengths);
8b73c356 13258 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13259 goto err_out;
fdc90cb4
JJ
13260 }
13261
978c4450 13262 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13263 ++counts[lengths[hn]];
13264
978c4450 13265 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13266 {
13267 unsigned long j;
13268 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13269 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13270 for (j = 1; j <= maxlength; ++j)
13271 {
13272 nzero_counts += counts[j] * j;
13273 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13274 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13275 (nzero_counts * 100.0) / nsyms);
13276 }
13277 }
13278
13279 free (counts);
13280 free (lengths);
fdc90cb4 13281 }
978c4450
AM
13282 free (filedata->gnubuckets);
13283 filedata->gnubuckets = NULL;
13284 filedata->ngnubuckets = 0;
13285 free (filedata->gnuchains);
13286 filedata->gnuchains = NULL;
13287 filedata->ngnuchains = 0;
13288 free (filedata->mipsxlat);
13289 filedata->mipsxlat = NULL;
015dc7e1 13290 return true;
fd486f32
AM
13291
13292 err_out:
978c4450
AM
13293 free (filedata->gnubuckets);
13294 filedata->gnubuckets = NULL;
13295 filedata->ngnubuckets = 0;
13296 free (filedata->gnuchains);
13297 filedata->gnuchains = NULL;
13298 filedata->ngnuchains = 0;
13299 free (filedata->mipsxlat);
13300 filedata->mipsxlat = NULL;
13301 free (filedata->buckets);
13302 filedata->buckets = NULL;
13303 filedata->nbuckets = 0;
13304 free (filedata->chains);
13305 filedata->chains = NULL;
015dc7e1 13306 return false;
252b5132
RH
13307}
13308
015dc7e1 13309static bool
ca0e11aa 13310process_syminfo (Filedata * filedata)
252b5132 13311{
b4c96d0d 13312 unsigned int i;
252b5132 13313
978c4450 13314 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13315 || !do_dynamic)
13316 /* No syminfo, this is ok. */
015dc7e1 13317 return true;
252b5132
RH
13318
13319 /* There better should be a dynamic symbol section. */
978c4450 13320 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13321 return false;
252b5132 13322
ca0e11aa
NC
13323 if (filedata->is_separate)
13324 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13325 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13326 filedata->dynamic_syminfo_nent),
13327 filedata->file_name,
13328 filedata->dynamic_syminfo_offset,
13329 filedata->dynamic_syminfo_nent);
13330 else
d3a49aa8
AM
13331 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13332 "contains %d entry:\n",
13333 "\nDynamic info segment at offset 0x%lx "
13334 "contains %d entries:\n",
978c4450 13335 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13336 filedata->dynamic_syminfo_offset,
13337 filedata->dynamic_syminfo_nent);
252b5132
RH
13338
13339 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13340 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13341 {
978c4450 13342 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13343
31104126 13344 printf ("%4d: ", i);
978c4450 13345 if (i >= filedata->num_dynamic_syms)
4082ef84 13346 printf (_("<corrupt index>"));
84714f86
AM
13347 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13348 print_symbol (30, get_dynamic_name (filedata,
978c4450 13349 filedata->dynamic_symbols[i].st_name));
d79b3d50 13350 else
978c4450 13351 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13352 putchar (' ');
252b5132 13353
978c4450 13354 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13355 {
13356 case SYMINFO_BT_SELF:
13357 fputs ("SELF ", stdout);
13358 break;
13359 case SYMINFO_BT_PARENT:
13360 fputs ("PARENT ", stdout);
13361 break;
13362 default:
978c4450
AM
13363 if (filedata->dynamic_syminfo[i].si_boundto > 0
13364 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13365 && valid_dynamic_name (filedata,
978c4450 13366 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13367 {
84714f86 13368 print_symbol (10, get_dynamic_name (filedata,
978c4450 13369 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13370 putchar (' ' );
13371 }
252b5132 13372 else
978c4450 13373 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13374 break;
13375 }
13376
13377 if (flags & SYMINFO_FLG_DIRECT)
13378 printf (" DIRECT");
13379 if (flags & SYMINFO_FLG_PASSTHRU)
13380 printf (" PASSTHRU");
13381 if (flags & SYMINFO_FLG_COPY)
13382 printf (" COPY");
13383 if (flags & SYMINFO_FLG_LAZYLOAD)
13384 printf (" LAZYLOAD");
13385
13386 puts ("");
13387 }
13388
015dc7e1 13389 return true;
252b5132
RH
13390}
13391
75802ccb
CE
13392/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13393 is contained by the region START .. END. The types of ADDR, START
13394 and END should all be the same. Note both ADDR + NELEM and END
13395 point to just beyond the end of the regions that are being tested. */
13396#define IN_RANGE(START,END,ADDR,NELEM) \
13397 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13398
cf13d699
NC
13399/* Check to see if the given reloc needs to be handled in a target specific
13400 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13401 FALSE.
13402
13403 If called with reloc == NULL, then this is a signal that reloc processing
13404 for the current section has finished, and any saved state should be
13405 discarded. */
09c11c86 13406
015dc7e1 13407static bool
dda8d76d
NC
13408target_specific_reloc_handling (Filedata * filedata,
13409 Elf_Internal_Rela * reloc,
13410 unsigned char * start,
13411 unsigned char * end,
13412 Elf_Internal_Sym * symtab,
13413 unsigned long num_syms)
252b5132 13414{
f84ce13b
NC
13415 unsigned int reloc_type = 0;
13416 unsigned long sym_index = 0;
13417
13418 if (reloc)
13419 {
dda8d76d 13420 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13421 sym_index = get_reloc_symindex (reloc->r_info);
13422 }
252b5132 13423
dda8d76d 13424 switch (filedata->file_header.e_machine)
252b5132 13425 {
13761a11
NC
13426 case EM_MSP430:
13427 case EM_MSP430_OLD:
13428 {
13429 static Elf_Internal_Sym * saved_sym = NULL;
13430
f84ce13b
NC
13431 if (reloc == NULL)
13432 {
13433 saved_sym = NULL;
015dc7e1 13434 return true;
f84ce13b
NC
13435 }
13436
13761a11
NC
13437 switch (reloc_type)
13438 {
13439 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13440 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13441 if (uses_msp430x_relocs (filedata))
13761a11 13442 break;
1a0670f3 13443 /* Fall through. */
13761a11 13444 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13445 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13446 /* PR 21139. */
13447 if (sym_index >= num_syms)
13448 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13449 sym_index);
13450 else
13451 saved_sym = symtab + sym_index;
015dc7e1 13452 return true;
13761a11
NC
13453
13454 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13455 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13456 goto handle_sym_diff;
0b4362b0 13457
13761a11
NC
13458 case 5: /* R_MSP430_16_BYTE */
13459 case 9: /* R_MSP430_8 */
7d81bc93 13460 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13461 if (uses_msp430x_relocs (filedata))
13761a11
NC
13462 break;
13463 goto handle_sym_diff;
13464
13465 case 2: /* R_MSP430_ABS16 */
13466 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13467 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13468 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13469 break;
13470 goto handle_sym_diff;
0b4362b0 13471
13761a11
NC
13472 handle_sym_diff:
13473 if (saved_sym != NULL)
13474 {
13475 bfd_vma value;
5a805384 13476 unsigned int reloc_size = 0;
7d81bc93
JL
13477 int leb_ret = 0;
13478 switch (reloc_type)
13479 {
13480 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13481 reloc_size = 4;
13482 break;
13483 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13484 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13485 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13486 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13487 &reloc_size, &leb_ret);
7d81bc93
JL
13488 break;
13489 default:
13490 reloc_size = 2;
13491 break;
13492 }
13761a11 13493
5a805384 13494 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13495 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13496 "ULEB128 value\n"),
13497 (long) reloc->r_offset);
13498 else if (sym_index >= num_syms)
f84ce13b
NC
13499 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13500 sym_index);
03f7786e 13501 else
f84ce13b
NC
13502 {
13503 value = reloc->r_addend + (symtab[sym_index].st_value
13504 - saved_sym->st_value);
13505
b32e566b 13506 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13507 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13508 else
13509 /* PR 21137 */
13510 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13511 (long) reloc->r_offset);
f84ce13b 13512 }
13761a11
NC
13513
13514 saved_sym = NULL;
015dc7e1 13515 return true;
13761a11
NC
13516 }
13517 break;
13518
13519 default:
13520 if (saved_sym != NULL)
071436c6 13521 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13522 break;
13523 }
13524 break;
13525 }
13526
cf13d699
NC
13527 case EM_MN10300:
13528 case EM_CYGNUS_MN10300:
13529 {
13530 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13531
f84ce13b
NC
13532 if (reloc == NULL)
13533 {
13534 saved_sym = NULL;
015dc7e1 13535 return true;
f84ce13b
NC
13536 }
13537
cf13d699
NC
13538 switch (reloc_type)
13539 {
13540 case 34: /* R_MN10300_ALIGN */
015dc7e1 13541 return true;
cf13d699 13542 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13543 if (sym_index >= num_syms)
13544 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13545 sym_index);
13546 else
13547 saved_sym = symtab + sym_index;
015dc7e1 13548 return true;
f84ce13b 13549
cf13d699
NC
13550 case 1: /* R_MN10300_32 */
13551 case 2: /* R_MN10300_16 */
13552 if (saved_sym != NULL)
13553 {
03f7786e 13554 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13555 bfd_vma value;
252b5132 13556
f84ce13b
NC
13557 if (sym_index >= num_syms)
13558 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13559 sym_index);
03f7786e 13560 else
f84ce13b
NC
13561 {
13562 value = reloc->r_addend + (symtab[sym_index].st_value
13563 - saved_sym->st_value);
13564
b32e566b 13565 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13566 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13567 else
13568 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13569 (long) reloc->r_offset);
f84ce13b 13570 }
252b5132 13571
cf13d699 13572 saved_sym = NULL;
015dc7e1 13573 return true;
cf13d699
NC
13574 }
13575 break;
13576 default:
13577 if (saved_sym != NULL)
071436c6 13578 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13579 break;
13580 }
13581 break;
13582 }
6ff71e76
NC
13583
13584 case EM_RL78:
13585 {
13586 static bfd_vma saved_sym1 = 0;
13587 static bfd_vma saved_sym2 = 0;
13588 static bfd_vma value;
13589
f84ce13b
NC
13590 if (reloc == NULL)
13591 {
13592 saved_sym1 = saved_sym2 = 0;
015dc7e1 13593 return true;
f84ce13b
NC
13594 }
13595
6ff71e76
NC
13596 switch (reloc_type)
13597 {
13598 case 0x80: /* R_RL78_SYM. */
13599 saved_sym1 = saved_sym2;
f84ce13b
NC
13600 if (sym_index >= num_syms)
13601 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13602 sym_index);
13603 else
13604 {
13605 saved_sym2 = symtab[sym_index].st_value;
13606 saved_sym2 += reloc->r_addend;
13607 }
015dc7e1 13608 return true;
6ff71e76
NC
13609
13610 case 0x83: /* R_RL78_OPsub. */
13611 value = saved_sym1 - saved_sym2;
13612 saved_sym2 = saved_sym1 = 0;
015dc7e1 13613 return true;
6ff71e76
NC
13614 break;
13615
13616 case 0x41: /* R_RL78_ABS32. */
b32e566b 13617 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13618 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13619 else
13620 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13621 (long) reloc->r_offset);
6ff71e76 13622 value = 0;
015dc7e1 13623 return true;
6ff71e76
NC
13624
13625 case 0x43: /* R_RL78_ABS16. */
b32e566b 13626 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13627 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13628 else
13629 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13630 (long) reloc->r_offset);
6ff71e76 13631 value = 0;
015dc7e1 13632 return true;
6ff71e76
NC
13633
13634 default:
13635 break;
13636 }
13637 break;
13638 }
252b5132
RH
13639 }
13640
015dc7e1 13641 return false;
252b5132
RH
13642}
13643
aca88567
NC
13644/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13645 DWARF debug sections. This is a target specific test. Note - we do not
13646 go through the whole including-target-headers-multiple-times route, (as
13647 we have already done with <elf/h8.h>) because this would become very
13648 messy and even then this function would have to contain target specific
13649 information (the names of the relocs instead of their numeric values).
13650 FIXME: This is not the correct way to solve this problem. The proper way
13651 is to have target specific reloc sizing and typing functions created by
13652 the reloc-macros.h header, in the same way that it already creates the
13653 reloc naming functions. */
13654
015dc7e1 13655static bool
dda8d76d 13656is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13657{
d347c9df 13658 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13659 switch (filedata->file_header.e_machine)
aca88567 13660 {
41e92641 13661 case EM_386:
22abe556 13662 case EM_IAMCU:
41e92641 13663 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13664 case EM_68K:
13665 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13666 case EM_860:
13667 return reloc_type == 1; /* R_860_32. */
13668 case EM_960:
13669 return reloc_type == 2; /* R_960_32. */
a06ea964 13670 case EM_AARCH64:
9282b95a
JW
13671 return (reloc_type == 258
13672 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13673 case EM_BPF:
13674 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13675 case EM_ADAPTEVA_EPIPHANY:
13676 return reloc_type == 3;
aca88567 13677 case EM_ALPHA:
137b6b5f 13678 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13679 case EM_ARC:
13680 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13681 case EM_ARC_COMPACT:
13682 case EM_ARC_COMPACT2:
13683 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13684 case EM_ARM:
13685 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13686 case EM_AVR_OLD:
aca88567
NC
13687 case EM_AVR:
13688 return reloc_type == 1;
13689 case EM_BLACKFIN:
13690 return reloc_type == 0x12; /* R_byte4_data. */
13691 case EM_CRIS:
13692 return reloc_type == 3; /* R_CRIS_32. */
13693 case EM_CR16:
13694 return reloc_type == 3; /* R_CR16_NUM32. */
13695 case EM_CRX:
13696 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13697 case EM_CSKY:
13698 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13699 case EM_CYGNUS_FRV:
13700 return reloc_type == 1;
41e92641
NC
13701 case EM_CYGNUS_D10V:
13702 case EM_D10V:
13703 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13704 case EM_CYGNUS_D30V:
13705 case EM_D30V:
13706 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13707 case EM_DLX:
13708 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13709 case EM_CYGNUS_FR30:
13710 case EM_FR30:
13711 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13712 case EM_FT32:
13713 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13714 case EM_H8S:
13715 case EM_H8_300:
13716 case EM_H8_300H:
13717 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13718 case EM_IA_64:
262cdac7
AM
13719 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13720 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13721 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13722 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13723 case EM_IP2K_OLD:
13724 case EM_IP2K:
13725 return reloc_type == 2; /* R_IP2K_32. */
13726 case EM_IQ2000:
13727 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13728 case EM_LATTICEMICO32:
13729 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 13730 case EM_LOONGARCH:
13731 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 13732 case EM_M32C_OLD:
aca88567
NC
13733 case EM_M32C:
13734 return reloc_type == 3; /* R_M32C_32. */
13735 case EM_M32R:
13736 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13737 case EM_68HC11:
13738 case EM_68HC12:
13739 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13740 case EM_S12Z:
2849d19f
JD
13741 return reloc_type == 7 || /* R_S12Z_EXT32 */
13742 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13743 case EM_MCORE:
13744 return reloc_type == 1; /* R_MCORE_ADDR32. */
13745 case EM_CYGNUS_MEP:
13746 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13747 case EM_METAG:
13748 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13749 case EM_MICROBLAZE:
13750 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13751 case EM_MIPS:
13752 return reloc_type == 2; /* R_MIPS_32. */
13753 case EM_MMIX:
13754 return reloc_type == 4; /* R_MMIX_32. */
13755 case EM_CYGNUS_MN10200:
13756 case EM_MN10200:
13757 return reloc_type == 1; /* R_MN10200_32. */
13758 case EM_CYGNUS_MN10300:
13759 case EM_MN10300:
13760 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13761 case EM_MOXIE:
13762 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13763 case EM_MSP430_OLD:
13764 case EM_MSP430:
13761a11 13765 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13766 case EM_MT:
13767 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13768 case EM_NDS32:
13769 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13770 case EM_ALTERA_NIOS2:
36591ba1 13771 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13772 case EM_NIOS32:
13773 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13774 case EM_OR1K:
13775 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13776 case EM_PARISC:
9abca702 13777 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13778 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13779 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13780 case EM_PJ:
13781 case EM_PJ_OLD:
13782 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13783 case EM_PPC64:
13784 return reloc_type == 1; /* R_PPC64_ADDR32. */
13785 case EM_PPC:
13786 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13787 case EM_TI_PRU:
13788 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13789 case EM_RISCV:
13790 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13791 case EM_RL78:
13792 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13793 case EM_RX:
13794 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13795 case EM_S370:
13796 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13797 case EM_S390_OLD:
13798 case EM_S390:
13799 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13800 case EM_SCORE:
13801 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13802 case EM_SH:
13803 return reloc_type == 1; /* R_SH_DIR32. */
13804 case EM_SPARC32PLUS:
13805 case EM_SPARCV9:
13806 case EM_SPARC:
13807 return reloc_type == 3 /* R_SPARC_32. */
13808 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13809 case EM_SPU:
13810 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13811 case EM_TI_C6000:
13812 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13813 case EM_TILEGX:
13814 return reloc_type == 2; /* R_TILEGX_32. */
13815 case EM_TILEPRO:
13816 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13817 case EM_CYGNUS_V850:
13818 case EM_V850:
13819 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13820 case EM_V800:
13821 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13822 case EM_VAX:
13823 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13824 case EM_VISIUM:
13825 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13826 case EM_WEBASSEMBLY:
13827 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13828 case EM_X86_64:
8a9036a4 13829 case EM_L1OM:
7a9068fe 13830 case EM_K1OM:
aca88567 13831 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13832 case EM_XC16X:
13833 case EM_C166:
13834 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13835 case EM_XGATE:
13836 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13837 case EM_XSTORMY16:
13838 return reloc_type == 1; /* R_XSTROMY16_32. */
13839 case EM_XTENSA_OLD:
13840 case EM_XTENSA:
13841 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13842 case EM_Z80:
13843 return reloc_type == 6; /* R_Z80_32. */
aca88567 13844 default:
bee0ee85
NC
13845 {
13846 static unsigned int prev_warn = 0;
13847
13848 /* Avoid repeating the same warning multiple times. */
dda8d76d 13849 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13850 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13851 filedata->file_header.e_machine);
13852 prev_warn = filedata->file_header.e_machine;
015dc7e1 13853 return false;
bee0ee85 13854 }
aca88567
NC
13855 }
13856}
13857
13858/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13859 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13860
015dc7e1 13861static bool
dda8d76d 13862is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13863{
dda8d76d 13864 switch (filedata->file_header.e_machine)
d347c9df 13865 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13866 {
41e92641 13867 case EM_386:
22abe556 13868 case EM_IAMCU:
3e0873ac 13869 return reloc_type == 2; /* R_386_PC32. */
aca88567 13870 case EM_68K:
3e0873ac 13871 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13872 case EM_AARCH64:
13873 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13874 case EM_ADAPTEVA_EPIPHANY:
13875 return reloc_type == 6;
aca88567
NC
13876 case EM_ALPHA:
13877 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13878 case EM_ARC_COMPACT:
13879 case EM_ARC_COMPACT2:
13880 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13881 case EM_ARM:
3e0873ac 13882 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13883 case EM_AVR_OLD:
13884 case EM_AVR:
13885 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13886 case EM_MICROBLAZE:
13887 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13888 case EM_OR1K:
13889 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13890 case EM_PARISC:
85acf597 13891 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13892 case EM_PPC:
13893 return reloc_type == 26; /* R_PPC_REL32. */
13894 case EM_PPC64:
3e0873ac 13895 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13896 case EM_RISCV:
13897 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13898 case EM_S390_OLD:
13899 case EM_S390:
3e0873ac 13900 return reloc_type == 5; /* R_390_PC32. */
aca88567 13901 case EM_SH:
3e0873ac 13902 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13903 case EM_SPARC32PLUS:
13904 case EM_SPARCV9:
13905 case EM_SPARC:
3e0873ac 13906 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13907 case EM_SPU:
13908 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13909 case EM_TILEGX:
13910 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13911 case EM_TILEPRO:
13912 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13913 case EM_VISIUM:
13914 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13915 case EM_X86_64:
8a9036a4 13916 case EM_L1OM:
7a9068fe 13917 case EM_K1OM:
3e0873ac 13918 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13919 case EM_VAX:
13920 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13921 case EM_XTENSA_OLD:
13922 case EM_XTENSA:
13923 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13924 default:
13925 /* Do not abort or issue an error message here. Not all targets use
13926 pc-relative 32-bit relocs in their DWARF debug information and we
13927 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13928 more helpful warning message will be generated by apply_relocations
13929 anyway, so just return. */
015dc7e1 13930 return false;
aca88567
NC
13931 }
13932}
13933
13934/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13935 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13936
015dc7e1 13937static bool
dda8d76d 13938is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13939{
dda8d76d 13940 switch (filedata->file_header.e_machine)
aca88567 13941 {
a06ea964
NC
13942 case EM_AARCH64:
13943 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13944 case EM_ALPHA:
13945 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13946 case EM_IA_64:
262cdac7
AM
13947 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13948 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 13949 case EM_LOONGARCH:
13950 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
13951 case EM_PARISC:
13952 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13953 case EM_PPC64:
13954 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13955 case EM_RISCV:
13956 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13957 case EM_SPARC32PLUS:
13958 case EM_SPARCV9:
13959 case EM_SPARC:
714da62f
NC
13960 return reloc_type == 32 /* R_SPARC_64. */
13961 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13962 case EM_X86_64:
8a9036a4 13963 case EM_L1OM:
7a9068fe 13964 case EM_K1OM:
aca88567 13965 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13966 case EM_S390_OLD:
13967 case EM_S390:
aa137e4d
NC
13968 return reloc_type == 22; /* R_S390_64. */
13969 case EM_TILEGX:
13970 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13971 case EM_MIPS:
aa137e4d 13972 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13973 default:
015dc7e1 13974 return false;
aca88567
NC
13975 }
13976}
13977
85acf597
RH
13978/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13979 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13980
015dc7e1 13981static bool
dda8d76d 13982is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13983{
dda8d76d 13984 switch (filedata->file_header.e_machine)
85acf597 13985 {
a06ea964
NC
13986 case EM_AARCH64:
13987 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13988 case EM_ALPHA:
aa137e4d 13989 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13990 case EM_IA_64:
262cdac7
AM
13991 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13992 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13993 case EM_PARISC:
aa137e4d 13994 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13995 case EM_PPC64:
aa137e4d 13996 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13997 case EM_SPARC32PLUS:
13998 case EM_SPARCV9:
13999 case EM_SPARC:
aa137e4d 14000 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14001 case EM_X86_64:
8a9036a4 14002 case EM_L1OM:
7a9068fe 14003 case EM_K1OM:
aa137e4d 14004 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14005 case EM_S390_OLD:
14006 case EM_S390:
aa137e4d
NC
14007 return reloc_type == 23; /* R_S390_PC64. */
14008 case EM_TILEGX:
14009 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14010 default:
015dc7e1 14011 return false;
85acf597
RH
14012 }
14013}
14014
4dc3c23d
AM
14015/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14016 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14017
015dc7e1 14018static bool
dda8d76d 14019is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14020{
dda8d76d 14021 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14022 {
14023 case EM_CYGNUS_MN10200:
14024 case EM_MN10200:
14025 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14026 case EM_FT32:
14027 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14028 case EM_Z80:
14029 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14030 default:
015dc7e1 14031 return false;
4dc3c23d
AM
14032 }
14033}
14034
aca88567
NC
14035/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14036 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14037
015dc7e1 14038static bool
dda8d76d 14039is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14040{
d347c9df 14041 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14042 switch (filedata->file_header.e_machine)
4b78141a 14043 {
886a2506
NC
14044 case EM_ARC:
14045 case EM_ARC_COMPACT:
14046 case EM_ARC_COMPACT2:
14047 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14048 case EM_ADAPTEVA_EPIPHANY:
14049 return reloc_type == 5;
aca88567
NC
14050 case EM_AVR_OLD:
14051 case EM_AVR:
14052 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14053 case EM_CYGNUS_D10V:
14054 case EM_D10V:
14055 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14056 case EM_FT32:
14057 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14058 case EM_H8S:
14059 case EM_H8_300:
14060 case EM_H8_300H:
aca88567
NC
14061 return reloc_type == R_H8_DIR16;
14062 case EM_IP2K_OLD:
14063 case EM_IP2K:
14064 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14065 case EM_M32C_OLD:
f4236fe4
DD
14066 case EM_M32C:
14067 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14068 case EM_CYGNUS_MN10200:
14069 case EM_MN10200:
14070 return reloc_type == 2; /* R_MN10200_16. */
14071 case EM_CYGNUS_MN10300:
14072 case EM_MN10300:
14073 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14074 case EM_MSP430:
dda8d76d 14075 if (uses_msp430x_relocs (filedata))
13761a11 14076 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14077 /* Fall through. */
78c8d46c 14078 case EM_MSP430_OLD:
aca88567 14079 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14080 case EM_NDS32:
14081 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14082 case EM_ALTERA_NIOS2:
36591ba1 14083 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14084 case EM_NIOS32:
14085 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14086 case EM_OR1K:
14087 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14088 case EM_RISCV:
14089 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14090 case EM_TI_PRU:
14091 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14092 case EM_TI_C6000:
14093 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14094 case EM_VISIUM:
14095 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14096 case EM_XC16X:
14097 case EM_C166:
14098 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14099 case EM_XGATE:
14100 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14101 case EM_Z80:
14102 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14103 default:
015dc7e1 14104 return false;
4b78141a
NC
14105 }
14106}
14107
39e07931
AS
14108/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14109 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14110
015dc7e1 14111static bool
39e07931
AS
14112is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14113{
14114 switch (filedata->file_header.e_machine)
14115 {
14116 case EM_RISCV:
14117 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14118 case EM_Z80:
14119 return reloc_type == 1; /* R_Z80_8. */
39e07931 14120 default:
015dc7e1 14121 return false;
39e07931
AS
14122 }
14123}
14124
14125/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14126 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14127
015dc7e1 14128static bool
39e07931
AS
14129is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14130{
14131 switch (filedata->file_header.e_machine)
14132 {
14133 case EM_RISCV:
14134 return reloc_type == 53; /* R_RISCV_SET6. */
14135 default:
015dc7e1 14136 return false;
39e07931
AS
14137 }
14138}
14139
03336641
JW
14140/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14141 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14142
015dc7e1 14143static bool
03336641
JW
14144is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14145{
14146 /* Please keep this table alpha-sorted for ease of visual lookup. */
14147 switch (filedata->file_header.e_machine)
14148 {
14149 case EM_RISCV:
14150 return reloc_type == 35; /* R_RISCV_ADD32. */
14151 default:
015dc7e1 14152 return false;
03336641
JW
14153 }
14154}
14155
14156/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14157 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14158
015dc7e1 14159static bool
03336641
JW
14160is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14161{
14162 /* Please keep this table alpha-sorted for ease of visual lookup. */
14163 switch (filedata->file_header.e_machine)
14164 {
14165 case EM_RISCV:
14166 return reloc_type == 39; /* R_RISCV_SUB32. */
14167 default:
015dc7e1 14168 return false;
03336641
JW
14169 }
14170}
14171
14172/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14173 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14174
015dc7e1 14175static bool
03336641
JW
14176is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14177{
14178 /* Please keep this table alpha-sorted for ease of visual lookup. */
14179 switch (filedata->file_header.e_machine)
14180 {
14181 case EM_RISCV:
14182 return reloc_type == 36; /* R_RISCV_ADD64. */
14183 default:
015dc7e1 14184 return false;
03336641
JW
14185 }
14186}
14187
14188/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14189 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14190
015dc7e1 14191static bool
03336641
JW
14192is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14193{
14194 /* Please keep this table alpha-sorted for ease of visual lookup. */
14195 switch (filedata->file_header.e_machine)
14196 {
14197 case EM_RISCV:
14198 return reloc_type == 40; /* R_RISCV_SUB64. */
14199 default:
015dc7e1 14200 return false;
03336641
JW
14201 }
14202}
14203
14204/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14205 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14206
015dc7e1 14207static bool
03336641
JW
14208is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14209{
14210 /* Please keep this table alpha-sorted for ease of visual lookup. */
14211 switch (filedata->file_header.e_machine)
14212 {
14213 case EM_RISCV:
14214 return reloc_type == 34; /* R_RISCV_ADD16. */
14215 default:
015dc7e1 14216 return false;
03336641
JW
14217 }
14218}
14219
14220/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14221 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14222
015dc7e1 14223static bool
03336641
JW
14224is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14225{
14226 /* Please keep this table alpha-sorted for ease of visual lookup. */
14227 switch (filedata->file_header.e_machine)
14228 {
14229 case EM_RISCV:
14230 return reloc_type == 38; /* R_RISCV_SUB16. */
14231 default:
015dc7e1 14232 return false;
03336641
JW
14233 }
14234}
14235
14236/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14237 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14238
015dc7e1 14239static bool
03336641
JW
14240is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14241{
14242 /* Please keep this table alpha-sorted for ease of visual lookup. */
14243 switch (filedata->file_header.e_machine)
14244 {
14245 case EM_RISCV:
14246 return reloc_type == 33; /* R_RISCV_ADD8. */
14247 default:
015dc7e1 14248 return false;
03336641
JW
14249 }
14250}
14251
14252/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14253 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14254
015dc7e1 14255static bool
03336641
JW
14256is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14257{
14258 /* Please keep this table alpha-sorted for ease of visual lookup. */
14259 switch (filedata->file_header.e_machine)
14260 {
14261 case EM_RISCV:
14262 return reloc_type == 37; /* R_RISCV_SUB8. */
14263 default:
015dc7e1 14264 return false;
03336641
JW
14265 }
14266}
14267
39e07931
AS
14268/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14269 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14270
015dc7e1 14271static bool
39e07931
AS
14272is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14273{
14274 switch (filedata->file_header.e_machine)
14275 {
14276 case EM_RISCV:
14277 return reloc_type == 52; /* R_RISCV_SUB6. */
14278 default:
015dc7e1 14279 return false;
39e07931
AS
14280 }
14281}
14282
2a7b2e88
JK
14283/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14284 relocation entries (possibly formerly used for SHT_GROUP sections). */
14285
015dc7e1 14286static bool
dda8d76d 14287is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14288{
dda8d76d 14289 switch (filedata->file_header.e_machine)
2a7b2e88 14290 {
cb8f3167 14291 case EM_386: /* R_386_NONE. */
d347c9df 14292 case EM_68K: /* R_68K_NONE. */
cfb8c092 14293 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14294 case EM_ALPHA: /* R_ALPHA_NONE. */
14295 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14296 case EM_ARC: /* R_ARC_NONE. */
886a2506 14297 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14298 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14299 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14300 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14301 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14302 case EM_FT32: /* R_FT32_NONE. */
14303 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14304 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14305 case EM_L1OM: /* R_X86_64_NONE. */
14306 case EM_M32R: /* R_M32R_NONE. */
14307 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14308 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14309 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14310 case EM_NIOS32: /* R_NIOS_NONE. */
14311 case EM_OR1K: /* R_OR1K_NONE. */
14312 case EM_PARISC: /* R_PARISC_NONE. */
14313 case EM_PPC64: /* R_PPC64_NONE. */
14314 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14315 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14316 case EM_S390: /* R_390_NONE. */
14317 case EM_S390_OLD:
14318 case EM_SH: /* R_SH_NONE. */
14319 case EM_SPARC32PLUS:
14320 case EM_SPARC: /* R_SPARC_NONE. */
14321 case EM_SPARCV9:
aa137e4d
NC
14322 case EM_TILEGX: /* R_TILEGX_NONE. */
14323 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14324 case EM_TI_C6000:/* R_C6000_NONE. */
14325 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14326 case EM_XC16X:
6655dba2 14327 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14328 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14329 return reloc_type == 0;
d347c9df 14330
a06ea964
NC
14331 case EM_AARCH64:
14332 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14333 case EM_AVR_OLD:
14334 case EM_AVR:
14335 return (reloc_type == 0 /* R_AVR_NONE. */
14336 || reloc_type == 30 /* R_AVR_DIFF8. */
14337 || reloc_type == 31 /* R_AVR_DIFF16. */
14338 || reloc_type == 32 /* R_AVR_DIFF32. */);
14339 case EM_METAG:
14340 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14341 case EM_NDS32:
14342 return (reloc_type == 0 /* R_XTENSA_NONE. */
14343 || reloc_type == 204 /* R_NDS32_DIFF8. */
14344 || reloc_type == 205 /* R_NDS32_DIFF16. */
14345 || reloc_type == 206 /* R_NDS32_DIFF32. */
14346 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14347 case EM_TI_PRU:
14348 return (reloc_type == 0 /* R_PRU_NONE. */
14349 || reloc_type == 65 /* R_PRU_DIFF8. */
14350 || reloc_type == 66 /* R_PRU_DIFF16. */
14351 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14352 case EM_XTENSA_OLD:
14353 case EM_XTENSA:
4dc3c23d
AM
14354 return (reloc_type == 0 /* R_XTENSA_NONE. */
14355 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14356 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14357 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14358 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14359 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14360 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14361 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14362 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14363 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14364 }
015dc7e1 14365 return false;
2a7b2e88
JK
14366}
14367
d1c4b12b
NC
14368/* Returns TRUE if there is a relocation against
14369 section NAME at OFFSET bytes. */
14370
015dc7e1 14371bool
d1c4b12b
NC
14372reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14373{
14374 Elf_Internal_Rela * relocs;
14375 Elf_Internal_Rela * rp;
14376
14377 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14378 return false;
d1c4b12b
NC
14379
14380 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14381
14382 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14383 if (rp->r_offset == offset)
015dc7e1 14384 return true;
d1c4b12b 14385
015dc7e1 14386 return false;
d1c4b12b
NC
14387}
14388
cf13d699 14389/* Apply relocations to a section.
32ec8896
NC
14390 Returns TRUE upon success, FALSE otherwise.
14391 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14392 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14393 will be set to the number of relocs loaded.
14394
cf13d699 14395 Note: So far support has been added only for those relocations
32ec8896
NC
14396 which can be found in debug sections. FIXME: Add support for
14397 more relocations ? */
1b315056 14398
015dc7e1 14399static bool
dda8d76d 14400apply_relocations (Filedata * filedata,
d1c4b12b
NC
14401 const Elf_Internal_Shdr * section,
14402 unsigned char * start,
14403 bfd_size_type size,
1449284b 14404 void ** relocs_return,
d1c4b12b 14405 unsigned long * num_relocs_return)
1b315056 14406{
cf13d699 14407 Elf_Internal_Shdr * relsec;
0d2a7a93 14408 unsigned char * end = start + size;
cb8f3167 14409
d1c4b12b
NC
14410 if (relocs_return != NULL)
14411 {
14412 * (Elf_Internal_Rela **) relocs_return = NULL;
14413 * num_relocs_return = 0;
14414 }
14415
dda8d76d 14416 if (filedata->file_header.e_type != ET_REL)
32ec8896 14417 /* No relocs to apply. */
015dc7e1 14418 return true;
1b315056 14419
cf13d699 14420 /* Find the reloc section associated with the section. */
dda8d76d
NC
14421 for (relsec = filedata->section_headers;
14422 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14423 ++relsec)
252b5132 14424 {
015dc7e1 14425 bool is_rela;
41e92641 14426 unsigned long num_relocs;
2cf0635d
NC
14427 Elf_Internal_Rela * relocs;
14428 Elf_Internal_Rela * rp;
14429 Elf_Internal_Shdr * symsec;
14430 Elf_Internal_Sym * symtab;
ba5cdace 14431 unsigned long num_syms;
2cf0635d 14432 Elf_Internal_Sym * sym;
252b5132 14433
41e92641 14434 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14435 || relsec->sh_info >= filedata->file_header.e_shnum
14436 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14437 || relsec->sh_size == 0
dda8d76d 14438 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14439 continue;
428409d5 14440
a788aedd
AM
14441 symsec = filedata->section_headers + relsec->sh_link;
14442 if (symsec->sh_type != SHT_SYMTAB
14443 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14444 return false;
a788aedd 14445
41e92641
NC
14446 is_rela = relsec->sh_type == SHT_RELA;
14447
14448 if (is_rela)
14449 {
dda8d76d 14450 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14451 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14452 return false;
41e92641
NC
14453 }
14454 else
14455 {
dda8d76d 14456 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14457 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14458 return false;
41e92641
NC
14459 }
14460
14461 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14462 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14463 is_rela = false;
428409d5 14464
4de91c10 14465 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14466
41e92641 14467 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14468 {
015dc7e1
AM
14469 bfd_vma addend;
14470 unsigned int reloc_type;
14471 unsigned int reloc_size;
14472 bool reloc_inplace = false;
14473 bool reloc_subtract = false;
14474 unsigned char *rloc;
14475 unsigned long sym_index;
4b78141a 14476
dda8d76d 14477 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14478
dda8d76d 14479 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14480 continue;
dda8d76d 14481 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14482 continue;
dda8d76d
NC
14483 else if (is_32bit_abs_reloc (filedata, reloc_type)
14484 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14485 reloc_size = 4;
dda8d76d
NC
14486 else if (is_64bit_abs_reloc (filedata, reloc_type)
14487 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14488 reloc_size = 8;
dda8d76d 14489 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14490 reloc_size = 3;
dda8d76d 14491 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14492 reloc_size = 2;
39e07931
AS
14493 else if (is_8bit_abs_reloc (filedata, reloc_type)
14494 || is_6bit_abs_reloc (filedata, reloc_type))
14495 reloc_size = 1;
03336641
JW
14496 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14497 reloc_type))
14498 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14499 {
14500 reloc_size = 4;
015dc7e1 14501 reloc_inplace = true;
03336641
JW
14502 }
14503 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14504 reloc_type))
14505 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14506 {
14507 reloc_size = 8;
015dc7e1 14508 reloc_inplace = true;
03336641
JW
14509 }
14510 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14511 reloc_type))
14512 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14513 {
14514 reloc_size = 2;
015dc7e1 14515 reloc_inplace = true;
03336641
JW
14516 }
14517 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14518 reloc_type))
14519 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14520 {
14521 reloc_size = 1;
015dc7e1 14522 reloc_inplace = true;
03336641 14523 }
39e07931
AS
14524 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14525 reloc_type)))
14526 {
14527 reloc_size = 1;
015dc7e1 14528 reloc_inplace = true;
39e07931 14529 }
aca88567 14530 else
4b78141a 14531 {
bee0ee85 14532 static unsigned int prev_reloc = 0;
dda8d76d 14533
bee0ee85
NC
14534 if (reloc_type != prev_reloc)
14535 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14536 reloc_type, printable_section_name (filedata, section));
bee0ee85 14537 prev_reloc = reloc_type;
4b78141a
NC
14538 continue;
14539 }
103f02d3 14540
91d6fa6a 14541 rloc = start + rp->r_offset;
75802ccb 14542 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14543 {
14544 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14545 (unsigned long) rp->r_offset,
dda8d76d 14546 printable_section_name (filedata, section));
700dd8b7
L
14547 continue;
14548 }
103f02d3 14549
ba5cdace
NC
14550 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14551 if (sym_index >= num_syms)
14552 {
14553 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14554 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14555 continue;
14556 }
14557 sym = symtab + sym_index;
41e92641
NC
14558
14559 /* If the reloc has a symbol associated with it,
55f25fc3
L
14560 make sure that it is of an appropriate type.
14561
14562 Relocations against symbols without type can happen.
14563 Gcc -feliminate-dwarf2-dups may generate symbols
14564 without type for debug info.
14565
14566 Icc generates relocations against function symbols
14567 instead of local labels.
14568
14569 Relocations against object symbols can happen, eg when
14570 referencing a global array. For an example of this see
14571 the _clz.o binary in libgcc.a. */
aca88567 14572 if (sym != symtab
b8871f35 14573 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14574 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14575 {
d3a49aa8 14576 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14577 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14578 printable_section_name (filedata, relsec),
d3a49aa8 14579 (long int)(rp - relocs));
aca88567 14580 continue;
5b18a4bc 14581 }
252b5132 14582
4dc3c23d
AM
14583 addend = 0;
14584 if (is_rela)
14585 addend += rp->r_addend;
c47320c3
AM
14586 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14587 partial_inplace. */
4dc3c23d 14588 if (!is_rela
dda8d76d 14589 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14590 && reloc_type == 1)
dda8d76d
NC
14591 || ((filedata->file_header.e_machine == EM_PJ
14592 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14593 && reloc_type == 1)
dda8d76d
NC
14594 || ((filedata->file_header.e_machine == EM_D30V
14595 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14596 && reloc_type == 12)
14597 || reloc_inplace)
39e07931
AS
14598 {
14599 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14600 addend += byte_get (rloc, reloc_size) & 0x3f;
14601 else
14602 addend += byte_get (rloc, reloc_size);
14603 }
cb8f3167 14604
dda8d76d
NC
14605 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14606 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14607 {
14608 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14609 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14610 addend -= 8;
91d6fa6a 14611 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14612 reloc_size);
14613 }
39e07931
AS
14614 else if (is_6bit_abs_reloc (filedata, reloc_type)
14615 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14616 {
14617 if (reloc_subtract)
14618 addend -= sym->st_value;
14619 else
14620 addend += sym->st_value;
14621 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14622 byte_put (rloc, addend, reloc_size);
14623 }
03336641
JW
14624 else if (reloc_subtract)
14625 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14626 else
91d6fa6a 14627 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14628 }
252b5132 14629
5b18a4bc 14630 free (symtab);
f84ce13b
NC
14631 /* Let the target specific reloc processing code know that
14632 we have finished with these relocs. */
dda8d76d 14633 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14634
14635 if (relocs_return)
14636 {
14637 * (Elf_Internal_Rela **) relocs_return = relocs;
14638 * num_relocs_return = num_relocs;
14639 }
14640 else
14641 free (relocs);
14642
5b18a4bc
NC
14643 break;
14644 }
32ec8896 14645
015dc7e1 14646 return true;
5b18a4bc 14647}
103f02d3 14648
cf13d699 14649#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14650static bool
dda8d76d 14651disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14652{
dda8d76d 14653 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14654
74e1a04b 14655 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14656
015dc7e1 14657 return true;
cf13d699
NC
14658}
14659#endif
14660
14661/* Reads in the contents of SECTION from FILE, returning a pointer
14662 to a malloc'ed buffer or NULL if something went wrong. */
14663
14664static char *
dda8d76d 14665get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14666{
dda8d76d 14667 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14668
14669 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14670 {
c6b78c96 14671 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14672 printable_section_name (filedata, section));
cf13d699
NC
14673 return NULL;
14674 }
14675
dda8d76d 14676 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14677 _("section contents"));
cf13d699
NC
14678}
14679
0e602686
NC
14680/* Uncompresses a section that was compressed using zlib, in place. */
14681
015dc7e1 14682static bool
dda8d76d
NC
14683uncompress_section_contents (unsigned char ** buffer,
14684 dwarf_size_type uncompressed_size,
14685 dwarf_size_type * size)
0e602686
NC
14686{
14687 dwarf_size_type compressed_size = *size;
14688 unsigned char * compressed_buffer = *buffer;
14689 unsigned char * uncompressed_buffer;
14690 z_stream strm;
14691 int rc;
14692
14693 /* It is possible the section consists of several compressed
14694 buffers concatenated together, so we uncompress in a loop. */
14695 /* PR 18313: The state field in the z_stream structure is supposed
14696 to be invisible to the user (ie us), but some compilers will
14697 still complain about it being used without initialisation. So
14698 we first zero the entire z_stream structure and then set the fields
14699 that we need. */
14700 memset (& strm, 0, sizeof strm);
14701 strm.avail_in = compressed_size;
14702 strm.next_in = (Bytef *) compressed_buffer;
14703 strm.avail_out = uncompressed_size;
14704 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14705
14706 rc = inflateInit (& strm);
14707 while (strm.avail_in > 0)
14708 {
14709 if (rc != Z_OK)
3624a6c1 14710 break;
0e602686
NC
14711 strm.next_out = ((Bytef *) uncompressed_buffer
14712 + (uncompressed_size - strm.avail_out));
14713 rc = inflate (&strm, Z_FINISH);
14714 if (rc != Z_STREAM_END)
3624a6c1 14715 break;
0e602686
NC
14716 rc = inflateReset (& strm);
14717 }
ad92f33d
AM
14718 if (inflateEnd (& strm) != Z_OK
14719 || rc != Z_OK
0e602686
NC
14720 || strm.avail_out != 0)
14721 goto fail;
14722
14723 *buffer = uncompressed_buffer;
14724 *size = uncompressed_size;
015dc7e1 14725 return true;
0e602686
NC
14726
14727 fail:
14728 free (uncompressed_buffer);
14729 /* Indicate decompression failure. */
14730 *buffer = NULL;
015dc7e1 14731 return false;
0e602686 14732}
dd24e3da 14733
015dc7e1 14734static bool
dda8d76d 14735dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14736{
015dc7e1
AM
14737 Elf_Internal_Shdr *relsec;
14738 bfd_size_type num_bytes;
14739 unsigned char *data;
14740 unsigned char *end;
14741 unsigned char *real_start;
14742 unsigned char *start;
14743 bool some_strings_shown;
cf13d699 14744
dda8d76d 14745 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14746 if (start == NULL)
c6b78c96 14747 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14748 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14749
0e602686 14750 num_bytes = section->sh_size;
cf13d699 14751
835f2fae
NC
14752 if (filedata->is_separate)
14753 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14754 printable_section_name (filedata, section),
14755 filedata->file_name);
14756 else
14757 printf (_("\nString dump of section '%s':\n"),
14758 printable_section_name (filedata, section));
cf13d699 14759
0e602686
NC
14760 if (decompress_dumps)
14761 {
14762 dwarf_size_type new_size = num_bytes;
14763 dwarf_size_type uncompressed_size = 0;
14764
14765 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14766 {
14767 Elf_Internal_Chdr chdr;
14768 unsigned int compression_header_size
ebdf1ebf
NC
14769 = get_compression_header (& chdr, (unsigned char *) start,
14770 num_bytes);
5844b465
NC
14771 if (compression_header_size == 0)
14772 /* An error message will have already been generated
14773 by get_compression_header. */
14774 goto error_out;
0e602686 14775
813dabb9 14776 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14777 {
813dabb9 14778 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14779 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14780 goto error_out;
813dabb9 14781 }
813dabb9
L
14782 uncompressed_size = chdr.ch_size;
14783 start += compression_header_size;
14784 new_size -= compression_header_size;
0e602686
NC
14785 }
14786 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14787 {
14788 /* Read the zlib header. In this case, it should be "ZLIB"
14789 followed by the uncompressed section size, 8 bytes in
14790 big-endian order. */
14791 uncompressed_size = start[4]; uncompressed_size <<= 8;
14792 uncompressed_size += start[5]; uncompressed_size <<= 8;
14793 uncompressed_size += start[6]; uncompressed_size <<= 8;
14794 uncompressed_size += start[7]; uncompressed_size <<= 8;
14795 uncompressed_size += start[8]; uncompressed_size <<= 8;
14796 uncompressed_size += start[9]; uncompressed_size <<= 8;
14797 uncompressed_size += start[10]; uncompressed_size <<= 8;
14798 uncompressed_size += start[11];
14799 start += 12;
14800 new_size -= 12;
14801 }
14802
1835f746
NC
14803 if (uncompressed_size)
14804 {
14805 if (uncompress_section_contents (& start,
14806 uncompressed_size, & new_size))
14807 num_bytes = new_size;
14808 else
14809 {
14810 error (_("Unable to decompress section %s\n"),
dda8d76d 14811 printable_section_name (filedata, section));
f761cb13 14812 goto error_out;
1835f746
NC
14813 }
14814 }
bc303e5d
NC
14815 else
14816 start = real_start;
0e602686 14817 }
fd8008d8 14818
cf13d699
NC
14819 /* If the section being dumped has relocations against it the user might
14820 be expecting these relocations to have been applied. Check for this
14821 case and issue a warning message in order to avoid confusion.
14822 FIXME: Maybe we ought to have an option that dumps a section with
14823 relocs applied ? */
dda8d76d
NC
14824 for (relsec = filedata->section_headers;
14825 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14826 ++relsec)
14827 {
14828 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14829 || relsec->sh_info >= filedata->file_header.e_shnum
14830 || filedata->section_headers + relsec->sh_info != section
cf13d699 14831 || relsec->sh_size == 0
dda8d76d 14832 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14833 continue;
14834
14835 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14836 break;
14837 }
14838
cf13d699
NC
14839 data = start;
14840 end = start + num_bytes;
015dc7e1 14841 some_strings_shown = false;
cf13d699 14842
ba3265d0
NC
14843#ifdef HAVE_MBSTATE_T
14844 mbstate_t state;
14845 /* Initialise the multibyte conversion state. */
14846 memset (& state, 0, sizeof (state));
14847#endif
14848
015dc7e1 14849 bool continuing = false;
ba3265d0 14850
cf13d699
NC
14851 while (data < end)
14852 {
14853 while (!ISPRINT (* data))
14854 if (++ data >= end)
14855 break;
14856
14857 if (data < end)
14858 {
071436c6
NC
14859 size_t maxlen = end - data;
14860
ba3265d0
NC
14861 if (continuing)
14862 {
14863 printf (" ");
015dc7e1 14864 continuing = false;
ba3265d0
NC
14865 }
14866 else
14867 {
d1ce973e 14868 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14869 }
14870
4082ef84
NC
14871 if (maxlen > 0)
14872 {
f3da8a96 14873 char c = 0;
ba3265d0
NC
14874
14875 while (maxlen)
14876 {
14877 c = *data++;
14878
14879 if (c == 0)
14880 break;
14881
14882 /* PR 25543: Treat new-lines as string-ending characters. */
14883 if (c == '\n')
14884 {
14885 printf ("\\n\n");
14886 if (*data != 0)
015dc7e1 14887 continuing = true;
ba3265d0
NC
14888 break;
14889 }
14890
14891 /* Do not print control characters directly as they can affect terminal
14892 settings. Such characters usually appear in the names generated
14893 by the assembler for local labels. */
14894 if (ISCNTRL (c))
14895 {
14896 printf ("^%c", c + 0x40);
14897 }
14898 else if (ISPRINT (c))
14899 {
14900 putchar (c);
14901 }
14902 else
14903 {
14904 size_t n;
14905#ifdef HAVE_MBSTATE_T
14906 wchar_t w;
14907#endif
14908 /* Let printf do the hard work of displaying multibyte characters. */
14909 printf ("%.1s", data - 1);
14910#ifdef HAVE_MBSTATE_T
14911 /* Try to find out how many bytes made up the character that was
14912 just printed. Advance the symbol pointer past the bytes that
14913 were displayed. */
14914 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14915#else
14916 n = 1;
14917#endif
14918 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14919 data += (n - 1);
14920 }
14921 }
14922
14923 if (c != '\n')
14924 putchar ('\n');
4082ef84
NC
14925 }
14926 else
14927 {
14928 printf (_("<corrupt>\n"));
14929 data = end;
14930 }
015dc7e1 14931 some_strings_shown = true;
cf13d699
NC
14932 }
14933 }
14934
14935 if (! some_strings_shown)
14936 printf (_(" No strings found in this section."));
14937
0e602686 14938 free (real_start);
cf13d699
NC
14939
14940 putchar ('\n');
015dc7e1 14941 return true;
f761cb13
AM
14942
14943error_out:
14944 free (real_start);
015dc7e1 14945 return false;
cf13d699
NC
14946}
14947
015dc7e1
AM
14948static bool
14949dump_section_as_bytes (Elf_Internal_Shdr *section,
14950 Filedata *filedata,
14951 bool relocate)
cf13d699
NC
14952{
14953 Elf_Internal_Shdr * relsec;
0e602686
NC
14954 bfd_size_type bytes;
14955 bfd_size_type section_size;
14956 bfd_vma addr;
14957 unsigned char * data;
14958 unsigned char * real_start;
14959 unsigned char * start;
14960
dda8d76d 14961 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14962 if (start == NULL)
c6b78c96 14963 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14964 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14965
0e602686 14966 section_size = section->sh_size;
cf13d699 14967
835f2fae
NC
14968 if (filedata->is_separate)
14969 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14970 printable_section_name (filedata, section),
14971 filedata->file_name);
14972 else
14973 printf (_("\nHex dump of section '%s':\n"),
14974 printable_section_name (filedata, section));
cf13d699 14975
0e602686
NC
14976 if (decompress_dumps)
14977 {
14978 dwarf_size_type new_size = section_size;
14979 dwarf_size_type uncompressed_size = 0;
14980
14981 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14982 {
14983 Elf_Internal_Chdr chdr;
14984 unsigned int compression_header_size
ebdf1ebf 14985 = get_compression_header (& chdr, start, section_size);
0e602686 14986
5844b465
NC
14987 if (compression_header_size == 0)
14988 /* An error message will have already been generated
14989 by get_compression_header. */
14990 goto error_out;
14991
813dabb9 14992 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14993 {
813dabb9 14994 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14995 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14996 goto error_out;
0e602686 14997 }
813dabb9
L
14998 uncompressed_size = chdr.ch_size;
14999 start += compression_header_size;
15000 new_size -= compression_header_size;
0e602686
NC
15001 }
15002 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15003 {
15004 /* Read the zlib header. In this case, it should be "ZLIB"
15005 followed by the uncompressed section size, 8 bytes in
15006 big-endian order. */
15007 uncompressed_size = start[4]; uncompressed_size <<= 8;
15008 uncompressed_size += start[5]; uncompressed_size <<= 8;
15009 uncompressed_size += start[6]; uncompressed_size <<= 8;
15010 uncompressed_size += start[7]; uncompressed_size <<= 8;
15011 uncompressed_size += start[8]; uncompressed_size <<= 8;
15012 uncompressed_size += start[9]; uncompressed_size <<= 8;
15013 uncompressed_size += start[10]; uncompressed_size <<= 8;
15014 uncompressed_size += start[11];
15015 start += 12;
15016 new_size -= 12;
15017 }
15018
f055032e
NC
15019 if (uncompressed_size)
15020 {
15021 if (uncompress_section_contents (& start, uncompressed_size,
15022 & new_size))
bc303e5d
NC
15023 {
15024 section_size = new_size;
15025 }
f055032e
NC
15026 else
15027 {
15028 error (_("Unable to decompress section %s\n"),
dda8d76d 15029 printable_section_name (filedata, section));
bc303e5d 15030 /* FIXME: Print the section anyway ? */
f761cb13 15031 goto error_out;
f055032e
NC
15032 }
15033 }
bc303e5d
NC
15034 else
15035 start = real_start;
0e602686 15036 }
14ae95f2 15037
cf13d699
NC
15038 if (relocate)
15039 {
dda8d76d 15040 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15041 goto error_out;
cf13d699
NC
15042 }
15043 else
15044 {
15045 /* If the section being dumped has relocations against it the user might
15046 be expecting these relocations to have been applied. Check for this
15047 case and issue a warning message in order to avoid confusion.
15048 FIXME: Maybe we ought to have an option that dumps a section with
15049 relocs applied ? */
dda8d76d
NC
15050 for (relsec = filedata->section_headers;
15051 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15052 ++relsec)
15053 {
15054 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15055 || relsec->sh_info >= filedata->file_header.e_shnum
15056 || filedata->section_headers + relsec->sh_info != section
cf13d699 15057 || relsec->sh_size == 0
dda8d76d 15058 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15059 continue;
15060
15061 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15062 break;
15063 }
15064 }
15065
15066 addr = section->sh_addr;
0e602686 15067 bytes = section_size;
cf13d699
NC
15068 data = start;
15069
15070 while (bytes)
15071 {
15072 int j;
15073 int k;
15074 int lbytes;
15075
15076 lbytes = (bytes > 16 ? 16 : bytes);
15077
15078 printf (" 0x%8.8lx ", (unsigned long) addr);
15079
15080 for (j = 0; j < 16; j++)
15081 {
15082 if (j < lbytes)
15083 printf ("%2.2x", data[j]);
15084 else
15085 printf (" ");
15086
15087 if ((j & 3) == 3)
15088 printf (" ");
15089 }
15090
15091 for (j = 0; j < lbytes; j++)
15092 {
15093 k = data[j];
15094 if (k >= ' ' && k < 0x7f)
15095 printf ("%c", k);
15096 else
15097 printf (".");
15098 }
15099
15100 putchar ('\n');
15101
15102 data += lbytes;
15103 addr += lbytes;
15104 bytes -= lbytes;
15105 }
15106
0e602686 15107 free (real_start);
cf13d699
NC
15108
15109 putchar ('\n');
015dc7e1 15110 return true;
f761cb13
AM
15111
15112 error_out:
15113 free (real_start);
015dc7e1 15114 return false;
cf13d699
NC
15115}
15116
094e34f2 15117#ifdef ENABLE_LIBCTF
7d9813f1
NA
15118static ctf_sect_t *
15119shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15120{
84714f86 15121 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15122 buf->cts_size = shdr->sh_size;
15123 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15124
15125 return buf;
15126}
15127
15128/* Formatting callback function passed to ctf_dump. Returns either the pointer
15129 it is passed, or a pointer to newly-allocated storage, in which case
15130 dump_ctf() will free it when it no longer needs it. */
15131
2f6ecaed
NA
15132static char *
15133dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15134 char *s, void *arg)
7d9813f1 15135{
3e50a591 15136 const char *blanks = arg;
7d9813f1
NA
15137 char *new_s;
15138
3e50a591 15139 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15140 return s;
15141 return new_s;
15142}
15143
926c9e76
NA
15144/* Dump CTF errors/warnings. */
15145static void
139633c3 15146dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15147{
15148 ctf_next_t *it = NULL;
15149 char *errtext;
15150 int is_warning;
15151 int err;
15152
15153 /* Dump accumulated errors and warnings. */
15154 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15155 {
5e9b84f7 15156 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15157 errtext);
15158 free (errtext);
15159 }
15160 if (err != ECTF_NEXT_END)
15161 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15162}
15163
2f6ecaed
NA
15164/* Dump one CTF archive member. */
15165
80b56fad
NA
15166static void
15167dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15168 size_t member)
2f6ecaed 15169{
2f6ecaed
NA
15170 const char *things[] = {"Header", "Labels", "Data objects",
15171 "Function objects", "Variables", "Types", "Strings",
15172 ""};
15173 const char **thing;
15174 size_t i;
15175
80b56fad
NA
15176 /* Don't print out the name of the default-named archive member if it appears
15177 first in the list. The name .ctf appears everywhere, even for things that
15178 aren't really archives, so printing it out is liable to be confusing; also,
15179 the common case by far is for only one archive member to exist, and hiding
15180 it in that case seems worthwhile. */
2f6ecaed 15181
80b56fad
NA
15182 if (strcmp (name, ".ctf") != 0 || member != 0)
15183 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15184
80b56fad
NA
15185 if (ctf_parent_name (ctf) != NULL)
15186 ctf_import (ctf, parent);
2f6ecaed
NA
15187
15188 for (i = 0, thing = things; *thing[0]; thing++, i++)
15189 {
15190 ctf_dump_state_t *s = NULL;
15191 char *item;
15192
15193 printf ("\n %s:\n", *thing);
15194 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15195 (void *) " ")) != NULL)
15196 {
15197 printf ("%s\n", item);
15198 free (item);
15199 }
15200
15201 if (ctf_errno (ctf))
15202 {
15203 error (_("Iteration failed: %s, %s\n"), *thing,
15204 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15205 break;
2f6ecaed
NA
15206 }
15207 }
8b37e7b6 15208
926c9e76 15209 dump_ctf_errs (ctf);
2f6ecaed
NA
15210}
15211
015dc7e1 15212static bool
7d9813f1
NA
15213dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15214{
7d9813f1
NA
15215 Elf_Internal_Shdr * symtab_sec = NULL;
15216 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15217 void * data = NULL;
15218 void * symdata = NULL;
15219 void * strdata = NULL;
80b56fad 15220 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15221 ctf_sect_t * symsectp = NULL;
15222 ctf_sect_t * strsectp = NULL;
2f6ecaed 15223 ctf_archive_t * ctfa = NULL;
139633c3 15224 ctf_dict_t * parent = NULL;
80b56fad 15225 ctf_dict_t * fp;
7d9813f1 15226
80b56fad
NA
15227 ctf_next_t *i = NULL;
15228 const char *name;
15229 size_t member = 0;
7d9813f1 15230 int err;
015dc7e1 15231 bool ret = false;
7d9813f1
NA
15232
15233 shdr_to_ctf_sect (&ctfsect, section, filedata);
15234 data = get_section_contents (section, filedata);
15235 ctfsect.cts_data = data;
15236
616febde 15237 if (!dump_ctf_symtab_name)
3d16b64e 15238 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15239
15240 if (!dump_ctf_strtab_name)
3d16b64e 15241 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15242
15243 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15244 {
15245 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15246 {
15247 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15248 goto fail;
15249 }
15250 if ((symdata = (void *) get_data (NULL, filedata,
15251 symtab_sec->sh_offset, 1,
15252 symtab_sec->sh_size,
15253 _("symbols"))) == NULL)
15254 goto fail;
15255 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15256 symsect.cts_data = symdata;
15257 }
835f2fae 15258
df16e041 15259 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15260 {
15261 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15262 {
15263 error (_("No string table section named %s\n"),
15264 dump_ctf_strtab_name);
15265 goto fail;
15266 }
15267 if ((strdata = (void *) get_data (NULL, filedata,
15268 strtab_sec->sh_offset, 1,
15269 strtab_sec->sh_size,
15270 _("strings"))) == NULL)
15271 goto fail;
15272 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15273 strsect.cts_data = strdata;
15274 }
835f2fae 15275
2f6ecaed
NA
15276 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15277 libctf papers over the difference, so we can pretend it is always an
80b56fad 15278 archive. */
7d9813f1 15279
2f6ecaed 15280 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15281 {
926c9e76 15282 dump_ctf_errs (NULL);
7d9813f1
NA
15283 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15284 goto fail;
15285 }
15286
96c61be5
NA
15287 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15288 != ELFDATA2MSB);
15289
80b56fad
NA
15290 /* Preload the parent dict, since it will need to be imported into every
15291 child in turn. */
15292 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15293 {
926c9e76 15294 dump_ctf_errs (NULL);
2f6ecaed
NA
15295 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15296 goto fail;
7d9813f1
NA
15297 }
15298
015dc7e1 15299 ret = true;
7d9813f1 15300
835f2fae
NC
15301 if (filedata->is_separate)
15302 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15303 printable_section_name (filedata, section),
15304 filedata->file_name);
15305 else
15306 printf (_("\nDump of CTF section '%s':\n"),
15307 printable_section_name (filedata, section));
7d9813f1 15308
80b56fad
NA
15309 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15310 dump_ctf_archive_member (fp, name, parent, member++);
15311 if (err != ECTF_NEXT_END)
15312 {
15313 dump_ctf_errs (NULL);
15314 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15315 ret = false;
15316 }
7d9813f1
NA
15317
15318 fail:
139633c3 15319 ctf_dict_close (parent);
2f6ecaed 15320 ctf_close (ctfa);
7d9813f1
NA
15321 free (data);
15322 free (symdata);
15323 free (strdata);
15324 return ret;
15325}
094e34f2 15326#endif
7d9813f1 15327
015dc7e1 15328static bool
dda8d76d
NC
15329load_specific_debug_section (enum dwarf_section_display_enum debug,
15330 const Elf_Internal_Shdr * sec,
15331 void * data)
1007acb3 15332{
2cf0635d 15333 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15334 char buf [64];
dda8d76d 15335 Filedata * filedata = (Filedata *) data;
9abca702 15336
19e6b90e 15337 if (section->start != NULL)
dda8d76d
NC
15338 {
15339 /* If it is already loaded, do nothing. */
15340 if (streq (section->filename, filedata->file_name))
015dc7e1 15341 return true;
dda8d76d
NC
15342 free (section->start);
15343 }
1007acb3 15344
19e6b90e
L
15345 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15346 section->address = sec->sh_addr;
dda8d76d
NC
15347 section->filename = filedata->file_name;
15348 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15349 sec->sh_offset, 1,
15350 sec->sh_size, buf);
59245841
NC
15351 if (section->start == NULL)
15352 section->size = 0;
15353 else
15354 {
77115a4a
L
15355 unsigned char *start = section->start;
15356 dwarf_size_type size = sec->sh_size;
dab394de 15357 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15358
15359 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15360 {
15361 Elf_Internal_Chdr chdr;
d8024a91
NC
15362 unsigned int compression_header_size;
15363
f53be977
L
15364 if (size < (is_32bit_elf
15365 ? sizeof (Elf32_External_Chdr)
15366 : sizeof (Elf64_External_Chdr)))
d8024a91 15367 {
55be8fd0 15368 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15369 section->name);
015dc7e1 15370 return false;
d8024a91
NC
15371 }
15372
ebdf1ebf 15373 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15374 if (compression_header_size == 0)
15375 /* An error message will have already been generated
15376 by get_compression_header. */
015dc7e1 15377 return false;
d8024a91 15378
813dabb9
L
15379 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15380 {
15381 warn (_("section '%s' has unsupported compress type: %d\n"),
15382 section->name, chdr.ch_type);
015dc7e1 15383 return false;
813dabb9 15384 }
dab394de 15385 uncompressed_size = chdr.ch_size;
77115a4a
L
15386 start += compression_header_size;
15387 size -= compression_header_size;
15388 }
dab394de
L
15389 else if (size > 12 && streq ((char *) start, "ZLIB"))
15390 {
15391 /* Read the zlib header. In this case, it should be "ZLIB"
15392 followed by the uncompressed section size, 8 bytes in
15393 big-endian order. */
15394 uncompressed_size = start[4]; uncompressed_size <<= 8;
15395 uncompressed_size += start[5]; uncompressed_size <<= 8;
15396 uncompressed_size += start[6]; uncompressed_size <<= 8;
15397 uncompressed_size += start[7]; uncompressed_size <<= 8;
15398 uncompressed_size += start[8]; uncompressed_size <<= 8;
15399 uncompressed_size += start[9]; uncompressed_size <<= 8;
15400 uncompressed_size += start[10]; uncompressed_size <<= 8;
15401 uncompressed_size += start[11];
15402 start += 12;
15403 size -= 12;
15404 }
15405
1835f746 15406 if (uncompressed_size)
77115a4a 15407 {
1835f746
NC
15408 if (uncompress_section_contents (&start, uncompressed_size,
15409 &size))
15410 {
15411 /* Free the compressed buffer, update the section buffer
15412 and the section size if uncompress is successful. */
15413 free (section->start);
15414 section->start = start;
15415 }
15416 else
15417 {
15418 error (_("Unable to decompress section %s\n"),
dda8d76d 15419 printable_section_name (filedata, sec));
015dc7e1 15420 return false;
1835f746 15421 }
77115a4a 15422 }
bc303e5d 15423
77115a4a 15424 section->size = size;
59245841 15425 }
4a114e3e 15426
1b315056 15427 if (section->start == NULL)
015dc7e1 15428 return false;
1b315056 15429
19e6b90e 15430 if (debug_displays [debug].relocate)
32ec8896 15431 {
dda8d76d 15432 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15433 & section->reloc_info, & section->num_relocs))
015dc7e1 15434 return false;
32ec8896 15435 }
d1c4b12b
NC
15436 else
15437 {
15438 section->reloc_info = NULL;
15439 section->num_relocs = 0;
15440 }
1007acb3 15441
015dc7e1 15442 return true;
1007acb3
L
15443}
15444
301a9420
AM
15445#if HAVE_LIBDEBUGINFOD
15446/* Return a hex string representation of the build-id. */
15447unsigned char *
15448get_build_id (void * data)
15449{
ca0e11aa 15450 Filedata * filedata = (Filedata *) data;
301a9420
AM
15451 Elf_Internal_Shdr * shdr;
15452 unsigned long i;
15453
55be8fd0
NC
15454 /* Iterate through notes to find note.gnu.build-id.
15455 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15456 for (i = 0, shdr = filedata->section_headers;
15457 i < filedata->file_header.e_shnum && shdr != NULL;
15458 i++, shdr++)
15459 {
15460 if (shdr->sh_type != SHT_NOTE)
15461 continue;
15462
15463 char * next;
15464 char * end;
15465 size_t data_remaining;
15466 size_t min_notesz;
15467 Elf_External_Note * enote;
15468 Elf_Internal_Note inote;
15469
15470 bfd_vma offset = shdr->sh_offset;
15471 bfd_vma align = shdr->sh_addralign;
15472 bfd_vma length = shdr->sh_size;
15473
15474 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15475 if (enote == NULL)
15476 continue;
15477
15478 if (align < 4)
15479 align = 4;
15480 else if (align != 4 && align != 8)
f761cb13
AM
15481 {
15482 free (enote);
15483 continue;
15484 }
301a9420
AM
15485
15486 end = (char *) enote + length;
15487 data_remaining = end - (char *) enote;
15488
15489 if (!is_ia64_vms (filedata))
15490 {
15491 min_notesz = offsetof (Elf_External_Note, name);
15492 if (data_remaining < min_notesz)
15493 {
55be8fd0
NC
15494 warn (_("\
15495malformed note encountered in section %s whilst scanning for build-id note\n"),
15496 printable_section_name (filedata, shdr));
f761cb13 15497 free (enote);
55be8fd0 15498 continue;
301a9420
AM
15499 }
15500 data_remaining -= min_notesz;
15501
15502 inote.type = BYTE_GET (enote->type);
15503 inote.namesz = BYTE_GET (enote->namesz);
15504 inote.namedata = enote->name;
15505 inote.descsz = BYTE_GET (enote->descsz);
15506 inote.descdata = ((char *) enote
15507 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15508 inote.descpos = offset + (inote.descdata - (char *) enote);
15509 next = ((char *) enote
15510 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15511 }
15512 else
15513 {
15514 Elf64_External_VMS_Note *vms_enote;
15515
15516 /* PR binutils/15191
15517 Make sure that there is enough data to read. */
15518 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15519 if (data_remaining < min_notesz)
15520 {
55be8fd0
NC
15521 warn (_("\
15522malformed note encountered in section %s whilst scanning for build-id note\n"),
15523 printable_section_name (filedata, shdr));
f761cb13 15524 free (enote);
55be8fd0 15525 continue;
301a9420
AM
15526 }
15527 data_remaining -= min_notesz;
15528
15529 vms_enote = (Elf64_External_VMS_Note *) enote;
15530 inote.type = BYTE_GET (vms_enote->type);
15531 inote.namesz = BYTE_GET (vms_enote->namesz);
15532 inote.namedata = vms_enote->name;
15533 inote.descsz = BYTE_GET (vms_enote->descsz);
15534 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15535 inote.descpos = offset + (inote.descdata - (char *) enote);
15536 next = inote.descdata + align_power (inote.descsz, 3);
15537 }
15538
15539 /* Skip malformed notes. */
15540 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15541 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15542 || (size_t) (next - inote.descdata) < inote.descsz
15543 || ((size_t) (next - inote.descdata)
15544 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15545 {
55be8fd0
NC
15546 warn (_("\
15547malformed note encountered in section %s whilst scanning for build-id note\n"),
15548 printable_section_name (filedata, shdr));
f761cb13 15549 free (enote);
301a9420
AM
15550 continue;
15551 }
15552
15553 /* Check if this is the build-id note. If so then convert the build-id
15554 bytes to a hex string. */
15555 if (inote.namesz > 0
24d127aa 15556 && startswith (inote.namedata, "GNU")
301a9420
AM
15557 && inote.type == NT_GNU_BUILD_ID)
15558 {
15559 unsigned long j;
15560 char * build_id;
15561
15562 build_id = malloc (inote.descsz * 2 + 1);
15563 if (build_id == NULL)
f761cb13
AM
15564 {
15565 free (enote);
15566 return NULL;
15567 }
301a9420
AM
15568
15569 for (j = 0; j < inote.descsz; ++j)
15570 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15571 build_id[inote.descsz * 2] = '\0';
f761cb13 15572 free (enote);
301a9420 15573
55be8fd0 15574 return (unsigned char *) build_id;
301a9420 15575 }
f761cb13 15576 free (enote);
301a9420
AM
15577 }
15578
15579 return NULL;
15580}
15581#endif /* HAVE_LIBDEBUGINFOD */
15582
657d0d47
CC
15583/* If this is not NULL, load_debug_section will only look for sections
15584 within the list of sections given here. */
32ec8896 15585static unsigned int * section_subset = NULL;
657d0d47 15586
015dc7e1 15587bool
dda8d76d 15588load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15589{
2cf0635d
NC
15590 struct dwarf_section * section = &debug_displays [debug].section;
15591 Elf_Internal_Shdr * sec;
dda8d76d
NC
15592 Filedata * filedata = (Filedata *) data;
15593
f425ec66
NC
15594 /* Without section headers we cannot find any sections. */
15595 if (filedata->section_headers == NULL)
015dc7e1 15596 return false;
f425ec66 15597
9c1ce108
AM
15598 if (filedata->string_table == NULL
15599 && filedata->file_header.e_shstrndx != SHN_UNDEF
15600 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15601 {
15602 Elf_Internal_Shdr * strs;
15603
15604 /* Read in the string table, so that we have section names to scan. */
15605 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15606
4dff97b2 15607 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15608 {
9c1ce108
AM
15609 filedata->string_table
15610 = (char *) get_data (NULL, filedata, strs->sh_offset,
15611 1, strs->sh_size, _("string table"));
dda8d76d 15612
9c1ce108
AM
15613 filedata->string_table_length
15614 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15615 }
15616 }
d966045b
DJ
15617
15618 /* Locate the debug section. */
dda8d76d 15619 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15620 if (sec != NULL)
15621 section->name = section->uncompressed_name;
15622 else
15623 {
dda8d76d 15624 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15625 if (sec != NULL)
15626 section->name = section->compressed_name;
15627 }
15628 if (sec == NULL)
015dc7e1 15629 return false;
d966045b 15630
657d0d47
CC
15631 /* If we're loading from a subset of sections, and we've loaded
15632 a section matching this name before, it's likely that it's a
15633 different one. */
15634 if (section_subset != NULL)
15635 free_debug_section (debug);
15636
dda8d76d 15637 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15638}
15639
19e6b90e
L
15640void
15641free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15642{
2cf0635d 15643 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15644
19e6b90e
L
15645 if (section->start == NULL)
15646 return;
1007acb3 15647
19e6b90e
L
15648 free ((char *) section->start);
15649 section->start = NULL;
15650 section->address = 0;
15651 section->size = 0;
a788aedd 15652
9db70fc3
AM
15653 free (section->reloc_info);
15654 section->reloc_info = NULL;
15655 section->num_relocs = 0;
1007acb3
L
15656}
15657
015dc7e1 15658static bool
dda8d76d 15659display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15660{
84714f86
AM
15661 const char *name = (section_name_valid (filedata, section)
15662 ? section_name (filedata, section) : "");
15663 const char *print_name = printable_section_name (filedata, section);
19e6b90e 15664 bfd_size_type length;
015dc7e1 15665 bool result = true;
3f5e193b 15666 int i;
1007acb3 15667
19e6b90e
L
15668 length = section->sh_size;
15669 if (length == 0)
1007acb3 15670 {
74e1a04b 15671 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15672 return true;
1007acb3 15673 }
5dff79d8
NC
15674 if (section->sh_type == SHT_NOBITS)
15675 {
15676 /* There is no point in dumping the contents of a debugging section
15677 which has the NOBITS type - the bits in the file will be random.
15678 This can happen when a file containing a .eh_frame section is
15679 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15680 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15681 print_name);
015dc7e1 15682 return false;
5dff79d8 15683 }
1007acb3 15684
24d127aa 15685 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15686 name = ".debug_info";
1007acb3 15687
19e6b90e
L
15688 /* See if we know how to display the contents of this section. */
15689 for (i = 0; i < max; i++)
d85bf2ba
NC
15690 {
15691 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15692 struct dwarf_section_display * display = debug_displays + i;
15693 struct dwarf_section * sec = & display->section;
d966045b 15694
d85bf2ba 15695 if (streq (sec->uncompressed_name, name)
24d127aa 15696 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15697 || streq (sec->compressed_name, name))
15698 {
015dc7e1 15699 bool secondary = (section != find_section (filedata, name));
1007acb3 15700
d85bf2ba
NC
15701 if (secondary)
15702 free_debug_section (id);
dda8d76d 15703
24d127aa 15704 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15705 sec->name = name;
15706 else if (streq (sec->uncompressed_name, name))
15707 sec->name = sec->uncompressed_name;
15708 else
15709 sec->name = sec->compressed_name;
657d0d47 15710
d85bf2ba
NC
15711 if (load_specific_debug_section (id, section, filedata))
15712 {
15713 /* If this debug section is part of a CU/TU set in a .dwp file,
15714 restrict load_debug_section to the sections in that set. */
15715 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15716
d85bf2ba 15717 result &= display->display (sec, filedata);
657d0d47 15718
d85bf2ba 15719 section_subset = NULL;
1007acb3 15720
44266f36 15721 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15722 free_debug_section (id);
15723 }
15724 break;
15725 }
15726 }
1007acb3 15727
19e6b90e 15728 if (i == max)
1007acb3 15729 {
74e1a04b 15730 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15731 result = false;
1007acb3
L
15732 }
15733
19e6b90e 15734 return result;
5b18a4bc 15735}
103f02d3 15736
aef1f6d0
DJ
15737/* Set DUMP_SECTS for all sections where dumps were requested
15738 based on section name. */
15739
15740static void
dda8d76d 15741initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15742{
2cf0635d 15743 struct dump_list_entry * cur;
aef1f6d0
DJ
15744
15745 for (cur = dump_sects_byname; cur; cur = cur->next)
15746 {
15747 unsigned int i;
015dc7e1 15748 bool any = false;
aef1f6d0 15749
dda8d76d 15750 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
15751 if (section_name_valid (filedata, filedata->section_headers + i)
15752 && streq (section_name (filedata, filedata->section_headers + i),
15753 cur->name))
aef1f6d0 15754 {
6431e409 15755 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15756 any = true;
aef1f6d0
DJ
15757 }
15758
835f2fae
NC
15759 if (!any && !filedata->is_separate)
15760 warn (_("Section '%s' was not dumped because it does not exist\n"),
15761 cur->name);
aef1f6d0
DJ
15762 }
15763}
15764
015dc7e1 15765static bool
dda8d76d 15766process_section_contents (Filedata * filedata)
5b18a4bc 15767{
2cf0635d 15768 Elf_Internal_Shdr * section;
19e6b90e 15769 unsigned int i;
015dc7e1 15770 bool res = true;
103f02d3 15771
19e6b90e 15772 if (! do_dump)
015dc7e1 15773 return true;
103f02d3 15774
dda8d76d 15775 initialise_dumps_byname (filedata);
aef1f6d0 15776
dda8d76d 15777 for (i = 0, section = filedata->section_headers;
6431e409 15778 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15779 i++, section++)
15780 {
6431e409 15781 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15782
d6bfbc39
NC
15783 if (filedata->is_separate && ! process_links)
15784 dump &= DEBUG_DUMP;
047c3dbf 15785
19e6b90e 15786#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15787 if (dump & DISASS_DUMP)
15788 {
15789 if (! disassemble_section (section, filedata))
015dc7e1 15790 res = false;
dda8d76d 15791 }
19e6b90e 15792#endif
dda8d76d 15793 if (dump & HEX_DUMP)
32ec8896 15794 {
015dc7e1
AM
15795 if (! dump_section_as_bytes (section, filedata, false))
15796 res = false;
32ec8896 15797 }
103f02d3 15798
dda8d76d 15799 if (dump & RELOC_DUMP)
32ec8896 15800 {
015dc7e1
AM
15801 if (! dump_section_as_bytes (section, filedata, true))
15802 res = false;
32ec8896 15803 }
09c11c86 15804
dda8d76d 15805 if (dump & STRING_DUMP)
32ec8896 15806 {
dda8d76d 15807 if (! dump_section_as_strings (section, filedata))
015dc7e1 15808 res = false;
32ec8896 15809 }
cf13d699 15810
dda8d76d 15811 if (dump & DEBUG_DUMP)
32ec8896 15812 {
dda8d76d 15813 if (! display_debug_section (i, section, filedata))
015dc7e1 15814 res = false;
32ec8896 15815 }
7d9813f1 15816
094e34f2 15817#ifdef ENABLE_LIBCTF
7d9813f1
NA
15818 if (dump & CTF_DUMP)
15819 {
15820 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15821 res = false;
7d9813f1 15822 }
094e34f2 15823#endif
5b18a4bc 15824 }
103f02d3 15825
835f2fae 15826 if (! filedata->is_separate)
0ee3043f 15827 {
835f2fae
NC
15828 /* Check to see if the user requested a
15829 dump of a section that does not exist. */
15830 for (; i < filedata->dump.num_dump_sects; i++)
15831 if (filedata->dump.dump_sects[i])
15832 {
ca0e11aa 15833 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15834 res = false;
835f2fae 15835 }
0ee3043f 15836 }
32ec8896
NC
15837
15838 return res;
5b18a4bc 15839}
103f02d3 15840
5b18a4bc 15841static void
19e6b90e 15842process_mips_fpe_exception (int mask)
5b18a4bc 15843{
19e6b90e
L
15844 if (mask)
15845 {
015dc7e1 15846 bool first = true;
32ec8896 15847
19e6b90e 15848 if (mask & OEX_FPU_INEX)
015dc7e1 15849 fputs ("INEX", stdout), first = false;
19e6b90e 15850 if (mask & OEX_FPU_UFLO)
015dc7e1 15851 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15852 if (mask & OEX_FPU_OFLO)
015dc7e1 15853 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15854 if (mask & OEX_FPU_DIV0)
015dc7e1 15855 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15856 if (mask & OEX_FPU_INVAL)
15857 printf ("%sINVAL", first ? "" : "|");
15858 }
5b18a4bc 15859 else
19e6b90e 15860 fputs ("0", stdout);
5b18a4bc 15861}
103f02d3 15862
f6f0e17b
NC
15863/* Display's the value of TAG at location P. If TAG is
15864 greater than 0 it is assumed to be an unknown tag, and
15865 a message is printed to this effect. Otherwise it is
15866 assumed that a message has already been printed.
15867
15868 If the bottom bit of TAG is set it assumed to have a
15869 string value, otherwise it is assumed to have an integer
15870 value.
15871
15872 Returns an updated P pointing to the first unread byte
15873 beyond the end of TAG's value.
15874
15875 Reads at or beyond END will not be made. */
15876
15877static unsigned char *
60abdbed 15878display_tag_value (signed int tag,
f6f0e17b
NC
15879 unsigned char * p,
15880 const unsigned char * const end)
15881{
15882 unsigned long val;
15883
15884 if (tag > 0)
15885 printf (" Tag_unknown_%d: ", tag);
15886
15887 if (p >= end)
15888 {
4082ef84 15889 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15890 }
15891 else if (tag & 1)
15892 {
071436c6
NC
15893 /* PR 17531 file: 027-19978-0.004. */
15894 size_t maxlen = (end - p) - 1;
15895
15896 putchar ('"');
4082ef84
NC
15897 if (maxlen > 0)
15898 {
15899 print_symbol ((int) maxlen, (const char *) p);
15900 p += strnlen ((char *) p, maxlen) + 1;
15901 }
15902 else
15903 {
15904 printf (_("<corrupt string tag>"));
15905 p = (unsigned char *) end;
15906 }
071436c6 15907 printf ("\"\n");
f6f0e17b
NC
15908 }
15909 else
15910 {
cd30bcef 15911 READ_ULEB (val, p, end);
f6f0e17b
NC
15912 printf ("%ld (0x%lx)\n", val, val);
15913 }
15914
4082ef84 15915 assert (p <= end);
f6f0e17b
NC
15916 return p;
15917}
15918
53a346d8
CZ
15919/* ARC ABI attributes section. */
15920
15921static unsigned char *
15922display_arc_attribute (unsigned char * p,
15923 const unsigned char * const end)
15924{
15925 unsigned int tag;
53a346d8
CZ
15926 unsigned int val;
15927
cd30bcef 15928 READ_ULEB (tag, p, end);
53a346d8
CZ
15929
15930 switch (tag)
15931 {
15932 case Tag_ARC_PCS_config:
cd30bcef 15933 READ_ULEB (val, p, end);
53a346d8
CZ
15934 printf (" Tag_ARC_PCS_config: ");
15935 switch (val)
15936 {
15937 case 0:
15938 printf (_("Absent/Non standard\n"));
15939 break;
15940 case 1:
15941 printf (_("Bare metal/mwdt\n"));
15942 break;
15943 case 2:
15944 printf (_("Bare metal/newlib\n"));
15945 break;
15946 case 3:
15947 printf (_("Linux/uclibc\n"));
15948 break;
15949 case 4:
15950 printf (_("Linux/glibc\n"));
15951 break;
15952 default:
15953 printf (_("Unknown\n"));
15954 break;
15955 }
15956 break;
15957
15958 case Tag_ARC_CPU_base:
cd30bcef 15959 READ_ULEB (val, p, end);
53a346d8
CZ
15960 printf (" Tag_ARC_CPU_base: ");
15961 switch (val)
15962 {
15963 default:
15964 case TAG_CPU_NONE:
15965 printf (_("Absent\n"));
15966 break;
15967 case TAG_CPU_ARC6xx:
15968 printf ("ARC6xx\n");
15969 break;
15970 case TAG_CPU_ARC7xx:
15971 printf ("ARC7xx\n");
15972 break;
15973 case TAG_CPU_ARCEM:
15974 printf ("ARCEM\n");
15975 break;
15976 case TAG_CPU_ARCHS:
15977 printf ("ARCHS\n");
15978 break;
15979 }
15980 break;
15981
15982 case Tag_ARC_CPU_variation:
cd30bcef 15983 READ_ULEB (val, p, end);
53a346d8
CZ
15984 printf (" Tag_ARC_CPU_variation: ");
15985 switch (val)
15986 {
15987 default:
15988 if (val > 0 && val < 16)
53a346d8 15989 printf ("Core%d\n", val);
d8cbc93b
JL
15990 else
15991 printf ("Unknown\n");
15992 break;
15993
53a346d8
CZ
15994 case 0:
15995 printf (_("Absent\n"));
15996 break;
15997 }
15998 break;
15999
16000 case Tag_ARC_CPU_name:
16001 printf (" Tag_ARC_CPU_name: ");
16002 p = display_tag_value (-1, p, end);
16003 break;
16004
16005 case Tag_ARC_ABI_rf16:
cd30bcef 16006 READ_ULEB (val, p, end);
53a346d8
CZ
16007 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16008 break;
16009
16010 case Tag_ARC_ABI_osver:
cd30bcef 16011 READ_ULEB (val, p, end);
53a346d8
CZ
16012 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16013 break;
16014
16015 case Tag_ARC_ABI_pic:
16016 case Tag_ARC_ABI_sda:
cd30bcef 16017 READ_ULEB (val, p, end);
53a346d8
CZ
16018 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16019 : " Tag_ARC_ABI_pic: ");
16020 switch (val)
16021 {
16022 case 0:
16023 printf (_("Absent\n"));
16024 break;
16025 case 1:
16026 printf ("MWDT\n");
16027 break;
16028 case 2:
16029 printf ("GNU\n");
16030 break;
16031 default:
16032 printf (_("Unknown\n"));
16033 break;
16034 }
16035 break;
16036
16037 case Tag_ARC_ABI_tls:
cd30bcef 16038 READ_ULEB (val, p, end);
53a346d8
CZ
16039 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16040 break;
16041
16042 case Tag_ARC_ABI_enumsize:
cd30bcef 16043 READ_ULEB (val, p, end);
53a346d8
CZ
16044 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16045 _("smallest"));
16046 break;
16047
16048 case Tag_ARC_ABI_exceptions:
cd30bcef 16049 READ_ULEB (val, p, end);
53a346d8
CZ
16050 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16051 : _("default"));
16052 break;
16053
16054 case Tag_ARC_ABI_double_size:
cd30bcef 16055 READ_ULEB (val, p, end);
53a346d8
CZ
16056 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16057 break;
16058
16059 case Tag_ARC_ISA_config:
16060 printf (" Tag_ARC_ISA_config: ");
16061 p = display_tag_value (-1, p, end);
16062 break;
16063
16064 case Tag_ARC_ISA_apex:
16065 printf (" Tag_ARC_ISA_apex: ");
16066 p = display_tag_value (-1, p, end);
16067 break;
16068
16069 case Tag_ARC_ISA_mpy_option:
cd30bcef 16070 READ_ULEB (val, p, end);
53a346d8
CZ
16071 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16072 break;
16073
db1e1b45 16074 case Tag_ARC_ATR_version:
cd30bcef 16075 READ_ULEB (val, p, end);
db1e1b45 16076 printf (" Tag_ARC_ATR_version: %d\n", val);
16077 break;
16078
53a346d8
CZ
16079 default:
16080 return display_tag_value (tag & 1, p, end);
16081 }
16082
16083 return p;
16084}
16085
11c1ff18
PB
16086/* ARM EABI attributes section. */
16087typedef struct
16088{
70e99720 16089 unsigned int tag;
2cf0635d 16090 const char * name;
11c1ff18 16091 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16092 unsigned int type;
288f0ba2 16093 const char *const *table;
11c1ff18
PB
16094} arm_attr_public_tag;
16095
288f0ba2 16096static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16097 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16098 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 16099 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
16100static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16101static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16102 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16103static const char *const arm_attr_tag_FP_arch[] =
bca38921 16104 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16105 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16106static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16107static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16108 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16109 "NEON for ARMv8.1"};
288f0ba2 16110static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16111 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16112 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16113static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16114 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16115static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16116 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16117static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16118 {"Absolute", "PC-relative", "None"};
288f0ba2 16119static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16120 {"None", "direct", "GOT-indirect"};
288f0ba2 16121static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16122 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16123static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16124static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16125 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16126static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16127static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16128static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16129 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16130static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16131 {"Unused", "small", "int", "forced to int"};
288f0ba2 16132static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16133 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16134static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16135 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16136static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16137 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16138static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16139 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16140 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16141static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16142 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16143 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16144static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16145static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16146 {"Not Allowed", "Allowed"};
288f0ba2 16147static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16148 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16149static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16150 {"Follow architecture", "Allowed"};
288f0ba2 16151static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16152 {"Not Allowed", "Allowed"};
288f0ba2 16153static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16154 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16155 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16156static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16157static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16158 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16159 "TrustZone and Virtualization Extensions"};
288f0ba2 16160static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16161 {"Not Allowed", "Allowed"};
11c1ff18 16162
288f0ba2 16163static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16164 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16165
99db83d0
AC
16166static const char * arm_attr_tag_PAC_extension[] =
16167 {"No PAC/AUT instructions",
16168 "PAC/AUT instructions permitted in the NOP space",
16169 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16170
4b535030
AC
16171static const char * arm_attr_tag_BTI_extension[] =
16172 {"BTI instructions not permitted",
16173 "BTI instructions permitted in the NOP space",
16174 "BTI instructions permitted in the NOP and in the non-NOP space"};
16175
b81ee92f
AC
16176static const char * arm_attr_tag_BTI_use[] =
16177 {"Compiled without branch target enforcement",
16178 "Compiled with branch target enforcement"};
16179
c9fed665
AC
16180static const char * arm_attr_tag_PACRET_use[] =
16181 {"Compiled without return address signing and authentication",
16182 "Compiled with return address signing and authentication"};
16183
11c1ff18
PB
16184#define LOOKUP(id, name) \
16185 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16186static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16187{
16188 {4, "CPU_raw_name", 1, NULL},
16189 {5, "CPU_name", 1, NULL},
16190 LOOKUP(6, CPU_arch),
16191 {7, "CPU_arch_profile", 0, NULL},
16192 LOOKUP(8, ARM_ISA_use),
16193 LOOKUP(9, THUMB_ISA_use),
75375b3e 16194 LOOKUP(10, FP_arch),
11c1ff18 16195 LOOKUP(11, WMMX_arch),
f5f53991
AS
16196 LOOKUP(12, Advanced_SIMD_arch),
16197 LOOKUP(13, PCS_config),
11c1ff18
PB
16198 LOOKUP(14, ABI_PCS_R9_use),
16199 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16200 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16201 LOOKUP(17, ABI_PCS_GOT_use),
16202 LOOKUP(18, ABI_PCS_wchar_t),
16203 LOOKUP(19, ABI_FP_rounding),
16204 LOOKUP(20, ABI_FP_denormal),
16205 LOOKUP(21, ABI_FP_exceptions),
16206 LOOKUP(22, ABI_FP_user_exceptions),
16207 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16208 {24, "ABI_align_needed", 0, NULL},
16209 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16210 LOOKUP(26, ABI_enum_size),
16211 LOOKUP(27, ABI_HardFP_use),
16212 LOOKUP(28, ABI_VFP_args),
16213 LOOKUP(29, ABI_WMMX_args),
16214 LOOKUP(30, ABI_optimization_goals),
16215 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16216 {32, "compatibility", 0, NULL},
f5f53991 16217 LOOKUP(34, CPU_unaligned_access),
75375b3e 16218 LOOKUP(36, FP_HP_extension),
8e79c3df 16219 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16220 LOOKUP(42, MPextension_use),
16221 LOOKUP(44, DIV_use),
15afaa63 16222 LOOKUP(46, DSP_extension),
a7ad558c 16223 LOOKUP(48, MVE_arch),
99db83d0 16224 LOOKUP(50, PAC_extension),
4b535030 16225 LOOKUP(52, BTI_extension),
b81ee92f 16226 LOOKUP(74, BTI_use),
c9fed665 16227 LOOKUP(76, PACRET_use),
f5f53991
AS
16228 {64, "nodefaults", 0, NULL},
16229 {65, "also_compatible_with", 0, NULL},
16230 LOOKUP(66, T2EE_use),
16231 {67, "conformance", 1, NULL},
16232 LOOKUP(68, Virtualization_use),
cd21e546 16233 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16234};
16235#undef LOOKUP
16236
11c1ff18 16237static unsigned char *
f6f0e17b
NC
16238display_arm_attribute (unsigned char * p,
16239 const unsigned char * const end)
11c1ff18 16240{
70e99720 16241 unsigned int tag;
70e99720 16242 unsigned int val;
2cf0635d 16243 arm_attr_public_tag * attr;
11c1ff18 16244 unsigned i;
70e99720 16245 unsigned int type;
11c1ff18 16246
cd30bcef 16247 READ_ULEB (tag, p, end);
11c1ff18 16248 attr = NULL;
2cf0635d 16249 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16250 {
16251 if (arm_attr_public_tags[i].tag == tag)
16252 {
16253 attr = &arm_attr_public_tags[i];
16254 break;
16255 }
16256 }
16257
16258 if (attr)
16259 {
16260 printf (" Tag_%s: ", attr->name);
16261 switch (attr->type)
16262 {
16263 case 0:
16264 switch (tag)
16265 {
16266 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16267 READ_ULEB (val, p, end);
11c1ff18
PB
16268 switch (val)
16269 {
2b692964
NC
16270 case 0: printf (_("None\n")); break;
16271 case 'A': printf (_("Application\n")); break;
16272 case 'R': printf (_("Realtime\n")); break;
16273 case 'M': printf (_("Microcontroller\n")); break;
16274 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16275 default: printf ("??? (%d)\n", val); break;
16276 }
16277 break;
16278
75375b3e 16279 case 24: /* Tag_align_needed. */
cd30bcef 16280 READ_ULEB (val, p, end);
75375b3e
MGD
16281 switch (val)
16282 {
2b692964
NC
16283 case 0: printf (_("None\n")); break;
16284 case 1: printf (_("8-byte\n")); break;
16285 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16286 case 3: printf ("??? 3\n"); break;
16287 default:
16288 if (val <= 12)
dd24e3da 16289 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16290 1 << val);
16291 else
16292 printf ("??? (%d)\n", val);
16293 break;
16294 }
16295 break;
16296
16297 case 25: /* Tag_align_preserved. */
cd30bcef 16298 READ_ULEB (val, p, end);
75375b3e
MGD
16299 switch (val)
16300 {
2b692964
NC
16301 case 0: printf (_("None\n")); break;
16302 case 1: printf (_("8-byte, except leaf SP\n")); break;
16303 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16304 case 3: printf ("??? 3\n"); break;
16305 default:
16306 if (val <= 12)
dd24e3da 16307 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16308 1 << val);
16309 else
16310 printf ("??? (%d)\n", val);
16311 break;
16312 }
16313 break;
16314
11c1ff18 16315 case 32: /* Tag_compatibility. */
071436c6 16316 {
cd30bcef 16317 READ_ULEB (val, p, end);
071436c6 16318 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16319 if (p < end - 1)
16320 {
16321 size_t maxlen = (end - p) - 1;
16322
16323 print_symbol ((int) maxlen, (const char *) p);
16324 p += strnlen ((char *) p, maxlen) + 1;
16325 }
16326 else
16327 {
16328 printf (_("<corrupt>"));
16329 p = (unsigned char *) end;
16330 }
071436c6 16331 putchar ('\n');
071436c6 16332 }
11c1ff18
PB
16333 break;
16334
f5f53991 16335 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16336 /* PR 17531: file: 001-505008-0.01. */
16337 if (p < end)
16338 p++;
2b692964 16339 printf (_("True\n"));
f5f53991
AS
16340 break;
16341
16342 case 65: /* Tag_also_compatible_with. */
cd30bcef 16343 READ_ULEB (val, p, end);
f5f53991
AS
16344 if (val == 6 /* Tag_CPU_arch. */)
16345 {
cd30bcef 16346 READ_ULEB (val, p, end);
071436c6 16347 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16348 printf ("??? (%d)\n", val);
16349 else
16350 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16351 }
16352 else
16353 printf ("???\n");
071436c6
NC
16354 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16355 ;
f5f53991
AS
16356 break;
16357
11c1ff18 16358 default:
bee0ee85
NC
16359 printf (_("<unknown: %d>\n"), tag);
16360 break;
11c1ff18
PB
16361 }
16362 return p;
16363
16364 case 1:
f6f0e17b 16365 return display_tag_value (-1, p, end);
11c1ff18 16366 case 2:
f6f0e17b 16367 return display_tag_value (0, p, end);
11c1ff18
PB
16368
16369 default:
16370 assert (attr->type & 0x80);
cd30bcef 16371 READ_ULEB (val, p, end);
11c1ff18
PB
16372 type = attr->type & 0x7f;
16373 if (val >= type)
16374 printf ("??? (%d)\n", val);
16375 else
16376 printf ("%s\n", attr->table[val]);
16377 return p;
16378 }
16379 }
11c1ff18 16380
f6f0e17b 16381 return display_tag_value (tag, p, end);
11c1ff18
PB
16382}
16383
104d59d1 16384static unsigned char *
60bca95a 16385display_gnu_attribute (unsigned char * p,
60abdbed 16386 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16387 const unsigned char * const end)
104d59d1 16388{
cd30bcef 16389 unsigned int tag;
60abdbed 16390 unsigned int val;
104d59d1 16391
cd30bcef 16392 READ_ULEB (tag, p, end);
104d59d1
JM
16393
16394 /* Tag_compatibility is the only generic GNU attribute defined at
16395 present. */
16396 if (tag == 32)
16397 {
cd30bcef 16398 READ_ULEB (val, p, end);
071436c6
NC
16399
16400 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16401 if (p == end)
16402 {
071436c6 16403 printf (_("<corrupt>\n"));
f6f0e17b
NC
16404 warn (_("corrupt vendor attribute\n"));
16405 }
16406 else
16407 {
4082ef84
NC
16408 if (p < end - 1)
16409 {
16410 size_t maxlen = (end - p) - 1;
071436c6 16411
4082ef84
NC
16412 print_symbol ((int) maxlen, (const char *) p);
16413 p += strnlen ((char *) p, maxlen) + 1;
16414 }
16415 else
16416 {
16417 printf (_("<corrupt>"));
16418 p = (unsigned char *) end;
16419 }
071436c6 16420 putchar ('\n');
f6f0e17b 16421 }
104d59d1
JM
16422 return p;
16423 }
16424
16425 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16426 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16427
f6f0e17b 16428 return display_tag_value (tag, p, end);
104d59d1
JM
16429}
16430
85f7484a
PB
16431static unsigned char *
16432display_m68k_gnu_attribute (unsigned char * p,
16433 unsigned int tag,
16434 const unsigned char * const end)
16435{
16436 unsigned int val;
16437
16438 if (tag == Tag_GNU_M68K_ABI_FP)
16439 {
16440 printf (" Tag_GNU_M68K_ABI_FP: ");
16441 if (p == end)
16442 {
16443 printf (_("<corrupt>\n"));
16444 return p;
16445 }
16446 READ_ULEB (val, p, end);
16447
16448 if (val > 3)
16449 printf ("(%#x), ", val);
16450
16451 switch (val & 3)
16452 {
16453 case 0:
16454 printf (_("unspecified hard/soft float\n"));
16455 break;
16456 case 1:
16457 printf (_("hard float\n"));
16458 break;
16459 case 2:
16460 printf (_("soft float\n"));
16461 break;
16462 }
16463 return p;
16464 }
16465
16466 return display_tag_value (tag & 1, p, end);
16467}
16468
34c8bcba 16469static unsigned char *
f6f0e17b 16470display_power_gnu_attribute (unsigned char * p,
60abdbed 16471 unsigned int tag,
f6f0e17b 16472 const unsigned char * const end)
34c8bcba 16473{
005d79fd 16474 unsigned int val;
34c8bcba
JM
16475
16476 if (tag == Tag_GNU_Power_ABI_FP)
16477 {
34c8bcba 16478 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16479 if (p == end)
005d79fd
AM
16480 {
16481 printf (_("<corrupt>\n"));
16482 return p;
16483 }
cd30bcef 16484 READ_ULEB (val, p, end);
60bca95a 16485
005d79fd
AM
16486 if (val > 15)
16487 printf ("(%#x), ", val);
16488
16489 switch (val & 3)
34c8bcba
JM
16490 {
16491 case 0:
005d79fd 16492 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16493 break;
16494 case 1:
005d79fd 16495 printf (_("hard float, "));
34c8bcba
JM
16496 break;
16497 case 2:
005d79fd 16498 printf (_("soft float, "));
34c8bcba 16499 break;
3c7b9897 16500 case 3:
005d79fd 16501 printf (_("single-precision hard float, "));
3c7b9897 16502 break;
005d79fd
AM
16503 }
16504
16505 switch (val & 0xC)
16506 {
16507 case 0:
16508 printf (_("unspecified long double\n"));
16509 break;
16510 case 4:
16511 printf (_("128-bit IBM long double\n"));
16512 break;
16513 case 8:
16514 printf (_("64-bit long double\n"));
16515 break;
16516 case 12:
16517 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16518 break;
16519 }
16520 return p;
005d79fd 16521 }
34c8bcba 16522
c6e65352
DJ
16523 if (tag == Tag_GNU_Power_ABI_Vector)
16524 {
c6e65352 16525 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16526 if (p == end)
005d79fd
AM
16527 {
16528 printf (_("<corrupt>\n"));
16529 return p;
16530 }
cd30bcef 16531 READ_ULEB (val, p, end);
005d79fd
AM
16532
16533 if (val > 3)
16534 printf ("(%#x), ", val);
16535
16536 switch (val & 3)
c6e65352
DJ
16537 {
16538 case 0:
005d79fd 16539 printf (_("unspecified\n"));
c6e65352
DJ
16540 break;
16541 case 1:
005d79fd 16542 printf (_("generic\n"));
c6e65352
DJ
16543 break;
16544 case 2:
16545 printf ("AltiVec\n");
16546 break;
16547 case 3:
16548 printf ("SPE\n");
16549 break;
c6e65352
DJ
16550 }
16551 return p;
005d79fd 16552 }
c6e65352 16553
f82e0623
NF
16554 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16555 {
005d79fd 16556 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16557 if (p == end)
f6f0e17b 16558 {
005d79fd 16559 printf (_("<corrupt>\n"));
f6f0e17b
NC
16560 return p;
16561 }
cd30bcef 16562 READ_ULEB (val, p, end);
0b4362b0 16563
005d79fd
AM
16564 if (val > 2)
16565 printf ("(%#x), ", val);
16566
16567 switch (val & 3)
16568 {
16569 case 0:
16570 printf (_("unspecified\n"));
16571 break;
16572 case 1:
16573 printf ("r3/r4\n");
16574 break;
16575 case 2:
16576 printf (_("memory\n"));
16577 break;
16578 case 3:
16579 printf ("???\n");
16580 break;
16581 }
f82e0623
NF
16582 return p;
16583 }
16584
f6f0e17b 16585 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16586}
16587
643f7afb
AK
16588static unsigned char *
16589display_s390_gnu_attribute (unsigned char * p,
60abdbed 16590 unsigned int tag,
643f7afb
AK
16591 const unsigned char * const end)
16592{
cd30bcef 16593 unsigned int val;
643f7afb
AK
16594
16595 if (tag == Tag_GNU_S390_ABI_Vector)
16596 {
643f7afb 16597 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16598 READ_ULEB (val, p, end);
643f7afb
AK
16599
16600 switch (val)
16601 {
16602 case 0:
16603 printf (_("any\n"));
16604 break;
16605 case 1:
16606 printf (_("software\n"));
16607 break;
16608 case 2:
16609 printf (_("hardware\n"));
16610 break;
16611 default:
16612 printf ("??? (%d)\n", val);
16613 break;
16614 }
16615 return p;
16616 }
16617
16618 return display_tag_value (tag & 1, p, end);
16619}
16620
9e8c70f9 16621static void
60abdbed 16622display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16623{
16624 if (mask)
16625 {
015dc7e1 16626 bool first = true;
071436c6 16627
9e8c70f9 16628 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16629 fputs ("mul32", stdout), first = false;
9e8c70f9 16630 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16631 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16632 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16633 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16634 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16635 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16636 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16637 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16638 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16639 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16640 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16641 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16642 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16643 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16644 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16645 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16646 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16647 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16648 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16649 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16650 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16651 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16652 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16653 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16654 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16655 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16656 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16657 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16658 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16659 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16660 }
16661 else
071436c6
NC
16662 fputc ('0', stdout);
16663 fputc ('\n', stdout);
9e8c70f9
DM
16664}
16665
3d68f91c 16666static void
60abdbed 16667display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16668{
16669 if (mask)
16670 {
015dc7e1 16671 bool first = true;
071436c6 16672
3d68f91c 16673 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16674 fputs ("fjathplus", stdout), first = false;
3d68f91c 16675 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16676 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16677 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16678 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16679 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16680 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16681 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16682 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16683 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16684 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16685 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16686 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16687 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16688 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16689 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16690 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16691 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16692 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16693 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16694 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16695 }
16696 else
071436c6
NC
16697 fputc ('0', stdout);
16698 fputc ('\n', stdout);
3d68f91c
JM
16699}
16700
9e8c70f9 16701static unsigned char *
f6f0e17b 16702display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16703 unsigned int tag,
f6f0e17b 16704 const unsigned char * const end)
9e8c70f9 16705{
cd30bcef 16706 unsigned int val;
3d68f91c 16707
9e8c70f9
DM
16708 if (tag == Tag_GNU_Sparc_HWCAPS)
16709 {
cd30bcef 16710 READ_ULEB (val, p, end);
9e8c70f9 16711 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16712 display_sparc_hwcaps (val);
16713 return p;
3d68f91c
JM
16714 }
16715 if (tag == Tag_GNU_Sparc_HWCAPS2)
16716 {
cd30bcef 16717 READ_ULEB (val, p, end);
3d68f91c
JM
16718 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16719 display_sparc_hwcaps2 (val);
16720 return p;
16721 }
9e8c70f9 16722
f6f0e17b 16723 return display_tag_value (tag, p, end);
9e8c70f9
DM
16724}
16725
351cdf24 16726static void
32ec8896 16727print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16728{
16729 switch (val)
16730 {
16731 case Val_GNU_MIPS_ABI_FP_ANY:
16732 printf (_("Hard or soft float\n"));
16733 break;
16734 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16735 printf (_("Hard float (double precision)\n"));
16736 break;
16737 case Val_GNU_MIPS_ABI_FP_SINGLE:
16738 printf (_("Hard float (single precision)\n"));
16739 break;
16740 case Val_GNU_MIPS_ABI_FP_SOFT:
16741 printf (_("Soft float\n"));
16742 break;
16743 case Val_GNU_MIPS_ABI_FP_OLD_64:
16744 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16745 break;
16746 case Val_GNU_MIPS_ABI_FP_XX:
16747 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16748 break;
16749 case Val_GNU_MIPS_ABI_FP_64:
16750 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16751 break;
16752 case Val_GNU_MIPS_ABI_FP_64A:
16753 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16754 break;
3350cc01
CM
16755 case Val_GNU_MIPS_ABI_FP_NAN2008:
16756 printf (_("NaN 2008 compatibility\n"));
16757 break;
351cdf24
MF
16758 default:
16759 printf ("??? (%d)\n", val);
16760 break;
16761 }
16762}
16763
2cf19d5c 16764static unsigned char *
f6f0e17b 16765display_mips_gnu_attribute (unsigned char * p,
60abdbed 16766 unsigned int tag,
f6f0e17b 16767 const unsigned char * const end)
2cf19d5c 16768{
2cf19d5c
JM
16769 if (tag == Tag_GNU_MIPS_ABI_FP)
16770 {
32ec8896 16771 unsigned int val;
f6f0e17b 16772
2cf19d5c 16773 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16774 READ_ULEB (val, p, end);
351cdf24 16775 print_mips_fp_abi_value (val);
2cf19d5c
JM
16776 return p;
16777 }
16778
a9f58168
CF
16779 if (tag == Tag_GNU_MIPS_ABI_MSA)
16780 {
32ec8896 16781 unsigned int val;
a9f58168 16782
a9f58168 16783 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16784 READ_ULEB (val, p, end);
a9f58168
CF
16785
16786 switch (val)
16787 {
16788 case Val_GNU_MIPS_ABI_MSA_ANY:
16789 printf (_("Any MSA or not\n"));
16790 break;
16791 case Val_GNU_MIPS_ABI_MSA_128:
16792 printf (_("128-bit MSA\n"));
16793 break;
16794 default:
16795 printf ("??? (%d)\n", val);
16796 break;
16797 }
16798 return p;
16799 }
16800
f6f0e17b 16801 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16802}
16803
59e6276b 16804static unsigned char *
f6f0e17b
NC
16805display_tic6x_attribute (unsigned char * p,
16806 const unsigned char * const end)
59e6276b 16807{
60abdbed 16808 unsigned int tag;
cd30bcef 16809 unsigned int val;
59e6276b 16810
cd30bcef 16811 READ_ULEB (tag, p, end);
59e6276b
JM
16812
16813 switch (tag)
16814 {
75fa6dc1 16815 case Tag_ISA:
75fa6dc1 16816 printf (" Tag_ISA: ");
cd30bcef 16817 READ_ULEB (val, p, end);
59e6276b
JM
16818
16819 switch (val)
16820 {
75fa6dc1 16821 case C6XABI_Tag_ISA_none:
59e6276b
JM
16822 printf (_("None\n"));
16823 break;
75fa6dc1 16824 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16825 printf ("C62x\n");
16826 break;
75fa6dc1 16827 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16828 printf ("C67x\n");
16829 break;
75fa6dc1 16830 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16831 printf ("C67x+\n");
16832 break;
75fa6dc1 16833 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16834 printf ("C64x\n");
16835 break;
75fa6dc1 16836 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16837 printf ("C64x+\n");
16838 break;
75fa6dc1 16839 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16840 printf ("C674x\n");
16841 break;
16842 default:
16843 printf ("??? (%d)\n", val);
16844 break;
16845 }
16846 return p;
16847
87779176 16848 case Tag_ABI_wchar_t:
87779176 16849 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16850 READ_ULEB (val, p, end);
87779176
JM
16851 switch (val)
16852 {
16853 case 0:
16854 printf (_("Not used\n"));
16855 break;
16856 case 1:
16857 printf (_("2 bytes\n"));
16858 break;
16859 case 2:
16860 printf (_("4 bytes\n"));
16861 break;
16862 default:
16863 printf ("??? (%d)\n", val);
16864 break;
16865 }
16866 return p;
16867
16868 case Tag_ABI_stack_align_needed:
87779176 16869 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16870 READ_ULEB (val, p, end);
87779176
JM
16871 switch (val)
16872 {
16873 case 0:
16874 printf (_("8-byte\n"));
16875 break;
16876 case 1:
16877 printf (_("16-byte\n"));
16878 break;
16879 default:
16880 printf ("??? (%d)\n", val);
16881 break;
16882 }
16883 return p;
16884
16885 case Tag_ABI_stack_align_preserved:
cd30bcef 16886 READ_ULEB (val, p, end);
87779176
JM
16887 printf (" Tag_ABI_stack_align_preserved: ");
16888 switch (val)
16889 {
16890 case 0:
16891 printf (_("8-byte\n"));
16892 break;
16893 case 1:
16894 printf (_("16-byte\n"));
16895 break;
16896 default:
16897 printf ("??? (%d)\n", val);
16898 break;
16899 }
16900 return p;
16901
b5593623 16902 case Tag_ABI_DSBT:
cd30bcef 16903 READ_ULEB (val, p, end);
b5593623
JM
16904 printf (" Tag_ABI_DSBT: ");
16905 switch (val)
16906 {
16907 case 0:
16908 printf (_("DSBT addressing not used\n"));
16909 break;
16910 case 1:
16911 printf (_("DSBT addressing used\n"));
16912 break;
16913 default:
16914 printf ("??? (%d)\n", val);
16915 break;
16916 }
16917 return p;
16918
87779176 16919 case Tag_ABI_PID:
cd30bcef 16920 READ_ULEB (val, p, end);
87779176
JM
16921 printf (" Tag_ABI_PID: ");
16922 switch (val)
16923 {
16924 case 0:
16925 printf (_("Data addressing position-dependent\n"));
16926 break;
16927 case 1:
16928 printf (_("Data addressing position-independent, GOT near DP\n"));
16929 break;
16930 case 2:
16931 printf (_("Data addressing position-independent, GOT far from DP\n"));
16932 break;
16933 default:
16934 printf ("??? (%d)\n", val);
16935 break;
16936 }
16937 return p;
16938
16939 case Tag_ABI_PIC:
cd30bcef 16940 READ_ULEB (val, p, end);
87779176
JM
16941 printf (" Tag_ABI_PIC: ");
16942 switch (val)
16943 {
16944 case 0:
16945 printf (_("Code addressing position-dependent\n"));
16946 break;
16947 case 1:
16948 printf (_("Code addressing position-independent\n"));
16949 break;
16950 default:
16951 printf ("??? (%d)\n", val);
16952 break;
16953 }
16954 return p;
16955
16956 case Tag_ABI_array_object_alignment:
cd30bcef 16957 READ_ULEB (val, p, end);
87779176
JM
16958 printf (" Tag_ABI_array_object_alignment: ");
16959 switch (val)
16960 {
16961 case 0:
16962 printf (_("8-byte\n"));
16963 break;
16964 case 1:
16965 printf (_("4-byte\n"));
16966 break;
16967 case 2:
16968 printf (_("16-byte\n"));
16969 break;
16970 default:
16971 printf ("??? (%d)\n", val);
16972 break;
16973 }
16974 return p;
16975
16976 case Tag_ABI_array_object_align_expected:
cd30bcef 16977 READ_ULEB (val, p, end);
87779176
JM
16978 printf (" Tag_ABI_array_object_align_expected: ");
16979 switch (val)
16980 {
16981 case 0:
16982 printf (_("8-byte\n"));
16983 break;
16984 case 1:
16985 printf (_("4-byte\n"));
16986 break;
16987 case 2:
16988 printf (_("16-byte\n"));
16989 break;
16990 default:
16991 printf ("??? (%d)\n", val);
16992 break;
16993 }
16994 return p;
16995
3cbd1c06 16996 case Tag_ABI_compatibility:
071436c6 16997 {
cd30bcef 16998 READ_ULEB (val, p, end);
071436c6 16999 printf (" Tag_ABI_compatibility: ");
071436c6 17000 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17001 if (p < end - 1)
17002 {
17003 size_t maxlen = (end - p) - 1;
17004
17005 print_symbol ((int) maxlen, (const char *) p);
17006 p += strnlen ((char *) p, maxlen) + 1;
17007 }
17008 else
17009 {
17010 printf (_("<corrupt>"));
17011 p = (unsigned char *) end;
17012 }
071436c6 17013 putchar ('\n');
071436c6
NC
17014 return p;
17015 }
87779176
JM
17016
17017 case Tag_ABI_conformance:
071436c6 17018 {
4082ef84
NC
17019 printf (" Tag_ABI_conformance: \"");
17020 if (p < end - 1)
17021 {
17022 size_t maxlen = (end - p) - 1;
071436c6 17023
4082ef84
NC
17024 print_symbol ((int) maxlen, (const char *) p);
17025 p += strnlen ((char *) p, maxlen) + 1;
17026 }
17027 else
17028 {
17029 printf (_("<corrupt>"));
17030 p = (unsigned char *) end;
17031 }
071436c6 17032 printf ("\"\n");
071436c6
NC
17033 return p;
17034 }
59e6276b
JM
17035 }
17036
f6f0e17b
NC
17037 return display_tag_value (tag, p, end);
17038}
59e6276b 17039
f6f0e17b 17040static void
60abdbed 17041display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17042{
17043 unsigned long addr = 0;
17044 size_t bytes = end - p;
17045
feceaa59 17046 assert (end >= p);
f6f0e17b 17047 while (bytes)
87779176 17048 {
f6f0e17b
NC
17049 int j;
17050 int k;
17051 int lbytes = (bytes > 16 ? 16 : bytes);
17052
17053 printf (" 0x%8.8lx ", addr);
17054
17055 for (j = 0; j < 16; j++)
17056 {
17057 if (j < lbytes)
17058 printf ("%2.2x", p[j]);
17059 else
17060 printf (" ");
17061
17062 if ((j & 3) == 3)
17063 printf (" ");
17064 }
17065
17066 for (j = 0; j < lbytes; j++)
17067 {
17068 k = p[j];
17069 if (k >= ' ' && k < 0x7f)
17070 printf ("%c", k);
17071 else
17072 printf (".");
17073 }
17074
17075 putchar ('\n');
17076
17077 p += lbytes;
17078 bytes -= lbytes;
17079 addr += lbytes;
87779176 17080 }
59e6276b 17081
f6f0e17b 17082 putchar ('\n');
59e6276b
JM
17083}
17084
13761a11 17085static unsigned char *
b0191216 17086display_msp430_attribute (unsigned char * p,
13761a11
NC
17087 const unsigned char * const end)
17088{
60abdbed
NC
17089 unsigned int val;
17090 unsigned int tag;
13761a11 17091
cd30bcef 17092 READ_ULEB (tag, p, end);
0b4362b0 17093
13761a11
NC
17094 switch (tag)
17095 {
17096 case OFBA_MSPABI_Tag_ISA:
13761a11 17097 printf (" Tag_ISA: ");
cd30bcef 17098 READ_ULEB (val, p, end);
13761a11
NC
17099 switch (val)
17100 {
17101 case 0: printf (_("None\n")); break;
17102 case 1: printf (_("MSP430\n")); break;
17103 case 2: printf (_("MSP430X\n")); break;
17104 default: printf ("??? (%d)\n", val); break;
17105 }
17106 break;
17107
17108 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17109 printf (" Tag_Code_Model: ");
cd30bcef 17110 READ_ULEB (val, p, end);
13761a11
NC
17111 switch (val)
17112 {
17113 case 0: printf (_("None\n")); break;
17114 case 1: printf (_("Small\n")); break;
17115 case 2: printf (_("Large\n")); break;
17116 default: printf ("??? (%d)\n", val); break;
17117 }
17118 break;
17119
17120 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17121 printf (" Tag_Data_Model: ");
cd30bcef 17122 READ_ULEB (val, p, end);
13761a11
NC
17123 switch (val)
17124 {
17125 case 0: printf (_("None\n")); break;
17126 case 1: printf (_("Small\n")); break;
17127 case 2: printf (_("Large\n")); break;
17128 case 3: printf (_("Restricted Large\n")); break;
17129 default: printf ("??? (%d)\n", val); break;
17130 }
17131 break;
17132
17133 default:
17134 printf (_(" <unknown tag %d>: "), tag);
17135
17136 if (tag & 1)
17137 {
071436c6 17138 putchar ('"');
4082ef84
NC
17139 if (p < end - 1)
17140 {
17141 size_t maxlen = (end - p) - 1;
17142
17143 print_symbol ((int) maxlen, (const char *) p);
17144 p += strnlen ((char *) p, maxlen) + 1;
17145 }
17146 else
17147 {
17148 printf (_("<corrupt>"));
17149 p = (unsigned char *) end;
17150 }
071436c6 17151 printf ("\"\n");
13761a11
NC
17152 }
17153 else
17154 {
cd30bcef 17155 READ_ULEB (val, p, end);
13761a11
NC
17156 printf ("%d (0x%x)\n", val, val);
17157 }
17158 break;
17159 }
17160
4082ef84 17161 assert (p <= end);
13761a11
NC
17162 return p;
17163}
17164
c0ea7c52
JL
17165static unsigned char *
17166display_msp430_gnu_attribute (unsigned char * p,
17167 unsigned int tag,
17168 const unsigned char * const end)
17169{
17170 if (tag == Tag_GNU_MSP430_Data_Region)
17171 {
cd30bcef 17172 unsigned int val;
c0ea7c52 17173
c0ea7c52 17174 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17175 READ_ULEB (val, p, end);
c0ea7c52
JL
17176
17177 switch (val)
17178 {
17179 case Val_GNU_MSP430_Data_Region_Any:
17180 printf (_("Any Region\n"));
17181 break;
17182 case Val_GNU_MSP430_Data_Region_Lower:
17183 printf (_("Lower Region Only\n"));
17184 break;
17185 default:
cd30bcef 17186 printf ("??? (%u)\n", val);
c0ea7c52
JL
17187 }
17188 return p;
17189 }
17190 return display_tag_value (tag & 1, p, end);
17191}
17192
2dc8dd17
JW
17193struct riscv_attr_tag_t {
17194 const char *name;
cd30bcef 17195 unsigned int tag;
2dc8dd17
JW
17196};
17197
17198static struct riscv_attr_tag_t riscv_attr_tag[] =
17199{
17200#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17201 T(arch),
17202 T(priv_spec),
17203 T(priv_spec_minor),
17204 T(priv_spec_revision),
17205 T(unaligned_access),
17206 T(stack_align),
17207#undef T
17208};
17209
17210static unsigned char *
17211display_riscv_attribute (unsigned char *p,
17212 const unsigned char * const end)
17213{
cd30bcef
AM
17214 unsigned int val;
17215 unsigned int tag;
2dc8dd17
JW
17216 struct riscv_attr_tag_t *attr = NULL;
17217 unsigned i;
17218
cd30bcef 17219 READ_ULEB (tag, p, end);
2dc8dd17
JW
17220
17221 /* Find the name of attribute. */
17222 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17223 {
17224 if (riscv_attr_tag[i].tag == tag)
17225 {
17226 attr = &riscv_attr_tag[i];
17227 break;
17228 }
17229 }
17230
17231 if (attr)
17232 printf (" %s: ", attr->name);
17233 else
17234 return display_tag_value (tag, p, end);
17235
17236 switch (tag)
17237 {
17238 case Tag_RISCV_priv_spec:
17239 case Tag_RISCV_priv_spec_minor:
17240 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17241 READ_ULEB (val, p, end);
17242 printf (_("%u\n"), val);
2dc8dd17
JW
17243 break;
17244 case Tag_RISCV_unaligned_access:
cd30bcef 17245 READ_ULEB (val, p, end);
2dc8dd17
JW
17246 switch (val)
17247 {
17248 case 0:
17249 printf (_("No unaligned access\n"));
17250 break;
17251 case 1:
17252 printf (_("Unaligned access\n"));
17253 break;
17254 }
17255 break;
17256 case Tag_RISCV_stack_align:
cd30bcef
AM
17257 READ_ULEB (val, p, end);
17258 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17259 break;
17260 case Tag_RISCV_arch:
17261 p = display_tag_value (-1, p, end);
17262 break;
17263 default:
17264 return display_tag_value (tag, p, end);
17265 }
17266
17267 return p;
17268}
17269
0861f561
CQ
17270static unsigned char *
17271display_csky_attribute (unsigned char * p,
17272 const unsigned char * const end)
17273{
17274 unsigned int tag;
17275 unsigned int val;
17276 READ_ULEB (tag, p, end);
17277
17278 if (tag >= Tag_CSKY_MAX)
17279 {
17280 return display_tag_value (-1, p, end);
17281 }
17282
17283 switch (tag)
17284 {
17285 case Tag_CSKY_ARCH_NAME:
17286 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17287 return display_tag_value (-1, p, end);
17288 case Tag_CSKY_CPU_NAME:
17289 printf (" Tag_CSKY_CPU_NAME:\t\t");
17290 return display_tag_value (-1, p, end);
17291
17292 case Tag_CSKY_ISA_FLAGS:
17293 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17294 return display_tag_value (0, p, end);
17295 case Tag_CSKY_ISA_EXT_FLAGS:
17296 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17297 return display_tag_value (0, p, end);
17298
17299 case Tag_CSKY_DSP_VERSION:
17300 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17301 READ_ULEB (val, p, end);
17302 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17303 printf ("DSP Extension\n");
17304 else if (val == VAL_CSKY_DSP_VERSION_2)
17305 printf ("DSP 2.0\n");
17306 break;
17307
17308 case Tag_CSKY_VDSP_VERSION:
17309 printf (" Tag_CSKY_VDSP_VERSION:\t");
17310 READ_ULEB (val, p, end);
17311 printf ("VDSP Version %d\n", val);
17312 break;
17313
17314 case Tag_CSKY_FPU_VERSION:
17315 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17316 READ_ULEB (val, p, end);
17317 if (val == VAL_CSKY_FPU_VERSION_1)
17318 printf ("ABIV1 FPU Version 1\n");
17319 else if (val == VAL_CSKY_FPU_VERSION_2)
17320 printf ("FPU Version 2\n");
17321 break;
17322
17323 case Tag_CSKY_FPU_ABI:
17324 printf (" Tag_CSKY_FPU_ABI:\t\t");
17325 READ_ULEB (val, p, end);
17326 if (val == VAL_CSKY_FPU_ABI_HARD)
17327 printf ("Hard\n");
17328 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17329 printf ("SoftFP\n");
17330 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17331 printf ("Soft\n");
17332 break;
17333 case Tag_CSKY_FPU_ROUNDING:
17334 READ_ULEB (val, p, end);
f253158f
NC
17335 if (val == 1)
17336 {
17337 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17338 printf ("Needed\n");
17339 }
0861f561
CQ
17340 break;
17341 case Tag_CSKY_FPU_DENORMAL:
17342 READ_ULEB (val, p, end);
f253158f
NC
17343 if (val == 1)
17344 {
17345 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17346 printf ("Needed\n");
17347 }
0861f561
CQ
17348 break;
17349 case Tag_CSKY_FPU_Exception:
17350 READ_ULEB (val, p, end);
f253158f
NC
17351 if (val == 1)
17352 {
17353 printf (" Tag_CSKY_FPU_Exception:\t");
17354 printf ("Needed\n");
17355 }
0861f561
CQ
17356 break;
17357 case Tag_CSKY_FPU_NUMBER_MODULE:
17358 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17359 return display_tag_value (-1, p, end);
17360 case Tag_CSKY_FPU_HARDFP:
17361 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17362 READ_ULEB (val, p, end);
17363 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17364 printf (" Half");
17365 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17366 printf (" Single");
17367 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17368 printf (" Double");
17369 printf ("\n");
17370 break;
17371 default:
17372 return display_tag_value (tag, p, end);
17373 }
17374 return p;
17375}
17376
015dc7e1 17377static bool
dda8d76d 17378process_attributes (Filedata * filedata,
60bca95a 17379 const char * public_name,
104d59d1 17380 unsigned int proc_type,
f6f0e17b 17381 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17382 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17383{
2cf0635d 17384 Elf_Internal_Shdr * sect;
11c1ff18 17385 unsigned i;
015dc7e1 17386 bool res = true;
11c1ff18
PB
17387
17388 /* Find the section header so that we get the size. */
dda8d76d
NC
17389 for (i = 0, sect = filedata->section_headers;
17390 i < filedata->file_header.e_shnum;
11c1ff18
PB
17391 i++, sect++)
17392 {
071436c6
NC
17393 unsigned char * contents;
17394 unsigned char * p;
17395
104d59d1 17396 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17397 continue;
17398
dda8d76d 17399 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17400 sect->sh_size, _("attributes"));
60bca95a 17401 if (contents == NULL)
32ec8896 17402 {
015dc7e1 17403 res = false;
32ec8896
NC
17404 continue;
17405 }
60bca95a 17406
11c1ff18 17407 p = contents;
60abdbed
NC
17408 /* The first character is the version of the attributes.
17409 Currently only version 1, (aka 'A') is recognised here. */
17410 if (*p != 'A')
32ec8896
NC
17411 {
17412 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17413 res = false;
32ec8896 17414 }
60abdbed 17415 else
11c1ff18 17416 {
071436c6
NC
17417 bfd_vma section_len;
17418
17419 section_len = sect->sh_size - 1;
11c1ff18 17420 p++;
60bca95a 17421
071436c6 17422 while (section_len > 0)
11c1ff18 17423 {
071436c6 17424 bfd_vma attr_len;
e9847026 17425 unsigned int namelen;
015dc7e1
AM
17426 bool public_section;
17427 bool gnu_section;
11c1ff18 17428
071436c6 17429 if (section_len <= 4)
e0a31db1
NC
17430 {
17431 error (_("Tag section ends prematurely\n"));
015dc7e1 17432 res = false;
e0a31db1
NC
17433 break;
17434 }
071436c6 17435 attr_len = byte_get (p, 4);
11c1ff18 17436 p += 4;
60bca95a 17437
071436c6 17438 if (attr_len > section_len)
11c1ff18 17439 {
071436c6
NC
17440 error (_("Bad attribute length (%u > %u)\n"),
17441 (unsigned) attr_len, (unsigned) section_len);
17442 attr_len = section_len;
015dc7e1 17443 res = false;
11c1ff18 17444 }
74e1a04b 17445 /* PR 17531: file: 001-101425-0.004 */
071436c6 17446 else if (attr_len < 5)
74e1a04b 17447 {
071436c6 17448 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17449 res = false;
74e1a04b
NC
17450 break;
17451 }
e9847026 17452
071436c6
NC
17453 section_len -= attr_len;
17454 attr_len -= 4;
17455
17456 namelen = strnlen ((char *) p, attr_len) + 1;
17457 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17458 {
17459 error (_("Corrupt attribute section name\n"));
015dc7e1 17460 res = false;
e9847026
NC
17461 break;
17462 }
17463
071436c6
NC
17464 printf (_("Attribute Section: "));
17465 print_symbol (INT_MAX, (const char *) p);
17466 putchar ('\n');
60bca95a
NC
17467
17468 if (public_name && streq ((char *) p, public_name))
015dc7e1 17469 public_section = true;
11c1ff18 17470 else
015dc7e1 17471 public_section = false;
60bca95a
NC
17472
17473 if (streq ((char *) p, "gnu"))
015dc7e1 17474 gnu_section = true;
104d59d1 17475 else
015dc7e1 17476 gnu_section = false;
60bca95a 17477
11c1ff18 17478 p += namelen;
071436c6 17479 attr_len -= namelen;
e0a31db1 17480
071436c6 17481 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17482 {
e0a31db1 17483 int tag;
cd30bcef 17484 unsigned int val;
11c1ff18 17485 bfd_vma size;
071436c6 17486 unsigned char * end;
60bca95a 17487
e0a31db1 17488 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17489 if (attr_len < 6)
e0a31db1
NC
17490 {
17491 error (_("Unused bytes at end of section\n"));
015dc7e1 17492 res = false;
e0a31db1
NC
17493 section_len = 0;
17494 break;
17495 }
17496
17497 tag = *(p++);
11c1ff18 17498 size = byte_get (p, 4);
071436c6 17499 if (size > attr_len)
11c1ff18 17500 {
e9847026 17501 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17502 (unsigned) size, (unsigned) attr_len);
015dc7e1 17503 res = false;
071436c6 17504 size = attr_len;
11c1ff18 17505 }
e0a31db1
NC
17506 /* PR binutils/17531: Safe handling of corrupt files. */
17507 if (size < 6)
17508 {
17509 error (_("Bad subsection length (%u < 6)\n"),
17510 (unsigned) size);
015dc7e1 17511 res = false;
e0a31db1
NC
17512 section_len = 0;
17513 break;
17514 }
60bca95a 17515
071436c6 17516 attr_len -= size;
11c1ff18 17517 end = p + size - 1;
071436c6 17518 assert (end <= contents + sect->sh_size);
11c1ff18 17519 p += 4;
60bca95a 17520
11c1ff18
PB
17521 switch (tag)
17522 {
17523 case 1:
2b692964 17524 printf (_("File Attributes\n"));
11c1ff18
PB
17525 break;
17526 case 2:
2b692964 17527 printf (_("Section Attributes:"));
11c1ff18
PB
17528 goto do_numlist;
17529 case 3:
2b692964 17530 printf (_("Symbol Attributes:"));
1a0670f3 17531 /* Fall through. */
11c1ff18
PB
17532 do_numlist:
17533 for (;;)
17534 {
cd30bcef 17535 READ_ULEB (val, p, end);
11c1ff18
PB
17536 if (val == 0)
17537 break;
17538 printf (" %d", val);
17539 }
17540 printf ("\n");
17541 break;
17542 default:
2b692964 17543 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17544 public_section = false;
11c1ff18
PB
17545 break;
17546 }
60bca95a 17547
071436c6 17548 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17549 {
17550 while (p < end)
f6f0e17b 17551 p = display_pub_attribute (p, end);
60abdbed 17552 assert (p == end);
104d59d1 17553 }
071436c6 17554 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17555 {
17556 while (p < end)
17557 p = display_gnu_attribute (p,
f6f0e17b
NC
17558 display_proc_gnu_attribute,
17559 end);
60abdbed 17560 assert (p == end);
11c1ff18 17561 }
071436c6 17562 else if (p < end)
11c1ff18 17563 {
071436c6 17564 printf (_(" Unknown attribute:\n"));
f6f0e17b 17565 display_raw_attribute (p, end);
11c1ff18
PB
17566 p = end;
17567 }
071436c6
NC
17568 else
17569 attr_len = 0;
11c1ff18
PB
17570 }
17571 }
17572 }
d70c5fc7 17573
60bca95a 17574 free (contents);
11c1ff18 17575 }
32ec8896
NC
17576
17577 return res;
11c1ff18
PB
17578}
17579
ccb4c951
RS
17580/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17581 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17582 and return the VMA of the next entry, or -1 if there was a problem.
17583 Does not read from DATA_END or beyond. */
ccb4c951
RS
17584
17585static bfd_vma
82b1b41b
NC
17586print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17587 unsigned char * data_end)
ccb4c951
RS
17588{
17589 printf (" ");
17590 print_vma (addr, LONG_HEX);
17591 printf (" ");
17592 if (addr < pltgot + 0xfff0)
17593 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17594 else
17595 printf ("%10s", "");
17596 printf (" ");
17597 if (data == NULL)
2b692964 17598 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17599 else
17600 {
17601 bfd_vma entry;
82b1b41b 17602 unsigned char * from = data + addr - pltgot;
ccb4c951 17603
82b1b41b
NC
17604 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17605 {
17606 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17607 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17608 return (bfd_vma) -1;
17609 }
17610 else
17611 {
17612 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17613 print_vma (entry, LONG_HEX);
17614 }
ccb4c951
RS
17615 }
17616 return addr + (is_32bit_elf ? 4 : 8);
17617}
17618
861fb55a
DJ
17619/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17620 PLTGOT. Print the Address and Initial fields of an entry at VMA
17621 ADDR and return the VMA of the next entry. */
17622
17623static bfd_vma
2cf0635d 17624print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17625{
17626 printf (" ");
17627 print_vma (addr, LONG_HEX);
17628 printf (" ");
17629 if (data == NULL)
2b692964 17630 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17631 else
17632 {
17633 bfd_vma entry;
17634
17635 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17636 print_vma (entry, LONG_HEX);
17637 }
17638 return addr + (is_32bit_elf ? 4 : 8);
17639}
17640
351cdf24
MF
17641static void
17642print_mips_ases (unsigned int mask)
17643{
17644 if (mask & AFL_ASE_DSP)
17645 fputs ("\n\tDSP ASE", stdout);
17646 if (mask & AFL_ASE_DSPR2)
17647 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17648 if (mask & AFL_ASE_DSPR3)
17649 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17650 if (mask & AFL_ASE_EVA)
17651 fputs ("\n\tEnhanced VA Scheme", stdout);
17652 if (mask & AFL_ASE_MCU)
17653 fputs ("\n\tMCU (MicroController) ASE", stdout);
17654 if (mask & AFL_ASE_MDMX)
17655 fputs ("\n\tMDMX ASE", stdout);
17656 if (mask & AFL_ASE_MIPS3D)
17657 fputs ("\n\tMIPS-3D ASE", stdout);
17658 if (mask & AFL_ASE_MT)
17659 fputs ("\n\tMT ASE", stdout);
17660 if (mask & AFL_ASE_SMARTMIPS)
17661 fputs ("\n\tSmartMIPS ASE", stdout);
17662 if (mask & AFL_ASE_VIRT)
17663 fputs ("\n\tVZ ASE", stdout);
17664 if (mask & AFL_ASE_MSA)
17665 fputs ("\n\tMSA ASE", stdout);
17666 if (mask & AFL_ASE_MIPS16)
17667 fputs ("\n\tMIPS16 ASE", stdout);
17668 if (mask & AFL_ASE_MICROMIPS)
17669 fputs ("\n\tMICROMIPS ASE", stdout);
17670 if (mask & AFL_ASE_XPA)
17671 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17672 if (mask & AFL_ASE_MIPS16E2)
17673 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17674 if (mask & AFL_ASE_CRC)
17675 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17676 if (mask & AFL_ASE_GINV)
17677 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17678 if (mask & AFL_ASE_LOONGSON_MMI)
17679 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17680 if (mask & AFL_ASE_LOONGSON_CAM)
17681 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17682 if (mask & AFL_ASE_LOONGSON_EXT)
17683 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17684 if (mask & AFL_ASE_LOONGSON_EXT2)
17685 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17686 if (mask == 0)
17687 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17688 else if ((mask & ~AFL_ASE_MASK) != 0)
17689 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17690}
17691
17692static void
17693print_mips_isa_ext (unsigned int isa_ext)
17694{
17695 switch (isa_ext)
17696 {
17697 case 0:
17698 fputs (_("None"), stdout);
17699 break;
17700 case AFL_EXT_XLR:
17701 fputs ("RMI XLR", stdout);
17702 break;
2c629856
N
17703 case AFL_EXT_OCTEON3:
17704 fputs ("Cavium Networks Octeon3", stdout);
17705 break;
351cdf24
MF
17706 case AFL_EXT_OCTEON2:
17707 fputs ("Cavium Networks Octeon2", stdout);
17708 break;
17709 case AFL_EXT_OCTEONP:
17710 fputs ("Cavium Networks OcteonP", stdout);
17711 break;
351cdf24
MF
17712 case AFL_EXT_OCTEON:
17713 fputs ("Cavium Networks Octeon", stdout);
17714 break;
17715 case AFL_EXT_5900:
17716 fputs ("Toshiba R5900", stdout);
17717 break;
17718 case AFL_EXT_4650:
17719 fputs ("MIPS R4650", stdout);
17720 break;
17721 case AFL_EXT_4010:
17722 fputs ("LSI R4010", stdout);
17723 break;
17724 case AFL_EXT_4100:
17725 fputs ("NEC VR4100", stdout);
17726 break;
17727 case AFL_EXT_3900:
17728 fputs ("Toshiba R3900", stdout);
17729 break;
17730 case AFL_EXT_10000:
17731 fputs ("MIPS R10000", stdout);
17732 break;
17733 case AFL_EXT_SB1:
17734 fputs ("Broadcom SB-1", stdout);
17735 break;
17736 case AFL_EXT_4111:
17737 fputs ("NEC VR4111/VR4181", stdout);
17738 break;
17739 case AFL_EXT_4120:
17740 fputs ("NEC VR4120", stdout);
17741 break;
17742 case AFL_EXT_5400:
17743 fputs ("NEC VR5400", stdout);
17744 break;
17745 case AFL_EXT_5500:
17746 fputs ("NEC VR5500", stdout);
17747 break;
17748 case AFL_EXT_LOONGSON_2E:
17749 fputs ("ST Microelectronics Loongson 2E", stdout);
17750 break;
17751 case AFL_EXT_LOONGSON_2F:
17752 fputs ("ST Microelectronics Loongson 2F", stdout);
17753 break;
38bf472a
MR
17754 case AFL_EXT_INTERAPTIV_MR2:
17755 fputs ("Imagination interAptiv MR2", stdout);
17756 break;
351cdf24 17757 default:
00ac7aa0 17758 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17759 }
17760}
17761
32ec8896 17762static signed int
351cdf24
MF
17763get_mips_reg_size (int reg_size)
17764{
17765 return (reg_size == AFL_REG_NONE) ? 0
17766 : (reg_size == AFL_REG_32) ? 32
17767 : (reg_size == AFL_REG_64) ? 64
17768 : (reg_size == AFL_REG_128) ? 128
17769 : -1;
17770}
17771
015dc7e1 17772static bool
dda8d76d 17773process_mips_specific (Filedata * filedata)
5b18a4bc 17774{
2cf0635d 17775 Elf_Internal_Dyn * entry;
351cdf24 17776 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17777 size_t liblist_offset = 0;
17778 size_t liblistno = 0;
17779 size_t conflictsno = 0;
17780 size_t options_offset = 0;
17781 size_t conflicts_offset = 0;
861fb55a
DJ
17782 size_t pltrelsz = 0;
17783 size_t pltrel = 0;
ccb4c951 17784 bfd_vma pltgot = 0;
861fb55a
DJ
17785 bfd_vma mips_pltgot = 0;
17786 bfd_vma jmprel = 0;
ccb4c951
RS
17787 bfd_vma local_gotno = 0;
17788 bfd_vma gotsym = 0;
17789 bfd_vma symtabno = 0;
015dc7e1 17790 bool res = true;
103f02d3 17791
dda8d76d 17792 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17793 display_mips_gnu_attribute))
015dc7e1 17794 res = false;
2cf19d5c 17795
dda8d76d 17796 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17797
17798 if (sect != NULL)
17799 {
17800 Elf_External_ABIFlags_v0 *abiflags_ext;
17801 Elf_Internal_ABIFlags_v0 abiflags_in;
17802
17803 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17804 {
17805 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17806 res = false;
32ec8896 17807 }
351cdf24
MF
17808 else
17809 {
dda8d76d 17810 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17811 sect->sh_size, _("MIPS ABI Flags section"));
17812 if (abiflags_ext)
17813 {
17814 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17815 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17816 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17817 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17818 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17819 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17820 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17821 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17822 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17823 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17824 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17825
17826 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17827 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17828 if (abiflags_in.isa_rev > 1)
17829 printf ("r%d", abiflags_in.isa_rev);
17830 printf ("\nGPR size: %d",
17831 get_mips_reg_size (abiflags_in.gpr_size));
17832 printf ("\nCPR1 size: %d",
17833 get_mips_reg_size (abiflags_in.cpr1_size));
17834 printf ("\nCPR2 size: %d",
17835 get_mips_reg_size (abiflags_in.cpr2_size));
17836 fputs ("\nFP ABI: ", stdout);
17837 print_mips_fp_abi_value (abiflags_in.fp_abi);
17838 fputs ("ISA Extension: ", stdout);
17839 print_mips_isa_ext (abiflags_in.isa_ext);
17840 fputs ("\nASEs:", stdout);
17841 print_mips_ases (abiflags_in.ases);
17842 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17843 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17844 fputc ('\n', stdout);
17845 free (abiflags_ext);
17846 }
17847 }
17848 }
17849
19e6b90e 17850 /* We have a lot of special sections. Thanks SGI! */
978c4450 17851 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17852 {
17853 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17854 sect = find_section (filedata, ".got");
bbdd9a68
MR
17855 if (sect != NULL)
17856 {
17857 unsigned char *data_end;
17858 unsigned char *data;
17859 bfd_vma ent, end;
17860 int addr_size;
17861
17862 pltgot = sect->sh_addr;
17863
17864 ent = pltgot;
17865 addr_size = (is_32bit_elf ? 4 : 8);
17866 end = pltgot + sect->sh_size;
17867
dda8d76d 17868 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17869 end - pltgot, 1,
17870 _("Global Offset Table data"));
17871 /* PR 12855: Null data is handled gracefully throughout. */
17872 data_end = data + (end - pltgot);
17873
17874 printf (_("\nStatic GOT:\n"));
17875 printf (_(" Canonical gp value: "));
17876 print_vma (ent + 0x7ff0, LONG_HEX);
17877 printf ("\n\n");
17878
17879 /* In a dynamic binary GOT[0] is reserved for the dynamic
17880 loader to store the lazy resolver pointer, however in
17881 a static binary it may well have been omitted and GOT
17882 reduced to a table of addresses.
17883 PR 21344: Check for the entry being fully available
17884 before fetching it. */
17885 if (data
17886 && data + ent - pltgot + addr_size <= data_end
17887 && byte_get (data + ent - pltgot, addr_size) == 0)
17888 {
17889 printf (_(" Reserved entries:\n"));
17890 printf (_(" %*s %10s %*s\n"),
17891 addr_size * 2, _("Address"), _("Access"),
17892 addr_size * 2, _("Value"));
17893 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17894 printf ("\n");
17895 if (ent == (bfd_vma) -1)
17896 goto sgot_print_fail;
17897
17898 /* Check for the MSB of GOT[1] being set, identifying a
17899 GNU object. This entry will be used by some runtime
17900 loaders, to store the module pointer. Otherwise this
17901 is an ordinary local entry.
17902 PR 21344: Check for the entry being fully available
17903 before fetching it. */
17904 if (data
17905 && data + ent - pltgot + addr_size <= data_end
17906 && (byte_get (data + ent - pltgot, addr_size)
17907 >> (addr_size * 8 - 1)) != 0)
17908 {
17909 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17910 printf ("\n");
17911 if (ent == (bfd_vma) -1)
17912 goto sgot_print_fail;
17913 }
17914 printf ("\n");
17915 }
17916
f17e9d8a 17917 if (data != NULL && ent < end)
bbdd9a68
MR
17918 {
17919 printf (_(" Local entries:\n"));
17920 printf (" %*s %10s %*s\n",
17921 addr_size * 2, _("Address"), _("Access"),
17922 addr_size * 2, _("Value"));
17923 while (ent < end)
17924 {
17925 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17926 printf ("\n");
17927 if (ent == (bfd_vma) -1)
17928 goto sgot_print_fail;
17929 }
17930 printf ("\n");
17931 }
17932
17933 sgot_print_fail:
9db70fc3 17934 free (data);
bbdd9a68
MR
17935 }
17936 return res;
17937 }
252b5132 17938
978c4450 17939 for (entry = filedata->dynamic_section;
071436c6 17940 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17941 (entry < filedata->dynamic_section + filedata->dynamic_nent
17942 && entry->d_tag != DT_NULL);
071436c6 17943 ++entry)
252b5132
RH
17944 switch (entry->d_tag)
17945 {
17946 case DT_MIPS_LIBLIST:
d93f0186 17947 liblist_offset
dda8d76d 17948 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17949 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17950 break;
17951 case DT_MIPS_LIBLISTNO:
17952 liblistno = entry->d_un.d_val;
17953 break;
17954 case DT_MIPS_OPTIONS:
dda8d76d 17955 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17956 break;
17957 case DT_MIPS_CONFLICT:
d93f0186 17958 conflicts_offset
dda8d76d 17959 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17960 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17961 break;
17962 case DT_MIPS_CONFLICTNO:
17963 conflictsno = entry->d_un.d_val;
17964 break;
ccb4c951 17965 case DT_PLTGOT:
861fb55a
DJ
17966 pltgot = entry->d_un.d_ptr;
17967 break;
ccb4c951
RS
17968 case DT_MIPS_LOCAL_GOTNO:
17969 local_gotno = entry->d_un.d_val;
17970 break;
17971 case DT_MIPS_GOTSYM:
17972 gotsym = entry->d_un.d_val;
17973 break;
17974 case DT_MIPS_SYMTABNO:
17975 symtabno = entry->d_un.d_val;
17976 break;
861fb55a
DJ
17977 case DT_MIPS_PLTGOT:
17978 mips_pltgot = entry->d_un.d_ptr;
17979 break;
17980 case DT_PLTREL:
17981 pltrel = entry->d_un.d_val;
17982 break;
17983 case DT_PLTRELSZ:
17984 pltrelsz = entry->d_un.d_val;
17985 break;
17986 case DT_JMPREL:
17987 jmprel = entry->d_un.d_ptr;
17988 break;
252b5132
RH
17989 default:
17990 break;
17991 }
17992
17993 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17994 {
2cf0635d 17995 Elf32_External_Lib * elib;
252b5132
RH
17996 size_t cnt;
17997
dda8d76d 17998 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17999 sizeof (Elf32_External_Lib),
18000 liblistno,
18001 _("liblist section data"));
a6e9f9df 18002 if (elib)
252b5132 18003 {
d3a49aa8
AM
18004 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18005 "\nSection '.liblist' contains %lu entries:\n",
18006 (unsigned long) liblistno),
a6e9f9df 18007 (unsigned long) liblistno);
2b692964 18008 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18009 stdout);
18010
18011 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18012 {
a6e9f9df 18013 Elf32_Lib liblist;
91d6fa6a 18014 time_t atime;
d5b07ef4 18015 char timebuf[128];
2cf0635d 18016 struct tm * tmp;
a6e9f9df
AM
18017
18018 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18019 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18020 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18021 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18022 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18023
91d6fa6a 18024 tmp = gmtime (&atime);
e9e44622
JJ
18025 snprintf (timebuf, sizeof (timebuf),
18026 "%04u-%02u-%02uT%02u:%02u:%02u",
18027 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18028 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18029
31104126 18030 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18031 if (valid_dynamic_name (filedata, liblist.l_name))
18032 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18033 else
2b692964 18034 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18035 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18036 liblist.l_version);
a6e9f9df
AM
18037
18038 if (liblist.l_flags == 0)
2b692964 18039 puts (_(" NONE"));
a6e9f9df
AM
18040 else
18041 {
18042 static const struct
252b5132 18043 {
2cf0635d 18044 const char * name;
a6e9f9df 18045 int bit;
252b5132 18046 }
a6e9f9df
AM
18047 l_flags_vals[] =
18048 {
18049 { " EXACT_MATCH", LL_EXACT_MATCH },
18050 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18051 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18052 { " EXPORTS", LL_EXPORTS },
18053 { " DELAY_LOAD", LL_DELAY_LOAD },
18054 { " DELTA", LL_DELTA }
18055 };
18056 int flags = liblist.l_flags;
18057 size_t fcnt;
18058
60bca95a 18059 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18060 if ((flags & l_flags_vals[fcnt].bit) != 0)
18061 {
18062 fputs (l_flags_vals[fcnt].name, stdout);
18063 flags ^= l_flags_vals[fcnt].bit;
18064 }
18065 if (flags != 0)
18066 printf (" %#x", (unsigned int) flags);
252b5132 18067
a6e9f9df
AM
18068 puts ("");
18069 }
252b5132 18070 }
252b5132 18071
a6e9f9df
AM
18072 free (elib);
18073 }
32ec8896 18074 else
015dc7e1 18075 res = false;
252b5132
RH
18076 }
18077
18078 if (options_offset != 0)
18079 {
2cf0635d 18080 Elf_External_Options * eopt;
252b5132
RH
18081 size_t offset;
18082 int cnt;
dda8d76d 18083 sect = filedata->section_headers;
252b5132
RH
18084
18085 /* Find the section header so that we get the size. */
dda8d76d 18086 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18087 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18088 if (sect == NULL)
18089 {
18090 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18091 return false;
071436c6 18092 }
7fc0c668
NC
18093 /* PR 24243 */
18094 if (sect->sh_size < sizeof (* eopt))
18095 {
18096 error (_("The MIPS options section is too small.\n"));
015dc7e1 18097 return false;
7fc0c668 18098 }
252b5132 18099
dda8d76d 18100 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18101 sect->sh_size, _("options"));
a6e9f9df 18102 if (eopt)
252b5132 18103 {
fd17d1e6 18104 Elf_Internal_Options option;
76da6bbe 18105
a6e9f9df 18106 offset = cnt = 0;
82b1b41b 18107 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18108 {
2cf0635d 18109 Elf_External_Options * eoption;
fd17d1e6 18110 unsigned int optsize;
252b5132 18111
a6e9f9df 18112 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18113
fd17d1e6 18114 optsize = BYTE_GET (eoption->size);
76da6bbe 18115
82b1b41b 18116 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18117 if (optsize < sizeof (* eopt)
18118 || optsize > sect->sh_size - offset)
82b1b41b 18119 {
645f43a8 18120 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18121 optsize);
645f43a8 18122 free (eopt);
015dc7e1 18123 return false;
82b1b41b 18124 }
fd17d1e6 18125 offset += optsize;
a6e9f9df
AM
18126 ++cnt;
18127 }
252b5132 18128
d3a49aa8
AM
18129 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18130 "\nSection '%s' contains %d entries:\n",
18131 cnt),
dda8d76d 18132 printable_section_name (filedata, sect), cnt);
76da6bbe 18133
82b1b41b 18134 offset = 0;
a6e9f9df 18135 while (cnt-- > 0)
252b5132 18136 {
a6e9f9df 18137 size_t len;
fd17d1e6
AM
18138 Elf_External_Options * eoption;
18139
18140 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18141
18142 option.kind = BYTE_GET (eoption->kind);
18143 option.size = BYTE_GET (eoption->size);
18144 option.section = BYTE_GET (eoption->section);
18145 option.info = BYTE_GET (eoption->info);
a6e9f9df 18146
fd17d1e6 18147 switch (option.kind)
252b5132 18148 {
a6e9f9df
AM
18149 case ODK_NULL:
18150 /* This shouldn't happen. */
d0c4e780 18151 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18152 option.section, option.info);
a6e9f9df 18153 break;
2e6be59c 18154
a6e9f9df
AM
18155 case ODK_REGINFO:
18156 printf (" REGINFO ");
dda8d76d 18157 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18158 {
2cf0635d 18159 Elf32_External_RegInfo * ereg;
b34976b6 18160 Elf32_RegInfo reginfo;
a6e9f9df 18161
2e6be59c 18162 /* 32bit form. */
fd17d1e6
AM
18163 if (option.size < (sizeof (Elf_External_Options)
18164 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18165 {
18166 printf (_("<corrupt>\n"));
18167 error (_("Truncated MIPS REGINFO option\n"));
18168 cnt = 0;
18169 break;
18170 }
18171
fd17d1e6 18172 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18173
a6e9f9df
AM
18174 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18175 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18176 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18177 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18178 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18179 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18180
d0c4e780
AM
18181 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18182 reginfo.ri_gprmask, reginfo.ri_gp_value);
18183 printf (" "
18184 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18185 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18186 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18187 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18188 }
18189 else
18190 {
18191 /* 64 bit form. */
2cf0635d 18192 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18193 Elf64_Internal_RegInfo reginfo;
18194
fd17d1e6
AM
18195 if (option.size < (sizeof (Elf_External_Options)
18196 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18197 {
18198 printf (_("<corrupt>\n"));
18199 error (_("Truncated MIPS REGINFO option\n"));
18200 cnt = 0;
18201 break;
18202 }
18203
fd17d1e6 18204 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18205 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18206 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18207 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18208 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18209 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18210 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18211
d0c4e780
AM
18212 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18213 reginfo.ri_gprmask, reginfo.ri_gp_value);
18214 printf (" "
18215 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18216 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18217 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18218 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18219 }
fd17d1e6 18220 offset += option.size;
a6e9f9df 18221 continue;
2e6be59c 18222
a6e9f9df
AM
18223 case ODK_EXCEPTIONS:
18224 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18225 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18226 fputs (") fpe_max(", stdout);
fd17d1e6 18227 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18228 fputs (")", stdout);
18229
fd17d1e6 18230 if (option.info & OEX_PAGE0)
a6e9f9df 18231 fputs (" PAGE0", stdout);
fd17d1e6 18232 if (option.info & OEX_SMM)
a6e9f9df 18233 fputs (" SMM", stdout);
fd17d1e6 18234 if (option.info & OEX_FPDBUG)
a6e9f9df 18235 fputs (" FPDBUG", stdout);
fd17d1e6 18236 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18237 fputs (" DISMISS", stdout);
18238 break;
2e6be59c 18239
a6e9f9df
AM
18240 case ODK_PAD:
18241 fputs (" PAD ", stdout);
fd17d1e6 18242 if (option.info & OPAD_PREFIX)
a6e9f9df 18243 fputs (" PREFIX", stdout);
fd17d1e6 18244 if (option.info & OPAD_POSTFIX)
a6e9f9df 18245 fputs (" POSTFIX", stdout);
fd17d1e6 18246 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18247 fputs (" SYMBOL", stdout);
18248 break;
2e6be59c 18249
a6e9f9df
AM
18250 case ODK_HWPATCH:
18251 fputs (" HWPATCH ", stdout);
fd17d1e6 18252 if (option.info & OHW_R4KEOP)
a6e9f9df 18253 fputs (" R4KEOP", stdout);
fd17d1e6 18254 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18255 fputs (" R8KPFETCH", stdout);
fd17d1e6 18256 if (option.info & OHW_R5KEOP)
a6e9f9df 18257 fputs (" R5KEOP", stdout);
fd17d1e6 18258 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18259 fputs (" R5KCVTL", stdout);
18260 break;
2e6be59c 18261
a6e9f9df
AM
18262 case ODK_FILL:
18263 fputs (" FILL ", stdout);
18264 /* XXX Print content of info word? */
18265 break;
2e6be59c 18266
a6e9f9df
AM
18267 case ODK_TAGS:
18268 fputs (" TAGS ", stdout);
18269 /* XXX Print content of info word? */
18270 break;
2e6be59c 18271
a6e9f9df
AM
18272 case ODK_HWAND:
18273 fputs (" HWAND ", stdout);
fd17d1e6 18274 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18275 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18276 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18277 fputs (" R4KEOP_CLEAN", stdout);
18278 break;
2e6be59c 18279
a6e9f9df
AM
18280 case ODK_HWOR:
18281 fputs (" HWOR ", stdout);
fd17d1e6 18282 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18283 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18284 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18285 fputs (" R4KEOP_CLEAN", stdout);
18286 break;
2e6be59c 18287
a6e9f9df 18288 case ODK_GP_GROUP:
d0c4e780 18289 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18290 option.info & OGP_GROUP,
18291 (option.info & OGP_SELF) >> 16);
a6e9f9df 18292 break;
2e6be59c 18293
a6e9f9df 18294 case ODK_IDENT:
d0c4e780 18295 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18296 option.info & OGP_GROUP,
18297 (option.info & OGP_SELF) >> 16);
a6e9f9df 18298 break;
2e6be59c 18299
a6e9f9df
AM
18300 default:
18301 /* This shouldn't happen. */
d0c4e780 18302 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18303 option.kind, option.section, option.info);
a6e9f9df 18304 break;
252b5132 18305 }
a6e9f9df 18306
2cf0635d 18307 len = sizeof (* eopt);
fd17d1e6 18308 while (len < option.size)
82b1b41b 18309 {
fd17d1e6 18310 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18311
82b1b41b
NC
18312 if (ISPRINT (datum))
18313 printf ("%c", datum);
18314 else
18315 printf ("\\%03o", datum);
18316 len ++;
18317 }
a6e9f9df 18318 fputs ("\n", stdout);
82b1b41b 18319
fd17d1e6 18320 offset += option.size;
252b5132 18321 }
a6e9f9df 18322 free (eopt);
252b5132 18323 }
32ec8896 18324 else
015dc7e1 18325 res = false;
252b5132
RH
18326 }
18327
18328 if (conflicts_offset != 0 && conflictsno != 0)
18329 {
2cf0635d 18330 Elf32_Conflict * iconf;
252b5132
RH
18331 size_t cnt;
18332
978c4450 18333 if (filedata->dynamic_symbols == NULL)
252b5132 18334 {
591a748a 18335 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18336 return false;
252b5132
RH
18337 }
18338
7296a62a
NC
18339 /* PR 21345 - print a slightly more helpful error message
18340 if we are sure that the cmalloc will fail. */
645f43a8 18341 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18342 {
18343 error (_("Overlarge number of conflicts detected: %lx\n"),
18344 (long) conflictsno);
015dc7e1 18345 return false;
7296a62a
NC
18346 }
18347
3f5e193b 18348 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18349 if (iconf == NULL)
18350 {
8b73c356 18351 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18352 return false;
252b5132
RH
18353 }
18354
9ea033b2 18355 if (is_32bit_elf)
252b5132 18356 {
2cf0635d 18357 Elf32_External_Conflict * econf32;
a6e9f9df 18358
3f5e193b 18359 econf32 = (Elf32_External_Conflict *)
95099889
AM
18360 get_data (NULL, filedata, conflicts_offset,
18361 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18362 if (!econf32)
5a814d6d
AM
18363 {
18364 free (iconf);
015dc7e1 18365 return false;
5a814d6d 18366 }
252b5132
RH
18367
18368 for (cnt = 0; cnt < conflictsno; ++cnt)
18369 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18370
18371 free (econf32);
252b5132
RH
18372 }
18373 else
18374 {
2cf0635d 18375 Elf64_External_Conflict * econf64;
a6e9f9df 18376
3f5e193b 18377 econf64 = (Elf64_External_Conflict *)
95099889
AM
18378 get_data (NULL, filedata, conflicts_offset,
18379 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18380 if (!econf64)
5a814d6d
AM
18381 {
18382 free (iconf);
015dc7e1 18383 return false;
5a814d6d 18384 }
252b5132
RH
18385
18386 for (cnt = 0; cnt < conflictsno; ++cnt)
18387 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18388
18389 free (econf64);
252b5132
RH
18390 }
18391
d3a49aa8
AM
18392 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18393 "\nSection '.conflict' contains %lu entries:\n",
18394 (unsigned long) conflictsno),
c7e7ca54 18395 (unsigned long) conflictsno);
252b5132
RH
18396 puts (_(" Num: Index Value Name"));
18397
18398 for (cnt = 0; cnt < conflictsno; ++cnt)
18399 {
b34976b6 18400 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18401
978c4450 18402 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18403 printf (_("<corrupt symbol index>"));
d79b3d50 18404 else
e0a31db1
NC
18405 {
18406 Elf_Internal_Sym * psym;
18407
978c4450 18408 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18409 print_vma (psym->st_value, FULL_HEX);
18410 putchar (' ');
84714f86
AM
18411 if (valid_dynamic_name (filedata, psym->st_name))
18412 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18413 else
18414 printf (_("<corrupt: %14ld>"), psym->st_name);
18415 }
31104126 18416 putchar ('\n');
252b5132
RH
18417 }
18418
252b5132
RH
18419 free (iconf);
18420 }
18421
ccb4c951
RS
18422 if (pltgot != 0 && local_gotno != 0)
18423 {
91d6fa6a 18424 bfd_vma ent, local_end, global_end;
bbeee7ea 18425 size_t i, offset;
2cf0635d 18426 unsigned char * data;
82b1b41b 18427 unsigned char * data_end;
bbeee7ea 18428 int addr_size;
ccb4c951 18429
91d6fa6a 18430 ent = pltgot;
ccb4c951
RS
18431 addr_size = (is_32bit_elf ? 4 : 8);
18432 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18433
74e1a04b
NC
18434 /* PR binutils/17533 file: 012-111227-0.004 */
18435 if (symtabno < gotsym)
18436 {
18437 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18438 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18439 return false;
74e1a04b 18440 }
82b1b41b 18441
74e1a04b 18442 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18443 /* PR 17531: file: 54c91a34. */
18444 if (global_end < local_end)
18445 {
18446 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18447 return false;
82b1b41b 18448 }
948f632f 18449
dda8d76d
NC
18450 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18451 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18452 global_end - pltgot, 1,
18453 _("Global Offset Table data"));
919383ac 18454 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18455 data_end = data + (global_end - pltgot);
59245841 18456
ccb4c951
RS
18457 printf (_("\nPrimary GOT:\n"));
18458 printf (_(" Canonical gp value: "));
18459 print_vma (pltgot + 0x7ff0, LONG_HEX);
18460 printf ("\n\n");
18461
18462 printf (_(" Reserved entries:\n"));
18463 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18464 addr_size * 2, _("Address"), _("Access"),
18465 addr_size * 2, _("Initial"));
82b1b41b 18466 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18467 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18468 if (ent == (bfd_vma) -1)
18469 goto got_print_fail;
75ec1fdb 18470
c4ab9505
MR
18471 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18472 This entry will be used by some runtime loaders, to store the
18473 module pointer. Otherwise this is an ordinary local entry.
18474 PR 21344: Check for the entry being fully available before
18475 fetching it. */
18476 if (data
18477 && data + ent - pltgot + addr_size <= data_end
18478 && (byte_get (data + ent - pltgot, addr_size)
18479 >> (addr_size * 8 - 1)) != 0)
18480 {
18481 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18482 printf (_(" Module pointer (GNU extension)\n"));
18483 if (ent == (bfd_vma) -1)
18484 goto got_print_fail;
ccb4c951
RS
18485 }
18486 printf ("\n");
18487
f17e9d8a 18488 if (data != NULL && ent < local_end)
ccb4c951
RS
18489 {
18490 printf (_(" Local entries:\n"));
cc5914eb 18491 printf (" %*s %10s %*s\n",
2b692964
NC
18492 addr_size * 2, _("Address"), _("Access"),
18493 addr_size * 2, _("Initial"));
91d6fa6a 18494 while (ent < local_end)
ccb4c951 18495 {
82b1b41b 18496 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18497 printf ("\n");
82b1b41b
NC
18498 if (ent == (bfd_vma) -1)
18499 goto got_print_fail;
ccb4c951
RS
18500 }
18501 printf ("\n");
18502 }
18503
f17e9d8a 18504 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18505 {
18506 int sym_width;
18507
18508 printf (_(" Global entries:\n"));
cc5914eb 18509 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18510 addr_size * 2, _("Address"),
18511 _("Access"),
2b692964 18512 addr_size * 2, _("Initial"),
9cf03b7e
NC
18513 addr_size * 2, _("Sym.Val."),
18514 _("Type"),
18515 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18516 _("Ndx"), _("Name"));
0b4362b0 18517
ccb4c951 18518 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18519
ccb4c951
RS
18520 for (i = gotsym; i < symtabno; i++)
18521 {
82b1b41b 18522 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18523 printf (" ");
e0a31db1 18524
978c4450 18525 if (filedata->dynamic_symbols == NULL)
e0a31db1 18526 printf (_("<no dynamic symbols>"));
978c4450 18527 else if (i < filedata->num_dynamic_syms)
e0a31db1 18528 {
978c4450 18529 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18530
18531 print_vma (psym->st_value, LONG_HEX);
18532 printf (" %-7s %3s ",
dda8d76d
NC
18533 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18534 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18535
84714f86 18536 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18537 print_symbol (sym_width,
84714f86 18538 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18539 else
18540 printf (_("<corrupt: %14ld>"), psym->st_name);
18541 }
ccb4c951 18542 else
7fc5ac57
JBG
18543 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18544 (unsigned long) i);
e0a31db1 18545
ccb4c951 18546 printf ("\n");
82b1b41b
NC
18547 if (ent == (bfd_vma) -1)
18548 break;
ccb4c951
RS
18549 }
18550 printf ("\n");
18551 }
18552
82b1b41b 18553 got_print_fail:
9db70fc3 18554 free (data);
ccb4c951
RS
18555 }
18556
861fb55a
DJ
18557 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18558 {
91d6fa6a 18559 bfd_vma ent, end;
861fb55a
DJ
18560 size_t offset, rel_offset;
18561 unsigned long count, i;
2cf0635d 18562 unsigned char * data;
861fb55a 18563 int addr_size, sym_width;
2cf0635d 18564 Elf_Internal_Rela * rels;
861fb55a 18565
dda8d76d 18566 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18567 if (pltrel == DT_RELA)
18568 {
dda8d76d 18569 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18570 return false;
861fb55a
DJ
18571 }
18572 else
18573 {
dda8d76d 18574 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18575 return false;
861fb55a
DJ
18576 }
18577
91d6fa6a 18578 ent = mips_pltgot;
861fb55a
DJ
18579 addr_size = (is_32bit_elf ? 4 : 8);
18580 end = mips_pltgot + (2 + count) * addr_size;
18581
dda8d76d
NC
18582 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18583 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18584 1, _("Procedure Linkage Table data"));
59245841 18585 if (data == NULL)
288f0ba2
AM
18586 {
18587 free (rels);
015dc7e1 18588 return false;
288f0ba2 18589 }
59245841 18590
9cf03b7e 18591 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18592 printf (_(" Reserved entries:\n"));
18593 printf (_(" %*s %*s Purpose\n"),
2b692964 18594 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18595 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18596 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18597 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18598 printf (_(" Module pointer\n"));
861fb55a
DJ
18599 printf ("\n");
18600
18601 printf (_(" Entries:\n"));
cc5914eb 18602 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18603 addr_size * 2, _("Address"),
18604 addr_size * 2, _("Initial"),
18605 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18606 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18607 for (i = 0; i < count; i++)
18608 {
df97ab2a 18609 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18610
91d6fa6a 18611 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18612 printf (" ");
e0a31db1 18613
978c4450 18614 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18615 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18616 else
e0a31db1 18617 {
978c4450 18618 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18619
18620 print_vma (psym->st_value, LONG_HEX);
18621 printf (" %-7s %3s ",
dda8d76d
NC
18622 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18623 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 18624 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18625 print_symbol (sym_width,
84714f86 18626 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18627 else
18628 printf (_("<corrupt: %14ld>"), psym->st_name);
18629 }
861fb55a
DJ
18630 printf ("\n");
18631 }
18632 printf ("\n");
18633
9db70fc3 18634 free (data);
861fb55a
DJ
18635 free (rels);
18636 }
18637
32ec8896 18638 return res;
252b5132
RH
18639}
18640
015dc7e1 18641static bool
dda8d76d 18642process_nds32_specific (Filedata * filedata)
35c08157
KLC
18643{
18644 Elf_Internal_Shdr *sect = NULL;
18645
dda8d76d 18646 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18647 if (sect != NULL && sect->sh_size >= 4)
35c08157 18648 {
9c7b8e9b
AM
18649 unsigned char *buf;
18650 unsigned int flag;
35c08157
KLC
18651
18652 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18653 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18654 _("NDS32 elf flags section"));
35c08157 18655
9c7b8e9b 18656 if (buf == NULL)
015dc7e1 18657 return false;
32ec8896 18658
9c7b8e9b
AM
18659 flag = byte_get (buf, 4);
18660 free (buf);
18661 switch (flag & 0x3)
35c08157
KLC
18662 {
18663 case 0:
18664 printf ("(VEC_SIZE):\tNo entry.\n");
18665 break;
18666 case 1:
18667 printf ("(VEC_SIZE):\t4 bytes\n");
18668 break;
18669 case 2:
18670 printf ("(VEC_SIZE):\t16 bytes\n");
18671 break;
18672 case 3:
18673 printf ("(VEC_SIZE):\treserved\n");
18674 break;
18675 }
18676 }
18677
015dc7e1 18678 return true;
35c08157
KLC
18679}
18680
015dc7e1 18681static bool
dda8d76d 18682process_gnu_liblist (Filedata * filedata)
047b2264 18683{
2cf0635d
NC
18684 Elf_Internal_Shdr * section;
18685 Elf_Internal_Shdr * string_sec;
18686 Elf32_External_Lib * elib;
18687 char * strtab;
c256ffe7 18688 size_t strtab_size;
047b2264 18689 size_t cnt;
d3a49aa8 18690 unsigned long num_liblist;
047b2264 18691 unsigned i;
015dc7e1 18692 bool res = true;
047b2264
JJ
18693
18694 if (! do_arch)
015dc7e1 18695 return true;
047b2264 18696
dda8d76d
NC
18697 for (i = 0, section = filedata->section_headers;
18698 i < filedata->file_header.e_shnum;
b34976b6 18699 i++, section++)
047b2264
JJ
18700 {
18701 switch (section->sh_type)
18702 {
18703 case SHT_GNU_LIBLIST:
dda8d76d 18704 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18705 break;
18706
3f5e193b 18707 elib = (Elf32_External_Lib *)
dda8d76d 18708 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18709 _("liblist section data"));
047b2264
JJ
18710
18711 if (elib == NULL)
32ec8896 18712 {
015dc7e1 18713 res = false;
32ec8896
NC
18714 break;
18715 }
047b2264 18716
dda8d76d
NC
18717 string_sec = filedata->section_headers + section->sh_link;
18718 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18719 string_sec->sh_size,
18720 _("liblist string table"));
047b2264
JJ
18721 if (strtab == NULL
18722 || section->sh_entsize != sizeof (Elf32_External_Lib))
18723 {
18724 free (elib);
2842702f 18725 free (strtab);
015dc7e1 18726 res = false;
047b2264
JJ
18727 break;
18728 }
59245841 18729 strtab_size = string_sec->sh_size;
047b2264 18730
d3a49aa8
AM
18731 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18732 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18733 "\nLibrary list section '%s' contains %lu entries:\n",
18734 num_liblist),
dda8d76d 18735 printable_section_name (filedata, section),
d3a49aa8 18736 num_liblist);
047b2264 18737
2b692964 18738 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18739
18740 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18741 ++cnt)
18742 {
18743 Elf32_Lib liblist;
91d6fa6a 18744 time_t atime;
d5b07ef4 18745 char timebuf[128];
2cf0635d 18746 struct tm * tmp;
047b2264
JJ
18747
18748 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18749 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18750 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18751 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18752 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18753
91d6fa6a 18754 tmp = gmtime (&atime);
e9e44622
JJ
18755 snprintf (timebuf, sizeof (timebuf),
18756 "%04u-%02u-%02uT%02u:%02u:%02u",
18757 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18758 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18759
18760 printf ("%3lu: ", (unsigned long) cnt);
18761 if (do_wide)
c256ffe7 18762 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18763 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18764 else
c256ffe7 18765 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18766 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18767 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18768 liblist.l_version, liblist.l_flags);
18769 }
18770
18771 free (elib);
2842702f 18772 free (strtab);
047b2264
JJ
18773 }
18774 }
18775
32ec8896 18776 return res;
047b2264
JJ
18777}
18778
9437c45b 18779static const char *
dda8d76d 18780get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18781{
18782 static char buff[64];
103f02d3 18783
dda8d76d 18784 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18785 switch (e_type)
18786 {
57346661 18787 case NT_AUXV:
1ec5cd37 18788 return _("NT_AUXV (auxiliary vector)");
57346661 18789 case NT_PRSTATUS:
1ec5cd37 18790 return _("NT_PRSTATUS (prstatus structure)");
57346661 18791 case NT_FPREGSET:
1ec5cd37 18792 return _("NT_FPREGSET (floating point registers)");
57346661 18793 case NT_PRPSINFO:
1ec5cd37 18794 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18795 case NT_TASKSTRUCT:
1ec5cd37 18796 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18797 case NT_GDB_TDESC:
18798 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18799 case NT_PRXFPREG:
1ec5cd37 18800 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18801 case NT_PPC_VMX:
18802 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18803 case NT_PPC_VSX:
18804 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18805 case NT_PPC_TAR:
18806 return _("NT_PPC_TAR (ppc TAR register)");
18807 case NT_PPC_PPR:
18808 return _("NT_PPC_PPR (ppc PPR register)");
18809 case NT_PPC_DSCR:
18810 return _("NT_PPC_DSCR (ppc DSCR register)");
18811 case NT_PPC_EBB:
18812 return _("NT_PPC_EBB (ppc EBB registers)");
18813 case NT_PPC_PMU:
18814 return _("NT_PPC_PMU (ppc PMU registers)");
18815 case NT_PPC_TM_CGPR:
18816 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18817 case NT_PPC_TM_CFPR:
18818 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18819 case NT_PPC_TM_CVMX:
18820 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18821 case NT_PPC_TM_CVSX:
3fd21718 18822 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18823 case NT_PPC_TM_SPR:
18824 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18825 case NT_PPC_TM_CTAR:
18826 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18827 case NT_PPC_TM_CPPR:
18828 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18829 case NT_PPC_TM_CDSCR:
18830 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18831 case NT_386_TLS:
18832 return _("NT_386_TLS (x86 TLS information)");
18833 case NT_386_IOPERM:
18834 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18835 case NT_X86_XSTATE:
18836 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18837 case NT_X86_CET:
18838 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18839 case NT_S390_HIGH_GPRS:
18840 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18841 case NT_S390_TIMER:
18842 return _("NT_S390_TIMER (s390 timer register)");
18843 case NT_S390_TODCMP:
18844 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18845 case NT_S390_TODPREG:
18846 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18847 case NT_S390_CTRS:
18848 return _("NT_S390_CTRS (s390 control registers)");
18849 case NT_S390_PREFIX:
18850 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18851 case NT_S390_LAST_BREAK:
18852 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18853 case NT_S390_SYSTEM_CALL:
18854 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18855 case NT_S390_TDB:
18856 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18857 case NT_S390_VXRS_LOW:
18858 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18859 case NT_S390_VXRS_HIGH:
18860 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18861 case NT_S390_GS_CB:
18862 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18863 case NT_S390_GS_BC:
18864 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18865 case NT_ARM_VFP:
18866 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18867 case NT_ARM_TLS:
18868 return _("NT_ARM_TLS (AArch TLS registers)");
18869 case NT_ARM_HW_BREAK:
18870 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18871 case NT_ARM_HW_WATCH:
18872 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18873 case NT_ARM_SVE:
18874 return _("NT_ARM_SVE (AArch SVE registers)");
18875 case NT_ARM_PAC_MASK:
18876 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
18877 case NT_ARM_PACA_KEYS:
18878 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
18879 case NT_ARM_PACG_KEYS:
18880 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
18881 case NT_ARM_TAGGED_ADDR_CTRL:
18882 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
18883 case NT_ARM_PAC_ENABLED_KEYS:
18884 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
18885 case NT_ARC_V2:
18886 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18887 case NT_RISCV_CSR:
18888 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18889 case NT_PSTATUS:
1ec5cd37 18890 return _("NT_PSTATUS (pstatus structure)");
57346661 18891 case NT_FPREGS:
1ec5cd37 18892 return _("NT_FPREGS (floating point registers)");
57346661 18893 case NT_PSINFO:
1ec5cd37 18894 return _("NT_PSINFO (psinfo structure)");
57346661 18895 case NT_LWPSTATUS:
1ec5cd37 18896 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18897 case NT_LWPSINFO:
1ec5cd37 18898 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18899 case NT_WIN32PSTATUS:
1ec5cd37 18900 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18901 case NT_SIGINFO:
18902 return _("NT_SIGINFO (siginfo_t data)");
18903 case NT_FILE:
18904 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18905 default:
18906 break;
18907 }
18908 else
18909 switch (e_type)
18910 {
18911 case NT_VERSION:
18912 return _("NT_VERSION (version)");
18913 case NT_ARCH:
18914 return _("NT_ARCH (architecture)");
9ef920e9 18915 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18916 return _("OPEN");
9ef920e9 18917 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18918 return _("func");
c8795e1f
NC
18919 case NT_GO_BUILDID:
18920 return _("GO BUILDID");
1ec5cd37
NC
18921 default:
18922 break;
18923 }
18924
e9e44622 18925 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18926 return buff;
779fe533
NC
18927}
18928
015dc7e1 18929static bool
9ece1fa9
TT
18930print_core_note (Elf_Internal_Note *pnote)
18931{
18932 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18933 bfd_vma count, page_size;
18934 unsigned char *descdata, *filenames, *descend;
18935
18936 if (pnote->type != NT_FILE)
04ac15ab
AS
18937 {
18938 if (do_wide)
18939 printf ("\n");
015dc7e1 18940 return true;
04ac15ab 18941 }
9ece1fa9
TT
18942
18943#ifndef BFD64
18944 if (!is_32bit_elf)
18945 {
18946 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18947 /* Still "successful". */
015dc7e1 18948 return true;
9ece1fa9
TT
18949 }
18950#endif
18951
18952 if (pnote->descsz < 2 * addr_size)
18953 {
32ec8896 18954 error (_(" Malformed note - too short for header\n"));
015dc7e1 18955 return false;
9ece1fa9
TT
18956 }
18957
18958 descdata = (unsigned char *) pnote->descdata;
18959 descend = descdata + pnote->descsz;
18960
18961 if (descdata[pnote->descsz - 1] != '\0')
18962 {
32ec8896 18963 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18964 return false;
9ece1fa9
TT
18965 }
18966
18967 count = byte_get (descdata, addr_size);
18968 descdata += addr_size;
18969
18970 page_size = byte_get (descdata, addr_size);
18971 descdata += addr_size;
18972
5396a86e
AM
18973 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18974 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18975 {
32ec8896 18976 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18977 return false;
9ece1fa9
TT
18978 }
18979
18980 printf (_(" Page size: "));
18981 print_vma (page_size, DEC);
18982 printf ("\n");
18983
18984 printf (_(" %*s%*s%*s\n"),
18985 (int) (2 + 2 * addr_size), _("Start"),
18986 (int) (4 + 2 * addr_size), _("End"),
18987 (int) (4 + 2 * addr_size), _("Page Offset"));
18988 filenames = descdata + count * 3 * addr_size;
595712bb 18989 while (count-- > 0)
9ece1fa9
TT
18990 {
18991 bfd_vma start, end, file_ofs;
18992
18993 if (filenames == descend)
18994 {
32ec8896 18995 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18996 return false;
9ece1fa9
TT
18997 }
18998
18999 start = byte_get (descdata, addr_size);
19000 descdata += addr_size;
19001 end = byte_get (descdata, addr_size);
19002 descdata += addr_size;
19003 file_ofs = byte_get (descdata, addr_size);
19004 descdata += addr_size;
19005
19006 printf (" ");
19007 print_vma (start, FULL_HEX);
19008 printf (" ");
19009 print_vma (end, FULL_HEX);
19010 printf (" ");
19011 print_vma (file_ofs, FULL_HEX);
19012 printf ("\n %s\n", filenames);
19013
19014 filenames += 1 + strlen ((char *) filenames);
19015 }
19016
015dc7e1 19017 return true;
9ece1fa9
TT
19018}
19019
1118d252
RM
19020static const char *
19021get_gnu_elf_note_type (unsigned e_type)
19022{
1449284b 19023 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19024 switch (e_type)
19025 {
19026 case NT_GNU_ABI_TAG:
19027 return _("NT_GNU_ABI_TAG (ABI version tag)");
19028 case NT_GNU_HWCAP:
19029 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19030 case NT_GNU_BUILD_ID:
19031 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19032 case NT_GNU_GOLD_VERSION:
19033 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19034 case NT_GNU_PROPERTY_TYPE_0:
19035 return _("NT_GNU_PROPERTY_TYPE_0");
19036 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19037 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19038 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19039 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19040 default:
1449284b
NC
19041 {
19042 static char buff[64];
1118d252 19043
1449284b
NC
19044 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19045 return buff;
19046 }
19047 }
1118d252
RM
19048}
19049
a9eafb08
L
19050static void
19051decode_x86_compat_isa (unsigned int bitmask)
19052{
19053 while (bitmask)
19054 {
19055 unsigned int bit = bitmask & (- bitmask);
19056
19057 bitmask &= ~ bit;
19058 switch (bit)
19059 {
19060 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19061 printf ("i486");
19062 break;
19063 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19064 printf ("586");
19065 break;
19066 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19067 printf ("686");
19068 break;
19069 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19070 printf ("SSE");
19071 break;
19072 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19073 printf ("SSE2");
19074 break;
19075 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19076 printf ("SSE3");
19077 break;
19078 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19079 printf ("SSSE3");
19080 break;
19081 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19082 printf ("SSE4_1");
19083 break;
19084 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19085 printf ("SSE4_2");
19086 break;
19087 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19088 printf ("AVX");
19089 break;
19090 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19091 printf ("AVX2");
19092 break;
19093 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19094 printf ("AVX512F");
19095 break;
19096 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19097 printf ("AVX512CD");
19098 break;
19099 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19100 printf ("AVX512ER");
19101 break;
19102 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19103 printf ("AVX512PF");
19104 break;
19105 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19106 printf ("AVX512VL");
19107 break;
19108 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19109 printf ("AVX512DQ");
19110 break;
19111 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19112 printf ("AVX512BW");
19113 break;
65b3d26e
L
19114 default:
19115 printf (_("<unknown: %x>"), bit);
19116 break;
a9eafb08
L
19117 }
19118 if (bitmask)
19119 printf (", ");
19120 }
19121}
19122
9ef920e9 19123static void
32930e4e 19124decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19125{
0a59decb 19126 if (!bitmask)
90c745dc
L
19127 {
19128 printf (_("<None>"));
19129 return;
19130 }
90c745dc 19131
9ef920e9
NC
19132 while (bitmask)
19133 {
1fc87489 19134 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19135
19136 bitmask &= ~ bit;
19137 switch (bit)
19138 {
32930e4e 19139 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19140 printf ("CMOV");
19141 break;
32930e4e 19142 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19143 printf ("SSE");
19144 break;
32930e4e 19145 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19146 printf ("SSE2");
19147 break;
32930e4e 19148 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19149 printf ("SSE3");
19150 break;
32930e4e 19151 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19152 printf ("SSSE3");
19153 break;
32930e4e 19154 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19155 printf ("SSE4_1");
19156 break;
32930e4e 19157 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19158 printf ("SSE4_2");
19159 break;
32930e4e 19160 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19161 printf ("AVX");
19162 break;
32930e4e 19163 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19164 printf ("AVX2");
19165 break;
32930e4e 19166 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19167 printf ("FMA");
19168 break;
32930e4e 19169 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19170 printf ("AVX512F");
19171 break;
32930e4e 19172 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19173 printf ("AVX512CD");
19174 break;
32930e4e 19175 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19176 printf ("AVX512ER");
19177 break;
32930e4e 19178 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19179 printf ("AVX512PF");
19180 break;
32930e4e 19181 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19182 printf ("AVX512VL");
19183 break;
32930e4e 19184 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19185 printf ("AVX512DQ");
19186 break;
32930e4e 19187 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19188 printf ("AVX512BW");
19189 break;
32930e4e 19190 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19191 printf ("AVX512_4FMAPS");
19192 break;
32930e4e 19193 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19194 printf ("AVX512_4VNNIW");
19195 break;
32930e4e 19196 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19197 printf ("AVX512_BITALG");
19198 break;
32930e4e 19199 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19200 printf ("AVX512_IFMA");
19201 break;
32930e4e 19202 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19203 printf ("AVX512_VBMI");
19204 break;
32930e4e 19205 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19206 printf ("AVX512_VBMI2");
19207 break;
32930e4e 19208 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19209 printf ("AVX512_VNNI");
19210 break;
32930e4e 19211 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19212 printf ("AVX512_BF16");
19213 break;
65b3d26e
L
19214 default:
19215 printf (_("<unknown: %x>"), bit);
19216 break;
9ef920e9
NC
19217 }
19218 if (bitmask)
19219 printf (", ");
19220 }
19221}
19222
32930e4e
L
19223static void
19224decode_x86_isa (unsigned int bitmask)
19225{
32930e4e
L
19226 while (bitmask)
19227 {
19228 unsigned int bit = bitmask & (- bitmask);
19229
19230 bitmask &= ~ bit;
19231 switch (bit)
19232 {
b0ab0693
L
19233 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19234 printf ("x86-64-baseline");
19235 break;
32930e4e
L
19236 case GNU_PROPERTY_X86_ISA_1_V2:
19237 printf ("x86-64-v2");
19238 break;
19239 case GNU_PROPERTY_X86_ISA_1_V3:
19240 printf ("x86-64-v3");
19241 break;
19242 case GNU_PROPERTY_X86_ISA_1_V4:
19243 printf ("x86-64-v4");
19244 break;
19245 default:
19246 printf (_("<unknown: %x>"), bit);
19247 break;
19248 }
19249 if (bitmask)
19250 printf (", ");
19251 }
19252}
19253
ee2fdd6f 19254static void
a9eafb08 19255decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19256{
0a59decb 19257 if (!bitmask)
90c745dc
L
19258 {
19259 printf (_("<None>"));
19260 return;
19261 }
90c745dc 19262
ee2fdd6f
L
19263 while (bitmask)
19264 {
19265 unsigned int bit = bitmask & (- bitmask);
19266
19267 bitmask &= ~ bit;
19268 switch (bit)
19269 {
19270 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19271 printf ("IBT");
ee2fdd6f 19272 break;
48580982 19273 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19274 printf ("SHSTK");
48580982 19275 break;
279d901e
L
19276 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19277 printf ("LAM_U48");
19278 break;
19279 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19280 printf ("LAM_U57");
19281 break;
ee2fdd6f
L
19282 default:
19283 printf (_("<unknown: %x>"), bit);
19284 break;
19285 }
19286 if (bitmask)
19287 printf (", ");
19288 }
19289}
19290
a9eafb08
L
19291static void
19292decode_x86_feature_2 (unsigned int bitmask)
19293{
0a59decb 19294 if (!bitmask)
90c745dc
L
19295 {
19296 printf (_("<None>"));
19297 return;
19298 }
90c745dc 19299
a9eafb08
L
19300 while (bitmask)
19301 {
19302 unsigned int bit = bitmask & (- bitmask);
19303
19304 bitmask &= ~ bit;
19305 switch (bit)
19306 {
19307 case GNU_PROPERTY_X86_FEATURE_2_X86:
19308 printf ("x86");
19309 break;
19310 case GNU_PROPERTY_X86_FEATURE_2_X87:
19311 printf ("x87");
19312 break;
19313 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19314 printf ("MMX");
19315 break;
19316 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19317 printf ("XMM");
19318 break;
19319 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19320 printf ("YMM");
19321 break;
19322 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19323 printf ("ZMM");
19324 break;
a308b89d
L
19325 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19326 printf ("TMM");
19327 break;
32930e4e
L
19328 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19329 printf ("MASK");
19330 break;
a9eafb08
L
19331 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19332 printf ("FXSR");
19333 break;
19334 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19335 printf ("XSAVE");
19336 break;
19337 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19338 printf ("XSAVEOPT");
19339 break;
19340 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19341 printf ("XSAVEC");
19342 break;
65b3d26e
L
19343 default:
19344 printf (_("<unknown: %x>"), bit);
19345 break;
a9eafb08
L
19346 }
19347 if (bitmask)
19348 printf (", ");
19349 }
19350}
19351
cd702818
SD
19352static void
19353decode_aarch64_feature_1_and (unsigned int bitmask)
19354{
19355 while (bitmask)
19356 {
19357 unsigned int bit = bitmask & (- bitmask);
19358
19359 bitmask &= ~ bit;
19360 switch (bit)
19361 {
19362 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19363 printf ("BTI");
19364 break;
19365
19366 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19367 printf ("PAC");
19368 break;
19369
19370 default:
19371 printf (_("<unknown: %x>"), bit);
19372 break;
19373 }
19374 if (bitmask)
19375 printf (", ");
19376 }
19377}
19378
6320fd00
L
19379static void
19380decode_1_needed (unsigned int bitmask)
19381{
19382 while (bitmask)
19383 {
19384 unsigned int bit = bitmask & (- bitmask);
19385
19386 bitmask &= ~ bit;
19387 switch (bit)
19388 {
19389 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19390 printf ("indirect external access");
19391 break;
19392 default:
19393 printf (_("<unknown: %x>"), bit);
19394 break;
19395 }
19396 if (bitmask)
19397 printf (", ");
19398 }
19399}
19400
9ef920e9 19401static void
dda8d76d 19402print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19403{
19404 unsigned char * ptr = (unsigned char *) pnote->descdata;
19405 unsigned char * ptr_end = ptr + pnote->descsz;
19406 unsigned int size = is_32bit_elf ? 4 : 8;
19407
19408 printf (_(" Properties: "));
19409
1fc87489 19410 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19411 {
19412 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19413 return;
19414 }
19415
6ab2c4ed 19416 while (ptr < ptr_end)
9ef920e9 19417 {
1fc87489 19418 unsigned int j;
6ab2c4ed
MC
19419 unsigned int type;
19420 unsigned int datasz;
19421
19422 if ((size_t) (ptr_end - ptr) < 8)
19423 {
19424 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19425 break;
19426 }
19427
19428 type = byte_get (ptr, 4);
19429 datasz = byte_get (ptr + 4, 4);
9ef920e9 19430
1fc87489 19431 ptr += 8;
9ef920e9 19432
6ab2c4ed 19433 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19434 {
1fc87489
L
19435 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19436 type, datasz);
9ef920e9 19437 break;
1fc87489 19438 }
9ef920e9 19439
1fc87489
L
19440 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19441 {
dda8d76d
NC
19442 if (filedata->file_header.e_machine == EM_X86_64
19443 || filedata->file_header.e_machine == EM_IAMCU
19444 || filedata->file_header.e_machine == EM_386)
1fc87489 19445 {
aa7bca9b
L
19446 unsigned int bitmask;
19447
19448 if (datasz == 4)
0a59decb 19449 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19450 else
19451 bitmask = 0;
19452
1fc87489
L
19453 switch (type)
19454 {
19455 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19456 if (datasz != 4)
aa7bca9b
L
19457 printf (_("x86 ISA used: <corrupt length: %#x> "),
19458 datasz);
1fc87489 19459 else
aa7bca9b
L
19460 {
19461 printf ("x86 ISA used: ");
19462 decode_x86_isa (bitmask);
19463 }
1fc87489 19464 goto next;
9ef920e9 19465
1fc87489 19466 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19467 if (datasz != 4)
aa7bca9b
L
19468 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19469 datasz);
1fc87489 19470 else
aa7bca9b
L
19471 {
19472 printf ("x86 ISA needed: ");
19473 decode_x86_isa (bitmask);
19474 }
1fc87489 19475 goto next;
9ef920e9 19476
ee2fdd6f 19477 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19478 if (datasz != 4)
aa7bca9b
L
19479 printf (_("x86 feature: <corrupt length: %#x> "),
19480 datasz);
ee2fdd6f 19481 else
aa7bca9b
L
19482 {
19483 printf ("x86 feature: ");
a9eafb08
L
19484 decode_x86_feature_1 (bitmask);
19485 }
19486 goto next;
19487
19488 case GNU_PROPERTY_X86_FEATURE_2_USED:
19489 if (datasz != 4)
19490 printf (_("x86 feature used: <corrupt length: %#x> "),
19491 datasz);
19492 else
19493 {
19494 printf ("x86 feature used: ");
19495 decode_x86_feature_2 (bitmask);
19496 }
19497 goto next;
19498
19499 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19500 if (datasz != 4)
19501 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19502 else
19503 {
19504 printf ("x86 feature needed: ");
19505 decode_x86_feature_2 (bitmask);
19506 }
19507 goto next;
19508
19509 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19510 if (datasz != 4)
19511 printf (_("x86 ISA used: <corrupt length: %#x> "),
19512 datasz);
19513 else
19514 {
19515 printf ("x86 ISA used: ");
19516 decode_x86_compat_isa (bitmask);
19517 }
19518 goto next;
19519
19520 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19521 if (datasz != 4)
19522 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19523 datasz);
19524 else
19525 {
19526 printf ("x86 ISA needed: ");
19527 decode_x86_compat_isa (bitmask);
aa7bca9b 19528 }
ee2fdd6f
L
19529 goto next;
19530
32930e4e
L
19531 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19532 if (datasz != 4)
19533 printf (_("x86 ISA used: <corrupt length: %#x> "),
19534 datasz);
19535 else
19536 {
19537 printf ("x86 ISA used: ");
19538 decode_x86_compat_2_isa (bitmask);
19539 }
19540 goto next;
19541
19542 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19543 if (datasz != 4)
19544 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19545 datasz);
19546 else
19547 {
19548 printf ("x86 ISA needed: ");
19549 decode_x86_compat_2_isa (bitmask);
19550 }
19551 goto next;
19552
1fc87489
L
19553 default:
19554 break;
19555 }
19556 }
cd702818
SD
19557 else if (filedata->file_header.e_machine == EM_AARCH64)
19558 {
19559 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19560 {
19561 printf ("AArch64 feature: ");
19562 if (datasz != 4)
19563 printf (_("<corrupt length: %#x> "), datasz);
19564 else
19565 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19566 goto next;
19567 }
19568 }
1fc87489
L
19569 }
19570 else
19571 {
19572 switch (type)
9ef920e9 19573 {
1fc87489
L
19574 case GNU_PROPERTY_STACK_SIZE:
19575 printf (_("stack size: "));
19576 if (datasz != size)
19577 printf (_("<corrupt length: %#x> "), datasz);
19578 else
19579 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19580 goto next;
19581
19582 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19583 printf ("no copy on protected ");
19584 if (datasz)
19585 printf (_("<corrupt length: %#x> "), datasz);
19586 goto next;
19587
19588 default:
5a767724
L
19589 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19590 && type <= GNU_PROPERTY_UINT32_AND_HI)
19591 || (type >= GNU_PROPERTY_UINT32_OR_LO
19592 && type <= GNU_PROPERTY_UINT32_OR_HI))
19593 {
6320fd00
L
19594 switch (type)
19595 {
19596 case GNU_PROPERTY_1_NEEDED:
19597 if (datasz != 4)
19598 printf (_("1_needed: <corrupt length: %#x> "),
19599 datasz);
19600 else
19601 {
19602 unsigned int bitmask = byte_get (ptr, 4);
19603 printf ("1_needed: ");
19604 decode_1_needed (bitmask);
19605 }
19606 goto next;
19607
19608 default:
19609 break;
19610 }
5a767724
L
19611 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19612 printf (_("UINT32_AND (%#x): "), type);
19613 else
19614 printf (_("UINT32_OR (%#x): "), type);
19615 if (datasz != 4)
19616 printf (_("<corrupt length: %#x> "), datasz);
19617 else
19618 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19619 goto next;
19620 }
9ef920e9
NC
19621 break;
19622 }
9ef920e9
NC
19623 }
19624
1fc87489
L
19625 if (type < GNU_PROPERTY_LOPROC)
19626 printf (_("<unknown type %#x data: "), type);
19627 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19628 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19629 else
19630 printf (_("<application-specific type %#x data: "), type);
19631 for (j = 0; j < datasz; ++j)
19632 printf ("%02x ", ptr[j] & 0xff);
19633 printf (">");
19634
dc1e8a47 19635 next:
9ef920e9 19636 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19637 if (ptr == ptr_end)
19638 break;
1fc87489 19639
6ab2c4ed
MC
19640 if (do_wide)
19641 printf (", ");
19642 else
19643 printf ("\n\t");
9ef920e9
NC
19644 }
19645
19646 printf ("\n");
19647}
19648
015dc7e1 19649static bool
dda8d76d 19650print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19651{
1449284b 19652 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19653 switch (pnote->type)
19654 {
19655 case NT_GNU_BUILD_ID:
19656 {
19657 unsigned long i;
19658
19659 printf (_(" Build ID: "));
19660 for (i = 0; i < pnote->descsz; ++i)
19661 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19662 printf ("\n");
664f90a3
TT
19663 }
19664 break;
19665
19666 case NT_GNU_ABI_TAG:
19667 {
19668 unsigned long os, major, minor, subminor;
19669 const char *osname;
19670
3102e897
NC
19671 /* PR 17531: file: 030-599401-0.004. */
19672 if (pnote->descsz < 16)
19673 {
19674 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19675 break;
19676 }
19677
664f90a3
TT
19678 os = byte_get ((unsigned char *) pnote->descdata, 4);
19679 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19680 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19681 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19682
19683 switch (os)
19684 {
19685 case GNU_ABI_TAG_LINUX:
19686 osname = "Linux";
19687 break;
19688 case GNU_ABI_TAG_HURD:
19689 osname = "Hurd";
19690 break;
19691 case GNU_ABI_TAG_SOLARIS:
19692 osname = "Solaris";
19693 break;
19694 case GNU_ABI_TAG_FREEBSD:
19695 osname = "FreeBSD";
19696 break;
19697 case GNU_ABI_TAG_NETBSD:
19698 osname = "NetBSD";
19699 break;
14ae95f2
RM
19700 case GNU_ABI_TAG_SYLLABLE:
19701 osname = "Syllable";
19702 break;
19703 case GNU_ABI_TAG_NACL:
19704 osname = "NaCl";
19705 break;
664f90a3
TT
19706 default:
19707 osname = "Unknown";
19708 break;
19709 }
19710
19711 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19712 major, minor, subminor);
19713 }
19714 break;
926c5385
CC
19715
19716 case NT_GNU_GOLD_VERSION:
19717 {
19718 unsigned long i;
19719
19720 printf (_(" Version: "));
19721 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19722 printf ("%c", pnote->descdata[i]);
19723 printf ("\n");
19724 }
19725 break;
1449284b
NC
19726
19727 case NT_GNU_HWCAP:
19728 {
19729 unsigned long num_entries, mask;
19730
19731 /* Hardware capabilities information. Word 0 is the number of entries.
19732 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19733 is a series of entries, where each entry is a single byte followed
19734 by a nul terminated string. The byte gives the bit number to test
19735 if enabled in the bitmask. */
19736 printf (_(" Hardware Capabilities: "));
19737 if (pnote->descsz < 8)
19738 {
32ec8896 19739 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19740 return false;
1449284b
NC
19741 }
19742 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19743 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19744 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19745 /* FIXME: Add code to display the entries... */
19746 }
19747 break;
19748
9ef920e9 19749 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19750 print_gnu_property_note (filedata, pnote);
9ef920e9 19751 break;
9abca702 19752
1449284b
NC
19753 default:
19754 /* Handle unrecognised types. An error message should have already been
19755 created by get_gnu_elf_note_type(), so all that we need to do is to
19756 display the data. */
19757 {
19758 unsigned long i;
19759
19760 printf (_(" Description data: "));
19761 for (i = 0; i < pnote->descsz; ++i)
19762 printf ("%02x ", pnote->descdata[i] & 0xff);
19763 printf ("\n");
19764 }
19765 break;
664f90a3
TT
19766 }
19767
015dc7e1 19768 return true;
664f90a3
TT
19769}
19770
685080f2
NC
19771static const char *
19772get_v850_elf_note_type (enum v850_notes n_type)
19773{
19774 static char buff[64];
19775
19776 switch (n_type)
19777 {
19778 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19779 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19780 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19781 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19782 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19783 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19784 default:
19785 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19786 return buff;
19787 }
19788}
19789
015dc7e1 19790static bool
685080f2
NC
19791print_v850_note (Elf_Internal_Note * pnote)
19792{
19793 unsigned int val;
19794
19795 if (pnote->descsz != 4)
015dc7e1 19796 return false;
32ec8896 19797
685080f2
NC
19798 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19799
19800 if (val == 0)
19801 {
19802 printf (_("not set\n"));
015dc7e1 19803 return true;
685080f2
NC
19804 }
19805
19806 switch (pnote->type)
19807 {
19808 case V850_NOTE_ALIGNMENT:
19809 switch (val)
19810 {
015dc7e1
AM
19811 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19812 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19813 }
19814 break;
14ae95f2 19815
685080f2
NC
19816 case V850_NOTE_DATA_SIZE:
19817 switch (val)
19818 {
015dc7e1
AM
19819 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19820 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19821 }
19822 break;
14ae95f2 19823
685080f2
NC
19824 case V850_NOTE_FPU_INFO:
19825 switch (val)
19826 {
015dc7e1
AM
19827 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19828 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19829 }
19830 break;
14ae95f2 19831
685080f2
NC
19832 case V850_NOTE_MMU_INFO:
19833 case V850_NOTE_CACHE_INFO:
19834 case V850_NOTE_SIMD_INFO:
19835 if (val == EF_RH850_SIMD)
19836 {
19837 printf (_("yes\n"));
015dc7e1 19838 return true;
685080f2
NC
19839 }
19840 break;
19841
19842 default:
19843 /* An 'unknown note type' message will already have been displayed. */
19844 break;
19845 }
19846
19847 printf (_("unknown value: %x\n"), val);
015dc7e1 19848 return false;
685080f2
NC
19849}
19850
015dc7e1 19851static bool
c6056a74
SF
19852process_netbsd_elf_note (Elf_Internal_Note * pnote)
19853{
19854 unsigned int version;
19855
19856 switch (pnote->type)
19857 {
19858 case NT_NETBSD_IDENT:
b966f55f
AM
19859 if (pnote->descsz < 1)
19860 break;
c6056a74
SF
19861 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19862 if ((version / 10000) % 100)
b966f55f 19863 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19864 version, version / 100000000, (version / 1000000) % 100,
19865 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19866 'A' + (version / 10000) % 26);
c6056a74
SF
19867 else
19868 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19869 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19870 (version / 100) % 100);
015dc7e1 19871 return true;
c6056a74
SF
19872
19873 case NT_NETBSD_MARCH:
9abca702 19874 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19875 pnote->descdata);
015dc7e1 19876 return true;
c6056a74 19877
9abca702 19878 case NT_NETBSD_PAX:
b966f55f
AM
19879 if (pnote->descsz < 1)
19880 break;
9abca702
CZ
19881 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19882 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19883 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19884 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19885 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19886 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19887 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19888 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19889 return true;
c6056a74 19890 }
b966f55f
AM
19891
19892 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19893 pnote->descsz, pnote->type);
015dc7e1 19894 return false;
c6056a74
SF
19895}
19896
f4ddf30f 19897static const char *
dda8d76d 19898get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19899{
f4ddf30f
JB
19900 switch (e_type)
19901 {
19902 case NT_FREEBSD_THRMISC:
19903 return _("NT_THRMISC (thrmisc structure)");
19904 case NT_FREEBSD_PROCSTAT_PROC:
19905 return _("NT_PROCSTAT_PROC (proc data)");
19906 case NT_FREEBSD_PROCSTAT_FILES:
19907 return _("NT_PROCSTAT_FILES (files data)");
19908 case NT_FREEBSD_PROCSTAT_VMMAP:
19909 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19910 case NT_FREEBSD_PROCSTAT_GROUPS:
19911 return _("NT_PROCSTAT_GROUPS (groups data)");
19912 case NT_FREEBSD_PROCSTAT_UMASK:
19913 return _("NT_PROCSTAT_UMASK (umask data)");
19914 case NT_FREEBSD_PROCSTAT_RLIMIT:
19915 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19916 case NT_FREEBSD_PROCSTAT_OSREL:
19917 return _("NT_PROCSTAT_OSREL (osreldate data)");
19918 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19919 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19920 case NT_FREEBSD_PROCSTAT_AUXV:
19921 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19922 case NT_FREEBSD_PTLWPINFO:
19923 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19924 }
dda8d76d 19925 return get_note_type (filedata, e_type);
f4ddf30f
JB
19926}
19927
9437c45b 19928static const char *
dda8d76d 19929get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19930{
19931 static char buff[64];
19932
540e6170
CZ
19933 switch (e_type)
19934 {
19935 case NT_NETBSDCORE_PROCINFO:
19936 /* NetBSD core "procinfo" structure. */
19937 return _("NetBSD procinfo structure");
9437c45b 19938
540e6170
CZ
19939 case NT_NETBSDCORE_AUXV:
19940 return _("NetBSD ELF auxiliary vector data");
9437c45b 19941
06d949ec
KR
19942 case NT_NETBSDCORE_LWPSTATUS:
19943 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19944
540e6170 19945 default:
06d949ec 19946 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19947 defined for NetBSD core files. If the note type is less
19948 than the start of the machine-dependent note types, we don't
19949 understand it. */
19950
19951 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19952 {
19953 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19954 return buff;
19955 }
19956 break;
9437c45b
JT
19957 }
19958
dda8d76d 19959 switch (filedata->file_header.e_machine)
9437c45b
JT
19960 {
19961 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19962 and PT_GETFPREGS == mach+2. */
19963
19964 case EM_OLD_ALPHA:
19965 case EM_ALPHA:
19966 case EM_SPARC:
19967 case EM_SPARC32PLUS:
19968 case EM_SPARCV9:
19969 switch (e_type)
19970 {
2b692964 19971 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19972 return _("PT_GETREGS (reg structure)");
2b692964 19973 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19974 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19975 default:
19976 break;
19977 }
19978 break;
19979
c0d38b0e
CZ
19980 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19981 There's also old PT___GETREGS40 == mach + 1 for old reg
19982 structure which lacks GBR. */
19983 case EM_SH:
19984 switch (e_type)
19985 {
19986 case NT_NETBSDCORE_FIRSTMACH + 1:
19987 return _("PT___GETREGS40 (old reg structure)");
19988 case NT_NETBSDCORE_FIRSTMACH + 3:
19989 return _("PT_GETREGS (reg structure)");
19990 case NT_NETBSDCORE_FIRSTMACH + 5:
19991 return _("PT_GETFPREGS (fpreg structure)");
19992 default:
19993 break;
19994 }
19995 break;
19996
9437c45b
JT
19997 /* On all other arch's, PT_GETREGS == mach+1 and
19998 PT_GETFPREGS == mach+3. */
19999 default:
20000 switch (e_type)
20001 {
2b692964 20002 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20003 return _("PT_GETREGS (reg structure)");
2b692964 20004 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20005 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20006 default:
20007 break;
20008 }
20009 }
20010
9cf03b7e 20011 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20012 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20013 return buff;
20014}
20015
98ca73af
FC
20016static const char *
20017get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20018{
20019 switch (e_type)
20020 {
20021 case NT_OPENBSD_PROCINFO:
20022 return _("OpenBSD procinfo structure");
20023 case NT_OPENBSD_AUXV:
20024 return _("OpenBSD ELF auxiliary vector data");
20025 case NT_OPENBSD_REGS:
20026 return _("OpenBSD regular registers");
20027 case NT_OPENBSD_FPREGS:
20028 return _("OpenBSD floating point registers");
20029 case NT_OPENBSD_WCOOKIE:
20030 return _("OpenBSD window cookie");
20031 }
20032
20033 return get_note_type (filedata, e_type);
20034}
20035
70616151
TT
20036static const char *
20037get_stapsdt_note_type (unsigned e_type)
20038{
20039 static char buff[64];
20040
20041 switch (e_type)
20042 {
20043 case NT_STAPSDT:
20044 return _("NT_STAPSDT (SystemTap probe descriptors)");
20045
20046 default:
20047 break;
20048 }
20049
20050 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20051 return buff;
20052}
20053
015dc7e1 20054static bool
c6a9fc58
TT
20055print_stapsdt_note (Elf_Internal_Note *pnote)
20056{
3ca60c57
NC
20057 size_t len, maxlen;
20058 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20059 char *data = pnote->descdata;
20060 char *data_end = pnote->descdata + pnote->descsz;
20061 bfd_vma pc, base_addr, semaphore;
20062 char *provider, *probe, *arg_fmt;
20063
3ca60c57
NC
20064 if (pnote->descsz < (addr_size * 3))
20065 goto stapdt_note_too_small;
20066
c6a9fc58
TT
20067 pc = byte_get ((unsigned char *) data, addr_size);
20068 data += addr_size;
3ca60c57 20069
c6a9fc58
TT
20070 base_addr = byte_get ((unsigned char *) data, addr_size);
20071 data += addr_size;
3ca60c57 20072
c6a9fc58
TT
20073 semaphore = byte_get ((unsigned char *) data, addr_size);
20074 data += addr_size;
20075
3ca60c57
NC
20076 if (data >= data_end)
20077 goto stapdt_note_too_small;
20078 maxlen = data_end - data;
20079 len = strnlen (data, maxlen);
20080 if (len < maxlen)
20081 {
20082 provider = data;
20083 data += len + 1;
20084 }
20085 else
20086 goto stapdt_note_too_small;
20087
20088 if (data >= data_end)
20089 goto stapdt_note_too_small;
20090 maxlen = data_end - data;
20091 len = strnlen (data, maxlen);
20092 if (len < maxlen)
20093 {
20094 probe = data;
20095 data += len + 1;
20096 }
20097 else
20098 goto stapdt_note_too_small;
9abca702 20099
3ca60c57
NC
20100 if (data >= data_end)
20101 goto stapdt_note_too_small;
20102 maxlen = data_end - data;
20103 len = strnlen (data, maxlen);
20104 if (len < maxlen)
20105 {
20106 arg_fmt = data;
20107 data += len + 1;
20108 }
20109 else
20110 goto stapdt_note_too_small;
c6a9fc58
TT
20111
20112 printf (_(" Provider: %s\n"), provider);
20113 printf (_(" Name: %s\n"), probe);
20114 printf (_(" Location: "));
20115 print_vma (pc, FULL_HEX);
20116 printf (_(", Base: "));
20117 print_vma (base_addr, FULL_HEX);
20118 printf (_(", Semaphore: "));
20119 print_vma (semaphore, FULL_HEX);
9cf03b7e 20120 printf ("\n");
c6a9fc58
TT
20121 printf (_(" Arguments: %s\n"), arg_fmt);
20122
20123 return data == data_end;
3ca60c57
NC
20124
20125 stapdt_note_too_small:
20126 printf (_(" <corrupt - note is too small>\n"));
20127 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20128 return false;
c6a9fc58
TT
20129}
20130
00e98fc7
TG
20131static const char *
20132get_ia64_vms_note_type (unsigned e_type)
20133{
20134 static char buff[64];
20135
20136 switch (e_type)
20137 {
20138 case NT_VMS_MHD:
20139 return _("NT_VMS_MHD (module header)");
20140 case NT_VMS_LNM:
20141 return _("NT_VMS_LNM (language name)");
20142 case NT_VMS_SRC:
20143 return _("NT_VMS_SRC (source files)");
20144 case NT_VMS_TITLE:
9cf03b7e 20145 return "NT_VMS_TITLE";
00e98fc7
TG
20146 case NT_VMS_EIDC:
20147 return _("NT_VMS_EIDC (consistency check)");
20148 case NT_VMS_FPMODE:
20149 return _("NT_VMS_FPMODE (FP mode)");
20150 case NT_VMS_LINKTIME:
9cf03b7e 20151 return "NT_VMS_LINKTIME";
00e98fc7
TG
20152 case NT_VMS_IMGNAM:
20153 return _("NT_VMS_IMGNAM (image name)");
20154 case NT_VMS_IMGID:
20155 return _("NT_VMS_IMGID (image id)");
20156 case NT_VMS_LINKID:
20157 return _("NT_VMS_LINKID (link id)");
20158 case NT_VMS_IMGBID:
20159 return _("NT_VMS_IMGBID (build id)");
20160 case NT_VMS_GSTNAM:
20161 return _("NT_VMS_GSTNAM (sym table name)");
20162 case NT_VMS_ORIG_DYN:
9cf03b7e 20163 return "NT_VMS_ORIG_DYN";
00e98fc7 20164 case NT_VMS_PATCHTIME:
9cf03b7e 20165 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20166 default:
20167 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20168 return buff;
20169 }
20170}
20171
015dc7e1 20172static bool
00e98fc7
TG
20173print_ia64_vms_note (Elf_Internal_Note * pnote)
20174{
8d18bf79
NC
20175 int maxlen = pnote->descsz;
20176
20177 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20178 goto desc_size_fail;
20179
00e98fc7
TG
20180 switch (pnote->type)
20181 {
20182 case NT_VMS_MHD:
8d18bf79
NC
20183 if (maxlen <= 36)
20184 goto desc_size_fail;
20185
20186 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20187
20188 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20189 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20190 if (l + 34 < maxlen)
20191 {
20192 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20193 if (l + 35 < maxlen)
20194 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20195 else
20196 printf (_(" Module version : <missing>\n"));
20197 }
00e98fc7 20198 else
8d18bf79
NC
20199 {
20200 printf (_(" Module name : <missing>\n"));
20201 printf (_(" Module version : <missing>\n"));
20202 }
00e98fc7 20203 break;
8d18bf79 20204
00e98fc7 20205 case NT_VMS_LNM:
8d18bf79 20206 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20207 break;
8d18bf79 20208
00e98fc7
TG
20209#ifdef BFD64
20210 case NT_VMS_FPMODE:
9cf03b7e 20211 printf (_(" Floating Point mode: "));
8d18bf79
NC
20212 if (maxlen < 8)
20213 goto desc_size_fail;
20214 /* FIXME: Generate an error if descsz > 8 ? */
20215
4a5cb34f 20216 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20217 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20218 break;
8d18bf79 20219
00e98fc7
TG
20220 case NT_VMS_LINKTIME:
20221 printf (_(" Link time: "));
8d18bf79
NC
20222 if (maxlen < 8)
20223 goto desc_size_fail;
20224 /* FIXME: Generate an error if descsz > 8 ? */
20225
00e98fc7 20226 print_vms_time
8d18bf79 20227 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20228 printf ("\n");
20229 break;
8d18bf79 20230
00e98fc7
TG
20231 case NT_VMS_PATCHTIME:
20232 printf (_(" Patch time: "));
8d18bf79
NC
20233 if (maxlen < 8)
20234 goto desc_size_fail;
20235 /* FIXME: Generate an error if descsz > 8 ? */
20236
00e98fc7 20237 print_vms_time
8d18bf79 20238 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20239 printf ("\n");
20240 break;
8d18bf79 20241
00e98fc7 20242 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20243 if (maxlen < 34)
20244 goto desc_size_fail;
20245
00e98fc7
TG
20246 printf (_(" Major id: %u, minor id: %u\n"),
20247 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20248 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20249 printf (_(" Last modified : "));
00e98fc7
TG
20250 print_vms_time
20251 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20252 printf (_("\n Link flags : "));
4a5cb34f 20253 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20254 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20255 printf (_(" Header flags: 0x%08x\n"),
948f632f 20256 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20257 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20258 break;
20259#endif
8d18bf79 20260
00e98fc7 20261 case NT_VMS_IMGNAM:
8d18bf79 20262 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20263 break;
8d18bf79 20264
00e98fc7 20265 case NT_VMS_GSTNAM:
8d18bf79 20266 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20267 break;
8d18bf79 20268
00e98fc7 20269 case NT_VMS_IMGID:
8d18bf79 20270 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20271 break;
8d18bf79 20272
00e98fc7 20273 case NT_VMS_LINKID:
8d18bf79 20274 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20275 break;
8d18bf79 20276
00e98fc7 20277 default:
015dc7e1 20278 return false;
00e98fc7 20279 }
8d18bf79 20280
015dc7e1 20281 return true;
8d18bf79
NC
20282
20283 desc_size_fail:
20284 printf (_(" <corrupt - data size is too small>\n"));
20285 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20286 return false;
00e98fc7
TG
20287}
20288
fd486f32
AM
20289struct build_attr_cache {
20290 Filedata *filedata;
20291 char *strtab;
20292 unsigned long strtablen;
20293 Elf_Internal_Sym *symtab;
20294 unsigned long nsyms;
20295} ba_cache;
20296
6f156d7a
NC
20297/* Find the symbol associated with a build attribute that is attached
20298 to address OFFSET. If PNAME is non-NULL then store the name of
20299 the symbol (if found) in the provided pointer, Returns NULL if a
20300 symbol could not be found. */
c799a79d 20301
6f156d7a 20302static Elf_Internal_Sym *
015dc7e1
AM
20303get_symbol_for_build_attribute (Filedata *filedata,
20304 unsigned long offset,
20305 bool is_open_attr,
20306 const char **pname)
9ef920e9 20307{
fd486f32
AM
20308 Elf_Internal_Sym *saved_sym = NULL;
20309 Elf_Internal_Sym *sym;
9ef920e9 20310
dda8d76d 20311 if (filedata->section_headers != NULL
fd486f32 20312 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20313 {
c799a79d 20314 Elf_Internal_Shdr * symsec;
9ef920e9 20315
fd486f32
AM
20316 free (ba_cache.strtab);
20317 ba_cache.strtab = NULL;
20318 free (ba_cache.symtab);
20319 ba_cache.symtab = NULL;
20320
c799a79d 20321 /* Load the symbol and string sections. */
dda8d76d
NC
20322 for (symsec = filedata->section_headers;
20323 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20324 symsec ++)
9ef920e9 20325 {
28d13567
AM
20326 if (symsec->sh_type == SHT_SYMTAB
20327 && get_symtab (filedata, symsec,
20328 &ba_cache.symtab, &ba_cache.nsyms,
20329 &ba_cache.strtab, &ba_cache.strtablen))
20330 break;
9ef920e9 20331 }
fd486f32 20332 ba_cache.filedata = filedata;
9ef920e9
NC
20333 }
20334
fd486f32 20335 if (ba_cache.symtab == NULL)
6f156d7a 20336 return NULL;
9ef920e9 20337
c799a79d 20338 /* Find a symbol whose value matches offset. */
fd486f32 20339 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20340 if (sym->st_value == offset)
20341 {
fd486f32 20342 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20343 /* Huh ? This should not happen. */
20344 continue;
9ef920e9 20345
fd486f32 20346 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20347 continue;
9ef920e9 20348
9b9b1092 20349 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20350 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20351 if (ba_cache.strtab[sym->st_name] == '$'
20352 && ba_cache.strtab[sym->st_name + 1] != 0
20353 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20354 continue;
20355
c799a79d
NC
20356 if (is_open_attr)
20357 {
20358 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20359 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20360 FUNC symbols entirely. */
20361 switch (ELF_ST_TYPE (sym->st_info))
20362 {
c799a79d 20363 case STT_OBJECT:
6f156d7a 20364 case STT_FILE:
c799a79d 20365 saved_sym = sym;
6f156d7a
NC
20366 if (sym->st_size)
20367 {
20368 /* If the symbol has a size associated
20369 with it then we can stop searching. */
fd486f32 20370 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20371 }
c799a79d 20372 continue;
9ef920e9 20373
c799a79d
NC
20374 case STT_FUNC:
20375 /* Ignore function symbols. */
20376 continue;
20377
20378 default:
20379 break;
20380 }
20381
20382 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20383 {
c799a79d
NC
20384 case STB_GLOBAL:
20385 if (saved_sym == NULL
20386 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20387 saved_sym = sym;
20388 break;
c871dade 20389
c799a79d
NC
20390 case STB_LOCAL:
20391 if (saved_sym == NULL)
20392 saved_sym = sym;
20393 break;
20394
20395 default:
9ef920e9
NC
20396 break;
20397 }
20398 }
c799a79d
NC
20399 else
20400 {
20401 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20402 continue;
20403
20404 saved_sym = sym;
20405 break;
20406 }
20407 }
20408
6f156d7a 20409 if (saved_sym && pname)
fd486f32 20410 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20411
20412 return saved_sym;
c799a79d
NC
20413}
20414
d20e98ab
NC
20415/* Returns true iff addr1 and addr2 are in the same section. */
20416
015dc7e1 20417static bool
d20e98ab
NC
20418same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20419{
20420 Elf_Internal_Shdr * a1;
20421 Elf_Internal_Shdr * a2;
20422
20423 a1 = find_section_by_address (filedata, addr1);
20424 a2 = find_section_by_address (filedata, addr2);
9abca702 20425
d20e98ab
NC
20426 return a1 == a2 && a1 != NULL;
20427}
20428
015dc7e1 20429static bool
dda8d76d
NC
20430print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20431 Filedata * filedata)
c799a79d 20432{
015dc7e1
AM
20433 static unsigned long global_offset = 0;
20434 static unsigned long global_end = 0;
20435 static unsigned long func_offset = 0;
20436 static unsigned long func_end = 0;
c871dade 20437
015dc7e1
AM
20438 Elf_Internal_Sym *sym;
20439 const char *name;
20440 unsigned long start;
20441 unsigned long end;
20442 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20443
20444 switch (pnote->descsz)
c799a79d 20445 {
6f156d7a
NC
20446 case 0:
20447 /* A zero-length description means that the range of
20448 the previous note of the same type should be used. */
c799a79d 20449 if (is_open_attr)
c871dade 20450 {
6f156d7a
NC
20451 if (global_end > global_offset)
20452 printf (_(" Applies to region from %#lx to %#lx\n"),
20453 global_offset, global_end);
20454 else
20455 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20456 }
20457 else
20458 {
6f156d7a
NC
20459 if (func_end > func_offset)
20460 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20461 else
20462 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20463 }
015dc7e1 20464 return true;
9ef920e9 20465
6f156d7a
NC
20466 case 4:
20467 start = byte_get ((unsigned char *) pnote->descdata, 4);
20468 end = 0;
20469 break;
20470
20471 case 8:
c74147bb
NC
20472 start = byte_get ((unsigned char *) pnote->descdata, 4);
20473 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20474 break;
20475
20476 case 16:
20477 start = byte_get ((unsigned char *) pnote->descdata, 8);
20478 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20479 break;
9abca702 20480
6f156d7a 20481 default:
c799a79d
NC
20482 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20483 printf (_(" <invalid descsz>"));
015dc7e1 20484 return false;
c799a79d
NC
20485 }
20486
6f156d7a
NC
20487 name = NULL;
20488 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20489 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20490 in order to avoid them being confused with the start address of the
20491 first function in the file... */
20492 if (sym == NULL && is_open_attr)
20493 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20494 & name);
6f156d7a
NC
20495
20496 if (end == 0 && sym != NULL && sym->st_size > 0)
20497 end = start + sym->st_size;
c799a79d
NC
20498
20499 if (is_open_attr)
20500 {
d20e98ab
NC
20501 /* FIXME: Need to properly allow for section alignment.
20502 16 is just the alignment used on x86_64. */
20503 if (global_end > 0
20504 && start > BFD_ALIGN (global_end, 16)
20505 /* Build notes are not guaranteed to be organised in order of
20506 increasing address, but we should find the all of the notes
20507 for one section in the same place. */
20508 && same_section (filedata, start, global_end))
6f156d7a
NC
20509 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20510 global_end + 1, start - 1);
20511
20512 printf (_(" Applies to region from %#lx"), start);
20513 global_offset = start;
20514
20515 if (end)
20516 {
20517 printf (_(" to %#lx"), end);
20518 global_end = end;
20519 }
c799a79d
NC
20520 }
20521 else
20522 {
6f156d7a
NC
20523 printf (_(" Applies to region from %#lx"), start);
20524 func_offset = start;
20525
20526 if (end)
20527 {
20528 printf (_(" to %#lx"), end);
20529 func_end = end;
20530 }
c799a79d
NC
20531 }
20532
6f156d7a
NC
20533 if (sym && name)
20534 printf (_(" (%s)"), name);
20535
20536 printf ("\n");
015dc7e1 20537 return true;
9ef920e9
NC
20538}
20539
015dc7e1 20540static bool
9ef920e9
NC
20541print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20542{
1d15e434
NC
20543 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20544 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20545 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20546 char name_type;
20547 char name_attribute;
1d15e434 20548 const char * expected_types;
9ef920e9
NC
20549 const char * name = pnote->namedata;
20550 const char * text;
88305e1b 20551 signed int left;
9ef920e9
NC
20552
20553 if (name == NULL || pnote->namesz < 2)
20554 {
20555 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20556 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20557 return false;
9ef920e9
NC
20558 }
20559
6f156d7a
NC
20560 if (do_wide)
20561 left = 28;
20562 else
20563 left = 20;
88305e1b
NC
20564
20565 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20566 if (name[0] == 'G' && name[1] == 'A')
20567 {
6f156d7a
NC
20568 if (pnote->namesz < 4)
20569 {
20570 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20571 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20572 return false;
6f156d7a
NC
20573 }
20574
88305e1b
NC
20575 printf ("GA");
20576 name += 2;
20577 left -= 2;
20578 }
20579
9ef920e9
NC
20580 switch ((name_type = * name))
20581 {
20582 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20583 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20584 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20585 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20586 printf ("%c", * name);
88305e1b 20587 left --;
9ef920e9
NC
20588 break;
20589 default:
20590 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20591 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20592 return false;
9ef920e9
NC
20593 }
20594
9ef920e9
NC
20595 ++ name;
20596 text = NULL;
20597
20598 switch ((name_attribute = * name))
20599 {
20600 case GNU_BUILD_ATTRIBUTE_VERSION:
20601 text = _("<version>");
1d15e434 20602 expected_types = string_expected;
9ef920e9
NC
20603 ++ name;
20604 break;
20605 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20606 text = _("<stack prot>");
75d7d298 20607 expected_types = "!+*";
9ef920e9
NC
20608 ++ name;
20609 break;
20610 case GNU_BUILD_ATTRIBUTE_RELRO:
20611 text = _("<relro>");
1d15e434 20612 expected_types = bool_expected;
9ef920e9
NC
20613 ++ name;
20614 break;
20615 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20616 text = _("<stack size>");
1d15e434 20617 expected_types = number_expected;
9ef920e9
NC
20618 ++ name;
20619 break;
20620 case GNU_BUILD_ATTRIBUTE_TOOL:
20621 text = _("<tool>");
1d15e434 20622 expected_types = string_expected;
9ef920e9
NC
20623 ++ name;
20624 break;
20625 case GNU_BUILD_ATTRIBUTE_ABI:
20626 text = _("<ABI>");
20627 expected_types = "$*";
20628 ++ name;
20629 break;
20630 case GNU_BUILD_ATTRIBUTE_PIC:
20631 text = _("<PIC>");
1d15e434 20632 expected_types = number_expected;
9ef920e9
NC
20633 ++ name;
20634 break;
a8be5506
NC
20635 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20636 text = _("<short enum>");
1d15e434 20637 expected_types = bool_expected;
a8be5506
NC
20638 ++ name;
20639 break;
9ef920e9
NC
20640 default:
20641 if (ISPRINT (* name))
20642 {
20643 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20644
20645 if (len > left && ! do_wide)
20646 len = left;
75d7d298 20647 printf ("%.*s:", len, name);
9ef920e9 20648 left -= len;
0dd6ae21 20649 name += len;
9ef920e9
NC
20650 }
20651 else
20652 {
3e6b6445 20653 static char tmpbuf [128];
88305e1b 20654
3e6b6445
NC
20655 error (_("unrecognised byte in name field: %d\n"), * name);
20656 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20657 text = tmpbuf;
20658 name ++;
9ef920e9
NC
20659 }
20660 expected_types = "*$!+";
20661 break;
20662 }
20663
20664 if (text)
88305e1b 20665 left -= printf ("%s", text);
9ef920e9
NC
20666
20667 if (strchr (expected_types, name_type) == NULL)
75d7d298 20668 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20669
20670 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20671 {
20672 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20673 (unsigned long) pnote->namesz,
20674 (long) (name - pnote->namedata));
015dc7e1 20675 return false;
9ef920e9
NC
20676 }
20677
20678 if (left < 1 && ! do_wide)
015dc7e1 20679 return true;
9ef920e9
NC
20680
20681 switch (name_type)
20682 {
20683 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20684 {
b06b2c92 20685 unsigned int bytes;
ddef72cd
NC
20686 unsigned long long val = 0;
20687 unsigned int shift = 0;
20688 char * decoded = NULL;
20689
b06b2c92
NC
20690 bytes = pnote->namesz - (name - pnote->namedata);
20691 if (bytes > 0)
20692 /* The -1 is because the name field is always 0 terminated, and we
20693 want to be able to ensure that the shift in the while loop below
20694 will not overflow. */
20695 -- bytes;
20696
ddef72cd
NC
20697 if (bytes > sizeof (val))
20698 {
3e6b6445
NC
20699 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20700 bytes);
20701 bytes = sizeof (val);
ddef72cd 20702 }
3e6b6445
NC
20703 /* We do not bother to warn if bytes == 0 as this can
20704 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20705
20706 while (bytes --)
20707 {
54b8331d 20708 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20709
20710 val |= byte << shift;
9ef920e9
NC
20711 shift += 8;
20712 }
20713
75d7d298 20714 switch (name_attribute)
9ef920e9 20715 {
75d7d298 20716 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20717 switch (val)
20718 {
75d7d298
NC
20719 case 0: decoded = "static"; break;
20720 case 1: decoded = "pic"; break;
20721 case 2: decoded = "PIC"; break;
20722 case 3: decoded = "pie"; break;
20723 case 4: decoded = "PIE"; break;
20724 default: break;
9ef920e9 20725 }
75d7d298
NC
20726 break;
20727 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20728 switch (val)
9ef920e9 20729 {
75d7d298
NC
20730 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20731 case 0: decoded = "off"; break;
20732 case 1: decoded = "on"; break;
20733 case 2: decoded = "all"; break;
20734 case 3: decoded = "strong"; break;
20735 case 4: decoded = "explicit"; break;
20736 default: break;
9ef920e9 20737 }
75d7d298
NC
20738 break;
20739 default:
20740 break;
9ef920e9
NC
20741 }
20742
75d7d298 20743 if (decoded != NULL)
3e6b6445
NC
20744 {
20745 print_symbol (-left, decoded);
20746 left = 0;
20747 }
20748 else if (val == 0)
20749 {
20750 printf ("0x0");
20751 left -= 3;
20752 }
9ef920e9 20753 else
75d7d298
NC
20754 {
20755 if (do_wide)
ddef72cd 20756 left -= printf ("0x%llx", val);
75d7d298 20757 else
ddef72cd 20758 left -= printf ("0x%-.*llx", left, val);
75d7d298 20759 }
9ef920e9
NC
20760 }
20761 break;
20762 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20763 left -= print_symbol (- left, name);
20764 break;
20765 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20766 left -= print_symbol (- left, "true");
20767 break;
20768 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20769 left -= print_symbol (- left, "false");
20770 break;
20771 }
20772
20773 if (do_wide && left > 0)
20774 printf ("%-*s", left, " ");
9abca702 20775
015dc7e1 20776 return true;
9ef920e9
NC
20777}
20778
6d118b09
NC
20779/* Note that by the ELF standard, the name field is already null byte
20780 terminated, and namesz includes the terminating null byte.
20781 I.E. the value of namesz for the name "FSF" is 4.
20782
e3c8793a 20783 If the value of namesz is zero, there is no name present. */
9ef920e9 20784
015dc7e1 20785static bool
9ef920e9 20786process_note (Elf_Internal_Note * pnote,
dda8d76d 20787 Filedata * filedata)
779fe533 20788{
2cf0635d
NC
20789 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20790 const char * nt;
9437c45b
JT
20791
20792 if (pnote->namesz == 0)
1ec5cd37
NC
20793 /* If there is no note name, then use the default set of
20794 note type strings. */
dda8d76d 20795 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20796
24d127aa 20797 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20798 /* GNU-specific object file notes. */
20799 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20800
24d127aa 20801 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20802 /* FreeBSD-specific core file notes. */
dda8d76d 20803 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20804
24d127aa 20805 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20806 /* NetBSD-specific core file notes. */
dda8d76d 20807 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20808
24d127aa 20809 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20810 /* NetBSD-specific core file notes. */
20811 return process_netbsd_elf_note (pnote);
20812
24d127aa 20813 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20814 /* NetBSD-specific core file notes. */
20815 return process_netbsd_elf_note (pnote);
20816
98ca73af
FC
20817 else if (startswith (pnote->namedata, "OpenBSD"))
20818 /* OpenBSD-specific core file notes. */
20819 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
20820
e9b095a5 20821 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20822 {
20823 /* SPU-specific core file notes. */
20824 nt = pnote->namedata + 4;
20825 name = "SPU";
20826 }
20827
24d127aa 20828 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20829 /* VMS/ia64-specific file notes. */
20830 nt = get_ia64_vms_note_type (pnote->type);
20831
24d127aa 20832 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20833 nt = get_stapsdt_note_type (pnote->type);
20834
9437c45b 20835 else
1ec5cd37
NC
20836 /* Don't recognize this note name; just use the default set of
20837 note type strings. */
dda8d76d 20838 nt = get_note_type (filedata, pnote->type);
9437c45b 20839
1449284b 20840 printf (" ");
9ef920e9 20841
24d127aa 20842 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20843 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20844 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20845 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20846 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20847 print_gnu_build_attribute_name (pnote);
20848 else
20849 print_symbol (-20, name);
20850
20851 if (do_wide)
20852 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20853 else
20854 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20855
24d127aa 20856 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20857 return print_ia64_vms_note (pnote);
24d127aa 20858 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20859 return print_gnu_note (filedata, pnote);
24d127aa 20860 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20861 return print_stapsdt_note (pnote);
24d127aa 20862 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20863 return print_core_note (pnote);
24d127aa 20864 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20865 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20866 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20867 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20868 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20869 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20870
9ef920e9 20871 if (pnote->descsz)
1449284b
NC
20872 {
20873 unsigned long i;
20874
20875 printf (_(" description data: "));
20876 for (i = 0; i < pnote->descsz; i++)
178d8719 20877 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20878 if (!do_wide)
20879 printf ("\n");
1449284b
NC
20880 }
20881
9ef920e9
NC
20882 if (do_wide)
20883 printf ("\n");
20884
015dc7e1 20885 return true;
1449284b 20886}
6d118b09 20887
015dc7e1 20888static bool
dda8d76d
NC
20889process_notes_at (Filedata * filedata,
20890 Elf_Internal_Shdr * section,
20891 bfd_vma offset,
82ed9683
L
20892 bfd_vma length,
20893 bfd_vma align)
779fe533 20894{
015dc7e1
AM
20895 Elf_External_Note *pnotes;
20896 Elf_External_Note *external;
20897 char *end;
20898 bool res = true;
103f02d3 20899
779fe533 20900 if (length <= 0)
015dc7e1 20901 return false;
103f02d3 20902
1449284b
NC
20903 if (section)
20904 {
dda8d76d 20905 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20906 if (pnotes)
32ec8896 20907 {
dda8d76d 20908 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20909 {
20910 free (pnotes);
015dc7e1 20911 return false;
f761cb13 20912 }
32ec8896 20913 }
1449284b
NC
20914 }
20915 else
82ed9683 20916 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20917 _("notes"));
4dff97b2 20918
dd24e3da 20919 if (pnotes == NULL)
015dc7e1 20920 return false;
779fe533 20921
103f02d3 20922 external = pnotes;
103f02d3 20923
ca0e11aa
NC
20924 if (filedata->is_separate)
20925 printf (_("In linked file '%s': "), filedata->file_name);
20926 else
20927 printf ("\n");
1449284b 20928 if (section)
ca0e11aa 20929 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20930 else
ca0e11aa 20931 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20932 (unsigned long) offset, (unsigned long) length);
20933
82ed9683
L
20934 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20935 specifies that notes should be aligned to 4 bytes in 32-bit
20936 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20937 we also support 4 byte alignment in 64-bit objects. If section
20938 alignment is less than 4, we treate alignment as 4 bytes. */
20939 if (align < 4)
20940 align = 4;
20941 else if (align != 4 && align != 8)
20942 {
20943 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20944 (long) align);
a788aedd 20945 free (pnotes);
015dc7e1 20946 return false;
82ed9683
L
20947 }
20948
dbe15e4e 20949 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20950
c8071705
NC
20951 end = (char *) pnotes + length;
20952 while ((char *) external < end)
779fe533 20953 {
b34976b6 20954 Elf_Internal_Note inote;
15b42fb0 20955 size_t min_notesz;
4dff97b2 20956 char * next;
2cf0635d 20957 char * temp = NULL;
c8071705 20958 size_t data_remaining = end - (char *) external;
6d118b09 20959
dda8d76d 20960 if (!is_ia64_vms (filedata))
15b42fb0 20961 {
9dd3a467
NC
20962 /* PR binutils/15191
20963 Make sure that there is enough data to read. */
15b42fb0
AM
20964 min_notesz = offsetof (Elf_External_Note, name);
20965 if (data_remaining < min_notesz)
9dd3a467 20966 {
d3a49aa8
AM
20967 warn (ngettext ("Corrupt note: only %ld byte remains, "
20968 "not enough for a full note\n",
20969 "Corrupt note: only %ld bytes remain, "
20970 "not enough for a full note\n",
20971 data_remaining),
20972 (long) data_remaining);
9dd3a467
NC
20973 break;
20974 }
5396a86e
AM
20975 data_remaining -= min_notesz;
20976
15b42fb0
AM
20977 inote.type = BYTE_GET (external->type);
20978 inote.namesz = BYTE_GET (external->namesz);
20979 inote.namedata = external->name;
20980 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20981 inote.descdata = ((char *) external
4dff97b2 20982 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20983 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20984 next = ((char *) external
4dff97b2 20985 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20986 }
00e98fc7 20987 else
15b42fb0
AM
20988 {
20989 Elf64_External_VMS_Note *vms_external;
00e98fc7 20990
9dd3a467
NC
20991 /* PR binutils/15191
20992 Make sure that there is enough data to read. */
15b42fb0
AM
20993 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20994 if (data_remaining < min_notesz)
9dd3a467 20995 {
d3a49aa8
AM
20996 warn (ngettext ("Corrupt note: only %ld byte remains, "
20997 "not enough for a full note\n",
20998 "Corrupt note: only %ld bytes remain, "
20999 "not enough for a full note\n",
21000 data_remaining),
21001 (long) data_remaining);
9dd3a467
NC
21002 break;
21003 }
5396a86e 21004 data_remaining -= min_notesz;
3e55a963 21005
15b42fb0
AM
21006 vms_external = (Elf64_External_VMS_Note *) external;
21007 inote.type = BYTE_GET (vms_external->type);
21008 inote.namesz = BYTE_GET (vms_external->namesz);
21009 inote.namedata = vms_external->name;
21010 inote.descsz = BYTE_GET (vms_external->descsz);
21011 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21012 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21013 next = inote.descdata + align_power (inote.descsz, 3);
21014 }
21015
5396a86e
AM
21016 /* PR 17531: file: 3443835e. */
21017 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21018 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21019 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21020 || (size_t) (next - inote.descdata) < inote.descsz
21021 || ((size_t) (next - inote.descdata)
21022 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21023 {
15b42fb0 21024 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21025 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21026 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21027 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21028 break;
21029 }
21030
15b42fb0 21031 external = (Elf_External_Note *) next;
dd24e3da 21032
6d118b09
NC
21033 /* Verify that name is null terminated. It appears that at least
21034 one version of Linux (RedHat 6.0) generates corefiles that don't
21035 comply with the ELF spec by failing to include the null byte in
21036 namesz. */
18344509 21037 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21038 {
5396a86e 21039 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21040 {
5396a86e
AM
21041 temp = (char *) malloc (inote.namesz + 1);
21042 if (temp == NULL)
21043 {
21044 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21045 res = false;
5396a86e
AM
21046 break;
21047 }
76da6bbe 21048
5396a86e
AM
21049 memcpy (temp, inote.namedata, inote.namesz);
21050 inote.namedata = temp;
21051 }
21052 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21053 }
21054
dda8d76d 21055 if (! process_note (& inote, filedata))
015dc7e1 21056 res = false;
103f02d3 21057
9db70fc3
AM
21058 free (temp);
21059 temp = NULL;
779fe533
NC
21060 }
21061
21062 free (pnotes);
103f02d3 21063
779fe533
NC
21064 return res;
21065}
21066
015dc7e1 21067static bool
dda8d76d 21068process_corefile_note_segments (Filedata * filedata)
779fe533 21069{
015dc7e1 21070 Elf_Internal_Phdr *segment;
b34976b6 21071 unsigned int i;
015dc7e1 21072 bool res = true;
103f02d3 21073
dda8d76d 21074 if (! get_program_headers (filedata))
015dc7e1 21075 return true;
103f02d3 21076
dda8d76d
NC
21077 for (i = 0, segment = filedata->program_headers;
21078 i < filedata->file_header.e_phnum;
b34976b6 21079 i++, segment++)
779fe533
NC
21080 {
21081 if (segment->p_type == PT_NOTE)
dda8d76d 21082 if (! process_notes_at (filedata, NULL,
32ec8896 21083 (bfd_vma) segment->p_offset,
82ed9683
L
21084 (bfd_vma) segment->p_filesz,
21085 (bfd_vma) segment->p_align))
015dc7e1 21086 res = false;
779fe533 21087 }
103f02d3 21088
779fe533
NC
21089 return res;
21090}
21091
015dc7e1 21092static bool
dda8d76d 21093process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21094{
21095 Elf_External_Note * pnotes;
21096 Elf_External_Note * external;
c8071705 21097 char * end;
015dc7e1 21098 bool res = true;
685080f2
NC
21099
21100 if (length <= 0)
015dc7e1 21101 return false;
685080f2 21102
dda8d76d 21103 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21104 _("v850 notes"));
21105 if (pnotes == NULL)
015dc7e1 21106 return false;
685080f2
NC
21107
21108 external = pnotes;
c8071705 21109 end = (char*) pnotes + length;
685080f2
NC
21110
21111 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21112 (unsigned long) offset, (unsigned long) length);
21113
c8071705 21114 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21115 {
21116 Elf_External_Note * next;
21117 Elf_Internal_Note inote;
21118
21119 inote.type = BYTE_GET (external->type);
21120 inote.namesz = BYTE_GET (external->namesz);
21121 inote.namedata = external->name;
21122 inote.descsz = BYTE_GET (external->descsz);
21123 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21124 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21125
c8071705
NC
21126 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21127 {
21128 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21129 inote.descdata = inote.namedata;
21130 inote.namesz = 0;
21131 }
21132
685080f2
NC
21133 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21134
c8071705 21135 if ( ((char *) next > end)
685080f2
NC
21136 || ((char *) next < (char *) pnotes))
21137 {
21138 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21139 (unsigned long) ((char *) external - (char *) pnotes));
21140 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21141 inote.type, inote.namesz, inote.descsz);
21142 break;
21143 }
21144
21145 external = next;
21146
21147 /* Prevent out-of-bounds indexing. */
c8071705 21148 if ( inote.namedata + inote.namesz > end
685080f2
NC
21149 || inote.namedata + inote.namesz < inote.namedata)
21150 {
21151 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21152 (unsigned long) ((char *) external - (char *) pnotes));
21153 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21154 inote.type, inote.namesz, inote.descsz);
21155 break;
21156 }
21157
21158 printf (" %s: ", get_v850_elf_note_type (inote.type));
21159
21160 if (! print_v850_note (& inote))
21161 {
015dc7e1 21162 res = false;
685080f2
NC
21163 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21164 inote.namesz, inote.descsz);
21165 }
21166 }
21167
21168 free (pnotes);
21169
21170 return res;
21171}
21172
015dc7e1 21173static bool
dda8d76d 21174process_note_sections (Filedata * filedata)
1ec5cd37 21175{
015dc7e1 21176 Elf_Internal_Shdr *section;
1ec5cd37 21177 unsigned long i;
32ec8896 21178 unsigned int n = 0;
015dc7e1 21179 bool res = true;
1ec5cd37 21180
dda8d76d
NC
21181 for (i = 0, section = filedata->section_headers;
21182 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21183 i++, section++)
685080f2
NC
21184 {
21185 if (section->sh_type == SHT_NOTE)
21186 {
dda8d76d 21187 if (! process_notes_at (filedata, section,
32ec8896 21188 (bfd_vma) section->sh_offset,
82ed9683
L
21189 (bfd_vma) section->sh_size,
21190 (bfd_vma) section->sh_addralign))
015dc7e1 21191 res = false;
685080f2
NC
21192 n++;
21193 }
21194
dda8d76d
NC
21195 if (( filedata->file_header.e_machine == EM_V800
21196 || filedata->file_header.e_machine == EM_V850
21197 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21198 && section->sh_type == SHT_RENESAS_INFO)
21199 {
dda8d76d 21200 if (! process_v850_notes (filedata,
32ec8896
NC
21201 (bfd_vma) section->sh_offset,
21202 (bfd_vma) section->sh_size))
015dc7e1 21203 res = false;
685080f2
NC
21204 n++;
21205 }
21206 }
df565f32
NC
21207
21208 if (n == 0)
21209 /* Try processing NOTE segments instead. */
dda8d76d 21210 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21211
21212 return res;
21213}
21214
015dc7e1 21215static bool
dda8d76d 21216process_notes (Filedata * filedata)
779fe533
NC
21217{
21218 /* If we have not been asked to display the notes then do nothing. */
21219 if (! do_notes)
015dc7e1 21220 return true;
103f02d3 21221
dda8d76d
NC
21222 if (filedata->file_header.e_type != ET_CORE)
21223 return process_note_sections (filedata);
103f02d3 21224
779fe533 21225 /* No program headers means no NOTE segment. */
dda8d76d
NC
21226 if (filedata->file_header.e_phnum > 0)
21227 return process_corefile_note_segments (filedata);
779fe533 21228
ca0e11aa
NC
21229 if (filedata->is_separate)
21230 printf (_("No notes found in linked file '%s'.\n"),
21231 filedata->file_name);
21232 else
21233 printf (_("No notes found file.\n"));
21234
015dc7e1 21235 return true;
779fe533
NC
21236}
21237
60abdbed
NC
21238static unsigned char *
21239display_public_gnu_attributes (unsigned char * start,
21240 const unsigned char * const end)
21241{
21242 printf (_(" Unknown GNU attribute: %s\n"), start);
21243
21244 start += strnlen ((char *) start, end - start);
21245 display_raw_attribute (start, end);
21246
21247 return (unsigned char *) end;
21248}
21249
21250static unsigned char *
21251display_generic_attribute (unsigned char * start,
21252 unsigned int tag,
21253 const unsigned char * const end)
21254{
21255 if (tag == 0)
21256 return (unsigned char *) end;
21257
21258 return display_tag_value (tag, start, end);
21259}
21260
015dc7e1 21261static bool
dda8d76d 21262process_arch_specific (Filedata * filedata)
252b5132 21263{
a952a375 21264 if (! do_arch)
015dc7e1 21265 return true;
a952a375 21266
dda8d76d 21267 switch (filedata->file_header.e_machine)
252b5132 21268 {
53a346d8
CZ
21269 case EM_ARC:
21270 case EM_ARC_COMPACT:
21271 case EM_ARC_COMPACT2:
dda8d76d 21272 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21273 display_arc_attribute,
21274 display_generic_attribute);
11c1ff18 21275 case EM_ARM:
dda8d76d 21276 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21277 display_arm_attribute,
21278 display_generic_attribute);
21279
252b5132 21280 case EM_MIPS:
4fe85591 21281 case EM_MIPS_RS3_LE:
dda8d76d 21282 return process_mips_specific (filedata);
60abdbed
NC
21283
21284 case EM_MSP430:
dda8d76d 21285 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21286 display_msp430_attribute,
c0ea7c52 21287 display_msp430_gnu_attribute);
60abdbed 21288
2dc8dd17
JW
21289 case EM_RISCV:
21290 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21291 display_riscv_attribute,
21292 display_generic_attribute);
21293
35c08157 21294 case EM_NDS32:
dda8d76d 21295 return process_nds32_specific (filedata);
60abdbed 21296
85f7484a
PB
21297 case EM_68K:
21298 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21299 display_m68k_gnu_attribute);
21300
34c8bcba 21301 case EM_PPC:
b82317dd 21302 case EM_PPC64:
dda8d76d 21303 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21304 display_power_gnu_attribute);
21305
643f7afb
AK
21306 case EM_S390:
21307 case EM_S390_OLD:
dda8d76d 21308 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21309 display_s390_gnu_attribute);
21310
9e8c70f9
DM
21311 case EM_SPARC:
21312 case EM_SPARC32PLUS:
21313 case EM_SPARCV9:
dda8d76d 21314 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21315 display_sparc_gnu_attribute);
21316
59e6276b 21317 case EM_TI_C6000:
dda8d76d 21318 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21319 display_tic6x_attribute,
21320 display_generic_attribute);
21321
0861f561
CQ
21322 case EM_CSKY:
21323 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21324 display_csky_attribute, NULL);
21325
252b5132 21326 default:
dda8d76d 21327 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21328 display_public_gnu_attributes,
21329 display_generic_attribute);
252b5132 21330 }
252b5132
RH
21331}
21332
015dc7e1 21333static bool
dda8d76d 21334get_file_header (Filedata * filedata)
252b5132 21335{
9ea033b2 21336 /* Read in the identity array. */
dda8d76d 21337 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21338 return false;
252b5132 21339
9ea033b2 21340 /* Determine how to read the rest of the header. */
dda8d76d 21341 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21342 {
1a0670f3
AM
21343 default:
21344 case ELFDATANONE:
adab8cdc
AO
21345 case ELFDATA2LSB:
21346 byte_get = byte_get_little_endian;
21347 byte_put = byte_put_little_endian;
21348 break;
21349 case ELFDATA2MSB:
21350 byte_get = byte_get_big_endian;
21351 byte_put = byte_put_big_endian;
21352 break;
9ea033b2
NC
21353 }
21354
21355 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21356 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21357
21358 /* Read in the rest of the header. */
21359 if (is_32bit_elf)
21360 {
21361 Elf32_External_Ehdr ehdr32;
252b5132 21362
dda8d76d 21363 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21364 return false;
103f02d3 21365
dda8d76d
NC
21366 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21367 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21368 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21369 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21370 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21371 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21372 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21373 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21374 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21375 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21376 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21377 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21378 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21379 }
252b5132 21380 else
9ea033b2
NC
21381 {
21382 Elf64_External_Ehdr ehdr64;
a952a375
NC
21383
21384 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21385 we will not be able to cope with the 64bit data found in
21386 64 ELF files. Detect this now and abort before we start
50c2245b 21387 overwriting things. */
a952a375
NC
21388 if (sizeof (bfd_vma) < 8)
21389 {
e3c8793a
NC
21390 error (_("This instance of readelf has been built without support for a\n\
2139164 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21392 return false;
a952a375 21393 }
103f02d3 21394
dda8d76d 21395 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21396 return false;
103f02d3 21397
dda8d76d
NC
21398 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21399 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21400 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21401 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21402 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21403 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21404 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21405 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21406 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21407 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21408 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21409 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21410 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21411 }
252b5132 21412
015dc7e1 21413 return true;
252b5132
RH
21414}
21415
13acb58d
AM
21416static void
21417free_filedata (Filedata *filedata)
21418{
21419 free (filedata->program_interpreter);
13acb58d 21420 free (filedata->program_headers);
13acb58d 21421 free (filedata->section_headers);
13acb58d 21422 free (filedata->string_table);
13acb58d 21423 free (filedata->dump.dump_sects);
13acb58d 21424 free (filedata->dynamic_strings);
13acb58d 21425 free (filedata->dynamic_symbols);
13acb58d 21426 free (filedata->dynamic_syminfo);
13acb58d 21427 free (filedata->dynamic_section);
13acb58d
AM
21428
21429 while (filedata->symtab_shndx_list != NULL)
21430 {
21431 elf_section_list *next = filedata->symtab_shndx_list->next;
21432 free (filedata->symtab_shndx_list);
21433 filedata->symtab_shndx_list = next;
21434 }
21435
21436 free (filedata->section_headers_groups);
13acb58d
AM
21437
21438 if (filedata->section_groups)
21439 {
21440 size_t i;
21441 struct group_list * g;
21442 struct group_list * next;
21443
21444 for (i = 0; i < filedata->group_count; i++)
21445 {
21446 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21447 {
21448 next = g->next;
21449 free (g);
21450 }
21451 }
21452
21453 free (filedata->section_groups);
13acb58d 21454 }
066f8fbe
AM
21455 memset (&filedata->section_headers, 0,
21456 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21457}
21458
dda8d76d
NC
21459static void
21460close_file (Filedata * filedata)
21461{
21462 if (filedata)
21463 {
21464 if (filedata->handle)
21465 fclose (filedata->handle);
21466 free (filedata);
21467 }
21468}
21469
21470void
21471close_debug_file (void * data)
21472{
13acb58d 21473 free_filedata ((Filedata *) data);
dda8d76d
NC
21474 close_file ((Filedata *) data);
21475}
21476
21477static Filedata *
015dc7e1 21478open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21479{
21480 struct stat statbuf;
21481 Filedata * filedata = NULL;
21482
21483 if (stat (pathname, & statbuf) < 0
21484 || ! S_ISREG (statbuf.st_mode))
21485 goto fail;
21486
21487 filedata = calloc (1, sizeof * filedata);
21488 if (filedata == NULL)
21489 goto fail;
21490
21491 filedata->handle = fopen (pathname, "rb");
21492 if (filedata->handle == NULL)
21493 goto fail;
21494
21495 filedata->file_size = (bfd_size_type) statbuf.st_size;
21496 filedata->file_name = pathname;
ca0e11aa 21497 filedata->is_separate = is_separate;
dda8d76d
NC
21498
21499 if (! get_file_header (filedata))
21500 goto fail;
21501
4de91c10
AM
21502 if (!get_section_headers (filedata, false))
21503 goto fail;
dda8d76d
NC
21504
21505 return filedata;
21506
21507 fail:
21508 if (filedata)
21509 {
21510 if (filedata->handle)
21511 fclose (filedata->handle);
21512 free (filedata);
21513 }
21514 return NULL;
21515}
21516
21517void *
21518open_debug_file (const char * pathname)
21519{
015dc7e1 21520 return open_file (pathname, true);
dda8d76d
NC
21521}
21522
835f2fae
NC
21523static void
21524initialise_dump_sects (Filedata * filedata)
21525{
21526 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21527 Note we do this even if cmdline_dump_sects is empty because we
21528 must make sure that the dump_sets array is zeroed out before each
21529 object file is processed. */
21530 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21531 memset (filedata->dump.dump_sects, 0,
21532 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21533
21534 if (cmdline.num_dump_sects > 0)
21535 {
21536 if (filedata->dump.num_dump_sects == 0)
21537 /* A sneaky way of allocating the dump_sects array. */
21538 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21539
21540 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21541 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21542 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21543 }
21544}
21545
fb52b2f4
NC
21546/* Process one ELF object file according to the command line options.
21547 This file may actually be stored in an archive. The file is
32ec8896
NC
21548 positioned at the start of the ELF object. Returns TRUE if no
21549 problems were encountered, FALSE otherwise. */
fb52b2f4 21550
015dc7e1 21551static bool
dda8d76d 21552process_object (Filedata * filedata)
252b5132 21553{
015dc7e1 21554 bool have_separate_files;
252b5132 21555 unsigned int i;
015dc7e1 21556 bool res;
252b5132 21557
dda8d76d 21558 if (! get_file_header (filedata))
252b5132 21559 {
dda8d76d 21560 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21561 return false;
252b5132
RH
21562 }
21563
21564 /* Initialise per file variables. */
978c4450
AM
21565 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21566 filedata->version_info[i] = 0;
252b5132 21567
978c4450
AM
21568 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21569 filedata->dynamic_info[i] = 0;
21570 filedata->dynamic_info_DT_GNU_HASH = 0;
21571 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21572
21573 /* Process the file. */
21574 if (show_name)
dda8d76d 21575 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21576
835f2fae 21577 initialise_dump_sects (filedata);
d70c5fc7 21578
4de91c10
AM
21579 /* There may be some extensions in the first section header. Don't
21580 bomb if we can't read it. */
21581 get_section_headers (filedata, true);
21582
dda8d76d 21583 if (! process_file_header (filedata))
4de91c10
AM
21584 {
21585 res = false;
21586 goto out;
21587 }
252b5132 21588
e331b18d
AM
21589 /* Throw away the single section header read above, so that we
21590 re-read the entire set. */
21591 free (filedata->section_headers);
21592 filedata->section_headers = NULL;
21593
dda8d76d 21594 if (! process_section_headers (filedata))
2f62977e 21595 {
32ec8896 21596 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21597 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21598
2f62977e 21599 if (! do_using_dynamic)
015dc7e1 21600 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21601 }
252b5132 21602
dda8d76d 21603 if (! process_section_groups (filedata))
32ec8896 21604 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21605 do_unwind = false;
d1f5c6e3 21606
93df3340
AM
21607 process_program_headers (filedata);
21608
21609 res = process_dynamic_section (filedata);
252b5132 21610
dda8d76d 21611 if (! process_relocs (filedata))
015dc7e1 21612 res = false;
252b5132 21613
dda8d76d 21614 if (! process_unwind (filedata))
015dc7e1 21615 res = false;
4d6ed7c8 21616
dda8d76d 21617 if (! process_symbol_table (filedata))
015dc7e1 21618 res = false;
252b5132 21619
0f03783c 21620 if (! process_lto_symbol_tables (filedata))
015dc7e1 21621 res = false;
b9e920ec 21622
dda8d76d 21623 if (! process_syminfo (filedata))
015dc7e1 21624 res = false;
252b5132 21625
dda8d76d 21626 if (! process_version_sections (filedata))
015dc7e1 21627 res = false;
252b5132 21628
82ed9683 21629 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21630 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21631 else
015dc7e1 21632 have_separate_files = false;
dda8d76d
NC
21633
21634 if (! process_section_contents (filedata))
015dc7e1 21635 res = false;
f5842774 21636
24841daa 21637 if (have_separate_files)
dda8d76d 21638 {
24841daa
NC
21639 separate_info * d;
21640
21641 for (d = first_separate_info; d != NULL; d = d->next)
21642 {
835f2fae
NC
21643 initialise_dump_sects (d->handle);
21644
ca0e11aa 21645 if (process_links && ! process_file_header (d->handle))
015dc7e1 21646 res = false;
ca0e11aa 21647 else if (! process_section_headers (d->handle))
015dc7e1 21648 res = false;
d6bfbc39 21649 else if (! process_section_contents (d->handle))
015dc7e1 21650 res = false;
ca0e11aa
NC
21651 else if (process_links)
21652 {
ca0e11aa 21653 if (! process_section_groups (d->handle))
015dc7e1 21654 res = false;
93df3340 21655 process_program_headers (d->handle);
ca0e11aa 21656 if (! process_dynamic_section (d->handle))
015dc7e1 21657 res = false;
ca0e11aa 21658 if (! process_relocs (d->handle))
015dc7e1 21659 res = false;
ca0e11aa 21660 if (! process_unwind (d->handle))
015dc7e1 21661 res = false;
ca0e11aa 21662 if (! process_symbol_table (d->handle))
015dc7e1 21663 res = false;
ca0e11aa 21664 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21665 res = false;
ca0e11aa 21666 if (! process_syminfo (d->handle))
015dc7e1 21667 res = false;
ca0e11aa 21668 if (! process_version_sections (d->handle))
015dc7e1 21669 res = false;
ca0e11aa 21670 if (! process_notes (d->handle))
015dc7e1 21671 res = false;
ca0e11aa 21672 }
24841daa
NC
21673 }
21674
21675 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21676 }
21677
21678 if (! process_notes (filedata))
015dc7e1 21679 res = false;
103f02d3 21680
dda8d76d 21681 if (! process_gnu_liblist (filedata))
015dc7e1 21682 res = false;
047b2264 21683
dda8d76d 21684 if (! process_arch_specific (filedata))
015dc7e1 21685 res = false;
252b5132 21686
4de91c10 21687 out:
13acb58d 21688 free_filedata (filedata);
e4b17d5c 21689
19e6b90e 21690 free_debug_memory ();
18bd398b 21691
32ec8896 21692 return res;
252b5132
RH
21693}
21694
2cf0635d 21695/* Process an ELF archive.
32ec8896
NC
21696 On entry the file is positioned just after the ARMAG string.
21697 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21698
015dc7e1
AM
21699static bool
21700process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21701{
21702 struct archive_info arch;
21703 struct archive_info nested_arch;
21704 size_t got;
015dc7e1 21705 bool ret = true;
2cf0635d 21706
015dc7e1 21707 show_name = true;
2cf0635d
NC
21708
21709 /* The ARCH structure is used to hold information about this archive. */
21710 arch.file_name = NULL;
21711 arch.file = NULL;
21712 arch.index_array = NULL;
21713 arch.sym_table = NULL;
21714 arch.longnames = NULL;
21715
21716 /* The NESTED_ARCH structure is used as a single-item cache of information
21717 about a nested archive (when members of a thin archive reside within
21718 another regular archive file). */
21719 nested_arch.file_name = NULL;
21720 nested_arch.file = NULL;
21721 nested_arch.index_array = NULL;
21722 nested_arch.sym_table = NULL;
21723 nested_arch.longnames = NULL;
21724
dda8d76d 21725 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21726 filedata->file_size, is_thin_archive,
21727 do_archive_index) != 0)
2cf0635d 21728 {
015dc7e1 21729 ret = false;
2cf0635d 21730 goto out;
4145f1d5 21731 }
fb52b2f4 21732
4145f1d5
NC
21733 if (do_archive_index)
21734 {
2cf0635d 21735 if (arch.sym_table == NULL)
1cb7d8b1
AM
21736 error (_("%s: unable to dump the index as none was found\n"),
21737 filedata->file_name);
4145f1d5
NC
21738 else
21739 {
591f7597 21740 unsigned long i, l;
4145f1d5
NC
21741 unsigned long current_pos;
21742
1cb7d8b1
AM
21743 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21744 "in the symbol table)\n"),
21745 filedata->file_name, (unsigned long) arch.index_num,
21746 arch.sym_size);
dda8d76d
NC
21747
21748 current_pos = ftell (filedata->handle);
4145f1d5 21749
2cf0635d 21750 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21751 {
1cb7d8b1
AM
21752 if (i == 0
21753 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21754 {
21755 char * member_name
21756 = get_archive_member_name_at (&arch, arch.index_array[i],
21757 &nested_arch);
2cf0635d 21758
1cb7d8b1
AM
21759 if (member_name != NULL)
21760 {
21761 char * qualified_name
21762 = make_qualified_name (&arch, &nested_arch,
21763 member_name);
2cf0635d 21764
1cb7d8b1
AM
21765 if (qualified_name != NULL)
21766 {
21767 printf (_("Contents of binary %s at offset "),
21768 qualified_name);
c2a7d3f5
NC
21769 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21770 putchar ('\n');
1cb7d8b1
AM
21771 free (qualified_name);
21772 }
fd486f32 21773 free (member_name);
4145f1d5
NC
21774 }
21775 }
2cf0635d
NC
21776
21777 if (l >= arch.sym_size)
4145f1d5 21778 {
1cb7d8b1
AM
21779 error (_("%s: end of the symbol table reached "
21780 "before the end of the index\n"),
dda8d76d 21781 filedata->file_name);
015dc7e1 21782 ret = false;
cb8f3167 21783 break;
4145f1d5 21784 }
591f7597 21785 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21786 printf ("\t%.*s\n",
21787 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21788 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21789 }
21790
67ce483b 21791 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21792 l = (l + 7) & ~ 7;
21793 else
21794 l += l & 1;
21795
2cf0635d 21796 if (l < arch.sym_size)
32ec8896 21797 {
d3a49aa8
AM
21798 error (ngettext ("%s: %ld byte remains in the symbol table, "
21799 "but without corresponding entries in "
21800 "the index table\n",
21801 "%s: %ld bytes remain in the symbol table, "
21802 "but without corresponding entries in "
21803 "the index table\n",
21804 arch.sym_size - l),
dda8d76d 21805 filedata->file_name, arch.sym_size - l);
015dc7e1 21806 ret = false;
32ec8896 21807 }
4145f1d5 21808
dda8d76d 21809 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21810 {
1cb7d8b1
AM
21811 error (_("%s: failed to seek back to start of object files "
21812 "in the archive\n"),
dda8d76d 21813 filedata->file_name);
015dc7e1 21814 ret = false;
2cf0635d 21815 goto out;
4145f1d5 21816 }
fb52b2f4 21817 }
4145f1d5
NC
21818
21819 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21820 && !do_segments && !do_header && !do_dump && !do_version
21821 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21822 && !do_section_groups && !do_dyn_syms)
2cf0635d 21823 {
015dc7e1 21824 ret = true; /* Archive index only. */
2cf0635d
NC
21825 goto out;
21826 }
fb52b2f4
NC
21827 }
21828
fb52b2f4
NC
21829 while (1)
21830 {
2cf0635d
NC
21831 char * name;
21832 size_t namelen;
21833 char * qualified_name;
21834
21835 /* Read the next archive header. */
dda8d76d 21836 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21837 {
21838 error (_("%s: failed to seek to next archive header\n"),
21839 arch.file_name);
015dc7e1 21840 ret = false;
1cb7d8b1
AM
21841 break;
21842 }
dda8d76d 21843 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21844 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21845 {
21846 if (got == 0)
2cf0635d 21847 break;
28e817cc
NC
21848 /* PR 24049 - we cannot use filedata->file_name as this will
21849 have already been freed. */
21850 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21851
015dc7e1 21852 ret = false;
1cb7d8b1
AM
21853 break;
21854 }
2cf0635d 21855 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21856 {
21857 error (_("%s: did not find a valid archive header\n"),
21858 arch.file_name);
015dc7e1 21859 ret = false;
1cb7d8b1
AM
21860 break;
21861 }
2cf0635d
NC
21862
21863 arch.next_arhdr_offset += sizeof arch.arhdr;
21864
978c4450 21865 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
21866
21867 name = get_archive_member_name (&arch, &nested_arch);
21868 if (name == NULL)
fb52b2f4 21869 {
28e817cc 21870 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21871 ret = false;
d989285c 21872 break;
fb52b2f4 21873 }
2cf0635d 21874 namelen = strlen (name);
fb52b2f4 21875
2cf0635d
NC
21876 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21877 if (qualified_name == NULL)
fb52b2f4 21878 {
28e817cc 21879 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21880 free (name);
015dc7e1 21881 ret = false;
d989285c 21882 break;
fb52b2f4
NC
21883 }
21884
2cf0635d 21885 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21886 {
21887 /* This is a proxy for an external member of a thin archive. */
21888 Filedata * member_filedata;
21889 char * member_file_name = adjust_relative_path
dda8d76d 21890 (filedata->file_name, name, namelen);
32ec8896 21891
fd486f32 21892 free (name);
1cb7d8b1
AM
21893 if (member_file_name == NULL)
21894 {
fd486f32 21895 free (qualified_name);
015dc7e1 21896 ret = false;
1cb7d8b1
AM
21897 break;
21898 }
2cf0635d 21899
015dc7e1 21900 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21901 if (member_filedata == NULL)
21902 {
21903 error (_("Input file '%s' is not readable.\n"), member_file_name);
21904 free (member_file_name);
fd486f32 21905 free (qualified_name);
015dc7e1 21906 ret = false;
1cb7d8b1
AM
21907 break;
21908 }
2cf0635d 21909
978c4450 21910 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21911 member_filedata->file_name = qualified_name;
2cf0635d 21912
75a2da57
AH
21913 /* The call to process_object() expects the file to be at the beginning. */
21914 rewind (member_filedata->handle);
21915
1cb7d8b1 21916 if (! process_object (member_filedata))
015dc7e1 21917 ret = false;
2cf0635d 21918
1cb7d8b1
AM
21919 close_file (member_filedata);
21920 free (member_file_name);
1cb7d8b1 21921 }
2cf0635d 21922 else if (is_thin_archive)
1cb7d8b1
AM
21923 {
21924 Filedata thin_filedata;
eb02c04d 21925
1cb7d8b1 21926 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21927
a043396b
NC
21928 /* PR 15140: Allow for corrupt thin archives. */
21929 if (nested_arch.file == NULL)
21930 {
21931 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21932 qualified_name, name);
fd486f32
AM
21933 free (qualified_name);
21934 free (name);
015dc7e1 21935 ret = false;
a043396b
NC
21936 break;
21937 }
fd486f32 21938 free (name);
a043396b 21939
1cb7d8b1 21940 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21941 filedata->archive_file_offset
21942 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21943
1cb7d8b1
AM
21944 /* The nested archive file will have been opened and setup by
21945 get_archive_member_name. */
978c4450
AM
21946 if (fseek (nested_arch.file, filedata->archive_file_offset,
21947 SEEK_SET) != 0)
1cb7d8b1
AM
21948 {
21949 error (_("%s: failed to seek to archive member.\n"),
21950 nested_arch.file_name);
fd486f32 21951 free (qualified_name);
015dc7e1 21952 ret = false;
1cb7d8b1
AM
21953 break;
21954 }
2cf0635d 21955
dda8d76d
NC
21956 thin_filedata.handle = nested_arch.file;
21957 thin_filedata.file_name = qualified_name;
9abca702 21958
1cb7d8b1 21959 if (! process_object (& thin_filedata))
015dc7e1 21960 ret = false;
1cb7d8b1 21961 }
2cf0635d 21962 else
1cb7d8b1 21963 {
fd486f32 21964 free (name);
978c4450 21965 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21966 filedata->file_name = qualified_name;
1cb7d8b1 21967 if (! process_object (filedata))
015dc7e1 21968 ret = false;
237877b8 21969 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 21970 /* Stop looping with "negative" archive_file_size. */
978c4450 21971 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21972 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21973 }
fb52b2f4 21974
2cf0635d 21975 free (qualified_name);
fb52b2f4
NC
21976 }
21977
4145f1d5 21978 out:
2cf0635d
NC
21979 if (nested_arch.file != NULL)
21980 fclose (nested_arch.file);
21981 release_archive (&nested_arch);
21982 release_archive (&arch);
fb52b2f4 21983
d989285c 21984 return ret;
fb52b2f4
NC
21985}
21986
015dc7e1 21987static bool
2cf0635d 21988process_file (char * file_name)
fb52b2f4 21989{
dda8d76d 21990 Filedata * filedata = NULL;
fb52b2f4
NC
21991 struct stat statbuf;
21992 char armag[SARMAG];
015dc7e1 21993 bool ret = true;
fb52b2f4
NC
21994
21995 if (stat (file_name, &statbuf) < 0)
21996 {
f24ddbdd
NC
21997 if (errno == ENOENT)
21998 error (_("'%s': No such file\n"), file_name);
21999 else
22000 error (_("Could not locate '%s'. System error message: %s\n"),
22001 file_name, strerror (errno));
015dc7e1 22002 return false;
f24ddbdd
NC
22003 }
22004
22005 if (! S_ISREG (statbuf.st_mode))
22006 {
22007 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22008 return false;
fb52b2f4
NC
22009 }
22010
dda8d76d
NC
22011 filedata = calloc (1, sizeof * filedata);
22012 if (filedata == NULL)
22013 {
22014 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22015 return false;
dda8d76d
NC
22016 }
22017
22018 filedata->file_name = file_name;
22019 filedata->handle = fopen (file_name, "rb");
22020 if (filedata->handle == NULL)
fb52b2f4 22021 {
f24ddbdd 22022 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22023 free (filedata);
015dc7e1 22024 return false;
fb52b2f4
NC
22025 }
22026
dda8d76d 22027 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22028 {
4145f1d5 22029 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22030 fclose (filedata->handle);
22031 free (filedata);
015dc7e1 22032 return false;
fb52b2f4
NC
22033 }
22034
dda8d76d 22035 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22036 filedata->is_separate = false;
f54498b4 22037
fb52b2f4 22038 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22039 {
015dc7e1
AM
22040 if (! process_archive (filedata, false))
22041 ret = false;
32ec8896 22042 }
2cf0635d 22043 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22044 {
015dc7e1
AM
22045 if ( ! process_archive (filedata, true))
22046 ret = false;
32ec8896 22047 }
fb52b2f4
NC
22048 else
22049 {
1b513401 22050 if (do_archive_index && !check_all)
4145f1d5
NC
22051 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22052 file_name);
22053
dda8d76d 22054 rewind (filedata->handle);
978c4450 22055 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22056
dda8d76d 22057 if (! process_object (filedata))
015dc7e1 22058 ret = false;
fb52b2f4
NC
22059 }
22060
dda8d76d 22061 fclose (filedata->handle);
8fb879cd
AM
22062 free (filedata->section_headers);
22063 free (filedata->program_headers);
22064 free (filedata->string_table);
6431e409 22065 free (filedata->dump.dump_sects);
dda8d76d 22066 free (filedata);
32ec8896 22067
fd486f32 22068 free (ba_cache.strtab);
1bd6175a 22069 ba_cache.strtab = NULL;
fd486f32 22070 free (ba_cache.symtab);
1bd6175a 22071 ba_cache.symtab = NULL;
fd486f32
AM
22072 ba_cache.filedata = NULL;
22073
fb52b2f4
NC
22074 return ret;
22075}
22076
252b5132
RH
22077#ifdef SUPPORT_DISASSEMBLY
22078/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22079 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22080 symbols. */
252b5132
RH
22081
22082void
2cf0635d 22083print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22084{
22085 fprintf (outfile,"0x%8.8x", addr);
22086}
22087
e3c8793a 22088/* Needed by the i386 disassembler. */
dda8d76d 22089
252b5132
RH
22090void
22091db_task_printsym (unsigned int addr)
22092{
22093 print_address (addr, stderr);
22094}
22095#endif
22096
22097int
2cf0635d 22098main (int argc, char ** argv)
252b5132 22099{
ff78d6d6
L
22100 int err;
22101
87b9f255 22102#ifdef HAVE_LC_MESSAGES
252b5132 22103 setlocale (LC_MESSAGES, "");
3882b010 22104#endif
3882b010 22105 setlocale (LC_CTYPE, "");
252b5132
RH
22106 bindtextdomain (PACKAGE, LOCALEDIR);
22107 textdomain (PACKAGE);
22108
869b9d07
MM
22109 expandargv (&argc, &argv);
22110
dda8d76d 22111 parse_args (& cmdline, argc, argv);
59f14fc0 22112
18bd398b 22113 if (optind < (argc - 1))
1b513401
NC
22114 /* When displaying information for more than one file,
22115 prefix the information with the file name. */
015dc7e1 22116 show_name = true;
5656ba2c
L
22117 else if (optind >= argc)
22118 {
1b513401 22119 /* Ensure that the warning is always displayed. */
015dc7e1 22120 do_checks = true;
1b513401 22121
5656ba2c
L
22122 warn (_("Nothing to do.\n"));
22123 usage (stderr);
22124 }
18bd398b 22125
015dc7e1 22126 err = false;
252b5132 22127 while (optind < argc)
32ec8896 22128 if (! process_file (argv[optind++]))
015dc7e1 22129 err = true;
252b5132 22130
9db70fc3 22131 free (cmdline.dump_sects);
252b5132 22132
7d9813f1
NA
22133 free (dump_ctf_symtab_name);
22134 free (dump_ctf_strtab_name);
22135 free (dump_ctf_parent_name);
22136
32ec8896 22137 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22138}