]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
opcodes: handle bfd_amdgcn_arch in configure script
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
a2c58332 2 Copyright (C) 1998-2022 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"
0d646226 60#include "demanguse.h"
19e6b90e 61#include "dwarf.h"
7d9813f1 62#include "ctf-api.h"
79bc120c 63#include "demangle.h"
252b5132
RH
64
65#include "elf/common.h"
66#include "elf/external.h"
67#include "elf/internal.h"
252b5132 68
4b78141a
NC
69
70/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
71 we can obtain the H8 reloc numbers. We need these for the
72 get_reloc_size() function. We include h8.h again after defining
73 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
74
75#include "elf/h8.h"
76#undef _ELF_H8_H
77
78/* Undo the effects of #including reloc-macros.h. */
79
80#undef START_RELOC_NUMBERS
81#undef RELOC_NUMBER
82#undef FAKE_RELOC
83#undef EMPTY_RELOC
84#undef END_RELOC_NUMBERS
85#undef _RELOC_MACROS_H
86
252b5132
RH
87/* The following headers use the elf/reloc-macros.h file to
88 automatically generate relocation recognition functions
89 such as elf_mips_reloc_type() */
90
91#define RELOC_MACROS_GEN_FUNC
92
a06ea964 93#include "elf/aarch64.h"
252b5132 94#include "elf/alpha.h"
3b16e843 95#include "elf/arc.h"
252b5132 96#include "elf/arm.h"
3b16e843 97#include "elf/avr.h"
1d65ded4 98#include "elf/bfin.h"
60bca95a 99#include "elf/cr16.h"
3b16e843 100#include "elf/cris.h"
1c0d3aa6 101#include "elf/crx.h"
b8891f8d 102#include "elf/csky.h"
252b5132
RH
103#include "elf/d10v.h"
104#include "elf/d30v.h"
d172d4ba 105#include "elf/dlx.h"
aca4efc7 106#include "elf/bpf.h"
cfb8c092 107#include "elf/epiphany.h"
252b5132 108#include "elf/fr30.h"
5c70f934 109#include "elf/frv.h"
3f8107ab 110#include "elf/ft32.h"
3b16e843
NC
111#include "elf/h8.h"
112#include "elf/hppa.h"
113#include "elf/i386.h"
f954747f
AM
114#include "elf/i370.h"
115#include "elf/i860.h"
116#include "elf/i960.h"
3b16e843 117#include "elf/ia64.h"
1e4cf259 118#include "elf/ip2k.h"
84e94c90 119#include "elf/lm32.h"
1c0d3aa6 120#include "elf/iq2000.h"
49f58d10 121#include "elf/m32c.h"
3b16e843
NC
122#include "elf/m32r.h"
123#include "elf/m68k.h"
75751cd9 124#include "elf/m68hc11.h"
7b4ae824 125#include "elf/s12z.h"
252b5132 126#include "elf/mcore.h"
15ab5209 127#include "elf/mep.h"
a3c62988 128#include "elf/metag.h"
7ba29e2a 129#include "elf/microblaze.h"
3b16e843 130#include "elf/mips.h"
3c3bdf30 131#include "elf/mmix.h"
3b16e843
NC
132#include "elf/mn10200.h"
133#include "elf/mn10300.h"
5506d11a 134#include "elf/moxie.h"
4970f871 135#include "elf/mt.h"
2469cfa2 136#include "elf/msp430.h"
35c08157 137#include "elf/nds32.h"
fe944acf 138#include "elf/nfp.h"
13761a11 139#include "elf/nios2.h"
73589c9d 140#include "elf/or1k.h"
7d466069 141#include "elf/pj.h"
3b16e843 142#include "elf/ppc.h"
c833c019 143#include "elf/ppc64.h"
2b100bb5 144#include "elf/pru.h"
03336641 145#include "elf/riscv.h"
99c513f6 146#include "elf/rl78.h"
c7927a3c 147#include "elf/rx.h"
a85d7ed0 148#include "elf/s390.h"
1c0d3aa6 149#include "elf/score.h"
3b16e843
NC
150#include "elf/sh.h"
151#include "elf/sparc.h"
e9f53129 152#include "elf/spu.h"
40b36596 153#include "elf/tic6x.h"
aa137e4d
NC
154#include "elf/tilegx.h"
155#include "elf/tilepro.h"
3b16e843 156#include "elf/v850.h"
179d3252 157#include "elf/vax.h"
619ed720 158#include "elf/visium.h"
f96bd6c2 159#include "elf/wasm32.h"
3b16e843 160#include "elf/x86-64.h"
c29aca4a 161#include "elf/xc16x.h"
f6c1a2d5 162#include "elf/xgate.h"
93fbbb04 163#include "elf/xstormy16.h"
88da6820 164#include "elf/xtensa.h"
6655dba2 165#include "elf/z80.h"
e9a0721f 166#include "elf/loongarch.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
015dc7e1
AM
215static bool show_name = false;
216static bool do_dynamic = false;
217static bool do_syms = false;
218static bool do_dyn_syms = false;
219static bool do_lto_syms = false;
220static bool do_reloc = false;
221static bool do_sections = false;
222static bool do_section_groups = false;
223static bool do_section_details = false;
224static bool do_segments = false;
225static bool do_unwind = false;
226static bool do_using_dynamic = false;
227static bool do_header = false;
228static bool do_dump = false;
229static bool do_version = false;
230static bool do_histogram = false;
231static bool do_debugging = false;
232static bool do_ctf = false;
233static bool do_arch = false;
234static bool do_notes = false;
235static bool do_archive_index = false;
236static bool check_all = false;
237static bool is_32bit_elf = false;
238static bool decompress_dumps = false;
239static bool do_not_show_symbol_truncation = false;
240static bool do_demangle = false; /* Pretty print C++ symbol names. */
241static bool process_links = false;
e1dbfc17 242static bool dump_any_debugging = false;
79bc120c 243static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 244static int sym_base = 0;
252b5132 245
7d9813f1
NA
246static char *dump_ctf_parent_name;
247static char *dump_ctf_symtab_name;
248static char *dump_ctf_strtab_name;
249
e4b17d5c
L
250struct group_list
251{
dda8d76d
NC
252 struct group_list * next;
253 unsigned int section_index;
e4b17d5c
L
254};
255
256struct group
257{
dda8d76d
NC
258 struct group_list * root;
259 unsigned int group_index;
e4b17d5c
L
260};
261
978c4450
AM
262typedef struct filedata
263{
264 const char * file_name;
015dc7e1 265 bool is_separate;
978c4450
AM
266 FILE * handle;
267 bfd_size_type file_size;
268 Elf_Internal_Ehdr file_header;
066f8fbe
AM
269 unsigned long archive_file_offset;
270 unsigned long archive_file_size;
271 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
272 Elf_Internal_Shdr * section_headers;
273 Elf_Internal_Phdr * program_headers;
274 char * string_table;
275 unsigned long string_table_length;
978c4450
AM
276 unsigned long dynamic_addr;
277 bfd_size_type dynamic_size;
278 size_t dynamic_nent;
279 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 280 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
281 char * dynamic_strings;
282 unsigned long dynamic_strings_length;
8ac10c5b 283 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
284 unsigned long num_dynamic_syms;
285 Elf_Internal_Sym * dynamic_symbols;
286 bfd_vma version_info[16];
287 unsigned int dynamic_syminfo_nent;
288 Elf_Internal_Syminfo * dynamic_syminfo;
289 unsigned long dynamic_syminfo_offset;
290 bfd_size_type nbuckets;
291 bfd_size_type nchains;
292 bfd_vma * buckets;
293 bfd_vma * chains;
294 bfd_size_type ngnubuckets;
295 bfd_size_type ngnuchains;
296 bfd_vma * gnubuckets;
297 bfd_vma * gnuchains;
298 bfd_vma * mipsxlat;
299 bfd_vma gnusymidx;
13acb58d 300 char * program_interpreter;
978c4450
AM
301 bfd_vma dynamic_info[DT_ENCODING];
302 bfd_vma dynamic_info_DT_GNU_HASH;
303 bfd_vma dynamic_info_DT_MIPS_XHASH;
304 elf_section_list * symtab_shndx_list;
305 size_t group_count;
306 struct group * section_groups;
307 struct group ** section_headers_groups;
308 /* A dynamic array of flags indicating for which sections a dump of
309 some kind has been requested. It is reset on a per-object file
310 basis and then initialised from the cmdline_dump_sects array,
311 the results of interpreting the -w switch, and the
312 dump_sects_byname list. */
313 struct dump_data dump;
314} Filedata;
aef1f6d0 315
c256ffe7 316/* How to print a vma value. */
843dd992
NC
317typedef enum print_mode
318{
319 HEX,
047c3dbf 320 HEX_5,
843dd992
NC
321 DEC,
322 DEC_5,
323 UNSIGNED,
047c3dbf 324 UNSIGNED_5,
843dd992 325 PREFIX_HEX,
047c3dbf 326 PREFIX_HEX_5,
843dd992 327 FULL_HEX,
047c3dbf
NL
328 LONG_HEX,
329 OCTAL,
330 OCTAL_5
843dd992
NC
331}
332print_mode;
333
b3aa80b4
NC
334typedef enum unicode_display_type
335{
336 unicode_default = 0,
337 unicode_locale,
338 unicode_escape,
339 unicode_hex,
340 unicode_highlight,
341 unicode_invalid
342} unicode_display_type;
343
344static unicode_display_type unicode_display = unicode_default;
345
a7fd1186
FS
346typedef enum
347{
348 reltype_unknown,
349 reltype_rel,
350 reltype_rela,
351 reltype_relr
352} relocation_type;
353
bb4d2ac2
L
354/* Versioned symbol info. */
355enum versioned_symbol_info
356{
357 symbol_undefined,
358 symbol_hidden,
359 symbol_public
360};
361
32ec8896 362static const char * get_symbol_version_string
015dc7e1 363 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 364 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 365
9c19a809
NC
366#define UNKNOWN -1
367
84714f86
AM
368static inline const char *
369section_name (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
370{
371 return filedata->string_table + hdr->sh_name;
372}
b9e920ec 373
84714f86
AM
374static inline bool
375section_name_valid (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
376{
377 return (hdr != NULL
378 && filedata->string_table != NULL
379 && hdr->sh_name < filedata->string_table_length);
380}
b9e920ec 381
84714f86
AM
382static inline const char *
383section_name_print (const Filedata *filedata, const Elf_Internal_Shdr *hdr)
384{
385 if (hdr == NULL)
386 return _("<none>");
387 if (filedata->string_table == NULL)
388 return _("<no-strings>");
389 if (hdr->sh_name >= filedata->string_table_length)
390 return _("<corrupt>");
391 return section_name (filedata, hdr);
392}
252b5132 393
ee42cf8c 394#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 395
84714f86
AM
396static inline bool
397valid_symbol_name (const char *strtab, size_t strtab_size, uint64_t offset)
398{
399 return strtab != NULL && offset < strtab_size;
400}
401
402static inline bool
403valid_dynamic_name (const Filedata *filedata, uint64_t offset)
404{
405 return valid_symbol_name (filedata->dynamic_strings,
406 filedata->dynamic_strings_length, offset);
407}
408
d79b3d50
NC
409/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
410 already been called and verified that the string exists. */
84714f86
AM
411static inline const char *
412get_dynamic_name (const Filedata *filedata, size_t offset)
413{
414 return filedata->dynamic_strings + offset;
415}
18bd398b 416
61865e30
NC
417#define REMOVE_ARCH_BITS(ADDR) \
418 do \
419 { \
dda8d76d 420 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
421 (ADDR) &= ~1; \
422 } \
423 while (0)
f16a9783
MS
424
425/* Get the correct GNU hash section name. */
978c4450
AM
426#define GNU_HASH_SECTION_NAME(filedata) \
427 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 428\f
66cfc0fd
AM
429/* Print a BFD_VMA to an internal buffer, for use in error messages.
430 BFD_FMA_FMT can't be used in translated strings. */
431
432static const char *
433bfd_vmatoa (char *fmtch, bfd_vma value)
434{
435 /* bfd_vmatoa is used more then once in a printf call for output.
436 Cycle through an array of buffers. */
437 static int buf_pos = 0;
438 static struct bfd_vmatoa_buf
439 {
440 char place[64];
441 } buf[4];
442 char *ret;
443 char fmt[32];
444
445 ret = buf[buf_pos++].place;
446 buf_pos %= ARRAY_SIZE (buf);
447
448 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
449 snprintf (ret, sizeof (buf[0].place), fmt, value);
450 return ret;
451}
452
dda8d76d
NC
453/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
454 OFFSET + the offset of the current archive member, if we are examining an
455 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
456 allocate a buffer using malloc and fill that. In either case return the
457 pointer to the start of the retrieved data or NULL if something went wrong.
458 If something does go wrong and REASON is not NULL then emit an error
459 message using REASON as part of the context. */
59245841 460
c256ffe7 461static void *
dda8d76d
NC
462get_data (void * var,
463 Filedata * filedata,
464 unsigned long offset,
465 bfd_size_type size,
466 bfd_size_type nmemb,
467 const char * reason)
a6e9f9df 468{
2cf0635d 469 void * mvar;
57028622 470 bfd_size_type amt = size * nmemb;
a6e9f9df 471
c256ffe7 472 if (size == 0 || nmemb == 0)
a6e9f9df
AM
473 return NULL;
474
57028622
NC
475 /* If the size_t type is smaller than the bfd_size_type, eg because
476 you are building a 32-bit tool on a 64-bit host, then make sure
477 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
478 if ((size_t) size != size
479 || (size_t) nmemb != nmemb
480 || (size_t) amt != amt)
57028622
NC
481 {
482 if (reason)
66cfc0fd
AM
483 error (_("Size truncation prevents reading %s"
484 " elements of size %s for %s\n"),
485 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
486 return NULL;
487 }
488
489 /* Check for size overflow. */
7c1c1904 490 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
491 {
492 if (reason)
66cfc0fd
AM
493 error (_("Size overflow prevents reading %s"
494 " elements of size %s for %s\n"),
495 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
496 return NULL;
497 }
498
c22b42ce 499 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 500 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
501 if (filedata->archive_file_offset > filedata->file_size
502 || offset > filedata->file_size - filedata->archive_file_offset
503 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 504 {
049b0c3a 505 if (reason)
66cfc0fd
AM
506 error (_("Reading %s bytes extends past end of file for %s\n"),
507 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
508 return NULL;
509 }
510
978c4450
AM
511 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
512 SEEK_SET))
071436c6
NC
513 {
514 if (reason)
c9c1d674 515 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 516 filedata->archive_file_offset + offset, reason);
071436c6
NC
517 return NULL;
518 }
519
a6e9f9df
AM
520 mvar = var;
521 if (mvar == NULL)
522 {
7c1c1904
AM
523 /* + 1 so that we can '\0' terminate invalid string table sections. */
524 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
525
526 if (mvar == NULL)
527 {
049b0c3a 528 if (reason)
66cfc0fd
AM
529 error (_("Out of memory allocating %s bytes for %s\n"),
530 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
531 return NULL;
532 }
c256ffe7 533
c9c1d674 534 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
535 }
536
dda8d76d 537 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 538 {
049b0c3a 539 if (reason)
66cfc0fd
AM
540 error (_("Unable to read in %s bytes of %s\n"),
541 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
542 if (mvar != var)
543 free (mvar);
544 return NULL;
545 }
546
547 return mvar;
548}
549
32ec8896
NC
550/* Print a VMA value in the MODE specified.
551 Returns the number of characters displayed. */
cb8f3167 552
32ec8896 553static unsigned int
14a91970 554print_vma (bfd_vma vma, print_mode mode)
66543521 555{
32ec8896 556 unsigned int nc = 0;
66543521 557
14a91970 558 switch (mode)
66543521 559 {
14a91970
AM
560 case FULL_HEX:
561 nc = printf ("0x");
1a0670f3 562 /* Fall through. */
14a91970 563 case LONG_HEX:
f7a99963 564#ifdef BFD64
14a91970 565 if (is_32bit_elf)
437c2fb7 566 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 567#endif
14a91970
AM
568 printf_vma (vma);
569 return nc + 16;
b19aac67 570
14a91970
AM
571 case DEC_5:
572 if (vma <= 99999)
573 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 574 /* Fall through. */
14a91970
AM
575 case PREFIX_HEX:
576 nc = printf ("0x");
1a0670f3 577 /* Fall through. */
14a91970
AM
578 case HEX:
579 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 580
047c3dbf
NL
581 case PREFIX_HEX_5:
582 nc = printf ("0x");
583 /* Fall through. */
584 case HEX_5:
585 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
586
14a91970
AM
587 case DEC:
588 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 589
14a91970
AM
590 case UNSIGNED:
591 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 592
047c3dbf
NL
593 case UNSIGNED_5:
594 return printf ("%5" BFD_VMA_FMT "u", vma);
595
596 case OCTAL:
597 return printf ("%" BFD_VMA_FMT "o", vma);
598
599 case OCTAL_5:
600 return printf ("%5" BFD_VMA_FMT "o", vma);
601
32ec8896
NC
602 default:
603 /* FIXME: Report unrecognised mode ? */
604 return 0;
f7a99963 605 }
f7a99963
NC
606}
607
047c3dbf 608
7bfd842d 609/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 610 multibye characters (assuming the host environment supports them).
31104126 611
7bfd842d
NC
612 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
613
0942c7ab
NC
614 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
615 abs(WIDTH) - 5 characters followed by "[...]".
616
7bfd842d
NC
617 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
618 padding as necessary.
171191ba
NC
619
620 Returns the number of emitted characters. */
621
622static unsigned int
0942c7ab 623print_symbol (signed int width, const char * symbol)
31104126 624{
015dc7e1
AM
625 bool extra_padding = false;
626 bool do_dots = false;
32ec8896 627 signed int num_printed = 0;
3bfcb652 628#ifdef HAVE_MBSTATE_T
7bfd842d 629 mbstate_t state;
3bfcb652 630#endif
32ec8896 631 unsigned int width_remaining;
79bc120c 632 const void * alloced_symbol = NULL;
961c521f 633
7bfd842d 634 if (width < 0)
961c521f 635 {
88305e1b 636 /* Keep the width positive. This helps the code below. */
961c521f 637 width = - width;
015dc7e1 638 extra_padding = true;
0b4362b0 639 }
56d8f8a9
NC
640 else if (width == 0)
641 return 0;
961c521f 642
7bfd842d
NC
643 if (do_wide)
644 /* Set the remaining width to a very large value.
645 This simplifies the code below. */
646 width_remaining = INT_MAX;
647 else
0942c7ab
NC
648 {
649 width_remaining = width;
650 if (! do_not_show_symbol_truncation
651 && (int) strlen (symbol) > width)
652 {
653 width_remaining -= 5;
654 if ((int) width_remaining < 0)
655 width_remaining = 0;
015dc7e1 656 do_dots = true;
0942c7ab
NC
657 }
658 }
cb8f3167 659
3bfcb652 660#ifdef HAVE_MBSTATE_T
7bfd842d
NC
661 /* Initialise the multibyte conversion state. */
662 memset (& state, 0, sizeof (state));
3bfcb652 663#endif
961c521f 664
79bc120c
NC
665 if (do_demangle && *symbol)
666 {
667 const char * res = cplus_demangle (symbol, demangle_flags);
668
669 if (res != NULL)
670 alloced_symbol = symbol = res;
671 }
672
7bfd842d
NC
673 while (width_remaining)
674 {
675 size_t n;
7bfd842d 676 const char c = *symbol++;
961c521f 677
7bfd842d 678 if (c == 0)
961c521f
NC
679 break;
680
b3aa80b4
NC
681 if (ISPRINT (c))
682 {
683 putchar (c);
684 width_remaining --;
685 num_printed ++;
686 }
687 else if (ISCNTRL (c))
961c521f 688 {
b3aa80b4
NC
689 /* Do not print control characters directly as they can affect terminal
690 settings. Such characters usually appear in the names generated
691 by the assembler for local labels. */
692
7bfd842d 693 if (width_remaining < 2)
961c521f
NC
694 break;
695
7bfd842d
NC
696 printf ("^%c", c + 0x40);
697 width_remaining -= 2;
171191ba 698 num_printed += 2;
961c521f 699 }
b3aa80b4 700 else if (c == 0x7f)
7bfd842d 701 {
b3aa80b4
NC
702 if (width_remaining < 5)
703 break;
704 printf ("<DEL>");
705 width_remaining -= 5;
706 num_printed += 5;
707 }
708 else if (unicode_display != unicode_locale
709 && unicode_display != unicode_default)
710 {
711 /* Display unicode characters as something else. */
712 unsigned char bytes[4];
713 bool is_utf8;
795588ae 714 unsigned int nbytes;
b3aa80b4
NC
715
716 bytes[0] = c;
717
718 if (bytes[0] < 0xc0)
719 {
720 nbytes = 1;
721 is_utf8 = false;
722 }
723 else
724 {
725 bytes[1] = *symbol++;
726
727 if ((bytes[1] & 0xc0) != 0x80)
728 {
729 is_utf8 = false;
730 /* Do not consume this character. It may only
731 be the first byte in the sequence that was
732 corrupt. */
733 --symbol;
734 nbytes = 1;
735 }
736 else if ((bytes[0] & 0x20) == 0)
737 {
738 is_utf8 = true;
739 nbytes = 2;
740 }
741 else
742 {
743 bytes[2] = *symbol++;
744
745 if ((bytes[2] & 0xc0) != 0x80)
746 {
747 is_utf8 = false;
748 symbol -= 2;
749 nbytes = 1;
750 }
751 else if ((bytes[0] & 0x10) == 0)
752 {
753 is_utf8 = true;
754 nbytes = 3;
755 }
756 else
757 {
758 bytes[3] = *symbol++;
759
760 nbytes = 4;
761
762 if ((bytes[3] & 0xc0) != 0x80)
763 {
764 is_utf8 = false;
765 symbol -= 3;
766 nbytes = 1;
767 }
768 else
769 is_utf8 = true;
770 }
771 }
772 }
773
774 if (unicode_display == unicode_invalid)
775 is_utf8 = false;
776
777 if (unicode_display == unicode_hex || ! is_utf8)
778 {
795588ae 779 unsigned int i;
b3aa80b4
NC
780
781 if (width_remaining < (nbytes * 2) + 2)
782 break;
783
784 putchar (is_utf8 ? '<' : '{');
785 printf ("0x");
786 for (i = 0; i < nbytes; i++)
787 printf ("%02x", bytes[i]);
788 putchar (is_utf8 ? '>' : '}');
789 }
790 else
791 {
792 if (unicode_display == unicode_highlight && isatty (1))
793 printf ("\x1B[31;47m"); /* Red. */
794
795 switch (nbytes)
796 {
797 case 2:
798 if (width_remaining < 6)
799 break;
800 printf ("\\u%02x%02x",
801 (bytes[0] & 0x1c) >> 2,
802 ((bytes[0] & 0x03) << 6) | (bytes[1] & 0x3f));
803 break;
804 case 3:
805 if (width_remaining < 6)
806 break;
807 printf ("\\u%02x%02x",
808 ((bytes[0] & 0x0f) << 4) | ((bytes[1] & 0x3c) >> 2),
809 ((bytes[1] & 0x03) << 6) | (bytes[2] & 0x3f));
810 break;
811 case 4:
812 if (width_remaining < 8)
813 break;
814 printf ("\\u%02x%02x%02x",
815 ((bytes[0] & 0x07) << 6) | ((bytes[1] & 0x3c) >> 2),
816 ((bytes[1] & 0x03) << 6) | ((bytes[2] & 0x3c) >> 2),
817 ((bytes[2] & 0x03) << 6) | (bytes[3] & 0x3f));
818
819 break;
820 default:
821 /* URG. */
822 break;
823 }
824
825 if (unicode_display == unicode_highlight && isatty (1))
826 printf ("\033[0m"); /* Default colour. */
827 }
828
829 if (bytes[nbytes - 1] == 0)
830 break;
7bfd842d 831 }
961c521f
NC
832 else
833 {
3bfcb652
NC
834#ifdef HAVE_MBSTATE_T
835 wchar_t w;
836#endif
7bfd842d
NC
837 /* Let printf do the hard work of displaying multibyte characters. */
838 printf ("%.1s", symbol - 1);
839 width_remaining --;
840 num_printed ++;
841
3bfcb652 842#ifdef HAVE_MBSTATE_T
7bfd842d
NC
843 /* Try to find out how many bytes made up the character that was
844 just printed. Advance the symbol pointer past the bytes that
845 were displayed. */
846 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
847#else
848 n = 1;
849#endif
7bfd842d
NC
850 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
851 symbol += (n - 1);
961c521f 852 }
961c521f 853 }
171191ba 854
0942c7ab
NC
855 if (do_dots)
856 num_printed += printf ("[...]");
857
7bfd842d 858 if (extra_padding && num_printed < width)
171191ba
NC
859 {
860 /* Fill in the remaining spaces. */
7bfd842d
NC
861 printf ("%-*s", width - num_printed, " ");
862 num_printed = width;
171191ba
NC
863 }
864
79bc120c 865 free ((void *) alloced_symbol);
171191ba 866 return num_printed;
31104126
NC
867}
868
1449284b 869/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
870 the given section's name. Like print_symbol, except that it does not try
871 to print multibyte characters, it just interprets them as hex values. */
872
873static const char *
dda8d76d 874printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 875{
ca0e11aa 876#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 877 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
84714f86 878 const char * name = section_name_print (filedata, sec);
74e1a04b
NC
879 char * buf = sec_name_buf;
880 char c;
881 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
882
883 while ((c = * name ++) != 0)
884 {
885 if (ISCNTRL (c))
886 {
887 if (remaining < 2)
888 break;
948f632f 889
74e1a04b
NC
890 * buf ++ = '^';
891 * buf ++ = c + 0x40;
892 remaining -= 2;
893 }
894 else if (ISPRINT (c))
895 {
896 * buf ++ = c;
897 remaining -= 1;
898 }
899 else
900 {
901 static char hex[17] = "0123456789ABCDEF";
902
903 if (remaining < 4)
904 break;
905 * buf ++ = '<';
906 * buf ++ = hex[(c & 0xf0) >> 4];
907 * buf ++ = hex[c & 0x0f];
908 * buf ++ = '>';
909 remaining -= 4;
910 }
911
912 if (remaining == 0)
913 break;
914 }
915
916 * buf = 0;
917 return sec_name_buf;
918}
919
920static const char *
dda8d76d 921printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 922{
dda8d76d 923 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
924 return _("<corrupt>");
925
dda8d76d 926 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
927}
928
89fac5e3
RS
929/* Return a pointer to section NAME, or NULL if no such section exists. */
930
931static Elf_Internal_Shdr *
dda8d76d 932find_section (Filedata * filedata, const char * name)
89fac5e3
RS
933{
934 unsigned int i;
935
68807c3c
NC
936 if (filedata->section_headers == NULL)
937 return NULL;
dda8d76d
NC
938
939 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
940 if (section_name_valid (filedata, filedata->section_headers + i)
941 && streq (section_name (filedata, filedata->section_headers + i),
942 name))
dda8d76d 943 return filedata->section_headers + i;
89fac5e3
RS
944
945 return NULL;
946}
947
0b6ae522
DJ
948/* Return a pointer to a section containing ADDR, or NULL if no such
949 section exists. */
950
951static Elf_Internal_Shdr *
dda8d76d 952find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
953{
954 unsigned int i;
955
68807c3c
NC
956 if (filedata->section_headers == NULL)
957 return NULL;
958
dda8d76d 959 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 960 {
dda8d76d
NC
961 Elf_Internal_Shdr *sec = filedata->section_headers + i;
962
0b6ae522
DJ
963 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
964 return sec;
965 }
966
967 return NULL;
968}
969
071436c6 970static Elf_Internal_Shdr *
dda8d76d 971find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
972{
973 unsigned int i;
974
68807c3c
NC
975 if (filedata->section_headers == NULL)
976 return NULL;
977
dda8d76d 978 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 979 {
dda8d76d
NC
980 Elf_Internal_Shdr *sec = filedata->section_headers + i;
981
071436c6
NC
982 if (sec->sh_type == type)
983 return sec;
984 }
985
986 return NULL;
987}
988
657d0d47
CC
989/* Return a pointer to section NAME, or NULL if no such section exists,
990 restricted to the list of sections given in SET. */
991
992static Elf_Internal_Shdr *
dda8d76d 993find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
994{
995 unsigned int i;
996
68807c3c
NC
997 if (filedata->section_headers == NULL)
998 return NULL;
999
657d0d47
CC
1000 if (set != NULL)
1001 {
1002 while ((i = *set++) > 0)
b814a36d
NC
1003 {
1004 /* See PR 21156 for a reproducer. */
dda8d76d 1005 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
1006 continue; /* FIXME: Should we issue an error message ? */
1007
84714f86
AM
1008 if (section_name_valid (filedata, filedata->section_headers + i)
1009 && streq (section_name (filedata, filedata->section_headers + i),
1010 name))
dda8d76d 1011 return filedata->section_headers + i;
b814a36d 1012 }
657d0d47
CC
1013 }
1014
dda8d76d 1015 return find_section (filedata, name);
657d0d47
CC
1016}
1017
32ec8896 1018/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
1019 This OS has so many departures from the ELF standard that we test it at
1020 many places. */
1021
015dc7e1 1022static inline bool
dda8d76d 1023is_ia64_vms (Filedata * filedata)
28f997cf 1024{
dda8d76d
NC
1025 return filedata->file_header.e_machine == EM_IA_64
1026 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
1027}
1028
bcedfee6 1029/* Guess the relocation size commonly used by the specific machines. */
252b5132 1030
015dc7e1 1031static bool
2dc4cec1 1032guess_is_rela (unsigned int e_machine)
252b5132 1033{
9c19a809 1034 switch (e_machine)
252b5132
RH
1035 {
1036 /* Targets that use REL relocations. */
252b5132 1037 case EM_386:
22abe556 1038 case EM_IAMCU:
f954747f 1039 case EM_960:
e9f53129 1040 case EM_ARM:
2b0337b0 1041 case EM_D10V:
252b5132 1042 case EM_CYGNUS_D10V:
e9f53129 1043 case EM_DLX:
252b5132 1044 case EM_MIPS:
4fe85591 1045 case EM_MIPS_RS3_LE:
e9f53129 1046 case EM_CYGNUS_M32R:
1c0d3aa6 1047 case EM_SCORE:
f6c1a2d5 1048 case EM_XGATE:
fe944acf 1049 case EM_NFP:
aca4efc7 1050 case EM_BPF:
015dc7e1 1051 return false;
103f02d3 1052
252b5132
RH
1053 /* Targets that use RELA relocations. */
1054 case EM_68K:
f954747f 1055 case EM_860:
a06ea964 1056 case EM_AARCH64:
cfb8c092 1057 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
1058 case EM_ALPHA:
1059 case EM_ALTERA_NIOS2:
886a2506
NC
1060 case EM_ARC:
1061 case EM_ARC_COMPACT:
1062 case EM_ARC_COMPACT2:
e9f53129
AM
1063 case EM_AVR:
1064 case EM_AVR_OLD:
1065 case EM_BLACKFIN:
60bca95a 1066 case EM_CR16:
e9f53129
AM
1067 case EM_CRIS:
1068 case EM_CRX:
b8891f8d 1069 case EM_CSKY:
2b0337b0 1070 case EM_D30V:
252b5132 1071 case EM_CYGNUS_D30V:
2b0337b0 1072 case EM_FR30:
3f8107ab 1073 case EM_FT32:
252b5132 1074 case EM_CYGNUS_FR30:
5c70f934 1075 case EM_CYGNUS_FRV:
e9f53129
AM
1076 case EM_H8S:
1077 case EM_H8_300:
1078 case EM_H8_300H:
800eeca4 1079 case EM_IA_64:
1e4cf259
NC
1080 case EM_IP2K:
1081 case EM_IP2K_OLD:
3b36097d 1082 case EM_IQ2000:
84e94c90 1083 case EM_LATTICEMICO32:
ff7eeb89 1084 case EM_M32C_OLD:
49f58d10 1085 case EM_M32C:
e9f53129
AM
1086 case EM_M32R:
1087 case EM_MCORE:
15ab5209 1088 case EM_CYGNUS_MEP:
a3c62988 1089 case EM_METAG:
e9f53129
AM
1090 case EM_MMIX:
1091 case EM_MN10200:
1092 case EM_CYGNUS_MN10200:
1093 case EM_MN10300:
1094 case EM_CYGNUS_MN10300:
5506d11a 1095 case EM_MOXIE:
e9f53129
AM
1096 case EM_MSP430:
1097 case EM_MSP430_OLD:
d031aafb 1098 case EM_MT:
35c08157 1099 case EM_NDS32:
64fd6348 1100 case EM_NIOS32:
73589c9d 1101 case EM_OR1K:
e9f53129
AM
1102 case EM_PPC64:
1103 case EM_PPC:
2b100bb5 1104 case EM_TI_PRU:
e23eba97 1105 case EM_RISCV:
99c513f6 1106 case EM_RL78:
c7927a3c 1107 case EM_RX:
e9f53129
AM
1108 case EM_S390:
1109 case EM_S390_OLD:
1110 case EM_SH:
1111 case EM_SPARC:
1112 case EM_SPARC32PLUS:
1113 case EM_SPARCV9:
1114 case EM_SPU:
40b36596 1115 case EM_TI_C6000:
aa137e4d
NC
1116 case EM_TILEGX:
1117 case EM_TILEPRO:
708e2187 1118 case EM_V800:
e9f53129
AM
1119 case EM_V850:
1120 case EM_CYGNUS_V850:
1121 case EM_VAX:
619ed720 1122 case EM_VISIUM:
e9f53129 1123 case EM_X86_64:
8a9036a4 1124 case EM_L1OM:
7a9068fe 1125 case EM_K1OM:
e9f53129
AM
1126 case EM_XSTORMY16:
1127 case EM_XTENSA:
1128 case EM_XTENSA_OLD:
7ba29e2a
NC
1129 case EM_MICROBLAZE:
1130 case EM_MICROBLAZE_OLD:
f96bd6c2 1131 case EM_WEBASSEMBLY:
015dc7e1 1132 return true;
103f02d3 1133
e9f53129
AM
1134 case EM_68HC05:
1135 case EM_68HC08:
1136 case EM_68HC11:
1137 case EM_68HC16:
1138 case EM_FX66:
1139 case EM_ME16:
d1133906 1140 case EM_MMA:
d1133906
NC
1141 case EM_NCPU:
1142 case EM_NDR1:
e9f53129 1143 case EM_PCP:
d1133906 1144 case EM_ST100:
e9f53129 1145 case EM_ST19:
d1133906 1146 case EM_ST7:
e9f53129
AM
1147 case EM_ST9PLUS:
1148 case EM_STARCORE:
d1133906 1149 case EM_SVX:
e9f53129 1150 case EM_TINYJ:
9c19a809
NC
1151 default:
1152 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 1153 return false;
9c19a809
NC
1154 }
1155}
252b5132 1156
dda8d76d 1157/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1158 Returns TRUE upon success, FALSE otherwise. If successful then a
1159 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
1160 and the number of relocs loaded is placed in *NRELASP. It is the caller's
1161 responsibility to free the allocated buffer. */
1162
015dc7e1 1163static bool
dda8d76d
NC
1164slurp_rela_relocs (Filedata * filedata,
1165 unsigned long rel_offset,
1166 unsigned long rel_size,
1167 Elf_Internal_Rela ** relasp,
1168 unsigned long * nrelasp)
9c19a809 1169{
2cf0635d 1170 Elf_Internal_Rela * relas;
8b73c356 1171 size_t nrelas;
4d6ed7c8 1172 unsigned int i;
252b5132 1173
4d6ed7c8
NC
1174 if (is_32bit_elf)
1175 {
2cf0635d 1176 Elf32_External_Rela * erelas;
103f02d3 1177
dda8d76d 1178 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1179 rel_size, _("32-bit relocation data"));
a6e9f9df 1180 if (!erelas)
015dc7e1 1181 return false;
252b5132 1182
4d6ed7c8 1183 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1184
3f5e193b
NC
1185 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1186 sizeof (Elf_Internal_Rela));
103f02d3 1187
4d6ed7c8
NC
1188 if (relas == NULL)
1189 {
c256ffe7 1190 free (erelas);
591a748a 1191 error (_("out of memory parsing relocs\n"));
015dc7e1 1192 return false;
4d6ed7c8 1193 }
103f02d3 1194
4d6ed7c8
NC
1195 for (i = 0; i < nrelas; i++)
1196 {
1197 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1198 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1199 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1200 }
103f02d3 1201
4d6ed7c8
NC
1202 free (erelas);
1203 }
1204 else
1205 {
2cf0635d 1206 Elf64_External_Rela * erelas;
103f02d3 1207
dda8d76d 1208 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1209 rel_size, _("64-bit relocation data"));
a6e9f9df 1210 if (!erelas)
015dc7e1 1211 return false;
4d6ed7c8
NC
1212
1213 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1214
3f5e193b
NC
1215 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1216 sizeof (Elf_Internal_Rela));
103f02d3 1217
4d6ed7c8
NC
1218 if (relas == NULL)
1219 {
c256ffe7 1220 free (erelas);
591a748a 1221 error (_("out of memory parsing relocs\n"));
015dc7e1 1222 return false;
9c19a809 1223 }
4d6ed7c8
NC
1224
1225 for (i = 0; i < nrelas; i++)
9c19a809 1226 {
66543521
AM
1227 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1228 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1229 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1230
1231 /* The #ifdef BFD64 below is to prevent a compile time
1232 warning. We know that if we do not have a 64 bit data
1233 type that we will never execute this code anyway. */
1234#ifdef BFD64
dda8d76d
NC
1235 if (filedata->file_header.e_machine == EM_MIPS
1236 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1237 {
1238 /* In little-endian objects, r_info isn't really a
1239 64-bit little-endian value: it has a 32-bit
1240 little-endian symbol index followed by four
1241 individual byte fields. Reorder INFO
1242 accordingly. */
91d6fa6a
NC
1243 bfd_vma inf = relas[i].r_info;
1244 inf = (((inf & 0xffffffff) << 32)
1245 | ((inf >> 56) & 0xff)
1246 | ((inf >> 40) & 0xff00)
1247 | ((inf >> 24) & 0xff0000)
1248 | ((inf >> 8) & 0xff000000));
1249 relas[i].r_info = inf;
861fb55a
DJ
1250 }
1251#endif /* BFD64 */
4d6ed7c8 1252 }
103f02d3 1253
4d6ed7c8
NC
1254 free (erelas);
1255 }
32ec8896 1256
4d6ed7c8
NC
1257 *relasp = relas;
1258 *nrelasp = nrelas;
015dc7e1 1259 return true;
4d6ed7c8 1260}
103f02d3 1261
dda8d76d 1262/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1263 Returns TRUE upon success, FALSE otherwise. If successful then a
1264 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1265 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1266 responsibility to free the allocated buffer. */
1267
015dc7e1 1268static bool
dda8d76d
NC
1269slurp_rel_relocs (Filedata * filedata,
1270 unsigned long rel_offset,
1271 unsigned long rel_size,
1272 Elf_Internal_Rela ** relsp,
1273 unsigned long * nrelsp)
4d6ed7c8 1274{
2cf0635d 1275 Elf_Internal_Rela * rels;
8b73c356 1276 size_t nrels;
4d6ed7c8 1277 unsigned int i;
103f02d3 1278
4d6ed7c8
NC
1279 if (is_32bit_elf)
1280 {
2cf0635d 1281 Elf32_External_Rel * erels;
103f02d3 1282
dda8d76d 1283 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1284 rel_size, _("32-bit relocation data"));
a6e9f9df 1285 if (!erels)
015dc7e1 1286 return false;
103f02d3 1287
4d6ed7c8 1288 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1289
3f5e193b 1290 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1291
4d6ed7c8
NC
1292 if (rels == NULL)
1293 {
c256ffe7 1294 free (erels);
591a748a 1295 error (_("out of memory parsing relocs\n"));
015dc7e1 1296 return false;
4d6ed7c8
NC
1297 }
1298
1299 for (i = 0; i < nrels; i++)
1300 {
1301 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1302 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1303 rels[i].r_addend = 0;
9ea033b2 1304 }
4d6ed7c8
NC
1305
1306 free (erels);
9c19a809
NC
1307 }
1308 else
1309 {
2cf0635d 1310 Elf64_External_Rel * erels;
9ea033b2 1311
dda8d76d 1312 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1313 rel_size, _("64-bit relocation data"));
a6e9f9df 1314 if (!erels)
015dc7e1 1315 return false;
103f02d3 1316
4d6ed7c8 1317 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1318
3f5e193b 1319 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1320
4d6ed7c8 1321 if (rels == NULL)
9c19a809 1322 {
c256ffe7 1323 free (erels);
591a748a 1324 error (_("out of memory parsing relocs\n"));
015dc7e1 1325 return false;
4d6ed7c8 1326 }
103f02d3 1327
4d6ed7c8
NC
1328 for (i = 0; i < nrels; i++)
1329 {
66543521
AM
1330 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1331 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1332 rels[i].r_addend = 0;
861fb55a
DJ
1333
1334 /* The #ifdef BFD64 below is to prevent a compile time
1335 warning. We know that if we do not have a 64 bit data
1336 type that we will never execute this code anyway. */
1337#ifdef BFD64
dda8d76d
NC
1338 if (filedata->file_header.e_machine == EM_MIPS
1339 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1340 {
1341 /* In little-endian objects, r_info isn't really a
1342 64-bit little-endian value: it has a 32-bit
1343 little-endian symbol index followed by four
1344 individual byte fields. Reorder INFO
1345 accordingly. */
91d6fa6a
NC
1346 bfd_vma inf = rels[i].r_info;
1347 inf = (((inf & 0xffffffff) << 32)
1348 | ((inf >> 56) & 0xff)
1349 | ((inf >> 40) & 0xff00)
1350 | ((inf >> 24) & 0xff0000)
1351 | ((inf >> 8) & 0xff000000));
1352 rels[i].r_info = inf;
861fb55a
DJ
1353 }
1354#endif /* BFD64 */
4d6ed7c8 1355 }
103f02d3 1356
4d6ed7c8
NC
1357 free (erels);
1358 }
32ec8896 1359
4d6ed7c8
NC
1360 *relsp = rels;
1361 *nrelsp = nrels;
015dc7e1 1362 return true;
4d6ed7c8 1363}
103f02d3 1364
a7fd1186
FS
1365static bool
1366slurp_relr_relocs (Filedata * filedata,
1367 unsigned long relr_offset,
1368 unsigned long relr_size,
1369 bfd_vma ** relrsp,
1370 unsigned long * nrelrsp)
1371{
1372 void *relrs;
1373 size_t size = 0, nentries, i;
1374 bfd_vma base = 0, addr, entry;
1375
1376 relrs = get_data (NULL, filedata, relr_offset, 1, relr_size,
1377 _("RELR relocation data"));
1378 if (!relrs)
1379 return false;
1380
1381 if (is_32bit_elf)
1382 nentries = relr_size / sizeof (Elf32_External_Relr);
1383 else
1384 nentries = relr_size / sizeof (Elf64_External_Relr);
1385 for (i = 0; i < nentries; i++)
1386 {
1387 if (is_32bit_elf)
1388 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1389 else
1390 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1391 if ((entry & 1) == 0)
1392 size++;
1393 else
1394 while ((entry >>= 1) != 0)
1395 if ((entry & 1) == 1)
1396 size++;
1397 }
1398
1399 *relrsp = (bfd_vma *) xmalloc (size * sizeof (bfd_vma));
1400 if (*relrsp == NULL)
1401 {
1402 free (relrs);
1403 error (_("out of memory parsing relocs\n"));
1404 return false;
1405 }
1406
1407 size = 0;
1408 for (i = 0; i < nentries; i++)
1409 {
1410 const bfd_vma entry_bytes = is_32bit_elf ? 4 : 8;
1411
1412 if (is_32bit_elf)
1413 entry = BYTE_GET (((Elf32_External_Relr *)relrs)[i].r_data);
1414 else
1415 entry = BYTE_GET (((Elf64_External_Relr *)relrs)[i].r_data);
1416 if ((entry & 1) == 0)
1417 {
1418 (*relrsp)[size++] = entry;
1419 base = entry + entry_bytes;
1420 }
1421 else
1422 {
1423 for (addr = base; (entry >>= 1) != 0; addr += entry_bytes)
1424 if ((entry & 1) != 0)
1425 (*relrsp)[size++] = addr;
1426 base += entry_bytes * (entry_bytes * CHAR_BIT - 1);
1427 }
1428 }
1429
1430 *nrelrsp = size;
1431 free (relrs);
1432 return true;
1433}
1434
aca88567
NC
1435/* Returns the reloc type extracted from the reloc info field. */
1436
1437static unsigned int
dda8d76d 1438get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1439{
1440 if (is_32bit_elf)
1441 return ELF32_R_TYPE (reloc_info);
1442
dda8d76d 1443 switch (filedata->file_header.e_machine)
aca88567
NC
1444 {
1445 case EM_MIPS:
1446 /* Note: We assume that reloc_info has already been adjusted for us. */
1447 return ELF64_MIPS_R_TYPE (reloc_info);
1448
1449 case EM_SPARCV9:
1450 return ELF64_R_TYPE_ID (reloc_info);
1451
1452 default:
1453 return ELF64_R_TYPE (reloc_info);
1454 }
1455}
1456
1457/* Return the symbol index extracted from the reloc info field. */
1458
1459static bfd_vma
1460get_reloc_symindex (bfd_vma reloc_info)
1461{
1462 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1463}
1464
015dc7e1 1465static inline bool
dda8d76d 1466uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1467{
1468 return
dda8d76d 1469 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1470 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1471 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1472 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1473 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1474}
1475
d3ba0551
AM
1476/* Display the contents of the relocation data found at the specified
1477 offset. */
ee42cf8c 1478
015dc7e1 1479static bool
dda8d76d
NC
1480dump_relocations (Filedata * filedata,
1481 unsigned long rel_offset,
1482 unsigned long rel_size,
1483 Elf_Internal_Sym * symtab,
1484 unsigned long nsyms,
1485 char * strtab,
1486 unsigned long strtablen,
a7fd1186 1487 relocation_type rel_type,
015dc7e1 1488 bool is_dynsym)
4d6ed7c8 1489{
32ec8896 1490 unsigned long i;
2cf0635d 1491 Elf_Internal_Rela * rels;
015dc7e1 1492 bool res = true;
103f02d3 1493
a7fd1186
FS
1494 if (rel_type == reltype_unknown)
1495 rel_type = guess_is_rela (filedata->file_header.e_machine) ? reltype_rela : reltype_rel;
103f02d3 1496
a7fd1186 1497 if (rel_type == reltype_rela)
4d6ed7c8 1498 {
dda8d76d 1499 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1500 return false;
4d6ed7c8 1501 }
a7fd1186 1502 else if (rel_type == reltype_rel)
4d6ed7c8 1503 {
dda8d76d 1504 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1505 return false;
252b5132 1506 }
a7fd1186
FS
1507 else if (rel_type == reltype_relr)
1508 {
1509 bfd_vma * relrs;
1510 const char *format
1511 = is_32bit_elf ? "%08" BFD_VMA_FMT "x\n" : "%016" BFD_VMA_FMT "x\n";
1512
1513 if (!slurp_relr_relocs (filedata, rel_offset, rel_size, &relrs,
1514 &rel_size))
1515 return false;
1516
1517 printf (ngettext (" %lu offset\n", " %lu offsets\n", rel_size), rel_size);
1518 for (i = 0; i < rel_size; i++)
1519 printf (format, relrs[i]);
1520 free (relrs);
1521 return true;
1522 }
252b5132 1523
410f7a12
L
1524 if (is_32bit_elf)
1525 {
a7fd1186 1526 if (rel_type == reltype_rela)
2c71103e
NC
1527 {
1528 if (do_wide)
1529 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1530 else
1531 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1532 }
410f7a12 1533 else
2c71103e
NC
1534 {
1535 if (do_wide)
1536 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1537 else
1538 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1539 }
410f7a12 1540 }
252b5132 1541 else
410f7a12 1542 {
a7fd1186 1543 if (rel_type == reltype_rela)
2c71103e
NC
1544 {
1545 if (do_wide)
8beeaeb7 1546 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1547 else
1548 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1549 }
410f7a12 1550 else
2c71103e
NC
1551 {
1552 if (do_wide)
8beeaeb7 1553 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1554 else
1555 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1556 }
410f7a12 1557 }
252b5132
RH
1558
1559 for (i = 0; i < rel_size; i++)
1560 {
2cf0635d 1561 const char * rtype;
b34976b6 1562 bfd_vma offset;
91d6fa6a 1563 bfd_vma inf;
b34976b6
AM
1564 bfd_vma symtab_index;
1565 bfd_vma type;
103f02d3 1566
b34976b6 1567 offset = rels[i].r_offset;
91d6fa6a 1568 inf = rels[i].r_info;
103f02d3 1569
dda8d76d 1570 type = get_reloc_type (filedata, inf);
91d6fa6a 1571 symtab_index = get_reloc_symindex (inf);
252b5132 1572
410f7a12
L
1573 if (is_32bit_elf)
1574 {
39dbeff8
AM
1575 printf ("%8.8lx %8.8lx ",
1576 (unsigned long) offset & 0xffffffff,
91d6fa6a 1577 (unsigned long) inf & 0xffffffff);
410f7a12
L
1578 }
1579 else
1580 {
39dbeff8 1581 printf (do_wide
d1ce973e
AM
1582 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1583 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1584 offset, inf);
410f7a12 1585 }
103f02d3 1586
dda8d76d 1587 switch (filedata->file_header.e_machine)
252b5132
RH
1588 {
1589 default:
1590 rtype = NULL;
1591 break;
1592
a06ea964
NC
1593 case EM_AARCH64:
1594 rtype = elf_aarch64_reloc_type (type);
1595 break;
1596
2b0337b0 1597 case EM_M32R:
252b5132 1598 case EM_CYGNUS_M32R:
9ea033b2 1599 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1600 break;
1601
1602 case EM_386:
22abe556 1603 case EM_IAMCU:
9ea033b2 1604 rtype = elf_i386_reloc_type (type);
252b5132
RH
1605 break;
1606
ba2685cc
AM
1607 case EM_68HC11:
1608 case EM_68HC12:
1609 rtype = elf_m68hc11_reloc_type (type);
1610 break;
75751cd9 1611
7b4ae824
JD
1612 case EM_S12Z:
1613 rtype = elf_s12z_reloc_type (type);
1614 break;
1615
252b5132 1616 case EM_68K:
9ea033b2 1617 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1618 break;
1619
f954747f
AM
1620 case EM_960:
1621 rtype = elf_i960_reloc_type (type);
1622 break;
1623
adde6300 1624 case EM_AVR:
2b0337b0 1625 case EM_AVR_OLD:
adde6300
AM
1626 rtype = elf_avr_reloc_type (type);
1627 break;
1628
9ea033b2
NC
1629 case EM_OLD_SPARCV9:
1630 case EM_SPARC32PLUS:
1631 case EM_SPARCV9:
252b5132 1632 case EM_SPARC:
9ea033b2 1633 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1634 break;
1635
e9f53129
AM
1636 case EM_SPU:
1637 rtype = elf_spu_reloc_type (type);
1638 break;
1639
708e2187
NC
1640 case EM_V800:
1641 rtype = v800_reloc_type (type);
1642 break;
2b0337b0 1643 case EM_V850:
252b5132 1644 case EM_CYGNUS_V850:
9ea033b2 1645 rtype = v850_reloc_type (type);
252b5132
RH
1646 break;
1647
2b0337b0 1648 case EM_D10V:
252b5132 1649 case EM_CYGNUS_D10V:
9ea033b2 1650 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1651 break;
1652
2b0337b0 1653 case EM_D30V:
252b5132 1654 case EM_CYGNUS_D30V:
9ea033b2 1655 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1656 break;
1657
d172d4ba
NC
1658 case EM_DLX:
1659 rtype = elf_dlx_reloc_type (type);
1660 break;
1661
252b5132 1662 case EM_SH:
9ea033b2 1663 rtype = elf_sh_reloc_type (type);
252b5132
RH
1664 break;
1665
2b0337b0 1666 case EM_MN10300:
252b5132 1667 case EM_CYGNUS_MN10300:
9ea033b2 1668 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1669 break;
1670
2b0337b0 1671 case EM_MN10200:
252b5132 1672 case EM_CYGNUS_MN10200:
9ea033b2 1673 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1674 break;
1675
2b0337b0 1676 case EM_FR30:
252b5132 1677 case EM_CYGNUS_FR30:
9ea033b2 1678 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1679 break;
1680
ba2685cc
AM
1681 case EM_CYGNUS_FRV:
1682 rtype = elf_frv_reloc_type (type);
1683 break;
5c70f934 1684
b8891f8d
AJ
1685 case EM_CSKY:
1686 rtype = elf_csky_reloc_type (type);
1687 break;
1688
3f8107ab
AM
1689 case EM_FT32:
1690 rtype = elf_ft32_reloc_type (type);
1691 break;
1692
252b5132 1693 case EM_MCORE:
9ea033b2 1694 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1695 break;
1696
3c3bdf30
NC
1697 case EM_MMIX:
1698 rtype = elf_mmix_reloc_type (type);
1699 break;
1700
5506d11a
AM
1701 case EM_MOXIE:
1702 rtype = elf_moxie_reloc_type (type);
1703 break;
1704
2469cfa2 1705 case EM_MSP430:
dda8d76d 1706 if (uses_msp430x_relocs (filedata))
13761a11
NC
1707 {
1708 rtype = elf_msp430x_reloc_type (type);
1709 break;
1710 }
1a0670f3 1711 /* Fall through. */
2469cfa2
NC
1712 case EM_MSP430_OLD:
1713 rtype = elf_msp430_reloc_type (type);
1714 break;
1715
35c08157
KLC
1716 case EM_NDS32:
1717 rtype = elf_nds32_reloc_type (type);
1718 break;
1719
252b5132 1720 case EM_PPC:
9ea033b2 1721 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1722 break;
1723
c833c019
AM
1724 case EM_PPC64:
1725 rtype = elf_ppc64_reloc_type (type);
1726 break;
1727
252b5132 1728 case EM_MIPS:
4fe85591 1729 case EM_MIPS_RS3_LE:
9ea033b2 1730 rtype = elf_mips_reloc_type (type);
252b5132
RH
1731 break;
1732
e23eba97
NC
1733 case EM_RISCV:
1734 rtype = elf_riscv_reloc_type (type);
1735 break;
1736
252b5132 1737 case EM_ALPHA:
9ea033b2 1738 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1739 break;
1740
1741 case EM_ARM:
9ea033b2 1742 rtype = elf_arm_reloc_type (type);
252b5132
RH
1743 break;
1744
584da044 1745 case EM_ARC:
886a2506
NC
1746 case EM_ARC_COMPACT:
1747 case EM_ARC_COMPACT2:
9ea033b2 1748 rtype = elf_arc_reloc_type (type);
252b5132
RH
1749 break;
1750
1751 case EM_PARISC:
69e617ca 1752 rtype = elf_hppa_reloc_type (type);
252b5132 1753 break;
7d466069 1754
b8720f9d
JL
1755 case EM_H8_300:
1756 case EM_H8_300H:
1757 case EM_H8S:
1758 rtype = elf_h8_reloc_type (type);
1759 break;
1760
73589c9d
CS
1761 case EM_OR1K:
1762 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1763 break;
1764
7d466069 1765 case EM_PJ:
2b0337b0 1766 case EM_PJ_OLD:
7d466069
ILT
1767 rtype = elf_pj_reloc_type (type);
1768 break;
800eeca4
JW
1769 case EM_IA_64:
1770 rtype = elf_ia64_reloc_type (type);
1771 break;
1b61cf92
HPN
1772
1773 case EM_CRIS:
1774 rtype = elf_cris_reloc_type (type);
1775 break;
535c37ff 1776
f954747f
AM
1777 case EM_860:
1778 rtype = elf_i860_reloc_type (type);
1779 break;
1780
bcedfee6 1781 case EM_X86_64:
8a9036a4 1782 case EM_L1OM:
7a9068fe 1783 case EM_K1OM:
bcedfee6
NC
1784 rtype = elf_x86_64_reloc_type (type);
1785 break;
a85d7ed0 1786
f954747f
AM
1787 case EM_S370:
1788 rtype = i370_reloc_type (type);
1789 break;
1790
53c7db4b
KH
1791 case EM_S390_OLD:
1792 case EM_S390:
1793 rtype = elf_s390_reloc_type (type);
1794 break;
93fbbb04 1795
1c0d3aa6
NC
1796 case EM_SCORE:
1797 rtype = elf_score_reloc_type (type);
1798 break;
1799
93fbbb04
GK
1800 case EM_XSTORMY16:
1801 rtype = elf_xstormy16_reloc_type (type);
1802 break;
179d3252 1803
1fe1f39c
NC
1804 case EM_CRX:
1805 rtype = elf_crx_reloc_type (type);
1806 break;
1807
179d3252
JT
1808 case EM_VAX:
1809 rtype = elf_vax_reloc_type (type);
1810 break;
1e4cf259 1811
619ed720
EB
1812 case EM_VISIUM:
1813 rtype = elf_visium_reloc_type (type);
1814 break;
1815
aca4efc7
JM
1816 case EM_BPF:
1817 rtype = elf_bpf_reloc_type (type);
1818 break;
1819
cfb8c092
NC
1820 case EM_ADAPTEVA_EPIPHANY:
1821 rtype = elf_epiphany_reloc_type (type);
1822 break;
1823
1e4cf259
NC
1824 case EM_IP2K:
1825 case EM_IP2K_OLD:
1826 rtype = elf_ip2k_reloc_type (type);
1827 break;
3b36097d
SC
1828
1829 case EM_IQ2000:
1830 rtype = elf_iq2000_reloc_type (type);
1831 break;
88da6820
NC
1832
1833 case EM_XTENSA_OLD:
1834 case EM_XTENSA:
1835 rtype = elf_xtensa_reloc_type (type);
1836 break;
a34e3ecb 1837
84e94c90
NC
1838 case EM_LATTICEMICO32:
1839 rtype = elf_lm32_reloc_type (type);
1840 break;
1841
ff7eeb89 1842 case EM_M32C_OLD:
49f58d10
JB
1843 case EM_M32C:
1844 rtype = elf_m32c_reloc_type (type);
1845 break;
1846
d031aafb
NS
1847 case EM_MT:
1848 rtype = elf_mt_reloc_type (type);
a34e3ecb 1849 break;
1d65ded4
CM
1850
1851 case EM_BLACKFIN:
1852 rtype = elf_bfin_reloc_type (type);
1853 break;
15ab5209
DB
1854
1855 case EM_CYGNUS_MEP:
1856 rtype = elf_mep_reloc_type (type);
1857 break;
60bca95a
NC
1858
1859 case EM_CR16:
1860 rtype = elf_cr16_reloc_type (type);
1861 break;
dd24e3da 1862
7ba29e2a
NC
1863 case EM_MICROBLAZE:
1864 case EM_MICROBLAZE_OLD:
1865 rtype = elf_microblaze_reloc_type (type);
1866 break;
c7927a3c 1867
99c513f6
DD
1868 case EM_RL78:
1869 rtype = elf_rl78_reloc_type (type);
1870 break;
1871
c7927a3c
NC
1872 case EM_RX:
1873 rtype = elf_rx_reloc_type (type);
1874 break;
c29aca4a 1875
a3c62988
NC
1876 case EM_METAG:
1877 rtype = elf_metag_reloc_type (type);
1878 break;
1879
c29aca4a
NC
1880 case EM_XC16X:
1881 case EM_C166:
1882 rtype = elf_xc16x_reloc_type (type);
1883 break;
40b36596
JM
1884
1885 case EM_TI_C6000:
1886 rtype = elf_tic6x_reloc_type (type);
1887 break;
aa137e4d
NC
1888
1889 case EM_TILEGX:
1890 rtype = elf_tilegx_reloc_type (type);
1891 break;
1892
1893 case EM_TILEPRO:
1894 rtype = elf_tilepro_reloc_type (type);
1895 break;
f6c1a2d5 1896
f96bd6c2
PC
1897 case EM_WEBASSEMBLY:
1898 rtype = elf_wasm32_reloc_type (type);
1899 break;
1900
f6c1a2d5
NC
1901 case EM_XGATE:
1902 rtype = elf_xgate_reloc_type (type);
1903 break;
36591ba1
SL
1904
1905 case EM_ALTERA_NIOS2:
1906 rtype = elf_nios2_reloc_type (type);
1907 break;
2b100bb5
DD
1908
1909 case EM_TI_PRU:
1910 rtype = elf_pru_reloc_type (type);
1911 break;
fe944acf
FT
1912
1913 case EM_NFP:
1914 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1915 rtype = elf_nfp3200_reloc_type (type);
1916 else
1917 rtype = elf_nfp_reloc_type (type);
1918 break;
6655dba2
SB
1919
1920 case EM_Z80:
1921 rtype = elf_z80_reloc_type (type);
1922 break;
e9a0721f 1923
1924 case EM_LOONGARCH:
1925 rtype = elf_loongarch_reloc_type (type);
1926 break;
1927
252b5132
RH
1928 }
1929
1930 if (rtype == NULL)
39dbeff8 1931 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1932 else
5c144731 1933 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1934
dda8d76d 1935 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1936 && rtype != NULL
7ace3541 1937 && streq (rtype, "R_ALPHA_LITUSE")
a7fd1186 1938 && rel_type == reltype_rela)
7ace3541
RH
1939 {
1940 switch (rels[i].r_addend)
1941 {
1942 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1943 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1944 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1945 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1946 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1947 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1948 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1949 default: rtype = NULL;
1950 }
32ec8896 1951
7ace3541
RH
1952 if (rtype)
1953 printf (" (%s)", rtype);
1954 else
1955 {
1956 putchar (' ');
1957 printf (_("<unknown addend: %lx>"),
1958 (unsigned long) rels[i].r_addend);
015dc7e1 1959 res = false;
7ace3541
RH
1960 }
1961 }
1962 else if (symtab_index)
252b5132 1963 {
af3fc3bc 1964 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1965 {
27a45f42
AS
1966 error (_(" bad symbol index: %08lx in reloc\n"),
1967 (unsigned long) symtab_index);
015dc7e1 1968 res = false;
32ec8896 1969 }
af3fc3bc 1970 else
19936277 1971 {
2cf0635d 1972 Elf_Internal_Sym * psym;
bb4d2ac2
L
1973 const char * version_string;
1974 enum versioned_symbol_info sym_info;
1975 unsigned short vna_other;
19936277 1976
af3fc3bc 1977 psym = symtab + symtab_index;
103f02d3 1978
bb4d2ac2 1979 version_string
dda8d76d 1980 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1981 strtab, strtablen,
1982 symtab_index,
1983 psym,
1984 &sym_info,
1985 &vna_other);
1986
af3fc3bc 1987 printf (" ");
171191ba 1988
d8045f23
NC
1989 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1990 {
1991 const char * name;
1992 unsigned int len;
1993 unsigned int width = is_32bit_elf ? 8 : 14;
1994
1995 /* Relocations against GNU_IFUNC symbols do not use the value
1996 of the symbol as the address to relocate against. Instead
1997 they invoke the function named by the symbol and use its
1998 result as the address for relocation.
1999
2000 To indicate this to the user, do not display the value of
2001 the symbol in the "Symbols's Value" field. Instead show
2002 its name followed by () as a hint that the symbol is
2003 invoked. */
2004
2005 if (strtab == NULL
2006 || psym->st_name == 0
2007 || psym->st_name >= strtablen)
2008 name = "??";
2009 else
2010 name = strtab + psym->st_name;
2011
2012 len = print_symbol (width, name);
bb4d2ac2
L
2013 if (version_string)
2014 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2015 version_string);
d8045f23
NC
2016 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
2017 }
2018 else
2019 {
2020 print_vma (psym->st_value, LONG_HEX);
171191ba 2021
d8045f23
NC
2022 printf (is_32bit_elf ? " " : " ");
2023 }
103f02d3 2024
af3fc3bc 2025 if (psym->st_name == 0)
f1ef08cb 2026 {
2cf0635d 2027 const char * sec_name = "<null>";
f1ef08cb
AM
2028 char name_buf[40];
2029
2030 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
2031 {
b9af6379
AM
2032 if (psym->st_shndx < filedata->file_header.e_shnum
2033 && filedata->section_headers != NULL)
84714f86
AM
2034 sec_name = section_name_print (filedata,
2035 filedata->section_headers
b9e920ec 2036 + psym->st_shndx);
f1ef08cb
AM
2037 else if (psym->st_shndx == SHN_ABS)
2038 sec_name = "ABS";
2039 else if (psym->st_shndx == SHN_COMMON)
2040 sec_name = "COMMON";
dda8d76d 2041 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 2042 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 2043 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 2044 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 2045 sec_name = "SCOMMON";
dda8d76d 2046 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
2047 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
2048 sec_name = "SUNDEF";
dda8d76d
NC
2049 else if ((filedata->file_header.e_machine == EM_X86_64
2050 || filedata->file_header.e_machine == EM_L1OM
2051 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
2052 && psym->st_shndx == SHN_X86_64_LCOMMON)
2053 sec_name = "LARGE_COMMON";
dda8d76d
NC
2054 else if (filedata->file_header.e_machine == EM_IA_64
2055 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
2056 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
2057 sec_name = "ANSI_COM";
dda8d76d 2058 else if (is_ia64_vms (filedata)
148b93f2
NC
2059 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
2060 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
2061 else
2062 {
2063 sprintf (name_buf, "<section 0x%x>",
2064 (unsigned int) psym->st_shndx);
2065 sec_name = name_buf;
2066 }
2067 }
2068 print_symbol (22, sec_name);
2069 }
af3fc3bc 2070 else if (strtab == NULL)
d79b3d50 2071 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 2072 else if (psym->st_name >= strtablen)
32ec8896 2073 {
27a45f42
AS
2074 error (_("<corrupt string table index: %3ld>\n"),
2075 psym->st_name);
015dc7e1 2076 res = false;
32ec8896 2077 }
af3fc3bc 2078 else
bb4d2ac2
L
2079 {
2080 print_symbol (22, strtab + psym->st_name);
2081 if (version_string)
2082 printf (sym_info == symbol_public ? "@@%s" : "@%s",
2083 version_string);
2084 }
103f02d3 2085
a7fd1186 2086 if (rel_type == reltype_rela)
171191ba 2087 {
7360e63f 2088 bfd_vma off = rels[i].r_addend;
171191ba 2089
7360e63f 2090 if ((bfd_signed_vma) off < 0)
598aaa76 2091 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 2092 else
598aaa76 2093 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 2094 }
19936277 2095 }
252b5132 2096 }
a7fd1186 2097 else if (rel_type == reltype_rela)
f7a99963 2098 {
7360e63f 2099 bfd_vma off = rels[i].r_addend;
e04d7088
L
2100
2101 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 2102 if ((bfd_signed_vma) off < 0)
e04d7088
L
2103 printf ("-%" BFD_VMA_FMT "x", - off);
2104 else
2105 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 2106 }
252b5132 2107
dda8d76d 2108 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
2109 && rtype != NULL
2110 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 2111 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 2112
252b5132 2113 putchar ('\n');
2c71103e 2114
aca88567 2115#ifdef BFD64
dda8d76d 2116 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 2117 {
91d6fa6a
NC
2118 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
2119 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
2120 const char * rtype2 = elf_mips_reloc_type (type2);
2121 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 2122
2c71103e
NC
2123 printf (" Type2: ");
2124
2125 if (rtype2 == NULL)
39dbeff8
AM
2126 printf (_("unrecognized: %-7lx"),
2127 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
2128 else
2129 printf ("%-17.17s", rtype2);
2130
18bd398b 2131 printf ("\n Type3: ");
2c71103e
NC
2132
2133 if (rtype3 == NULL)
39dbeff8
AM
2134 printf (_("unrecognized: %-7lx"),
2135 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
2136 else
2137 printf ("%-17.17s", rtype3);
2138
53c7db4b 2139 putchar ('\n');
2c71103e 2140 }
aca88567 2141#endif /* BFD64 */
252b5132
RH
2142 }
2143
c8286bd1 2144 free (rels);
32ec8896
NC
2145
2146 return res;
252b5132
RH
2147}
2148
37c18eed
SD
2149static const char *
2150get_aarch64_dynamic_type (unsigned long type)
2151{
2152 switch (type)
2153 {
2154 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 2155 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 2156 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
2157 default:
2158 return NULL;
2159 }
2160}
2161
252b5132 2162static const char *
d3ba0551 2163get_mips_dynamic_type (unsigned long type)
252b5132
RH
2164{
2165 switch (type)
2166 {
2167 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
2168 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
2169 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
2170 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
2171 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
2172 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
2173 case DT_MIPS_MSYM: return "MIPS_MSYM";
2174 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
2175 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
2176 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
2177 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
2178 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
2179 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
2180 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
2181 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
2182 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
2183 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 2184 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
2185 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
2186 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
2187 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
2188 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
2189 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
2190 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
2191 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
2192 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
2193 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
2194 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
2195 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
2196 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
2197 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
2198 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
2199 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
2200 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
2201 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
2202 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
2203 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
2204 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
2205 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
2206 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
2207 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
2208 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
2209 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
2210 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
2211 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
2212 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 2213 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
2214 default:
2215 return NULL;
2216 }
2217}
2218
9a097730 2219static const char *
d3ba0551 2220get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
2221{
2222 switch (type)
2223 {
2224 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
2225 default:
2226 return NULL;
2227 }
103f02d3
UD
2228}
2229
7490d522
AM
2230static const char *
2231get_ppc_dynamic_type (unsigned long type)
2232{
2233 switch (type)
2234 {
a7f2871e 2235 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 2236 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
2237 default:
2238 return NULL;
2239 }
2240}
2241
f1cb7e17 2242static const char *
d3ba0551 2243get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
2244{
2245 switch (type)
2246 {
a7f2871e
AM
2247 case DT_PPC64_GLINK: return "PPC64_GLINK";
2248 case DT_PPC64_OPD: return "PPC64_OPD";
2249 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 2250 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
2251 default:
2252 return NULL;
2253 }
2254}
2255
103f02d3 2256static const char *
d3ba0551 2257get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
2258{
2259 switch (type)
2260 {
2261 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
2262 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
2263 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
2264 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
2265 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
2266 case DT_HP_PREINIT: return "HP_PREINIT";
2267 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
2268 case DT_HP_NEEDED: return "HP_NEEDED";
2269 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
2270 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
2271 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
2272 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
2273 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2274 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2275 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2276 case DT_HP_FILTERED: return "HP_FILTERED";
2277 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2278 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2279 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2280 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2281 case DT_PLT: return "PLT";
2282 case DT_PLT_SIZE: return "PLT_SIZE";
2283 case DT_DLT: return "DLT";
2284 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2285 default:
2286 return NULL;
2287 }
2288}
9a097730 2289
ecc51f48 2290static const char *
d3ba0551 2291get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2292{
2293 switch (type)
2294 {
148b93f2
NC
2295 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2296 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2297 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2298 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2299 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2300 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2301 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2302 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2303 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2304 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2305 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2306 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2307 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2308 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2309 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2310 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2311 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2312 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2313 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2314 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2315 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2316 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2317 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2318 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2319 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2320 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2321 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2322 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2323 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2324 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2325 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2326 default:
2327 return NULL;
2328 }
2329}
2330
fd85a6a1
NC
2331static const char *
2332get_solaris_section_type (unsigned long type)
2333{
2334 switch (type)
2335 {
2336 case 0x6fffffee: return "SUNW_ancillary";
2337 case 0x6fffffef: return "SUNW_capchain";
2338 case 0x6ffffff0: return "SUNW_capinfo";
2339 case 0x6ffffff1: return "SUNW_symsort";
2340 case 0x6ffffff2: return "SUNW_tlssort";
2341 case 0x6ffffff3: return "SUNW_LDYNSYM";
2342 case 0x6ffffff4: return "SUNW_dof";
2343 case 0x6ffffff5: return "SUNW_cap";
2344 case 0x6ffffff6: return "SUNW_SIGNATURE";
2345 case 0x6ffffff7: return "SUNW_ANNOTATE";
2346 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2347 case 0x6ffffff9: return "SUNW_DEBUG";
2348 case 0x6ffffffa: return "SUNW_move";
2349 case 0x6ffffffb: return "SUNW_COMDAT";
2350 case 0x6ffffffc: return "SUNW_syminfo";
2351 case 0x6ffffffd: return "SUNW_verdef";
2352 case 0x6ffffffe: return "SUNW_verneed";
2353 case 0x6fffffff: return "SUNW_versym";
2354 case 0x70000000: return "SPARC_GOTDATA";
2355 default: return NULL;
2356 }
2357}
2358
fabcb361
RH
2359static const char *
2360get_alpha_dynamic_type (unsigned long type)
2361{
2362 switch (type)
2363 {
2364 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2365 default: return NULL;
fabcb361
RH
2366 }
2367}
2368
1c0d3aa6
NC
2369static const char *
2370get_score_dynamic_type (unsigned long type)
2371{
2372 switch (type)
2373 {
2374 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2375 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2376 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2377 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2378 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2379 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2380 default: return NULL;
1c0d3aa6
NC
2381 }
2382}
2383
40b36596
JM
2384static const char *
2385get_tic6x_dynamic_type (unsigned long type)
2386{
2387 switch (type)
2388 {
2389 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2390 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2391 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2392 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2393 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2394 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2395 default: return NULL;
40b36596
JM
2396 }
2397}
1c0d3aa6 2398
36591ba1
SL
2399static const char *
2400get_nios2_dynamic_type (unsigned long type)
2401{
2402 switch (type)
2403 {
2404 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2405 default: return NULL;
36591ba1
SL
2406 }
2407}
2408
fd85a6a1
NC
2409static const char *
2410get_solaris_dynamic_type (unsigned long type)
2411{
2412 switch (type)
2413 {
2414 case 0x6000000d: return "SUNW_AUXILIARY";
2415 case 0x6000000e: return "SUNW_RTLDINF";
2416 case 0x6000000f: return "SUNW_FILTER";
2417 case 0x60000010: return "SUNW_CAP";
2418 case 0x60000011: return "SUNW_SYMTAB";
2419 case 0x60000012: return "SUNW_SYMSZ";
2420 case 0x60000013: return "SUNW_SORTENT";
2421 case 0x60000014: return "SUNW_SYMSORT";
2422 case 0x60000015: return "SUNW_SYMSORTSZ";
2423 case 0x60000016: return "SUNW_TLSSORT";
2424 case 0x60000017: return "SUNW_TLSSORTSZ";
2425 case 0x60000018: return "SUNW_CAPINFO";
2426 case 0x60000019: return "SUNW_STRPAD";
2427 case 0x6000001a: return "SUNW_CAPCHAIN";
2428 case 0x6000001b: return "SUNW_LDMACH";
2429 case 0x6000001d: return "SUNW_CAPCHAINENT";
2430 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2431 case 0x60000021: return "SUNW_PARENT";
2432 case 0x60000023: return "SUNW_ASLR";
2433 case 0x60000025: return "SUNW_RELAX";
2434 case 0x60000029: return "SUNW_NXHEAP";
2435 case 0x6000002b: return "SUNW_NXSTACK";
2436
2437 case 0x70000001: return "SPARC_REGISTER";
2438 case 0x7ffffffd: return "AUXILIARY";
2439 case 0x7ffffffe: return "USED";
2440 case 0x7fffffff: return "FILTER";
2441
15f205b1 2442 default: return NULL;
fd85a6a1
NC
2443 }
2444}
2445
8155b853
NC
2446static const char *
2447get_riscv_dynamic_type (unsigned long type)
2448{
2449 switch (type)
2450 {
2451 case DT_RISCV_VARIANT_CC: return "RISCV_VARIANT_CC";
2452 default:
2453 return NULL;
2454 }
2455}
2456
252b5132 2457static const char *
dda8d76d 2458get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2459{
e9e44622 2460 static char buff[64];
252b5132
RH
2461
2462 switch (type)
2463 {
2464 case DT_NULL: return "NULL";
2465 case DT_NEEDED: return "NEEDED";
2466 case DT_PLTRELSZ: return "PLTRELSZ";
2467 case DT_PLTGOT: return "PLTGOT";
2468 case DT_HASH: return "HASH";
2469 case DT_STRTAB: return "STRTAB";
2470 case DT_SYMTAB: return "SYMTAB";
2471 case DT_RELA: return "RELA";
2472 case DT_RELASZ: return "RELASZ";
2473 case DT_RELAENT: return "RELAENT";
2474 case DT_STRSZ: return "STRSZ";
2475 case DT_SYMENT: return "SYMENT";
2476 case DT_INIT: return "INIT";
2477 case DT_FINI: return "FINI";
2478 case DT_SONAME: return "SONAME";
2479 case DT_RPATH: return "RPATH";
2480 case DT_SYMBOLIC: return "SYMBOLIC";
2481 case DT_REL: return "REL";
2482 case DT_RELSZ: return "RELSZ";
2483 case DT_RELENT: return "RELENT";
dd207c13
FS
2484 case DT_RELR: return "RELR";
2485 case DT_RELRSZ: return "RELRSZ";
2486 case DT_RELRENT: return "RELRENT";
252b5132
RH
2487 case DT_PLTREL: return "PLTREL";
2488 case DT_DEBUG: return "DEBUG";
2489 case DT_TEXTREL: return "TEXTREL";
2490 case DT_JMPREL: return "JMPREL";
2491 case DT_BIND_NOW: return "BIND_NOW";
2492 case DT_INIT_ARRAY: return "INIT_ARRAY";
2493 case DT_FINI_ARRAY: return "FINI_ARRAY";
2494 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2495 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2496 case DT_RUNPATH: return "RUNPATH";
2497 case DT_FLAGS: return "FLAGS";
2d0e6f43 2498
d1133906
NC
2499 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2500 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2501 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2502
05107a46 2503 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2504 case DT_PLTPADSZ: return "PLTPADSZ";
2505 case DT_MOVEENT: return "MOVEENT";
2506 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2507 case DT_FEATURE: return "FEATURE";
252b5132
RH
2508 case DT_POSFLAG_1: return "POSFLAG_1";
2509 case DT_SYMINSZ: return "SYMINSZ";
2510 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2511
252b5132 2512 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2513 case DT_CONFIG: return "CONFIG";
2514 case DT_DEPAUDIT: return "DEPAUDIT";
2515 case DT_AUDIT: return "AUDIT";
2516 case DT_PLTPAD: return "PLTPAD";
2517 case DT_MOVETAB: return "MOVETAB";
252b5132 2518 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2519
252b5132 2520 case DT_VERSYM: return "VERSYM";
103f02d3 2521
67a4f2b7
AO
2522 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2523 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2524 case DT_RELACOUNT: return "RELACOUNT";
2525 case DT_RELCOUNT: return "RELCOUNT";
2526 case DT_FLAGS_1: return "FLAGS_1";
2527 case DT_VERDEF: return "VERDEF";
2528 case DT_VERDEFNUM: return "VERDEFNUM";
2529 case DT_VERNEED: return "VERNEED";
2530 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2531
019148e4 2532 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2533 case DT_USED: return "USED";
2534 case DT_FILTER: return "FILTER";
103f02d3 2535
047b2264
JJ
2536 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2537 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2538 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2539 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2540 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2541 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2542 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2543
252b5132
RH
2544 default:
2545 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2546 {
2cf0635d 2547 const char * result;
103f02d3 2548
dda8d76d 2549 switch (filedata->file_header.e_machine)
252b5132 2550 {
37c18eed
SD
2551 case EM_AARCH64:
2552 result = get_aarch64_dynamic_type (type);
2553 break;
252b5132 2554 case EM_MIPS:
4fe85591 2555 case EM_MIPS_RS3_LE:
252b5132
RH
2556 result = get_mips_dynamic_type (type);
2557 break;
9a097730
RH
2558 case EM_SPARCV9:
2559 result = get_sparc64_dynamic_type (type);
2560 break;
7490d522
AM
2561 case EM_PPC:
2562 result = get_ppc_dynamic_type (type);
2563 break;
f1cb7e17
AM
2564 case EM_PPC64:
2565 result = get_ppc64_dynamic_type (type);
2566 break;
ecc51f48
NC
2567 case EM_IA_64:
2568 result = get_ia64_dynamic_type (type);
2569 break;
fabcb361
RH
2570 case EM_ALPHA:
2571 result = get_alpha_dynamic_type (type);
2572 break;
1c0d3aa6
NC
2573 case EM_SCORE:
2574 result = get_score_dynamic_type (type);
2575 break;
40b36596
JM
2576 case EM_TI_C6000:
2577 result = get_tic6x_dynamic_type (type);
2578 break;
36591ba1
SL
2579 case EM_ALTERA_NIOS2:
2580 result = get_nios2_dynamic_type (type);
2581 break;
8155b853
NC
2582 case EM_RISCV:
2583 result = get_riscv_dynamic_type (type);
2584 break;
252b5132 2585 default:
dda8d76d 2586 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2587 result = get_solaris_dynamic_type (type);
2588 else
2589 result = NULL;
252b5132
RH
2590 break;
2591 }
2592
2593 if (result != NULL)
2594 return result;
2595
e9e44622 2596 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2597 }
eec8f817 2598 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2599 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2600 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2601 {
2cf0635d 2602 const char * result;
103f02d3 2603
dda8d76d 2604 switch (filedata->file_header.e_machine)
103f02d3
UD
2605 {
2606 case EM_PARISC:
2607 result = get_parisc_dynamic_type (type);
2608 break;
148b93f2
NC
2609 case EM_IA_64:
2610 result = get_ia64_dynamic_type (type);
2611 break;
103f02d3 2612 default:
dda8d76d 2613 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2614 result = get_solaris_dynamic_type (type);
2615 else
2616 result = NULL;
103f02d3
UD
2617 break;
2618 }
2619
2620 if (result != NULL)
2621 return result;
2622
e9e44622
JJ
2623 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2624 type);
103f02d3 2625 }
252b5132 2626 else
e9e44622 2627 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2628
252b5132
RH
2629 return buff;
2630 }
2631}
2632
93df3340
AM
2633static bool get_program_headers (Filedata *);
2634static bool get_dynamic_section (Filedata *);
2635
2636static void
2637locate_dynamic_section (Filedata *filedata)
2638{
2639 unsigned long dynamic_addr = 0;
2640 bfd_size_type dynamic_size = 0;
2641
2642 if (filedata->file_header.e_phnum != 0
2643 && get_program_headers (filedata))
2644 {
2645 Elf_Internal_Phdr *segment;
2646 unsigned int i;
2647
2648 for (i = 0, segment = filedata->program_headers;
2649 i < filedata->file_header.e_phnum;
2650 i++, segment++)
2651 {
2652 if (segment->p_type == PT_DYNAMIC)
2653 {
2654 dynamic_addr = segment->p_offset;
2655 dynamic_size = segment->p_filesz;
2656
2657 if (filedata->section_headers != NULL)
2658 {
2659 Elf_Internal_Shdr *sec;
2660
2661 sec = find_section (filedata, ".dynamic");
2662 if (sec != NULL)
2663 {
2664 if (sec->sh_size == 0
2665 || sec->sh_type == SHT_NOBITS)
2666 {
2667 dynamic_addr = 0;
2668 dynamic_size = 0;
2669 }
2670 else
2671 {
2672 dynamic_addr = sec->sh_offset;
2673 dynamic_size = sec->sh_size;
2674 }
2675 }
2676 }
2677
2678 if (dynamic_addr > filedata->file_size
2679 || (dynamic_size > filedata->file_size - dynamic_addr))
2680 {
2681 dynamic_addr = 0;
2682 dynamic_size = 0;
2683 }
2684 break;
2685 }
2686 }
2687 }
2688 filedata->dynamic_addr = dynamic_addr;
2689 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2690}
2691
2692static bool
2693is_pie (Filedata *filedata)
2694{
2695 Elf_Internal_Dyn *entry;
2696
2697 if (filedata->dynamic_size == 0)
2698 locate_dynamic_section (filedata);
2699 if (filedata->dynamic_size <= 1)
2700 return false;
2701
2702 if (!get_dynamic_section (filedata))
2703 return false;
2704
2705 for (entry = filedata->dynamic_section;
2706 entry < filedata->dynamic_section + filedata->dynamic_nent;
2707 entry++)
2708 {
2709 if (entry->d_tag == DT_FLAGS_1)
2710 {
2711 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2712 return true;
2713 break;
2714 }
2715 }
2716 return false;
2717}
2718
252b5132 2719static char *
93df3340 2720get_file_type (Filedata *filedata)
252b5132 2721{
93df3340 2722 unsigned e_type = filedata->file_header.e_type;
89246a0e 2723 static char buff[64];
252b5132
RH
2724
2725 switch (e_type)
2726 {
32ec8896
NC
2727 case ET_NONE: return _("NONE (None)");
2728 case ET_REL: return _("REL (Relocatable file)");
2729 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2730 case ET_DYN:
2731 if (is_pie (filedata))
2732 return _("DYN (Position-Independent Executable file)");
2733 else
2734 return _("DYN (Shared object file)");
32ec8896 2735 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2736
2737 default:
2738 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2739 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2740 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2741 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2742 else
e9e44622 2743 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2744 return buff;
2745 }
2746}
2747
2748static char *
d3ba0551 2749get_machine_name (unsigned e_machine)
252b5132 2750{
b34976b6 2751 static char buff[64]; /* XXX */
252b5132
RH
2752
2753 switch (e_machine)
2754 {
55e22ca8
NC
2755 /* Please keep this switch table sorted by increasing EM_ value. */
2756 /* 0 */
c45021f2
NC
2757 case EM_NONE: return _("None");
2758 case EM_M32: return "WE32100";
2759 case EM_SPARC: return "Sparc";
2760 case EM_386: return "Intel 80386";
2761 case EM_68K: return "MC68000";
2762 case EM_88K: return "MC88000";
22abe556 2763 case EM_IAMCU: return "Intel MCU";
fb70ec17 2764 case EM_860: return "Intel 80860";
c45021f2
NC
2765 case EM_MIPS: return "MIPS R3000";
2766 case EM_S370: return "IBM System/370";
55e22ca8 2767 /* 10 */
7036c0e1 2768 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2769 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2770 case EM_PARISC: return "HPPA";
55e22ca8 2771 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2772 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2773 case EM_960: return "Intel 80960";
c45021f2 2774 case EM_PPC: return "PowerPC";
55e22ca8 2775 /* 20 */
285d1771 2776 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2777 case EM_S390_OLD:
2778 case EM_S390: return "IBM S/390";
2779 case EM_SPU: return "SPU";
2780 /* 30 */
2781 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2782 case EM_FR20: return "Fujitsu FR20";
2783 case EM_RH32: return "TRW RH32";
b34976b6 2784 case EM_MCORE: return "MCORE";
55e22ca8 2785 /* 40 */
7036c0e1
AJ
2786 case EM_ARM: return "ARM";
2787 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2788 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2789 case EM_SPARCV9: return "Sparc v9";
2790 case EM_TRICORE: return "Siemens Tricore";
584da044 2791 case EM_ARC: return "ARC";
c2dcd04e
NC
2792 case EM_H8_300: return "Renesas H8/300";
2793 case EM_H8_300H: return "Renesas H8/300H";
2794 case EM_H8S: return "Renesas H8S";
2795 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2796 /* 50 */
30800947 2797 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2798 case EM_MIPS_X: return "Stanford MIPS-X";
2799 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2800 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2801 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2802 case EM_PCP: return "Siemens PCP";
2803 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2804 case EM_NDR1: return "Denso NDR1 microprocesspr";
2805 case EM_STARCORE: return "Motorola Star*Core processor";
2806 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2807 /* 60 */
7036c0e1
AJ
2808 case EM_ST100: return "STMicroelectronics ST100 processor";
2809 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2810 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2811 case EM_PDSP: return "Sony DSP processor";
2812 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2813 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2814 case EM_FX66: return "Siemens FX66 microcontroller";
2815 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2816 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2817 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2818 /* 70 */
7036c0e1
AJ
2819 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2820 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2821 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2822 case EM_SVX: return "Silicon Graphics SVx";
2823 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2824 case EM_VAX: return "Digital VAX";
1b61cf92 2825 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2826 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2827 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2828 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2829 /* 80 */
b34976b6 2830 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2831 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2832 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2833 case EM_AVR_OLD:
2834 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2835 case EM_CYGNUS_FR30:
2836 case EM_FR30: return "Fujitsu FR30";
2837 case EM_CYGNUS_D10V:
2838 case EM_D10V: return "d10v";
2839 case EM_CYGNUS_D30V:
2840 case EM_D30V: return "d30v";
2841 case EM_CYGNUS_V850:
2842 case EM_V850: return "Renesas V850";
2843 case EM_CYGNUS_M32R:
2844 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2845 case EM_CYGNUS_MN10300:
2846 case EM_MN10300: return "mn10300";
2847 /* 90 */
2848 case EM_CYGNUS_MN10200:
2849 case EM_MN10200: return "mn10200";
2850 case EM_PJ: return "picoJava";
73589c9d 2851 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2852 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2853 case EM_XTENSA_OLD:
2854 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2855 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2856 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2857 case EM_NS32K: return "National Semiconductor 32000 series";
2858 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2859 case EM_SNP1K: return "Trebia SNP 1000 processor";
2860 /* 100 */
9abca702 2861 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2862 case EM_IP2K_OLD:
2863 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2864 case EM_MAX: return "MAX Processor";
2865 case EM_CR: return "National Semiconductor CompactRISC";
2866 case EM_F2MC16: return "Fujitsu F2MC16";
2867 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2868 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2869 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2870 case EM_SEP: return "Sharp embedded microprocessor";
2871 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2872 /* 110 */
11636f9e
JM
2873 case EM_UNICORE: return "Unicore";
2874 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2875 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2876 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2877 case EM_CRX: return "National Semiconductor CRX microprocessor";
2878 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2879 case EM_C166:
d70c5fc7 2880 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2881 case EM_M16C: return "Renesas M16C series microprocessors";
2882 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2883 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2884 /* 120 */
2885 case EM_M32C: return "Renesas M32c";
2886 /* 130 */
11636f9e
JM
2887 case EM_TSK3000: return "Altium TSK3000 core";
2888 case EM_RS08: return "Freescale RS08 embedded processor";
2889 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2890 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2891 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2892 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2893 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2894 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2895 /* 140 */
11636f9e
JM
2896 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2897 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2898 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2899 case EM_TI_PRU: return "TI PRU I/O processor";
2900 /* 160 */
11636f9e
JM
2901 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2902 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2903 case EM_R32C: return "Renesas R32C series microprocessors";
2904 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2905 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2906 case EM_8051: return "Intel 8051 and variants";
2907 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2908 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2909 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2910 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2911 /* 170 */
11636f9e
JM
2912 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2913 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2914 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2915 case EM_RX: return "Renesas RX";
a3c62988 2916 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2917 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2918 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2919 case EM_CR16:
2920 case EM_MICROBLAZE:
2921 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2922 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2923 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2924 /* 180 */
2925 case EM_L1OM: return "Intel L1OM";
2926 case EM_K1OM: return "Intel K1OM";
2927 case EM_INTEL182: return "Intel (reserved)";
2928 case EM_AARCH64: return "AArch64";
2929 case EM_ARM184: return "ARM (reserved)";
2930 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2931 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2932 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2933 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2934 /* 190 */
11636f9e 2935 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2936 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2937 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2938 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2939 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2940 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2941 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2942 case EM_RL78: return "Renesas RL78";
6d913794 2943 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2944 case EM_78K0R: return "Renesas 78K0R";
2945 /* 200 */
6d913794 2946 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2947 case EM_BA1: return "Beyond BA1 CPU architecture";
2948 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2949 case EM_XCORE: return "XMOS xCORE processor family";
2950 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2951 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2952 /* 210 */
6d913794
NC
2953 case EM_KM32: return "KM211 KM32 32-bit processor";
2954 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2955 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2956 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2957 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2958 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2959 case EM_COGE: return "Cognitive Smart Memory Processor";
2960 case EM_COOL: return "Bluechip Systems CoolEngine";
2961 case EM_NORC: return "Nanoradio Optimized RISC";
2962 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2963 /* 220 */
15f205b1 2964 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2965 case EM_VISIUM: return "CDS VISIUMcore processor";
2966 case EM_FT32: return "FTDI Chip FT32";
2967 case EM_MOXIE: return "Moxie";
2968 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2969 /* 230 (all reserved) */
2970 /* 240 */
55e22ca8
NC
2971 case EM_RISCV: return "RISC-V";
2972 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2973 case EM_CEVA: return "CEVA Processor Architecture Family";
2974 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2975 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2976 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2977 case EM_IMG1: return "Imagination Technologies";
2978 /* 250 */
fe944acf 2979 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2980 case EM_VE: return "NEC Vector Engine";
2981 case EM_CSKY: return "C-SKY";
2982 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2983 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2984 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2985 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2986 case EM_65816: return "WDC 65816/65C816";
01a8c731 2987 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2988 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2989
2990 /* Large numbers... */
2991 case EM_MT: return "Morpho Techologies MT processor";
2992 case EM_ALPHA: return "Alpha";
2993 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2994 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2995 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2996 case EM_IQ2000: return "Vitesse IQ2000";
2997 case EM_M32C_OLD:
2998 case EM_NIOS32: return "Altera Nios";
2999 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
3000 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
3001 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 3002 case EM_S12Z: return "Freescale S12Z";
55e22ca8 3003
252b5132 3004 default:
35d9dd2f 3005 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
3006 return buff;
3007 }
3008}
3009
a9522a21
AB
3010static void
3011decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
3012{
3013 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 3014 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
3015 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
3016 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
3017 architectures.
3018
3019 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
3020 but also sets a specific architecture type in the e_flags field.
3021
3022 However, when decoding the flags we don't worry if we see an
3023 unexpected pairing, for example EM_ARC_COMPACT machine type, with
3024 ARCEM architecture type. */
3025
3026 switch (e_flags & EF_ARC_MACH_MSK)
3027 {
3028 /* We only expect these to occur for EM_ARC_COMPACT2. */
3029 case EF_ARC_CPU_ARCV2EM:
3030 strcat (buf, ", ARC EM");
3031 break;
3032 case EF_ARC_CPU_ARCV2HS:
3033 strcat (buf, ", ARC HS");
3034 break;
3035
3036 /* We only expect these to occur for EM_ARC_COMPACT. */
3037 case E_ARC_MACH_ARC600:
3038 strcat (buf, ", ARC600");
3039 break;
3040 case E_ARC_MACH_ARC601:
3041 strcat (buf, ", ARC601");
3042 break;
3043 case E_ARC_MACH_ARC700:
3044 strcat (buf, ", ARC700");
3045 break;
3046
3047 /* The only times we should end up here are (a) A corrupt ELF, (b) A
3048 new ELF with new architecture being read by an old version of
3049 readelf, or (c) An ELF built with non-GNU compiler that does not
3050 set the architecture in the e_flags. */
3051 default:
3052 if (e_machine == EM_ARC_COMPACT)
3053 strcat (buf, ", Unknown ARCompact");
3054 else
3055 strcat (buf, ", Unknown ARC");
3056 break;
3057 }
3058
3059 switch (e_flags & EF_ARC_OSABI_MSK)
3060 {
3061 case E_ARC_OSABI_ORIG:
3062 strcat (buf, ", (ABI:legacy)");
3063 break;
3064 case E_ARC_OSABI_V2:
3065 strcat (buf, ", (ABI:v2)");
3066 break;
3067 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
3068 case E_ARC_OSABI_V3:
3069 strcat (buf, ", v3 no-legacy-syscalls ABI");
3070 break;
53a346d8
CZ
3071 case E_ARC_OSABI_V4:
3072 strcat (buf, ", v4 ABI");
3073 break;
a9522a21
AB
3074 default:
3075 strcat (buf, ", unrecognised ARC OSABI flag");
3076 break;
3077 }
3078}
3079
f3485b74 3080static void
d3ba0551 3081decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
3082{
3083 unsigned eabi;
015dc7e1 3084 bool unknown = false;
f3485b74
NC
3085
3086 eabi = EF_ARM_EABI_VERSION (e_flags);
3087 e_flags &= ~ EF_ARM_EABIMASK;
3088
3089 /* Handle "generic" ARM flags. */
3090 if (e_flags & EF_ARM_RELEXEC)
3091 {
3092 strcat (buf, ", relocatable executable");
3093 e_flags &= ~ EF_ARM_RELEXEC;
3094 }
76da6bbe 3095
18a20338
CL
3096 if (e_flags & EF_ARM_PIC)
3097 {
3098 strcat (buf, ", position independent");
3099 e_flags &= ~ EF_ARM_PIC;
3100 }
3101
f3485b74
NC
3102 /* Now handle EABI specific flags. */
3103 switch (eabi)
3104 {
3105 default:
2c71103e 3106 strcat (buf, ", <unrecognized EABI>");
f3485b74 3107 if (e_flags)
015dc7e1 3108 unknown = true;
f3485b74
NC
3109 break;
3110
3111 case EF_ARM_EABI_VER1:
a5bcd848 3112 strcat (buf, ", Version1 EABI");
f3485b74
NC
3113 while (e_flags)
3114 {
3115 unsigned flag;
76da6bbe 3116
f3485b74
NC
3117 /* Process flags one bit at a time. */
3118 flag = e_flags & - e_flags;
3119 e_flags &= ~ flag;
76da6bbe 3120
f3485b74
NC
3121 switch (flag)
3122 {
a5bcd848 3123 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
3124 strcat (buf, ", sorted symbol tables");
3125 break;
76da6bbe 3126
f3485b74 3127 default:
015dc7e1 3128 unknown = true;
f3485b74
NC
3129 break;
3130 }
3131 }
3132 break;
76da6bbe 3133
a5bcd848
PB
3134 case EF_ARM_EABI_VER2:
3135 strcat (buf, ", Version2 EABI");
3136 while (e_flags)
3137 {
3138 unsigned flag;
3139
3140 /* Process flags one bit at a time. */
3141 flag = e_flags & - e_flags;
3142 e_flags &= ~ flag;
3143
3144 switch (flag)
3145 {
3146 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
3147 strcat (buf, ", sorted symbol tables");
3148 break;
3149
3150 case EF_ARM_DYNSYMSUSESEGIDX:
3151 strcat (buf, ", dynamic symbols use segment index");
3152 break;
3153
3154 case EF_ARM_MAPSYMSFIRST:
3155 strcat (buf, ", mapping symbols precede others");
3156 break;
3157
3158 default:
015dc7e1 3159 unknown = true;
a5bcd848
PB
3160 break;
3161 }
3162 }
3163 break;
3164
d507cf36
PB
3165 case EF_ARM_EABI_VER3:
3166 strcat (buf, ", Version3 EABI");
8cb51566
PB
3167 break;
3168
3169 case EF_ARM_EABI_VER4:
3170 strcat (buf, ", Version4 EABI");
3bfcb652
NC
3171 while (e_flags)
3172 {
3173 unsigned flag;
3174
3175 /* Process flags one bit at a time. */
3176 flag = e_flags & - e_flags;
3177 e_flags &= ~ flag;
3178
3179 switch (flag)
3180 {
3181 case EF_ARM_BE8:
3182 strcat (buf, ", BE8");
3183 break;
3184
3185 case EF_ARM_LE8:
3186 strcat (buf, ", LE8");
3187 break;
3188
3189 default:
015dc7e1 3190 unknown = true;
3bfcb652
NC
3191 break;
3192 }
3bfcb652
NC
3193 }
3194 break;
3a4a14e9
PB
3195
3196 case EF_ARM_EABI_VER5:
3197 strcat (buf, ", Version5 EABI");
d507cf36
PB
3198 while (e_flags)
3199 {
3200 unsigned flag;
3201
3202 /* Process flags one bit at a time. */
3203 flag = e_flags & - e_flags;
3204 e_flags &= ~ flag;
3205
3206 switch (flag)
3207 {
3208 case EF_ARM_BE8:
3209 strcat (buf, ", BE8");
3210 break;
3211
3212 case EF_ARM_LE8:
3213 strcat (buf, ", LE8");
3214 break;
3215
3bfcb652
NC
3216 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
3217 strcat (buf, ", soft-float ABI");
3218 break;
3219
3220 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
3221 strcat (buf, ", hard-float ABI");
3222 break;
3223
d507cf36 3224 default:
015dc7e1 3225 unknown = true;
d507cf36
PB
3226 break;
3227 }
3228 }
3229 break;
3230
f3485b74 3231 case EF_ARM_EABI_UNKNOWN:
a5bcd848 3232 strcat (buf, ", GNU EABI");
f3485b74
NC
3233 while (e_flags)
3234 {
3235 unsigned flag;
76da6bbe 3236
f3485b74
NC
3237 /* Process flags one bit at a time. */
3238 flag = e_flags & - e_flags;
3239 e_flags &= ~ flag;
76da6bbe 3240
f3485b74
NC
3241 switch (flag)
3242 {
a5bcd848 3243 case EF_ARM_INTERWORK:
f3485b74
NC
3244 strcat (buf, ", interworking enabled");
3245 break;
76da6bbe 3246
a5bcd848 3247 case EF_ARM_APCS_26:
f3485b74
NC
3248 strcat (buf, ", uses APCS/26");
3249 break;
76da6bbe 3250
a5bcd848 3251 case EF_ARM_APCS_FLOAT:
f3485b74
NC
3252 strcat (buf, ", uses APCS/float");
3253 break;
76da6bbe 3254
a5bcd848 3255 case EF_ARM_PIC:
f3485b74
NC
3256 strcat (buf, ", position independent");
3257 break;
76da6bbe 3258
a5bcd848 3259 case EF_ARM_ALIGN8:
f3485b74
NC
3260 strcat (buf, ", 8 bit structure alignment");
3261 break;
76da6bbe 3262
a5bcd848 3263 case EF_ARM_NEW_ABI:
f3485b74
NC
3264 strcat (buf, ", uses new ABI");
3265 break;
76da6bbe 3266
a5bcd848 3267 case EF_ARM_OLD_ABI:
f3485b74
NC
3268 strcat (buf, ", uses old ABI");
3269 break;
76da6bbe 3270
a5bcd848 3271 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
3272 strcat (buf, ", software FP");
3273 break;
76da6bbe 3274
90e01f86
ILT
3275 case EF_ARM_VFP_FLOAT:
3276 strcat (buf, ", VFP");
3277 break;
3278
fde78edd
NC
3279 case EF_ARM_MAVERICK_FLOAT:
3280 strcat (buf, ", Maverick FP");
3281 break;
3282
f3485b74 3283 default:
015dc7e1 3284 unknown = true;
f3485b74
NC
3285 break;
3286 }
3287 }
3288 }
f3485b74
NC
3289
3290 if (unknown)
2b692964 3291 strcat (buf,_(", <unknown>"));
f3485b74
NC
3292}
3293
343433df
AB
3294static void
3295decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3296{
3297 --size; /* Leave space for null terminator. */
3298
3299 switch (e_flags & EF_AVR_MACH)
3300 {
3301 case E_AVR_MACH_AVR1:
3302 strncat (buf, ", avr:1", size);
3303 break;
3304 case E_AVR_MACH_AVR2:
3305 strncat (buf, ", avr:2", size);
3306 break;
3307 case E_AVR_MACH_AVR25:
3308 strncat (buf, ", avr:25", size);
3309 break;
3310 case E_AVR_MACH_AVR3:
3311 strncat (buf, ", avr:3", size);
3312 break;
3313 case E_AVR_MACH_AVR31:
3314 strncat (buf, ", avr:31", size);
3315 break;
3316 case E_AVR_MACH_AVR35:
3317 strncat (buf, ", avr:35", size);
3318 break;
3319 case E_AVR_MACH_AVR4:
3320 strncat (buf, ", avr:4", size);
3321 break;
3322 case E_AVR_MACH_AVR5:
3323 strncat (buf, ", avr:5", size);
3324 break;
3325 case E_AVR_MACH_AVR51:
3326 strncat (buf, ", avr:51", size);
3327 break;
3328 case E_AVR_MACH_AVR6:
3329 strncat (buf, ", avr:6", size);
3330 break;
3331 case E_AVR_MACH_AVRTINY:
3332 strncat (buf, ", avr:100", size);
3333 break;
3334 case E_AVR_MACH_XMEGA1:
3335 strncat (buf, ", avr:101", size);
3336 break;
3337 case E_AVR_MACH_XMEGA2:
3338 strncat (buf, ", avr:102", size);
3339 break;
3340 case E_AVR_MACH_XMEGA3:
3341 strncat (buf, ", avr:103", size);
3342 break;
3343 case E_AVR_MACH_XMEGA4:
3344 strncat (buf, ", avr:104", size);
3345 break;
3346 case E_AVR_MACH_XMEGA5:
3347 strncat (buf, ", avr:105", size);
3348 break;
3349 case E_AVR_MACH_XMEGA6:
3350 strncat (buf, ", avr:106", size);
3351 break;
3352 case E_AVR_MACH_XMEGA7:
3353 strncat (buf, ", avr:107", size);
3354 break;
3355 default:
3356 strncat (buf, ", avr:<unknown>", size);
3357 break;
3358 }
3359
3360 size -= strlen (buf);
3361 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3362 strncat (buf, ", link-relax", size);
3363}
3364
35c08157
KLC
3365static void
3366decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3367{
3368 unsigned abi;
3369 unsigned arch;
3370 unsigned config;
3371 unsigned version;
015dc7e1 3372 bool has_fpu = false;
32ec8896 3373 unsigned int r = 0;
35c08157
KLC
3374
3375 static const char *ABI_STRINGS[] =
3376 {
3377 "ABI v0", /* use r5 as return register; only used in N1213HC */
3378 "ABI v1", /* use r0 as return register */
3379 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3380 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3381 "AABI",
3382 "ABI2 FP+"
35c08157
KLC
3383 };
3384 static const char *VER_STRINGS[] =
3385 {
3386 "Andes ELF V1.3 or older",
3387 "Andes ELF V1.3.1",
3388 "Andes ELF V1.4"
3389 };
3390 static const char *ARCH_STRINGS[] =
3391 {
3392 "",
3393 "Andes Star v1.0",
3394 "Andes Star v2.0",
3395 "Andes Star v3.0",
3396 "Andes Star v3.0m"
3397 };
3398
3399 abi = EF_NDS_ABI & e_flags;
3400 arch = EF_NDS_ARCH & e_flags;
3401 config = EF_NDS_INST & e_flags;
3402 version = EF_NDS32_ELF_VERSION & e_flags;
3403
3404 memset (buf, 0, size);
3405
3406 switch (abi)
3407 {
3408 case E_NDS_ABI_V0:
3409 case E_NDS_ABI_V1:
3410 case E_NDS_ABI_V2:
3411 case E_NDS_ABI_V2FP:
3412 case E_NDS_ABI_AABI:
40c7a7cb 3413 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3414 /* In case there are holes in the array. */
3415 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3416 break;
3417
3418 default:
3419 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3420 break;
3421 }
3422
3423 switch (version)
3424 {
3425 case E_NDS32_ELF_VER_1_2:
3426 case E_NDS32_ELF_VER_1_3:
3427 case E_NDS32_ELF_VER_1_4:
3428 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3429 break;
3430
3431 default:
3432 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3433 break;
3434 }
3435
3436 if (E_NDS_ABI_V0 == abi)
3437 {
3438 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3439 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3440 if (arch == E_NDS_ARCH_STAR_V1_0)
3441 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3442 return;
3443 }
3444
3445 switch (arch)
3446 {
3447 case E_NDS_ARCH_STAR_V1_0:
3448 case E_NDS_ARCH_STAR_V2_0:
3449 case E_NDS_ARCH_STAR_V3_0:
3450 case E_NDS_ARCH_STAR_V3_M:
3451 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3452 break;
3453
3454 default:
3455 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3456 /* ARCH version determines how the e_flags are interpreted.
3457 If it is unknown, we cannot proceed. */
3458 return;
3459 }
3460
3461 /* Newer ABI; Now handle architecture specific flags. */
3462 if (arch == E_NDS_ARCH_STAR_V1_0)
3463 {
3464 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3465 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3466
3467 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3468 r += snprintf (buf + r, size -r, ", MAC");
3469
3470 if (config & E_NDS32_HAS_DIV_INST)
3471 r += snprintf (buf + r, size -r, ", DIV");
3472
3473 if (config & E_NDS32_HAS_16BIT_INST)
3474 r += snprintf (buf + r, size -r, ", 16b");
3475 }
3476 else
3477 {
3478 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3479 {
3480 if (version <= E_NDS32_ELF_VER_1_3)
3481 r += snprintf (buf + r, size -r, ", [B8]");
3482 else
3483 r += snprintf (buf + r, size -r, ", EX9");
3484 }
3485
3486 if (config & E_NDS32_HAS_MAC_DX_INST)
3487 r += snprintf (buf + r, size -r, ", MAC_DX");
3488
3489 if (config & E_NDS32_HAS_DIV_DX_INST)
3490 r += snprintf (buf + r, size -r, ", DIV_DX");
3491
3492 if (config & E_NDS32_HAS_16BIT_INST)
3493 {
3494 if (version <= E_NDS32_ELF_VER_1_3)
3495 r += snprintf (buf + r, size -r, ", 16b");
3496 else
3497 r += snprintf (buf + r, size -r, ", IFC");
3498 }
3499 }
3500
3501 if (config & E_NDS32_HAS_EXT_INST)
3502 r += snprintf (buf + r, size -r, ", PERF1");
3503
3504 if (config & E_NDS32_HAS_EXT2_INST)
3505 r += snprintf (buf + r, size -r, ", PERF2");
3506
3507 if (config & E_NDS32_HAS_FPU_INST)
3508 {
015dc7e1 3509 has_fpu = true;
35c08157
KLC
3510 r += snprintf (buf + r, size -r, ", FPU_SP");
3511 }
3512
3513 if (config & E_NDS32_HAS_FPU_DP_INST)
3514 {
015dc7e1 3515 has_fpu = true;
35c08157
KLC
3516 r += snprintf (buf + r, size -r, ", FPU_DP");
3517 }
3518
3519 if (config & E_NDS32_HAS_FPU_MAC_INST)
3520 {
015dc7e1 3521 has_fpu = true;
35c08157
KLC
3522 r += snprintf (buf + r, size -r, ", FPU_MAC");
3523 }
3524
3525 if (has_fpu)
3526 {
3527 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3528 {
3529 case E_NDS32_FPU_REG_8SP_4DP:
3530 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3531 break;
3532 case E_NDS32_FPU_REG_16SP_8DP:
3533 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3534 break;
3535 case E_NDS32_FPU_REG_32SP_16DP:
3536 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3537 break;
3538 case E_NDS32_FPU_REG_32SP_32DP:
3539 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3540 break;
3541 }
3542 }
3543
3544 if (config & E_NDS32_HAS_AUDIO_INST)
3545 r += snprintf (buf + r, size -r, ", AUDIO");
3546
3547 if (config & E_NDS32_HAS_STRING_INST)
3548 r += snprintf (buf + r, size -r, ", STR");
3549
3550 if (config & E_NDS32_HAS_REDUCED_REGS)
3551 r += snprintf (buf + r, size -r, ", 16REG");
3552
3553 if (config & E_NDS32_HAS_VIDEO_INST)
3554 {
3555 if (version <= E_NDS32_ELF_VER_1_3)
3556 r += snprintf (buf + r, size -r, ", VIDEO");
3557 else
3558 r += snprintf (buf + r, size -r, ", SATURATION");
3559 }
3560
3561 if (config & E_NDS32_HAS_ENCRIPT_INST)
3562 r += snprintf (buf + r, size -r, ", ENCRP");
3563
3564 if (config & E_NDS32_HAS_L2C_INST)
3565 r += snprintf (buf + r, size -r, ", L2C");
3566}
3567
252b5132 3568static char *
dda8d76d 3569get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3570{
b34976b6 3571 static char buf[1024];
252b5132
RH
3572
3573 buf[0] = '\0';
76da6bbe 3574
252b5132
RH
3575 if (e_flags)
3576 {
3577 switch (e_machine)
3578 {
3579 default:
3580 break;
3581
886a2506 3582 case EM_ARC_COMPACT2:
886a2506 3583 case EM_ARC_COMPACT:
a9522a21
AB
3584 decode_ARC_machine_flags (e_flags, e_machine, buf);
3585 break;
886a2506 3586
f3485b74
NC
3587 case EM_ARM:
3588 decode_ARM_machine_flags (e_flags, buf);
3589 break;
76da6bbe 3590
343433df
AB
3591 case EM_AVR:
3592 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3593 break;
3594
781303ce
MF
3595 case EM_BLACKFIN:
3596 if (e_flags & EF_BFIN_PIC)
3597 strcat (buf, ", PIC");
3598
3599 if (e_flags & EF_BFIN_FDPIC)
3600 strcat (buf, ", FDPIC");
3601
3602 if (e_flags & EF_BFIN_CODE_IN_L1)
3603 strcat (buf, ", code in L1");
3604
3605 if (e_flags & EF_BFIN_DATA_IN_L1)
3606 strcat (buf, ", data in L1");
3607
3608 break;
3609
ec2dfb42
AO
3610 case EM_CYGNUS_FRV:
3611 switch (e_flags & EF_FRV_CPU_MASK)
3612 {
3613 case EF_FRV_CPU_GENERIC:
3614 break;
3615
3616 default:
3617 strcat (buf, ", fr???");
3618 break;
57346661 3619
ec2dfb42
AO
3620 case EF_FRV_CPU_FR300:
3621 strcat (buf, ", fr300");
3622 break;
3623
3624 case EF_FRV_CPU_FR400:
3625 strcat (buf, ", fr400");
3626 break;
3627 case EF_FRV_CPU_FR405:
3628 strcat (buf, ", fr405");
3629 break;
3630
3631 case EF_FRV_CPU_FR450:
3632 strcat (buf, ", fr450");
3633 break;
3634
3635 case EF_FRV_CPU_FR500:
3636 strcat (buf, ", fr500");
3637 break;
3638 case EF_FRV_CPU_FR550:
3639 strcat (buf, ", fr550");
3640 break;
3641
3642 case EF_FRV_CPU_SIMPLE:
3643 strcat (buf, ", simple");
3644 break;
3645 case EF_FRV_CPU_TOMCAT:
3646 strcat (buf, ", tomcat");
3647 break;
3648 }
1c877e87 3649 break;
ec2dfb42 3650
53c7db4b 3651 case EM_68K:
425c6cb0 3652 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3653 strcat (buf, ", m68000");
425c6cb0 3654 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3655 strcat (buf, ", cpu32");
3656 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3657 strcat (buf, ", fido_a");
425c6cb0 3658 else
266abb8f 3659 {
2cf0635d
NC
3660 char const * isa = _("unknown");
3661 char const * mac = _("unknown mac");
3662 char const * additional = NULL;
0112cd26 3663
c694fd50 3664 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3665 {
c694fd50 3666 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3667 isa = "A";
3668 additional = ", nodiv";
3669 break;
c694fd50 3670 case EF_M68K_CF_ISA_A:
266abb8f
NS
3671 isa = "A";
3672 break;
c694fd50 3673 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3674 isa = "A+";
3675 break;
c694fd50 3676 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3677 isa = "B";
3678 additional = ", nousp";
3679 break;
c694fd50 3680 case EF_M68K_CF_ISA_B:
266abb8f
NS
3681 isa = "B";
3682 break;
f608cd77
NS
3683 case EF_M68K_CF_ISA_C:
3684 isa = "C";
3685 break;
3686 case EF_M68K_CF_ISA_C_NODIV:
3687 isa = "C";
3688 additional = ", nodiv";
3689 break;
266abb8f
NS
3690 }
3691 strcat (buf, ", cf, isa ");
3692 strcat (buf, isa);
0b2e31dc
NS
3693 if (additional)
3694 strcat (buf, additional);
c694fd50 3695 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3696 strcat (buf, ", float");
c694fd50 3697 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3698 {
3699 case 0:
3700 mac = NULL;
3701 break;
c694fd50 3702 case EF_M68K_CF_MAC:
266abb8f
NS
3703 mac = "mac";
3704 break;
c694fd50 3705 case EF_M68K_CF_EMAC:
266abb8f
NS
3706 mac = "emac";
3707 break;
f608cd77
NS
3708 case EF_M68K_CF_EMAC_B:
3709 mac = "emac_b";
3710 break;
266abb8f
NS
3711 }
3712 if (mac)
3713 {
3714 strcat (buf, ", ");
3715 strcat (buf, mac);
3716 }
266abb8f 3717 }
53c7db4b 3718 break;
33c63f9d 3719
153a2776
NC
3720 case EM_CYGNUS_MEP:
3721 switch (e_flags & EF_MEP_CPU_MASK)
3722 {
3723 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3724 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3725 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3726 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3727 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3728 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3729 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3730 }
3731
3732 switch (e_flags & EF_MEP_COP_MASK)
3733 {
3734 case EF_MEP_COP_NONE: break;
3735 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3736 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3737 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3738 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3739 default: strcat (buf, _("<unknown MeP copro type>")); break;
3740 }
3741
3742 if (e_flags & EF_MEP_LIBRARY)
3743 strcat (buf, ", Built for Library");
3744
3745 if (e_flags & EF_MEP_INDEX_MASK)
3746 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3747 e_flags & EF_MEP_INDEX_MASK);
3748
3749 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3750 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3751 e_flags & ~ EF_MEP_ALL_FLAGS);
3752 break;
3753
252b5132
RH
3754 case EM_PPC:
3755 if (e_flags & EF_PPC_EMB)
3756 strcat (buf, ", emb");
3757
3758 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3759 strcat (buf, _(", relocatable"));
252b5132
RH
3760
3761 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3762 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3763 break;
3764
ee67d69a
AM
3765 case EM_PPC64:
3766 if (e_flags & EF_PPC64_ABI)
3767 {
3768 char abi[] = ", abiv0";
3769
3770 abi[6] += e_flags & EF_PPC64_ABI;
3771 strcat (buf, abi);
3772 }
3773 break;
3774
708e2187
NC
3775 case EM_V800:
3776 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3777 strcat (buf, ", RH850 ABI");
0b4362b0 3778
708e2187
NC
3779 if (e_flags & EF_V800_850E3)
3780 strcat (buf, ", V3 architecture");
3781
3782 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3783 strcat (buf, ", FPU not used");
3784
3785 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3786 strcat (buf, ", regmode: COMMON");
3787
3788 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3789 strcat (buf, ", r4 not used");
3790
3791 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3792 strcat (buf, ", r30 not used");
3793
3794 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3795 strcat (buf, ", r5 not used");
3796
3797 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3798 strcat (buf, ", r2 not used");
3799
3800 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3801 {
3802 switch (e_flags & - e_flags)
3803 {
3804 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3805 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3806 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3807 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3808 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3809 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3810 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3811 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3812 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3813 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3814 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3815 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3816 default: break;
3817 }
3818 }
3819 break;
3820
2b0337b0 3821 case EM_V850:
252b5132
RH
3822 case EM_CYGNUS_V850:
3823 switch (e_flags & EF_V850_ARCH)
3824 {
78c8d46c
NC
3825 case E_V850E3V5_ARCH:
3826 strcat (buf, ", v850e3v5");
3827 break;
1cd986c5
NC
3828 case E_V850E2V3_ARCH:
3829 strcat (buf, ", v850e2v3");
3830 break;
3831 case E_V850E2_ARCH:
3832 strcat (buf, ", v850e2");
3833 break;
3834 case E_V850E1_ARCH:
3835 strcat (buf, ", v850e1");
8ad30312 3836 break;
252b5132
RH
3837 case E_V850E_ARCH:
3838 strcat (buf, ", v850e");
3839 break;
252b5132
RH
3840 case E_V850_ARCH:
3841 strcat (buf, ", v850");
3842 break;
3843 default:
2b692964 3844 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3845 break;
3846 }
3847 break;
3848
2b0337b0 3849 case EM_M32R:
252b5132
RH
3850 case EM_CYGNUS_M32R:
3851 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3852 strcat (buf, ", m32r");
252b5132
RH
3853 break;
3854
3855 case EM_MIPS:
4fe85591 3856 case EM_MIPS_RS3_LE:
252b5132
RH
3857 if (e_flags & EF_MIPS_NOREORDER)
3858 strcat (buf, ", noreorder");
3859
3860 if (e_flags & EF_MIPS_PIC)
3861 strcat (buf, ", pic");
3862
3863 if (e_flags & EF_MIPS_CPIC)
3864 strcat (buf, ", cpic");
3865
d1bdd336
TS
3866 if (e_flags & EF_MIPS_UCODE)
3867 strcat (buf, ", ugen_reserved");
3868
252b5132
RH
3869 if (e_flags & EF_MIPS_ABI2)
3870 strcat (buf, ", abi2");
3871
43521d43
TS
3872 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3873 strcat (buf, ", odk first");
3874
a5d22d2a
TS
3875 if (e_flags & EF_MIPS_32BITMODE)
3876 strcat (buf, ", 32bitmode");
3877
ba92f887
MR
3878 if (e_flags & EF_MIPS_NAN2008)
3879 strcat (buf, ", nan2008");
3880
fef1b0b3
SE
3881 if (e_flags & EF_MIPS_FP64)
3882 strcat (buf, ", fp64");
3883
156c2f8b
NC
3884 switch ((e_flags & EF_MIPS_MACH))
3885 {
3886 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3887 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3888 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3889 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3890 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3891 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3892 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3893 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3894 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3895 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3896 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3897 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3898 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3899 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3900 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3901 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3902 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3903 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3904 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3905 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3906 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3907 case 0:
3908 /* We simply ignore the field in this case to avoid confusion:
3909 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3910 extension. */
3911 break;
2b692964 3912 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3913 }
43521d43
TS
3914
3915 switch ((e_flags & EF_MIPS_ABI))
3916 {
3917 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3918 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3919 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3920 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3921 case 0:
3922 /* We simply ignore the field in this case to avoid confusion:
3923 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3924 This means it is likely to be an o32 file, but not for
3925 sure. */
3926 break;
2b692964 3927 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3928 }
3929
3930 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3931 strcat (buf, ", mdmx");
3932
3933 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3934 strcat (buf, ", mips16");
3935
df58fc94
RS
3936 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3937 strcat (buf, ", micromips");
3938
43521d43
TS
3939 switch ((e_flags & EF_MIPS_ARCH))
3940 {
3941 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3942 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3943 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3944 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3945 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3946 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3947 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3948 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3949 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3950 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3951 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3952 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3953 }
252b5132 3954 break;
351b4b40 3955
35c08157
KLC
3956 case EM_NDS32:
3957 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3958 break;
3959
fe944acf
FT
3960 case EM_NFP:
3961 switch (EF_NFP_MACH (e_flags))
3962 {
3963 case E_NFP_MACH_3200:
3964 strcat (buf, ", NFP-32xx");
3965 break;
3966 case E_NFP_MACH_6000:
3967 strcat (buf, ", NFP-6xxx");
3968 break;
3969 }
3970 break;
3971
e23eba97
NC
3972 case EM_RISCV:
3973 if (e_flags & EF_RISCV_RVC)
3974 strcat (buf, ", RVC");
2922d21d 3975
7f999549
JW
3976 if (e_flags & EF_RISCV_RVE)
3977 strcat (buf, ", RVE");
3978
2922d21d
AW
3979 switch (e_flags & EF_RISCV_FLOAT_ABI)
3980 {
3981 case EF_RISCV_FLOAT_ABI_SOFT:
3982 strcat (buf, ", soft-float ABI");
3983 break;
3984
3985 case EF_RISCV_FLOAT_ABI_SINGLE:
3986 strcat (buf, ", single-float ABI");
3987 break;
3988
3989 case EF_RISCV_FLOAT_ABI_DOUBLE:
3990 strcat (buf, ", double-float ABI");
3991 break;
3992
3993 case EF_RISCV_FLOAT_ABI_QUAD:
3994 strcat (buf, ", quad-float ABI");
3995 break;
3996 }
e23eba97
NC
3997 break;
3998
ccde1100
AO
3999 case EM_SH:
4000 switch ((e_flags & EF_SH_MACH_MASK))
4001 {
4002 case EF_SH1: strcat (buf, ", sh1"); break;
4003 case EF_SH2: strcat (buf, ", sh2"); break;
4004 case EF_SH3: strcat (buf, ", sh3"); break;
4005 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
4006 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
4007 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
4008 case EF_SH3E: strcat (buf, ", sh3e"); break;
4009 case EF_SH4: strcat (buf, ", sh4"); break;
4010 case EF_SH5: strcat (buf, ", sh5"); break;
4011 case EF_SH2E: strcat (buf, ", sh2e"); break;
4012 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 4013 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
4014 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
4015 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 4016 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
4017 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
4018 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
4019 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
4020 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
4021 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
4022 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 4023 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
4024 }
4025
cec6a5b8
MR
4026 if (e_flags & EF_SH_PIC)
4027 strcat (buf, ", pic");
4028
4029 if (e_flags & EF_SH_FDPIC)
4030 strcat (buf, ", fdpic");
ccde1100 4031 break;
948f632f 4032
73589c9d
CS
4033 case EM_OR1K:
4034 if (e_flags & EF_OR1K_NODELAY)
4035 strcat (buf, ", no delay");
4036 break;
57346661 4037
351b4b40
RH
4038 case EM_SPARCV9:
4039 if (e_flags & EF_SPARC_32PLUS)
4040 strcat (buf, ", v8+");
4041
4042 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
4043 strcat (buf, ", ultrasparcI");
4044
4045 if (e_flags & EF_SPARC_SUN_US3)
4046 strcat (buf, ", ultrasparcIII");
351b4b40
RH
4047
4048 if (e_flags & EF_SPARC_HAL_R1)
4049 strcat (buf, ", halr1");
4050
4051 if (e_flags & EF_SPARC_LEDATA)
4052 strcat (buf, ", ledata");
4053
4054 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
4055 strcat (buf, ", tso");
4056
4057 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
4058 strcat (buf, ", pso");
4059
4060 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
4061 strcat (buf, ", rmo");
4062 break;
7d466069 4063
103f02d3
UD
4064 case EM_PARISC:
4065 switch (e_flags & EF_PARISC_ARCH)
4066 {
4067 case EFA_PARISC_1_0:
4068 strcpy (buf, ", PA-RISC 1.0");
4069 break;
4070 case EFA_PARISC_1_1:
4071 strcpy (buf, ", PA-RISC 1.1");
4072 break;
4073 case EFA_PARISC_2_0:
4074 strcpy (buf, ", PA-RISC 2.0");
4075 break;
4076 default:
4077 break;
4078 }
4079 if (e_flags & EF_PARISC_TRAPNIL)
4080 strcat (buf, ", trapnil");
4081 if (e_flags & EF_PARISC_EXT)
4082 strcat (buf, ", ext");
4083 if (e_flags & EF_PARISC_LSB)
4084 strcat (buf, ", lsb");
4085 if (e_flags & EF_PARISC_WIDE)
4086 strcat (buf, ", wide");
4087 if (e_flags & EF_PARISC_NO_KABP)
4088 strcat (buf, ", no kabp");
4089 if (e_flags & EF_PARISC_LAZYSWAP)
4090 strcat (buf, ", lazyswap");
30800947 4091 break;
76da6bbe 4092
7d466069 4093 case EM_PJ:
2b0337b0 4094 case EM_PJ_OLD:
7d466069
ILT
4095 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
4096 strcat (buf, ", new calling convention");
4097
4098 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
4099 strcat (buf, ", gnu calling convention");
4100 break;
4d6ed7c8
NC
4101
4102 case EM_IA_64:
4103 if ((e_flags & EF_IA_64_ABI64))
4104 strcat (buf, ", 64-bit");
4105 else
4106 strcat (buf, ", 32-bit");
4107 if ((e_flags & EF_IA_64_REDUCEDFP))
4108 strcat (buf, ", reduced fp model");
4109 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
4110 strcat (buf, ", no function descriptors, constant gp");
4111 else if ((e_flags & EF_IA_64_CONS_GP))
4112 strcat (buf, ", constant gp");
4113 if ((e_flags & EF_IA_64_ABSOLUTE))
4114 strcat (buf, ", absolute");
dda8d76d 4115 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
4116 {
4117 if ((e_flags & EF_IA_64_VMS_LINKAGES))
4118 strcat (buf, ", vms_linkages");
4119 switch ((e_flags & EF_IA_64_VMS_COMCOD))
4120 {
4121 case EF_IA_64_VMS_COMCOD_SUCCESS:
4122 break;
4123 case EF_IA_64_VMS_COMCOD_WARNING:
4124 strcat (buf, ", warning");
4125 break;
4126 case EF_IA_64_VMS_COMCOD_ERROR:
4127 strcat (buf, ", error");
4128 break;
4129 case EF_IA_64_VMS_COMCOD_ABORT:
4130 strcat (buf, ", abort");
4131 break;
4132 default:
bee0ee85
NC
4133 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
4134 e_flags & EF_IA_64_VMS_COMCOD);
4135 strcat (buf, ", <unknown>");
28f997cf
TG
4136 }
4137 }
4d6ed7c8 4138 break;
179d3252
JT
4139
4140 case EM_VAX:
4141 if ((e_flags & EF_VAX_NONPIC))
4142 strcat (buf, ", non-PIC");
4143 if ((e_flags & EF_VAX_DFLOAT))
4144 strcat (buf, ", D-Float");
4145 if ((e_flags & EF_VAX_GFLOAT))
4146 strcat (buf, ", G-Float");
4147 break;
c7927a3c 4148
619ed720
EB
4149 case EM_VISIUM:
4150 if (e_flags & EF_VISIUM_ARCH_MCM)
4151 strcat (buf, ", mcm");
4152 else if (e_flags & EF_VISIUM_ARCH_MCM24)
4153 strcat (buf, ", mcm24");
4154 if (e_flags & EF_VISIUM_ARCH_GR6)
4155 strcat (buf, ", gr6");
4156 break;
4157
4046d87a 4158 case EM_RL78:
1740ba0c
NC
4159 switch (e_flags & E_FLAG_RL78_CPU_MASK)
4160 {
4161 case E_FLAG_RL78_ANY_CPU: break;
4162 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
4163 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
4164 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
4165 }
856ea05c
KP
4166 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
4167 strcat (buf, ", 64-bit doubles");
4046d87a 4168 break;
0b4362b0 4169
c7927a3c
NC
4170 case EM_RX:
4171 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
4172 strcat (buf, ", 64-bit doubles");
4173 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 4174 strcat (buf, ", dsp");
d4cb0ea0 4175 if (e_flags & E_FLAG_RX_PID)
0b4362b0 4176 strcat (buf, ", pid");
708e2187
NC
4177 if (e_flags & E_FLAG_RX_ABI)
4178 strcat (buf, ", RX ABI");
3525236c
NC
4179 if (e_flags & E_FLAG_RX_SINSNS_SET)
4180 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
4181 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
4182 if (e_flags & E_FLAG_RX_V2)
4183 strcat (buf, ", V2");
f87673e0
YS
4184 if (e_flags & E_FLAG_RX_V3)
4185 strcat (buf, ", V3");
d4cb0ea0 4186 break;
55786da2
AK
4187
4188 case EM_S390:
4189 if (e_flags & EF_S390_HIGH_GPRS)
4190 strcat (buf, ", highgprs");
d4cb0ea0 4191 break;
40b36596
JM
4192
4193 case EM_TI_C6000:
4194 if ((e_flags & EF_C6000_REL))
4195 strcat (buf, ", relocatable module");
d4cb0ea0 4196 break;
13761a11
NC
4197
4198 case EM_MSP430:
4199 strcat (buf, _(": architecture variant: "));
4200 switch (e_flags & EF_MSP430_MACH)
4201 {
4202 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
4203 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
4204 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
4205 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
4206 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
4207 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
4208 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
4209 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
4210 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
4211 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
4212 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
4213 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
4214 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
4215 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
4216 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
4217 default:
4218 strcat (buf, _(": unknown")); break;
4219 }
4220
4221 if (e_flags & ~ EF_MSP430_MACH)
4222 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
4223 break;
4224
4225 case EM_Z80:
4226 switch (e_flags & EF_Z80_MACH_MSK)
4227 {
4228 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
4229 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
4230 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
4231 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
4232 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
4233 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 4234 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
4235 default:
4236 strcat (buf, _(", unknown")); break;
4237 }
4238 break;
e9a0721f 4239 case EM_LOONGARCH:
4240 if (EF_LOONGARCH_IS_LP64 (e_flags))
4241 strcat (buf, ", LP64");
4242 else if (EF_LOONGARCH_IS_ILP32 (e_flags))
4243 strcat (buf, ", ILP32");
4244
4245 if (EF_LOONGARCH_IS_SOFT_FLOAT (e_flags))
4246 strcat (buf, ", SOFT-FLOAT");
4247 else if (EF_LOONGARCH_IS_SINGLE_FLOAT (e_flags))
4248 strcat (buf, ", SINGLE-FLOAT");
4249 else if (EF_LOONGARCH_IS_DOUBLE_FLOAT (e_flags))
4250 strcat (buf, ", DOUBLE-FLOAT");
4251
4252 break;
252b5132
RH
4253 }
4254 }
4255
4256 return buf;
4257}
4258
252b5132 4259static const char *
dda8d76d 4260get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
4261{
4262 static char buff[32];
4263
4264 switch (osabi)
4265 {
4266 case ELFOSABI_NONE: return "UNIX - System V";
4267 case ELFOSABI_HPUX: return "UNIX - HP-UX";
4268 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 4269 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
4270 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
4271 case ELFOSABI_AIX: return "UNIX - AIX";
4272 case ELFOSABI_IRIX: return "UNIX - IRIX";
4273 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
4274 case ELFOSABI_TRU64: return "UNIX - TRU64";
4275 case ELFOSABI_MODESTO: return "Novell - Modesto";
4276 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
4277 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
4278 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 4279 case ELFOSABI_AROS: return "AROS";
11636f9e 4280 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
4281 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
4282 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 4283 default:
40b36596 4284 if (osabi >= 64)
dda8d76d 4285 switch (filedata->file_header.e_machine)
40b36596
JM
4286 {
4287 case EM_ARM:
4288 switch (osabi)
4289 {
4290 case ELFOSABI_ARM: return "ARM";
18a20338 4291 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4292 default:
4293 break;
4294 }
4295 break;
4296
4297 case EM_MSP430:
4298 case EM_MSP430_OLD:
619ed720 4299 case EM_VISIUM:
40b36596
JM
4300 switch (osabi)
4301 {
4302 case ELFOSABI_STANDALONE: return _("Standalone App");
4303 default:
4304 break;
4305 }
4306 break;
4307
4308 case EM_TI_C6000:
4309 switch (osabi)
4310 {
4311 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4312 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4313 default:
4314 break;
4315 }
4316 break;
4317
4318 default:
4319 break;
4320 }
e9e44622 4321 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4322 return buff;
4323 }
4324}
4325
a06ea964
NC
4326static const char *
4327get_aarch64_segment_type (unsigned long type)
4328{
4329 switch (type)
4330 {
32ec8896
NC
4331 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4332 default: return NULL;
a06ea964 4333 }
a06ea964
NC
4334}
4335
b294bdf8
MM
4336static const char *
4337get_arm_segment_type (unsigned long type)
4338{
4339 switch (type)
4340 {
32ec8896
NC
4341 case PT_ARM_EXIDX: return "EXIDX";
4342 default: return NULL;
b294bdf8 4343 }
b294bdf8
MM
4344}
4345
b4cbbe8f
AK
4346static const char *
4347get_s390_segment_type (unsigned long type)
4348{
4349 switch (type)
4350 {
4351 case PT_S390_PGSTE: return "S390_PGSTE";
4352 default: return NULL;
4353 }
4354}
4355
d3ba0551
AM
4356static const char *
4357get_mips_segment_type (unsigned long type)
252b5132
RH
4358{
4359 switch (type)
4360 {
32ec8896
NC
4361 case PT_MIPS_REGINFO: return "REGINFO";
4362 case PT_MIPS_RTPROC: return "RTPROC";
4363 case PT_MIPS_OPTIONS: return "OPTIONS";
4364 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4365 default: return NULL;
252b5132 4366 }
252b5132
RH
4367}
4368
103f02d3 4369static const char *
d3ba0551 4370get_parisc_segment_type (unsigned long type)
103f02d3
UD
4371{
4372 switch (type)
4373 {
103f02d3
UD
4374 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4375 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4376 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4377 default: return NULL;
103f02d3 4378 }
103f02d3
UD
4379}
4380
4d6ed7c8 4381static const char *
d3ba0551 4382get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4383{
4384 switch (type)
4385 {
4386 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4387 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4388 default: return NULL;
4d6ed7c8 4389 }
4d6ed7c8
NC
4390}
4391
40b36596
JM
4392static const char *
4393get_tic6x_segment_type (unsigned long type)
4394{
4395 switch (type)
4396 {
32ec8896
NC
4397 case PT_C6000_PHATTR: return "C6000_PHATTR";
4398 default: return NULL;
40b36596 4399 }
40b36596
JM
4400}
4401
fbc95f1e
KC
4402static const char *
4403get_riscv_segment_type (unsigned long type)
4404{
4405 switch (type)
4406 {
4407 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4408 default: return NULL;
4409 }
4410}
4411
df3a023b
AM
4412static const char *
4413get_hpux_segment_type (unsigned long type, unsigned e_machine)
4414{
4415 if (e_machine == EM_PARISC)
4416 switch (type)
4417 {
4418 case PT_HP_TLS: return "HP_TLS";
4419 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4420 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4421 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4422 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4423 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4424 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4425 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4426 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4427 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4428 case PT_HP_PARALLEL: return "HP_PARALLEL";
4429 case PT_HP_FASTBIND: return "HP_FASTBIND";
4430 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4431 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4432 case PT_HP_STACK: return "HP_STACK";
4433 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4434 default: return NULL;
4435 }
4436
4437 if (e_machine == EM_IA_64)
4438 switch (type)
4439 {
4440 case PT_HP_TLS: return "HP_TLS";
4441 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4442 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4443 case PT_IA_64_HP_STACK: return "HP_STACK";
4444 default: return NULL;
4445 }
4446
4447 return NULL;
4448}
4449
5522f910
NC
4450static const char *
4451get_solaris_segment_type (unsigned long type)
4452{
4453 switch (type)
4454 {
4455 case 0x6464e550: return "PT_SUNW_UNWIND";
4456 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4457 case 0x6ffffff7: return "PT_LOSUNW";
4458 case 0x6ffffffa: return "PT_SUNWBSS";
4459 case 0x6ffffffb: return "PT_SUNWSTACK";
4460 case 0x6ffffffc: return "PT_SUNWDTRACE";
4461 case 0x6ffffffd: return "PT_SUNWCAP";
4462 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4463 default: return NULL;
5522f910
NC
4464 }
4465}
4466
252b5132 4467static const char *
dda8d76d 4468get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4469{
b34976b6 4470 static char buff[32];
252b5132
RH
4471
4472 switch (p_type)
4473 {
b34976b6
AM
4474 case PT_NULL: return "NULL";
4475 case PT_LOAD: return "LOAD";
252b5132 4476 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4477 case PT_INTERP: return "INTERP";
4478 case PT_NOTE: return "NOTE";
4479 case PT_SHLIB: return "SHLIB";
4480 case PT_PHDR: return "PHDR";
13ae64f3 4481 case PT_TLS: return "TLS";
32ec8896 4482 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4483 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4484 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4485 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4486
3eba3ef3
NC
4487 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4488 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4489 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4490
252b5132 4491 default:
df3a023b 4492 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4493 {
2cf0635d 4494 const char * result;
103f02d3 4495
dda8d76d 4496 switch (filedata->file_header.e_machine)
252b5132 4497 {
a06ea964
NC
4498 case EM_AARCH64:
4499 result = get_aarch64_segment_type (p_type);
4500 break;
b294bdf8
MM
4501 case EM_ARM:
4502 result = get_arm_segment_type (p_type);
4503 break;
252b5132 4504 case EM_MIPS:
4fe85591 4505 case EM_MIPS_RS3_LE:
252b5132
RH
4506 result = get_mips_segment_type (p_type);
4507 break;
103f02d3
UD
4508 case EM_PARISC:
4509 result = get_parisc_segment_type (p_type);
4510 break;
4d6ed7c8
NC
4511 case EM_IA_64:
4512 result = get_ia64_segment_type (p_type);
4513 break;
40b36596
JM
4514 case EM_TI_C6000:
4515 result = get_tic6x_segment_type (p_type);
4516 break;
b4cbbe8f
AK
4517 case EM_S390:
4518 case EM_S390_OLD:
4519 result = get_s390_segment_type (p_type);
4520 break;
fbc95f1e
KC
4521 case EM_RISCV:
4522 result = get_riscv_segment_type (p_type);
4523 break;
252b5132
RH
4524 default:
4525 result = NULL;
4526 break;
4527 }
103f02d3 4528
252b5132
RH
4529 if (result != NULL)
4530 return result;
103f02d3 4531
1a9ccd70 4532 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4533 }
4534 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4535 {
df3a023b 4536 const char * result = NULL;
103f02d3 4537
df3a023b 4538 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4539 {
df3a023b
AM
4540 case ELFOSABI_GNU:
4541 case ELFOSABI_FREEBSD:
4542 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4543 {
4544 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4545 result = buff;
4546 }
103f02d3 4547 break;
df3a023b
AM
4548 case ELFOSABI_HPUX:
4549 result = get_hpux_segment_type (p_type,
4550 filedata->file_header.e_machine);
4551 break;
4552 case ELFOSABI_SOLARIS:
4553 result = get_solaris_segment_type (p_type);
00428cca 4554 break;
103f02d3 4555 default:
103f02d3
UD
4556 break;
4557 }
103f02d3
UD
4558 if (result != NULL)
4559 return result;
4560
1a9ccd70 4561 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4562 }
252b5132 4563 else
e9e44622 4564 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4565
4566 return buff;
4567 }
4568}
4569
53a346d8
CZ
4570static const char *
4571get_arc_section_type_name (unsigned int sh_type)
4572{
4573 switch (sh_type)
4574 {
4575 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4576 default:
4577 break;
4578 }
4579 return NULL;
4580}
4581
252b5132 4582static const char *
d3ba0551 4583get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4584{
4585 switch (sh_type)
4586 {
b34976b6
AM
4587 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4588 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4589 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4590 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4591 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4592 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4593 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4594 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4595 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4596 case SHT_MIPS_RELD: return "MIPS_RELD";
4597 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4598 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4599 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4600 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4601 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4602 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4603 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4604 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4605 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4606 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4607 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4608 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4609 case SHT_MIPS_LINE: return "MIPS_LINE";
4610 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4611 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4612 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4613 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4614 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4615 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4616 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4617 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4618 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4619 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4620 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4621 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4622 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4623 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4624 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4625 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4626 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4627 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4628 default:
4629 break;
4630 }
4631 return NULL;
4632}
4633
103f02d3 4634static const char *
d3ba0551 4635get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4636{
4637 switch (sh_type)
4638 {
4639 case SHT_PARISC_EXT: return "PARISC_EXT";
4640 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4641 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4642 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4643 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4644 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4645 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4646 default: return NULL;
103f02d3 4647 }
103f02d3
UD
4648}
4649
4d6ed7c8 4650static const char *
dda8d76d 4651get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4652{
18bd398b 4653 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4654 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4655 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4656
4d6ed7c8
NC
4657 switch (sh_type)
4658 {
148b93f2
NC
4659 case SHT_IA_64_EXT: return "IA_64_EXT";
4660 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4661 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4662 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4663 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4664 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4665 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4666 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4667 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4668 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4669 default:
4670 break;
4671 }
4672 return NULL;
4673}
4674
d2b2c203
DJ
4675static const char *
4676get_x86_64_section_type_name (unsigned int sh_type)
4677{
4678 switch (sh_type)
4679 {
4680 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4681 default: return NULL;
d2b2c203 4682 }
d2b2c203
DJ
4683}
4684
a06ea964
NC
4685static const char *
4686get_aarch64_section_type_name (unsigned int sh_type)
4687{
4688 switch (sh_type)
4689 {
32ec8896
NC
4690 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4691 default: return NULL;
a06ea964 4692 }
a06ea964
NC
4693}
4694
40a18ebd
NC
4695static const char *
4696get_arm_section_type_name (unsigned int sh_type)
4697{
4698 switch (sh_type)
4699 {
7f6fed87
NC
4700 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4701 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4702 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4703 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4704 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4705 default: return NULL;
40a18ebd 4706 }
40a18ebd
NC
4707}
4708
40b36596
JM
4709static const char *
4710get_tic6x_section_type_name (unsigned int sh_type)
4711{
4712 switch (sh_type)
4713 {
32ec8896
NC
4714 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4715 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4716 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4717 case SHT_TI_ICODE: return "TI_ICODE";
4718 case SHT_TI_XREF: return "TI_XREF";
4719 case SHT_TI_HANDLER: return "TI_HANDLER";
4720 case SHT_TI_INITINFO: return "TI_INITINFO";
4721 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4722 default: return NULL;
40b36596 4723 }
40b36596
JM
4724}
4725
13761a11 4726static const char *
b0191216 4727get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4728{
4729 switch (sh_type)
4730 {
32ec8896
NC
4731 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4732 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4733 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4734 default: return NULL;
13761a11
NC
4735 }
4736}
4737
fe944acf
FT
4738static const char *
4739get_nfp_section_type_name (unsigned int sh_type)
4740{
4741 switch (sh_type)
4742 {
4743 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4744 case SHT_NFP_INITREG: return "NFP_INITREG";
4745 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4746 default: return NULL;
4747 }
4748}
4749
685080f2
NC
4750static const char *
4751get_v850_section_type_name (unsigned int sh_type)
4752{
4753 switch (sh_type)
4754 {
32ec8896
NC
4755 case SHT_V850_SCOMMON: return "V850 Small Common";
4756 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4757 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4758 case SHT_RENESAS_IOP: return "RENESAS IOP";
4759 case SHT_RENESAS_INFO: return "RENESAS INFO";
4760 default: return NULL;
685080f2
NC
4761 }
4762}
4763
2dc8dd17
JW
4764static const char *
4765get_riscv_section_type_name (unsigned int sh_type)
4766{
4767 switch (sh_type)
4768 {
4769 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4770 default: return NULL;
4771 }
4772}
4773
0861f561
CQ
4774static const char *
4775get_csky_section_type_name (unsigned int sh_type)
4776{
4777 switch (sh_type)
4778 {
4779 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4780 default: return NULL;
4781 }
4782}
4783
252b5132 4784static const char *
dda8d76d 4785get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4786{
b34976b6 4787 static char buff[32];
9fb71ee4 4788 const char * result;
252b5132
RH
4789
4790 switch (sh_type)
4791 {
4792 case SHT_NULL: return "NULL";
4793 case SHT_PROGBITS: return "PROGBITS";
4794 case SHT_SYMTAB: return "SYMTAB";
4795 case SHT_STRTAB: return "STRTAB";
4796 case SHT_RELA: return "RELA";
dd207c13 4797 case SHT_RELR: return "RELR";
252b5132
RH
4798 case SHT_HASH: return "HASH";
4799 case SHT_DYNAMIC: return "DYNAMIC";
4800 case SHT_NOTE: return "NOTE";
4801 case SHT_NOBITS: return "NOBITS";
4802 case SHT_REL: return "REL";
4803 case SHT_SHLIB: return "SHLIB";
4804 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4805 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4806 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4807 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4808 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4809 case SHT_GROUP: return "GROUP";
67ce483b 4810 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4811 case SHT_GNU_verdef: return "VERDEF";
4812 case SHT_GNU_verneed: return "VERNEED";
4813 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4814 case 0x6ffffff0: return "VERSYM";
4815 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4816 case 0x7ffffffd: return "AUXILIARY";
4817 case 0x7fffffff: return "FILTER";
047b2264 4818 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4819
4820 default:
4821 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4822 {
dda8d76d 4823 switch (filedata->file_header.e_machine)
252b5132 4824 {
53a346d8
CZ
4825 case EM_ARC:
4826 case EM_ARC_COMPACT:
4827 case EM_ARC_COMPACT2:
4828 result = get_arc_section_type_name (sh_type);
4829 break;
252b5132 4830 case EM_MIPS:
4fe85591 4831 case EM_MIPS_RS3_LE:
252b5132
RH
4832 result = get_mips_section_type_name (sh_type);
4833 break;
103f02d3
UD
4834 case EM_PARISC:
4835 result = get_parisc_section_type_name (sh_type);
4836 break;
4d6ed7c8 4837 case EM_IA_64:
dda8d76d 4838 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4839 break;
d2b2c203 4840 case EM_X86_64:
8a9036a4 4841 case EM_L1OM:
7a9068fe 4842 case EM_K1OM:
d2b2c203
DJ
4843 result = get_x86_64_section_type_name (sh_type);
4844 break;
a06ea964
NC
4845 case EM_AARCH64:
4846 result = get_aarch64_section_type_name (sh_type);
4847 break;
40a18ebd
NC
4848 case EM_ARM:
4849 result = get_arm_section_type_name (sh_type);
4850 break;
40b36596
JM
4851 case EM_TI_C6000:
4852 result = get_tic6x_section_type_name (sh_type);
4853 break;
13761a11 4854 case EM_MSP430:
b0191216 4855 result = get_msp430_section_type_name (sh_type);
13761a11 4856 break;
fe944acf
FT
4857 case EM_NFP:
4858 result = get_nfp_section_type_name (sh_type);
4859 break;
685080f2
NC
4860 case EM_V800:
4861 case EM_V850:
4862 case EM_CYGNUS_V850:
4863 result = get_v850_section_type_name (sh_type);
4864 break;
2dc8dd17
JW
4865 case EM_RISCV:
4866 result = get_riscv_section_type_name (sh_type);
4867 break;
0861f561
CQ
4868 case EM_CSKY:
4869 result = get_csky_section_type_name (sh_type);
4870 break;
252b5132
RH
4871 default:
4872 result = NULL;
4873 break;
4874 }
4875
4876 if (result != NULL)
4877 return result;
4878
9fb71ee4 4879 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4880 }
4881 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4882 {
dda8d76d 4883 switch (filedata->file_header.e_machine)
148b93f2
NC
4884 {
4885 case EM_IA_64:
dda8d76d 4886 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4887 break;
4888 default:
dda8d76d 4889 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4890 result = get_solaris_section_type (sh_type);
4891 else
1b4b80bf
NC
4892 {
4893 switch (sh_type)
4894 {
4895 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4896 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4897 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4898 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4899 default:
4900 result = NULL;
4901 break;
4902 }
4903 }
148b93f2
NC
4904 break;
4905 }
4906
4907 if (result != NULL)
4908 return result;
4909
9fb71ee4 4910 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4911 }
252b5132 4912 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4913 {
dda8d76d 4914 switch (filedata->file_header.e_machine)
685080f2
NC
4915 {
4916 case EM_V800:
4917 case EM_V850:
4918 case EM_CYGNUS_V850:
9fb71ee4 4919 result = get_v850_section_type_name (sh_type);
a9fb83be 4920 break;
685080f2 4921 default:
9fb71ee4 4922 result = NULL;
685080f2
NC
4923 break;
4924 }
4925
9fb71ee4
NC
4926 if (result != NULL)
4927 return result;
4928
4929 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4930 }
252b5132 4931 else
a7dbfd1c
NC
4932 /* This message is probably going to be displayed in a 15
4933 character wide field, so put the hex value first. */
4934 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4935
252b5132
RH
4936 return buff;
4937 }
4938}
4939
79bc120c
NC
4940enum long_option_values
4941{
4942 OPTION_DEBUG_DUMP = 512,
4943 OPTION_DYN_SYMS,
0f03783c 4944 OPTION_LTO_SYMS,
79bc120c
NC
4945 OPTION_DWARF_DEPTH,
4946 OPTION_DWARF_START,
4947 OPTION_DWARF_CHECK,
4948 OPTION_CTF_DUMP,
4949 OPTION_CTF_PARENT,
4950 OPTION_CTF_SYMBOLS,
4951 OPTION_CTF_STRINGS,
4952 OPTION_WITH_SYMBOL_VERSIONS,
4953 OPTION_RECURSE_LIMIT,
4954 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4955 OPTION_NO_DEMANGLING,
4956 OPTION_SYM_BASE
79bc120c 4957};
2979dc34 4958
85b1c36d 4959static struct option options[] =
252b5132 4960{
79bc120c
NC
4961 /* Note - This table is alpha-sorted on the 'val'
4962 field in order to make adding new options easier. */
4963 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4964 {"all", no_argument, 0, 'a'},
79bc120c
NC
4965 {"demangle", optional_argument, 0, 'C'},
4966 {"archive-index", no_argument, 0, 'c'},
4967 {"use-dynamic", no_argument, 0, 'D'},
4968 {"dynamic", no_argument, 0, 'd'},
b34976b6 4969 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4970 {"section-groups", no_argument, 0, 'g'},
4971 {"help", no_argument, 0, 'H'},
4972 {"file-header", no_argument, 0, 'h'},
b34976b6 4973 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4974 {"lint", no_argument, 0, 'L'},
4975 {"enable-checks", no_argument, 0, 'L'},
4976 {"program-headers", no_argument, 0, 'l'},
b34976b6 4977 {"segments", no_argument, 0, 'l'},
595cf52e 4978 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4979 {"notes", no_argument, 0, 'n'},
ca0e11aa 4980 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4981 {"string-dump", required_argument, 0, 'p'},
4982 {"relocated-dump", required_argument, 0, 'R'},
4983 {"relocs", no_argument, 0, 'r'},
4984 {"section-headers", no_argument, 0, 'S'},
4985 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4986 {"symbols", no_argument, 0, 's'},
4987 {"syms", no_argument, 0, 's'},
79bc120c
NC
4988 {"silent-truncation",no_argument, 0, 'T'},
4989 {"section-details", no_argument, 0, 't'},
b3aa80b4 4990 {"unicode", required_argument, NULL, 'U'},
09c11c86 4991 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4992 {"version-info", no_argument, 0, 'V'},
4993 {"version", no_argument, 0, 'v'},
4994 {"wide", no_argument, 0, 'W'},
b34976b6 4995 {"hex-dump", required_argument, 0, 'x'},
0e602686 4996 {"decompress", no_argument, 0, 'z'},
252b5132 4997
79bc120c
NC
4998 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4999 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5000 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5001 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5002 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5003 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5004 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5005 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5006 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5007 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5008#ifdef ENABLE_LIBCTF
d344b407 5009 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5010 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5011 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5012 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5013#endif
047c3dbf 5014 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5015
b34976b6 5016 {0, no_argument, 0, 0}
252b5132
RH
5017};
5018
5019static void
2cf0635d 5020usage (FILE * stream)
252b5132 5021{
92f01d61
JM
5022 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5023 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5024 fprintf (stream, _(" Options are:\n"));
5025 fprintf (stream, _("\
5026 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5027 fprintf (stream, _("\
5028 -h --file-header Display the ELF file header\n"));
5029 fprintf (stream, _("\
5030 -l --program-headers Display the program headers\n"));
5031 fprintf (stream, _("\
5032 --segments An alias for --program-headers\n"));
5033 fprintf (stream, _("\
5034 -S --section-headers Display the sections' header\n"));
5035 fprintf (stream, _("\
5036 --sections An alias for --section-headers\n"));
5037 fprintf (stream, _("\
5038 -g --section-groups Display the section groups\n"));
5039 fprintf (stream, _("\
5040 -t --section-details Display the section details\n"));
5041 fprintf (stream, _("\
5042 -e --headers Equivalent to: -h -l -S\n"));
5043 fprintf (stream, _("\
5044 -s --syms Display the symbol table\n"));
5045 fprintf (stream, _("\
5046 --symbols An alias for --syms\n"));
5047 fprintf (stream, _("\
5048 --dyn-syms Display the dynamic symbol table\n"));
5049 fprintf (stream, _("\
5050 --lto-syms Display LTO symbol tables\n"));
5051 fprintf (stream, _("\
047c3dbf
NL
5052 --sym-base=[0|8|10|16] \n\
5053 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5054 mixed (the default), octal, decimal, hexadecimal.\n"));
5055 fprintf (stream, _("\
0d646226
AM
5056 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5057 display_demangler_styles (stream, _("\
5058 STYLE can be "));
d6249f5f
AM
5059 fprintf (stream, _("\
5060 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5061 fprintf (stream, _("\
5062 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5063 fprintf (stream, _("\
5064 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5065 fprintf (stream, _("\
5066 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5067 Display unicode characters as determined by the current locale\n\
5068 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5069 escape sequences, or treat them as invalid and display as\n\
5070 \"{hex sequences}\"\n"));
d6249f5f
AM
5071 fprintf (stream, _("\
5072 -n --notes Display the core notes (if present)\n"));
5073 fprintf (stream, _("\
5074 -r --relocs Display the relocations (if present)\n"));
5075 fprintf (stream, _("\
5076 -u --unwind Display the unwind info (if present)\n"));
5077 fprintf (stream, _("\
5078 -d --dynamic Display the dynamic section (if present)\n"));
5079 fprintf (stream, _("\
5080 -V --version-info Display the version sections (if present)\n"));
5081 fprintf (stream, _("\
5082 -A --arch-specific Display architecture specific information (if any)\n"));
5083 fprintf (stream, _("\
5084 -c --archive-index Display the symbol/file index in an archive\n"));
5085 fprintf (stream, _("\
5086 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5087 fprintf (stream, _("\
5088 -L --lint|--enable-checks\n\
5089 Display warning messages for possible problems\n"));
5090 fprintf (stream, _("\
09c11c86 5091 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5092 Dump the contents of section <number|name> as bytes\n"));
5093 fprintf (stream, _("\
09c11c86 5094 -p --string-dump=<number|name>\n\
d6249f5f
AM
5095 Dump the contents of section <number|name> as strings\n"));
5096 fprintf (stream, _("\
cf13d699 5097 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5098 Dump the relocated contents of section <number|name>\n"));
5099 fprintf (stream, _("\
5100 -z --decompress Decompress section before dumping it\n"));
5101 fprintf (stream, _("\
5102 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5103 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5104 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5105 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5106 U/=trace_info]\n\
5107 Display the contents of DWARF debug sections\n"));
5108 fprintf (stream, _("\
5109 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5110 debuginfo files\n"));
5111 fprintf (stream, _("\
5112 -P --process-links Display the contents of non-debug sections in separate\n\
5113 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5114#if DEFAULT_FOR_FOLLOW_LINKS
5115 fprintf (stream, _("\
d6249f5f
AM
5116 -wK --debug-dump=follow-links\n\
5117 Follow links to separate debug info files (default)\n"));
5118 fprintf (stream, _("\
5119 -wN --debug-dump=no-follow-links\n\
5120 Do not follow links to separate debug info files\n"));
c46b7066
NC
5121#else
5122 fprintf (stream, _("\
d6249f5f
AM
5123 -wK --debug-dump=follow-links\n\
5124 Follow links to separate debug info files\n"));
5125 fprintf (stream, _("\
5126 -wN --debug-dump=no-follow-links\n\
5127 Do not follow links to separate debug info files\n\
5128 (default)\n"));
bed566bb
NC
5129#endif
5130#if HAVE_LIBDEBUGINFOD
5131 fprintf (stream, _("\
5132 -wD --debug-dump=use-debuginfod\n\
5133 When following links, also query debuginfod servers (default)\n"));
5134 fprintf (stream, _("\
5135 -wE --debug-dump=do-not-use-debuginfod\n\
5136 When following links, do not query debuginfod servers\n"));
c46b7066 5137#endif
fd2f0033 5138 fprintf (stream, _("\
d6249f5f
AM
5139 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5140 fprintf (stream, _("\
5141 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5142#ifdef ENABLE_LIBCTF
7d9813f1 5143 fprintf (stream, _("\
d6249f5f
AM
5144 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5145 fprintf (stream, _("\
80b56fad 5146 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5147 fprintf (stream, _("\
7d9813f1 5148 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5149 Use section <number|name> as the CTF external symtab\n"));
5150 fprintf (stream, _("\
7d9813f1 5151 --ctf-strings=<number|name>\n\
d6249f5f 5152 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5153#endif
7d9813f1 5154
252b5132 5155#ifdef SUPPORT_DISASSEMBLY
92f01d61 5156 fprintf (stream, _("\
09c11c86
NC
5157 -i --instruction-dump=<number|name>\n\
5158 Disassemble the contents of section <number|name>\n"));
252b5132 5159#endif
92f01d61 5160 fprintf (stream, _("\
d6249f5f
AM
5161 -I --histogram Display histogram of bucket list lengths\n"));
5162 fprintf (stream, _("\
5163 -W --wide Allow output width to exceed 80 characters\n"));
5164 fprintf (stream, _("\
5165 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5166 fprintf (stream, _("\
5167 @<file> Read options from <file>\n"));
5168 fprintf (stream, _("\
5169 -H --help Display this information\n"));
5170 fprintf (stream, _("\
8b53311e 5171 -v --version Display the version number of readelf\n"));
1118d252 5172
92f01d61
JM
5173 if (REPORT_BUGS_TO[0] && stream == stdout)
5174 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5175
92f01d61 5176 exit (stream == stdout ? 0 : 1);
252b5132
RH
5177}
5178
18bd398b
NC
5179/* Record the fact that the user wants the contents of section number
5180 SECTION to be displayed using the method(s) encoded as flags bits
5181 in TYPE. Note, TYPE can be zero if we are creating the array for
5182 the first time. */
5183
252b5132 5184static void
6431e409
AM
5185request_dump_bynumber (struct dump_data *dumpdata,
5186 unsigned int section, dump_type type)
252b5132 5187{
6431e409 5188 if (section >= dumpdata->num_dump_sects)
252b5132 5189 {
2cf0635d 5190 dump_type * new_dump_sects;
252b5132 5191
3f5e193b 5192 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5193 sizeof (* new_dump_sects));
252b5132
RH
5194
5195 if (new_dump_sects == NULL)
591a748a 5196 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5197 else
5198 {
6431e409 5199 if (dumpdata->dump_sects)
21b65bac
NC
5200 {
5201 /* Copy current flag settings. */
6431e409
AM
5202 memcpy (new_dump_sects, dumpdata->dump_sects,
5203 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5204
6431e409 5205 free (dumpdata->dump_sects);
21b65bac 5206 }
252b5132 5207
6431e409
AM
5208 dumpdata->dump_sects = new_dump_sects;
5209 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5210 }
5211 }
5212
6431e409
AM
5213 if (dumpdata->dump_sects)
5214 dumpdata->dump_sects[section] |= type;
252b5132
RH
5215}
5216
aef1f6d0
DJ
5217/* Request a dump by section name. */
5218
5219static void
2cf0635d 5220request_dump_byname (const char * section, dump_type type)
aef1f6d0 5221{
2cf0635d 5222 struct dump_list_entry * new_request;
aef1f6d0 5223
3f5e193b
NC
5224 new_request = (struct dump_list_entry *)
5225 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5226 if (!new_request)
591a748a 5227 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5228
5229 new_request->name = strdup (section);
5230 if (!new_request->name)
591a748a 5231 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5232
5233 new_request->type = type;
5234
5235 new_request->next = dump_sects_byname;
5236 dump_sects_byname = new_request;
5237}
5238
cf13d699 5239static inline void
6431e409 5240request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5241{
5242 int section;
5243 char * cp;
5244
015dc7e1 5245 do_dump = true;
cf13d699
NC
5246 section = strtoul (optarg, & cp, 0);
5247
5248 if (! *cp && section >= 0)
6431e409 5249 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5250 else
5251 request_dump_byname (optarg, type);
5252}
5253
252b5132 5254static void
6431e409 5255parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5256{
5257 int c;
5258
5259 if (argc < 2)
92f01d61 5260 usage (stderr);
252b5132
RH
5261
5262 while ((c = getopt_long
b3aa80b4 5263 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5264 {
252b5132
RH
5265 switch (c)
5266 {
5267 case 0:
5268 /* Long options. */
5269 break;
5270 case 'H':
92f01d61 5271 usage (stdout);
252b5132
RH
5272 break;
5273
5274 case 'a':
015dc7e1
AM
5275 do_syms = true;
5276 do_reloc = true;
5277 do_unwind = true;
5278 do_dynamic = true;
5279 do_header = true;
5280 do_sections = true;
5281 do_section_groups = true;
5282 do_segments = true;
5283 do_version = true;
5284 do_histogram = true;
5285 do_arch = true;
5286 do_notes = true;
252b5132 5287 break;
79bc120c 5288
f5842774 5289 case 'g':
015dc7e1 5290 do_section_groups = true;
f5842774 5291 break;
5477e8a0 5292 case 't':
595cf52e 5293 case 'N':
015dc7e1
AM
5294 do_sections = true;
5295 do_section_details = true;
595cf52e 5296 break;
252b5132 5297 case 'e':
015dc7e1
AM
5298 do_header = true;
5299 do_sections = true;
5300 do_segments = true;
252b5132 5301 break;
a952a375 5302 case 'A':
015dc7e1 5303 do_arch = true;
a952a375 5304 break;
252b5132 5305 case 'D':
015dc7e1 5306 do_using_dynamic = true;
252b5132
RH
5307 break;
5308 case 'r':
015dc7e1 5309 do_reloc = true;
252b5132 5310 break;
4d6ed7c8 5311 case 'u':
015dc7e1 5312 do_unwind = true;
4d6ed7c8 5313 break;
252b5132 5314 case 'h':
015dc7e1 5315 do_header = true;
252b5132
RH
5316 break;
5317 case 'l':
015dc7e1 5318 do_segments = true;
252b5132
RH
5319 break;
5320 case 's':
015dc7e1 5321 do_syms = true;
252b5132
RH
5322 break;
5323 case 'S':
015dc7e1 5324 do_sections = true;
252b5132
RH
5325 break;
5326 case 'd':
015dc7e1 5327 do_dynamic = true;
252b5132 5328 break;
a952a375 5329 case 'I':
015dc7e1 5330 do_histogram = true;
a952a375 5331 break;
779fe533 5332 case 'n':
015dc7e1 5333 do_notes = true;
779fe533 5334 break;
4145f1d5 5335 case 'c':
015dc7e1 5336 do_archive_index = true;
4145f1d5 5337 break;
1b513401 5338 case 'L':
015dc7e1 5339 do_checks = true;
1b513401 5340 break;
ca0e11aa 5341 case 'P':
015dc7e1
AM
5342 process_links = true;
5343 do_follow_links = true;
e1dbfc17 5344 dump_any_debugging = true;
ca0e11aa 5345 break;
252b5132 5346 case 'x':
6431e409 5347 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5348 break;
09c11c86 5349 case 'p':
6431e409 5350 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5351 break;
5352 case 'R':
6431e409 5353 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5354 break;
0e602686 5355 case 'z':
015dc7e1 5356 decompress_dumps = true;
0e602686 5357 break;
252b5132 5358 case 'w':
015dc7e1 5359 do_dump = true;
e1dbfc17 5360 dump_any_debugging = true;
0f03783c 5361 if (optarg == NULL)
613ff48b 5362 {
015dc7e1 5363 do_debugging = true;
613ff48b
CC
5364 dwarf_select_sections_all ();
5365 }
252b5132
RH
5366 else
5367 {
015dc7e1 5368 do_debugging = false;
4cb93e3b 5369 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5370 }
5371 break;
2979dc34 5372 case OPTION_DEBUG_DUMP:
015dc7e1 5373 do_dump = true;
e1dbfc17 5374 dump_any_debugging = true;
0f03783c 5375 if (optarg == NULL)
d6249f5f
AM
5376 {
5377 do_debugging = true;
5378 dwarf_select_sections_all ();
5379 }
2979dc34
JJ
5380 else
5381 {
015dc7e1 5382 do_debugging = false;
4cb93e3b 5383 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5384 }
5385 break;
fd2f0033
TT
5386 case OPTION_DWARF_DEPTH:
5387 {
5388 char *cp;
5389
5390 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5391 }
5392 break;
5393 case OPTION_DWARF_START:
5394 {
5395 char *cp;
5396
5397 dwarf_start_die = strtoul (optarg, & cp, 0);
5398 }
5399 break;
4723351a 5400 case OPTION_DWARF_CHECK:
015dc7e1 5401 dwarf_check = true;
4723351a 5402 break;
7d9813f1 5403 case OPTION_CTF_DUMP:
015dc7e1 5404 do_ctf = true;
6431e409 5405 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5406 break;
5407 case OPTION_CTF_SYMBOLS:
df16e041 5408 free (dump_ctf_symtab_name);
7d9813f1
NA
5409 dump_ctf_symtab_name = strdup (optarg);
5410 break;
5411 case OPTION_CTF_STRINGS:
df16e041 5412 free (dump_ctf_strtab_name);
7d9813f1
NA
5413 dump_ctf_strtab_name = strdup (optarg);
5414 break;
5415 case OPTION_CTF_PARENT:
df16e041 5416 free (dump_ctf_parent_name);
7d9813f1
NA
5417 dump_ctf_parent_name = strdup (optarg);
5418 break;
2c610e4b 5419 case OPTION_DYN_SYMS:
015dc7e1 5420 do_dyn_syms = true;
2c610e4b 5421 break;
0f03783c 5422 case OPTION_LTO_SYMS:
015dc7e1 5423 do_lto_syms = true;
0f03783c 5424 break;
252b5132
RH
5425#ifdef SUPPORT_DISASSEMBLY
5426 case 'i':
6431e409 5427 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5428 break;
252b5132
RH
5429#endif
5430 case 'v':
5431 print_version (program_name);
5432 break;
5433 case 'V':
015dc7e1 5434 do_version = true;
252b5132 5435 break;
d974e256 5436 case 'W':
015dc7e1 5437 do_wide = true;
d974e256 5438 break;
0942c7ab 5439 case 'T':
015dc7e1 5440 do_not_show_symbol_truncation = true;
0942c7ab 5441 break;
79bc120c 5442 case 'C':
015dc7e1 5443 do_demangle = true;
79bc120c
NC
5444 if (optarg != NULL)
5445 {
5446 enum demangling_styles style;
5447
5448 style = cplus_demangle_name_to_style (optarg);
5449 if (style == unknown_demangling)
5450 error (_("unknown demangling style `%s'"), optarg);
5451
5452 cplus_demangle_set_style (style);
5453 }
5454 break;
5455 case OPTION_NO_DEMANGLING:
015dc7e1 5456 do_demangle = false;
79bc120c
NC
5457 break;
5458 case OPTION_RECURSE_LIMIT:
5459 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5460 break;
5461 case OPTION_NO_RECURSE_LIMIT:
5462 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5463 break;
5464 case OPTION_WITH_SYMBOL_VERSIONS:
5465 /* Ignored for backward compatibility. */
5466 break;
b9e920ec 5467
b3aa80b4
NC
5468 case 'U':
5469 if (optarg == NULL)
5470 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5471 else if (streq (optarg, "default") || streq (optarg, "d"))
5472 unicode_display = unicode_default;
5473 else if (streq (optarg, "locale") || streq (optarg, "l"))
5474 unicode_display = unicode_locale;
5475 else if (streq (optarg, "escape") || streq (optarg, "e"))
5476 unicode_display = unicode_escape;
5477 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5478 unicode_display = unicode_invalid;
5479 else if (streq (optarg, "hex") || streq (optarg, "x"))
5480 unicode_display = unicode_hex;
5481 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5482 unicode_display = unicode_highlight;
5483 else
5484 error (_("invalid argument to -U/--unicode: %s"), optarg);
5485 break;
5486
047c3dbf
NL
5487 case OPTION_SYM_BASE:
5488 sym_base = 0;
5489 if (optarg != NULL)
5490 {
5491 sym_base = strtoul (optarg, NULL, 0);
5492 switch (sym_base)
5493 {
5494 case 0:
5495 case 8:
5496 case 10:
5497 case 16:
5498 break;
5499
5500 default:
5501 sym_base = 0;
5502 break;
5503 }
5504 }
5505 break;
5506
252b5132 5507 default:
252b5132
RH
5508 /* xgettext:c-format */
5509 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5510 /* Fall through. */
252b5132 5511 case '?':
92f01d61 5512 usage (stderr);
252b5132
RH
5513 }
5514 }
5515
4d6ed7c8 5516 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5517 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5518 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5519 && !do_section_groups && !do_archive_index
0f03783c 5520 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5521 {
5522 if (do_checks)
5523 {
015dc7e1
AM
5524 check_all = true;
5525 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5526 do_segments = do_header = do_dump = do_version = true;
5527 do_histogram = do_debugging = do_arch = do_notes = true;
5528 do_section_groups = do_archive_index = do_dyn_syms = true;
5529 do_lto_syms = true;
1b513401
NC
5530 }
5531 else
5532 usage (stderr);
5533 }
252b5132
RH
5534}
5535
5536static const char *
d3ba0551 5537get_elf_class (unsigned int elf_class)
252b5132 5538{
b34976b6 5539 static char buff[32];
103f02d3 5540
252b5132
RH
5541 switch (elf_class)
5542 {
5543 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5544 case ELFCLASS32: return "ELF32";
5545 case ELFCLASS64: return "ELF64";
ab5e7794 5546 default:
e9e44622 5547 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5548 return buff;
252b5132
RH
5549 }
5550}
5551
5552static const char *
d3ba0551 5553get_data_encoding (unsigned int encoding)
252b5132 5554{
b34976b6 5555 static char buff[32];
103f02d3 5556
252b5132
RH
5557 switch (encoding)
5558 {
5559 case ELFDATANONE: return _("none");
33c63f9d
CM
5560 case ELFDATA2LSB: return _("2's complement, little endian");
5561 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5562 default:
e9e44622 5563 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5564 return buff;
252b5132
RH
5565 }
5566}
5567
dda8d76d 5568/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5569
015dc7e1 5570static bool
dda8d76d 5571process_file_header (Filedata * filedata)
252b5132 5572{
dda8d76d
NC
5573 Elf_Internal_Ehdr * header = & filedata->file_header;
5574
5575 if ( header->e_ident[EI_MAG0] != ELFMAG0
5576 || header->e_ident[EI_MAG1] != ELFMAG1
5577 || header->e_ident[EI_MAG2] != ELFMAG2
5578 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5579 {
5580 error
5581 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5582 return false;
252b5132
RH
5583 }
5584
ca0e11aa
NC
5585 if (! filedata->is_separate)
5586 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5587
252b5132
RH
5588 if (do_header)
5589 {
32ec8896 5590 unsigned i;
252b5132 5591
ca0e11aa
NC
5592 if (filedata->is_separate)
5593 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5594 else
5595 printf (_("ELF Header:\n"));
252b5132 5596 printf (_(" Magic: "));
b34976b6 5597 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5598 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5599 printf ("\n");
5600 printf (_(" Class: %s\n"),
dda8d76d 5601 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5602 printf (_(" Data: %s\n"),
dda8d76d 5603 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5604 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5605 header->e_ident[EI_VERSION],
5606 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5607 ? _(" (current)")
dda8d76d 5608 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5609 ? _(" <unknown>")
789be9f7 5610 : "")));
252b5132 5611 printf (_(" OS/ABI: %s\n"),
dda8d76d 5612 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5613 printf (_(" ABI Version: %d\n"),
dda8d76d 5614 header->e_ident[EI_ABIVERSION]);
252b5132 5615 printf (_(" Type: %s\n"),
93df3340 5616 get_file_type (filedata));
252b5132 5617 printf (_(" Machine: %s\n"),
dda8d76d 5618 get_machine_name (header->e_machine));
252b5132 5619 printf (_(" Version: 0x%lx\n"),
e8a64888 5620 header->e_version);
76da6bbe 5621
f7a99963 5622 printf (_(" Entry point address: "));
e8a64888 5623 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5624 printf (_("\n Start of program headers: "));
e8a64888 5625 print_vma (header->e_phoff, DEC);
f7a99963 5626 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5627 print_vma (header->e_shoff, DEC);
f7a99963 5628 printf (_(" (bytes into file)\n"));
76da6bbe 5629
252b5132 5630 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5631 header->e_flags,
dda8d76d 5632 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5633 printf (_(" Size of this header: %u (bytes)\n"),
5634 header->e_ehsize);
5635 printf (_(" Size of program headers: %u (bytes)\n"),
5636 header->e_phentsize);
5637 printf (_(" Number of program headers: %u"),
5638 header->e_phnum);
dda8d76d
NC
5639 if (filedata->section_headers != NULL
5640 && header->e_phnum == PN_XNUM
5641 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5642 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5643 putc ('\n', stdout);
e8a64888
AM
5644 printf (_(" Size of section headers: %u (bytes)\n"),
5645 header->e_shentsize);
5646 printf (_(" Number of section headers: %u"),
5647 header->e_shnum);
dda8d76d 5648 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5649 {
5650 header->e_shnum = filedata->section_headers[0].sh_size;
5651 printf (" (%u)", header->e_shnum);
5652 }
560f3c1c 5653 putc ('\n', stdout);
e8a64888
AM
5654 printf (_(" Section header string table index: %u"),
5655 header->e_shstrndx);
dda8d76d
NC
5656 if (filedata->section_headers != NULL
5657 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5658 {
5659 header->e_shstrndx = filedata->section_headers[0].sh_link;
5660 printf (" (%u)", header->e_shstrndx);
5661 }
5662 if (header->e_shstrndx != SHN_UNDEF
5663 && header->e_shstrndx >= header->e_shnum)
5664 {
5665 header->e_shstrndx = SHN_UNDEF;
5666 printf (_(" <corrupt: out of range>"));
5667 }
560f3c1c
AM
5668 putc ('\n', stdout);
5669 }
5670
dda8d76d 5671 if (filedata->section_headers != NULL)
560f3c1c 5672 {
dda8d76d
NC
5673 if (header->e_phnum == PN_XNUM
5674 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5675 {
5676 /* Throw away any cached read of PN_XNUM headers. */
5677 free (filedata->program_headers);
5678 filedata->program_headers = NULL;
5679 header->e_phnum = filedata->section_headers[0].sh_info;
5680 }
dda8d76d
NC
5681 if (header->e_shnum == SHN_UNDEF)
5682 header->e_shnum = filedata->section_headers[0].sh_size;
5683 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5684 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5685 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5686 header->e_shstrndx = SHN_UNDEF;
252b5132 5687 }
103f02d3 5688
015dc7e1 5689 return true;
9ea033b2
NC
5690}
5691
dda8d76d
NC
5692/* Read in the program headers from FILEDATA and store them in PHEADERS.
5693 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5694
015dc7e1 5695static bool
dda8d76d 5696get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5697{
2cf0635d
NC
5698 Elf32_External_Phdr * phdrs;
5699 Elf32_External_Phdr * external;
5700 Elf_Internal_Phdr * internal;
b34976b6 5701 unsigned int i;
dda8d76d
NC
5702 unsigned int size = filedata->file_header.e_phentsize;
5703 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5704
5705 /* PR binutils/17531: Cope with unexpected section header sizes. */
5706 if (size == 0 || num == 0)
015dc7e1 5707 return false;
e0a31db1
NC
5708 if (size < sizeof * phdrs)
5709 {
5710 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5711 return false;
e0a31db1
NC
5712 }
5713 if (size > sizeof * phdrs)
5714 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5715
dda8d76d 5716 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5717 size, num, _("program headers"));
5718 if (phdrs == NULL)
015dc7e1 5719 return false;
9ea033b2 5720
91d6fa6a 5721 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5722 i < filedata->file_header.e_phnum;
b34976b6 5723 i++, internal++, external++)
252b5132 5724 {
9ea033b2
NC
5725 internal->p_type = BYTE_GET (external->p_type);
5726 internal->p_offset = BYTE_GET (external->p_offset);
5727 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5728 internal->p_paddr = BYTE_GET (external->p_paddr);
5729 internal->p_filesz = BYTE_GET (external->p_filesz);
5730 internal->p_memsz = BYTE_GET (external->p_memsz);
5731 internal->p_flags = BYTE_GET (external->p_flags);
5732 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5733 }
5734
9ea033b2 5735 free (phdrs);
015dc7e1 5736 return true;
252b5132
RH
5737}
5738
dda8d76d
NC
5739/* Read in the program headers from FILEDATA and store them in PHEADERS.
5740 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5741
015dc7e1 5742static bool
dda8d76d 5743get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5744{
2cf0635d
NC
5745 Elf64_External_Phdr * phdrs;
5746 Elf64_External_Phdr * external;
5747 Elf_Internal_Phdr * internal;
b34976b6 5748 unsigned int i;
dda8d76d
NC
5749 unsigned int size = filedata->file_header.e_phentsize;
5750 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5751
5752 /* PR binutils/17531: Cope with unexpected section header sizes. */
5753 if (size == 0 || num == 0)
015dc7e1 5754 return false;
e0a31db1
NC
5755 if (size < sizeof * phdrs)
5756 {
5757 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5758 return false;
e0a31db1
NC
5759 }
5760 if (size > sizeof * phdrs)
5761 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5762
dda8d76d 5763 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5764 size, num, _("program headers"));
a6e9f9df 5765 if (!phdrs)
015dc7e1 5766 return false;
9ea033b2 5767
91d6fa6a 5768 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5769 i < filedata->file_header.e_phnum;
b34976b6 5770 i++, internal++, external++)
9ea033b2
NC
5771 {
5772 internal->p_type = BYTE_GET (external->p_type);
5773 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5774 internal->p_offset = BYTE_GET (external->p_offset);
5775 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5776 internal->p_paddr = BYTE_GET (external->p_paddr);
5777 internal->p_filesz = BYTE_GET (external->p_filesz);
5778 internal->p_memsz = BYTE_GET (external->p_memsz);
5779 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5780 }
5781
5782 free (phdrs);
015dc7e1 5783 return true;
9ea033b2 5784}
252b5132 5785
32ec8896 5786/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5787
015dc7e1 5788static bool
dda8d76d 5789get_program_headers (Filedata * filedata)
d93f0186 5790{
2cf0635d 5791 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5792
5793 /* Check cache of prior read. */
dda8d76d 5794 if (filedata->program_headers != NULL)
015dc7e1 5795 return true;
d93f0186 5796
82156ab7
NC
5797 /* Be kind to memory checkers by looking for
5798 e_phnum values which we know must be invalid. */
dda8d76d 5799 if (filedata->file_header.e_phnum
82156ab7 5800 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5801 >= filedata->file_size)
82156ab7
NC
5802 {
5803 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5804 filedata->file_header.e_phnum);
015dc7e1 5805 return false;
82156ab7 5806 }
d93f0186 5807
dda8d76d 5808 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5809 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5810 if (phdrs == NULL)
5811 {
8b73c356 5812 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5813 filedata->file_header.e_phnum);
015dc7e1 5814 return false;
d93f0186
NC
5815 }
5816
5817 if (is_32bit_elf
dda8d76d
NC
5818 ? get_32bit_program_headers (filedata, phdrs)
5819 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5820 {
dda8d76d 5821 filedata->program_headers = phdrs;
015dc7e1 5822 return true;
d93f0186
NC
5823 }
5824
5825 free (phdrs);
015dc7e1 5826 return false;
d93f0186
NC
5827}
5828
93df3340 5829/* Print program header info and locate dynamic section. */
2f62977e 5830
93df3340 5831static void
dda8d76d 5832process_program_headers (Filedata * filedata)
252b5132 5833{
2cf0635d 5834 Elf_Internal_Phdr * segment;
b34976b6 5835 unsigned int i;
1a9ccd70 5836 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5837
dda8d76d 5838 if (filedata->file_header.e_phnum == 0)
252b5132 5839 {
82f2dbf7 5840 /* PR binutils/12467. */
dda8d76d 5841 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5842 warn (_("possibly corrupt ELF header - it has a non-zero program"
5843 " header offset, but no program headers\n"));
82f2dbf7 5844 else if (do_segments)
ca0e11aa
NC
5845 {
5846 if (filedata->is_separate)
5847 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5848 filedata->file_name);
5849 else
5850 printf (_("\nThere are no program headers in this file.\n"));
5851 }
93df3340 5852 goto no_headers;
252b5132
RH
5853 }
5854
5855 if (do_segments && !do_header)
5856 {
ca0e11aa
NC
5857 if (filedata->is_separate)
5858 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5859 filedata->file_name, get_file_type (filedata));
ca0e11aa 5860 else
93df3340 5861 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5862 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5863 printf (ngettext ("There is %d program header, starting at offset %s\n",
5864 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5865 filedata->file_header.e_phnum),
5866 filedata->file_header.e_phnum,
5867 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5868 }
5869
dda8d76d 5870 if (! get_program_headers (filedata))
93df3340 5871 goto no_headers;
103f02d3 5872
252b5132
RH
5873 if (do_segments)
5874 {
dda8d76d 5875 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5876 printf (_("\nProgram Headers:\n"));
5877 else
5878 printf (_("\nProgram Headers:\n"));
76da6bbe 5879
f7a99963
NC
5880 if (is_32bit_elf)
5881 printf
5882 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5883 else if (do_wide)
5884 printf
5885 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5886 else
5887 {
5888 printf
5889 (_(" Type Offset VirtAddr PhysAddr\n"));
5890 printf
5891 (_(" FileSiz MemSiz Flags Align\n"));
5892 }
252b5132
RH
5893 }
5894
93df3340
AM
5895 unsigned long dynamic_addr = 0;
5896 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5897 for (i = 0, segment = filedata->program_headers;
5898 i < filedata->file_header.e_phnum;
b34976b6 5899 i++, segment++)
252b5132
RH
5900 {
5901 if (do_segments)
5902 {
dda8d76d 5903 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5904
5905 if (is_32bit_elf)
5906 {
5907 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5908 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5909 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5910 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5911 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5912 printf ("%c%c%c ",
5913 (segment->p_flags & PF_R ? 'R' : ' '),
5914 (segment->p_flags & PF_W ? 'W' : ' '),
5915 (segment->p_flags & PF_X ? 'E' : ' '));
5916 printf ("%#lx", (unsigned long) segment->p_align);
5917 }
d974e256
JJ
5918 else if (do_wide)
5919 {
5920 if ((unsigned long) segment->p_offset == segment->p_offset)
5921 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5922 else
5923 {
5924 print_vma (segment->p_offset, FULL_HEX);
5925 putchar (' ');
5926 }
5927
5928 print_vma (segment->p_vaddr, FULL_HEX);
5929 putchar (' ');
5930 print_vma (segment->p_paddr, FULL_HEX);
5931 putchar (' ');
5932
5933 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5934 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5935 else
5936 {
5937 print_vma (segment->p_filesz, FULL_HEX);
5938 putchar (' ');
5939 }
5940
5941 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5942 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5943 else
5944 {
f48e6c45 5945 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5946 }
5947
5948 printf (" %c%c%c ",
5949 (segment->p_flags & PF_R ? 'R' : ' '),
5950 (segment->p_flags & PF_W ? 'W' : ' '),
5951 (segment->p_flags & PF_X ? 'E' : ' '));
5952
5953 if ((unsigned long) segment->p_align == segment->p_align)
5954 printf ("%#lx", (unsigned long) segment->p_align);
5955 else
5956 {
5957 print_vma (segment->p_align, PREFIX_HEX);
5958 }
5959 }
f7a99963
NC
5960 else
5961 {
5962 print_vma (segment->p_offset, FULL_HEX);
5963 putchar (' ');
5964 print_vma (segment->p_vaddr, FULL_HEX);
5965 putchar (' ');
5966 print_vma (segment->p_paddr, FULL_HEX);
5967 printf ("\n ");
5968 print_vma (segment->p_filesz, FULL_HEX);
5969 putchar (' ');
5970 print_vma (segment->p_memsz, FULL_HEX);
5971 printf (" %c%c%c ",
5972 (segment->p_flags & PF_R ? 'R' : ' '),
5973 (segment->p_flags & PF_W ? 'W' : ' '),
5974 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5975 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5976 }
252b5132 5977
1a9ccd70
NC
5978 putc ('\n', stdout);
5979 }
f54498b4 5980
252b5132
RH
5981 switch (segment->p_type)
5982 {
1a9ccd70 5983 case PT_LOAD:
502d895c
NC
5984#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5985 required by the ELF standard, several programs, including the Linux
5986 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5987 if (previous_load
5988 && previous_load->p_vaddr > segment->p_vaddr)
5989 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5990#endif
1a9ccd70
NC
5991 if (segment->p_memsz < segment->p_filesz)
5992 error (_("the segment's file size is larger than its memory size\n"));
5993 previous_load = segment;
5994 break;
5995
5996 case PT_PHDR:
5997 /* PR 20815 - Verify that the program header is loaded into memory. */
5998 if (i > 0 && previous_load != NULL)
5999 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6000 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6001 {
6002 unsigned int j;
6003
dda8d76d 6004 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6005 {
6006 Elf_Internal_Phdr *load = filedata->program_headers + j;
6007 if (load->p_type == PT_LOAD
6008 && load->p_offset <= segment->p_offset
6009 && (load->p_offset + load->p_filesz
6010 >= segment->p_offset + segment->p_filesz)
6011 && load->p_vaddr <= segment->p_vaddr
6012 && (load->p_vaddr + load->p_filesz
6013 >= segment->p_vaddr + segment->p_filesz))
6014 break;
6015 }
dda8d76d 6016 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6017 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6018 }
6019 break;
6020
252b5132 6021 case PT_DYNAMIC:
93df3340 6022 if (dynamic_addr)
252b5132
RH
6023 error (_("more than one dynamic segment\n"));
6024
20737c13
AM
6025 /* By default, assume that the .dynamic section is the first
6026 section in the DYNAMIC segment. */
93df3340
AM
6027 dynamic_addr = segment->p_offset;
6028 dynamic_size = segment->p_filesz;
20737c13 6029
b2d38a17
NC
6030 /* Try to locate the .dynamic section. If there is
6031 a section header table, we can easily locate it. */
dda8d76d 6032 if (filedata->section_headers != NULL)
b2d38a17 6033 {
2cf0635d 6034 Elf_Internal_Shdr * sec;
b2d38a17 6035
dda8d76d 6036 sec = find_section (filedata, ".dynamic");
89fac5e3 6037 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6038 {
93df3340
AM
6039 /* A corresponding .dynamic section is expected, but on
6040 IA-64/OpenVMS it is OK for it to be missing. */
6041 if (!is_ia64_vms (filedata))
6042 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6043 break;
6044 }
6045
42bb2e33 6046 if (sec->sh_type == SHT_NOBITS)
20737c13 6047 {
93df3340
AM
6048 dynamic_addr = 0;
6049 dynamic_size = 0;
20737c13
AM
6050 break;
6051 }
42bb2e33 6052
93df3340
AM
6053 dynamic_addr = sec->sh_offset;
6054 dynamic_size = sec->sh_size;
b2d38a17 6055
8ac10c5b
L
6056 /* The PT_DYNAMIC segment, which is used by the run-time
6057 loader, should exactly match the .dynamic section. */
6058 if (do_checks
93df3340
AM
6059 && (dynamic_addr != segment->p_offset
6060 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6061 warn (_("\
6062the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6063 }
39e224f6
MW
6064
6065 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6066 segment. Check this after matching against the section headers
6067 so we don't warn on debuginfo file (which have NOBITS .dynamic
6068 sections). */
93df3340
AM
6069 if (dynamic_addr > filedata->file_size
6070 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6071 {
6072 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6073 dynamic_addr = 0;
6074 dynamic_size = 0;
39e224f6 6075 }
252b5132
RH
6076 break;
6077
6078 case PT_INTERP:
13acb58d
AM
6079 if (segment->p_offset >= filedata->file_size
6080 || segment->p_filesz > filedata->file_size - segment->p_offset
6081 || segment->p_filesz - 1 >= (size_t) -2
6082 || fseek (filedata->handle,
6083 filedata->archive_file_offset + (long) segment->p_offset,
6084 SEEK_SET))
252b5132
RH
6085 error (_("Unable to find program interpreter name\n"));
6086 else
6087 {
13acb58d
AM
6088 size_t len = segment->p_filesz;
6089 free (filedata->program_interpreter);
6090 filedata->program_interpreter = xmalloc (len + 1);
6091 len = fread (filedata->program_interpreter, 1, len,
6092 filedata->handle);
6093 filedata->program_interpreter[len] = 0;
252b5132
RH
6094
6095 if (do_segments)
f54498b4 6096 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6097 filedata->program_interpreter);
252b5132
RH
6098 }
6099 break;
6100 }
252b5132
RH
6101 }
6102
dda8d76d
NC
6103 if (do_segments
6104 && filedata->section_headers != NULL
6105 && filedata->string_table != NULL)
252b5132
RH
6106 {
6107 printf (_("\n Section to Segment mapping:\n"));
6108 printf (_(" Segment Sections...\n"));
6109
dda8d76d 6110 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6111 {
9ad5cbcf 6112 unsigned int j;
2cf0635d 6113 Elf_Internal_Shdr * section;
252b5132 6114
dda8d76d
NC
6115 segment = filedata->program_headers + i;
6116 section = filedata->section_headers + 1;
252b5132
RH
6117
6118 printf (" %2.2d ", i);
6119
dda8d76d 6120 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6121 {
f4638467
AM
6122 if (!ELF_TBSS_SPECIAL (section, segment)
6123 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6124 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6125 }
6126
6127 putc ('\n',stdout);
6128 }
6129 }
6130
93df3340
AM
6131 filedata->dynamic_addr = dynamic_addr;
6132 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6133 return;
6134
6135 no_headers:
6136 filedata->dynamic_addr = 0;
6137 filedata->dynamic_size = 1;
252b5132
RH
6138}
6139
6140
d93f0186
NC
6141/* Find the file offset corresponding to VMA by using the program headers. */
6142
6143static long
dda8d76d 6144offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6145{
2cf0635d 6146 Elf_Internal_Phdr * seg;
d93f0186 6147
dda8d76d 6148 if (! get_program_headers (filedata))
d93f0186
NC
6149 {
6150 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6151 return (long) vma;
6152 }
6153
dda8d76d
NC
6154 for (seg = filedata->program_headers;
6155 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6156 ++seg)
6157 {
6158 if (seg->p_type != PT_LOAD)
6159 continue;
6160
6161 if (vma >= (seg->p_vaddr & -seg->p_align)
6162 && vma + size <= seg->p_vaddr + seg->p_filesz)
6163 return vma - seg->p_vaddr + seg->p_offset;
6164 }
6165
6166 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6167 (unsigned long) vma);
d93f0186
NC
6168 return (long) vma;
6169}
6170
6171
dda8d76d
NC
6172/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6173 If PROBE is true, this is just a probe and we do not generate any error
6174 messages if the load fails. */
049b0c3a 6175
015dc7e1
AM
6176static bool
6177get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6178{
2cf0635d
NC
6179 Elf32_External_Shdr * shdrs;
6180 Elf_Internal_Shdr * internal;
dda8d76d
NC
6181 unsigned int i;
6182 unsigned int size = filedata->file_header.e_shentsize;
6183 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6184
6185 /* PR binutils/17531: Cope with unexpected section header sizes. */
6186 if (size == 0 || num == 0)
015dc7e1 6187 return false;
049b0c3a
NC
6188 if (size < sizeof * shdrs)
6189 {
6190 if (! probe)
6191 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6192 return false;
049b0c3a
NC
6193 }
6194 if (!probe && size > sizeof * shdrs)
6195 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6196
dda8d76d 6197 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6198 size, num,
6199 probe ? NULL : _("section headers"));
6200 if (shdrs == NULL)
015dc7e1 6201 return false;
252b5132 6202
dda8d76d
NC
6203 filedata->section_headers = (Elf_Internal_Shdr *)
6204 cmalloc (num, sizeof (Elf_Internal_Shdr));
6205 if (filedata->section_headers == NULL)
252b5132 6206 {
049b0c3a 6207 if (!probe)
8b73c356 6208 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6209 free (shdrs);
015dc7e1 6210 return false;
252b5132
RH
6211 }
6212
dda8d76d 6213 for (i = 0, internal = filedata->section_headers;
560f3c1c 6214 i < num;
b34976b6 6215 i++, internal++)
252b5132
RH
6216 {
6217 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6218 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6219 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6220 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6221 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6222 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6223 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6224 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6225 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6226 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6227 if (!probe && internal->sh_link > num)
6228 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6229 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6230 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6231 }
6232
6233 free (shdrs);
015dc7e1 6234 return true;
252b5132
RH
6235}
6236
dda8d76d
NC
6237/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6238
015dc7e1
AM
6239static bool
6240get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6241{
dda8d76d
NC
6242 Elf64_External_Shdr * shdrs;
6243 Elf_Internal_Shdr * internal;
6244 unsigned int i;
6245 unsigned int size = filedata->file_header.e_shentsize;
6246 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6247
6248 /* PR binutils/17531: Cope with unexpected section header sizes. */
6249 if (size == 0 || num == 0)
015dc7e1 6250 return false;
dda8d76d 6251
049b0c3a
NC
6252 if (size < sizeof * shdrs)
6253 {
6254 if (! probe)
6255 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6256 return false;
049b0c3a 6257 }
dda8d76d 6258
049b0c3a
NC
6259 if (! probe && size > sizeof * shdrs)
6260 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6261
dda8d76d
NC
6262 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6263 filedata->file_header.e_shoff,
049b0c3a
NC
6264 size, num,
6265 probe ? NULL : _("section headers"));
6266 if (shdrs == NULL)
015dc7e1 6267 return false;
9ea033b2 6268
dda8d76d
NC
6269 filedata->section_headers = (Elf_Internal_Shdr *)
6270 cmalloc (num, sizeof (Elf_Internal_Shdr));
6271 if (filedata->section_headers == NULL)
9ea033b2 6272 {
049b0c3a 6273 if (! probe)
8b73c356 6274 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6275 free (shdrs);
015dc7e1 6276 return false;
9ea033b2
NC
6277 }
6278
dda8d76d 6279 for (i = 0, internal = filedata->section_headers;
560f3c1c 6280 i < num;
b34976b6 6281 i++, internal++)
9ea033b2
NC
6282 {
6283 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6284 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6285 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6286 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6287 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6288 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6289 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6290 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6291 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6292 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6293 if (!probe && internal->sh_link > num)
6294 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6295 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6296 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6297 }
6298
6299 free (shdrs);
015dc7e1 6300 return true;
9ea033b2
NC
6301}
6302
4de91c10
AM
6303static bool
6304get_section_headers (Filedata *filedata, bool probe)
6305{
6306 if (filedata->section_headers != NULL)
6307 return true;
6308
4de91c10
AM
6309 if (is_32bit_elf)
6310 return get_32bit_section_headers (filedata, probe);
6311 else
6312 return get_64bit_section_headers (filedata, probe);
6313}
6314
252b5132 6315static Elf_Internal_Sym *
dda8d76d
NC
6316get_32bit_elf_symbols (Filedata * filedata,
6317 Elf_Internal_Shdr * section,
6318 unsigned long * num_syms_return)
252b5132 6319{
ba5cdace 6320 unsigned long number = 0;
dd24e3da 6321 Elf32_External_Sym * esyms = NULL;
ba5cdace 6322 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6323 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6324 Elf_Internal_Sym * psym;
b34976b6 6325 unsigned int j;
e3d39609 6326 elf_section_list * entry;
252b5132 6327
c9c1d674
EG
6328 if (section->sh_size == 0)
6329 {
6330 if (num_syms_return != NULL)
6331 * num_syms_return = 0;
6332 return NULL;
6333 }
6334
dd24e3da 6335 /* Run some sanity checks first. */
c9c1d674 6336 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6337 {
c9c1d674 6338 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6339 printable_section_name (filedata, section),
6340 (unsigned long) section->sh_entsize);
ba5cdace 6341 goto exit_point;
dd24e3da
NC
6342 }
6343
dda8d76d 6344 if (section->sh_size > filedata->file_size)
f54498b4
NC
6345 {
6346 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6347 printable_section_name (filedata, section),
6348 (unsigned long) section->sh_size);
f54498b4
NC
6349 goto exit_point;
6350 }
6351
dd24e3da
NC
6352 number = section->sh_size / section->sh_entsize;
6353
6354 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6355 {
c9c1d674 6356 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6357 (unsigned long) section->sh_size,
dda8d76d 6358 printable_section_name (filedata, section),
8066deb1 6359 (unsigned long) section->sh_entsize);
ba5cdace 6360 goto exit_point;
dd24e3da
NC
6361 }
6362
dda8d76d 6363 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6364 section->sh_size, _("symbols"));
dd24e3da 6365 if (esyms == NULL)
ba5cdace 6366 goto exit_point;
252b5132 6367
e3d39609 6368 shndx = NULL;
978c4450 6369 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6370 {
6371 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6372 continue;
6373
6374 if (shndx != NULL)
6375 {
6376 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6377 free (shndx);
6378 }
6379
6380 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6381 entry->hdr->sh_offset,
6382 1, entry->hdr->sh_size,
6383 _("symbol table section indices"));
6384 if (shndx == NULL)
6385 goto exit_point;
6386
6387 /* PR17531: file: heap-buffer-overflow */
6388 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6389 {
6390 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6391 printable_section_name (filedata, entry->hdr),
6392 (unsigned long) entry->hdr->sh_size,
6393 (unsigned long) section->sh_size);
6394 goto exit_point;
c9c1d674 6395 }
e3d39609 6396 }
9ad5cbcf 6397
3f5e193b 6398 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6399
6400 if (isyms == NULL)
6401 {
8b73c356
NC
6402 error (_("Out of memory reading %lu symbols\n"),
6403 (unsigned long) number);
dd24e3da 6404 goto exit_point;
252b5132
RH
6405 }
6406
dd24e3da 6407 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6408 {
6409 psym->st_name = BYTE_GET (esyms[j].st_name);
6410 psym->st_value = BYTE_GET (esyms[j].st_value);
6411 psym->st_size = BYTE_GET (esyms[j].st_size);
6412 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6413 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6414 psym->st_shndx
6415 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6416 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6417 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6418 psym->st_info = BYTE_GET (esyms[j].st_info);
6419 psym->st_other = BYTE_GET (esyms[j].st_other);
6420 }
6421
dd24e3da 6422 exit_point:
e3d39609
NC
6423 free (shndx);
6424 free (esyms);
252b5132 6425
ba5cdace
NC
6426 if (num_syms_return != NULL)
6427 * num_syms_return = isyms == NULL ? 0 : number;
6428
252b5132
RH
6429 return isyms;
6430}
6431
9ea033b2 6432static Elf_Internal_Sym *
dda8d76d
NC
6433get_64bit_elf_symbols (Filedata * filedata,
6434 Elf_Internal_Shdr * section,
6435 unsigned long * num_syms_return)
9ea033b2 6436{
ba5cdace
NC
6437 unsigned long number = 0;
6438 Elf64_External_Sym * esyms = NULL;
6439 Elf_External_Sym_Shndx * shndx = NULL;
6440 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6441 Elf_Internal_Sym * psym;
b34976b6 6442 unsigned int j;
e3d39609 6443 elf_section_list * entry;
9ea033b2 6444
c9c1d674
EG
6445 if (section->sh_size == 0)
6446 {
6447 if (num_syms_return != NULL)
6448 * num_syms_return = 0;
6449 return NULL;
6450 }
6451
dd24e3da 6452 /* Run some sanity checks first. */
c9c1d674 6453 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6454 {
c9c1d674 6455 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6456 printable_section_name (filedata, section),
8066deb1 6457 (unsigned long) section->sh_entsize);
ba5cdace 6458 goto exit_point;
dd24e3da
NC
6459 }
6460
dda8d76d 6461 if (section->sh_size > filedata->file_size)
f54498b4
NC
6462 {
6463 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6464 printable_section_name (filedata, section),
8066deb1 6465 (unsigned long) section->sh_size);
f54498b4
NC
6466 goto exit_point;
6467 }
6468
dd24e3da
NC
6469 number = section->sh_size / section->sh_entsize;
6470
6471 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6472 {
c9c1d674 6473 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6474 (unsigned long) section->sh_size,
dda8d76d 6475 printable_section_name (filedata, section),
8066deb1 6476 (unsigned long) section->sh_entsize);
ba5cdace 6477 goto exit_point;
dd24e3da
NC
6478 }
6479
dda8d76d 6480 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6481 section->sh_size, _("symbols"));
a6e9f9df 6482 if (!esyms)
ba5cdace 6483 goto exit_point;
9ea033b2 6484
e3d39609 6485 shndx = NULL;
978c4450 6486 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6487 {
6488 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6489 continue;
6490
6491 if (shndx != NULL)
6492 {
6493 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6494 free (shndx);
c9c1d674 6495 }
e3d39609
NC
6496
6497 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6498 entry->hdr->sh_offset,
6499 1, entry->hdr->sh_size,
6500 _("symbol table section indices"));
6501 if (shndx == NULL)
6502 goto exit_point;
6503
6504 /* PR17531: file: heap-buffer-overflow */
6505 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6506 {
6507 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6508 printable_section_name (filedata, entry->hdr),
6509 (unsigned long) entry->hdr->sh_size,
6510 (unsigned long) section->sh_size);
6511 goto exit_point;
6512 }
6513 }
9ad5cbcf 6514
3f5e193b 6515 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6516
6517 if (isyms == NULL)
6518 {
8b73c356
NC
6519 error (_("Out of memory reading %lu symbols\n"),
6520 (unsigned long) number);
ba5cdace 6521 goto exit_point;
9ea033b2
NC
6522 }
6523
ba5cdace 6524 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6525 {
6526 psym->st_name = BYTE_GET (esyms[j].st_name);
6527 psym->st_info = BYTE_GET (esyms[j].st_info);
6528 psym->st_other = BYTE_GET (esyms[j].st_other);
6529 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6530
4fbb74a6 6531 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6532 psym->st_shndx
6533 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6534 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6535 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6536
66543521
AM
6537 psym->st_value = BYTE_GET (esyms[j].st_value);
6538 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6539 }
6540
ba5cdace 6541 exit_point:
e3d39609
NC
6542 free (shndx);
6543 free (esyms);
ba5cdace
NC
6544
6545 if (num_syms_return != NULL)
6546 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6547
6548 return isyms;
6549}
6550
4de91c10
AM
6551static Elf_Internal_Sym *
6552get_elf_symbols (Filedata *filedata,
6553 Elf_Internal_Shdr *section,
6554 unsigned long *num_syms_return)
6555{
6556 if (is_32bit_elf)
6557 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6558 else
6559 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6560}
6561
d1133906 6562static const char *
dda8d76d 6563get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6564{
5477e8a0 6565 static char buff[1024];
2cf0635d 6566 char * p = buff;
32ec8896
NC
6567 unsigned int field_size = is_32bit_elf ? 8 : 16;
6568 signed int sindex;
6569 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6570 bfd_vma os_flags = 0;
6571 bfd_vma proc_flags = 0;
6572 bfd_vma unknown_flags = 0;
148b93f2 6573 static const struct
5477e8a0 6574 {
2cf0635d 6575 const char * str;
32ec8896 6576 unsigned int len;
5477e8a0
L
6577 }
6578 flags [] =
6579 {
cfcac11d
NC
6580 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6581 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6582 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6583 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6584 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6585 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6586 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6587 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6588 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6589 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6590 /* IA-64 specific. */
6591 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6592 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6593 /* IA-64 OpenVMS specific. */
6594 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6595 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6596 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6597 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6598 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6599 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6600 /* Generic. */
cfcac11d 6601 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6602 /* SPARC specific. */
77115a4a 6603 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6604 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6605 /* ARM specific. */
6606 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6607 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6608 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6609 /* GNU specific. */
6610 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6611 /* VLE specific. */
6612 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6613 /* GNU specific. */
6614 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6615 };
6616
6617 if (do_section_details)
6618 {
8d5ff12c
L
6619 sprintf (buff, "[%*.*lx]: ",
6620 field_size, field_size, (unsigned long) sh_flags);
6621 p += field_size + 4;
5477e8a0 6622 }
76da6bbe 6623
d1133906
NC
6624 while (sh_flags)
6625 {
6626 bfd_vma flag;
6627
6628 flag = sh_flags & - sh_flags;
6629 sh_flags &= ~ flag;
76da6bbe 6630
5477e8a0 6631 if (do_section_details)
d1133906 6632 {
5477e8a0
L
6633 switch (flag)
6634 {
91d6fa6a
NC
6635 case SHF_WRITE: sindex = 0; break;
6636 case SHF_ALLOC: sindex = 1; break;
6637 case SHF_EXECINSTR: sindex = 2; break;
6638 case SHF_MERGE: sindex = 3; break;
6639 case SHF_STRINGS: sindex = 4; break;
6640 case SHF_INFO_LINK: sindex = 5; break;
6641 case SHF_LINK_ORDER: sindex = 6; break;
6642 case SHF_OS_NONCONFORMING: sindex = 7; break;
6643 case SHF_GROUP: sindex = 8; break;
6644 case SHF_TLS: sindex = 9; break;
18ae9cc1 6645 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6646 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6647
5477e8a0 6648 default:
91d6fa6a 6649 sindex = -1;
dda8d76d 6650 switch (filedata->file_header.e_machine)
148b93f2 6651 {
cfcac11d 6652 case EM_IA_64:
148b93f2 6653 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6654 sindex = 10;
148b93f2 6655 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6656 sindex = 11;
148b93f2 6657#ifdef BFD64
dda8d76d 6658 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6659 switch (flag)
6660 {
91d6fa6a
NC
6661 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6662 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6663 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6664 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6665 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6666 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6667 default: break;
6668 }
6669#endif
cfcac11d
NC
6670 break;
6671
caa83f8b 6672 case EM_386:
22abe556 6673 case EM_IAMCU:
caa83f8b 6674 case EM_X86_64:
7f502d6c 6675 case EM_L1OM:
7a9068fe 6676 case EM_K1OM:
cfcac11d
NC
6677 case EM_OLD_SPARCV9:
6678 case EM_SPARC32PLUS:
6679 case EM_SPARCV9:
6680 case EM_SPARC:
18ae9cc1 6681 if (flag == SHF_ORDERED)
91d6fa6a 6682 sindex = 19;
cfcac11d 6683 break;
ac4c9b04
MG
6684
6685 case EM_ARM:
6686 switch (flag)
6687 {
6688 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6689 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6690 case SHF_COMDEF: sindex = 23; break;
6691 default: break;
6692 }
6693 break;
83eef883
AFB
6694 case EM_PPC:
6695 if (flag == SHF_PPC_VLE)
6696 sindex = 25;
6697 break;
99fabbc9
JL
6698 default:
6699 break;
6700 }
ac4c9b04 6701
99fabbc9
JL
6702 switch (filedata->file_header.e_ident[EI_OSABI])
6703 {
6704 case ELFOSABI_GNU:
6705 case ELFOSABI_FREEBSD:
6706 if (flag == SHF_GNU_RETAIN)
6707 sindex = 26;
6708 /* Fall through */
6709 case ELFOSABI_NONE:
6710 if (flag == SHF_GNU_MBIND)
6711 /* We should not recognize SHF_GNU_MBIND for
6712 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6713 not set the EI_OSABI header byte. */
6714 sindex = 24;
6715 break;
cfcac11d
NC
6716 default:
6717 break;
148b93f2 6718 }
99fabbc9 6719 break;
5477e8a0
L
6720 }
6721
91d6fa6a 6722 if (sindex != -1)
5477e8a0 6723 {
8d5ff12c
L
6724 if (p != buff + field_size + 4)
6725 {
6726 if (size < (10 + 2))
bee0ee85
NC
6727 {
6728 warn (_("Internal error: not enough buffer room for section flag info"));
6729 return _("<unknown>");
6730 }
8d5ff12c
L
6731 size -= 2;
6732 *p++ = ',';
6733 *p++ = ' ';
6734 }
6735
91d6fa6a
NC
6736 size -= flags [sindex].len;
6737 p = stpcpy (p, flags [sindex].str);
5477e8a0 6738 }
3b22753a 6739 else if (flag & SHF_MASKOS)
8d5ff12c 6740 os_flags |= flag;
d1133906 6741 else if (flag & SHF_MASKPROC)
8d5ff12c 6742 proc_flags |= flag;
d1133906 6743 else
8d5ff12c 6744 unknown_flags |= flag;
5477e8a0
L
6745 }
6746 else
6747 {
6748 switch (flag)
6749 {
6750 case SHF_WRITE: *p = 'W'; break;
6751 case SHF_ALLOC: *p = 'A'; break;
6752 case SHF_EXECINSTR: *p = 'X'; break;
6753 case SHF_MERGE: *p = 'M'; break;
6754 case SHF_STRINGS: *p = 'S'; break;
6755 case SHF_INFO_LINK: *p = 'I'; break;
6756 case SHF_LINK_ORDER: *p = 'L'; break;
6757 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6758 case SHF_GROUP: *p = 'G'; break;
6759 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6760 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6761 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6762
6763 default:
dda8d76d
NC
6764 if ((filedata->file_header.e_machine == EM_X86_64
6765 || filedata->file_header.e_machine == EM_L1OM
6766 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6767 && flag == SHF_X86_64_LARGE)
6768 *p = 'l';
dda8d76d 6769 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6770 && flag == SHF_ARM_PURECODE)
99fabbc9 6771 *p = 'y';
dda8d76d 6772 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6773 && flag == SHF_PPC_VLE)
99fabbc9 6774 *p = 'v';
5477e8a0
L
6775 else if (flag & SHF_MASKOS)
6776 {
99fabbc9
JL
6777 switch (filedata->file_header.e_ident[EI_OSABI])
6778 {
6779 case ELFOSABI_GNU:
6780 case ELFOSABI_FREEBSD:
6781 if (flag == SHF_GNU_RETAIN)
6782 {
6783 *p = 'R';
6784 break;
6785 }
6786 /* Fall through */
6787 case ELFOSABI_NONE:
6788 if (flag == SHF_GNU_MBIND)
6789 {
6790 /* We should not recognize SHF_GNU_MBIND for
6791 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6792 not set the EI_OSABI header byte. */
6793 *p = 'D';
6794 break;
6795 }
6796 /* Fall through */
6797 default:
6798 *p = 'o';
6799 sh_flags &= ~SHF_MASKOS;
6800 break;
6801 }
5477e8a0
L
6802 }
6803 else if (flag & SHF_MASKPROC)
6804 {
6805 *p = 'p';
6806 sh_flags &= ~ SHF_MASKPROC;
6807 }
6808 else
6809 *p = 'x';
6810 break;
6811 }
6812 p++;
d1133906
NC
6813 }
6814 }
76da6bbe 6815
8d5ff12c
L
6816 if (do_section_details)
6817 {
6818 if (os_flags)
6819 {
6820 size -= 5 + field_size;
6821 if (p != buff + field_size + 4)
6822 {
6823 if (size < (2 + 1))
bee0ee85
NC
6824 {
6825 warn (_("Internal error: not enough buffer room for section flag info"));
6826 return _("<unknown>");
6827 }
8d5ff12c
L
6828 size -= 2;
6829 *p++ = ',';
6830 *p++ = ' ';
6831 }
6832 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6833 (unsigned long) os_flags);
6834 p += 5 + field_size;
6835 }
6836 if (proc_flags)
6837 {
6838 size -= 7 + field_size;
6839 if (p != buff + field_size + 4)
6840 {
6841 if (size < (2 + 1))
bee0ee85
NC
6842 {
6843 warn (_("Internal error: not enough buffer room for section flag info"));
6844 return _("<unknown>");
6845 }
8d5ff12c
L
6846 size -= 2;
6847 *p++ = ',';
6848 *p++ = ' ';
6849 }
6850 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6851 (unsigned long) proc_flags);
6852 p += 7 + field_size;
6853 }
6854 if (unknown_flags)
6855 {
6856 size -= 10 + field_size;
6857 if (p != buff + field_size + 4)
6858 {
6859 if (size < (2 + 1))
bee0ee85
NC
6860 {
6861 warn (_("Internal error: not enough buffer room for section flag info"));
6862 return _("<unknown>");
6863 }
8d5ff12c
L
6864 size -= 2;
6865 *p++ = ',';
6866 *p++ = ' ';
6867 }
2b692964 6868 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6869 (unsigned long) unknown_flags);
6870 p += 10 + field_size;
6871 }
6872 }
6873
e9e44622 6874 *p = '\0';
d1133906
NC
6875 return buff;
6876}
6877
5844b465 6878static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6879get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6880{
6881 if (is_32bit_elf)
6882 {
6883 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6884
ebdf1ebf
NC
6885 if (size < sizeof (* echdr))
6886 {
6887 error (_("Compressed section is too small even for a compression header\n"));
6888 return 0;
6889 }
6890
77115a4a
L
6891 chdr->ch_type = BYTE_GET (echdr->ch_type);
6892 chdr->ch_size = BYTE_GET (echdr->ch_size);
6893 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6894 return sizeof (*echdr);
6895 }
6896 else
6897 {
6898 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6899
ebdf1ebf
NC
6900 if (size < sizeof (* echdr))
6901 {
6902 error (_("Compressed section is too small even for a compression header\n"));
6903 return 0;
6904 }
6905
77115a4a
L
6906 chdr->ch_type = BYTE_GET (echdr->ch_type);
6907 chdr->ch_size = BYTE_GET (echdr->ch_size);
6908 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6909 return sizeof (*echdr);
6910 }
6911}
6912
015dc7e1 6913static bool
dda8d76d 6914process_section_headers (Filedata * filedata)
252b5132 6915{
2cf0635d 6916 Elf_Internal_Shdr * section;
b34976b6 6917 unsigned int i;
252b5132 6918
dda8d76d 6919 if (filedata->file_header.e_shnum == 0)
252b5132 6920 {
82f2dbf7 6921 /* PR binutils/12467. */
dda8d76d 6922 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6923 {
6924 warn (_("possibly corrupt ELF file header - it has a non-zero"
6925 " section header offset, but no section headers\n"));
015dc7e1 6926 return false;
32ec8896 6927 }
82f2dbf7 6928 else if (do_sections)
252b5132
RH
6929 printf (_("\nThere are no sections in this file.\n"));
6930
015dc7e1 6931 return true;
252b5132
RH
6932 }
6933
6934 if (do_sections && !do_header)
ca0e11aa
NC
6935 {
6936 if (filedata->is_separate && process_links)
6937 printf (_("In linked file '%s': "), filedata->file_name);
6938 if (! filedata->is_separate || process_links)
6939 printf (ngettext ("There is %d section header, "
6940 "starting at offset 0x%lx:\n",
6941 "There are %d section headers, "
6942 "starting at offset 0x%lx:\n",
6943 filedata->file_header.e_shnum),
6944 filedata->file_header.e_shnum,
6945 (unsigned long) filedata->file_header.e_shoff);
6946 }
252b5132 6947
4de91c10
AM
6948 if (!get_section_headers (filedata, false))
6949 return false;
252b5132
RH
6950
6951 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6952 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6953 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6954 {
dda8d76d 6955 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6956
c256ffe7
JJ
6957 if (section->sh_size != 0)
6958 {
dda8d76d
NC
6959 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6960 1, section->sh_size,
6961 _("string table"));
0de14b54 6962
dda8d76d 6963 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6964 }
252b5132
RH
6965 }
6966
6967 /* Scan the sections for the dynamic symbol table
e3c8793a 6968 and dynamic string table and debug sections. */
89fac5e3 6969 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6970 switch (filedata->file_header.e_machine)
89fac5e3
RS
6971 {
6972 case EM_MIPS:
6973 case EM_MIPS_RS3_LE:
6974 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6975 FDE addresses. However, the ABI also has a semi-official ILP32
6976 variant for which the normal FDE address size rules apply.
6977
6978 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6979 section, where XX is the size of longs in bits. Unfortunately,
6980 earlier compilers provided no way of distinguishing ILP32 objects
6981 from LP64 objects, so if there's any doubt, we should assume that
6982 the official LP64 form is being used. */
dda8d76d
NC
6983 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6984 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6985 eh_addr_size = 8;
6986 break;
0f56a26a
DD
6987
6988 case EM_H8_300:
6989 case EM_H8_300H:
dda8d76d 6990 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6991 {
6992 case E_H8_MACH_H8300:
6993 case E_H8_MACH_H8300HN:
6994 case E_H8_MACH_H8300SN:
6995 case E_H8_MACH_H8300SXN:
6996 eh_addr_size = 2;
6997 break;
6998 case E_H8_MACH_H8300H:
6999 case E_H8_MACH_H8300S:
7000 case E_H8_MACH_H8300SX:
7001 eh_addr_size = 4;
7002 break;
7003 }
f4236fe4
DD
7004 break;
7005
ff7eeb89 7006 case EM_M32C_OLD:
f4236fe4 7007 case EM_M32C:
dda8d76d 7008 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7009 {
7010 case EF_M32C_CPU_M16C:
7011 eh_addr_size = 2;
7012 break;
7013 }
7014 break;
89fac5e3
RS
7015 }
7016
76ca31c0
NC
7017#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7018 do \
7019 { \
7020 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7021 if (section->sh_entsize != expected_entsize) \
9dd3a467 7022 { \
76ca31c0
NC
7023 char buf[40]; \
7024 sprintf_vma (buf, section->sh_entsize); \
7025 /* Note: coded this way so that there is a single string for \
7026 translation. */ \
7027 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7028 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7029 (unsigned) expected_entsize); \
9dd3a467 7030 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7031 } \
7032 } \
08d8fa11 7033 while (0)
9dd3a467
NC
7034
7035#define CHECK_ENTSIZE(section, i, type) \
1b513401 7036 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7037 sizeof (Elf64_External_##type))
7038
dda8d76d
NC
7039 for (i = 0, section = filedata->section_headers;
7040 i < filedata->file_header.e_shnum;
b34976b6 7041 i++, section++)
252b5132 7042 {
84714f86 7043 const char *name = section_name_print (filedata, section);
252b5132 7044
1b513401
NC
7045 /* Run some sanity checks on the headers and
7046 possibly fill in some file data as well. */
7047 switch (section->sh_type)
252b5132 7048 {
1b513401 7049 case SHT_DYNSYM:
978c4450 7050 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7051 {
7052 error (_("File contains multiple dynamic symbol tables\n"));
7053 continue;
7054 }
7055
08d8fa11 7056 CHECK_ENTSIZE (section, i, Sym);
978c4450 7057 filedata->dynamic_symbols
4de91c10 7058 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7059 filedata->dynamic_symtab_section = section;
1b513401
NC
7060 break;
7061
7062 case SHT_STRTAB:
7063 if (streq (name, ".dynstr"))
252b5132 7064 {
1b513401
NC
7065 if (filedata->dynamic_strings != NULL)
7066 {
7067 error (_("File contains multiple dynamic string tables\n"));
7068 continue;
7069 }
7070
7071 filedata->dynamic_strings
7072 = (char *) get_data (NULL, filedata, section->sh_offset,
7073 1, section->sh_size, _("dynamic strings"));
7074 filedata->dynamic_strings_length
7075 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7076 filedata->dynamic_strtab_section = section;
252b5132 7077 }
1b513401
NC
7078 break;
7079
7080 case SHT_SYMTAB_SHNDX:
7081 {
7082 elf_section_list * entry = xmalloc (sizeof * entry);
7083
7084 entry->hdr = section;
7085 entry->next = filedata->symtab_shndx_list;
7086 filedata->symtab_shndx_list = entry;
7087 }
7088 break;
7089
7090 case SHT_SYMTAB:
7091 CHECK_ENTSIZE (section, i, Sym);
7092 break;
7093
7094 case SHT_GROUP:
7095 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7096 break;
252b5132 7097
1b513401
NC
7098 case SHT_REL:
7099 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7100 if (do_checks && section->sh_size == 0)
1b513401
NC
7101 warn (_("Section '%s': zero-sized relocation section\n"), name);
7102 break;
7103
7104 case SHT_RELA:
7105 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7106 if (do_checks && section->sh_size == 0)
1b513401
NC
7107 warn (_("Section '%s': zero-sized relocation section\n"), name);
7108 break;
7109
682351b9
AM
7110 case SHT_RELR:
7111 CHECK_ENTSIZE (section, i, Relr);
7112 break;
7113
1b513401
NC
7114 case SHT_NOTE:
7115 case SHT_PROGBITS:
546cb2d8
NC
7116 /* Having a zero sized section is not illegal according to the
7117 ELF standard, but it might be an indication that something
7118 is wrong. So issue a warning if we are running in lint mode. */
7119 if (do_checks && section->sh_size == 0)
1b513401
NC
7120 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7121 break;
7122
7123 default:
7124 break;
7125 }
7126
7127 if ((do_debugging || do_debug_info || do_debug_abbrevs
7128 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7129 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7130 || do_debug_str || do_debug_str_offsets || do_debug_loc
7131 || do_debug_ranges
1b513401 7132 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7133 && (startswith (name, ".debug_")
7134 || startswith (name, ".zdebug_")))
252b5132 7135 {
1b315056
CS
7136 if (name[1] == 'z')
7137 name += sizeof (".zdebug_") - 1;
7138 else
7139 name += sizeof (".debug_") - 1;
252b5132
RH
7140
7141 if (do_debugging
24d127aa
ML
7142 || (do_debug_info && startswith (name, "info"))
7143 || (do_debug_info && startswith (name, "types"))
7144 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7145 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7146 || (do_debug_lines && startswith (name, "line."))
7147 || (do_debug_pubnames && startswith (name, "pubnames"))
7148 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7149 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7150 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7151 || (do_debug_aranges && startswith (name, "aranges"))
7152 || (do_debug_ranges && startswith (name, "ranges"))
7153 || (do_debug_ranges && startswith (name, "rnglists"))
7154 || (do_debug_frames && startswith (name, "frame"))
7155 || (do_debug_macinfo && startswith (name, "macinfo"))
7156 || (do_debug_macinfo && startswith (name, "macro"))
7157 || (do_debug_str && startswith (name, "str"))
7158 || (do_debug_links && startswith (name, "sup"))
7159 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7160 || (do_debug_loc && startswith (name, "loc"))
7161 || (do_debug_loc && startswith (name, "loclists"))
7162 || (do_debug_addr && startswith (name, "addr"))
7163 || (do_debug_cu_index && startswith (name, "cu_index"))
7164 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7165 )
6431e409 7166 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7167 }
a262ae96 7168 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7169 else if ((do_debugging || do_debug_info)
24d127aa 7170 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7171 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7172 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7173 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7174 else if (do_gdb_index && (streq (name, ".gdb_index")
7175 || streq (name, ".debug_names")))
6431e409 7176 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7177 /* Trace sections for Itanium VMS. */
7178 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7179 || do_trace_aranges)
24d127aa 7180 && startswith (name, ".trace_"))
6f875884
TG
7181 {
7182 name += sizeof (".trace_") - 1;
7183
7184 if (do_debugging
7185 || (do_trace_info && streq (name, "info"))
7186 || (do_trace_abbrevs && streq (name, "abbrev"))
7187 || (do_trace_aranges && streq (name, "aranges"))
7188 )
6431e409 7189 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7190 }
dda8d76d 7191 else if ((do_debugging || do_debug_links)
24d127aa
ML
7192 && (startswith (name, ".gnu_debuglink")
7193 || startswith (name, ".gnu_debugaltlink")))
6431e409 7194 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7195 }
7196
7197 if (! do_sections)
015dc7e1 7198 return true;
252b5132 7199
ca0e11aa 7200 if (filedata->is_separate && ! process_links)
015dc7e1 7201 return true;
ca0e11aa
NC
7202
7203 if (filedata->is_separate)
7204 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7205 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7206 printf (_("\nSection Headers:\n"));
7207 else
7208 printf (_("\nSection Header:\n"));
76da6bbe 7209
f7a99963 7210 if (is_32bit_elf)
595cf52e 7211 {
5477e8a0 7212 if (do_section_details)
595cf52e
L
7213 {
7214 printf (_(" [Nr] Name\n"));
5477e8a0 7215 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7216 }
7217 else
7218 printf
7219 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7220 }
d974e256 7221 else if (do_wide)
595cf52e 7222 {
5477e8a0 7223 if (do_section_details)
595cf52e
L
7224 {
7225 printf (_(" [Nr] Name\n"));
5477e8a0 7226 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7227 }
7228 else
7229 printf
7230 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7231 }
f7a99963
NC
7232 else
7233 {
5477e8a0 7234 if (do_section_details)
595cf52e
L
7235 {
7236 printf (_(" [Nr] Name\n"));
5477e8a0
L
7237 printf (_(" Type Address Offset Link\n"));
7238 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7239 }
7240 else
7241 {
7242 printf (_(" [Nr] Name Type Address Offset\n"));
7243 printf (_(" Size EntSize Flags Link Info Align\n"));
7244 }
f7a99963 7245 }
252b5132 7246
5477e8a0
L
7247 if (do_section_details)
7248 printf (_(" Flags\n"));
7249
dda8d76d
NC
7250 for (i = 0, section = filedata->section_headers;
7251 i < filedata->file_header.e_shnum;
b34976b6 7252 i++, section++)
252b5132 7253 {
dd905818
NC
7254 /* Run some sanity checks on the section header. */
7255
7256 /* Check the sh_link field. */
7257 switch (section->sh_type)
7258 {
285e3f99
AM
7259 case SHT_REL:
7260 case SHT_RELA:
7261 if (section->sh_link == 0
7262 && (filedata->file_header.e_type == ET_EXEC
7263 || filedata->file_header.e_type == ET_DYN))
7264 /* A dynamic relocation section where all entries use a
7265 zero symbol index need not specify a symtab section. */
7266 break;
7267 /* Fall through. */
dd905818
NC
7268 case SHT_SYMTAB_SHNDX:
7269 case SHT_GROUP:
7270 case SHT_HASH:
7271 case SHT_GNU_HASH:
7272 case SHT_GNU_versym:
285e3f99 7273 if (section->sh_link == 0
dda8d76d
NC
7274 || section->sh_link >= filedata->file_header.e_shnum
7275 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7276 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7277 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7278 i, section->sh_link);
7279 break;
7280
7281 case SHT_DYNAMIC:
7282 case SHT_SYMTAB:
7283 case SHT_DYNSYM:
7284 case SHT_GNU_verneed:
7285 case SHT_GNU_verdef:
7286 case SHT_GNU_LIBLIST:
285e3f99 7287 if (section->sh_link == 0
dda8d76d
NC
7288 || section->sh_link >= filedata->file_header.e_shnum
7289 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7290 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7291 i, section->sh_link);
7292 break;
7293
7294 case SHT_INIT_ARRAY:
7295 case SHT_FINI_ARRAY:
7296 case SHT_PREINIT_ARRAY:
7297 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7298 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7299 i, section->sh_link);
7300 break;
7301
7302 default:
7303 /* FIXME: Add support for target specific section types. */
7304#if 0 /* Currently we do not check other section types as there are too
7305 many special cases. Stab sections for example have a type
7306 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7307 section. */
7308 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7309 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7310 i, section->sh_link);
7311#endif
7312 break;
7313 }
7314
7315 /* Check the sh_info field. */
7316 switch (section->sh_type)
7317 {
7318 case SHT_REL:
7319 case SHT_RELA:
285e3f99
AM
7320 if (section->sh_info == 0
7321 && (filedata->file_header.e_type == ET_EXEC
7322 || filedata->file_header.e_type == ET_DYN))
7323 /* Dynamic relocations apply to segments, so they do not
7324 need to specify the section they relocate. */
7325 break;
7326 if (section->sh_info == 0
dda8d76d
NC
7327 || section->sh_info >= filedata->file_header.e_shnum
7328 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7329 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7330 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7331 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7332 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7333 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7334 /* FIXME: Are other section types valid ? */
dda8d76d 7335 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7336 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7337 i, section->sh_info);
dd905818
NC
7338 break;
7339
7340 case SHT_DYNAMIC:
7341 case SHT_HASH:
7342 case SHT_SYMTAB_SHNDX:
7343 case SHT_INIT_ARRAY:
7344 case SHT_FINI_ARRAY:
7345 case SHT_PREINIT_ARRAY:
7346 if (section->sh_info != 0)
7347 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7348 i, section->sh_info);
7349 break;
7350
7351 case SHT_GROUP:
7352 case SHT_SYMTAB:
7353 case SHT_DYNSYM:
7354 /* A symbol index - we assume that it is valid. */
7355 break;
7356
7357 default:
7358 /* FIXME: Add support for target specific section types. */
7359 if (section->sh_type == SHT_NOBITS)
7360 /* NOBITS section headers with non-zero sh_info fields can be
7361 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7362 information. The stripped sections have their headers
7363 preserved but their types set to SHT_NOBITS. So do not check
7364 this type of section. */
dd905818
NC
7365 ;
7366 else if (section->sh_flags & SHF_INFO_LINK)
7367 {
dda8d76d 7368 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7369 warn (_("[%2u]: Expected link to another section in info field"), i);
7370 }
a91e1603
L
7371 else if (section->sh_type < SHT_LOOS
7372 && (section->sh_flags & SHF_GNU_MBIND) == 0
7373 && section->sh_info != 0)
dd905818
NC
7374 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7375 i, section->sh_info);
7376 break;
7377 }
7378
3e6b6445 7379 /* Check the sh_size field. */
dda8d76d 7380 if (section->sh_size > filedata->file_size
3e6b6445
NC
7381 && section->sh_type != SHT_NOBITS
7382 && section->sh_type != SHT_NULL
7383 && section->sh_type < SHT_LOOS)
7384 warn (_("Size of section %u is larger than the entire file!\n"), i);
7385
7bfd842d 7386 printf (" [%2u] ", i);
5477e8a0 7387 if (do_section_details)
dda8d76d 7388 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7389 else
84714f86 7390 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7391
ea52a088 7392 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7393 get_section_type_name (filedata, section->sh_type));
0b4362b0 7394
f7a99963
NC
7395 if (is_32bit_elf)
7396 {
cfcac11d
NC
7397 const char * link_too_big = NULL;
7398
f7a99963 7399 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7400
f7a99963
NC
7401 printf ( " %6.6lx %6.6lx %2.2lx",
7402 (unsigned long) section->sh_offset,
7403 (unsigned long) section->sh_size,
7404 (unsigned long) section->sh_entsize);
d1133906 7405
5477e8a0
L
7406 if (do_section_details)
7407 fputs (" ", stdout);
7408 else
dda8d76d 7409 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7410
dda8d76d 7411 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7412 {
7413 link_too_big = "";
7414 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7415 an error but it can have special values in Solaris binaries. */
dda8d76d 7416 switch (filedata->file_header.e_machine)
cfcac11d 7417 {
caa83f8b 7418 case EM_386:
22abe556 7419 case EM_IAMCU:
caa83f8b 7420 case EM_X86_64:
7f502d6c 7421 case EM_L1OM:
7a9068fe 7422 case EM_K1OM:
cfcac11d
NC
7423 case EM_OLD_SPARCV9:
7424 case EM_SPARC32PLUS:
7425 case EM_SPARCV9:
7426 case EM_SPARC:
7427 if (section->sh_link == (SHN_BEFORE & 0xffff))
7428 link_too_big = "BEFORE";
7429 else if (section->sh_link == (SHN_AFTER & 0xffff))
7430 link_too_big = "AFTER";
7431 break;
7432 default:
7433 break;
7434 }
7435 }
7436
7437 if (do_section_details)
7438 {
7439 if (link_too_big != NULL && * link_too_big)
7440 printf ("<%s> ", link_too_big);
7441 else
7442 printf ("%2u ", section->sh_link);
7443 printf ("%3u %2lu\n", section->sh_info,
7444 (unsigned long) section->sh_addralign);
7445 }
7446 else
7447 printf ("%2u %3u %2lu\n",
7448 section->sh_link,
7449 section->sh_info,
7450 (unsigned long) section->sh_addralign);
7451
7452 if (link_too_big && ! * link_too_big)
7453 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7454 i, section->sh_link);
f7a99963 7455 }
d974e256
JJ
7456 else if (do_wide)
7457 {
7458 print_vma (section->sh_addr, LONG_HEX);
7459
7460 if ((long) section->sh_offset == section->sh_offset)
7461 printf (" %6.6lx", (unsigned long) section->sh_offset);
7462 else
7463 {
7464 putchar (' ');
7465 print_vma (section->sh_offset, LONG_HEX);
7466 }
7467
7468 if ((unsigned long) section->sh_size == section->sh_size)
7469 printf (" %6.6lx", (unsigned long) section->sh_size);
7470 else
7471 {
7472 putchar (' ');
7473 print_vma (section->sh_size, LONG_HEX);
7474 }
7475
7476 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7477 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7478 else
7479 {
7480 putchar (' ');
7481 print_vma (section->sh_entsize, LONG_HEX);
7482 }
7483
5477e8a0
L
7484 if (do_section_details)
7485 fputs (" ", stdout);
7486 else
dda8d76d 7487 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7488
72de5009 7489 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7490
7491 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7492 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7493 else
7494 {
7495 print_vma (section->sh_addralign, DEC);
7496 putchar ('\n');
7497 }
7498 }
5477e8a0 7499 else if (do_section_details)
595cf52e 7500 {
55cc53e9 7501 putchar (' ');
595cf52e
L
7502 print_vma (section->sh_addr, LONG_HEX);
7503 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7504 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7505 else
7506 {
7507 printf (" ");
7508 print_vma (section->sh_offset, LONG_HEX);
7509 }
72de5009 7510 printf (" %u\n ", section->sh_link);
595cf52e 7511 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7512 putchar (' ');
595cf52e
L
7513 print_vma (section->sh_entsize, LONG_HEX);
7514
72de5009
AM
7515 printf (" %-16u %lu\n",
7516 section->sh_info,
595cf52e
L
7517 (unsigned long) section->sh_addralign);
7518 }
f7a99963
NC
7519 else
7520 {
7521 putchar (' ');
7522 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7523 if ((long) section->sh_offset == section->sh_offset)
7524 printf (" %8.8lx", (unsigned long) section->sh_offset);
7525 else
7526 {
7527 printf (" ");
7528 print_vma (section->sh_offset, LONG_HEX);
7529 }
f7a99963
NC
7530 printf ("\n ");
7531 print_vma (section->sh_size, LONG_HEX);
7532 printf (" ");
7533 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7534
dda8d76d 7535 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7536
72de5009
AM
7537 printf (" %2u %3u %lu\n",
7538 section->sh_link,
7539 section->sh_info,
f7a99963
NC
7540 (unsigned long) section->sh_addralign);
7541 }
5477e8a0
L
7542
7543 if (do_section_details)
77115a4a 7544 {
dda8d76d 7545 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7546 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7547 {
7548 /* Minimum section size is 12 bytes for 32-bit compression
7549 header + 12 bytes for compressed data header. */
7550 unsigned char buf[24];
d8024a91 7551
77115a4a 7552 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7553 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7554 sizeof (buf), _("compression header")))
7555 {
7556 Elf_Internal_Chdr chdr;
d8024a91 7557
5844b465
NC
7558 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7559 printf (_(" [<corrupt>]\n"));
77115a4a 7560 else
5844b465
NC
7561 {
7562 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7563 printf (" ZLIB, ");
7564 else
7565 printf (_(" [<unknown>: 0x%x], "),
7566 chdr.ch_type);
7567 print_vma (chdr.ch_size, LONG_HEX);
7568 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7569 }
77115a4a
L
7570 }
7571 }
7572 }
252b5132
RH
7573 }
7574
5477e8a0 7575 if (!do_section_details)
3dbcc61d 7576 {
9fb71ee4
NC
7577 /* The ordering of the letters shown here matches the ordering of the
7578 corresponding SHF_xxx values, and hence the order in which these
7579 letters will be displayed to the user. */
7580 printf (_("Key to Flags:\n\
7581 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7582 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7583 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7584 switch (filedata->file_header.e_ident[EI_OSABI])
7585 {
7586 case ELFOSABI_GNU:
7587 case ELFOSABI_FREEBSD:
7588 printf (_("R (retain), "));
7589 /* Fall through */
7590 case ELFOSABI_NONE:
7591 printf (_("D (mbind), "));
7592 break;
7593 default:
7594 break;
7595 }
dda8d76d
NC
7596 if (filedata->file_header.e_machine == EM_X86_64
7597 || filedata->file_header.e_machine == EM_L1OM
7598 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7599 printf (_("l (large), "));
dda8d76d 7600 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7601 printf (_("y (purecode), "));
dda8d76d 7602 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7603 printf (_("v (VLE), "));
9fb71ee4 7604 printf ("p (processor specific)\n");
0b4362b0 7605 }
d1133906 7606
015dc7e1 7607 return true;
252b5132
RH
7608}
7609
015dc7e1 7610static bool
28d13567
AM
7611get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7612 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7613 char **strtab, unsigned long *strtablen)
7614{
7615 *strtab = NULL;
7616 *strtablen = 0;
4de91c10 7617 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7618
7619 if (*symtab == NULL)
015dc7e1 7620 return false;
28d13567
AM
7621
7622 if (symsec->sh_link != 0)
7623 {
7624 Elf_Internal_Shdr *strsec;
7625
7626 if (symsec->sh_link >= filedata->file_header.e_shnum)
7627 {
7628 error (_("Bad sh_link in symbol table section\n"));
7629 free (*symtab);
7630 *symtab = NULL;
7631 *nsyms = 0;
015dc7e1 7632 return false;
28d13567
AM
7633 }
7634
7635 strsec = filedata->section_headers + symsec->sh_link;
7636
7637 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7638 1, strsec->sh_size, _("string table"));
7639 if (*strtab == NULL)
7640 {
7641 free (*symtab);
7642 *symtab = NULL;
7643 *nsyms = 0;
015dc7e1 7644 return false;
28d13567
AM
7645 }
7646 *strtablen = strsec->sh_size;
7647 }
015dc7e1 7648 return true;
28d13567
AM
7649}
7650
f5842774
L
7651static const char *
7652get_group_flags (unsigned int flags)
7653{
1449284b 7654 static char buff[128];
220453ec 7655
6d913794
NC
7656 if (flags == 0)
7657 return "";
7658 else if (flags == GRP_COMDAT)
7659 return "COMDAT ";
f5842774 7660
89246a0e
AM
7661 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7662 flags,
7663 flags & GRP_MASKOS ? _("<OS specific>") : "",
7664 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7665 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7666 ? _("<unknown>") : ""));
6d913794 7667
f5842774
L
7668 return buff;
7669}
7670
015dc7e1 7671static bool
dda8d76d 7672process_section_groups (Filedata * filedata)
f5842774 7673{
2cf0635d 7674 Elf_Internal_Shdr * section;
f5842774 7675 unsigned int i;
2cf0635d
NC
7676 struct group * group;
7677 Elf_Internal_Shdr * symtab_sec;
7678 Elf_Internal_Shdr * strtab_sec;
7679 Elf_Internal_Sym * symtab;
ba5cdace 7680 unsigned long num_syms;
2cf0635d 7681 char * strtab;
c256ffe7 7682 size_t strtab_size;
d1f5c6e3
L
7683
7684 /* Don't process section groups unless needed. */
7685 if (!do_unwind && !do_section_groups)
015dc7e1 7686 return true;
f5842774 7687
dda8d76d 7688 if (filedata->file_header.e_shnum == 0)
f5842774
L
7689 {
7690 if (do_section_groups)
ca0e11aa
NC
7691 {
7692 if (filedata->is_separate)
7693 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7694 filedata->file_name);
7695 else
7696 printf (_("\nThere are no section groups in this file.\n"));
7697 }
015dc7e1 7698 return true;
f5842774
L
7699 }
7700
dda8d76d 7701 if (filedata->section_headers == NULL)
f5842774
L
7702 {
7703 error (_("Section headers are not available!\n"));
fa1908fd 7704 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7705 return false;
f5842774
L
7706 }
7707
978c4450
AM
7708 filedata->section_headers_groups
7709 = (struct group **) calloc (filedata->file_header.e_shnum,
7710 sizeof (struct group *));
e4b17d5c 7711
978c4450 7712 if (filedata->section_headers_groups == NULL)
e4b17d5c 7713 {
8b73c356 7714 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7715 filedata->file_header.e_shnum);
015dc7e1 7716 return false;
e4b17d5c
L
7717 }
7718
f5842774 7719 /* Scan the sections for the group section. */
978c4450 7720 filedata->group_count = 0;
dda8d76d
NC
7721 for (i = 0, section = filedata->section_headers;
7722 i < filedata->file_header.e_shnum;
f5842774 7723 i++, section++)
e4b17d5c 7724 if (section->sh_type == SHT_GROUP)
978c4450 7725 filedata->group_count++;
e4b17d5c 7726
978c4450 7727 if (filedata->group_count == 0)
d1f5c6e3
L
7728 {
7729 if (do_section_groups)
ca0e11aa
NC
7730 {
7731 if (filedata->is_separate)
7732 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7733 filedata->file_name);
7734 else
7735 printf (_("\nThere are no section groups in this file.\n"));
7736 }
d1f5c6e3 7737
015dc7e1 7738 return true;
d1f5c6e3
L
7739 }
7740
978c4450
AM
7741 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7742 sizeof (struct group));
e4b17d5c 7743
978c4450 7744 if (filedata->section_groups == NULL)
e4b17d5c 7745 {
8b73c356 7746 error (_("Out of memory reading %lu groups\n"),
978c4450 7747 (unsigned long) filedata->group_count);
015dc7e1 7748 return false;
e4b17d5c
L
7749 }
7750
d1f5c6e3
L
7751 symtab_sec = NULL;
7752 strtab_sec = NULL;
7753 symtab = NULL;
ba5cdace 7754 num_syms = 0;
d1f5c6e3 7755 strtab = NULL;
c256ffe7 7756 strtab_size = 0;
ca0e11aa
NC
7757
7758 if (filedata->is_separate)
7759 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7760
978c4450 7761 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7762 i < filedata->file_header.e_shnum;
e4b17d5c 7763 i++, section++)
f5842774
L
7764 {
7765 if (section->sh_type == SHT_GROUP)
7766 {
dda8d76d 7767 const char * name = printable_section_name (filedata, section);
74e1a04b 7768 const char * group_name;
2cf0635d
NC
7769 unsigned char * start;
7770 unsigned char * indices;
f5842774 7771 unsigned int entry, j, size;
2cf0635d
NC
7772 Elf_Internal_Shdr * sec;
7773 Elf_Internal_Sym * sym;
f5842774
L
7774
7775 /* Get the symbol table. */
dda8d76d
NC
7776 if (section->sh_link >= filedata->file_header.e_shnum
7777 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7778 != SHT_SYMTAB))
f5842774
L
7779 {
7780 error (_("Bad sh_link in group section `%s'\n"), name);
7781 continue;
7782 }
d1f5c6e3
L
7783
7784 if (symtab_sec != sec)
7785 {
7786 symtab_sec = sec;
9db70fc3 7787 free (symtab);
4de91c10 7788 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7789 }
f5842774 7790
dd24e3da
NC
7791 if (symtab == NULL)
7792 {
7793 error (_("Corrupt header in group section `%s'\n"), name);
7794 continue;
7795 }
7796
ba5cdace
NC
7797 if (section->sh_info >= num_syms)
7798 {
7799 error (_("Bad sh_info in group section `%s'\n"), name);
7800 continue;
7801 }
7802
f5842774
L
7803 sym = symtab + section->sh_info;
7804
7805 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7806 {
4fbb74a6 7807 if (sym->st_shndx == 0
dda8d76d 7808 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7809 {
7810 error (_("Bad sh_info in group section `%s'\n"), name);
7811 continue;
7812 }
ba2685cc 7813
84714f86
AM
7814 group_name = section_name_print (filedata,
7815 filedata->section_headers
b9e920ec 7816 + sym->st_shndx);
c256ffe7 7817 strtab_sec = NULL;
9db70fc3 7818 free (strtab);
f5842774 7819 strtab = NULL;
c256ffe7 7820 strtab_size = 0;
f5842774
L
7821 }
7822 else
7823 {
7824 /* Get the string table. */
dda8d76d 7825 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7826 {
7827 strtab_sec = NULL;
9db70fc3 7828 free (strtab);
c256ffe7
JJ
7829 strtab = NULL;
7830 strtab_size = 0;
7831 }
7832 else if (strtab_sec
dda8d76d 7833 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7834 {
7835 strtab_sec = sec;
9db70fc3 7836 free (strtab);
071436c6 7837
dda8d76d 7838 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7839 1, strtab_sec->sh_size,
7840 _("string table"));
c256ffe7 7841 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7842 }
c256ffe7 7843 group_name = sym->st_name < strtab_size
2b692964 7844 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7845 }
7846
c9c1d674
EG
7847 /* PR 17531: file: loop. */
7848 if (section->sh_entsize > section->sh_size)
7849 {
7850 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7851 printable_section_name (filedata, section),
8066deb1
AM
7852 (unsigned long) section->sh_entsize,
7853 (unsigned long) section->sh_size);
61dd8e19 7854 continue;
c9c1d674
EG
7855 }
7856
dda8d76d 7857 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7858 1, section->sh_size,
7859 _("section data"));
59245841
NC
7860 if (start == NULL)
7861 continue;
f5842774
L
7862
7863 indices = start;
7864 size = (section->sh_size / section->sh_entsize) - 1;
7865 entry = byte_get (indices, 4);
7866 indices += 4;
e4b17d5c
L
7867
7868 if (do_section_groups)
7869 {
2b692964 7870 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7871 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7872
e4b17d5c
L
7873 printf (_(" [Index] Name\n"));
7874 }
7875
7876 group->group_index = i;
7877
f5842774
L
7878 for (j = 0; j < size; j++)
7879 {
2cf0635d 7880 struct group_list * g;
e4b17d5c 7881
f5842774
L
7882 entry = byte_get (indices, 4);
7883 indices += 4;
7884
dda8d76d 7885 if (entry >= filedata->file_header.e_shnum)
391cb864 7886 {
57028622
NC
7887 static unsigned num_group_errors = 0;
7888
7889 if (num_group_errors ++ < 10)
7890 {
7891 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7892 entry, i, filedata->file_header.e_shnum - 1);
57028622 7893 if (num_group_errors == 10)
67ce483b 7894 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7895 }
391cb864
L
7896 continue;
7897 }
391cb864 7898
978c4450 7899 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7900 {
d1f5c6e3
L
7901 if (entry)
7902 {
57028622
NC
7903 static unsigned num_errs = 0;
7904
7905 if (num_errs ++ < 10)
7906 {
7907 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7908 entry, i,
978c4450 7909 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7910 if (num_errs == 10)
7911 warn (_("Further error messages about already contained group sections suppressed\n"));
7912 }
d1f5c6e3
L
7913 continue;
7914 }
7915 else
7916 {
7917 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7918 section group. We just warn it the first time
d1f5c6e3 7919 and ignore it afterwards. */
015dc7e1 7920 static bool warned = false;
d1f5c6e3
L
7921 if (!warned)
7922 {
7923 error (_("section 0 in group section [%5u]\n"),
978c4450 7924 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7925 warned = true;
d1f5c6e3
L
7926 }
7927 }
e4b17d5c
L
7928 }
7929
978c4450 7930 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7931
7932 if (do_section_groups)
7933 {
dda8d76d
NC
7934 sec = filedata->section_headers + entry;
7935 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7936 }
7937
3f5e193b 7938 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7939 g->section_index = entry;
7940 g->next = group->root;
7941 group->root = g;
f5842774
L
7942 }
7943
9db70fc3 7944 free (start);
e4b17d5c
L
7945
7946 group++;
f5842774
L
7947 }
7948 }
7949
9db70fc3
AM
7950 free (symtab);
7951 free (strtab);
015dc7e1 7952 return true;
f5842774
L
7953}
7954
28f997cf
TG
7955/* Data used to display dynamic fixups. */
7956
7957struct ia64_vms_dynfixup
7958{
7959 bfd_vma needed_ident; /* Library ident number. */
7960 bfd_vma needed; /* Index in the dstrtab of the library name. */
7961 bfd_vma fixup_needed; /* Index of the library. */
7962 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7963 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7964};
7965
7966/* Data used to display dynamic relocations. */
7967
7968struct ia64_vms_dynimgrela
7969{
7970 bfd_vma img_rela_cnt; /* Number of relocations. */
7971 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7972};
7973
7974/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7975 library). */
7976
015dc7e1 7977static bool
dda8d76d
NC
7978dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7979 struct ia64_vms_dynfixup * fixup,
7980 const char * strtab,
7981 unsigned int strtab_sz)
28f997cf 7982{
32ec8896 7983 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7984 long i;
32ec8896 7985 const char * lib_name;
28f997cf 7986
978c4450
AM
7987 imfs = get_data (NULL, filedata,
7988 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7989 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7990 _("dynamic section image fixups"));
7991 if (!imfs)
015dc7e1 7992 return false;
28f997cf
TG
7993
7994 if (fixup->needed < strtab_sz)
7995 lib_name = strtab + fixup->needed;
7996 else
7997 {
32ec8896 7998 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7999 (unsigned long) fixup->needed);
28f997cf
TG
8000 lib_name = "???";
8001 }
736990c4 8002
28f997cf
TG
8003 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8004 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8005 printf
8006 (_("Seg Offset Type SymVec DataType\n"));
8007
8008 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8009 {
8010 unsigned int type;
8011 const char *rtype;
8012
8013 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8014 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
8015 type = BYTE_GET (imfs [i].type);
8016 rtype = elf_ia64_reloc_type (type);
8017 if (rtype == NULL)
8018 printf (" 0x%08x ", type);
8019 else
8020 printf (" %-32s ", rtype);
8021 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8022 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8023 }
8024
8025 free (imfs);
015dc7e1 8026 return true;
28f997cf
TG
8027}
8028
8029/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8030
015dc7e1 8031static bool
dda8d76d 8032dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8033{
8034 Elf64_External_VMS_IMAGE_RELA *imrs;
8035 long i;
8036
978c4450
AM
8037 imrs = get_data (NULL, filedata,
8038 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8039 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8040 _("dynamic section image relocations"));
28f997cf 8041 if (!imrs)
015dc7e1 8042 return false;
28f997cf
TG
8043
8044 printf (_("\nImage relocs\n"));
8045 printf
8046 (_("Seg Offset Type Addend Seg Sym Off\n"));
8047
8048 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8049 {
8050 unsigned int type;
8051 const char *rtype;
8052
8053 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8054 printf ("%08" BFD_VMA_FMT "x ",
8055 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8056 type = BYTE_GET (imrs [i].type);
8057 rtype = elf_ia64_reloc_type (type);
8058 if (rtype == NULL)
8059 printf ("0x%08x ", type);
8060 else
8061 printf ("%-31s ", rtype);
8062 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8063 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8064 printf ("%08" BFD_VMA_FMT "x\n",
8065 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8066 }
8067
8068 free (imrs);
015dc7e1 8069 return true;
28f997cf
TG
8070}
8071
8072/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8073
015dc7e1 8074static bool
dda8d76d 8075process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8076{
8077 struct ia64_vms_dynfixup fixup;
8078 struct ia64_vms_dynimgrela imgrela;
8079 Elf_Internal_Dyn *entry;
28f997cf
TG
8080 bfd_vma strtab_off = 0;
8081 bfd_vma strtab_sz = 0;
8082 char *strtab = NULL;
015dc7e1 8083 bool res = true;
28f997cf
TG
8084
8085 memset (&fixup, 0, sizeof (fixup));
8086 memset (&imgrela, 0, sizeof (imgrela));
8087
8088 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8089 for (entry = filedata->dynamic_section;
8090 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8091 entry++)
8092 {
8093 switch (entry->d_tag)
8094 {
8095 case DT_IA_64_VMS_STRTAB_OFFSET:
8096 strtab_off = entry->d_un.d_val;
8097 break;
8098 case DT_STRSZ:
8099 strtab_sz = entry->d_un.d_val;
8100 if (strtab == NULL)
978c4450
AM
8101 strtab = get_data (NULL, filedata,
8102 filedata->dynamic_addr + strtab_off,
28f997cf 8103 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8104 if (strtab == NULL)
8105 strtab_sz = 0;
28f997cf
TG
8106 break;
8107
8108 case DT_IA_64_VMS_NEEDED_IDENT:
8109 fixup.needed_ident = entry->d_un.d_val;
8110 break;
8111 case DT_NEEDED:
8112 fixup.needed = entry->d_un.d_val;
8113 break;
8114 case DT_IA_64_VMS_FIXUP_NEEDED:
8115 fixup.fixup_needed = entry->d_un.d_val;
8116 break;
8117 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8118 fixup.fixup_rela_cnt = entry->d_un.d_val;
8119 break;
8120 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8121 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8122 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8123 res = false;
28f997cf 8124 break;
28f997cf
TG
8125 case DT_IA_64_VMS_IMG_RELA_CNT:
8126 imgrela.img_rela_cnt = entry->d_un.d_val;
8127 break;
8128 case DT_IA_64_VMS_IMG_RELA_OFF:
8129 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8130 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8131 res = false;
28f997cf
TG
8132 break;
8133
8134 default:
8135 break;
8136 }
8137 }
8138
9db70fc3 8139 free (strtab);
28f997cf
TG
8140
8141 return res;
8142}
8143
85b1c36d 8144static struct
566b0d53 8145{
2cf0635d 8146 const char * name;
566b0d53
L
8147 int reloc;
8148 int size;
a7fd1186 8149 relocation_type rel_type;
32ec8896
NC
8150}
8151 dynamic_relocations [] =
566b0d53 8152{
a7fd1186
FS
8153 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8154 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8155 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8156 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8157};
8158
252b5132 8159/* Process the reloc section. */
18bd398b 8160
015dc7e1 8161static bool
dda8d76d 8162process_relocs (Filedata * filedata)
252b5132 8163{
b34976b6
AM
8164 unsigned long rel_size;
8165 unsigned long rel_offset;
252b5132 8166
252b5132 8167 if (!do_reloc)
015dc7e1 8168 return true;
252b5132
RH
8169
8170 if (do_using_dynamic)
8171 {
a7fd1186 8172 relocation_type rel_type;
2cf0635d 8173 const char * name;
015dc7e1 8174 bool has_dynamic_reloc;
566b0d53 8175 unsigned int i;
0de14b54 8176
015dc7e1 8177 has_dynamic_reloc = false;
252b5132 8178
566b0d53 8179 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8180 {
a7fd1186 8181 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8182 name = dynamic_relocations [i].name;
978c4450
AM
8183 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8184 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8185
32ec8896 8186 if (rel_size)
015dc7e1 8187 has_dynamic_reloc = true;
566b0d53 8188
a7fd1186 8189 if (rel_type == reltype_unknown)
aa903cfb 8190 {
566b0d53 8191 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8192 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8193 {
8194 case DT_REL:
a7fd1186 8195 rel_type = reltype_rel;
566b0d53
L
8196 break;
8197 case DT_RELA:
a7fd1186 8198 rel_type = reltype_rela;
566b0d53
L
8199 break;
8200 }
aa903cfb 8201 }
252b5132 8202
566b0d53
L
8203 if (rel_size)
8204 {
ca0e11aa
NC
8205 if (filedata->is_separate)
8206 printf
8207 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8208 filedata->file_name, name, rel_offset, rel_size);
8209 else
8210 printf
8211 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8212 name, rel_offset, rel_size);
252b5132 8213
dda8d76d
NC
8214 dump_relocations (filedata,
8215 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8216 rel_size,
978c4450
AM
8217 filedata->dynamic_symbols,
8218 filedata->num_dynamic_syms,
8219 filedata->dynamic_strings,
8220 filedata->dynamic_strings_length,
a7fd1186 8221 rel_type, true /* is_dynamic */);
566b0d53 8222 }
252b5132 8223 }
566b0d53 8224
dda8d76d
NC
8225 if (is_ia64_vms (filedata))
8226 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8227 has_dynamic_reloc = true;
28f997cf 8228
566b0d53 8229 if (! has_dynamic_reloc)
ca0e11aa
NC
8230 {
8231 if (filedata->is_separate)
8232 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8233 filedata->file_name);
8234 else
8235 printf (_("\nThere are no dynamic relocations in this file.\n"));
8236 }
252b5132
RH
8237 }
8238 else
8239 {
2cf0635d 8240 Elf_Internal_Shdr * section;
b34976b6 8241 unsigned long i;
015dc7e1 8242 bool found = false;
252b5132 8243
dda8d76d
NC
8244 for (i = 0, section = filedata->section_headers;
8245 i < filedata->file_header.e_shnum;
b34976b6 8246 i++, section++)
252b5132
RH
8247 {
8248 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8249 && section->sh_type != SHT_REL
8250 && section->sh_type != SHT_RELR)
252b5132
RH
8251 continue;
8252
8253 rel_offset = section->sh_offset;
8254 rel_size = section->sh_size;
8255
8256 if (rel_size)
8257 {
a7fd1186 8258 relocation_type rel_type;
d3a49aa8 8259 unsigned long num_rela;
103f02d3 8260
ca0e11aa
NC
8261 if (filedata->is_separate)
8262 printf (_("\nIn linked file '%s' relocation section "),
8263 filedata->file_name);
8264 else
8265 printf (_("\nRelocation section "));
252b5132 8266
dda8d76d 8267 if (filedata->string_table == NULL)
19936277 8268 printf ("%d", section->sh_name);
252b5132 8269 else
dda8d76d 8270 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8271
d3a49aa8
AM
8272 num_rela = rel_size / section->sh_entsize;
8273 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8274 " at offset 0x%lx contains %lu entries:\n",
8275 num_rela),
8276 rel_offset, num_rela);
252b5132 8277
a7fd1186
FS
8278 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8279 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8280
4fbb74a6 8281 if (section->sh_link != 0
dda8d76d 8282 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8283 {
2cf0635d
NC
8284 Elf_Internal_Shdr * symsec;
8285 Elf_Internal_Sym * symtab;
d79b3d50 8286 unsigned long nsyms;
c256ffe7 8287 unsigned long strtablen = 0;
2cf0635d 8288 char * strtab = NULL;
57346661 8289
dda8d76d 8290 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8291 if (symsec->sh_type != SHT_SYMTAB
8292 && symsec->sh_type != SHT_DYNSYM)
8293 continue;
8294
28d13567
AM
8295 if (!get_symtab (filedata, symsec,
8296 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8297 continue;
252b5132 8298
dda8d76d 8299 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8300 symtab, nsyms, strtab, strtablen,
a7fd1186 8301 rel_type,
bb4d2ac2 8302 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8303 free (strtab);
d79b3d50
NC
8304 free (symtab);
8305 }
8306 else
dda8d76d 8307 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8308 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8309
015dc7e1 8310 found = true;
252b5132
RH
8311 }
8312 }
8313
8314 if (! found)
45ac8f4f
NC
8315 {
8316 /* Users sometimes forget the -D option, so try to be helpful. */
8317 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8318 {
978c4450 8319 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8320 {
ca0e11aa
NC
8321 if (filedata->is_separate)
8322 printf (_("\nThere are no static relocations in linked file '%s'."),
8323 filedata->file_name);
8324 else
8325 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8326 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8327
8328 break;
8329 }
8330 }
8331 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8332 {
8333 if (filedata->is_separate)
8334 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8335 filedata->file_name);
8336 else
8337 printf (_("\nThere are no relocations in this file.\n"));
8338 }
45ac8f4f 8339 }
252b5132
RH
8340 }
8341
015dc7e1 8342 return true;
252b5132
RH
8343}
8344
4d6ed7c8
NC
8345/* An absolute address consists of a section and an offset. If the
8346 section is NULL, the offset itself is the address, otherwise, the
8347 address equals to LOAD_ADDRESS(section) + offset. */
8348
8349struct absaddr
948f632f
DA
8350{
8351 unsigned short section;
8352 bfd_vma offset;
8353};
4d6ed7c8 8354
948f632f
DA
8355/* Find the nearest symbol at or below ADDR. Returns the symbol
8356 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8357
4d6ed7c8 8358static void
dda8d76d
NC
8359find_symbol_for_address (Filedata * filedata,
8360 Elf_Internal_Sym * symtab,
8361 unsigned long nsyms,
8362 const char * strtab,
8363 unsigned long strtab_size,
8364 struct absaddr addr,
8365 const char ** symname,
8366 bfd_vma * offset)
4d6ed7c8 8367{
d3ba0551 8368 bfd_vma dist = 0x100000;
2cf0635d 8369 Elf_Internal_Sym * sym;
948f632f
DA
8370 Elf_Internal_Sym * beg;
8371 Elf_Internal_Sym * end;
2cf0635d 8372 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8373
0b6ae522 8374 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8375 beg = symtab;
8376 end = symtab + nsyms;
0b6ae522 8377
948f632f 8378 while (beg < end)
4d6ed7c8 8379 {
948f632f
DA
8380 bfd_vma value;
8381
8382 sym = beg + (end - beg) / 2;
0b6ae522 8383
948f632f 8384 value = sym->st_value;
0b6ae522
DJ
8385 REMOVE_ARCH_BITS (value);
8386
948f632f 8387 if (sym->st_name != 0
4d6ed7c8 8388 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8389 && addr.offset >= value
8390 && addr.offset - value < dist)
4d6ed7c8
NC
8391 {
8392 best = sym;
0b6ae522 8393 dist = addr.offset - value;
4d6ed7c8
NC
8394 if (!dist)
8395 break;
8396 }
948f632f
DA
8397
8398 if (addr.offset < value)
8399 end = sym;
8400 else
8401 beg = sym + 1;
4d6ed7c8 8402 }
1b31d05e 8403
4d6ed7c8
NC
8404 if (best)
8405 {
57346661 8406 *symname = (best->st_name >= strtab_size
2b692964 8407 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8408 *offset = dist;
8409 return;
8410 }
1b31d05e 8411
4d6ed7c8
NC
8412 *symname = NULL;
8413 *offset = addr.offset;
8414}
8415
32ec8896 8416static /* signed */ int
948f632f
DA
8417symcmp (const void *p, const void *q)
8418{
8419 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8420 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8421
8422 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8423}
8424
8425/* Process the unwind section. */
8426
8427#include "unwind-ia64.h"
8428
8429struct ia64_unw_table_entry
8430{
8431 struct absaddr start;
8432 struct absaddr end;
8433 struct absaddr info;
8434};
8435
8436struct ia64_unw_aux_info
8437{
32ec8896
NC
8438 struct ia64_unw_table_entry * table; /* Unwind table. */
8439 unsigned long table_len; /* Length of unwind table. */
8440 unsigned char * info; /* Unwind info. */
8441 unsigned long info_size; /* Size of unwind info. */
8442 bfd_vma info_addr; /* Starting address of unwind info. */
8443 bfd_vma seg_base; /* Starting address of segment. */
8444 Elf_Internal_Sym * symtab; /* The symbol table. */
8445 unsigned long nsyms; /* Number of symbols. */
8446 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8447 unsigned long nfuns; /* Number of entries in funtab. */
8448 char * strtab; /* The string table. */
8449 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8450};
8451
015dc7e1 8452static bool
dda8d76d 8453dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8454{
2cf0635d 8455 struct ia64_unw_table_entry * tp;
948f632f 8456 unsigned long j, nfuns;
4d6ed7c8 8457 int in_body;
015dc7e1 8458 bool res = true;
7036c0e1 8459
948f632f
DA
8460 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8461 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8462 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8463 aux->funtab[nfuns++] = aux->symtab[j];
8464 aux->nfuns = nfuns;
8465 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8466
4d6ed7c8
NC
8467 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8468 {
8469 bfd_vma stamp;
8470 bfd_vma offset;
2cf0635d
NC
8471 const unsigned char * dp;
8472 const unsigned char * head;
53774b7e 8473 const unsigned char * end;
2cf0635d 8474 const char * procname;
4d6ed7c8 8475
dda8d76d 8476 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8477 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8478
8479 fputs ("\n<", stdout);
8480
8481 if (procname)
8482 {
8483 fputs (procname, stdout);
8484
8485 if (offset)
8486 printf ("+%lx", (unsigned long) offset);
8487 }
8488
8489 fputs (">: [", stdout);
8490 print_vma (tp->start.offset, PREFIX_HEX);
8491 fputc ('-', stdout);
8492 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8493 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8494 (unsigned long) (tp->info.offset - aux->seg_base));
8495
53774b7e
NC
8496 /* PR 17531: file: 86232b32. */
8497 if (aux->info == NULL)
8498 continue;
8499
97c0a079
AM
8500 offset = tp->info.offset;
8501 if (tp->info.section)
8502 {
8503 if (tp->info.section >= filedata->file_header.e_shnum)
8504 {
8505 warn (_("Invalid section %u in table entry %ld\n"),
8506 tp->info.section, (long) (tp - aux->table));
015dc7e1 8507 res = false;
97c0a079
AM
8508 continue;
8509 }
8510 offset += filedata->section_headers[tp->info.section].sh_addr;
8511 }
8512 offset -= aux->info_addr;
53774b7e 8513 /* PR 17531: file: 0997b4d1. */
90679903
AM
8514 if (offset >= aux->info_size
8515 || aux->info_size - offset < 8)
53774b7e
NC
8516 {
8517 warn (_("Invalid offset %lx in table entry %ld\n"),
8518 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8519 res = false;
53774b7e
NC
8520 continue;
8521 }
8522
97c0a079 8523 head = aux->info + offset;
a4a00738 8524 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8525
86f55779 8526 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8527 (unsigned) UNW_VER (stamp),
8528 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8529 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8530 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8531 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8532
8533 if (UNW_VER (stamp) != 1)
8534 {
2b692964 8535 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8536 continue;
8537 }
8538
8539 in_body = 0;
53774b7e
NC
8540 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8541 /* PR 17531: file: 16ceda89. */
8542 if (end > aux->info + aux->info_size)
8543 end = aux->info + aux->info_size;
8544 for (dp = head + 8; dp < end;)
b4477bc8 8545 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8546 }
948f632f
DA
8547
8548 free (aux->funtab);
32ec8896
NC
8549
8550 return res;
4d6ed7c8
NC
8551}
8552
015dc7e1 8553static bool
dda8d76d
NC
8554slurp_ia64_unwind_table (Filedata * filedata,
8555 struct ia64_unw_aux_info * aux,
8556 Elf_Internal_Shdr * sec)
4d6ed7c8 8557{
89fac5e3 8558 unsigned long size, nrelas, i;
2cf0635d
NC
8559 Elf_Internal_Phdr * seg;
8560 struct ia64_unw_table_entry * tep;
8561 Elf_Internal_Shdr * relsec;
8562 Elf_Internal_Rela * rela;
8563 Elf_Internal_Rela * rp;
8564 unsigned char * table;
8565 unsigned char * tp;
8566 Elf_Internal_Sym * sym;
8567 const char * relname;
4d6ed7c8 8568
53774b7e
NC
8569 aux->table_len = 0;
8570
4d6ed7c8
NC
8571 /* First, find the starting address of the segment that includes
8572 this section: */
8573
dda8d76d 8574 if (filedata->file_header.e_phnum)
4d6ed7c8 8575 {
dda8d76d 8576 if (! get_program_headers (filedata))
015dc7e1 8577 return false;
4d6ed7c8 8578
dda8d76d
NC
8579 for (seg = filedata->program_headers;
8580 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8581 ++seg)
4d6ed7c8
NC
8582 {
8583 if (seg->p_type != PT_LOAD)
8584 continue;
8585
8586 if (sec->sh_addr >= seg->p_vaddr
8587 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8588 {
8589 aux->seg_base = seg->p_vaddr;
8590 break;
8591 }
8592 }
4d6ed7c8
NC
8593 }
8594
8595 /* Second, build the unwind table from the contents of the unwind section: */
8596 size = sec->sh_size;
dda8d76d 8597 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8598 _("unwind table"));
a6e9f9df 8599 if (!table)
015dc7e1 8600 return false;
4d6ed7c8 8601
53774b7e 8602 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8603 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8604 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8605 tep = aux->table;
53774b7e
NC
8606
8607 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8608 {
8609 tep->start.section = SHN_UNDEF;
8610 tep->end.section = SHN_UNDEF;
8611 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8612 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8613 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8614 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8615 tep->start.offset += aux->seg_base;
8616 tep->end.offset += aux->seg_base;
8617 tep->info.offset += aux->seg_base;
8618 }
8619 free (table);
8620
41e92641 8621 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8622 for (relsec = filedata->section_headers;
8623 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8624 ++relsec)
8625 {
8626 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8627 || relsec->sh_info >= filedata->file_header.e_shnum
8628 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8629 continue;
8630
dda8d76d 8631 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8632 & rela, & nrelas))
53774b7e
NC
8633 {
8634 free (aux->table);
8635 aux->table = NULL;
8636 aux->table_len = 0;
015dc7e1 8637 return false;
53774b7e 8638 }
4d6ed7c8
NC
8639
8640 for (rp = rela; rp < rela + nrelas; ++rp)
8641 {
4770fb94 8642 unsigned int sym_ndx;
726bd37d
AM
8643 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8644 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8645
82b1b41b
NC
8646 /* PR 17531: file: 9fa67536. */
8647 if (relname == NULL)
8648 {
726bd37d 8649 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8650 continue;
8651 }
948f632f 8652
24d127aa 8653 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8654 {
82b1b41b 8655 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8656 continue;
8657 }
8658
89fac5e3 8659 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8660
53774b7e
NC
8661 /* PR 17531: file: 5bc8d9bf. */
8662 if (i >= aux->table_len)
8663 {
8664 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8665 continue;
8666 }
8667
4770fb94
AM
8668 sym_ndx = get_reloc_symindex (rp->r_info);
8669 if (sym_ndx >= aux->nsyms)
8670 {
8671 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8672 sym_ndx);
8673 continue;
8674 }
8675 sym = aux->symtab + sym_ndx;
8676
53774b7e 8677 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8678 {
8679 case 0:
8680 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8681 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8682 break;
8683 case 1:
8684 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8685 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8686 break;
8687 case 2:
8688 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8689 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8690 break;
8691 default:
8692 break;
8693 }
8694 }
8695
8696 free (rela);
8697 }
8698
015dc7e1 8699 return true;
4d6ed7c8
NC
8700}
8701
015dc7e1 8702static bool
dda8d76d 8703ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8704{
2cf0635d
NC
8705 Elf_Internal_Shdr * sec;
8706 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8707 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8708 struct ia64_unw_aux_info aux;
015dc7e1 8709 bool res = true;
f1467e33 8710
4d6ed7c8
NC
8711 memset (& aux, 0, sizeof (aux));
8712
dda8d76d 8713 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8714 {
28d13567 8715 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8716 {
28d13567 8717 if (aux.symtab)
4082ef84 8718 {
28d13567
AM
8719 error (_("Multiple symbol tables encountered\n"));
8720 free (aux.symtab);
8721 aux.symtab = NULL;
4082ef84 8722 free (aux.strtab);
28d13567 8723 aux.strtab = NULL;
4082ef84 8724 }
28d13567
AM
8725 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8726 &aux.strtab, &aux.strtab_size))
015dc7e1 8727 return false;
4d6ed7c8
NC
8728 }
8729 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8730 unwcount++;
8731 }
8732
8733 if (!unwcount)
8734 printf (_("\nThere are no unwind sections in this file.\n"));
8735
8736 while (unwcount-- > 0)
8737 {
84714f86 8738 const char *suffix;
579f31ac
JJ
8739 size_t len, len2;
8740
dda8d76d
NC
8741 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8742 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8743 if (sec->sh_type == SHT_IA_64_UNWIND)
8744 {
8745 unwsec = sec;
8746 break;
8747 }
4082ef84
NC
8748 /* We have already counted the number of SHT_IA64_UNWIND
8749 sections so the loop above should never fail. */
8750 assert (unwsec != NULL);
579f31ac
JJ
8751
8752 unwstart = i + 1;
8753 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8754
e4b17d5c
L
8755 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8756 {
8757 /* We need to find which section group it is in. */
4082ef84 8758 struct group_list * g;
e4b17d5c 8759
978c4450
AM
8760 if (filedata->section_headers_groups == NULL
8761 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8762 i = filedata->file_header.e_shnum;
4082ef84 8763 else
e4b17d5c 8764 {
978c4450 8765 g = filedata->section_headers_groups[i]->root;
18bd398b 8766
4082ef84
NC
8767 for (; g != NULL; g = g->next)
8768 {
dda8d76d 8769 sec = filedata->section_headers + g->section_index;
e4b17d5c 8770
84714f86
AM
8771 if (section_name_valid (filedata, sec)
8772 && streq (section_name (filedata, sec),
8773 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8774 break;
8775 }
8776
8777 if (g == NULL)
dda8d76d 8778 i = filedata->file_header.e_shnum;
4082ef84 8779 }
e4b17d5c 8780 }
84714f86
AM
8781 else if (section_name_valid (filedata, unwsec)
8782 && startswith (section_name (filedata, unwsec),
e9b095a5 8783 ELF_STRING_ia64_unwind_once))
579f31ac 8784 {
18bd398b 8785 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8786 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8787 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8788 for (i = 0, sec = filedata->section_headers;
8789 i < filedata->file_header.e_shnum;
579f31ac 8790 ++i, ++sec)
84714f86
AM
8791 if (section_name_valid (filedata, sec)
8792 && startswith (section_name (filedata, sec),
e9b095a5 8793 ELF_STRING_ia64_unwind_info_once)
84714f86 8794 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8795 break;
8796 }
8797 else
8798 {
8799 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8800 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8801 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8802 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8803 suffix = "";
84714f86
AM
8804 if (section_name_valid (filedata, unwsec)
8805 && startswith (section_name (filedata, unwsec),
8806 ELF_STRING_ia64_unwind))
8807 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8808 for (i = 0, sec = filedata->section_headers;
8809 i < filedata->file_header.e_shnum;
579f31ac 8810 ++i, ++sec)
84714f86
AM
8811 if (section_name_valid (filedata, sec)
8812 && startswith (section_name (filedata, sec),
8813 ELF_STRING_ia64_unwind_info)
8814 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8815 break;
8816 }
8817
dda8d76d 8818 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8819 {
8820 printf (_("\nCould not find unwind info section for "));
8821
dda8d76d 8822 if (filedata->string_table == NULL)
579f31ac
JJ
8823 printf ("%d", unwsec->sh_name);
8824 else
dda8d76d 8825 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8826 }
8827 else
4d6ed7c8 8828 {
4d6ed7c8 8829 aux.info_addr = sec->sh_addr;
dda8d76d 8830 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8831 sec->sh_size,
8832 _("unwind info"));
59245841 8833 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8834
579f31ac 8835 printf (_("\nUnwind section "));
4d6ed7c8 8836
dda8d76d 8837 if (filedata->string_table == NULL)
579f31ac
JJ
8838 printf ("%d", unwsec->sh_name);
8839 else
dda8d76d 8840 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8841
579f31ac 8842 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8843 (unsigned long) unwsec->sh_offset,
89fac5e3 8844 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8845
dda8d76d 8846 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8847 && aux.table_len > 0)
dda8d76d 8848 dump_ia64_unwind (filedata, & aux);
579f31ac 8849
9db70fc3
AM
8850 free ((char *) aux.table);
8851 free ((char *) aux.info);
579f31ac
JJ
8852 aux.table = NULL;
8853 aux.info = NULL;
8854 }
4d6ed7c8 8855 }
4d6ed7c8 8856
9db70fc3
AM
8857 free (aux.symtab);
8858 free ((char *) aux.strtab);
32ec8896
NC
8859
8860 return res;
4d6ed7c8
NC
8861}
8862
3f5e193b 8863struct hppa_unw_table_entry
32ec8896
NC
8864{
8865 struct absaddr start;
8866 struct absaddr end;
8867 unsigned int Cannot_unwind:1; /* 0 */
8868 unsigned int Millicode:1; /* 1 */
8869 unsigned int Millicode_save_sr0:1; /* 2 */
8870 unsigned int Region_description:2; /* 3..4 */
8871 unsigned int reserved1:1; /* 5 */
8872 unsigned int Entry_SR:1; /* 6 */
8873 unsigned int Entry_FR:4; /* Number saved 7..10 */
8874 unsigned int Entry_GR:5; /* Number saved 11..15 */
8875 unsigned int Args_stored:1; /* 16 */
8876 unsigned int Variable_Frame:1; /* 17 */
8877 unsigned int Separate_Package_Body:1; /* 18 */
8878 unsigned int Frame_Extension_Millicode:1; /* 19 */
8879 unsigned int Stack_Overflow_Check:1; /* 20 */
8880 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8881 unsigned int Ada_Region:1; /* 22 */
8882 unsigned int cxx_info:1; /* 23 */
8883 unsigned int cxx_try_catch:1; /* 24 */
8884 unsigned int sched_entry_seq:1; /* 25 */
8885 unsigned int reserved2:1; /* 26 */
8886 unsigned int Save_SP:1; /* 27 */
8887 unsigned int Save_RP:1; /* 28 */
8888 unsigned int Save_MRP_in_frame:1; /* 29 */
8889 unsigned int extn_ptr_defined:1; /* 30 */
8890 unsigned int Cleanup_defined:1; /* 31 */
8891
8892 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8893 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8894 unsigned int Large_frame:1; /* 2 */
8895 unsigned int Pseudo_SP_Set:1; /* 3 */
8896 unsigned int reserved4:1; /* 4 */
8897 unsigned int Total_frame_size:27; /* 5..31 */
8898};
3f5e193b 8899
57346661 8900struct hppa_unw_aux_info
948f632f 8901{
32ec8896
NC
8902 struct hppa_unw_table_entry * table; /* Unwind table. */
8903 unsigned long table_len; /* Length of unwind table. */
8904 bfd_vma seg_base; /* Starting address of segment. */
8905 Elf_Internal_Sym * symtab; /* The symbol table. */
8906 unsigned long nsyms; /* Number of symbols. */
8907 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8908 unsigned long nfuns; /* Number of entries in funtab. */
8909 char * strtab; /* The string table. */
8910 unsigned long strtab_size; /* Size of string table. */
948f632f 8911};
57346661 8912
015dc7e1 8913static bool
dda8d76d 8914dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8915{
2cf0635d 8916 struct hppa_unw_table_entry * tp;
948f632f 8917 unsigned long j, nfuns;
015dc7e1 8918 bool res = true;
948f632f
DA
8919
8920 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8921 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8922 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8923 aux->funtab[nfuns++] = aux->symtab[j];
8924 aux->nfuns = nfuns;
8925 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8926
57346661
AM
8927 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8928 {
8929 bfd_vma offset;
2cf0635d 8930 const char * procname;
57346661 8931
dda8d76d 8932 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8933 aux->strtab_size, tp->start, &procname,
8934 &offset);
8935
8936 fputs ("\n<", stdout);
8937
8938 if (procname)
8939 {
8940 fputs (procname, stdout);
8941
8942 if (offset)
8943 printf ("+%lx", (unsigned long) offset);
8944 }
8945
8946 fputs (">: [", stdout);
8947 print_vma (tp->start.offset, PREFIX_HEX);
8948 fputc ('-', stdout);
8949 print_vma (tp->end.offset, PREFIX_HEX);
8950 printf ("]\n\t");
8951
18bd398b
NC
8952#define PF(_m) if (tp->_m) printf (#_m " ");
8953#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8954 PF(Cannot_unwind);
8955 PF(Millicode);
8956 PF(Millicode_save_sr0);
18bd398b 8957 /* PV(Region_description); */
57346661
AM
8958 PF(Entry_SR);
8959 PV(Entry_FR);
8960 PV(Entry_GR);
8961 PF(Args_stored);
8962 PF(Variable_Frame);
8963 PF(Separate_Package_Body);
8964 PF(Frame_Extension_Millicode);
8965 PF(Stack_Overflow_Check);
8966 PF(Two_Instruction_SP_Increment);
8967 PF(Ada_Region);
8968 PF(cxx_info);
8969 PF(cxx_try_catch);
8970 PF(sched_entry_seq);
8971 PF(Save_SP);
8972 PF(Save_RP);
8973 PF(Save_MRP_in_frame);
8974 PF(extn_ptr_defined);
8975 PF(Cleanup_defined);
8976 PF(MPE_XL_interrupt_marker);
8977 PF(HP_UX_interrupt_marker);
8978 PF(Large_frame);
8979 PF(Pseudo_SP_Set);
8980 PV(Total_frame_size);
8981#undef PF
8982#undef PV
8983 }
8984
18bd398b 8985 printf ("\n");
948f632f
DA
8986
8987 free (aux->funtab);
32ec8896
NC
8988
8989 return res;
57346661
AM
8990}
8991
015dc7e1 8992static bool
dda8d76d
NC
8993slurp_hppa_unwind_table (Filedata * filedata,
8994 struct hppa_unw_aux_info * aux,
8995 Elf_Internal_Shdr * sec)
57346661 8996{
1c0751b2 8997 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8998 Elf_Internal_Phdr * seg;
8999 struct hppa_unw_table_entry * tep;
9000 Elf_Internal_Shdr * relsec;
9001 Elf_Internal_Rela * rela;
9002 Elf_Internal_Rela * rp;
9003 unsigned char * table;
9004 unsigned char * tp;
9005 Elf_Internal_Sym * sym;
9006 const char * relname;
57346661 9007
57346661
AM
9008 /* First, find the starting address of the segment that includes
9009 this section. */
dda8d76d 9010 if (filedata->file_header.e_phnum)
57346661 9011 {
dda8d76d 9012 if (! get_program_headers (filedata))
015dc7e1 9013 return false;
57346661 9014
dda8d76d
NC
9015 for (seg = filedata->program_headers;
9016 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9017 ++seg)
9018 {
9019 if (seg->p_type != PT_LOAD)
9020 continue;
9021
9022 if (sec->sh_addr >= seg->p_vaddr
9023 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9024 {
9025 aux->seg_base = seg->p_vaddr;
9026 break;
9027 }
9028 }
9029 }
9030
9031 /* Second, build the unwind table from the contents of the unwind
9032 section. */
9033 size = sec->sh_size;
dda8d76d 9034 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9035 _("unwind table"));
57346661 9036 if (!table)
015dc7e1 9037 return false;
57346661 9038
1c0751b2
DA
9039 unw_ent_size = 16;
9040 nentries = size / unw_ent_size;
9041 size = unw_ent_size * nentries;
57346661 9042
e3fdc001 9043 aux->table_len = nentries;
3f5e193b
NC
9044 tep = aux->table = (struct hppa_unw_table_entry *)
9045 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9046
1c0751b2 9047 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9048 {
9049 unsigned int tmp1, tmp2;
9050
9051 tep->start.section = SHN_UNDEF;
9052 tep->end.section = SHN_UNDEF;
9053
1c0751b2
DA
9054 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9055 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9056 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9057 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9058
9059 tep->start.offset += aux->seg_base;
9060 tep->end.offset += aux->seg_base;
57346661
AM
9061
9062 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9063 tep->Millicode = (tmp1 >> 30) & 0x1;
9064 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9065 tep->Region_description = (tmp1 >> 27) & 0x3;
9066 tep->reserved1 = (tmp1 >> 26) & 0x1;
9067 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9068 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9069 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9070 tep->Args_stored = (tmp1 >> 15) & 0x1;
9071 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9072 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9073 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9074 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9075 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9076 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9077 tep->cxx_info = (tmp1 >> 8) & 0x1;
9078 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9079 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9080 tep->reserved2 = (tmp1 >> 5) & 0x1;
9081 tep->Save_SP = (tmp1 >> 4) & 0x1;
9082 tep->Save_RP = (tmp1 >> 3) & 0x1;
9083 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9084 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9085 tep->Cleanup_defined = tmp1 & 0x1;
9086
9087 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9088 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9089 tep->Large_frame = (tmp2 >> 29) & 0x1;
9090 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9091 tep->reserved4 = (tmp2 >> 27) & 0x1;
9092 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9093 }
9094 free (table);
9095
9096 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9097 for (relsec = filedata->section_headers;
9098 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9099 ++relsec)
9100 {
9101 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9102 || relsec->sh_info >= filedata->file_header.e_shnum
9103 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9104 continue;
9105
dda8d76d 9106 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9107 & rela, & nrelas))
015dc7e1 9108 return false;
57346661
AM
9109
9110 for (rp = rela; rp < rela + nrelas; ++rp)
9111 {
4770fb94 9112 unsigned int sym_ndx;
726bd37d
AM
9113 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9114 relname = elf_hppa_reloc_type (r_type);
57346661 9115
726bd37d
AM
9116 if (relname == NULL)
9117 {
9118 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9119 continue;
9120 }
9121
57346661 9122 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9123 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9124 {
726bd37d 9125 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9126 continue;
9127 }
9128
9129 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9130 if (i >= aux->table_len)
9131 {
9132 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9133 continue;
9134 }
57346661 9135
4770fb94
AM
9136 sym_ndx = get_reloc_symindex (rp->r_info);
9137 if (sym_ndx >= aux->nsyms)
9138 {
9139 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9140 sym_ndx);
9141 continue;
9142 }
9143 sym = aux->symtab + sym_ndx;
9144
43f6cd05 9145 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9146 {
9147 case 0:
9148 aux->table[i].start.section = sym->st_shndx;
1e456d54 9149 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9150 break;
9151 case 1:
9152 aux->table[i].end.section = sym->st_shndx;
1e456d54 9153 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9154 break;
9155 default:
9156 break;
9157 }
9158 }
9159
9160 free (rela);
9161 }
9162
015dc7e1 9163 return true;
57346661
AM
9164}
9165
015dc7e1 9166static bool
dda8d76d 9167hppa_process_unwind (Filedata * filedata)
57346661 9168{
57346661 9169 struct hppa_unw_aux_info aux;
2cf0635d 9170 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9171 Elf_Internal_Shdr * sec;
18bd398b 9172 unsigned long i;
015dc7e1 9173 bool res = true;
57346661 9174
dda8d76d 9175 if (filedata->string_table == NULL)
015dc7e1 9176 return false;
1b31d05e
NC
9177
9178 memset (& aux, 0, sizeof (aux));
57346661 9179
dda8d76d 9180 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9181 {
28d13567 9182 if (sec->sh_type == SHT_SYMTAB)
57346661 9183 {
28d13567 9184 if (aux.symtab)
4082ef84 9185 {
28d13567
AM
9186 error (_("Multiple symbol tables encountered\n"));
9187 free (aux.symtab);
9188 aux.symtab = NULL;
4082ef84 9189 free (aux.strtab);
28d13567 9190 aux.strtab = NULL;
4082ef84 9191 }
28d13567
AM
9192 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9193 &aux.strtab, &aux.strtab_size))
015dc7e1 9194 return false;
57346661 9195 }
84714f86
AM
9196 else if (section_name_valid (filedata, sec)
9197 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9198 unwsec = sec;
9199 }
9200
9201 if (!unwsec)
9202 printf (_("\nThere are no unwind sections in this file.\n"));
9203
dda8d76d 9204 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9205 {
84714f86
AM
9206 if (section_name_valid (filedata, sec)
9207 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9208 {
43f6cd05 9209 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9210
d3a49aa8
AM
9211 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9212 "contains %lu entry:\n",
9213 "\nUnwind section '%s' at offset 0x%lx "
9214 "contains %lu entries:\n",
9215 num_unwind),
dda8d76d 9216 printable_section_name (filedata, sec),
57346661 9217 (unsigned long) sec->sh_offset,
d3a49aa8 9218 num_unwind);
57346661 9219
dda8d76d 9220 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9221 res = false;
66b09c7e
S
9222
9223 if (res && aux.table_len > 0)
32ec8896 9224 {
dda8d76d 9225 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9226 res = false;
32ec8896 9227 }
57346661 9228
9db70fc3 9229 free ((char *) aux.table);
57346661
AM
9230 aux.table = NULL;
9231 }
9232 }
9233
9db70fc3
AM
9234 free (aux.symtab);
9235 free ((char *) aux.strtab);
32ec8896
NC
9236
9237 return res;
57346661
AM
9238}
9239
0b6ae522
DJ
9240struct arm_section
9241{
a734115a
NC
9242 unsigned char * data; /* The unwind data. */
9243 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9244 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9245 unsigned long nrelas; /* The number of relocations. */
9246 unsigned int rel_type; /* REL or RELA ? */
9247 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9248};
9249
9250struct arm_unw_aux_info
9251{
dda8d76d 9252 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9253 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9254 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9255 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9256 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9257 char * strtab; /* The file's string table. */
9258 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9259};
9260
9261static const char *
dda8d76d
NC
9262arm_print_vma_and_name (Filedata * filedata,
9263 struct arm_unw_aux_info * aux,
9264 bfd_vma fn,
9265 struct absaddr addr)
0b6ae522
DJ
9266{
9267 const char *procname;
9268 bfd_vma sym_offset;
9269
9270 if (addr.section == SHN_UNDEF)
9271 addr.offset = fn;
9272
dda8d76d 9273 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9274 aux->strtab_size, addr, &procname,
9275 &sym_offset);
9276
9277 print_vma (fn, PREFIX_HEX);
9278
9279 if (procname)
9280 {
9281 fputs (" <", stdout);
9282 fputs (procname, stdout);
9283
9284 if (sym_offset)
9285 printf ("+0x%lx", (unsigned long) sym_offset);
9286 fputc ('>', stdout);
9287 }
9288
9289 return procname;
9290}
9291
9292static void
9293arm_free_section (struct arm_section *arm_sec)
9294{
9db70fc3
AM
9295 free (arm_sec->data);
9296 free (arm_sec->rela);
0b6ae522
DJ
9297}
9298
a734115a
NC
9299/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9300 cached section and install SEC instead.
9301 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9302 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9303 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9304 relocation's offset in ADDR.
1b31d05e
NC
9305 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9306 into the string table of the symbol associated with the reloc. If no
9307 reloc was applied store -1 there.
9308 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9309
015dc7e1 9310static bool
dda8d76d
NC
9311get_unwind_section_word (Filedata * filedata,
9312 struct arm_unw_aux_info * aux,
1b31d05e
NC
9313 struct arm_section * arm_sec,
9314 Elf_Internal_Shdr * sec,
9315 bfd_vma word_offset,
9316 unsigned int * wordp,
9317 struct absaddr * addr,
9318 bfd_vma * sym_name)
0b6ae522
DJ
9319{
9320 Elf_Internal_Rela *rp;
9321 Elf_Internal_Sym *sym;
9322 const char * relname;
9323 unsigned int word;
015dc7e1 9324 bool wrapped;
0b6ae522 9325
e0a31db1 9326 if (sec == NULL || arm_sec == NULL)
015dc7e1 9327 return false;
e0a31db1 9328
0b6ae522
DJ
9329 addr->section = SHN_UNDEF;
9330 addr->offset = 0;
9331
1b31d05e
NC
9332 if (sym_name != NULL)
9333 *sym_name = (bfd_vma) -1;
9334
a734115a 9335 /* If necessary, update the section cache. */
0b6ae522
DJ
9336 if (sec != arm_sec->sec)
9337 {
9338 Elf_Internal_Shdr *relsec;
9339
9340 arm_free_section (arm_sec);
9341
9342 arm_sec->sec = sec;
dda8d76d 9343 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9344 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9345 arm_sec->rela = NULL;
9346 arm_sec->nrelas = 0;
9347
dda8d76d
NC
9348 for (relsec = filedata->section_headers;
9349 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9350 ++relsec)
9351 {
dda8d76d
NC
9352 if (relsec->sh_info >= filedata->file_header.e_shnum
9353 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9354 /* PR 15745: Check the section type as well. */
9355 || (relsec->sh_type != SHT_REL
9356 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9357 continue;
9358
a734115a 9359 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9360 if (relsec->sh_type == SHT_REL)
9361 {
dda8d76d 9362 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9363 relsec->sh_size,
9364 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9365 return false;
0b6ae522 9366 }
1ae40aa4 9367 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9368 {
dda8d76d 9369 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9370 relsec->sh_size,
9371 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9372 return false;
0b6ae522 9373 }
1ae40aa4 9374 break;
0b6ae522
DJ
9375 }
9376
9377 arm_sec->next_rela = arm_sec->rela;
9378 }
9379
a734115a 9380 /* If there is no unwind data we can do nothing. */
0b6ae522 9381 if (arm_sec->data == NULL)
015dc7e1 9382 return false;
0b6ae522 9383
e0a31db1 9384 /* If the offset is invalid then fail. */
f32ba729
NC
9385 if (/* PR 21343 *//* PR 18879 */
9386 sec->sh_size < 4
9387 || word_offset > (sec->sh_size - 4)
1a915552 9388 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9389 return false;
e0a31db1 9390
a734115a 9391 /* Get the word at the required offset. */
0b6ae522
DJ
9392 word = byte_get (arm_sec->data + word_offset, 4);
9393
0eff7165
NC
9394 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9395 if (arm_sec->rela == NULL)
9396 {
9397 * wordp = word;
015dc7e1 9398 return true;
0eff7165
NC
9399 }
9400
a734115a 9401 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9402 wrapped = false;
0b6ae522
DJ
9403 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9404 {
9405 bfd_vma prelval, offset;
9406
9407 if (rp->r_offset > word_offset && !wrapped)
9408 {
9409 rp = arm_sec->rela;
015dc7e1 9410 wrapped = true;
0b6ae522
DJ
9411 }
9412 if (rp->r_offset > word_offset)
9413 break;
9414
9415 if (rp->r_offset & 3)
9416 {
9417 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9418 (unsigned long) rp->r_offset);
9419 continue;
9420 }
9421
9422 if (rp->r_offset < word_offset)
9423 continue;
9424
74e1a04b
NC
9425 /* PR 17531: file: 027-161405-0.004 */
9426 if (aux->symtab == NULL)
9427 continue;
9428
0b6ae522
DJ
9429 if (arm_sec->rel_type == SHT_REL)
9430 {
9431 offset = word & 0x7fffffff;
9432 if (offset & 0x40000000)
9433 offset |= ~ (bfd_vma) 0x7fffffff;
9434 }
a734115a 9435 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9436 offset = rp->r_addend;
a734115a 9437 else
74e1a04b
NC
9438 {
9439 error (_("Unknown section relocation type %d encountered\n"),
9440 arm_sec->rel_type);
9441 break;
9442 }
0b6ae522 9443
071436c6
NC
9444 /* PR 17531 file: 027-1241568-0.004. */
9445 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9446 {
9447 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9448 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9449 break;
9450 }
9451
9452 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9453 offset += sym->st_value;
9454 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9455
a734115a 9456 /* Check that we are processing the expected reloc type. */
dda8d76d 9457 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9458 {
9459 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9460 if (relname == NULL)
9461 {
9462 warn (_("Skipping unknown ARM relocation type: %d\n"),
9463 (int) ELF32_R_TYPE (rp->r_info));
9464 continue;
9465 }
a734115a
NC
9466
9467 if (streq (relname, "R_ARM_NONE"))
9468 continue;
0b4362b0 9469
a734115a
NC
9470 if (! streq (relname, "R_ARM_PREL31"))
9471 {
071436c6 9472 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9473 continue;
9474 }
9475 }
dda8d76d 9476 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9477 {
9478 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9479 if (relname == NULL)
9480 {
9481 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9482 (int) ELF32_R_TYPE (rp->r_info));
9483 continue;
9484 }
0b4362b0 9485
a734115a
NC
9486 if (streq (relname, "R_C6000_NONE"))
9487 continue;
9488
9489 if (! streq (relname, "R_C6000_PREL31"))
9490 {
071436c6 9491 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9492 continue;
9493 }
9494
9495 prelval >>= 1;
9496 }
9497 else
74e1a04b
NC
9498 {
9499 /* This function currently only supports ARM and TI unwinders. */
9500 warn (_("Only TI and ARM unwinders are currently supported\n"));
9501 break;
9502 }
fa197c1c 9503
0b6ae522
DJ
9504 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9505 addr->section = sym->st_shndx;
9506 addr->offset = offset;
74e1a04b 9507
1b31d05e
NC
9508 if (sym_name)
9509 * sym_name = sym->st_name;
0b6ae522
DJ
9510 break;
9511 }
9512
9513 *wordp = word;
9514 arm_sec->next_rela = rp;
9515
015dc7e1 9516 return true;
0b6ae522
DJ
9517}
9518
a734115a
NC
9519static const char *tic6x_unwind_regnames[16] =
9520{
0b4362b0
RM
9521 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9522 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9523 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9524};
fa197c1c 9525
0b6ae522 9526static void
fa197c1c 9527decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9528{
fa197c1c
PB
9529 int i;
9530
9531 for (i = 12; mask; mask >>= 1, i--)
9532 {
9533 if (mask & 1)
9534 {
9535 fputs (tic6x_unwind_regnames[i], stdout);
9536 if (mask > 1)
9537 fputs (", ", stdout);
9538 }
9539 }
9540}
0b6ae522
DJ
9541
9542#define ADVANCE \
9543 if (remaining == 0 && more_words) \
9544 { \
9545 data_offset += 4; \
dda8d76d 9546 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9547 data_offset, & word, & addr, NULL)) \
015dc7e1 9548 return false; \
0b6ae522
DJ
9549 remaining = 4; \
9550 more_words--; \
9551 } \
9552
9553#define GET_OP(OP) \
9554 ADVANCE; \
9555 if (remaining) \
9556 { \
9557 remaining--; \
9558 (OP) = word >> 24; \
9559 word <<= 8; \
9560 } \
9561 else \
9562 { \
2b692964 9563 printf (_("[Truncated opcode]\n")); \
015dc7e1 9564 return false; \
0b6ae522 9565 } \
cc5914eb 9566 printf ("0x%02x ", OP)
0b6ae522 9567
015dc7e1 9568static bool
dda8d76d
NC
9569decode_arm_unwind_bytecode (Filedata * filedata,
9570 struct arm_unw_aux_info * aux,
948f632f
DA
9571 unsigned int word,
9572 unsigned int remaining,
9573 unsigned int more_words,
9574 bfd_vma data_offset,
9575 Elf_Internal_Shdr * data_sec,
9576 struct arm_section * data_arm_sec)
fa197c1c
PB
9577{
9578 struct absaddr addr;
015dc7e1 9579 bool res = true;
0b6ae522
DJ
9580
9581 /* Decode the unwinding instructions. */
9582 while (1)
9583 {
9584 unsigned int op, op2;
9585
9586 ADVANCE;
9587 if (remaining == 0)
9588 break;
9589 remaining--;
9590 op = word >> 24;
9591 word <<= 8;
9592
cc5914eb 9593 printf (" 0x%02x ", op);
0b6ae522
DJ
9594
9595 if ((op & 0xc0) == 0x00)
9596 {
9597 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9598
cc5914eb 9599 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9600 }
9601 else if ((op & 0xc0) == 0x40)
9602 {
9603 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9604
cc5914eb 9605 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9606 }
9607 else if ((op & 0xf0) == 0x80)
9608 {
9609 GET_OP (op2);
9610 if (op == 0x80 && op2 == 0)
9611 printf (_("Refuse to unwind"));
9612 else
9613 {
9614 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9615 bool first = true;
0b6ae522 9616 int i;
2b692964 9617
0b6ae522
DJ
9618 printf ("pop {");
9619 for (i = 0; i < 12; i++)
9620 if (mask & (1 << i))
9621 {
9622 if (first)
015dc7e1 9623 first = false;
0b6ae522
DJ
9624 else
9625 printf (", ");
9626 printf ("r%d", 4 + i);
9627 }
9628 printf ("}");
9629 }
9630 }
9631 else if ((op & 0xf0) == 0x90)
9632 {
9633 if (op == 0x9d || op == 0x9f)
9634 printf (_(" [Reserved]"));
9635 else
cc5914eb 9636 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9637 }
9638 else if ((op & 0xf0) == 0xa0)
9639 {
9640 int end = 4 + (op & 0x07);
015dc7e1 9641 bool first = true;
0b6ae522 9642 int i;
61865e30 9643
0b6ae522
DJ
9644 printf (" pop {");
9645 for (i = 4; i <= end; i++)
9646 {
9647 if (first)
015dc7e1 9648 first = false;
0b6ae522
DJ
9649 else
9650 printf (", ");
9651 printf ("r%d", i);
9652 }
9653 if (op & 0x08)
9654 {
1b31d05e 9655 if (!first)
0b6ae522
DJ
9656 printf (", ");
9657 printf ("r14");
9658 }
9659 printf ("}");
9660 }
9661 else if (op == 0xb0)
9662 printf (_(" finish"));
9663 else if (op == 0xb1)
9664 {
9665 GET_OP (op2);
9666 if (op2 == 0 || (op2 & 0xf0) != 0)
9667 printf (_("[Spare]"));
9668 else
9669 {
9670 unsigned int mask = op2 & 0x0f;
015dc7e1 9671 bool first = true;
0b6ae522 9672 int i;
61865e30 9673
0b6ae522
DJ
9674 printf ("pop {");
9675 for (i = 0; i < 12; i++)
9676 if (mask & (1 << i))
9677 {
9678 if (first)
015dc7e1 9679 first = false;
0b6ae522
DJ
9680 else
9681 printf (", ");
9682 printf ("r%d", i);
9683 }
9684 printf ("}");
9685 }
9686 }
9687 else if (op == 0xb2)
9688 {
b115cf96 9689 unsigned char buf[9];
0b6ae522
DJ
9690 unsigned int i, len;
9691 unsigned long offset;
61865e30 9692
b115cf96 9693 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9694 {
9695 GET_OP (buf[i]);
9696 if ((buf[i] & 0x80) == 0)
9697 break;
9698 }
4082ef84 9699 if (i == sizeof (buf))
32ec8896 9700 {
27a45f42 9701 error (_("corrupt change to vsp\n"));
015dc7e1 9702 res = false;
32ec8896 9703 }
4082ef84
NC
9704 else
9705 {
015dc7e1 9706 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9707 assert (len == i + 1);
9708 offset = offset * 4 + 0x204;
9709 printf ("vsp = vsp + %ld", offset);
9710 }
0b6ae522 9711 }
61865e30 9712 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9713 {
61865e30
NC
9714 unsigned int first, last;
9715
9716 GET_OP (op2);
9717 first = op2 >> 4;
9718 last = op2 & 0x0f;
9719 if (op == 0xc8)
9720 first = first + 16;
9721 printf ("pop {D%d", first);
9722 if (last)
9723 printf ("-D%d", first + last);
9724 printf ("}");
9725 }
09854a88
TB
9726 else if (op == 0xb4)
9727 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9728 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9729 {
9730 unsigned int count = op & 0x07;
9731
9732 printf ("pop {D8");
9733 if (count)
9734 printf ("-D%d", 8 + count);
9735 printf ("}");
9736 }
9737 else if (op >= 0xc0 && op <= 0xc5)
9738 {
9739 unsigned int count = op & 0x07;
9740
9741 printf (" pop {wR10");
9742 if (count)
9743 printf ("-wR%d", 10 + count);
9744 printf ("}");
9745 }
9746 else if (op == 0xc6)
9747 {
9748 unsigned int first, last;
9749
9750 GET_OP (op2);
9751 first = op2 >> 4;
9752 last = op2 & 0x0f;
9753 printf ("pop {wR%d", first);
9754 if (last)
9755 printf ("-wR%d", first + last);
9756 printf ("}");
9757 }
9758 else if (op == 0xc7)
9759 {
9760 GET_OP (op2);
9761 if (op2 == 0 || (op2 & 0xf0) != 0)
9762 printf (_("[Spare]"));
0b6ae522
DJ
9763 else
9764 {
61865e30 9765 unsigned int mask = op2 & 0x0f;
015dc7e1 9766 bool first = true;
61865e30
NC
9767 int i;
9768
9769 printf ("pop {");
9770 for (i = 0; i < 4; i++)
9771 if (mask & (1 << i))
9772 {
9773 if (first)
015dc7e1 9774 first = false;
61865e30
NC
9775 else
9776 printf (", ");
9777 printf ("wCGR%d", i);
9778 }
9779 printf ("}");
0b6ae522
DJ
9780 }
9781 }
61865e30 9782 else
32ec8896
NC
9783 {
9784 printf (_(" [unsupported opcode]"));
015dc7e1 9785 res = false;
32ec8896
NC
9786 }
9787
0b6ae522
DJ
9788 printf ("\n");
9789 }
32ec8896
NC
9790
9791 return res;
fa197c1c
PB
9792}
9793
015dc7e1 9794static bool
dda8d76d
NC
9795decode_tic6x_unwind_bytecode (Filedata * filedata,
9796 struct arm_unw_aux_info * aux,
948f632f
DA
9797 unsigned int word,
9798 unsigned int remaining,
9799 unsigned int more_words,
9800 bfd_vma data_offset,
9801 Elf_Internal_Shdr * data_sec,
9802 struct arm_section * data_arm_sec)
fa197c1c
PB
9803{
9804 struct absaddr addr;
9805
9806 /* Decode the unwinding instructions. */
9807 while (1)
9808 {
9809 unsigned int op, op2;
9810
9811 ADVANCE;
9812 if (remaining == 0)
9813 break;
9814 remaining--;
9815 op = word >> 24;
9816 word <<= 8;
9817
9cf03b7e 9818 printf (" 0x%02x ", op);
fa197c1c
PB
9819
9820 if ((op & 0xc0) == 0x00)
9821 {
9822 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9823 printf (" sp = sp + %d", offset);
fa197c1c
PB
9824 }
9825 else if ((op & 0xc0) == 0x80)
9826 {
9827 GET_OP (op2);
9828 if (op == 0x80 && op2 == 0)
9829 printf (_("Refuse to unwind"));
9830 else
9831 {
9832 unsigned int mask = ((op & 0x1f) << 8) | op2;
9833 if (op & 0x20)
9834 printf ("pop compact {");
9835 else
9836 printf ("pop {");
9837
9838 decode_tic6x_unwind_regmask (mask);
9839 printf("}");
9840 }
9841 }
9842 else if ((op & 0xf0) == 0xc0)
9843 {
9844 unsigned int reg;
9845 unsigned int nregs;
9846 unsigned int i;
9847 const char *name;
a734115a
NC
9848 struct
9849 {
32ec8896
NC
9850 unsigned int offset;
9851 unsigned int reg;
fa197c1c
PB
9852 } regpos[16];
9853
9854 /* Scan entire instruction first so that GET_OP output is not
9855 interleaved with disassembly. */
9856 nregs = 0;
9857 for (i = 0; nregs < (op & 0xf); i++)
9858 {
9859 GET_OP (op2);
9860 reg = op2 >> 4;
9861 if (reg != 0xf)
9862 {
9863 regpos[nregs].offset = i * 2;
9864 regpos[nregs].reg = reg;
9865 nregs++;
9866 }
9867
9868 reg = op2 & 0xf;
9869 if (reg != 0xf)
9870 {
9871 regpos[nregs].offset = i * 2 + 1;
9872 regpos[nregs].reg = reg;
9873 nregs++;
9874 }
9875 }
9876
9877 printf (_("pop frame {"));
18344509 9878 if (nregs == 0)
fa197c1c 9879 {
18344509
NC
9880 printf (_("*corrupt* - no registers specified"));
9881 }
9882 else
9883 {
9884 reg = nregs - 1;
9885 for (i = i * 2; i > 0; i--)
fa197c1c 9886 {
18344509
NC
9887 if (regpos[reg].offset == i - 1)
9888 {
9889 name = tic6x_unwind_regnames[regpos[reg].reg];
9890 if (reg > 0)
9891 reg--;
9892 }
9893 else
9894 name = _("[pad]");
fa197c1c 9895
18344509
NC
9896 fputs (name, stdout);
9897 if (i > 1)
9898 printf (", ");
9899 }
fa197c1c
PB
9900 }
9901
9902 printf ("}");
9903 }
9904 else if (op == 0xd0)
9905 printf (" MOV FP, SP");
9906 else if (op == 0xd1)
9907 printf (" __c6xabi_pop_rts");
9908 else if (op == 0xd2)
9909 {
9910 unsigned char buf[9];
9911 unsigned int i, len;
9912 unsigned long offset;
a734115a 9913
fa197c1c
PB
9914 for (i = 0; i < sizeof (buf); i++)
9915 {
9916 GET_OP (buf[i]);
9917 if ((buf[i] & 0x80) == 0)
9918 break;
9919 }
0eff7165
NC
9920 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9921 if (i == sizeof (buf))
9922 {
0eff7165 9923 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9924 return false;
0eff7165 9925 }
948f632f 9926
015dc7e1 9927 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9928 assert (len == i + 1);
9929 offset = offset * 8 + 0x408;
9930 printf (_("sp = sp + %ld"), offset);
9931 }
9932 else if ((op & 0xf0) == 0xe0)
9933 {
9934 if ((op & 0x0f) == 7)
9935 printf (" RETURN");
9936 else
9937 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9938 }
9939 else
9940 {
9941 printf (_(" [unsupported opcode]"));
9942 }
9943 putchar ('\n');
9944 }
32ec8896 9945
015dc7e1 9946 return true;
fa197c1c
PB
9947}
9948
9949static bfd_vma
dda8d76d 9950arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9951{
9952 bfd_vma offset;
9953
9954 offset = word & 0x7fffffff;
9955 if (offset & 0x40000000)
9956 offset |= ~ (bfd_vma) 0x7fffffff;
9957
dda8d76d 9958 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9959 offset <<= 1;
9960
9961 return offset + where;
9962}
9963
015dc7e1 9964static bool
dda8d76d
NC
9965decode_arm_unwind (Filedata * filedata,
9966 struct arm_unw_aux_info * aux,
1b31d05e
NC
9967 unsigned int word,
9968 unsigned int remaining,
9969 bfd_vma data_offset,
9970 Elf_Internal_Shdr * data_sec,
9971 struct arm_section * data_arm_sec)
fa197c1c
PB
9972{
9973 int per_index;
9974 unsigned int more_words = 0;
37e14bc3 9975 struct absaddr addr;
1b31d05e 9976 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9977 bool res = true;
fa197c1c
PB
9978
9979 if (remaining == 0)
9980 {
1b31d05e
NC
9981 /* Fetch the first word.
9982 Note - when decoding an object file the address extracted
9983 here will always be 0. So we also pass in the sym_name
9984 parameter so that we can find the symbol associated with
9985 the personality routine. */
dda8d76d 9986 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9987 & word, & addr, & sym_name))
015dc7e1 9988 return false;
1b31d05e 9989
fa197c1c
PB
9990 remaining = 4;
9991 }
c93dbb25
CZ
9992 else
9993 {
9994 addr.section = SHN_UNDEF;
9995 addr.offset = 0;
9996 }
fa197c1c
PB
9997
9998 if ((word & 0x80000000) == 0)
9999 {
10000 /* Expand prel31 for personality routine. */
10001 bfd_vma fn;
10002 const char *procname;
10003
dda8d76d 10004 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10005 printf (_(" Personality routine: "));
1b31d05e
NC
10006 if (fn == 0
10007 && addr.section == SHN_UNDEF && addr.offset == 0
10008 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10009 {
10010 procname = aux->strtab + sym_name;
10011 print_vma (fn, PREFIX_HEX);
10012 if (procname)
10013 {
10014 fputs (" <", stdout);
10015 fputs (procname, stdout);
10016 fputc ('>', stdout);
10017 }
10018 }
10019 else
dda8d76d 10020 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10021 fputc ('\n', stdout);
10022
10023 /* The GCC personality routines use the standard compact
10024 encoding, starting with one byte giving the number of
10025 words. */
10026 if (procname != NULL
24d127aa
ML
10027 && (startswith (procname, "__gcc_personality_v0")
10028 || startswith (procname, "__gxx_personality_v0")
10029 || startswith (procname, "__gcj_personality_v0")
10030 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10031 {
10032 remaining = 0;
10033 more_words = 1;
10034 ADVANCE;
10035 if (!remaining)
10036 {
10037 printf (_(" [Truncated data]\n"));
015dc7e1 10038 return false;
fa197c1c
PB
10039 }
10040 more_words = word >> 24;
10041 word <<= 8;
10042 remaining--;
10043 per_index = -1;
10044 }
10045 else
015dc7e1 10046 return true;
fa197c1c
PB
10047 }
10048 else
10049 {
1b31d05e 10050 /* ARM EHABI Section 6.3:
0b4362b0 10051
1b31d05e 10052 An exception-handling table entry for the compact model looks like:
0b4362b0 10053
1b31d05e
NC
10054 31 30-28 27-24 23-0
10055 -- ----- ----- ----
10056 1 0 index Data for personalityRoutine[index] */
10057
dda8d76d 10058 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10059 && (word & 0x70000000))
32ec8896
NC
10060 {
10061 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10062 res = false;
32ec8896 10063 }
1b31d05e 10064
fa197c1c 10065 per_index = (word >> 24) & 0x7f;
1b31d05e 10066 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10067 if (per_index == 0)
10068 {
10069 more_words = 0;
10070 word <<= 8;
10071 remaining--;
10072 }
10073 else if (per_index < 3)
10074 {
10075 more_words = (word >> 16) & 0xff;
10076 word <<= 16;
10077 remaining -= 2;
10078 }
10079 }
10080
dda8d76d 10081 switch (filedata->file_header.e_machine)
fa197c1c
PB
10082 {
10083 case EM_ARM:
10084 if (per_index < 3)
10085 {
dda8d76d 10086 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10087 data_offset, data_sec, data_arm_sec))
015dc7e1 10088 res = false;
fa197c1c
PB
10089 }
10090 else
1b31d05e
NC
10091 {
10092 warn (_("Unknown ARM compact model index encountered\n"));
10093 printf (_(" [reserved]\n"));
015dc7e1 10094 res = false;
1b31d05e 10095 }
fa197c1c
PB
10096 break;
10097
10098 case EM_TI_C6000:
10099 if (per_index < 3)
10100 {
dda8d76d 10101 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10102 data_offset, data_sec, data_arm_sec))
015dc7e1 10103 res = false;
fa197c1c
PB
10104 }
10105 else if (per_index < 5)
10106 {
10107 if (((word >> 17) & 0x7f) == 0x7f)
10108 printf (_(" Restore stack from frame pointer\n"));
10109 else
10110 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10111 printf (_(" Registers restored: "));
10112 if (per_index == 4)
10113 printf (" (compact) ");
10114 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10115 putchar ('\n');
10116 printf (_(" Return register: %s\n"),
10117 tic6x_unwind_regnames[word & 0xf]);
10118 }
10119 else
1b31d05e 10120 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10121 break;
10122
10123 default:
74e1a04b 10124 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10125 filedata->file_header.e_machine);
015dc7e1 10126 res = false;
fa197c1c 10127 }
0b6ae522
DJ
10128
10129 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10130
10131 return res;
0b6ae522
DJ
10132}
10133
015dc7e1 10134static bool
dda8d76d
NC
10135dump_arm_unwind (Filedata * filedata,
10136 struct arm_unw_aux_info * aux,
10137 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10138{
10139 struct arm_section exidx_arm_sec, extab_arm_sec;
10140 unsigned int i, exidx_len;
948f632f 10141 unsigned long j, nfuns;
015dc7e1 10142 bool res = true;
0b6ae522
DJ
10143
10144 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10145 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10146 exidx_len = exidx_sec->sh_size / 8;
10147
948f632f
DA
10148 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10149 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10150 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10151 aux->funtab[nfuns++] = aux->symtab[j];
10152 aux->nfuns = nfuns;
10153 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10154
0b6ae522
DJ
10155 for (i = 0; i < exidx_len; i++)
10156 {
10157 unsigned int exidx_fn, exidx_entry;
10158 struct absaddr fn_addr, entry_addr;
10159 bfd_vma fn;
10160
10161 fputc ('\n', stdout);
10162
dda8d76d 10163 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10164 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10165 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10166 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10167 {
948f632f 10168 free (aux->funtab);
1b31d05e
NC
10169 arm_free_section (& exidx_arm_sec);
10170 arm_free_section (& extab_arm_sec);
015dc7e1 10171 return false;
0b6ae522
DJ
10172 }
10173
83c257ca
NC
10174 /* ARM EHABI, Section 5:
10175 An index table entry consists of 2 words.
10176 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10177 if (exidx_fn & 0x80000000)
32ec8896
NC
10178 {
10179 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10180 res = false;
32ec8896 10181 }
83c257ca 10182
dda8d76d 10183 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10184
dda8d76d 10185 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10186 fputs (": ", stdout);
10187
10188 if (exidx_entry == 1)
10189 {
10190 print_vma (exidx_entry, PREFIX_HEX);
10191 fputs (" [cantunwind]\n", stdout);
10192 }
10193 else if (exidx_entry & 0x80000000)
10194 {
10195 print_vma (exidx_entry, PREFIX_HEX);
10196 fputc ('\n', stdout);
dda8d76d 10197 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10198 }
10199 else
10200 {
8f73510c 10201 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10202 Elf_Internal_Shdr *table_sec;
10203
10204 fputs ("@", stdout);
dda8d76d 10205 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10206 print_vma (table, PREFIX_HEX);
10207 printf ("\n");
10208
10209 /* Locate the matching .ARM.extab. */
10210 if (entry_addr.section != SHN_UNDEF
dda8d76d 10211 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10212 {
dda8d76d 10213 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10214 table_offset = entry_addr.offset;
1a915552
NC
10215 /* PR 18879 */
10216 if (table_offset > table_sec->sh_size
10217 || ((bfd_signed_vma) table_offset) < 0)
10218 {
10219 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10220 (unsigned long) table_offset,
dda8d76d 10221 printable_section_name (filedata, table_sec));
015dc7e1 10222 res = false;
1a915552
NC
10223 continue;
10224 }
0b6ae522
DJ
10225 }
10226 else
10227 {
dda8d76d 10228 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10229 if (table_sec != NULL)
10230 table_offset = table - table_sec->sh_addr;
10231 }
32ec8896 10232
0b6ae522
DJ
10233 if (table_sec == NULL)
10234 {
10235 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10236 (unsigned long) table);
015dc7e1 10237 res = false;
0b6ae522
DJ
10238 continue;
10239 }
32ec8896 10240
dda8d76d 10241 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10242 &extab_arm_sec))
015dc7e1 10243 res = false;
0b6ae522
DJ
10244 }
10245 }
10246
10247 printf ("\n");
10248
948f632f 10249 free (aux->funtab);
0b6ae522
DJ
10250 arm_free_section (&exidx_arm_sec);
10251 arm_free_section (&extab_arm_sec);
32ec8896
NC
10252
10253 return res;
0b6ae522
DJ
10254}
10255
fa197c1c 10256/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10257
015dc7e1 10258static bool
dda8d76d 10259arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10260{
10261 struct arm_unw_aux_info aux;
10262 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10263 Elf_Internal_Shdr *sec;
10264 unsigned long i;
fa197c1c 10265 unsigned int sec_type;
015dc7e1 10266 bool res = true;
0b6ae522 10267
dda8d76d 10268 switch (filedata->file_header.e_machine)
fa197c1c
PB
10269 {
10270 case EM_ARM:
10271 sec_type = SHT_ARM_EXIDX;
10272 break;
10273
10274 case EM_TI_C6000:
10275 sec_type = SHT_C6000_UNWIND;
10276 break;
10277
0b4362b0 10278 default:
74e1a04b 10279 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10280 filedata->file_header.e_machine);
015dc7e1 10281 return false;
fa197c1c
PB
10282 }
10283
dda8d76d 10284 if (filedata->string_table == NULL)
015dc7e1 10285 return false;
1b31d05e
NC
10286
10287 memset (& aux, 0, sizeof (aux));
dda8d76d 10288 aux.filedata = filedata;
0b6ae522 10289
dda8d76d 10290 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10291 {
28d13567 10292 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10293 {
28d13567 10294 if (aux.symtab)
74e1a04b 10295 {
28d13567
AM
10296 error (_("Multiple symbol tables encountered\n"));
10297 free (aux.symtab);
10298 aux.symtab = NULL;
74e1a04b 10299 free (aux.strtab);
28d13567 10300 aux.strtab = NULL;
74e1a04b 10301 }
28d13567
AM
10302 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10303 &aux.strtab, &aux.strtab_size))
015dc7e1 10304 return false;
0b6ae522 10305 }
fa197c1c 10306 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10307 unwsec = sec;
10308 }
10309
1b31d05e 10310 if (unwsec == NULL)
0b6ae522 10311 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10312 else
dda8d76d 10313 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10314 {
10315 if (sec->sh_type == sec_type)
10316 {
d3a49aa8
AM
10317 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10318 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10319 "contains %lu entry:\n",
10320 "\nUnwind section '%s' at offset 0x%lx "
10321 "contains %lu entries:\n",
10322 num_unwind),
dda8d76d 10323 printable_section_name (filedata, sec),
1b31d05e 10324 (unsigned long) sec->sh_offset,
d3a49aa8 10325 num_unwind);
0b6ae522 10326
dda8d76d 10327 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10328 res = false;
1b31d05e
NC
10329 }
10330 }
0b6ae522 10331
9db70fc3
AM
10332 free (aux.symtab);
10333 free ((char *) aux.strtab);
32ec8896
NC
10334
10335 return res;
0b6ae522
DJ
10336}
10337
3ecc00ec
NC
10338static bool
10339no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10340{
10341 printf (_("No processor specific unwind information to decode\n"));
10342 return true;
10343}
10344
015dc7e1 10345static bool
dda8d76d 10346process_unwind (Filedata * filedata)
57346661 10347{
2cf0635d
NC
10348 struct unwind_handler
10349 {
32ec8896 10350 unsigned int machtype;
015dc7e1 10351 bool (* handler)(Filedata *);
2cf0635d
NC
10352 } handlers[] =
10353 {
0b6ae522 10354 { EM_ARM, arm_process_unwind },
57346661
AM
10355 { EM_IA_64, ia64_process_unwind },
10356 { EM_PARISC, hppa_process_unwind },
fa197c1c 10357 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10358 { EM_386, no_processor_specific_unwind },
10359 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10360 { 0, NULL }
57346661
AM
10361 };
10362 int i;
10363
10364 if (!do_unwind)
015dc7e1 10365 return true;
57346661
AM
10366
10367 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10368 if (filedata->file_header.e_machine == handlers[i].machtype)
10369 return handlers[i].handler (filedata);
57346661 10370
1b31d05e 10371 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10372 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10373 return true;
57346661
AM
10374}
10375
37c18eed
SD
10376static void
10377dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10378{
10379 switch (entry->d_tag)
10380 {
10381 case DT_AARCH64_BTI_PLT:
1dbade74 10382 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10383 break;
10384 default:
10385 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10386 break;
10387 }
10388 putchar ('\n');
10389}
10390
252b5132 10391static void
978c4450 10392dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10393{
10394 switch (entry->d_tag)
10395 {
10396 case DT_MIPS_FLAGS:
10397 if (entry->d_un.d_val == 0)
4b68bca3 10398 printf (_("NONE"));
252b5132
RH
10399 else
10400 {
10401 static const char * opts[] =
10402 {
10403 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10404 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10405 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10406 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10407 "RLD_ORDER_SAFE"
10408 };
10409 unsigned int cnt;
015dc7e1 10410 bool first = true;
2b692964 10411
60bca95a 10412 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10413 if (entry->d_un.d_val & (1 << cnt))
10414 {
10415 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10416 first = false;
252b5132 10417 }
252b5132
RH
10418 }
10419 break;
103f02d3 10420
252b5132 10421 case DT_MIPS_IVERSION:
84714f86 10422 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10423 printf (_("Interface Version: %s"),
84714f86 10424 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10425 else
76ca31c0
NC
10426 {
10427 char buf[40];
10428 sprintf_vma (buf, entry->d_un.d_ptr);
10429 /* Note: coded this way so that there is a single string for translation. */
10430 printf (_("<corrupt: %s>"), buf);
10431 }
252b5132 10432 break;
103f02d3 10433
252b5132
RH
10434 case DT_MIPS_TIME_STAMP:
10435 {
d5b07ef4 10436 char timebuf[128];
2cf0635d 10437 struct tm * tmp;
91d6fa6a 10438 time_t atime = entry->d_un.d_val;
82b1b41b 10439
91d6fa6a 10440 tmp = gmtime (&atime);
82b1b41b
NC
10441 /* PR 17531: file: 6accc532. */
10442 if (tmp == NULL)
10443 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10444 else
10445 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10446 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10447 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10448 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10449 }
10450 break;
103f02d3 10451
252b5132
RH
10452 case DT_MIPS_RLD_VERSION:
10453 case DT_MIPS_LOCAL_GOTNO:
10454 case DT_MIPS_CONFLICTNO:
10455 case DT_MIPS_LIBLISTNO:
10456 case DT_MIPS_SYMTABNO:
10457 case DT_MIPS_UNREFEXTNO:
10458 case DT_MIPS_HIPAGENO:
10459 case DT_MIPS_DELTA_CLASS_NO:
10460 case DT_MIPS_DELTA_INSTANCE_NO:
10461 case DT_MIPS_DELTA_RELOC_NO:
10462 case DT_MIPS_DELTA_SYM_NO:
10463 case DT_MIPS_DELTA_CLASSSYM_NO:
10464 case DT_MIPS_COMPACT_SIZE:
c69075ac 10465 print_vma (entry->d_un.d_val, DEC);
252b5132 10466 break;
103f02d3 10467
f16a9783 10468 case DT_MIPS_XHASH:
978c4450
AM
10469 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10470 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10471 /* Falls through. */
10472
103f02d3 10473 default:
4b68bca3 10474 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10475 }
4b68bca3 10476 putchar ('\n');
103f02d3
UD
10477}
10478
103f02d3 10479static void
2cf0635d 10480dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10481{
10482 switch (entry->d_tag)
10483 {
10484 case DT_HP_DLD_FLAGS:
10485 {
10486 static struct
10487 {
10488 long int bit;
2cf0635d 10489 const char * str;
5e220199
NC
10490 }
10491 flags[] =
10492 {
10493 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10494 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10495 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10496 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10497 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10498 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10499 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10500 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10501 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10502 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10503 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10504 { DT_HP_GST, "HP_GST" },
10505 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10506 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10507 { DT_HP_NODELETE, "HP_NODELETE" },
10508 { DT_HP_GROUP, "HP_GROUP" },
10509 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10510 };
015dc7e1 10511 bool first = true;
5e220199 10512 size_t cnt;
f7a99963 10513 bfd_vma val = entry->d_un.d_val;
103f02d3 10514
60bca95a 10515 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10516 if (val & flags[cnt].bit)
30800947
NC
10517 {
10518 if (! first)
10519 putchar (' ');
10520 fputs (flags[cnt].str, stdout);
015dc7e1 10521 first = false;
30800947
NC
10522 val ^= flags[cnt].bit;
10523 }
76da6bbe 10524
103f02d3 10525 if (val != 0 || first)
f7a99963
NC
10526 {
10527 if (! first)
10528 putchar (' ');
10529 print_vma (val, HEX);
10530 }
103f02d3
UD
10531 }
10532 break;
76da6bbe 10533
252b5132 10534 default:
f7a99963
NC
10535 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10536 break;
252b5132 10537 }
35b1837e 10538 putchar ('\n');
252b5132
RH
10539}
10540
28f997cf
TG
10541#ifdef BFD64
10542
10543/* VMS vs Unix time offset and factor. */
10544
10545#define VMS_EPOCH_OFFSET 35067168000000000LL
10546#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10547#ifndef INT64_MIN
10548#define INT64_MIN (-9223372036854775807LL - 1)
10549#endif
28f997cf
TG
10550
10551/* Display a VMS time in a human readable format. */
10552
10553static void
10554print_vms_time (bfd_int64_t vmstime)
10555{
dccc31de 10556 struct tm *tm = NULL;
28f997cf
TG
10557 time_t unxtime;
10558
dccc31de
AM
10559 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10560 {
10561 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10562 unxtime = vmstime;
10563 if (unxtime == vmstime)
10564 tm = gmtime (&unxtime);
10565 }
10566 if (tm != NULL)
10567 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10568 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10569 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10570}
10571#endif /* BFD64 */
10572
ecc51f48 10573static void
2cf0635d 10574dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10575{
10576 switch (entry->d_tag)
10577 {
0de14b54 10578 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10579 /* First 3 slots reserved. */
ecc51f48
NC
10580 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10581 printf (" -- ");
10582 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10583 break;
10584
28f997cf
TG
10585 case DT_IA_64_VMS_LINKTIME:
10586#ifdef BFD64
10587 print_vms_time (entry->d_un.d_val);
10588#endif
10589 break;
10590
10591 case DT_IA_64_VMS_LNKFLAGS:
10592 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10593 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10594 printf (" CALL_DEBUG");
10595 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10596 printf (" NOP0BUFS");
10597 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10598 printf (" P0IMAGE");
10599 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10600 printf (" MKTHREADS");
10601 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10602 printf (" UPCALLS");
10603 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10604 printf (" IMGSTA");
10605 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10606 printf (" INITIALIZE");
10607 if (entry->d_un.d_val & VMS_LF_MAIN)
10608 printf (" MAIN");
10609 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10610 printf (" EXE_INIT");
10611 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10612 printf (" TBK_IN_IMG");
10613 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10614 printf (" DBG_IN_IMG");
10615 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10616 printf (" TBK_IN_DSF");
10617 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10618 printf (" DBG_IN_DSF");
10619 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10620 printf (" SIGNATURES");
10621 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10622 printf (" REL_SEG_OFF");
10623 break;
10624
bdf4d63a
JJ
10625 default:
10626 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10627 break;
ecc51f48 10628 }
bdf4d63a 10629 putchar ('\n');
ecc51f48
NC
10630}
10631
015dc7e1 10632static bool
dda8d76d 10633get_32bit_dynamic_section (Filedata * filedata)
252b5132 10634{
2cf0635d
NC
10635 Elf32_External_Dyn * edyn;
10636 Elf32_External_Dyn * ext;
10637 Elf_Internal_Dyn * entry;
103f02d3 10638
978c4450
AM
10639 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10640 filedata->dynamic_addr, 1,
10641 filedata->dynamic_size,
10642 _("dynamic section"));
a6e9f9df 10643 if (!edyn)
015dc7e1 10644 return false;
103f02d3 10645
071436c6
NC
10646 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10647 might not have the luxury of section headers. Look for the DT_NULL
10648 terminator to determine the number of entries. */
978c4450
AM
10649 for (ext = edyn, filedata->dynamic_nent = 0;
10650 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10651 ext++)
10652 {
978c4450 10653 filedata->dynamic_nent++;
ba2685cc
AM
10654 if (BYTE_GET (ext->d_tag) == DT_NULL)
10655 break;
10656 }
252b5132 10657
978c4450
AM
10658 filedata->dynamic_section
10659 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10660 if (filedata->dynamic_section == NULL)
252b5132 10661 {
8b73c356 10662 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10663 (unsigned long) filedata->dynamic_nent);
9ea033b2 10664 free (edyn);
015dc7e1 10665 return false;
9ea033b2 10666 }
252b5132 10667
978c4450
AM
10668 for (ext = edyn, entry = filedata->dynamic_section;
10669 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10670 ext++, entry++)
9ea033b2 10671 {
fb514b26
AM
10672 entry->d_tag = BYTE_GET (ext->d_tag);
10673 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10674 }
10675
9ea033b2
NC
10676 free (edyn);
10677
015dc7e1 10678 return true;
9ea033b2
NC
10679}
10680
015dc7e1 10681static bool
dda8d76d 10682get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10683{
2cf0635d
NC
10684 Elf64_External_Dyn * edyn;
10685 Elf64_External_Dyn * ext;
10686 Elf_Internal_Dyn * entry;
103f02d3 10687
071436c6 10688 /* Read in the data. */
978c4450
AM
10689 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10690 filedata->dynamic_addr, 1,
10691 filedata->dynamic_size,
10692 _("dynamic section"));
a6e9f9df 10693 if (!edyn)
015dc7e1 10694 return false;
103f02d3 10695
071436c6
NC
10696 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10697 might not have the luxury of section headers. Look for the DT_NULL
10698 terminator to determine the number of entries. */
978c4450 10699 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10700 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10701 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10702 ext++)
10703 {
978c4450 10704 filedata->dynamic_nent++;
66543521 10705 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10706 break;
10707 }
252b5132 10708
978c4450
AM
10709 filedata->dynamic_section
10710 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10711 if (filedata->dynamic_section == NULL)
252b5132 10712 {
8b73c356 10713 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10714 (unsigned long) filedata->dynamic_nent);
252b5132 10715 free (edyn);
015dc7e1 10716 return false;
252b5132
RH
10717 }
10718
071436c6 10719 /* Convert from external to internal formats. */
978c4450
AM
10720 for (ext = edyn, entry = filedata->dynamic_section;
10721 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10722 ext++, entry++)
252b5132 10723 {
66543521
AM
10724 entry->d_tag = BYTE_GET (ext->d_tag);
10725 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10726 }
10727
10728 free (edyn);
10729
015dc7e1 10730 return true;
9ea033b2
NC
10731}
10732
4de91c10
AM
10733static bool
10734get_dynamic_section (Filedata *filedata)
10735{
10736 if (filedata->dynamic_section)
10737 return true;
10738
10739 if (is_32bit_elf)
10740 return get_32bit_dynamic_section (filedata);
10741 else
10742 return get_64bit_dynamic_section (filedata);
10743}
10744
e9e44622
JJ
10745static void
10746print_dynamic_flags (bfd_vma flags)
d1133906 10747{
015dc7e1 10748 bool first = true;
13ae64f3 10749
d1133906
NC
10750 while (flags)
10751 {
10752 bfd_vma flag;
10753
10754 flag = flags & - flags;
10755 flags &= ~ flag;
10756
e9e44622 10757 if (first)
015dc7e1 10758 first = false;
e9e44622
JJ
10759 else
10760 putc (' ', stdout);
13ae64f3 10761
d1133906
NC
10762 switch (flag)
10763 {
e9e44622
JJ
10764 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10765 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10766 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10767 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10768 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10769 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10770 }
10771 }
e9e44622 10772 puts ("");
d1133906
NC
10773}
10774
10ca4b04
L
10775static bfd_vma *
10776get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10777{
10778 unsigned char * e_data;
10779 bfd_vma * i_data;
10780
10781 /* If the size_t type is smaller than the bfd_size_type, eg because
10782 you are building a 32-bit tool on a 64-bit host, then make sure
10783 that when (number) is cast to (size_t) no information is lost. */
10784 if (sizeof (size_t) < sizeof (bfd_size_type)
10785 && (bfd_size_type) ((size_t) number) != number)
10786 {
10787 error (_("Size truncation prevents reading %s elements of size %u\n"),
10788 bfd_vmatoa ("u", number), ent_size);
10789 return NULL;
10790 }
10791
10792 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10793 attempting to allocate memory when the read is bound to fail. */
10794 if (ent_size * number > filedata->file_size)
10795 {
10796 error (_("Invalid number of dynamic entries: %s\n"),
10797 bfd_vmatoa ("u", number));
10798 return NULL;
10799 }
10800
10801 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10802 if (e_data == NULL)
10803 {
10804 error (_("Out of memory reading %s dynamic entries\n"),
10805 bfd_vmatoa ("u", number));
10806 return NULL;
10807 }
10808
10809 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10810 {
10811 error (_("Unable to read in %s bytes of dynamic data\n"),
10812 bfd_vmatoa ("u", number * ent_size));
10813 free (e_data);
10814 return NULL;
10815 }
10816
10817 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10818 if (i_data == NULL)
10819 {
10820 error (_("Out of memory allocating space for %s dynamic entries\n"),
10821 bfd_vmatoa ("u", number));
10822 free (e_data);
10823 return NULL;
10824 }
10825
10826 while (number--)
10827 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10828
10829 free (e_data);
10830
10831 return i_data;
10832}
10833
10834static unsigned long
10835get_num_dynamic_syms (Filedata * filedata)
10836{
10837 unsigned long num_of_syms = 0;
10838
10839 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10840 return num_of_syms;
10841
978c4450 10842 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10843 {
10844 unsigned char nb[8];
10845 unsigned char nc[8];
10846 unsigned int hash_ent_size = 4;
10847
10848 if ((filedata->file_header.e_machine == EM_ALPHA
10849 || filedata->file_header.e_machine == EM_S390
10850 || filedata->file_header.e_machine == EM_S390_OLD)
10851 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10852 hash_ent_size = 8;
10853
10854 if (fseek (filedata->handle,
978c4450
AM
10855 (filedata->archive_file_offset
10856 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10857 sizeof nb + sizeof nc)),
10858 SEEK_SET))
10859 {
10860 error (_("Unable to seek to start of dynamic information\n"));
10861 goto no_hash;
10862 }
10863
10864 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10865 {
10866 error (_("Failed to read in number of buckets\n"));
10867 goto no_hash;
10868 }
10869
10870 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10871 {
10872 error (_("Failed to read in number of chains\n"));
10873 goto no_hash;
10874 }
10875
978c4450
AM
10876 filedata->nbuckets = byte_get (nb, hash_ent_size);
10877 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10878
2482f306
AM
10879 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10880 {
10881 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10882 hash_ent_size);
10883 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10884 hash_ent_size);
001890e1 10885
2482f306
AM
10886 if (filedata->buckets != NULL && filedata->chains != NULL)
10887 num_of_syms = filedata->nchains;
10888 }
ceb9bf11 10889 no_hash:
10ca4b04
L
10890 if (num_of_syms == 0)
10891 {
9db70fc3
AM
10892 free (filedata->buckets);
10893 filedata->buckets = NULL;
10894 free (filedata->chains);
10895 filedata->chains = NULL;
978c4450 10896 filedata->nbuckets = 0;
10ca4b04
L
10897 }
10898 }
10899
978c4450 10900 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10901 {
10902 unsigned char nb[16];
10903 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10904 bfd_vma buckets_vma;
10905 unsigned long hn;
10ca4b04
L
10906
10907 if (fseek (filedata->handle,
978c4450
AM
10908 (filedata->archive_file_offset
10909 + offset_from_vma (filedata,
10910 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10911 sizeof nb)),
10912 SEEK_SET))
10913 {
10914 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10915 goto no_gnu_hash;
10916 }
10917
10918 if (fread (nb, 16, 1, filedata->handle) != 1)
10919 {
10920 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10921 goto no_gnu_hash;
10922 }
10923
978c4450
AM
10924 filedata->ngnubuckets = byte_get (nb, 4);
10925 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10926 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10927 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10928 if (is_32bit_elf)
10929 buckets_vma += bitmaskwords * 4;
10930 else
10931 buckets_vma += bitmaskwords * 8;
10932
10933 if (fseek (filedata->handle,
978c4450 10934 (filedata->archive_file_offset
10ca4b04
L
10935 + offset_from_vma (filedata, buckets_vma, 4)),
10936 SEEK_SET))
10937 {
10938 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10939 goto no_gnu_hash;
10940 }
10941
978c4450
AM
10942 filedata->gnubuckets
10943 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10944
978c4450 10945 if (filedata->gnubuckets == NULL)
90837ea7 10946 goto no_gnu_hash;
10ca4b04 10947
978c4450
AM
10948 for (i = 0; i < filedata->ngnubuckets; i++)
10949 if (filedata->gnubuckets[i] != 0)
10ca4b04 10950 {
978c4450 10951 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10952 goto no_gnu_hash;
10ca4b04 10953
978c4450
AM
10954 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10955 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10956 }
10957
10958 if (maxchain == 0xffffffff)
90837ea7 10959 goto no_gnu_hash;
10ca4b04 10960
978c4450 10961 maxchain -= filedata->gnusymidx;
10ca4b04
L
10962
10963 if (fseek (filedata->handle,
978c4450
AM
10964 (filedata->archive_file_offset
10965 + offset_from_vma (filedata,
10966 buckets_vma + 4 * (filedata->ngnubuckets
10967 + maxchain),
10968 4)),
10ca4b04
L
10969 SEEK_SET))
10970 {
10971 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10972 goto no_gnu_hash;
10973 }
10974
10975 do
10976 {
10977 if (fread (nb, 4, 1, filedata->handle) != 1)
10978 {
10979 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10980 goto no_gnu_hash;
10981 }
10982
10983 if (maxchain + 1 == 0)
90837ea7 10984 goto no_gnu_hash;
10ca4b04
L
10985
10986 ++maxchain;
10987 }
10988 while ((byte_get (nb, 4) & 1) == 0);
10989
10990 if (fseek (filedata->handle,
978c4450
AM
10991 (filedata->archive_file_offset
10992 + offset_from_vma (filedata, (buckets_vma
10993 + 4 * filedata->ngnubuckets),
10994 4)),
10ca4b04
L
10995 SEEK_SET))
10996 {
10997 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10998 goto no_gnu_hash;
10999 }
11000
978c4450
AM
11001 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11002 filedata->ngnuchains = maxchain;
10ca4b04 11003
978c4450 11004 if (filedata->gnuchains == NULL)
90837ea7 11005 goto no_gnu_hash;
10ca4b04 11006
978c4450 11007 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11008 {
11009 if (fseek (filedata->handle,
978c4450 11010 (filedata->archive_file_offset
10ca4b04 11011 + offset_from_vma (filedata, (buckets_vma
978c4450 11012 + 4 * (filedata->ngnubuckets
10ca4b04
L
11013 + maxchain)), 4)),
11014 SEEK_SET))
11015 {
11016 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11017 goto no_gnu_hash;
11018 }
11019
978c4450 11020 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11021 if (filedata->mipsxlat == NULL)
11022 goto no_gnu_hash;
10ca4b04
L
11023 }
11024
978c4450
AM
11025 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11026 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11027 {
978c4450
AM
11028 bfd_vma si = filedata->gnubuckets[hn];
11029 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11030
11031 do
11032 {
978c4450 11033 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11034 {
c31ab5a0
AM
11035 if (off < filedata->ngnuchains
11036 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11037 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11038 }
11039 else
11040 {
11041 if (si >= num_of_syms)
11042 num_of_syms = si + 1;
11043 }
11044 si++;
11045 }
978c4450
AM
11046 while (off < filedata->ngnuchains
11047 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11048 }
11049
90837ea7 11050 if (num_of_syms == 0)
10ca4b04 11051 {
90837ea7 11052 no_gnu_hash:
9db70fc3
AM
11053 free (filedata->mipsxlat);
11054 filedata->mipsxlat = NULL;
11055 free (filedata->gnuchains);
11056 filedata->gnuchains = NULL;
11057 free (filedata->gnubuckets);
11058 filedata->gnubuckets = NULL;
978c4450
AM
11059 filedata->ngnubuckets = 0;
11060 filedata->ngnuchains = 0;
10ca4b04
L
11061 }
11062 }
11063
11064 return num_of_syms;
11065}
11066
b2d38a17
NC
11067/* Parse and display the contents of the dynamic section. */
11068
015dc7e1 11069static bool
dda8d76d 11070process_dynamic_section (Filedata * filedata)
9ea033b2 11071{
2cf0635d 11072 Elf_Internal_Dyn * entry;
9ea033b2 11073
93df3340 11074 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11075 {
11076 if (do_dynamic)
ca0e11aa
NC
11077 {
11078 if (filedata->is_separate)
11079 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11080 filedata->file_name);
11081 else
11082 printf (_("\nThere is no dynamic section in this file.\n"));
11083 }
9ea033b2 11084
015dc7e1 11085 return true;
9ea033b2
NC
11086 }
11087
4de91c10
AM
11088 if (!get_dynamic_section (filedata))
11089 return false;
9ea033b2 11090
252b5132 11091 /* Find the appropriate symbol table. */
978c4450 11092 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11093 {
2482f306
AM
11094 unsigned long num_of_syms;
11095
978c4450
AM
11096 for (entry = filedata->dynamic_section;
11097 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11098 ++entry)
10ca4b04 11099 if (entry->d_tag == DT_SYMTAB)
978c4450 11100 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11101 else if (entry->d_tag == DT_SYMENT)
978c4450 11102 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11103 else if (entry->d_tag == DT_HASH)
978c4450 11104 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11105 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11106 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11107 else if ((filedata->file_header.e_machine == EM_MIPS
11108 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11109 && entry->d_tag == DT_MIPS_XHASH)
11110 {
978c4450
AM
11111 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11112 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11113 }
252b5132 11114
2482f306
AM
11115 num_of_syms = get_num_dynamic_syms (filedata);
11116
11117 if (num_of_syms != 0
11118 && filedata->dynamic_symbols == NULL
11119 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11120 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11121 {
11122 Elf_Internal_Phdr *seg;
2482f306 11123 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11124
2482f306
AM
11125 if (! get_program_headers (filedata))
11126 {
11127 error (_("Cannot interpret virtual addresses "
11128 "without program headers.\n"));
015dc7e1 11129 return false;
2482f306 11130 }
252b5132 11131
2482f306
AM
11132 for (seg = filedata->program_headers;
11133 seg < filedata->program_headers + filedata->file_header.e_phnum;
11134 ++seg)
11135 {
11136 if (seg->p_type != PT_LOAD)
11137 continue;
252b5132 11138
2482f306
AM
11139 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11140 {
11141 /* See PR 21379 for a reproducer. */
11142 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11143 return false;
2482f306 11144 }
252b5132 11145
2482f306
AM
11146 if (vma >= (seg->p_vaddr & -seg->p_align)
11147 && vma < seg->p_vaddr + seg->p_filesz)
11148 {
11149 /* Since we do not know how big the symbol table is,
11150 we default to reading in up to the end of PT_LOAD
11151 segment and processing that. This is overkill, I
11152 know, but it should work. */
11153 Elf_Internal_Shdr section;
11154 section.sh_offset = (vma - seg->p_vaddr
11155 + seg->p_offset);
11156 section.sh_size = (num_of_syms
11157 * filedata->dynamic_info[DT_SYMENT]);
11158 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11159
11160 if (do_checks
11161 && filedata->dynamic_symtab_section != NULL
11162 && ((filedata->dynamic_symtab_section->sh_offset
11163 != section.sh_offset)
11164 || (filedata->dynamic_symtab_section->sh_size
11165 != section.sh_size)
11166 || (filedata->dynamic_symtab_section->sh_entsize
11167 != section.sh_entsize)))
11168 warn (_("\
11169the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11170
2482f306
AM
11171 section.sh_name = filedata->string_table_length;
11172 filedata->dynamic_symbols
4de91c10 11173 = get_elf_symbols (filedata, &section,
2482f306
AM
11174 &filedata->num_dynamic_syms);
11175 if (filedata->dynamic_symbols == NULL
11176 || filedata->num_dynamic_syms != num_of_syms)
11177 {
11178 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11179 return false;
2482f306
AM
11180 }
11181 break;
11182 }
11183 }
11184 }
11185 }
252b5132
RH
11186
11187 /* Similarly find a string table. */
978c4450
AM
11188 if (filedata->dynamic_strings == NULL)
11189 for (entry = filedata->dynamic_section;
11190 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11191 ++entry)
11192 {
11193 if (entry->d_tag == DT_STRTAB)
978c4450 11194 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11195
10ca4b04 11196 if (entry->d_tag == DT_STRSZ)
978c4450 11197 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11198
978c4450
AM
11199 if (filedata->dynamic_info[DT_STRTAB]
11200 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11201 {
11202 unsigned long offset;
978c4450 11203 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11204
11205 offset = offset_from_vma (filedata,
978c4450 11206 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11207 str_tab_len);
8ac10c5b
L
11208 if (do_checks
11209 && filedata->dynamic_strtab_section
11210 && ((filedata->dynamic_strtab_section->sh_offset
11211 != (file_ptr) offset)
11212 || (filedata->dynamic_strtab_section->sh_size
11213 != str_tab_len)))
11214 warn (_("\
11215the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11216
978c4450
AM
11217 filedata->dynamic_strings
11218 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11219 _("dynamic string table"));
11220 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11221 {
11222 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11223 break;
11224 }
e3d39609 11225
978c4450 11226 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11227 break;
11228 }
11229 }
252b5132
RH
11230
11231 /* And find the syminfo section if available. */
978c4450 11232 if (filedata->dynamic_syminfo == NULL)
252b5132 11233 {
3e8bba36 11234 unsigned long syminsz = 0;
252b5132 11235
978c4450
AM
11236 for (entry = filedata->dynamic_section;
11237 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11238 ++entry)
252b5132
RH
11239 {
11240 if (entry->d_tag == DT_SYMINENT)
11241 {
11242 /* Note: these braces are necessary to avoid a syntax
11243 error from the SunOS4 C compiler. */
049b0c3a
NC
11244 /* PR binutils/17531: A corrupt file can trigger this test.
11245 So do not use an assert, instead generate an error message. */
11246 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11247 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11248 (int) entry->d_un.d_val);
252b5132
RH
11249 }
11250 else if (entry->d_tag == DT_SYMINSZ)
11251 syminsz = entry->d_un.d_val;
11252 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11253 filedata->dynamic_syminfo_offset
11254 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11255 }
11256
978c4450 11257 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11258 {
2cf0635d
NC
11259 Elf_External_Syminfo * extsyminfo;
11260 Elf_External_Syminfo * extsym;
11261 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11262
11263 /* There is a syminfo section. Read the data. */
3f5e193b 11264 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11265 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11266 1, syminsz, _("symbol information"));
a6e9f9df 11267 if (!extsyminfo)
015dc7e1 11268 return false;
252b5132 11269
978c4450 11270 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11271 {
11272 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11273 free (filedata->dynamic_syminfo);
e3d39609 11274 }
978c4450
AM
11275 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11276 if (filedata->dynamic_syminfo == NULL)
252b5132 11277 {
2482f306
AM
11278 error (_("Out of memory allocating %lu bytes "
11279 "for dynamic symbol info\n"),
8b73c356 11280 (unsigned long) syminsz);
015dc7e1 11281 return false;
252b5132
RH
11282 }
11283
2482f306
AM
11284 filedata->dynamic_syminfo_nent
11285 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11286 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11287 syminfo < (filedata->dynamic_syminfo
11288 + filedata->dynamic_syminfo_nent);
86dba8ee 11289 ++syminfo, ++extsym)
252b5132 11290 {
86dba8ee
AM
11291 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11292 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11293 }
11294
11295 free (extsyminfo);
11296 }
11297 }
11298
978c4450 11299 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11300 {
f253158f
NC
11301 if (filedata->is_separate)
11302 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11303 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11304 (unsigned long) filedata->dynamic_nent),
11305 filedata->file_name,
11306 filedata->dynamic_addr,
11307 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11308 else
11309 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11310 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11311 (unsigned long) filedata->dynamic_nent),
11312 filedata->dynamic_addr,
11313 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11314 }
252b5132
RH
11315 if (do_dynamic)
11316 printf (_(" Tag Type Name/Value\n"));
11317
978c4450
AM
11318 for (entry = filedata->dynamic_section;
11319 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11320 entry++)
252b5132
RH
11321 {
11322 if (do_dynamic)
f7a99963 11323 {
2cf0635d 11324 const char * dtype;
e699b9ff 11325
f7a99963
NC
11326 putchar (' ');
11327 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11328 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11329 printf (" (%s)%*s", dtype,
32ec8896 11330 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11331 }
252b5132
RH
11332
11333 switch (entry->d_tag)
11334 {
d1133906
NC
11335 case DT_FLAGS:
11336 if (do_dynamic)
e9e44622 11337 print_dynamic_flags (entry->d_un.d_val);
d1133906 11338 break;
76da6bbe 11339
252b5132
RH
11340 case DT_AUXILIARY:
11341 case DT_FILTER:
019148e4
L
11342 case DT_CONFIG:
11343 case DT_DEPAUDIT:
11344 case DT_AUDIT:
252b5132
RH
11345 if (do_dynamic)
11346 {
019148e4 11347 switch (entry->d_tag)
b34976b6 11348 {
019148e4
L
11349 case DT_AUXILIARY:
11350 printf (_("Auxiliary library"));
11351 break;
11352
11353 case DT_FILTER:
11354 printf (_("Filter library"));
11355 break;
11356
b34976b6 11357 case DT_CONFIG:
019148e4
L
11358 printf (_("Configuration file"));
11359 break;
11360
11361 case DT_DEPAUDIT:
11362 printf (_("Dependency audit library"));
11363 break;
11364
11365 case DT_AUDIT:
11366 printf (_("Audit library"));
11367 break;
11368 }
252b5132 11369
84714f86 11370 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11371 printf (": [%s]\n",
84714f86 11372 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11373 else
f7a99963
NC
11374 {
11375 printf (": ");
11376 print_vma (entry->d_un.d_val, PREFIX_HEX);
11377 putchar ('\n');
11378 }
252b5132
RH
11379 }
11380 break;
11381
dcefbbbd 11382 case DT_FEATURE:
252b5132
RH
11383 if (do_dynamic)
11384 {
11385 printf (_("Flags:"));
86f55779 11386
252b5132
RH
11387 if (entry->d_un.d_val == 0)
11388 printf (_(" None\n"));
11389 else
11390 {
11391 unsigned long int val = entry->d_un.d_val;
86f55779 11392
252b5132
RH
11393 if (val & DTF_1_PARINIT)
11394 {
11395 printf (" PARINIT");
11396 val ^= DTF_1_PARINIT;
11397 }
dcefbbbd
L
11398 if (val & DTF_1_CONFEXP)
11399 {
11400 printf (" CONFEXP");
11401 val ^= DTF_1_CONFEXP;
11402 }
252b5132
RH
11403 if (val != 0)
11404 printf (" %lx", val);
11405 puts ("");
11406 }
11407 }
11408 break;
11409
11410 case DT_POSFLAG_1:
11411 if (do_dynamic)
11412 {
11413 printf (_("Flags:"));
86f55779 11414
252b5132
RH
11415 if (entry->d_un.d_val == 0)
11416 printf (_(" None\n"));
11417 else
11418 {
11419 unsigned long int val = entry->d_un.d_val;
86f55779 11420
252b5132
RH
11421 if (val & DF_P1_LAZYLOAD)
11422 {
11423 printf (" LAZYLOAD");
11424 val ^= DF_P1_LAZYLOAD;
11425 }
11426 if (val & DF_P1_GROUPPERM)
11427 {
11428 printf (" GROUPPERM");
11429 val ^= DF_P1_GROUPPERM;
11430 }
11431 if (val != 0)
11432 printf (" %lx", val);
11433 puts ("");
11434 }
11435 }
11436 break;
11437
11438 case DT_FLAGS_1:
11439 if (do_dynamic)
11440 {
11441 printf (_("Flags:"));
11442 if (entry->d_un.d_val == 0)
11443 printf (_(" None\n"));
11444 else
11445 {
11446 unsigned long int val = entry->d_un.d_val;
86f55779 11447
252b5132
RH
11448 if (val & DF_1_NOW)
11449 {
11450 printf (" NOW");
11451 val ^= DF_1_NOW;
11452 }
11453 if (val & DF_1_GLOBAL)
11454 {
11455 printf (" GLOBAL");
11456 val ^= DF_1_GLOBAL;
11457 }
11458 if (val & DF_1_GROUP)
11459 {
11460 printf (" GROUP");
11461 val ^= DF_1_GROUP;
11462 }
11463 if (val & DF_1_NODELETE)
11464 {
11465 printf (" NODELETE");
11466 val ^= DF_1_NODELETE;
11467 }
11468 if (val & DF_1_LOADFLTR)
11469 {
11470 printf (" LOADFLTR");
11471 val ^= DF_1_LOADFLTR;
11472 }
11473 if (val & DF_1_INITFIRST)
11474 {
11475 printf (" INITFIRST");
11476 val ^= DF_1_INITFIRST;
11477 }
11478 if (val & DF_1_NOOPEN)
11479 {
11480 printf (" NOOPEN");
11481 val ^= DF_1_NOOPEN;
11482 }
11483 if (val & DF_1_ORIGIN)
11484 {
11485 printf (" ORIGIN");
11486 val ^= DF_1_ORIGIN;
11487 }
11488 if (val & DF_1_DIRECT)
11489 {
11490 printf (" DIRECT");
11491 val ^= DF_1_DIRECT;
11492 }
11493 if (val & DF_1_TRANS)
11494 {
11495 printf (" TRANS");
11496 val ^= DF_1_TRANS;
11497 }
11498 if (val & DF_1_INTERPOSE)
11499 {
11500 printf (" INTERPOSE");
11501 val ^= DF_1_INTERPOSE;
11502 }
f7db6139 11503 if (val & DF_1_NODEFLIB)
dcefbbbd 11504 {
f7db6139
L
11505 printf (" NODEFLIB");
11506 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11507 }
11508 if (val & DF_1_NODUMP)
11509 {
11510 printf (" NODUMP");
11511 val ^= DF_1_NODUMP;
11512 }
34b60028 11513 if (val & DF_1_CONFALT)
dcefbbbd 11514 {
34b60028
L
11515 printf (" CONFALT");
11516 val ^= DF_1_CONFALT;
11517 }
11518 if (val & DF_1_ENDFILTEE)
11519 {
11520 printf (" ENDFILTEE");
11521 val ^= DF_1_ENDFILTEE;
11522 }
11523 if (val & DF_1_DISPRELDNE)
11524 {
11525 printf (" DISPRELDNE");
11526 val ^= DF_1_DISPRELDNE;
11527 }
11528 if (val & DF_1_DISPRELPND)
11529 {
11530 printf (" DISPRELPND");
11531 val ^= DF_1_DISPRELPND;
11532 }
11533 if (val & DF_1_NODIRECT)
11534 {
11535 printf (" NODIRECT");
11536 val ^= DF_1_NODIRECT;
11537 }
11538 if (val & DF_1_IGNMULDEF)
11539 {
11540 printf (" IGNMULDEF");
11541 val ^= DF_1_IGNMULDEF;
11542 }
11543 if (val & DF_1_NOKSYMS)
11544 {
11545 printf (" NOKSYMS");
11546 val ^= DF_1_NOKSYMS;
11547 }
11548 if (val & DF_1_NOHDR)
11549 {
11550 printf (" NOHDR");
11551 val ^= DF_1_NOHDR;
11552 }
11553 if (val & DF_1_EDITED)
11554 {
11555 printf (" EDITED");
11556 val ^= DF_1_EDITED;
11557 }
11558 if (val & DF_1_NORELOC)
11559 {
11560 printf (" NORELOC");
11561 val ^= DF_1_NORELOC;
11562 }
11563 if (val & DF_1_SYMINTPOSE)
11564 {
11565 printf (" SYMINTPOSE");
11566 val ^= DF_1_SYMINTPOSE;
11567 }
11568 if (val & DF_1_GLOBAUDIT)
11569 {
11570 printf (" GLOBAUDIT");
11571 val ^= DF_1_GLOBAUDIT;
11572 }
11573 if (val & DF_1_SINGLETON)
11574 {
11575 printf (" SINGLETON");
11576 val ^= DF_1_SINGLETON;
dcefbbbd 11577 }
5c383f02
RO
11578 if (val & DF_1_STUB)
11579 {
11580 printf (" STUB");
11581 val ^= DF_1_STUB;
11582 }
11583 if (val & DF_1_PIE)
11584 {
11585 printf (" PIE");
11586 val ^= DF_1_PIE;
11587 }
b1202ffa
L
11588 if (val & DF_1_KMOD)
11589 {
11590 printf (" KMOD");
11591 val ^= DF_1_KMOD;
11592 }
11593 if (val & DF_1_WEAKFILTER)
11594 {
11595 printf (" WEAKFILTER");
11596 val ^= DF_1_WEAKFILTER;
11597 }
11598 if (val & DF_1_NOCOMMON)
11599 {
11600 printf (" NOCOMMON");
11601 val ^= DF_1_NOCOMMON;
11602 }
252b5132
RH
11603 if (val != 0)
11604 printf (" %lx", val);
11605 puts ("");
11606 }
11607 }
11608 break;
11609
11610 case DT_PLTREL:
978c4450 11611 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11612 if (do_dynamic)
dda8d76d 11613 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11614 break;
11615
11616 case DT_NULL :
11617 case DT_NEEDED :
11618 case DT_PLTGOT :
11619 case DT_HASH :
11620 case DT_STRTAB :
11621 case DT_SYMTAB :
11622 case DT_RELA :
11623 case DT_INIT :
11624 case DT_FINI :
11625 case DT_SONAME :
11626 case DT_RPATH :
11627 case DT_SYMBOLIC:
11628 case DT_REL :
a7fd1186 11629 case DT_RELR :
252b5132
RH
11630 case DT_DEBUG :
11631 case DT_TEXTREL :
11632 case DT_JMPREL :
019148e4 11633 case DT_RUNPATH :
978c4450 11634 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11635
11636 if (do_dynamic)
11637 {
84714f86 11638 const char *name;
252b5132 11639
84714f86
AM
11640 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11641 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11642 else
d79b3d50 11643 name = NULL;
252b5132
RH
11644
11645 if (name)
11646 {
11647 switch (entry->d_tag)
11648 {
11649 case DT_NEEDED:
11650 printf (_("Shared library: [%s]"), name);
11651
13acb58d
AM
11652 if (filedata->program_interpreter
11653 && streq (name, filedata->program_interpreter))
f7a99963 11654 printf (_(" program interpreter"));
252b5132
RH
11655 break;
11656
11657 case DT_SONAME:
f7a99963 11658 printf (_("Library soname: [%s]"), name);
252b5132
RH
11659 break;
11660
11661 case DT_RPATH:
f7a99963 11662 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11663 break;
11664
019148e4
L
11665 case DT_RUNPATH:
11666 printf (_("Library runpath: [%s]"), name);
11667 break;
11668
252b5132 11669 default:
f7a99963
NC
11670 print_vma (entry->d_un.d_val, PREFIX_HEX);
11671 break;
252b5132
RH
11672 }
11673 }
11674 else
f7a99963
NC
11675 print_vma (entry->d_un.d_val, PREFIX_HEX);
11676
11677 putchar ('\n');
252b5132
RH
11678 }
11679 break;
11680
11681 case DT_PLTRELSZ:
11682 case DT_RELASZ :
11683 case DT_STRSZ :
11684 case DT_RELSZ :
11685 case DT_RELAENT :
a7fd1186
FS
11686 case DT_RELRENT :
11687 case DT_RELRSZ :
252b5132
RH
11688 case DT_SYMENT :
11689 case DT_RELENT :
978c4450 11690 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11691 /* Fall through. */
252b5132
RH
11692 case DT_PLTPADSZ:
11693 case DT_MOVEENT :
11694 case DT_MOVESZ :
04d8355a 11695 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11696 case DT_INIT_ARRAYSZ:
11697 case DT_FINI_ARRAYSZ:
047b2264
JJ
11698 case DT_GNU_CONFLICTSZ:
11699 case DT_GNU_LIBLISTSZ:
252b5132 11700 if (do_dynamic)
f7a99963
NC
11701 {
11702 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11703 printf (_(" (bytes)\n"));
f7a99963 11704 }
252b5132
RH
11705 break;
11706
11707 case DT_VERDEFNUM:
11708 case DT_VERNEEDNUM:
11709 case DT_RELACOUNT:
11710 case DT_RELCOUNT:
11711 if (do_dynamic)
f7a99963
NC
11712 {
11713 print_vma (entry->d_un.d_val, UNSIGNED);
11714 putchar ('\n');
11715 }
252b5132
RH
11716 break;
11717
11718 case DT_SYMINSZ:
11719 case DT_SYMINENT:
11720 case DT_SYMINFO:
11721 case DT_USED:
11722 case DT_INIT_ARRAY:
11723 case DT_FINI_ARRAY:
11724 if (do_dynamic)
11725 {
d79b3d50 11726 if (entry->d_tag == DT_USED
84714f86 11727 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11728 {
84714f86
AM
11729 const char *name
11730 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11731
b34976b6 11732 if (*name)
252b5132
RH
11733 {
11734 printf (_("Not needed object: [%s]\n"), name);
11735 break;
11736 }
11737 }
103f02d3 11738
f7a99963
NC
11739 print_vma (entry->d_un.d_val, PREFIX_HEX);
11740 putchar ('\n');
252b5132
RH
11741 }
11742 break;
11743
11744 case DT_BIND_NOW:
11745 /* The value of this entry is ignored. */
35b1837e
AM
11746 if (do_dynamic)
11747 putchar ('\n');
252b5132 11748 break;
103f02d3 11749
047b2264
JJ
11750 case DT_GNU_PRELINKED:
11751 if (do_dynamic)
11752 {
2cf0635d 11753 struct tm * tmp;
91d6fa6a 11754 time_t atime = entry->d_un.d_val;
047b2264 11755
91d6fa6a 11756 tmp = gmtime (&atime);
071436c6
NC
11757 /* PR 17533 file: 041-1244816-0.004. */
11758 if (tmp == NULL)
5a2cbcf4
L
11759 printf (_("<corrupt time val: %lx"),
11760 (unsigned long) atime);
071436c6
NC
11761 else
11762 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11763 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11764 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11765
11766 }
11767 break;
11768
fdc90cb4 11769 case DT_GNU_HASH:
978c4450 11770 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11771 if (do_dynamic)
11772 {
11773 print_vma (entry->d_un.d_val, PREFIX_HEX);
11774 putchar ('\n');
11775 }
11776 break;
11777
a5da3dee
VDM
11778 case DT_GNU_FLAGS_1:
11779 if (do_dynamic)
11780 {
11781 printf (_("Flags:"));
11782 if (entry->d_un.d_val == 0)
11783 printf (_(" None\n"));
11784 else
11785 {
11786 unsigned long int val = entry->d_un.d_val;
11787
11788 if (val & DF_GNU_1_UNIQUE)
11789 {
11790 printf (" UNIQUE");
11791 val ^= DF_GNU_1_UNIQUE;
11792 }
11793 if (val != 0)
11794 printf (" %lx", val);
11795 puts ("");
11796 }
11797 }
11798 break;
11799
252b5132
RH
11800 default:
11801 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11802 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11803 = entry->d_un.d_val;
252b5132
RH
11804
11805 if (do_dynamic)
11806 {
dda8d76d 11807 switch (filedata->file_header.e_machine)
252b5132 11808 {
37c18eed
SD
11809 case EM_AARCH64:
11810 dynamic_section_aarch64_val (entry);
11811 break;
252b5132 11812 case EM_MIPS:
4fe85591 11813 case EM_MIPS_RS3_LE:
978c4450 11814 dynamic_section_mips_val (filedata, entry);
252b5132 11815 break;
103f02d3 11816 case EM_PARISC:
b2d38a17 11817 dynamic_section_parisc_val (entry);
103f02d3 11818 break;
ecc51f48 11819 case EM_IA_64:
b2d38a17 11820 dynamic_section_ia64_val (entry);
ecc51f48 11821 break;
252b5132 11822 default:
f7a99963
NC
11823 print_vma (entry->d_un.d_val, PREFIX_HEX);
11824 putchar ('\n');
252b5132
RH
11825 }
11826 }
11827 break;
11828 }
11829 }
11830
015dc7e1 11831 return true;
252b5132
RH
11832}
11833
11834static char *
d3ba0551 11835get_ver_flags (unsigned int flags)
252b5132 11836{
6d4f21f6 11837 static char buff[128];
252b5132
RH
11838
11839 buff[0] = 0;
11840
11841 if (flags == 0)
11842 return _("none");
11843
11844 if (flags & VER_FLG_BASE)
7bb1ad17 11845 strcat (buff, "BASE");
252b5132
RH
11846
11847 if (flags & VER_FLG_WEAK)
11848 {
11849 if (flags & VER_FLG_BASE)
7bb1ad17 11850 strcat (buff, " | ");
252b5132 11851
7bb1ad17 11852 strcat (buff, "WEAK");
252b5132
RH
11853 }
11854
44ec90b9
RO
11855 if (flags & VER_FLG_INFO)
11856 {
11857 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11858 strcat (buff, " | ");
44ec90b9 11859
7bb1ad17 11860 strcat (buff, "INFO");
44ec90b9
RO
11861 }
11862
11863 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11864 {
11865 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11866 strcat (buff, " | ");
11867
11868 strcat (buff, _("<unknown>"));
11869 }
252b5132
RH
11870
11871 return buff;
11872}
11873
11874/* Display the contents of the version sections. */
98fb390a 11875
015dc7e1 11876static bool
dda8d76d 11877process_version_sections (Filedata * filedata)
252b5132 11878{
2cf0635d 11879 Elf_Internal_Shdr * section;
b34976b6 11880 unsigned i;
015dc7e1 11881 bool found = false;
252b5132
RH
11882
11883 if (! do_version)
015dc7e1 11884 return true;
252b5132 11885
dda8d76d
NC
11886 for (i = 0, section = filedata->section_headers;
11887 i < filedata->file_header.e_shnum;
b34976b6 11888 i++, section++)
252b5132
RH
11889 {
11890 switch (section->sh_type)
11891 {
11892 case SHT_GNU_verdef:
11893 {
2cf0635d 11894 Elf_External_Verdef * edefs;
452bf675
AM
11895 unsigned long idx;
11896 unsigned long cnt;
2cf0635d 11897 char * endbuf;
252b5132 11898
015dc7e1 11899 found = true;
252b5132 11900
ca0e11aa
NC
11901 if (filedata->is_separate)
11902 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11903 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11904 section->sh_info),
11905 filedata->file_name,
11906 printable_section_name (filedata, section),
11907 section->sh_info);
11908 else
11909 printf (ngettext ("\nVersion definition section '%s' "
11910 "contains %u entry:\n",
11911 "\nVersion definition section '%s' "
11912 "contains %u entries:\n",
11913 section->sh_info),
11914 printable_section_name (filedata, section),
11915 section->sh_info);
047c3dbf 11916
ae9ac79e 11917 printf (_(" Addr: 0x"));
252b5132 11918 printf_vma (section->sh_addr);
233f82cf 11919 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11920 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11921 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11922
3f5e193b 11923 edefs = (Elf_External_Verdef *)
dda8d76d 11924 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11925 _("version definition section"));
a6e9f9df
AM
11926 if (!edefs)
11927 break;
59245841 11928 endbuf = (char *) edefs + section->sh_size;
252b5132 11929
1445030f 11930 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11931 {
2cf0635d
NC
11932 char * vstart;
11933 Elf_External_Verdef * edef;
b34976b6 11934 Elf_Internal_Verdef ent;
2cf0635d 11935 Elf_External_Verdaux * eaux;
b34976b6 11936 Elf_Internal_Verdaux aux;
452bf675 11937 unsigned long isum;
b34976b6 11938 int j;
103f02d3 11939
252b5132 11940 vstart = ((char *) edefs) + idx;
54806181
AM
11941 if (vstart + sizeof (*edef) > endbuf)
11942 break;
252b5132
RH
11943
11944 edef = (Elf_External_Verdef *) vstart;
11945
11946 ent.vd_version = BYTE_GET (edef->vd_version);
11947 ent.vd_flags = BYTE_GET (edef->vd_flags);
11948 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11949 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11950 ent.vd_hash = BYTE_GET (edef->vd_hash);
11951 ent.vd_aux = BYTE_GET (edef->vd_aux);
11952 ent.vd_next = BYTE_GET (edef->vd_next);
11953
452bf675 11954 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11955 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11956
11957 printf (_(" Index: %d Cnt: %d "),
11958 ent.vd_ndx, ent.vd_cnt);
11959
452bf675 11960 /* Check for overflow. */
1445030f 11961 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11962 break;
11963
252b5132
RH
11964 vstart += ent.vd_aux;
11965
1445030f
AM
11966 if (vstart + sizeof (*eaux) > endbuf)
11967 break;
252b5132
RH
11968 eaux = (Elf_External_Verdaux *) vstart;
11969
11970 aux.vda_name = BYTE_GET (eaux->vda_name);
11971 aux.vda_next = BYTE_GET (eaux->vda_next);
11972
84714f86 11973 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 11974 printf (_("Name: %s\n"),
84714f86 11975 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
11976 else
11977 printf (_("Name index: %ld\n"), aux.vda_name);
11978
11979 isum = idx + ent.vd_aux;
11980
b34976b6 11981 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11982 {
1445030f
AM
11983 if (aux.vda_next < sizeof (*eaux)
11984 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11985 {
11986 warn (_("Invalid vda_next field of %lx\n"),
11987 aux.vda_next);
11988 j = ent.vd_cnt;
11989 break;
11990 }
dd24e3da 11991 /* Check for overflow. */
7e26601c 11992 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11993 break;
11994
252b5132
RH
11995 isum += aux.vda_next;
11996 vstart += aux.vda_next;
11997
54806181
AM
11998 if (vstart + sizeof (*eaux) > endbuf)
11999 break;
1445030f 12000 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12001
12002 aux.vda_name = BYTE_GET (eaux->vda_name);
12003 aux.vda_next = BYTE_GET (eaux->vda_next);
12004
84714f86 12005 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12006 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12007 isum, j,
84714f86 12008 get_dynamic_name (filedata, aux.vda_name));
252b5132 12009 else
452bf675 12010 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12011 isum, j, aux.vda_name);
12012 }
dd24e3da 12013
54806181
AM
12014 if (j < ent.vd_cnt)
12015 printf (_(" Version def aux past end of section\n"));
252b5132 12016
c9f02c3e
MR
12017 /* PR 17531:
12018 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12019 if (ent.vd_next < sizeof (*edef)
12020 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12021 {
12022 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12023 cnt = section->sh_info;
12024 break;
12025 }
452bf675 12026 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12027 break;
12028
252b5132
RH
12029 idx += ent.vd_next;
12030 }
dd24e3da 12031
54806181
AM
12032 if (cnt < section->sh_info)
12033 printf (_(" Version definition past end of section\n"));
252b5132
RH
12034
12035 free (edefs);
12036 }
12037 break;
103f02d3 12038
252b5132
RH
12039 case SHT_GNU_verneed:
12040 {
2cf0635d 12041 Elf_External_Verneed * eneed;
452bf675
AM
12042 unsigned long idx;
12043 unsigned long cnt;
2cf0635d 12044 char * endbuf;
252b5132 12045
015dc7e1 12046 found = true;
252b5132 12047
ca0e11aa
NC
12048 if (filedata->is_separate)
12049 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12050 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12051 section->sh_info),
12052 filedata->file_name,
12053 printable_section_name (filedata, section),
12054 section->sh_info);
12055 else
12056 printf (ngettext ("\nVersion needs section '%s' "
12057 "contains %u entry:\n",
12058 "\nVersion needs section '%s' "
12059 "contains %u entries:\n",
12060 section->sh_info),
12061 printable_section_name (filedata, section),
12062 section->sh_info);
047c3dbf 12063
252b5132
RH
12064 printf (_(" Addr: 0x"));
12065 printf_vma (section->sh_addr);
72de5009 12066 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12067 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12068 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12069
dda8d76d 12070 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12071 section->sh_offset, 1,
12072 section->sh_size,
9cf03b7e 12073 _("Version Needs section"));
a6e9f9df
AM
12074 if (!eneed)
12075 break;
59245841 12076 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12077
12078 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12079 {
2cf0635d 12080 Elf_External_Verneed * entry;
b34976b6 12081 Elf_Internal_Verneed ent;
452bf675 12082 unsigned long isum;
b34976b6 12083 int j;
2cf0635d 12084 char * vstart;
252b5132
RH
12085
12086 vstart = ((char *) eneed) + idx;
54806181
AM
12087 if (vstart + sizeof (*entry) > endbuf)
12088 break;
252b5132
RH
12089
12090 entry = (Elf_External_Verneed *) vstart;
12091
12092 ent.vn_version = BYTE_GET (entry->vn_version);
12093 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12094 ent.vn_file = BYTE_GET (entry->vn_file);
12095 ent.vn_aux = BYTE_GET (entry->vn_aux);
12096 ent.vn_next = BYTE_GET (entry->vn_next);
12097
452bf675 12098 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12099
84714f86 12100 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12101 printf (_(" File: %s"),
84714f86 12102 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12103 else
12104 printf (_(" File: %lx"), ent.vn_file);
12105
12106 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12107
dd24e3da 12108 /* Check for overflow. */
7e26601c 12109 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12110 break;
252b5132
RH
12111 vstart += ent.vn_aux;
12112
12113 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12114 {
2cf0635d 12115 Elf_External_Vernaux * eaux;
b34976b6 12116 Elf_Internal_Vernaux aux;
252b5132 12117
54806181
AM
12118 if (vstart + sizeof (*eaux) > endbuf)
12119 break;
252b5132
RH
12120 eaux = (Elf_External_Vernaux *) vstart;
12121
12122 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12123 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12124 aux.vna_other = BYTE_GET (eaux->vna_other);
12125 aux.vna_name = BYTE_GET (eaux->vna_name);
12126 aux.vna_next = BYTE_GET (eaux->vna_next);
12127
84714f86 12128 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12129 printf (_(" %#06lx: Name: %s"),
84714f86 12130 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12131 else
452bf675 12132 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12133 isum, aux.vna_name);
12134
12135 printf (_(" Flags: %s Version: %d\n"),
12136 get_ver_flags (aux.vna_flags), aux.vna_other);
12137
1445030f
AM
12138 if (aux.vna_next < sizeof (*eaux)
12139 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12140 {
12141 warn (_("Invalid vna_next field of %lx\n"),
12142 aux.vna_next);
12143 j = ent.vn_cnt;
12144 break;
12145 }
1445030f
AM
12146 /* Check for overflow. */
12147 if (aux.vna_next > (size_t) (endbuf - vstart))
12148 break;
252b5132
RH
12149 isum += aux.vna_next;
12150 vstart += aux.vna_next;
12151 }
9cf03b7e 12152
54806181 12153 if (j < ent.vn_cnt)
f9a6a8f0 12154 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12155
1445030f
AM
12156 if (ent.vn_next < sizeof (*entry)
12157 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12158 {
452bf675 12159 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12160 cnt = section->sh_info;
12161 break;
12162 }
1445030f
AM
12163 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12164 break;
252b5132
RH
12165 idx += ent.vn_next;
12166 }
9cf03b7e 12167
54806181 12168 if (cnt < section->sh_info)
9cf03b7e 12169 warn (_("Missing Version Needs information\n"));
103f02d3 12170
252b5132
RH
12171 free (eneed);
12172 }
12173 break;
12174
12175 case SHT_GNU_versym:
12176 {
2cf0635d 12177 Elf_Internal_Shdr * link_section;
8b73c356
NC
12178 size_t total;
12179 unsigned int cnt;
2cf0635d
NC
12180 unsigned char * edata;
12181 unsigned short * data;
12182 char * strtab;
12183 Elf_Internal_Sym * symbols;
12184 Elf_Internal_Shdr * string_sec;
ba5cdace 12185 unsigned long num_syms;
d3ba0551 12186 long off;
252b5132 12187
dda8d76d 12188 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12189 break;
12190
dda8d76d 12191 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12192 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12193
dda8d76d 12194 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12195 break;
12196
015dc7e1 12197 found = true;
252b5132 12198
4de91c10 12199 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12200 if (symbols == NULL)
12201 break;
252b5132 12202
dda8d76d 12203 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12204
dda8d76d 12205 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12206 string_sec->sh_size,
12207 _("version string table"));
a6e9f9df 12208 if (!strtab)
0429c154
MS
12209 {
12210 free (symbols);
12211 break;
12212 }
252b5132 12213
ca0e11aa
NC
12214 if (filedata->is_separate)
12215 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12216 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12217 total),
12218 filedata->file_name,
12219 printable_section_name (filedata, section),
12220 (unsigned long) total);
12221 else
12222 printf (ngettext ("\nVersion symbols section '%s' "
12223 "contains %lu entry:\n",
12224 "\nVersion symbols section '%s' "
12225 "contains %lu entries:\n",
12226 total),
12227 printable_section_name (filedata, section),
12228 (unsigned long) total);
252b5132 12229
ae9ac79e 12230 printf (_(" Addr: 0x"));
252b5132 12231 printf_vma (section->sh_addr);
72de5009 12232 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12233 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12234 printable_section_name (filedata, link_section));
252b5132 12235
dda8d76d 12236 off = offset_from_vma (filedata,
978c4450 12237 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12238 total * sizeof (short));
95099889
AM
12239 edata = (unsigned char *) get_data (NULL, filedata, off,
12240 sizeof (short), total,
12241 _("version symbol data"));
a6e9f9df
AM
12242 if (!edata)
12243 {
12244 free (strtab);
0429c154 12245 free (symbols);
a6e9f9df
AM
12246 break;
12247 }
252b5132 12248
3f5e193b 12249 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12250
12251 for (cnt = total; cnt --;)
b34976b6
AM
12252 data[cnt] = byte_get (edata + cnt * sizeof (short),
12253 sizeof (short));
252b5132
RH
12254
12255 free (edata);
12256
12257 for (cnt = 0; cnt < total; cnt += 4)
12258 {
12259 int j, nn;
ab273396
AM
12260 char *name;
12261 char *invalid = _("*invalid*");
252b5132
RH
12262
12263 printf (" %03x:", cnt);
12264
12265 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12266 switch (data[cnt + j])
252b5132
RH
12267 {
12268 case 0:
12269 fputs (_(" 0 (*local*) "), stdout);
12270 break;
12271
12272 case 1:
12273 fputs (_(" 1 (*global*) "), stdout);
12274 break;
12275
12276 default:
c244d050
NC
12277 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12278 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12279
dd24e3da 12280 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12281 array, break to avoid an out-of-bounds read. */
12282 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12283 {
12284 warn (_("invalid index into symbol array\n"));
12285 break;
12286 }
12287
ab273396 12288 name = NULL;
978c4450 12289 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12290 {
b34976b6
AM
12291 Elf_Internal_Verneed ivn;
12292 unsigned long offset;
252b5132 12293
d93f0186 12294 offset = offset_from_vma
978c4450
AM
12295 (filedata,
12296 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12297 sizeof (Elf_External_Verneed));
252b5132 12298
b34976b6 12299 do
252b5132 12300 {
b34976b6
AM
12301 Elf_Internal_Vernaux ivna;
12302 Elf_External_Verneed evn;
12303 Elf_External_Vernaux evna;
12304 unsigned long a_off;
252b5132 12305
dda8d76d 12306 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12307 _("version need")) == NULL)
12308 break;
0b4362b0 12309
252b5132
RH
12310 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12311 ivn.vn_next = BYTE_GET (evn.vn_next);
12312
12313 a_off = offset + ivn.vn_aux;
12314
12315 do
12316 {
dda8d76d 12317 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12318 1, _("version need aux (2)")) == NULL)
12319 {
12320 ivna.vna_next = 0;
12321 ivna.vna_other = 0;
12322 }
12323 else
12324 {
12325 ivna.vna_next = BYTE_GET (evna.vna_next);
12326 ivna.vna_other = BYTE_GET (evna.vna_other);
12327 }
252b5132
RH
12328
12329 a_off += ivna.vna_next;
12330 }
b34976b6 12331 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12332 && ivna.vna_next != 0);
12333
b34976b6 12334 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12335 {
12336 ivna.vna_name = BYTE_GET (evna.vna_name);
12337
54806181 12338 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12339 name = invalid;
54806181
AM
12340 else
12341 name = strtab + ivna.vna_name;
252b5132
RH
12342 break;
12343 }
12344
12345 offset += ivn.vn_next;
12346 }
12347 while (ivn.vn_next);
12348 }
00d93f34 12349
ab273396 12350 if (data[cnt + j] != 0x8001
978c4450 12351 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12352 {
b34976b6
AM
12353 Elf_Internal_Verdef ivd;
12354 Elf_External_Verdef evd;
12355 unsigned long offset;
252b5132 12356
d93f0186 12357 offset = offset_from_vma
978c4450
AM
12358 (filedata,
12359 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12360 sizeof evd);
252b5132
RH
12361
12362 do
12363 {
dda8d76d 12364 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12365 _("version def")) == NULL)
12366 {
12367 ivd.vd_next = 0;
948f632f 12368 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12369 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12370 break;
59245841
NC
12371 }
12372 else
12373 {
12374 ivd.vd_next = BYTE_GET (evd.vd_next);
12375 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12376 }
252b5132
RH
12377
12378 offset += ivd.vd_next;
12379 }
c244d050 12380 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12381 && ivd.vd_next != 0);
12382
c244d050 12383 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12384 {
b34976b6
AM
12385 Elf_External_Verdaux evda;
12386 Elf_Internal_Verdaux ivda;
252b5132
RH
12387
12388 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12389
dda8d76d 12390 if (get_data (&evda, filedata,
59245841
NC
12391 offset - ivd.vd_next + ivd.vd_aux,
12392 sizeof (evda), 1,
12393 _("version def aux")) == NULL)
12394 break;
252b5132
RH
12395
12396 ivda.vda_name = BYTE_GET (evda.vda_name);
12397
54806181 12398 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12399 name = invalid;
12400 else if (name != NULL && name != invalid)
12401 name = _("*both*");
54806181
AM
12402 else
12403 name = strtab + ivda.vda_name;
252b5132
RH
12404 }
12405 }
ab273396
AM
12406 if (name != NULL)
12407 nn += printf ("(%s%-*s",
12408 name,
12409 12 - (int) strlen (name),
12410 ")");
252b5132
RH
12411
12412 if (nn < 18)
12413 printf ("%*c", 18 - nn, ' ');
12414 }
12415
12416 putchar ('\n');
12417 }
12418
12419 free (data);
12420 free (strtab);
12421 free (symbols);
12422 }
12423 break;
103f02d3 12424
252b5132
RH
12425 default:
12426 break;
12427 }
12428 }
12429
12430 if (! found)
ca0e11aa
NC
12431 {
12432 if (filedata->is_separate)
12433 printf (_("\nNo version information found in linked file '%s'.\n"),
12434 filedata->file_name);
12435 else
12436 printf (_("\nNo version information found in this file.\n"));
12437 }
252b5132 12438
015dc7e1 12439 return true;
252b5132
RH
12440}
12441
d1133906 12442static const char *
dda8d76d 12443get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12444{
89246a0e 12445 static char buff[64];
252b5132
RH
12446
12447 switch (binding)
12448 {
b34976b6
AM
12449 case STB_LOCAL: return "LOCAL";
12450 case STB_GLOBAL: return "GLOBAL";
12451 case STB_WEAK: return "WEAK";
252b5132
RH
12452 default:
12453 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12454 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12455 binding);
252b5132 12456 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12457 {
12458 if (binding == STB_GNU_UNIQUE
df3a023b 12459 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12460 return "UNIQUE";
12461 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12462 }
252b5132 12463 else
e9e44622 12464 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12465 return buff;
12466 }
12467}
12468
d1133906 12469static const char *
dda8d76d 12470get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12471{
89246a0e 12472 static char buff[64];
252b5132
RH
12473
12474 switch (type)
12475 {
b34976b6
AM
12476 case STT_NOTYPE: return "NOTYPE";
12477 case STT_OBJECT: return "OBJECT";
12478 case STT_FUNC: return "FUNC";
12479 case STT_SECTION: return "SECTION";
12480 case STT_FILE: return "FILE";
12481 case STT_COMMON: return "COMMON";
12482 case STT_TLS: return "TLS";
15ab5209
DB
12483 case STT_RELC: return "RELC";
12484 case STT_SRELC: return "SRELC";
252b5132
RH
12485 default:
12486 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12487 {
dda8d76d 12488 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12489 return "THUMB_FUNC";
103f02d3 12490
dda8d76d 12491 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12492 return "REGISTER";
12493
dda8d76d 12494 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12495 return "PARISC_MILLI";
12496
e9e44622 12497 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12498 }
252b5132 12499 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12500 {
dda8d76d 12501 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12502 {
12503 if (type == STT_HP_OPAQUE)
12504 return "HP_OPAQUE";
12505 if (type == STT_HP_STUB)
12506 return "HP_STUB";
12507 }
12508
d8045f23 12509 if (type == STT_GNU_IFUNC
dda8d76d 12510 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12511 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12512 return "IFUNC";
12513
e9e44622 12514 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12515 }
252b5132 12516 else
e9e44622 12517 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12518 return buff;
12519 }
12520}
12521
d1133906 12522static const char *
d3ba0551 12523get_symbol_visibility (unsigned int visibility)
d1133906
NC
12524{
12525 switch (visibility)
12526 {
b34976b6
AM
12527 case STV_DEFAULT: return "DEFAULT";
12528 case STV_INTERNAL: return "INTERNAL";
12529 case STV_HIDDEN: return "HIDDEN";
d1133906 12530 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12531 default:
27a45f42 12532 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12533 return _("<unknown>");
d1133906
NC
12534 }
12535}
12536
2057d69d
CZ
12537static const char *
12538get_alpha_symbol_other (unsigned int other)
9abca702 12539{
2057d69d
CZ
12540 switch (other)
12541 {
12542 case STO_ALPHA_NOPV: return "NOPV";
12543 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12544 default:
27a45f42 12545 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12546 return _("<unknown>");
9abca702 12547 }
2057d69d
CZ
12548}
12549
fd85a6a1
NC
12550static const char *
12551get_solaris_symbol_visibility (unsigned int visibility)
12552{
12553 switch (visibility)
12554 {
12555 case 4: return "EXPORTED";
12556 case 5: return "SINGLETON";
12557 case 6: return "ELIMINATE";
12558 default: return get_symbol_visibility (visibility);
12559 }
12560}
12561
2301ed1c
SN
12562static const char *
12563get_aarch64_symbol_other (unsigned int other)
12564{
12565 static char buf[32];
12566
12567 if (other & STO_AARCH64_VARIANT_PCS)
12568 {
12569 other &= ~STO_AARCH64_VARIANT_PCS;
12570 if (other == 0)
12571 return "VARIANT_PCS";
12572 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12573 return buf;
12574 }
12575 return NULL;
12576}
12577
5e2b0d47
NC
12578static const char *
12579get_mips_symbol_other (unsigned int other)
12580{
12581 switch (other)
12582 {
32ec8896
NC
12583 case STO_OPTIONAL: return "OPTIONAL";
12584 case STO_MIPS_PLT: return "MIPS PLT";
12585 case STO_MIPS_PIC: return "MIPS PIC";
12586 case STO_MICROMIPS: return "MICROMIPS";
12587 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12588 case STO_MIPS16: return "MIPS16";
12589 default: return NULL;
5e2b0d47
NC
12590 }
12591}
12592
28f997cf 12593static const char *
dda8d76d 12594get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12595{
dda8d76d 12596 if (is_ia64_vms (filedata))
28f997cf
TG
12597 {
12598 static char res[32];
12599
12600 res[0] = 0;
12601
12602 /* Function types is for images and .STB files only. */
dda8d76d 12603 switch (filedata->file_header.e_type)
28f997cf
TG
12604 {
12605 case ET_DYN:
12606 case ET_EXEC:
12607 switch (VMS_ST_FUNC_TYPE (other))
12608 {
12609 case VMS_SFT_CODE_ADDR:
12610 strcat (res, " CA");
12611 break;
12612 case VMS_SFT_SYMV_IDX:
12613 strcat (res, " VEC");
12614 break;
12615 case VMS_SFT_FD:
12616 strcat (res, " FD");
12617 break;
12618 case VMS_SFT_RESERVE:
12619 strcat (res, " RSV");
12620 break;
12621 default:
bee0ee85
NC
12622 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12623 VMS_ST_FUNC_TYPE (other));
12624 strcat (res, " <unknown>");
12625 break;
28f997cf
TG
12626 }
12627 break;
12628 default:
12629 break;
12630 }
12631 switch (VMS_ST_LINKAGE (other))
12632 {
12633 case VMS_STL_IGNORE:
12634 strcat (res, " IGN");
12635 break;
12636 case VMS_STL_RESERVE:
12637 strcat (res, " RSV");
12638 break;
12639 case VMS_STL_STD:
12640 strcat (res, " STD");
12641 break;
12642 case VMS_STL_LNK:
12643 strcat (res, " LNK");
12644 break;
12645 default:
bee0ee85
NC
12646 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12647 VMS_ST_LINKAGE (other));
12648 strcat (res, " <unknown>");
12649 break;
28f997cf
TG
12650 }
12651
12652 if (res[0] != 0)
12653 return res + 1;
12654 else
12655 return res;
12656 }
12657 return NULL;
12658}
12659
6911b7dc
AM
12660static const char *
12661get_ppc64_symbol_other (unsigned int other)
12662{
14732552
AM
12663 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12664 return NULL;
12665
12666 other >>= STO_PPC64_LOCAL_BIT;
12667 if (other <= 6)
6911b7dc 12668 {
89246a0e 12669 static char buf[64];
14732552
AM
12670 if (other >= 2)
12671 other = ppc64_decode_local_entry (other);
12672 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12673 return buf;
12674 }
12675 return NULL;
12676}
12677
8155b853
NC
12678static const char *
12679get_riscv_symbol_other (unsigned int other)
12680{
12681 static char buf[32];
12682 buf[0] = 0;
12683
12684 if (other & STO_RISCV_VARIANT_CC)
12685 {
12686 strcat (buf, _(" VARIANT_CC"));
12687 other &= ~STO_RISCV_VARIANT_CC;
12688 }
12689
12690 if (other != 0)
12691 snprintf (buf, sizeof buf, " %x", other);
12692
12693
12694 if (buf[0] != 0)
12695 return buf + 1;
12696 else
12697 return buf;
12698}
12699
5e2b0d47 12700static const char *
dda8d76d 12701get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12702{
12703 const char * result = NULL;
89246a0e 12704 static char buff [64];
5e2b0d47
NC
12705
12706 if (other == 0)
12707 return "";
12708
dda8d76d 12709 switch (filedata->file_header.e_machine)
5e2b0d47 12710 {
2057d69d
CZ
12711 case EM_ALPHA:
12712 result = get_alpha_symbol_other (other);
12713 break;
2301ed1c
SN
12714 case EM_AARCH64:
12715 result = get_aarch64_symbol_other (other);
12716 break;
5e2b0d47
NC
12717 case EM_MIPS:
12718 result = get_mips_symbol_other (other);
28f997cf
TG
12719 break;
12720 case EM_IA_64:
dda8d76d 12721 result = get_ia64_symbol_other (filedata, other);
28f997cf 12722 break;
6911b7dc
AM
12723 case EM_PPC64:
12724 result = get_ppc64_symbol_other (other);
12725 break;
8155b853
NC
12726 case EM_RISCV:
12727 result = get_riscv_symbol_other (other);
12728 break;
5e2b0d47 12729 default:
fd85a6a1 12730 result = NULL;
5e2b0d47
NC
12731 break;
12732 }
12733
12734 if (result)
12735 return result;
12736
12737 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12738 return buff;
12739}
12740
d1133906 12741static const char *
dda8d76d 12742get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12743{
b34976b6 12744 static char buff[32];
5cf1065c 12745
252b5132
RH
12746 switch (type)
12747 {
b34976b6
AM
12748 case SHN_UNDEF: return "UND";
12749 case SHN_ABS: return "ABS";
12750 case SHN_COMMON: return "COM";
252b5132 12751 default:
9ce701e2 12752 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12753 && filedata->file_header.e_machine == EM_IA_64
12754 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12755 return "ANSI_COM";
12756 else if ((filedata->file_header.e_machine == EM_X86_64
12757 || filedata->file_header.e_machine == EM_L1OM
12758 || filedata->file_header.e_machine == EM_K1OM)
12759 && type == SHN_X86_64_LCOMMON)
12760 return "LARGE_COM";
12761 else if ((type == SHN_MIPS_SCOMMON
12762 && filedata->file_header.e_machine == EM_MIPS)
12763 || (type == SHN_TIC6X_SCOMMON
12764 && filedata->file_header.e_machine == EM_TI_C6000))
12765 return "SCOM";
12766 else if (type == SHN_MIPS_SUNDEFINED
12767 && filedata->file_header.e_machine == EM_MIPS)
12768 return "SUND";
12769 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12770 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12771 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12772 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12773 else if (type >= SHN_LORESERVE)
12774 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12775 else if (filedata->file_header.e_shnum != 0
12776 && type >= filedata->file_header.e_shnum)
12777 sprintf (buff, _("bad section index[%3d]"), type);
12778 else
12779 sprintf (buff, "%3d", type);
12780 break;
fd85a6a1
NC
12781 }
12782
10ca4b04 12783 return buff;
6bd1a22c
L
12784}
12785
bb4d2ac2 12786static const char *
dda8d76d 12787get_symbol_version_string (Filedata * filedata,
015dc7e1 12788 bool is_dynsym,
1449284b
NC
12789 const char * strtab,
12790 unsigned long int strtab_size,
12791 unsigned int si,
12792 Elf_Internal_Sym * psym,
12793 enum versioned_symbol_info * sym_info,
12794 unsigned short * vna_other)
bb4d2ac2 12795{
ab273396
AM
12796 unsigned char data[2];
12797 unsigned short vers_data;
12798 unsigned long offset;
7a815dd5 12799 unsigned short max_vd_ndx;
bb4d2ac2 12800
ab273396 12801 if (!is_dynsym
978c4450 12802 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12803 return NULL;
bb4d2ac2 12804
978c4450
AM
12805 offset = offset_from_vma (filedata,
12806 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12807 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12808
dda8d76d 12809 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12810 sizeof (data), 1, _("version data")) == NULL)
12811 return NULL;
12812
12813 vers_data = byte_get (data, 2);
bb4d2ac2 12814
1f6f5dba 12815 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12816 return NULL;
bb4d2ac2 12817
0b8b7609 12818 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12819 max_vd_ndx = 0;
12820
ab273396
AM
12821 /* Usually we'd only see verdef for defined symbols, and verneed for
12822 undefined symbols. However, symbols defined by the linker in
12823 .dynbss for variables copied from a shared library in order to
12824 avoid text relocations are defined yet have verneed. We could
12825 use a heuristic to detect the special case, for example, check
12826 for verneed first on symbols defined in SHT_NOBITS sections, but
12827 it is simpler and more reliable to just look for both verdef and
12828 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12829
ab273396
AM
12830 if (psym->st_shndx != SHN_UNDEF
12831 && vers_data != 0x8001
978c4450 12832 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12833 {
12834 Elf_Internal_Verdef ivd;
12835 Elf_Internal_Verdaux ivda;
12836 Elf_External_Verdaux evda;
12837 unsigned long off;
bb4d2ac2 12838
dda8d76d 12839 off = offset_from_vma (filedata,
978c4450 12840 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12841 sizeof (Elf_External_Verdef));
12842
12843 do
bb4d2ac2 12844 {
ab273396
AM
12845 Elf_External_Verdef evd;
12846
dda8d76d 12847 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12848 _("version def")) == NULL)
12849 {
12850 ivd.vd_ndx = 0;
12851 ivd.vd_aux = 0;
12852 ivd.vd_next = 0;
1f6f5dba 12853 ivd.vd_flags = 0;
ab273396
AM
12854 }
12855 else
bb4d2ac2 12856 {
ab273396
AM
12857 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12858 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12859 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12860 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12861 }
bb4d2ac2 12862
7a815dd5
L
12863 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12864 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12865
ab273396
AM
12866 off += ivd.vd_next;
12867 }
12868 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12869
ab273396
AM
12870 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12871 {
9abca702 12872 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12873 return NULL;
12874
ab273396
AM
12875 off -= ivd.vd_next;
12876 off += ivd.vd_aux;
bb4d2ac2 12877
dda8d76d 12878 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12879 _("version def aux")) != NULL)
12880 {
12881 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12882
ab273396 12883 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12884 return (ivda.vda_name < strtab_size
12885 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12886 }
12887 }
12888 }
bb4d2ac2 12889
978c4450 12890 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12891 {
12892 Elf_External_Verneed evn;
12893 Elf_Internal_Verneed ivn;
12894 Elf_Internal_Vernaux ivna;
bb4d2ac2 12895
dda8d76d 12896 offset = offset_from_vma (filedata,
978c4450 12897 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12898 sizeof evn);
12899 do
12900 {
12901 unsigned long vna_off;
bb4d2ac2 12902
dda8d76d 12903 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12904 _("version need")) == NULL)
12905 {
12906 ivna.vna_next = 0;
12907 ivna.vna_other = 0;
12908 ivna.vna_name = 0;
12909 break;
12910 }
bb4d2ac2 12911
ab273396
AM
12912 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12913 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12914
ab273396 12915 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12916
ab273396
AM
12917 do
12918 {
12919 Elf_External_Vernaux evna;
bb4d2ac2 12920
dda8d76d 12921 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12922 _("version need aux (3)")) == NULL)
bb4d2ac2 12923 {
ab273396
AM
12924 ivna.vna_next = 0;
12925 ivna.vna_other = 0;
12926 ivna.vna_name = 0;
bb4d2ac2 12927 }
bb4d2ac2 12928 else
bb4d2ac2 12929 {
ab273396
AM
12930 ivna.vna_other = BYTE_GET (evna.vna_other);
12931 ivna.vna_next = BYTE_GET (evna.vna_next);
12932 ivna.vna_name = BYTE_GET (evna.vna_name);
12933 }
bb4d2ac2 12934
ab273396
AM
12935 vna_off += ivna.vna_next;
12936 }
12937 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12938
ab273396
AM
12939 if (ivna.vna_other == vers_data)
12940 break;
bb4d2ac2 12941
ab273396
AM
12942 offset += ivn.vn_next;
12943 }
12944 while (ivn.vn_next != 0);
bb4d2ac2 12945
ab273396
AM
12946 if (ivna.vna_other == vers_data)
12947 {
12948 *sym_info = symbol_undefined;
12949 *vna_other = ivna.vna_other;
12950 return (ivna.vna_name < strtab_size
12951 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12952 }
7a815dd5
L
12953 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12954 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12955 return _("<corrupt>");
bb4d2ac2 12956 }
ab273396 12957 return NULL;
bb4d2ac2
L
12958}
12959
047c3dbf
NL
12960/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12961
12962static unsigned int
12963print_dynamic_symbol_size (bfd_vma vma, int base)
12964{
12965 switch (base)
12966 {
12967 case 8:
12968 return print_vma (vma, OCTAL_5);
12969
12970 case 10:
12971 return print_vma (vma, UNSIGNED_5);
12972
12973 case 16:
12974 return print_vma (vma, PREFIX_HEX_5);
12975
12976 case 0:
12977 default:
12978 return print_vma (vma, DEC_5);
12979 }
12980}
12981
10ca4b04
L
12982static void
12983print_dynamic_symbol (Filedata *filedata, unsigned long si,
12984 Elf_Internal_Sym *symtab,
12985 Elf_Internal_Shdr *section,
12986 char *strtab, size_t strtab_size)
252b5132 12987{
10ca4b04
L
12988 const char *version_string;
12989 enum versioned_symbol_info sym_info;
12990 unsigned short vna_other;
23356397
NC
12991 bool is_valid;
12992 const char * sstr;
10ca4b04 12993 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12994
10ca4b04
L
12995 printf ("%6ld: ", si);
12996 print_vma (psym->st_value, LONG_HEX);
12997 putchar (' ');
047c3dbf 12998 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12999 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13000 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13001 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13002 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13003 else
252b5132 13004 {
10ca4b04 13005 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13006
10ca4b04
L
13007 printf (" %-7s", get_symbol_visibility (vis));
13008 /* Check to see if any other bits in the st_other field are set.
13009 Note - displaying this information disrupts the layout of the
13010 table being generated, but for the moment this case is very rare. */
13011 if (psym->st_other ^ vis)
13012 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13013 }
10ca4b04 13014 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13015
23356397
NC
13016 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13017 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13018 && filedata->section_headers != NULL
23356397
NC
13019 && psym->st_name == 0)
13020 {
84714f86
AM
13021 is_valid
13022 = section_name_valid (filedata,
13023 filedata->section_headers + psym->st_shndx);
23356397 13024 sstr = is_valid ?
84714f86
AM
13025 section_name_print (filedata,
13026 filedata->section_headers + psym->st_shndx)
23356397
NC
13027 : _("<corrupt>");
13028 }
13029 else
13030 {
84714f86 13031 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13032 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13033 }
10ca4b04
L
13034
13035 version_string
13036 = get_symbol_version_string (filedata,
13037 (section == NULL
13038 || section->sh_type == SHT_DYNSYM),
13039 strtab, strtab_size, si,
13040 psym, &sym_info, &vna_other);
b9e920ec 13041
0942c7ab
NC
13042 int len_avail = 21;
13043 if (! do_wide && version_string != NULL)
13044 {
ddb43bab 13045 char buffer[16];
0942c7ab 13046
ddb43bab 13047 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13048
13049 if (sym_info == symbol_undefined)
13050 len_avail -= sprintf (buffer," (%d)", vna_other);
13051 else if (sym_info != symbol_hidden)
13052 len_avail -= 1;
13053 }
13054
13055 print_symbol (len_avail, sstr);
b9e920ec 13056
10ca4b04
L
13057 if (version_string)
13058 {
13059 if (sym_info == symbol_undefined)
13060 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13061 else
10ca4b04
L
13062 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13063 version_string);
13064 }
6bd1a22c 13065
10ca4b04 13066 putchar ('\n');
6bd1a22c 13067
10ca4b04
L
13068 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13069 && section != NULL
13070 && si >= section->sh_info
13071 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13072 && filedata->file_header.e_machine != EM_MIPS
13073 /* Solaris binaries have been found to violate this requirement as
13074 well. Not sure if this is a bug or an ABI requirement. */
13075 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13076 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13077 si, printable_section_name (filedata, section), section->sh_info);
13078}
f16a9783 13079
0f03783c
NC
13080static const char *
13081get_lto_kind (unsigned int kind)
13082{
13083 switch (kind)
13084 {
13085 case 0: return "DEF";
13086 case 1: return "WEAKDEF";
13087 case 2: return "UNDEF";
13088 case 3: return "WEAKUNDEF";
13089 case 4: return "COMMON";
13090 default:
13091 break;
13092 }
13093
13094 static char buffer[30];
13095 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13096 sprintf (buffer, "<unknown: %u>", kind);
13097 return buffer;
13098}
13099
13100static const char *
13101get_lto_visibility (unsigned int visibility)
13102{
13103 switch (visibility)
13104 {
13105 case 0: return "DEFAULT";
13106 case 1: return "PROTECTED";
13107 case 2: return "INTERNAL";
13108 case 3: return "HIDDEN";
13109 default:
13110 break;
13111 }
13112
13113 static char buffer[30];
13114 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13115 sprintf (buffer, "<unknown: %u>", visibility);
13116 return buffer;
13117}
13118
13119static const char *
13120get_lto_sym_type (unsigned int sym_type)
13121{
13122 switch (sym_type)
13123 {
13124 case 0: return "UNKNOWN";
13125 case 1: return "FUNCTION";
13126 case 2: return "VARIABLE";
13127 default:
13128 break;
13129 }
13130
13131 static char buffer[30];
13132 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13133 sprintf (buffer, "<unknown: %u>", sym_type);
13134 return buffer;
13135}
13136
13137/* Display an LTO format symbol table.
13138 FIXME: The format of LTO symbol tables is not formalized.
13139 So this code could need changing in the future. */
13140
015dc7e1 13141static bool
0f03783c
NC
13142display_lto_symtab (Filedata * filedata,
13143 Elf_Internal_Shdr * section)
13144{
13145 if (section->sh_size == 0)
13146 {
ca0e11aa
NC
13147 if (filedata->is_separate)
13148 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13149 printable_section_name (filedata, section),
13150 filedata->file_name);
13151 else
13152 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13153 printable_section_name (filedata, section));
047c3dbf 13154
015dc7e1 13155 return true;
0f03783c
NC
13156 }
13157
13158 if (section->sh_size > filedata->file_size)
13159 {
13160 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13161 printable_section_name (filedata, section),
13162 (unsigned long) section->sh_size);
015dc7e1 13163 return false;
0f03783c
NC
13164 }
13165
13166 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13167 section->sh_size, 1, _("LTO symbols"));
13168 if (alloced_data == NULL)
015dc7e1 13169 return false;
0f03783c
NC
13170
13171 /* Look for extended data for the symbol table. */
13172 Elf_Internal_Shdr * ext;
13173 void * ext_data_orig = NULL;
13174 char * ext_data = NULL;
13175 char * ext_data_end = NULL;
13176 char * ext_name = NULL;
13177
13178 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13179 (section_name (filedata, section)
13180 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13181 && ext_name != NULL /* Paranoia. */
13182 && (ext = find_section (filedata, ext_name)) != NULL)
13183 {
13184 if (ext->sh_size < 3)
13185 error (_("LTO Symbol extension table '%s' is empty!\n"),
13186 printable_section_name (filedata, ext));
13187 else
13188 {
13189 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13190 ext->sh_size, 1,
13191 _("LTO ext symbol data"));
13192 if (ext_data != NULL)
13193 {
13194 ext_data_end = ext_data + ext->sh_size;
13195 if (* ext_data++ != 1)
13196 error (_("Unexpected version number in symbol extension table\n"));
13197 }
13198 }
13199 }
b9e920ec 13200
0f03783c
NC
13201 const unsigned char * data = (const unsigned char *) alloced_data;
13202 const unsigned char * end = data + section->sh_size;
13203
ca0e11aa
NC
13204 if (filedata->is_separate)
13205 printf (_("\nIn linked file '%s': "), filedata->file_name);
13206 else
13207 printf ("\n");
13208
0f03783c
NC
13209 if (ext_data_orig != NULL)
13210 {
13211 if (do_wide)
ca0e11aa 13212 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13213 printable_section_name (filedata, section),
13214 printable_section_name (filedata, ext));
13215 else
13216 {
ca0e11aa 13217 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13218 printable_section_name (filedata, section));
13219 printf (_(" and extension table '%s' contain:\n"),
13220 printable_section_name (filedata, ext));
13221 }
13222 }
13223 else
ca0e11aa 13224 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13225 printable_section_name (filedata, section));
b9e920ec 13226
0f03783c 13227 /* FIXME: Add a wide version. */
b9e920ec 13228 if (ext_data_orig != NULL)
0f03783c
NC
13229 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13230 else
13231 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13232
13233 /* FIXME: We do not handle style prefixes. */
13234
13235 while (data < end)
13236 {
13237 const unsigned char * sym_name = data;
13238 data += strnlen ((const char *) sym_name, end - data) + 1;
13239 if (data >= end)
13240 goto fail;
13241
13242 const unsigned char * comdat_key = data;
13243 data += strnlen ((const char *) comdat_key, end - data) + 1;
13244 if (data >= end)
13245 goto fail;
13246
13247 if (data + 2 + 8 + 4 > end)
13248 goto fail;
13249
13250 unsigned int kind = *data++;
13251 unsigned int visibility = *data++;
13252
13253 elf_vma size = byte_get (data, 8);
13254 data += 8;
13255
13256 elf_vma slot = byte_get (data, 4);
13257 data += 4;
13258
13259 if (ext_data != NULL)
13260 {
13261 if (ext_data < (ext_data_end - 1))
13262 {
13263 unsigned int sym_type = * ext_data ++;
13264 unsigned int sec_kind = * ext_data ++;
13265
13266 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13267 * comdat_key == 0 ? "-" : (char *) comdat_key,
13268 get_lto_kind (kind),
13269 get_lto_visibility (visibility),
13270 (long) size,
13271 (long) slot,
13272 get_lto_sym_type (sym_type),
13273 (long) sec_kind);
13274 print_symbol (6, (const char *) sym_name);
13275 }
13276 else
13277 {
13278 error (_("Ran out of LTO symbol extension data\n"));
13279 ext_data = NULL;
13280 /* FIXME: return FAIL result ? */
13281 }
13282 }
13283 else
13284 {
13285 printf (" %10s %10s %11s %08lx %08lx _",
13286 * comdat_key == 0 ? "-" : (char *) comdat_key,
13287 get_lto_kind (kind),
13288 get_lto_visibility (visibility),
13289 (long) size,
13290 (long) slot);
13291 print_symbol (21, (const char *) sym_name);
13292 }
13293 putchar ('\n');
13294 }
13295
13296 if (ext_data != NULL && ext_data < ext_data_end)
13297 {
13298 error (_("Data remains in the LTO symbol extension table\n"));
13299 goto fail;
13300 }
13301
13302 free (alloced_data);
13303 free (ext_data_orig);
13304 free (ext_name);
015dc7e1 13305 return true;
b9e920ec 13306
0f03783c
NC
13307 fail:
13308 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13309 free (alloced_data);
13310 free (ext_data_orig);
13311 free (ext_name);
015dc7e1 13312 return false;
0f03783c
NC
13313}
13314
13315/* Display LTO symbol tables. */
13316
015dc7e1 13317static bool
0f03783c
NC
13318process_lto_symbol_tables (Filedata * filedata)
13319{
13320 Elf_Internal_Shdr * section;
13321 unsigned int i;
015dc7e1 13322 bool res = true;
0f03783c
NC
13323
13324 if (!do_lto_syms)
015dc7e1 13325 return true;
0f03783c
NC
13326
13327 if (filedata->section_headers == NULL)
015dc7e1 13328 return true;
0f03783c
NC
13329
13330 for (i = 0, section = filedata->section_headers;
13331 i < filedata->file_header.e_shnum;
13332 i++, section++)
84714f86
AM
13333 if (section_name_valid (filedata, section)
13334 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13335 res &= display_lto_symtab (filedata, section);
13336
b9e920ec 13337 return res;
0f03783c
NC
13338}
13339
10ca4b04 13340/* Dump the symbol table. */
0f03783c 13341
015dc7e1 13342static bool
10ca4b04
L
13343process_symbol_table (Filedata * filedata)
13344{
13345 Elf_Internal_Shdr * section;
f16a9783 13346
10ca4b04 13347 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13348 return true;
6bd1a22c 13349
978c4450 13350 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13351 && do_syms
13352 && do_using_dynamic
978c4450
AM
13353 && filedata->dynamic_strings != NULL
13354 && filedata->dynamic_symbols != NULL)
6bd1a22c 13355 {
10ca4b04 13356 unsigned long si;
6bd1a22c 13357
ca0e11aa
NC
13358 if (filedata->is_separate)
13359 {
13360 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13361 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13362 filedata->num_dynamic_syms),
13363 filedata->file_name,
13364 filedata->num_dynamic_syms);
13365 }
13366 else
13367 {
13368 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13369 "\nSymbol table for image contains %lu entries:\n",
13370 filedata->num_dynamic_syms),
13371 filedata->num_dynamic_syms);
13372 }
10ca4b04
L
13373 if (is_32bit_elf)
13374 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13375 else
13376 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13377
978c4450
AM
13378 for (si = 0; si < filedata->num_dynamic_syms; si++)
13379 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13380 filedata->dynamic_strings,
13381 filedata->dynamic_strings_length);
252b5132 13382 }
8b73c356 13383 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13384 && filedata->section_headers != NULL)
252b5132 13385 {
b34976b6 13386 unsigned int i;
252b5132 13387
dda8d76d
NC
13388 for (i = 0, section = filedata->section_headers;
13389 i < filedata->file_header.e_shnum;
252b5132
RH
13390 i++, section++)
13391 {
2cf0635d 13392 char * strtab = NULL;
c256ffe7 13393 unsigned long int strtab_size = 0;
2cf0635d 13394 Elf_Internal_Sym * symtab;
ef3df110 13395 unsigned long si, num_syms;
252b5132 13396
2c610e4b
L
13397 if ((section->sh_type != SHT_SYMTAB
13398 && section->sh_type != SHT_DYNSYM)
13399 || (!do_syms
13400 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13401 continue;
13402
dd24e3da
NC
13403 if (section->sh_entsize == 0)
13404 {
13405 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13406 printable_section_name (filedata, section));
dd24e3da
NC
13407 continue;
13408 }
13409
d3a49aa8 13410 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13411
13412 if (filedata->is_separate)
13413 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13414 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13415 num_syms),
13416 filedata->file_name,
13417 printable_section_name (filedata, section),
13418 num_syms);
13419 else
13420 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13421 "\nSymbol table '%s' contains %lu entries:\n",
13422 num_syms),
13423 printable_section_name (filedata, section),
13424 num_syms);
dd24e3da 13425
f7a99963 13426 if (is_32bit_elf)
ca47b30c 13427 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13428 else
ca47b30c 13429 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13430
4de91c10 13431 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13432 if (symtab == NULL)
13433 continue;
13434
dda8d76d 13435 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13436 {
dda8d76d
NC
13437 strtab = filedata->string_table;
13438 strtab_size = filedata->string_table_length;
c256ffe7 13439 }
dda8d76d 13440 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13441 {
2cf0635d 13442 Elf_Internal_Shdr * string_sec;
252b5132 13443
dda8d76d 13444 string_sec = filedata->section_headers + section->sh_link;
252b5132 13445
dda8d76d 13446 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13447 1, string_sec->sh_size,
13448 _("string table"));
c256ffe7 13449 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13450 }
13451
10ca4b04
L
13452 for (si = 0; si < num_syms; si++)
13453 print_dynamic_symbol (filedata, si, symtab, section,
13454 strtab, strtab_size);
252b5132
RH
13455
13456 free (symtab);
dda8d76d 13457 if (strtab != filedata->string_table)
252b5132
RH
13458 free (strtab);
13459 }
13460 }
13461 else if (do_syms)
13462 printf
13463 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13464
978c4450 13465 if (do_histogram && filedata->buckets != NULL)
252b5132 13466 {
2cf0635d
NC
13467 unsigned long * lengths;
13468 unsigned long * counts;
66543521
AM
13469 unsigned long hn;
13470 bfd_vma si;
13471 unsigned long maxlength = 0;
13472 unsigned long nzero_counts = 0;
13473 unsigned long nsyms = 0;
6bd6a03d 13474 char *visited;
252b5132 13475
d3a49aa8
AM
13476 printf (ngettext ("\nHistogram for bucket list length "
13477 "(total of %lu bucket):\n",
13478 "\nHistogram for bucket list length "
13479 "(total of %lu buckets):\n",
978c4450
AM
13480 (unsigned long) filedata->nbuckets),
13481 (unsigned long) filedata->nbuckets);
252b5132 13482
978c4450
AM
13483 lengths = (unsigned long *) calloc (filedata->nbuckets,
13484 sizeof (*lengths));
252b5132
RH
13485 if (lengths == NULL)
13486 {
8b73c356 13487 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13488 goto err_out;
252b5132 13489 }
978c4450
AM
13490 visited = xcmalloc (filedata->nchains, 1);
13491 memset (visited, 0, filedata->nchains);
8b73c356
NC
13492
13493 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13494 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13495 {
978c4450 13496 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13497 {
b34976b6 13498 ++nsyms;
252b5132 13499 if (maxlength < ++lengths[hn])
b34976b6 13500 ++maxlength;
978c4450 13501 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13502 {
13503 error (_("histogram chain is corrupt\n"));
13504 break;
13505 }
13506 visited[si] = 1;
252b5132
RH
13507 }
13508 }
6bd6a03d 13509 free (visited);
252b5132 13510
3f5e193b 13511 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13512 if (counts == NULL)
13513 {
b2e951ec 13514 free (lengths);
8b73c356 13515 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13516 goto err_out;
252b5132
RH
13517 }
13518
978c4450 13519 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13520 ++counts[lengths[hn]];
252b5132 13521
978c4450 13522 if (filedata->nbuckets > 0)
252b5132 13523 {
66543521
AM
13524 unsigned long i;
13525 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13526 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13527 for (i = 1; i <= maxlength; ++i)
103f02d3 13528 {
66543521
AM
13529 nzero_counts += counts[i] * i;
13530 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13531 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13532 (nzero_counts * 100.0) / nsyms);
13533 }
252b5132
RH
13534 }
13535
13536 free (counts);
13537 free (lengths);
13538 }
13539
978c4450
AM
13540 free (filedata->buckets);
13541 filedata->buckets = NULL;
13542 filedata->nbuckets = 0;
13543 free (filedata->chains);
13544 filedata->chains = NULL;
252b5132 13545
978c4450 13546 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13547 {
2cf0635d
NC
13548 unsigned long * lengths;
13549 unsigned long * counts;
fdc90cb4
JJ
13550 unsigned long hn;
13551 unsigned long maxlength = 0;
13552 unsigned long nzero_counts = 0;
13553 unsigned long nsyms = 0;
fdc90cb4 13554
f16a9783 13555 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13556 "(total of %lu bucket):\n",
f16a9783 13557 "\nHistogram for `%s' bucket list length "
d3a49aa8 13558 "(total of %lu buckets):\n",
978c4450
AM
13559 (unsigned long) filedata->ngnubuckets),
13560 GNU_HASH_SECTION_NAME (filedata),
13561 (unsigned long) filedata->ngnubuckets);
8b73c356 13562
978c4450
AM
13563 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13564 sizeof (*lengths));
fdc90cb4
JJ
13565 if (lengths == NULL)
13566 {
8b73c356 13567 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13568 goto err_out;
fdc90cb4
JJ
13569 }
13570
fdc90cb4
JJ
13571 printf (_(" Length Number %% of total Coverage\n"));
13572
978c4450
AM
13573 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13574 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13575 {
13576 bfd_vma off, length = 1;
13577
978c4450 13578 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13579 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13580 off < filedata->ngnuchains
13581 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13582 ++off)
fdc90cb4
JJ
13583 ++length;
13584 lengths[hn] = length;
13585 if (length > maxlength)
13586 maxlength = length;
13587 nsyms += length;
13588 }
13589
3f5e193b 13590 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13591 if (counts == NULL)
13592 {
b2e951ec 13593 free (lengths);
8b73c356 13594 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13595 goto err_out;
fdc90cb4
JJ
13596 }
13597
978c4450 13598 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13599 ++counts[lengths[hn]];
13600
978c4450 13601 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13602 {
13603 unsigned long j;
13604 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13605 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13606 for (j = 1; j <= maxlength; ++j)
13607 {
13608 nzero_counts += counts[j] * j;
13609 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13610 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13611 (nzero_counts * 100.0) / nsyms);
13612 }
13613 }
13614
13615 free (counts);
13616 free (lengths);
fdc90cb4 13617 }
978c4450
AM
13618 free (filedata->gnubuckets);
13619 filedata->gnubuckets = NULL;
13620 filedata->ngnubuckets = 0;
13621 free (filedata->gnuchains);
13622 filedata->gnuchains = NULL;
13623 filedata->ngnuchains = 0;
13624 free (filedata->mipsxlat);
13625 filedata->mipsxlat = NULL;
015dc7e1 13626 return true;
fd486f32
AM
13627
13628 err_out:
978c4450
AM
13629 free (filedata->gnubuckets);
13630 filedata->gnubuckets = NULL;
13631 filedata->ngnubuckets = 0;
13632 free (filedata->gnuchains);
13633 filedata->gnuchains = NULL;
13634 filedata->ngnuchains = 0;
13635 free (filedata->mipsxlat);
13636 filedata->mipsxlat = NULL;
13637 free (filedata->buckets);
13638 filedata->buckets = NULL;
13639 filedata->nbuckets = 0;
13640 free (filedata->chains);
13641 filedata->chains = NULL;
015dc7e1 13642 return false;
252b5132
RH
13643}
13644
015dc7e1 13645static bool
ca0e11aa 13646process_syminfo (Filedata * filedata)
252b5132 13647{
b4c96d0d 13648 unsigned int i;
252b5132 13649
978c4450 13650 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13651 || !do_dynamic)
13652 /* No syminfo, this is ok. */
015dc7e1 13653 return true;
252b5132
RH
13654
13655 /* There better should be a dynamic symbol section. */
978c4450 13656 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13657 return false;
252b5132 13658
ca0e11aa
NC
13659 if (filedata->is_separate)
13660 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13661 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13662 filedata->dynamic_syminfo_nent),
13663 filedata->file_name,
13664 filedata->dynamic_syminfo_offset,
13665 filedata->dynamic_syminfo_nent);
13666 else
d3a49aa8
AM
13667 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13668 "contains %d entry:\n",
13669 "\nDynamic info segment at offset 0x%lx "
13670 "contains %d entries:\n",
978c4450 13671 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13672 filedata->dynamic_syminfo_offset,
13673 filedata->dynamic_syminfo_nent);
252b5132
RH
13674
13675 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13676 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13677 {
978c4450 13678 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13679
31104126 13680 printf ("%4d: ", i);
978c4450 13681 if (i >= filedata->num_dynamic_syms)
4082ef84 13682 printf (_("<corrupt index>"));
84714f86
AM
13683 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13684 print_symbol (30, get_dynamic_name (filedata,
978c4450 13685 filedata->dynamic_symbols[i].st_name));
d79b3d50 13686 else
978c4450 13687 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13688 putchar (' ');
252b5132 13689
978c4450 13690 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13691 {
13692 case SYMINFO_BT_SELF:
13693 fputs ("SELF ", stdout);
13694 break;
13695 case SYMINFO_BT_PARENT:
13696 fputs ("PARENT ", stdout);
13697 break;
13698 default:
978c4450
AM
13699 if (filedata->dynamic_syminfo[i].si_boundto > 0
13700 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13701 && valid_dynamic_name (filedata,
978c4450 13702 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13703 {
84714f86 13704 print_symbol (10, get_dynamic_name (filedata,
978c4450 13705 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13706 putchar (' ' );
13707 }
252b5132 13708 else
978c4450 13709 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13710 break;
13711 }
13712
13713 if (flags & SYMINFO_FLG_DIRECT)
13714 printf (" DIRECT");
13715 if (flags & SYMINFO_FLG_PASSTHRU)
13716 printf (" PASSTHRU");
13717 if (flags & SYMINFO_FLG_COPY)
13718 printf (" COPY");
13719 if (flags & SYMINFO_FLG_LAZYLOAD)
13720 printf (" LAZYLOAD");
13721
13722 puts ("");
13723 }
13724
015dc7e1 13725 return true;
252b5132
RH
13726}
13727
75802ccb
CE
13728/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13729 is contained by the region START .. END. The types of ADDR, START
13730 and END should all be the same. Note both ADDR + NELEM and END
13731 point to just beyond the end of the regions that are being tested. */
13732#define IN_RANGE(START,END,ADDR,NELEM) \
13733 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13734
cf13d699
NC
13735/* Check to see if the given reloc needs to be handled in a target specific
13736 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13737 FALSE.
13738
13739 If called with reloc == NULL, then this is a signal that reloc processing
13740 for the current section has finished, and any saved state should be
13741 discarded. */
09c11c86 13742
015dc7e1 13743static bool
dda8d76d
NC
13744target_specific_reloc_handling (Filedata * filedata,
13745 Elf_Internal_Rela * reloc,
13746 unsigned char * start,
13747 unsigned char * end,
13748 Elf_Internal_Sym * symtab,
13749 unsigned long num_syms)
252b5132 13750{
f84ce13b
NC
13751 unsigned int reloc_type = 0;
13752 unsigned long sym_index = 0;
13753
13754 if (reloc)
13755 {
dda8d76d 13756 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13757 sym_index = get_reloc_symindex (reloc->r_info);
13758 }
252b5132 13759
dda8d76d 13760 switch (filedata->file_header.e_machine)
252b5132 13761 {
13761a11
NC
13762 case EM_MSP430:
13763 case EM_MSP430_OLD:
13764 {
13765 static Elf_Internal_Sym * saved_sym = NULL;
13766
f84ce13b
NC
13767 if (reloc == NULL)
13768 {
13769 saved_sym = NULL;
015dc7e1 13770 return true;
f84ce13b
NC
13771 }
13772
13761a11
NC
13773 switch (reloc_type)
13774 {
13775 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13776 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13777 if (uses_msp430x_relocs (filedata))
13761a11 13778 break;
1a0670f3 13779 /* Fall through. */
13761a11 13780 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13781 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13782 /* PR 21139. */
13783 if (sym_index >= num_syms)
13784 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13785 sym_index);
13786 else
13787 saved_sym = symtab + sym_index;
015dc7e1 13788 return true;
13761a11
NC
13789
13790 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13791 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13792 goto handle_sym_diff;
0b4362b0 13793
13761a11
NC
13794 case 5: /* R_MSP430_16_BYTE */
13795 case 9: /* R_MSP430_8 */
7d81bc93 13796 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13797 if (uses_msp430x_relocs (filedata))
13761a11
NC
13798 break;
13799 goto handle_sym_diff;
13800
13801 case 2: /* R_MSP430_ABS16 */
13802 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13803 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13804 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13805 break;
13806 goto handle_sym_diff;
0b4362b0 13807
13761a11
NC
13808 handle_sym_diff:
13809 if (saved_sym != NULL)
13810 {
13811 bfd_vma value;
5a805384 13812 unsigned int reloc_size = 0;
7d81bc93
JL
13813 int leb_ret = 0;
13814 switch (reloc_type)
13815 {
13816 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13817 reloc_size = 4;
13818 break;
13819 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13820 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13821 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13822 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13823 &reloc_size, &leb_ret);
7d81bc93
JL
13824 break;
13825 default:
13826 reloc_size = 2;
13827 break;
13828 }
13761a11 13829
5a805384 13830 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13831 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13832 "ULEB128 value\n"),
13833 (long) reloc->r_offset);
13834 else if (sym_index >= num_syms)
f84ce13b
NC
13835 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13836 sym_index);
03f7786e 13837 else
f84ce13b
NC
13838 {
13839 value = reloc->r_addend + (symtab[sym_index].st_value
13840 - saved_sym->st_value);
13841
b32e566b 13842 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13843 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13844 else
13845 /* PR 21137 */
13846 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13847 (long) reloc->r_offset);
f84ce13b 13848 }
13761a11
NC
13849
13850 saved_sym = NULL;
015dc7e1 13851 return true;
13761a11
NC
13852 }
13853 break;
13854
13855 default:
13856 if (saved_sym != NULL)
071436c6 13857 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13858 break;
13859 }
13860 break;
13861 }
13862
cf13d699
NC
13863 case EM_MN10300:
13864 case EM_CYGNUS_MN10300:
13865 {
13866 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13867
f84ce13b
NC
13868 if (reloc == NULL)
13869 {
13870 saved_sym = NULL;
015dc7e1 13871 return true;
f84ce13b
NC
13872 }
13873
cf13d699
NC
13874 switch (reloc_type)
13875 {
13876 case 34: /* R_MN10300_ALIGN */
015dc7e1 13877 return true;
cf13d699 13878 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13879 if (sym_index >= num_syms)
13880 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13881 sym_index);
13882 else
13883 saved_sym = symtab + sym_index;
015dc7e1 13884 return true;
f84ce13b 13885
cf13d699
NC
13886 case 1: /* R_MN10300_32 */
13887 case 2: /* R_MN10300_16 */
13888 if (saved_sym != NULL)
13889 {
03f7786e 13890 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13891 bfd_vma value;
252b5132 13892
f84ce13b
NC
13893 if (sym_index >= num_syms)
13894 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13895 sym_index);
03f7786e 13896 else
f84ce13b
NC
13897 {
13898 value = reloc->r_addend + (symtab[sym_index].st_value
13899 - saved_sym->st_value);
13900
b32e566b 13901 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13902 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13903 else
13904 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13905 (long) reloc->r_offset);
f84ce13b 13906 }
252b5132 13907
cf13d699 13908 saved_sym = NULL;
015dc7e1 13909 return true;
cf13d699
NC
13910 }
13911 break;
13912 default:
13913 if (saved_sym != NULL)
071436c6 13914 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13915 break;
13916 }
13917 break;
13918 }
6ff71e76
NC
13919
13920 case EM_RL78:
13921 {
13922 static bfd_vma saved_sym1 = 0;
13923 static bfd_vma saved_sym2 = 0;
13924 static bfd_vma value;
13925
f84ce13b
NC
13926 if (reloc == NULL)
13927 {
13928 saved_sym1 = saved_sym2 = 0;
015dc7e1 13929 return true;
f84ce13b
NC
13930 }
13931
6ff71e76
NC
13932 switch (reloc_type)
13933 {
13934 case 0x80: /* R_RL78_SYM. */
13935 saved_sym1 = saved_sym2;
f84ce13b
NC
13936 if (sym_index >= num_syms)
13937 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13938 sym_index);
13939 else
13940 {
13941 saved_sym2 = symtab[sym_index].st_value;
13942 saved_sym2 += reloc->r_addend;
13943 }
015dc7e1 13944 return true;
6ff71e76
NC
13945
13946 case 0x83: /* R_RL78_OPsub. */
13947 value = saved_sym1 - saved_sym2;
13948 saved_sym2 = saved_sym1 = 0;
015dc7e1 13949 return true;
6ff71e76
NC
13950 break;
13951
13952 case 0x41: /* R_RL78_ABS32. */
b32e566b 13953 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13954 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13955 else
13956 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13957 (long) reloc->r_offset);
6ff71e76 13958 value = 0;
015dc7e1 13959 return true;
6ff71e76
NC
13960
13961 case 0x43: /* R_RL78_ABS16. */
b32e566b 13962 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13963 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13964 else
13965 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13966 (long) reloc->r_offset);
6ff71e76 13967 value = 0;
015dc7e1 13968 return true;
6ff71e76
NC
13969
13970 default:
13971 break;
13972 }
13973 break;
13974 }
252b5132
RH
13975 }
13976
015dc7e1 13977 return false;
252b5132
RH
13978}
13979
aca88567
NC
13980/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13981 DWARF debug sections. This is a target specific test. Note - we do not
13982 go through the whole including-target-headers-multiple-times route, (as
13983 we have already done with <elf/h8.h>) because this would become very
13984 messy and even then this function would have to contain target specific
13985 information (the names of the relocs instead of their numeric values).
13986 FIXME: This is not the correct way to solve this problem. The proper way
13987 is to have target specific reloc sizing and typing functions created by
13988 the reloc-macros.h header, in the same way that it already creates the
13989 reloc naming functions. */
13990
015dc7e1 13991static bool
dda8d76d 13992is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13993{
d347c9df 13994 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13995 switch (filedata->file_header.e_machine)
aca88567 13996 {
41e92641 13997 case EM_386:
22abe556 13998 case EM_IAMCU:
41e92641 13999 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14000 case EM_68K:
14001 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14002 case EM_860:
14003 return reloc_type == 1; /* R_860_32. */
14004 case EM_960:
14005 return reloc_type == 2; /* R_960_32. */
a06ea964 14006 case EM_AARCH64:
9282b95a
JW
14007 return (reloc_type == 258
14008 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14009 case EM_BPF:
14010 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14011 case EM_ADAPTEVA_EPIPHANY:
14012 return reloc_type == 3;
aca88567 14013 case EM_ALPHA:
137b6b5f 14014 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14015 case EM_ARC:
14016 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14017 case EM_ARC_COMPACT:
14018 case EM_ARC_COMPACT2:
14019 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14020 case EM_ARM:
14021 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14022 case EM_AVR_OLD:
aca88567
NC
14023 case EM_AVR:
14024 return reloc_type == 1;
14025 case EM_BLACKFIN:
14026 return reloc_type == 0x12; /* R_byte4_data. */
14027 case EM_CRIS:
14028 return reloc_type == 3; /* R_CRIS_32. */
14029 case EM_CR16:
14030 return reloc_type == 3; /* R_CR16_NUM32. */
14031 case EM_CRX:
14032 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14033 case EM_CSKY:
14034 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14035 case EM_CYGNUS_FRV:
14036 return reloc_type == 1;
41e92641
NC
14037 case EM_CYGNUS_D10V:
14038 case EM_D10V:
14039 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14040 case EM_CYGNUS_D30V:
14041 case EM_D30V:
14042 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14043 case EM_DLX:
14044 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14045 case EM_CYGNUS_FR30:
14046 case EM_FR30:
14047 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14048 case EM_FT32:
14049 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14050 case EM_H8S:
14051 case EM_H8_300:
14052 case EM_H8_300H:
14053 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14054 case EM_IA_64:
262cdac7
AM
14055 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14056 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14057 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14058 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14059 case EM_IP2K_OLD:
14060 case EM_IP2K:
14061 return reloc_type == 2; /* R_IP2K_32. */
14062 case EM_IQ2000:
14063 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14064 case EM_LATTICEMICO32:
14065 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14066 case EM_LOONGARCH:
14067 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14068 case EM_M32C_OLD:
aca88567
NC
14069 case EM_M32C:
14070 return reloc_type == 3; /* R_M32C_32. */
14071 case EM_M32R:
14072 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14073 case EM_68HC11:
14074 case EM_68HC12:
14075 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14076 case EM_S12Z:
2849d19f
JD
14077 return reloc_type == 7 || /* R_S12Z_EXT32 */
14078 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14079 case EM_MCORE:
14080 return reloc_type == 1; /* R_MCORE_ADDR32. */
14081 case EM_CYGNUS_MEP:
14082 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14083 case EM_METAG:
14084 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14085 case EM_MICROBLAZE:
14086 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14087 case EM_MIPS:
14088 return reloc_type == 2; /* R_MIPS_32. */
14089 case EM_MMIX:
14090 return reloc_type == 4; /* R_MMIX_32. */
14091 case EM_CYGNUS_MN10200:
14092 case EM_MN10200:
14093 return reloc_type == 1; /* R_MN10200_32. */
14094 case EM_CYGNUS_MN10300:
14095 case EM_MN10300:
14096 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14097 case EM_MOXIE:
14098 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14099 case EM_MSP430_OLD:
14100 case EM_MSP430:
13761a11 14101 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14102 case EM_MT:
14103 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
14104 case EM_NDS32:
14105 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 14106 case EM_ALTERA_NIOS2:
36591ba1 14107 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14108 case EM_NIOS32:
14109 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14110 case EM_OR1K:
14111 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14112 case EM_PARISC:
9abca702 14113 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14114 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14115 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14116 case EM_PJ:
14117 case EM_PJ_OLD:
14118 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14119 case EM_PPC64:
14120 return reloc_type == 1; /* R_PPC64_ADDR32. */
14121 case EM_PPC:
14122 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14123 case EM_TI_PRU:
14124 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14125 case EM_RISCV:
14126 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14127 case EM_RL78:
14128 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14129 case EM_RX:
14130 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14131 case EM_S370:
14132 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14133 case EM_S390_OLD:
14134 case EM_S390:
14135 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14136 case EM_SCORE:
14137 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14138 case EM_SH:
14139 return reloc_type == 1; /* R_SH_DIR32. */
14140 case EM_SPARC32PLUS:
14141 case EM_SPARCV9:
14142 case EM_SPARC:
14143 return reloc_type == 3 /* R_SPARC_32. */
14144 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14145 case EM_SPU:
14146 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14147 case EM_TI_C6000:
14148 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14149 case EM_TILEGX:
14150 return reloc_type == 2; /* R_TILEGX_32. */
14151 case EM_TILEPRO:
14152 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14153 case EM_CYGNUS_V850:
14154 case EM_V850:
14155 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14156 case EM_V800:
14157 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14158 case EM_VAX:
14159 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14160 case EM_VISIUM:
14161 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14162 case EM_WEBASSEMBLY:
14163 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14164 case EM_X86_64:
8a9036a4 14165 case EM_L1OM:
7a9068fe 14166 case EM_K1OM:
aca88567 14167 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14168 case EM_XC16X:
14169 case EM_C166:
14170 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14171 case EM_XGATE:
14172 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14173 case EM_XSTORMY16:
14174 return reloc_type == 1; /* R_XSTROMY16_32. */
14175 case EM_XTENSA_OLD:
14176 case EM_XTENSA:
14177 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14178 case EM_Z80:
14179 return reloc_type == 6; /* R_Z80_32. */
aca88567 14180 default:
bee0ee85
NC
14181 {
14182 static unsigned int prev_warn = 0;
14183
14184 /* Avoid repeating the same warning multiple times. */
dda8d76d 14185 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14186 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14187 filedata->file_header.e_machine);
14188 prev_warn = filedata->file_header.e_machine;
015dc7e1 14189 return false;
bee0ee85 14190 }
aca88567
NC
14191 }
14192}
14193
14194/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14195 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14196
015dc7e1 14197static bool
dda8d76d 14198is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14199{
dda8d76d 14200 switch (filedata->file_header.e_machine)
d347c9df 14201 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14202 {
41e92641 14203 case EM_386:
22abe556 14204 case EM_IAMCU:
3e0873ac 14205 return reloc_type == 2; /* R_386_PC32. */
aca88567 14206 case EM_68K:
3e0873ac 14207 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14208 case EM_AARCH64:
14209 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14210 case EM_ADAPTEVA_EPIPHANY:
14211 return reloc_type == 6;
aca88567
NC
14212 case EM_ALPHA:
14213 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14214 case EM_ARC_COMPACT:
14215 case EM_ARC_COMPACT2:
14216 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14217 case EM_ARM:
3e0873ac 14218 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14219 case EM_AVR_OLD:
14220 case EM_AVR:
14221 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14222 case EM_MICROBLAZE:
14223 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14224 case EM_OR1K:
14225 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14226 case EM_PARISC:
85acf597 14227 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14228 case EM_PPC:
14229 return reloc_type == 26; /* R_PPC_REL32. */
14230 case EM_PPC64:
3e0873ac 14231 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14232 case EM_RISCV:
14233 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14234 case EM_S390_OLD:
14235 case EM_S390:
3e0873ac 14236 return reloc_type == 5; /* R_390_PC32. */
aca88567 14237 case EM_SH:
3e0873ac 14238 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14239 case EM_SPARC32PLUS:
14240 case EM_SPARCV9:
14241 case EM_SPARC:
3e0873ac 14242 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14243 case EM_SPU:
14244 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14245 case EM_TILEGX:
14246 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14247 case EM_TILEPRO:
14248 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14249 case EM_VISIUM:
14250 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14251 case EM_X86_64:
8a9036a4 14252 case EM_L1OM:
7a9068fe 14253 case EM_K1OM:
3e0873ac 14254 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14255 case EM_VAX:
14256 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14257 case EM_XTENSA_OLD:
14258 case EM_XTENSA:
14259 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14260 default:
14261 /* Do not abort or issue an error message here. Not all targets use
14262 pc-relative 32-bit relocs in their DWARF debug information and we
14263 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14264 more helpful warning message will be generated by apply_relocations
14265 anyway, so just return. */
015dc7e1 14266 return false;
aca88567
NC
14267 }
14268}
14269
14270/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14271 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14272
015dc7e1 14273static bool
dda8d76d 14274is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14275{
dda8d76d 14276 switch (filedata->file_header.e_machine)
aca88567 14277 {
a06ea964
NC
14278 case EM_AARCH64:
14279 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14280 case EM_ALPHA:
14281 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14282 case EM_IA_64:
262cdac7
AM
14283 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14284 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14285 case EM_LOONGARCH:
14286 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14287 case EM_PARISC:
14288 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14289 case EM_PPC64:
14290 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14291 case EM_RISCV:
14292 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14293 case EM_SPARC32PLUS:
14294 case EM_SPARCV9:
14295 case EM_SPARC:
714da62f
NC
14296 return reloc_type == 32 /* R_SPARC_64. */
14297 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14298 case EM_X86_64:
8a9036a4 14299 case EM_L1OM:
7a9068fe 14300 case EM_K1OM:
aca88567 14301 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14302 case EM_S390_OLD:
14303 case EM_S390:
aa137e4d
NC
14304 return reloc_type == 22; /* R_S390_64. */
14305 case EM_TILEGX:
14306 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14307 case EM_MIPS:
aa137e4d 14308 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14309 default:
015dc7e1 14310 return false;
aca88567
NC
14311 }
14312}
14313
85acf597
RH
14314/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14315 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14316
015dc7e1 14317static bool
dda8d76d 14318is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14319{
dda8d76d 14320 switch (filedata->file_header.e_machine)
85acf597 14321 {
a06ea964
NC
14322 case EM_AARCH64:
14323 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14324 case EM_ALPHA:
aa137e4d 14325 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14326 case EM_IA_64:
262cdac7
AM
14327 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14328 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14329 case EM_PARISC:
aa137e4d 14330 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14331 case EM_PPC64:
aa137e4d 14332 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14333 case EM_SPARC32PLUS:
14334 case EM_SPARCV9:
14335 case EM_SPARC:
aa137e4d 14336 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14337 case EM_X86_64:
8a9036a4 14338 case EM_L1OM:
7a9068fe 14339 case EM_K1OM:
aa137e4d 14340 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14341 case EM_S390_OLD:
14342 case EM_S390:
aa137e4d
NC
14343 return reloc_type == 23; /* R_S390_PC64. */
14344 case EM_TILEGX:
14345 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14346 default:
015dc7e1 14347 return false;
85acf597
RH
14348 }
14349}
14350
4dc3c23d
AM
14351/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14352 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14353
015dc7e1 14354static bool
dda8d76d 14355is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14356{
dda8d76d 14357 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14358 {
14359 case EM_CYGNUS_MN10200:
14360 case EM_MN10200:
14361 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14362 case EM_FT32:
14363 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14364 case EM_Z80:
14365 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14366 default:
015dc7e1 14367 return false;
4dc3c23d
AM
14368 }
14369}
14370
aca88567
NC
14371/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14372 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14373
015dc7e1 14374static bool
dda8d76d 14375is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14376{
d347c9df 14377 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14378 switch (filedata->file_header.e_machine)
4b78141a 14379 {
886a2506
NC
14380 case EM_ARC:
14381 case EM_ARC_COMPACT:
14382 case EM_ARC_COMPACT2:
14383 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14384 case EM_ADAPTEVA_EPIPHANY:
14385 return reloc_type == 5;
aca88567
NC
14386 case EM_AVR_OLD:
14387 case EM_AVR:
14388 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14389 case EM_CYGNUS_D10V:
14390 case EM_D10V:
14391 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14392 case EM_FT32:
14393 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14394 case EM_H8S:
14395 case EM_H8_300:
14396 case EM_H8_300H:
aca88567
NC
14397 return reloc_type == R_H8_DIR16;
14398 case EM_IP2K_OLD:
14399 case EM_IP2K:
14400 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14401 case EM_M32C_OLD:
f4236fe4
DD
14402 case EM_M32C:
14403 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14404 case EM_CYGNUS_MN10200:
14405 case EM_MN10200:
14406 return reloc_type == 2; /* R_MN10200_16. */
14407 case EM_CYGNUS_MN10300:
14408 case EM_MN10300:
14409 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14410 case EM_MSP430:
dda8d76d 14411 if (uses_msp430x_relocs (filedata))
13761a11 14412 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14413 /* Fall through. */
78c8d46c 14414 case EM_MSP430_OLD:
aca88567 14415 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14416 case EM_NDS32:
14417 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14418 case EM_ALTERA_NIOS2:
36591ba1 14419 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14420 case EM_NIOS32:
14421 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14422 case EM_OR1K:
14423 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14424 case EM_RISCV:
14425 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14426 case EM_TI_PRU:
14427 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14428 case EM_TI_C6000:
14429 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14430 case EM_VISIUM:
14431 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14432 case EM_XC16X:
14433 case EM_C166:
14434 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14435 case EM_XGATE:
14436 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14437 case EM_Z80:
14438 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14439 default:
015dc7e1 14440 return false;
4b78141a
NC
14441 }
14442}
14443
39e07931
AS
14444/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14445 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14446
015dc7e1 14447static bool
39e07931
AS
14448is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14449{
14450 switch (filedata->file_header.e_machine)
14451 {
14452 case EM_RISCV:
14453 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14454 case EM_Z80:
14455 return reloc_type == 1; /* R_Z80_8. */
39e07931 14456 default:
015dc7e1 14457 return false;
39e07931
AS
14458 }
14459}
14460
14461/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14462 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14463
015dc7e1 14464static bool
39e07931
AS
14465is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14466{
14467 switch (filedata->file_header.e_machine)
14468 {
14469 case EM_RISCV:
14470 return reloc_type == 53; /* R_RISCV_SET6. */
14471 default:
015dc7e1 14472 return false;
39e07931
AS
14473 }
14474}
14475
03336641
JW
14476/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14477 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14478
015dc7e1 14479static bool
03336641
JW
14480is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14481{
14482 /* Please keep this table alpha-sorted for ease of visual lookup. */
14483 switch (filedata->file_header.e_machine)
14484 {
14485 case EM_RISCV:
14486 return reloc_type == 35; /* R_RISCV_ADD32. */
14487 default:
015dc7e1 14488 return false;
03336641
JW
14489 }
14490}
14491
14492/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14493 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14494
015dc7e1 14495static bool
03336641
JW
14496is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14497{
14498 /* Please keep this table alpha-sorted for ease of visual lookup. */
14499 switch (filedata->file_header.e_machine)
14500 {
14501 case EM_RISCV:
14502 return reloc_type == 39; /* R_RISCV_SUB32. */
14503 default:
015dc7e1 14504 return false;
03336641
JW
14505 }
14506}
14507
14508/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14509 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14510
015dc7e1 14511static bool
03336641
JW
14512is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14513{
14514 /* Please keep this table alpha-sorted for ease of visual lookup. */
14515 switch (filedata->file_header.e_machine)
14516 {
14517 case EM_RISCV:
14518 return reloc_type == 36; /* R_RISCV_ADD64. */
14519 default:
015dc7e1 14520 return false;
03336641
JW
14521 }
14522}
14523
14524/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14525 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14526
015dc7e1 14527static bool
03336641
JW
14528is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14529{
14530 /* Please keep this table alpha-sorted for ease of visual lookup. */
14531 switch (filedata->file_header.e_machine)
14532 {
14533 case EM_RISCV:
14534 return reloc_type == 40; /* R_RISCV_SUB64. */
14535 default:
015dc7e1 14536 return false;
03336641
JW
14537 }
14538}
14539
14540/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14541 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14542
015dc7e1 14543static bool
03336641
JW
14544is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14545{
14546 /* Please keep this table alpha-sorted for ease of visual lookup. */
14547 switch (filedata->file_header.e_machine)
14548 {
14549 case EM_RISCV:
14550 return reloc_type == 34; /* R_RISCV_ADD16. */
14551 default:
015dc7e1 14552 return false;
03336641
JW
14553 }
14554}
14555
14556/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14557 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14558
015dc7e1 14559static bool
03336641
JW
14560is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14561{
14562 /* Please keep this table alpha-sorted for ease of visual lookup. */
14563 switch (filedata->file_header.e_machine)
14564 {
14565 case EM_RISCV:
14566 return reloc_type == 38; /* R_RISCV_SUB16. */
14567 default:
015dc7e1 14568 return false;
03336641
JW
14569 }
14570}
14571
14572/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14573 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14574
015dc7e1 14575static bool
03336641
JW
14576is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14577{
14578 /* Please keep this table alpha-sorted for ease of visual lookup. */
14579 switch (filedata->file_header.e_machine)
14580 {
14581 case EM_RISCV:
14582 return reloc_type == 33; /* R_RISCV_ADD8. */
14583 default:
015dc7e1 14584 return false;
03336641
JW
14585 }
14586}
14587
14588/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14589 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14590
015dc7e1 14591static bool
03336641
JW
14592is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14593{
14594 /* Please keep this table alpha-sorted for ease of visual lookup. */
14595 switch (filedata->file_header.e_machine)
14596 {
14597 case EM_RISCV:
14598 return reloc_type == 37; /* R_RISCV_SUB8. */
14599 default:
015dc7e1 14600 return false;
03336641
JW
14601 }
14602}
14603
39e07931
AS
14604/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14605 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14606
015dc7e1 14607static bool
39e07931
AS
14608is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14609{
14610 switch (filedata->file_header.e_machine)
14611 {
14612 case EM_RISCV:
14613 return reloc_type == 52; /* R_RISCV_SUB6. */
14614 default:
015dc7e1 14615 return false;
39e07931
AS
14616 }
14617}
14618
2a7b2e88
JK
14619/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14620 relocation entries (possibly formerly used for SHT_GROUP sections). */
14621
015dc7e1 14622static bool
dda8d76d 14623is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14624{
dda8d76d 14625 switch (filedata->file_header.e_machine)
2a7b2e88 14626 {
cb8f3167 14627 case EM_386: /* R_386_NONE. */
d347c9df 14628 case EM_68K: /* R_68K_NONE. */
cfb8c092 14629 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14630 case EM_ALPHA: /* R_ALPHA_NONE. */
14631 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14632 case EM_ARC: /* R_ARC_NONE. */
886a2506 14633 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14634 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14635 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14636 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14637 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14638 case EM_FT32: /* R_FT32_NONE. */
14639 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14640 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14641 case EM_L1OM: /* R_X86_64_NONE. */
14642 case EM_M32R: /* R_M32R_NONE. */
14643 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14644 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14645 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14646 case EM_NIOS32: /* R_NIOS_NONE. */
14647 case EM_OR1K: /* R_OR1K_NONE. */
14648 case EM_PARISC: /* R_PARISC_NONE. */
14649 case EM_PPC64: /* R_PPC64_NONE. */
14650 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14651 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14652 case EM_S390: /* R_390_NONE. */
14653 case EM_S390_OLD:
14654 case EM_SH: /* R_SH_NONE. */
14655 case EM_SPARC32PLUS:
14656 case EM_SPARC: /* R_SPARC_NONE. */
14657 case EM_SPARCV9:
aa137e4d
NC
14658 case EM_TILEGX: /* R_TILEGX_NONE. */
14659 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14660 case EM_TI_C6000:/* R_C6000_NONE. */
14661 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14662 case EM_XC16X:
6655dba2 14663 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14664 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14665 return reloc_type == 0;
d347c9df 14666
a06ea964
NC
14667 case EM_AARCH64:
14668 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14669 case EM_AVR_OLD:
14670 case EM_AVR:
14671 return (reloc_type == 0 /* R_AVR_NONE. */
14672 || reloc_type == 30 /* R_AVR_DIFF8. */
14673 || reloc_type == 31 /* R_AVR_DIFF16. */
14674 || reloc_type == 32 /* R_AVR_DIFF32. */);
14675 case EM_METAG:
14676 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14677 case EM_NDS32:
14678 return (reloc_type == 0 /* R_XTENSA_NONE. */
14679 || reloc_type == 204 /* R_NDS32_DIFF8. */
14680 || reloc_type == 205 /* R_NDS32_DIFF16. */
14681 || reloc_type == 206 /* R_NDS32_DIFF32. */
14682 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14683 case EM_TI_PRU:
14684 return (reloc_type == 0 /* R_PRU_NONE. */
14685 || reloc_type == 65 /* R_PRU_DIFF8. */
14686 || reloc_type == 66 /* R_PRU_DIFF16. */
14687 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14688 case EM_XTENSA_OLD:
14689 case EM_XTENSA:
4dc3c23d
AM
14690 return (reloc_type == 0 /* R_XTENSA_NONE. */
14691 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14692 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14693 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14694 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14695 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14696 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14697 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14698 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14699 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14700 }
015dc7e1 14701 return false;
2a7b2e88
JK
14702}
14703
d1c4b12b
NC
14704/* Returns TRUE if there is a relocation against
14705 section NAME at OFFSET bytes. */
14706
015dc7e1 14707bool
d1c4b12b
NC
14708reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14709{
14710 Elf_Internal_Rela * relocs;
14711 Elf_Internal_Rela * rp;
14712
14713 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14714 return false;
d1c4b12b
NC
14715
14716 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14717
14718 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14719 if (rp->r_offset == offset)
015dc7e1 14720 return true;
d1c4b12b 14721
015dc7e1 14722 return false;
d1c4b12b
NC
14723}
14724
cf13d699 14725/* Apply relocations to a section.
32ec8896
NC
14726 Returns TRUE upon success, FALSE otherwise.
14727 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14728 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14729 will be set to the number of relocs loaded.
14730
cf13d699 14731 Note: So far support has been added only for those relocations
32ec8896
NC
14732 which can be found in debug sections. FIXME: Add support for
14733 more relocations ? */
1b315056 14734
015dc7e1 14735static bool
dda8d76d 14736apply_relocations (Filedata * filedata,
d1c4b12b
NC
14737 const Elf_Internal_Shdr * section,
14738 unsigned char * start,
14739 bfd_size_type size,
1449284b 14740 void ** relocs_return,
d1c4b12b 14741 unsigned long * num_relocs_return)
1b315056 14742{
cf13d699 14743 Elf_Internal_Shdr * relsec;
0d2a7a93 14744 unsigned char * end = start + size;
cb8f3167 14745
d1c4b12b
NC
14746 if (relocs_return != NULL)
14747 {
14748 * (Elf_Internal_Rela **) relocs_return = NULL;
14749 * num_relocs_return = 0;
14750 }
14751
dda8d76d 14752 if (filedata->file_header.e_type != ET_REL)
32ec8896 14753 /* No relocs to apply. */
015dc7e1 14754 return true;
1b315056 14755
cf13d699 14756 /* Find the reloc section associated with the section. */
dda8d76d
NC
14757 for (relsec = filedata->section_headers;
14758 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14759 ++relsec)
252b5132 14760 {
015dc7e1 14761 bool is_rela;
41e92641 14762 unsigned long num_relocs;
2cf0635d
NC
14763 Elf_Internal_Rela * relocs;
14764 Elf_Internal_Rela * rp;
14765 Elf_Internal_Shdr * symsec;
14766 Elf_Internal_Sym * symtab;
ba5cdace 14767 unsigned long num_syms;
2cf0635d 14768 Elf_Internal_Sym * sym;
252b5132 14769
41e92641 14770 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14771 || relsec->sh_info >= filedata->file_header.e_shnum
14772 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14773 || relsec->sh_size == 0
dda8d76d 14774 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14775 continue;
428409d5 14776
a788aedd
AM
14777 symsec = filedata->section_headers + relsec->sh_link;
14778 if (symsec->sh_type != SHT_SYMTAB
14779 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14780 return false;
a788aedd 14781
41e92641
NC
14782 is_rela = relsec->sh_type == SHT_RELA;
14783
14784 if (is_rela)
14785 {
dda8d76d 14786 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14787 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14788 return false;
41e92641
NC
14789 }
14790 else
14791 {
dda8d76d 14792 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14793 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14794 return false;
41e92641
NC
14795 }
14796
14797 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14798 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14799 is_rela = false;
428409d5 14800
4de91c10 14801 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14802
41e92641 14803 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14804 {
015dc7e1
AM
14805 bfd_vma addend;
14806 unsigned int reloc_type;
14807 unsigned int reloc_size;
14808 bool reloc_inplace = false;
14809 bool reloc_subtract = false;
14810 unsigned char *rloc;
14811 unsigned long sym_index;
4b78141a 14812
dda8d76d 14813 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14814
dda8d76d 14815 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14816 continue;
dda8d76d 14817 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14818 continue;
dda8d76d
NC
14819 else if (is_32bit_abs_reloc (filedata, reloc_type)
14820 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14821 reloc_size = 4;
dda8d76d
NC
14822 else if (is_64bit_abs_reloc (filedata, reloc_type)
14823 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14824 reloc_size = 8;
dda8d76d 14825 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14826 reloc_size = 3;
dda8d76d 14827 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14828 reloc_size = 2;
39e07931
AS
14829 else if (is_8bit_abs_reloc (filedata, reloc_type)
14830 || is_6bit_abs_reloc (filedata, reloc_type))
14831 reloc_size = 1;
03336641
JW
14832 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14833 reloc_type))
14834 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14835 {
14836 reloc_size = 4;
015dc7e1 14837 reloc_inplace = true;
03336641
JW
14838 }
14839 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14840 reloc_type))
14841 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14842 {
14843 reloc_size = 8;
015dc7e1 14844 reloc_inplace = true;
03336641
JW
14845 }
14846 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14847 reloc_type))
14848 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14849 {
14850 reloc_size = 2;
015dc7e1 14851 reloc_inplace = true;
03336641
JW
14852 }
14853 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14854 reloc_type))
14855 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14856 {
14857 reloc_size = 1;
015dc7e1 14858 reloc_inplace = true;
03336641 14859 }
39e07931
AS
14860 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14861 reloc_type)))
14862 {
14863 reloc_size = 1;
015dc7e1 14864 reloc_inplace = true;
39e07931 14865 }
aca88567 14866 else
4b78141a 14867 {
bee0ee85 14868 static unsigned int prev_reloc = 0;
dda8d76d 14869
bee0ee85
NC
14870 if (reloc_type != prev_reloc)
14871 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14872 reloc_type, printable_section_name (filedata, section));
bee0ee85 14873 prev_reloc = reloc_type;
4b78141a
NC
14874 continue;
14875 }
103f02d3 14876
91d6fa6a 14877 rloc = start + rp->r_offset;
75802ccb 14878 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14879 {
14880 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14881 (unsigned long) rp->r_offset,
dda8d76d 14882 printable_section_name (filedata, section));
700dd8b7
L
14883 continue;
14884 }
103f02d3 14885
ba5cdace
NC
14886 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14887 if (sym_index >= num_syms)
14888 {
14889 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14890 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14891 continue;
14892 }
14893 sym = symtab + sym_index;
41e92641
NC
14894
14895 /* If the reloc has a symbol associated with it,
55f25fc3
L
14896 make sure that it is of an appropriate type.
14897
14898 Relocations against symbols without type can happen.
14899 Gcc -feliminate-dwarf2-dups may generate symbols
14900 without type for debug info.
14901
14902 Icc generates relocations against function symbols
14903 instead of local labels.
14904
14905 Relocations against object symbols can happen, eg when
14906 referencing a global array. For an example of this see
14907 the _clz.o binary in libgcc.a. */
aca88567 14908 if (sym != symtab
b8871f35 14909 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14910 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14911 {
d3a49aa8 14912 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14913 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14914 printable_section_name (filedata, relsec),
d3a49aa8 14915 (long int)(rp - relocs));
aca88567 14916 continue;
5b18a4bc 14917 }
252b5132 14918
4dc3c23d
AM
14919 addend = 0;
14920 if (is_rela)
14921 addend += rp->r_addend;
c47320c3
AM
14922 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14923 partial_inplace. */
4dc3c23d 14924 if (!is_rela
dda8d76d 14925 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14926 && reloc_type == 1)
dda8d76d
NC
14927 || ((filedata->file_header.e_machine == EM_PJ
14928 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14929 && reloc_type == 1)
dda8d76d
NC
14930 || ((filedata->file_header.e_machine == EM_D30V
14931 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14932 && reloc_type == 12)
14933 || reloc_inplace)
39e07931
AS
14934 {
14935 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14936 addend += byte_get (rloc, reloc_size) & 0x3f;
14937 else
14938 addend += byte_get (rloc, reloc_size);
14939 }
cb8f3167 14940
dda8d76d
NC
14941 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14942 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14943 {
14944 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14945 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14946 addend -= 8;
91d6fa6a 14947 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14948 reloc_size);
14949 }
39e07931
AS
14950 else if (is_6bit_abs_reloc (filedata, reloc_type)
14951 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14952 {
14953 if (reloc_subtract)
14954 addend -= sym->st_value;
14955 else
14956 addend += sym->st_value;
14957 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14958 byte_put (rloc, addend, reloc_size);
14959 }
03336641
JW
14960 else if (reloc_subtract)
14961 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14962 else
91d6fa6a 14963 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14964 }
252b5132 14965
5b18a4bc 14966 free (symtab);
f84ce13b
NC
14967 /* Let the target specific reloc processing code know that
14968 we have finished with these relocs. */
dda8d76d 14969 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14970
14971 if (relocs_return)
14972 {
14973 * (Elf_Internal_Rela **) relocs_return = relocs;
14974 * num_relocs_return = num_relocs;
14975 }
14976 else
14977 free (relocs);
14978
5b18a4bc
NC
14979 break;
14980 }
32ec8896 14981
015dc7e1 14982 return true;
5b18a4bc 14983}
103f02d3 14984
cf13d699 14985#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14986static bool
dda8d76d 14987disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14988{
dda8d76d 14989 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14990
74e1a04b 14991 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14992
015dc7e1 14993 return true;
cf13d699
NC
14994}
14995#endif
14996
14997/* Reads in the contents of SECTION from FILE, returning a pointer
14998 to a malloc'ed buffer or NULL if something went wrong. */
14999
15000static char *
dda8d76d 15001get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15002{
dda8d76d 15003 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
15004
15005 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15006 {
c6b78c96 15007 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15008 printable_section_name (filedata, section));
cf13d699
NC
15009 return NULL;
15010 }
15011
dda8d76d 15012 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15013 _("section contents"));
cf13d699
NC
15014}
15015
0e602686
NC
15016/* Uncompresses a section that was compressed using zlib, in place. */
15017
015dc7e1 15018static bool
dda8d76d
NC
15019uncompress_section_contents (unsigned char ** buffer,
15020 dwarf_size_type uncompressed_size,
15021 dwarf_size_type * size)
0e602686
NC
15022{
15023 dwarf_size_type compressed_size = *size;
15024 unsigned char * compressed_buffer = *buffer;
15025 unsigned char * uncompressed_buffer;
15026 z_stream strm;
15027 int rc;
15028
15029 /* It is possible the section consists of several compressed
15030 buffers concatenated together, so we uncompress in a loop. */
15031 /* PR 18313: The state field in the z_stream structure is supposed
15032 to be invisible to the user (ie us), but some compilers will
15033 still complain about it being used without initialisation. So
15034 we first zero the entire z_stream structure and then set the fields
15035 that we need. */
15036 memset (& strm, 0, sizeof strm);
15037 strm.avail_in = compressed_size;
15038 strm.next_in = (Bytef *) compressed_buffer;
15039 strm.avail_out = uncompressed_size;
15040 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15041
15042 rc = inflateInit (& strm);
15043 while (strm.avail_in > 0)
15044 {
15045 if (rc != Z_OK)
3624a6c1 15046 break;
0e602686
NC
15047 strm.next_out = ((Bytef *) uncompressed_buffer
15048 + (uncompressed_size - strm.avail_out));
15049 rc = inflate (&strm, Z_FINISH);
15050 if (rc != Z_STREAM_END)
3624a6c1 15051 break;
0e602686
NC
15052 rc = inflateReset (& strm);
15053 }
ad92f33d
AM
15054 if (inflateEnd (& strm) != Z_OK
15055 || rc != Z_OK
0e602686
NC
15056 || strm.avail_out != 0)
15057 goto fail;
15058
15059 *buffer = uncompressed_buffer;
15060 *size = uncompressed_size;
015dc7e1 15061 return true;
0e602686
NC
15062
15063 fail:
15064 free (uncompressed_buffer);
15065 /* Indicate decompression failure. */
15066 *buffer = NULL;
015dc7e1 15067 return false;
0e602686 15068}
dd24e3da 15069
015dc7e1 15070static bool
dda8d76d 15071dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15072{
015dc7e1
AM
15073 Elf_Internal_Shdr *relsec;
15074 bfd_size_type num_bytes;
15075 unsigned char *data;
15076 unsigned char *end;
15077 unsigned char *real_start;
15078 unsigned char *start;
15079 bool some_strings_shown;
cf13d699 15080
dda8d76d 15081 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15082 if (start == NULL)
c6b78c96 15083 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15084 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15085
0e602686 15086 num_bytes = section->sh_size;
cf13d699 15087
835f2fae
NC
15088 if (filedata->is_separate)
15089 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15090 printable_section_name (filedata, section),
15091 filedata->file_name);
15092 else
15093 printf (_("\nString dump of section '%s':\n"),
15094 printable_section_name (filedata, section));
cf13d699 15095
0e602686
NC
15096 if (decompress_dumps)
15097 {
15098 dwarf_size_type new_size = num_bytes;
15099 dwarf_size_type uncompressed_size = 0;
15100
15101 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15102 {
15103 Elf_Internal_Chdr chdr;
15104 unsigned int compression_header_size
ebdf1ebf
NC
15105 = get_compression_header (& chdr, (unsigned char *) start,
15106 num_bytes);
5844b465
NC
15107 if (compression_header_size == 0)
15108 /* An error message will have already been generated
15109 by get_compression_header. */
15110 goto error_out;
0e602686 15111
813dabb9 15112 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15113 {
813dabb9 15114 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15115 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15116 goto error_out;
813dabb9 15117 }
813dabb9
L
15118 uncompressed_size = chdr.ch_size;
15119 start += compression_header_size;
15120 new_size -= compression_header_size;
0e602686
NC
15121 }
15122 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15123 {
15124 /* Read the zlib header. In this case, it should be "ZLIB"
15125 followed by the uncompressed section size, 8 bytes in
15126 big-endian order. */
15127 uncompressed_size = start[4]; uncompressed_size <<= 8;
15128 uncompressed_size += start[5]; uncompressed_size <<= 8;
15129 uncompressed_size += start[6]; uncompressed_size <<= 8;
15130 uncompressed_size += start[7]; uncompressed_size <<= 8;
15131 uncompressed_size += start[8]; uncompressed_size <<= 8;
15132 uncompressed_size += start[9]; uncompressed_size <<= 8;
15133 uncompressed_size += start[10]; uncompressed_size <<= 8;
15134 uncompressed_size += start[11];
15135 start += 12;
15136 new_size -= 12;
15137 }
15138
1835f746
NC
15139 if (uncompressed_size)
15140 {
15141 if (uncompress_section_contents (& start,
15142 uncompressed_size, & new_size))
15143 num_bytes = new_size;
15144 else
15145 {
15146 error (_("Unable to decompress section %s\n"),
dda8d76d 15147 printable_section_name (filedata, section));
f761cb13 15148 goto error_out;
1835f746
NC
15149 }
15150 }
bc303e5d
NC
15151 else
15152 start = real_start;
0e602686 15153 }
fd8008d8 15154
cf13d699
NC
15155 /* If the section being dumped has relocations against it the user might
15156 be expecting these relocations to have been applied. Check for this
15157 case and issue a warning message in order to avoid confusion.
15158 FIXME: Maybe we ought to have an option that dumps a section with
15159 relocs applied ? */
dda8d76d
NC
15160 for (relsec = filedata->section_headers;
15161 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15162 ++relsec)
15163 {
15164 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15165 || relsec->sh_info >= filedata->file_header.e_shnum
15166 || filedata->section_headers + relsec->sh_info != section
cf13d699 15167 || relsec->sh_size == 0
dda8d76d 15168 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15169 continue;
15170
15171 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15172 break;
15173 }
15174
cf13d699
NC
15175 data = start;
15176 end = start + num_bytes;
015dc7e1 15177 some_strings_shown = false;
cf13d699 15178
ba3265d0
NC
15179#ifdef HAVE_MBSTATE_T
15180 mbstate_t state;
15181 /* Initialise the multibyte conversion state. */
15182 memset (& state, 0, sizeof (state));
15183#endif
15184
015dc7e1 15185 bool continuing = false;
ba3265d0 15186
cf13d699
NC
15187 while (data < end)
15188 {
15189 while (!ISPRINT (* data))
15190 if (++ data >= end)
15191 break;
15192
15193 if (data < end)
15194 {
071436c6
NC
15195 size_t maxlen = end - data;
15196
ba3265d0
NC
15197 if (continuing)
15198 {
15199 printf (" ");
015dc7e1 15200 continuing = false;
ba3265d0
NC
15201 }
15202 else
15203 {
d1ce973e 15204 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15205 }
15206
4082ef84
NC
15207 if (maxlen > 0)
15208 {
f3da8a96 15209 char c = 0;
ba3265d0
NC
15210
15211 while (maxlen)
15212 {
15213 c = *data++;
15214
15215 if (c == 0)
15216 break;
15217
15218 /* PR 25543: Treat new-lines as string-ending characters. */
15219 if (c == '\n')
15220 {
15221 printf ("\\n\n");
15222 if (*data != 0)
015dc7e1 15223 continuing = true;
ba3265d0
NC
15224 break;
15225 }
15226
15227 /* Do not print control characters directly as they can affect terminal
15228 settings. Such characters usually appear in the names generated
15229 by the assembler for local labels. */
15230 if (ISCNTRL (c))
15231 {
15232 printf ("^%c", c + 0x40);
15233 }
15234 else if (ISPRINT (c))
15235 {
15236 putchar (c);
15237 }
15238 else
15239 {
15240 size_t n;
15241#ifdef HAVE_MBSTATE_T
15242 wchar_t w;
15243#endif
15244 /* Let printf do the hard work of displaying multibyte characters. */
15245 printf ("%.1s", data - 1);
15246#ifdef HAVE_MBSTATE_T
15247 /* Try to find out how many bytes made up the character that was
15248 just printed. Advance the symbol pointer past the bytes that
15249 were displayed. */
15250 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15251#else
15252 n = 1;
15253#endif
15254 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15255 data += (n - 1);
15256 }
15257 }
15258
15259 if (c != '\n')
15260 putchar ('\n');
4082ef84
NC
15261 }
15262 else
15263 {
15264 printf (_("<corrupt>\n"));
15265 data = end;
15266 }
015dc7e1 15267 some_strings_shown = true;
cf13d699
NC
15268 }
15269 }
15270
15271 if (! some_strings_shown)
15272 printf (_(" No strings found in this section."));
15273
0e602686 15274 free (real_start);
cf13d699
NC
15275
15276 putchar ('\n');
015dc7e1 15277 return true;
f761cb13
AM
15278
15279error_out:
15280 free (real_start);
015dc7e1 15281 return false;
cf13d699
NC
15282}
15283
015dc7e1
AM
15284static bool
15285dump_section_as_bytes (Elf_Internal_Shdr *section,
15286 Filedata *filedata,
15287 bool relocate)
cf13d699
NC
15288{
15289 Elf_Internal_Shdr * relsec;
0e602686
NC
15290 bfd_size_type bytes;
15291 bfd_size_type section_size;
15292 bfd_vma addr;
15293 unsigned char * data;
15294 unsigned char * real_start;
15295 unsigned char * start;
15296
dda8d76d 15297 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15298 if (start == NULL)
c6b78c96 15299 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15300 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15301
0e602686 15302 section_size = section->sh_size;
cf13d699 15303
835f2fae
NC
15304 if (filedata->is_separate)
15305 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15306 printable_section_name (filedata, section),
15307 filedata->file_name);
15308 else
15309 printf (_("\nHex dump of section '%s':\n"),
15310 printable_section_name (filedata, section));
cf13d699 15311
0e602686
NC
15312 if (decompress_dumps)
15313 {
15314 dwarf_size_type new_size = section_size;
15315 dwarf_size_type uncompressed_size = 0;
15316
15317 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15318 {
15319 Elf_Internal_Chdr chdr;
15320 unsigned int compression_header_size
ebdf1ebf 15321 = get_compression_header (& chdr, start, section_size);
0e602686 15322
5844b465
NC
15323 if (compression_header_size == 0)
15324 /* An error message will have already been generated
15325 by get_compression_header. */
15326 goto error_out;
15327
813dabb9 15328 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15329 {
813dabb9 15330 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15331 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15332 goto error_out;
0e602686 15333 }
813dabb9
L
15334 uncompressed_size = chdr.ch_size;
15335 start += compression_header_size;
15336 new_size -= compression_header_size;
0e602686
NC
15337 }
15338 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15339 {
15340 /* Read the zlib header. In this case, it should be "ZLIB"
15341 followed by the uncompressed section size, 8 bytes in
15342 big-endian order. */
15343 uncompressed_size = start[4]; uncompressed_size <<= 8;
15344 uncompressed_size += start[5]; uncompressed_size <<= 8;
15345 uncompressed_size += start[6]; uncompressed_size <<= 8;
15346 uncompressed_size += start[7]; uncompressed_size <<= 8;
15347 uncompressed_size += start[8]; uncompressed_size <<= 8;
15348 uncompressed_size += start[9]; uncompressed_size <<= 8;
15349 uncompressed_size += start[10]; uncompressed_size <<= 8;
15350 uncompressed_size += start[11];
15351 start += 12;
15352 new_size -= 12;
15353 }
15354
f055032e
NC
15355 if (uncompressed_size)
15356 {
15357 if (uncompress_section_contents (& start, uncompressed_size,
15358 & new_size))
bc303e5d
NC
15359 {
15360 section_size = new_size;
15361 }
f055032e
NC
15362 else
15363 {
15364 error (_("Unable to decompress section %s\n"),
dda8d76d 15365 printable_section_name (filedata, section));
bc303e5d 15366 /* FIXME: Print the section anyway ? */
f761cb13 15367 goto error_out;
f055032e
NC
15368 }
15369 }
bc303e5d
NC
15370 else
15371 start = real_start;
0e602686 15372 }
14ae95f2 15373
cf13d699
NC
15374 if (relocate)
15375 {
dda8d76d 15376 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15377 goto error_out;
cf13d699
NC
15378 }
15379 else
15380 {
15381 /* If the section being dumped has relocations against it the user might
15382 be expecting these relocations to have been applied. Check for this
15383 case and issue a warning message in order to avoid confusion.
15384 FIXME: Maybe we ought to have an option that dumps a section with
15385 relocs applied ? */
dda8d76d
NC
15386 for (relsec = filedata->section_headers;
15387 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15388 ++relsec)
15389 {
15390 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15391 || relsec->sh_info >= filedata->file_header.e_shnum
15392 || filedata->section_headers + relsec->sh_info != section
cf13d699 15393 || relsec->sh_size == 0
dda8d76d 15394 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15395 continue;
15396
15397 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15398 break;
15399 }
15400 }
15401
15402 addr = section->sh_addr;
0e602686 15403 bytes = section_size;
cf13d699
NC
15404 data = start;
15405
15406 while (bytes)
15407 {
15408 int j;
15409 int k;
15410 int lbytes;
15411
15412 lbytes = (bytes > 16 ? 16 : bytes);
15413
15414 printf (" 0x%8.8lx ", (unsigned long) addr);
15415
15416 for (j = 0; j < 16; j++)
15417 {
15418 if (j < lbytes)
15419 printf ("%2.2x", data[j]);
15420 else
15421 printf (" ");
15422
15423 if ((j & 3) == 3)
15424 printf (" ");
15425 }
15426
15427 for (j = 0; j < lbytes; j++)
15428 {
15429 k = data[j];
15430 if (k >= ' ' && k < 0x7f)
15431 printf ("%c", k);
15432 else
15433 printf (".");
15434 }
15435
15436 putchar ('\n');
15437
15438 data += lbytes;
15439 addr += lbytes;
15440 bytes -= lbytes;
15441 }
15442
0e602686 15443 free (real_start);
cf13d699
NC
15444
15445 putchar ('\n');
015dc7e1 15446 return true;
f761cb13
AM
15447
15448 error_out:
15449 free (real_start);
015dc7e1 15450 return false;
cf13d699
NC
15451}
15452
094e34f2 15453#ifdef ENABLE_LIBCTF
7d9813f1
NA
15454static ctf_sect_t *
15455shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15456{
84714f86 15457 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15458 buf->cts_size = shdr->sh_size;
15459 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15460
15461 return buf;
15462}
15463
15464/* Formatting callback function passed to ctf_dump. Returns either the pointer
15465 it is passed, or a pointer to newly-allocated storage, in which case
15466 dump_ctf() will free it when it no longer needs it. */
15467
2f6ecaed
NA
15468static char *
15469dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15470 char *s, void *arg)
7d9813f1 15471{
3e50a591 15472 const char *blanks = arg;
7d9813f1
NA
15473 char *new_s;
15474
3e50a591 15475 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15476 return s;
15477 return new_s;
15478}
15479
926c9e76
NA
15480/* Dump CTF errors/warnings. */
15481static void
139633c3 15482dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15483{
15484 ctf_next_t *it = NULL;
15485 char *errtext;
15486 int is_warning;
15487 int err;
15488
15489 /* Dump accumulated errors and warnings. */
15490 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15491 {
5e9b84f7 15492 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15493 errtext);
15494 free (errtext);
15495 }
15496 if (err != ECTF_NEXT_END)
15497 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15498}
15499
2f6ecaed
NA
15500/* Dump one CTF archive member. */
15501
80b56fad
NA
15502static void
15503dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15504 size_t member)
2f6ecaed 15505{
2f6ecaed
NA
15506 const char *things[] = {"Header", "Labels", "Data objects",
15507 "Function objects", "Variables", "Types", "Strings",
15508 ""};
15509 const char **thing;
15510 size_t i;
15511
80b56fad
NA
15512 /* Don't print out the name of the default-named archive member if it appears
15513 first in the list. The name .ctf appears everywhere, even for things that
15514 aren't really archives, so printing it out is liable to be confusing; also,
15515 the common case by far is for only one archive member to exist, and hiding
15516 it in that case seems worthwhile. */
2f6ecaed 15517
80b56fad
NA
15518 if (strcmp (name, ".ctf") != 0 || member != 0)
15519 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15520
80b56fad
NA
15521 if (ctf_parent_name (ctf) != NULL)
15522 ctf_import (ctf, parent);
2f6ecaed
NA
15523
15524 for (i = 0, thing = things; *thing[0]; thing++, i++)
15525 {
15526 ctf_dump_state_t *s = NULL;
15527 char *item;
15528
15529 printf ("\n %s:\n", *thing);
15530 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15531 (void *) " ")) != NULL)
15532 {
15533 printf ("%s\n", item);
15534 free (item);
15535 }
15536
15537 if (ctf_errno (ctf))
15538 {
15539 error (_("Iteration failed: %s, %s\n"), *thing,
15540 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15541 break;
2f6ecaed
NA
15542 }
15543 }
8b37e7b6 15544
926c9e76 15545 dump_ctf_errs (ctf);
2f6ecaed
NA
15546}
15547
015dc7e1 15548static bool
7d9813f1
NA
15549dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15550{
7d9813f1
NA
15551 Elf_Internal_Shdr * symtab_sec = NULL;
15552 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15553 void * data = NULL;
15554 void * symdata = NULL;
15555 void * strdata = NULL;
80b56fad 15556 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15557 ctf_sect_t * symsectp = NULL;
15558 ctf_sect_t * strsectp = NULL;
2f6ecaed 15559 ctf_archive_t * ctfa = NULL;
139633c3 15560 ctf_dict_t * parent = NULL;
80b56fad 15561 ctf_dict_t * fp;
7d9813f1 15562
80b56fad
NA
15563 ctf_next_t *i = NULL;
15564 const char *name;
15565 size_t member = 0;
7d9813f1 15566 int err;
015dc7e1 15567 bool ret = false;
7d9813f1
NA
15568
15569 shdr_to_ctf_sect (&ctfsect, section, filedata);
15570 data = get_section_contents (section, filedata);
15571 ctfsect.cts_data = data;
15572
616febde 15573 if (!dump_ctf_symtab_name)
3d16b64e 15574 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15575
15576 if (!dump_ctf_strtab_name)
3d16b64e 15577 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15578
15579 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15580 {
15581 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15582 {
15583 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15584 goto fail;
15585 }
15586 if ((symdata = (void *) get_data (NULL, filedata,
15587 symtab_sec->sh_offset, 1,
15588 symtab_sec->sh_size,
15589 _("symbols"))) == NULL)
15590 goto fail;
15591 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15592 symsect.cts_data = symdata;
15593 }
835f2fae 15594
df16e041 15595 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15596 {
15597 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15598 {
15599 error (_("No string table section named %s\n"),
15600 dump_ctf_strtab_name);
15601 goto fail;
15602 }
15603 if ((strdata = (void *) get_data (NULL, filedata,
15604 strtab_sec->sh_offset, 1,
15605 strtab_sec->sh_size,
15606 _("strings"))) == NULL)
15607 goto fail;
15608 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15609 strsect.cts_data = strdata;
15610 }
835f2fae 15611
2f6ecaed
NA
15612 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15613 libctf papers over the difference, so we can pretend it is always an
80b56fad 15614 archive. */
7d9813f1 15615
2f6ecaed 15616 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15617 {
926c9e76 15618 dump_ctf_errs (NULL);
7d9813f1
NA
15619 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15620 goto fail;
15621 }
15622
96c61be5
NA
15623 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15624 != ELFDATA2MSB);
15625
80b56fad
NA
15626 /* Preload the parent dict, since it will need to be imported into every
15627 child in turn. */
15628 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15629 {
926c9e76 15630 dump_ctf_errs (NULL);
2f6ecaed
NA
15631 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15632 goto fail;
7d9813f1
NA
15633 }
15634
015dc7e1 15635 ret = true;
7d9813f1 15636
835f2fae
NC
15637 if (filedata->is_separate)
15638 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15639 printable_section_name (filedata, section),
15640 filedata->file_name);
15641 else
15642 printf (_("\nDump of CTF section '%s':\n"),
15643 printable_section_name (filedata, section));
7d9813f1 15644
80b56fad
NA
15645 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15646 dump_ctf_archive_member (fp, name, parent, member++);
15647 if (err != ECTF_NEXT_END)
15648 {
15649 dump_ctf_errs (NULL);
15650 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15651 ret = false;
15652 }
7d9813f1
NA
15653
15654 fail:
139633c3 15655 ctf_dict_close (parent);
2f6ecaed 15656 ctf_close (ctfa);
7d9813f1
NA
15657 free (data);
15658 free (symdata);
15659 free (strdata);
15660 return ret;
15661}
094e34f2 15662#endif
7d9813f1 15663
015dc7e1 15664static bool
dda8d76d
NC
15665load_specific_debug_section (enum dwarf_section_display_enum debug,
15666 const Elf_Internal_Shdr * sec,
15667 void * data)
1007acb3 15668{
2cf0635d 15669 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15670 char buf [64];
dda8d76d 15671 Filedata * filedata = (Filedata *) data;
9abca702 15672
19e6b90e 15673 if (section->start != NULL)
dda8d76d
NC
15674 {
15675 /* If it is already loaded, do nothing. */
15676 if (streq (section->filename, filedata->file_name))
015dc7e1 15677 return true;
dda8d76d
NC
15678 free (section->start);
15679 }
1007acb3 15680
19e6b90e
L
15681 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15682 section->address = sec->sh_addr;
dda8d76d
NC
15683 section->filename = filedata->file_name;
15684 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15685 sec->sh_offset, 1,
15686 sec->sh_size, buf);
59245841
NC
15687 if (section->start == NULL)
15688 section->size = 0;
15689 else
15690 {
77115a4a
L
15691 unsigned char *start = section->start;
15692 dwarf_size_type size = sec->sh_size;
dab394de 15693 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15694
15695 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15696 {
15697 Elf_Internal_Chdr chdr;
d8024a91
NC
15698 unsigned int compression_header_size;
15699
f53be977
L
15700 if (size < (is_32bit_elf
15701 ? sizeof (Elf32_External_Chdr)
15702 : sizeof (Elf64_External_Chdr)))
d8024a91 15703 {
55be8fd0 15704 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15705 section->name);
015dc7e1 15706 return false;
d8024a91
NC
15707 }
15708
ebdf1ebf 15709 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15710 if (compression_header_size == 0)
15711 /* An error message will have already been generated
15712 by get_compression_header. */
015dc7e1 15713 return false;
d8024a91 15714
813dabb9
L
15715 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15716 {
15717 warn (_("section '%s' has unsupported compress type: %d\n"),
15718 section->name, chdr.ch_type);
015dc7e1 15719 return false;
813dabb9 15720 }
dab394de 15721 uncompressed_size = chdr.ch_size;
77115a4a
L
15722 start += compression_header_size;
15723 size -= compression_header_size;
15724 }
dab394de
L
15725 else if (size > 12 && streq ((char *) start, "ZLIB"))
15726 {
15727 /* Read the zlib header. In this case, it should be "ZLIB"
15728 followed by the uncompressed section size, 8 bytes in
15729 big-endian order. */
15730 uncompressed_size = start[4]; uncompressed_size <<= 8;
15731 uncompressed_size += start[5]; uncompressed_size <<= 8;
15732 uncompressed_size += start[6]; uncompressed_size <<= 8;
15733 uncompressed_size += start[7]; uncompressed_size <<= 8;
15734 uncompressed_size += start[8]; uncompressed_size <<= 8;
15735 uncompressed_size += start[9]; uncompressed_size <<= 8;
15736 uncompressed_size += start[10]; uncompressed_size <<= 8;
15737 uncompressed_size += start[11];
15738 start += 12;
15739 size -= 12;
15740 }
15741
1835f746 15742 if (uncompressed_size)
77115a4a 15743 {
1835f746
NC
15744 if (uncompress_section_contents (&start, uncompressed_size,
15745 &size))
15746 {
15747 /* Free the compressed buffer, update the section buffer
15748 and the section size if uncompress is successful. */
15749 free (section->start);
15750 section->start = start;
15751 }
15752 else
15753 {
15754 error (_("Unable to decompress section %s\n"),
dda8d76d 15755 printable_section_name (filedata, sec));
015dc7e1 15756 return false;
1835f746 15757 }
77115a4a 15758 }
bc303e5d 15759
77115a4a 15760 section->size = size;
59245841 15761 }
4a114e3e 15762
1b315056 15763 if (section->start == NULL)
015dc7e1 15764 return false;
1b315056 15765
19e6b90e 15766 if (debug_displays [debug].relocate)
32ec8896 15767 {
dda8d76d 15768 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15769 & section->reloc_info, & section->num_relocs))
015dc7e1 15770 return false;
32ec8896 15771 }
d1c4b12b
NC
15772 else
15773 {
15774 section->reloc_info = NULL;
15775 section->num_relocs = 0;
15776 }
1007acb3 15777
015dc7e1 15778 return true;
1007acb3
L
15779}
15780
301a9420
AM
15781#if HAVE_LIBDEBUGINFOD
15782/* Return a hex string representation of the build-id. */
15783unsigned char *
15784get_build_id (void * data)
15785{
ca0e11aa 15786 Filedata * filedata = (Filedata *) data;
301a9420
AM
15787 Elf_Internal_Shdr * shdr;
15788 unsigned long i;
15789
55be8fd0
NC
15790 /* Iterate through notes to find note.gnu.build-id.
15791 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15792 for (i = 0, shdr = filedata->section_headers;
15793 i < filedata->file_header.e_shnum && shdr != NULL;
15794 i++, shdr++)
15795 {
15796 if (shdr->sh_type != SHT_NOTE)
15797 continue;
15798
15799 char * next;
15800 char * end;
15801 size_t data_remaining;
15802 size_t min_notesz;
15803 Elf_External_Note * enote;
15804 Elf_Internal_Note inote;
15805
15806 bfd_vma offset = shdr->sh_offset;
15807 bfd_vma align = shdr->sh_addralign;
15808 bfd_vma length = shdr->sh_size;
15809
15810 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15811 if (enote == NULL)
15812 continue;
15813
15814 if (align < 4)
15815 align = 4;
15816 else if (align != 4 && align != 8)
f761cb13
AM
15817 {
15818 free (enote);
15819 continue;
15820 }
301a9420
AM
15821
15822 end = (char *) enote + length;
15823 data_remaining = end - (char *) enote;
15824
15825 if (!is_ia64_vms (filedata))
15826 {
15827 min_notesz = offsetof (Elf_External_Note, name);
15828 if (data_remaining < min_notesz)
15829 {
55be8fd0
NC
15830 warn (_("\
15831malformed note encountered in section %s whilst scanning for build-id note\n"),
15832 printable_section_name (filedata, shdr));
f761cb13 15833 free (enote);
55be8fd0 15834 continue;
301a9420
AM
15835 }
15836 data_remaining -= min_notesz;
15837
15838 inote.type = BYTE_GET (enote->type);
15839 inote.namesz = BYTE_GET (enote->namesz);
15840 inote.namedata = enote->name;
15841 inote.descsz = BYTE_GET (enote->descsz);
15842 inote.descdata = ((char *) enote
15843 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15844 inote.descpos = offset + (inote.descdata - (char *) enote);
15845 next = ((char *) enote
15846 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15847 }
15848 else
15849 {
15850 Elf64_External_VMS_Note *vms_enote;
15851
15852 /* PR binutils/15191
15853 Make sure that there is enough data to read. */
15854 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15855 if (data_remaining < min_notesz)
15856 {
55be8fd0
NC
15857 warn (_("\
15858malformed note encountered in section %s whilst scanning for build-id note\n"),
15859 printable_section_name (filedata, shdr));
f761cb13 15860 free (enote);
55be8fd0 15861 continue;
301a9420
AM
15862 }
15863 data_remaining -= min_notesz;
15864
15865 vms_enote = (Elf64_External_VMS_Note *) enote;
15866 inote.type = BYTE_GET (vms_enote->type);
15867 inote.namesz = BYTE_GET (vms_enote->namesz);
15868 inote.namedata = vms_enote->name;
15869 inote.descsz = BYTE_GET (vms_enote->descsz);
15870 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15871 inote.descpos = offset + (inote.descdata - (char *) enote);
15872 next = inote.descdata + align_power (inote.descsz, 3);
15873 }
15874
15875 /* Skip malformed notes. */
15876 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15877 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15878 || (size_t) (next - inote.descdata) < inote.descsz
15879 || ((size_t) (next - inote.descdata)
15880 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15881 {
55be8fd0
NC
15882 warn (_("\
15883malformed note encountered in section %s whilst scanning for build-id note\n"),
15884 printable_section_name (filedata, shdr));
f761cb13 15885 free (enote);
301a9420
AM
15886 continue;
15887 }
15888
15889 /* Check if this is the build-id note. If so then convert the build-id
15890 bytes to a hex string. */
15891 if (inote.namesz > 0
24d127aa 15892 && startswith (inote.namedata, "GNU")
301a9420
AM
15893 && inote.type == NT_GNU_BUILD_ID)
15894 {
15895 unsigned long j;
15896 char * build_id;
15897
15898 build_id = malloc (inote.descsz * 2 + 1);
15899 if (build_id == NULL)
f761cb13
AM
15900 {
15901 free (enote);
15902 return NULL;
15903 }
301a9420
AM
15904
15905 for (j = 0; j < inote.descsz; ++j)
15906 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15907 build_id[inote.descsz * 2] = '\0';
f761cb13 15908 free (enote);
301a9420 15909
55be8fd0 15910 return (unsigned char *) build_id;
301a9420 15911 }
f761cb13 15912 free (enote);
301a9420
AM
15913 }
15914
15915 return NULL;
15916}
15917#endif /* HAVE_LIBDEBUGINFOD */
15918
657d0d47
CC
15919/* If this is not NULL, load_debug_section will only look for sections
15920 within the list of sections given here. */
32ec8896 15921static unsigned int * section_subset = NULL;
657d0d47 15922
015dc7e1 15923bool
dda8d76d 15924load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15925{
2cf0635d
NC
15926 struct dwarf_section * section = &debug_displays [debug].section;
15927 Elf_Internal_Shdr * sec;
dda8d76d
NC
15928 Filedata * filedata = (Filedata *) data;
15929
e1dbfc17
L
15930 if (!dump_any_debugging)
15931 return false;
15932
f425ec66
NC
15933 /* Without section headers we cannot find any sections. */
15934 if (filedata->section_headers == NULL)
015dc7e1 15935 return false;
f425ec66 15936
9c1ce108
AM
15937 if (filedata->string_table == NULL
15938 && filedata->file_header.e_shstrndx != SHN_UNDEF
15939 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15940 {
15941 Elf_Internal_Shdr * strs;
15942
15943 /* Read in the string table, so that we have section names to scan. */
15944 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15945
4dff97b2 15946 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15947 {
9c1ce108
AM
15948 filedata->string_table
15949 = (char *) get_data (NULL, filedata, strs->sh_offset,
15950 1, strs->sh_size, _("string table"));
dda8d76d 15951
9c1ce108
AM
15952 filedata->string_table_length
15953 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15954 }
15955 }
d966045b
DJ
15956
15957 /* Locate the debug section. */
dda8d76d 15958 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15959 if (sec != NULL)
15960 section->name = section->uncompressed_name;
15961 else
15962 {
dda8d76d 15963 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15964 if (sec != NULL)
15965 section->name = section->compressed_name;
15966 }
15967 if (sec == NULL)
015dc7e1 15968 return false;
d966045b 15969
657d0d47
CC
15970 /* If we're loading from a subset of sections, and we've loaded
15971 a section matching this name before, it's likely that it's a
15972 different one. */
15973 if (section_subset != NULL)
15974 free_debug_section (debug);
15975
dda8d76d 15976 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15977}
15978
19e6b90e
L
15979void
15980free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15981{
2cf0635d 15982 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15983
19e6b90e
L
15984 if (section->start == NULL)
15985 return;
1007acb3 15986
19e6b90e
L
15987 free ((char *) section->start);
15988 section->start = NULL;
15989 section->address = 0;
15990 section->size = 0;
a788aedd 15991
9db70fc3
AM
15992 free (section->reloc_info);
15993 section->reloc_info = NULL;
15994 section->num_relocs = 0;
1007acb3
L
15995}
15996
015dc7e1 15997static bool
dda8d76d 15998display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15999{
84714f86
AM
16000 const char *name = (section_name_valid (filedata, section)
16001 ? section_name (filedata, section) : "");
16002 const char *print_name = printable_section_name (filedata, section);
19e6b90e 16003 bfd_size_type length;
015dc7e1 16004 bool result = true;
3f5e193b 16005 int i;
1007acb3 16006
19e6b90e
L
16007 length = section->sh_size;
16008 if (length == 0)
1007acb3 16009 {
74e1a04b 16010 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16011 return true;
1007acb3 16012 }
5dff79d8
NC
16013 if (section->sh_type == SHT_NOBITS)
16014 {
16015 /* There is no point in dumping the contents of a debugging section
16016 which has the NOBITS type - the bits in the file will be random.
16017 This can happen when a file containing a .eh_frame section is
16018 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16019 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16020 print_name);
015dc7e1 16021 return false;
5dff79d8 16022 }
1007acb3 16023
24d127aa 16024 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16025 name = ".debug_info";
1007acb3 16026
19e6b90e
L
16027 /* See if we know how to display the contents of this section. */
16028 for (i = 0; i < max; i++)
d85bf2ba
NC
16029 {
16030 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16031 struct dwarf_section_display * display = debug_displays + i;
16032 struct dwarf_section * sec = & display->section;
d966045b 16033
d85bf2ba 16034 if (streq (sec->uncompressed_name, name)
24d127aa 16035 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16036 || streq (sec->compressed_name, name))
16037 {
015dc7e1 16038 bool secondary = (section != find_section (filedata, name));
1007acb3 16039
d85bf2ba
NC
16040 if (secondary)
16041 free_debug_section (id);
dda8d76d 16042
24d127aa 16043 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16044 sec->name = name;
16045 else if (streq (sec->uncompressed_name, name))
16046 sec->name = sec->uncompressed_name;
16047 else
16048 sec->name = sec->compressed_name;
657d0d47 16049
d85bf2ba
NC
16050 if (load_specific_debug_section (id, section, filedata))
16051 {
16052 /* If this debug section is part of a CU/TU set in a .dwp file,
16053 restrict load_debug_section to the sections in that set. */
16054 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16055
d85bf2ba 16056 result &= display->display (sec, filedata);
657d0d47 16057
d85bf2ba 16058 section_subset = NULL;
1007acb3 16059
44266f36 16060 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16061 free_debug_section (id);
16062 }
16063 break;
16064 }
16065 }
1007acb3 16066
19e6b90e 16067 if (i == max)
1007acb3 16068 {
74e1a04b 16069 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16070 result = false;
1007acb3
L
16071 }
16072
19e6b90e 16073 return result;
5b18a4bc 16074}
103f02d3 16075
aef1f6d0
DJ
16076/* Set DUMP_SECTS for all sections where dumps were requested
16077 based on section name. */
16078
16079static void
dda8d76d 16080initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16081{
2cf0635d 16082 struct dump_list_entry * cur;
aef1f6d0
DJ
16083
16084 for (cur = dump_sects_byname; cur; cur = cur->next)
16085 {
16086 unsigned int i;
015dc7e1 16087 bool any = false;
aef1f6d0 16088
dda8d76d 16089 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16090 if (section_name_valid (filedata, filedata->section_headers + i)
16091 && streq (section_name (filedata, filedata->section_headers + i),
16092 cur->name))
aef1f6d0 16093 {
6431e409 16094 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16095 any = true;
aef1f6d0
DJ
16096 }
16097
835f2fae
NC
16098 if (!any && !filedata->is_separate)
16099 warn (_("Section '%s' was not dumped because it does not exist\n"),
16100 cur->name);
aef1f6d0
DJ
16101 }
16102}
16103
015dc7e1 16104static bool
dda8d76d 16105process_section_contents (Filedata * filedata)
5b18a4bc 16106{
2cf0635d 16107 Elf_Internal_Shdr * section;
19e6b90e 16108 unsigned int i;
015dc7e1 16109 bool res = true;
103f02d3 16110
19e6b90e 16111 if (! do_dump)
015dc7e1 16112 return true;
103f02d3 16113
dda8d76d 16114 initialise_dumps_byname (filedata);
aef1f6d0 16115
dda8d76d 16116 for (i = 0, section = filedata->section_headers;
6431e409 16117 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16118 i++, section++)
16119 {
6431e409 16120 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16121
d6bfbc39
NC
16122 if (filedata->is_separate && ! process_links)
16123 dump &= DEBUG_DUMP;
047c3dbf 16124
19e6b90e 16125#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16126 if (dump & DISASS_DUMP)
16127 {
16128 if (! disassemble_section (section, filedata))
015dc7e1 16129 res = false;
dda8d76d 16130 }
19e6b90e 16131#endif
dda8d76d 16132 if (dump & HEX_DUMP)
32ec8896 16133 {
015dc7e1
AM
16134 if (! dump_section_as_bytes (section, filedata, false))
16135 res = false;
32ec8896 16136 }
103f02d3 16137
dda8d76d 16138 if (dump & RELOC_DUMP)
32ec8896 16139 {
015dc7e1
AM
16140 if (! dump_section_as_bytes (section, filedata, true))
16141 res = false;
32ec8896 16142 }
09c11c86 16143
dda8d76d 16144 if (dump & STRING_DUMP)
32ec8896 16145 {
dda8d76d 16146 if (! dump_section_as_strings (section, filedata))
015dc7e1 16147 res = false;
32ec8896 16148 }
cf13d699 16149
dda8d76d 16150 if (dump & DEBUG_DUMP)
32ec8896 16151 {
dda8d76d 16152 if (! display_debug_section (i, section, filedata))
015dc7e1 16153 res = false;
32ec8896 16154 }
7d9813f1 16155
094e34f2 16156#ifdef ENABLE_LIBCTF
7d9813f1
NA
16157 if (dump & CTF_DUMP)
16158 {
16159 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16160 res = false;
7d9813f1 16161 }
094e34f2 16162#endif
5b18a4bc 16163 }
103f02d3 16164
835f2fae 16165 if (! filedata->is_separate)
0ee3043f 16166 {
835f2fae
NC
16167 /* Check to see if the user requested a
16168 dump of a section that does not exist. */
16169 for (; i < filedata->dump.num_dump_sects; i++)
16170 if (filedata->dump.dump_sects[i])
16171 {
ca0e11aa 16172 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16173 res = false;
835f2fae 16174 }
0ee3043f 16175 }
32ec8896
NC
16176
16177 return res;
5b18a4bc 16178}
103f02d3 16179
5b18a4bc 16180static void
19e6b90e 16181process_mips_fpe_exception (int mask)
5b18a4bc 16182{
19e6b90e
L
16183 if (mask)
16184 {
015dc7e1 16185 bool first = true;
32ec8896 16186
19e6b90e 16187 if (mask & OEX_FPU_INEX)
015dc7e1 16188 fputs ("INEX", stdout), first = false;
19e6b90e 16189 if (mask & OEX_FPU_UFLO)
015dc7e1 16190 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16191 if (mask & OEX_FPU_OFLO)
015dc7e1 16192 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16193 if (mask & OEX_FPU_DIV0)
015dc7e1 16194 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16195 if (mask & OEX_FPU_INVAL)
16196 printf ("%sINVAL", first ? "" : "|");
16197 }
5b18a4bc 16198 else
19e6b90e 16199 fputs ("0", stdout);
5b18a4bc 16200}
103f02d3 16201
f6f0e17b
NC
16202/* Display's the value of TAG at location P. If TAG is
16203 greater than 0 it is assumed to be an unknown tag, and
16204 a message is printed to this effect. Otherwise it is
16205 assumed that a message has already been printed.
16206
16207 If the bottom bit of TAG is set it assumed to have a
16208 string value, otherwise it is assumed to have an integer
16209 value.
16210
16211 Returns an updated P pointing to the first unread byte
16212 beyond the end of TAG's value.
16213
16214 Reads at or beyond END will not be made. */
16215
16216static unsigned char *
60abdbed 16217display_tag_value (signed int tag,
f6f0e17b
NC
16218 unsigned char * p,
16219 const unsigned char * const end)
16220{
16221 unsigned long val;
16222
16223 if (tag > 0)
16224 printf (" Tag_unknown_%d: ", tag);
16225
16226 if (p >= end)
16227 {
4082ef84 16228 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16229 }
16230 else if (tag & 1)
16231 {
071436c6
NC
16232 /* PR 17531 file: 027-19978-0.004. */
16233 size_t maxlen = (end - p) - 1;
16234
16235 putchar ('"');
4082ef84
NC
16236 if (maxlen > 0)
16237 {
16238 print_symbol ((int) maxlen, (const char *) p);
16239 p += strnlen ((char *) p, maxlen) + 1;
16240 }
16241 else
16242 {
16243 printf (_("<corrupt string tag>"));
16244 p = (unsigned char *) end;
16245 }
071436c6 16246 printf ("\"\n");
f6f0e17b
NC
16247 }
16248 else
16249 {
cd30bcef 16250 READ_ULEB (val, p, end);
f6f0e17b
NC
16251 printf ("%ld (0x%lx)\n", val, val);
16252 }
16253
4082ef84 16254 assert (p <= end);
f6f0e17b
NC
16255 return p;
16256}
16257
53a346d8
CZ
16258/* ARC ABI attributes section. */
16259
16260static unsigned char *
16261display_arc_attribute (unsigned char * p,
16262 const unsigned char * const end)
16263{
16264 unsigned int tag;
53a346d8
CZ
16265 unsigned int val;
16266
cd30bcef 16267 READ_ULEB (tag, p, end);
53a346d8
CZ
16268
16269 switch (tag)
16270 {
16271 case Tag_ARC_PCS_config:
cd30bcef 16272 READ_ULEB (val, p, end);
53a346d8
CZ
16273 printf (" Tag_ARC_PCS_config: ");
16274 switch (val)
16275 {
16276 case 0:
16277 printf (_("Absent/Non standard\n"));
16278 break;
16279 case 1:
16280 printf (_("Bare metal/mwdt\n"));
16281 break;
16282 case 2:
16283 printf (_("Bare metal/newlib\n"));
16284 break;
16285 case 3:
16286 printf (_("Linux/uclibc\n"));
16287 break;
16288 case 4:
16289 printf (_("Linux/glibc\n"));
16290 break;
16291 default:
16292 printf (_("Unknown\n"));
16293 break;
16294 }
16295 break;
16296
16297 case Tag_ARC_CPU_base:
cd30bcef 16298 READ_ULEB (val, p, end);
53a346d8
CZ
16299 printf (" Tag_ARC_CPU_base: ");
16300 switch (val)
16301 {
16302 default:
16303 case TAG_CPU_NONE:
16304 printf (_("Absent\n"));
16305 break;
16306 case TAG_CPU_ARC6xx:
16307 printf ("ARC6xx\n");
16308 break;
16309 case TAG_CPU_ARC7xx:
16310 printf ("ARC7xx\n");
16311 break;
16312 case TAG_CPU_ARCEM:
16313 printf ("ARCEM\n");
16314 break;
16315 case TAG_CPU_ARCHS:
16316 printf ("ARCHS\n");
16317 break;
16318 }
16319 break;
16320
16321 case Tag_ARC_CPU_variation:
cd30bcef 16322 READ_ULEB (val, p, end);
53a346d8
CZ
16323 printf (" Tag_ARC_CPU_variation: ");
16324 switch (val)
16325 {
16326 default:
16327 if (val > 0 && val < 16)
53a346d8 16328 printf ("Core%d\n", val);
d8cbc93b
JL
16329 else
16330 printf ("Unknown\n");
16331 break;
16332
53a346d8
CZ
16333 case 0:
16334 printf (_("Absent\n"));
16335 break;
16336 }
16337 break;
16338
16339 case Tag_ARC_CPU_name:
16340 printf (" Tag_ARC_CPU_name: ");
16341 p = display_tag_value (-1, p, end);
16342 break;
16343
16344 case Tag_ARC_ABI_rf16:
cd30bcef 16345 READ_ULEB (val, p, end);
53a346d8
CZ
16346 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16347 break;
16348
16349 case Tag_ARC_ABI_osver:
cd30bcef 16350 READ_ULEB (val, p, end);
53a346d8
CZ
16351 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16352 break;
16353
16354 case Tag_ARC_ABI_pic:
16355 case Tag_ARC_ABI_sda:
cd30bcef 16356 READ_ULEB (val, p, end);
53a346d8
CZ
16357 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16358 : " Tag_ARC_ABI_pic: ");
16359 switch (val)
16360 {
16361 case 0:
16362 printf (_("Absent\n"));
16363 break;
16364 case 1:
16365 printf ("MWDT\n");
16366 break;
16367 case 2:
16368 printf ("GNU\n");
16369 break;
16370 default:
16371 printf (_("Unknown\n"));
16372 break;
16373 }
16374 break;
16375
16376 case Tag_ARC_ABI_tls:
cd30bcef 16377 READ_ULEB (val, p, end);
53a346d8
CZ
16378 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16379 break;
16380
16381 case Tag_ARC_ABI_enumsize:
cd30bcef 16382 READ_ULEB (val, p, end);
53a346d8
CZ
16383 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16384 _("smallest"));
16385 break;
16386
16387 case Tag_ARC_ABI_exceptions:
cd30bcef 16388 READ_ULEB (val, p, end);
53a346d8
CZ
16389 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16390 : _("default"));
16391 break;
16392
16393 case Tag_ARC_ABI_double_size:
cd30bcef 16394 READ_ULEB (val, p, end);
53a346d8
CZ
16395 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16396 break;
16397
16398 case Tag_ARC_ISA_config:
16399 printf (" Tag_ARC_ISA_config: ");
16400 p = display_tag_value (-1, p, end);
16401 break;
16402
16403 case Tag_ARC_ISA_apex:
16404 printf (" Tag_ARC_ISA_apex: ");
16405 p = display_tag_value (-1, p, end);
16406 break;
16407
16408 case Tag_ARC_ISA_mpy_option:
cd30bcef 16409 READ_ULEB (val, p, end);
53a346d8
CZ
16410 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16411 break;
16412
db1e1b45 16413 case Tag_ARC_ATR_version:
cd30bcef 16414 READ_ULEB (val, p, end);
db1e1b45 16415 printf (" Tag_ARC_ATR_version: %d\n", val);
16416 break;
16417
53a346d8
CZ
16418 default:
16419 return display_tag_value (tag & 1, p, end);
16420 }
16421
16422 return p;
16423}
16424
11c1ff18
PB
16425/* ARM EABI attributes section. */
16426typedef struct
16427{
70e99720 16428 unsigned int tag;
2cf0635d 16429 const char * name;
11c1ff18 16430 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16431 unsigned int type;
288f0ba2 16432 const char *const *table;
11c1ff18
PB
16433} arm_attr_public_tag;
16434
288f0ba2 16435static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16436 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16437 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16438 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16439 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16440static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16441static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16442 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16443static const char *const arm_attr_tag_FP_arch[] =
bca38921 16444 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16445 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16446static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16447static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16448 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16449 "NEON for ARMv8.1"};
288f0ba2 16450static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16451 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16452 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16453static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16454 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16455static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16456 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16457static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16458 {"Absolute", "PC-relative", "None"};
288f0ba2 16459static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16460 {"None", "direct", "GOT-indirect"};
288f0ba2 16461static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16462 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16463static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16464static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16465 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16466static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16467static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16468static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16469 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16470static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16471 {"Unused", "small", "int", "forced to int"};
288f0ba2 16472static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16473 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16474static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16475 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16476static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16477 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16478static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16479 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16480 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16481static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16482 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16483 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16484static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16485static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16486 {"Not Allowed", "Allowed"};
288f0ba2 16487static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16488 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16489static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16490 {"Follow architecture", "Allowed"};
288f0ba2 16491static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16492 {"Not Allowed", "Allowed"};
288f0ba2 16493static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16494 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16495 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16496static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16497static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16498 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16499 "TrustZone and Virtualization Extensions"};
288f0ba2 16500static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16501 {"Not Allowed", "Allowed"};
11c1ff18 16502
288f0ba2 16503static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16504 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16505
99db83d0
AC
16506static const char * arm_attr_tag_PAC_extension[] =
16507 {"No PAC/AUT instructions",
16508 "PAC/AUT instructions permitted in the NOP space",
16509 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16510
4b535030
AC
16511static const char * arm_attr_tag_BTI_extension[] =
16512 {"BTI instructions not permitted",
16513 "BTI instructions permitted in the NOP space",
16514 "BTI instructions permitted in the NOP and in the non-NOP space"};
16515
b81ee92f
AC
16516static const char * arm_attr_tag_BTI_use[] =
16517 {"Compiled without branch target enforcement",
16518 "Compiled with branch target enforcement"};
16519
c9fed665
AC
16520static const char * arm_attr_tag_PACRET_use[] =
16521 {"Compiled without return address signing and authentication",
16522 "Compiled with return address signing and authentication"};
16523
11c1ff18
PB
16524#define LOOKUP(id, name) \
16525 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16526static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16527{
16528 {4, "CPU_raw_name", 1, NULL},
16529 {5, "CPU_name", 1, NULL},
16530 LOOKUP(6, CPU_arch),
16531 {7, "CPU_arch_profile", 0, NULL},
16532 LOOKUP(8, ARM_ISA_use),
16533 LOOKUP(9, THUMB_ISA_use),
75375b3e 16534 LOOKUP(10, FP_arch),
11c1ff18 16535 LOOKUP(11, WMMX_arch),
f5f53991
AS
16536 LOOKUP(12, Advanced_SIMD_arch),
16537 LOOKUP(13, PCS_config),
11c1ff18
PB
16538 LOOKUP(14, ABI_PCS_R9_use),
16539 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16540 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16541 LOOKUP(17, ABI_PCS_GOT_use),
16542 LOOKUP(18, ABI_PCS_wchar_t),
16543 LOOKUP(19, ABI_FP_rounding),
16544 LOOKUP(20, ABI_FP_denormal),
16545 LOOKUP(21, ABI_FP_exceptions),
16546 LOOKUP(22, ABI_FP_user_exceptions),
16547 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16548 {24, "ABI_align_needed", 0, NULL},
16549 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16550 LOOKUP(26, ABI_enum_size),
16551 LOOKUP(27, ABI_HardFP_use),
16552 LOOKUP(28, ABI_VFP_args),
16553 LOOKUP(29, ABI_WMMX_args),
16554 LOOKUP(30, ABI_optimization_goals),
16555 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16556 {32, "compatibility", 0, NULL},
f5f53991 16557 LOOKUP(34, CPU_unaligned_access),
75375b3e 16558 LOOKUP(36, FP_HP_extension),
8e79c3df 16559 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16560 LOOKUP(42, MPextension_use),
16561 LOOKUP(44, DIV_use),
15afaa63 16562 LOOKUP(46, DSP_extension),
a7ad558c 16563 LOOKUP(48, MVE_arch),
99db83d0 16564 LOOKUP(50, PAC_extension),
4b535030 16565 LOOKUP(52, BTI_extension),
b81ee92f 16566 LOOKUP(74, BTI_use),
c9fed665 16567 LOOKUP(76, PACRET_use),
f5f53991
AS
16568 {64, "nodefaults", 0, NULL},
16569 {65, "also_compatible_with", 0, NULL},
16570 LOOKUP(66, T2EE_use),
16571 {67, "conformance", 1, NULL},
16572 LOOKUP(68, Virtualization_use),
cd21e546 16573 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16574};
16575#undef LOOKUP
16576
11c1ff18 16577static unsigned char *
f6f0e17b
NC
16578display_arm_attribute (unsigned char * p,
16579 const unsigned char * const end)
11c1ff18 16580{
70e99720 16581 unsigned int tag;
70e99720 16582 unsigned int val;
2cf0635d 16583 arm_attr_public_tag * attr;
11c1ff18 16584 unsigned i;
70e99720 16585 unsigned int type;
11c1ff18 16586
cd30bcef 16587 READ_ULEB (tag, p, end);
11c1ff18 16588 attr = NULL;
2cf0635d 16589 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16590 {
16591 if (arm_attr_public_tags[i].tag == tag)
16592 {
16593 attr = &arm_attr_public_tags[i];
16594 break;
16595 }
16596 }
16597
16598 if (attr)
16599 {
16600 printf (" Tag_%s: ", attr->name);
16601 switch (attr->type)
16602 {
16603 case 0:
16604 switch (tag)
16605 {
16606 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16607 READ_ULEB (val, p, end);
11c1ff18
PB
16608 switch (val)
16609 {
2b692964
NC
16610 case 0: printf (_("None\n")); break;
16611 case 'A': printf (_("Application\n")); break;
16612 case 'R': printf (_("Realtime\n")); break;
16613 case 'M': printf (_("Microcontroller\n")); break;
16614 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16615 default: printf ("??? (%d)\n", val); break;
16616 }
16617 break;
16618
75375b3e 16619 case 24: /* Tag_align_needed. */
cd30bcef 16620 READ_ULEB (val, p, end);
75375b3e
MGD
16621 switch (val)
16622 {
2b692964
NC
16623 case 0: printf (_("None\n")); break;
16624 case 1: printf (_("8-byte\n")); break;
16625 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16626 case 3: printf ("??? 3\n"); break;
16627 default:
16628 if (val <= 12)
dd24e3da 16629 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16630 1 << val);
16631 else
16632 printf ("??? (%d)\n", val);
16633 break;
16634 }
16635 break;
16636
16637 case 25: /* Tag_align_preserved. */
cd30bcef 16638 READ_ULEB (val, p, end);
75375b3e
MGD
16639 switch (val)
16640 {
2b692964
NC
16641 case 0: printf (_("None\n")); break;
16642 case 1: printf (_("8-byte, except leaf SP\n")); break;
16643 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16644 case 3: printf ("??? 3\n"); break;
16645 default:
16646 if (val <= 12)
dd24e3da 16647 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16648 1 << val);
16649 else
16650 printf ("??? (%d)\n", val);
16651 break;
16652 }
16653 break;
16654
11c1ff18 16655 case 32: /* Tag_compatibility. */
071436c6 16656 {
cd30bcef 16657 READ_ULEB (val, p, end);
071436c6 16658 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16659 if (p < end - 1)
16660 {
16661 size_t maxlen = (end - p) - 1;
16662
16663 print_symbol ((int) maxlen, (const char *) p);
16664 p += strnlen ((char *) p, maxlen) + 1;
16665 }
16666 else
16667 {
16668 printf (_("<corrupt>"));
16669 p = (unsigned char *) end;
16670 }
071436c6 16671 putchar ('\n');
071436c6 16672 }
11c1ff18
PB
16673 break;
16674
f5f53991 16675 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16676 /* PR 17531: file: 001-505008-0.01. */
16677 if (p < end)
16678 p++;
2b692964 16679 printf (_("True\n"));
f5f53991
AS
16680 break;
16681
16682 case 65: /* Tag_also_compatible_with. */
cd30bcef 16683 READ_ULEB (val, p, end);
f5f53991
AS
16684 if (val == 6 /* Tag_CPU_arch. */)
16685 {
cd30bcef 16686 READ_ULEB (val, p, end);
071436c6 16687 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16688 printf ("??? (%d)\n", val);
16689 else
16690 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16691 }
16692 else
16693 printf ("???\n");
071436c6
NC
16694 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16695 ;
f5f53991
AS
16696 break;
16697
11c1ff18 16698 default:
bee0ee85
NC
16699 printf (_("<unknown: %d>\n"), tag);
16700 break;
11c1ff18
PB
16701 }
16702 return p;
16703
16704 case 1:
f6f0e17b 16705 return display_tag_value (-1, p, end);
11c1ff18 16706 case 2:
f6f0e17b 16707 return display_tag_value (0, p, end);
11c1ff18
PB
16708
16709 default:
16710 assert (attr->type & 0x80);
cd30bcef 16711 READ_ULEB (val, p, end);
11c1ff18
PB
16712 type = attr->type & 0x7f;
16713 if (val >= type)
16714 printf ("??? (%d)\n", val);
16715 else
16716 printf ("%s\n", attr->table[val]);
16717 return p;
16718 }
16719 }
11c1ff18 16720
f6f0e17b 16721 return display_tag_value (tag, p, end);
11c1ff18
PB
16722}
16723
104d59d1 16724static unsigned char *
60bca95a 16725display_gnu_attribute (unsigned char * p,
60abdbed 16726 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16727 const unsigned char * const end)
104d59d1 16728{
cd30bcef 16729 unsigned int tag;
60abdbed 16730 unsigned int val;
104d59d1 16731
cd30bcef 16732 READ_ULEB (tag, p, end);
104d59d1
JM
16733
16734 /* Tag_compatibility is the only generic GNU attribute defined at
16735 present. */
16736 if (tag == 32)
16737 {
cd30bcef 16738 READ_ULEB (val, p, end);
071436c6
NC
16739
16740 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16741 if (p == end)
16742 {
071436c6 16743 printf (_("<corrupt>\n"));
f6f0e17b
NC
16744 warn (_("corrupt vendor attribute\n"));
16745 }
16746 else
16747 {
4082ef84
NC
16748 if (p < end - 1)
16749 {
16750 size_t maxlen = (end - p) - 1;
071436c6 16751
4082ef84
NC
16752 print_symbol ((int) maxlen, (const char *) p);
16753 p += strnlen ((char *) p, maxlen) + 1;
16754 }
16755 else
16756 {
16757 printf (_("<corrupt>"));
16758 p = (unsigned char *) end;
16759 }
071436c6 16760 putchar ('\n');
f6f0e17b 16761 }
104d59d1
JM
16762 return p;
16763 }
16764
16765 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16766 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16767
f6f0e17b 16768 return display_tag_value (tag, p, end);
104d59d1
JM
16769}
16770
85f7484a
PB
16771static unsigned char *
16772display_m68k_gnu_attribute (unsigned char * p,
16773 unsigned int tag,
16774 const unsigned char * const end)
16775{
16776 unsigned int val;
16777
16778 if (tag == Tag_GNU_M68K_ABI_FP)
16779 {
16780 printf (" Tag_GNU_M68K_ABI_FP: ");
16781 if (p == end)
16782 {
16783 printf (_("<corrupt>\n"));
16784 return p;
16785 }
16786 READ_ULEB (val, p, end);
16787
16788 if (val > 3)
16789 printf ("(%#x), ", val);
16790
16791 switch (val & 3)
16792 {
16793 case 0:
16794 printf (_("unspecified hard/soft float\n"));
16795 break;
16796 case 1:
16797 printf (_("hard float\n"));
16798 break;
16799 case 2:
16800 printf (_("soft float\n"));
16801 break;
16802 }
16803 return p;
16804 }
16805
16806 return display_tag_value (tag & 1, p, end);
16807}
16808
34c8bcba 16809static unsigned char *
f6f0e17b 16810display_power_gnu_attribute (unsigned char * p,
60abdbed 16811 unsigned int tag,
f6f0e17b 16812 const unsigned char * const end)
34c8bcba 16813{
005d79fd 16814 unsigned int val;
34c8bcba
JM
16815
16816 if (tag == Tag_GNU_Power_ABI_FP)
16817 {
34c8bcba 16818 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16819 if (p == end)
005d79fd
AM
16820 {
16821 printf (_("<corrupt>\n"));
16822 return p;
16823 }
cd30bcef 16824 READ_ULEB (val, p, end);
60bca95a 16825
005d79fd
AM
16826 if (val > 15)
16827 printf ("(%#x), ", val);
16828
16829 switch (val & 3)
34c8bcba
JM
16830 {
16831 case 0:
005d79fd 16832 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16833 break;
16834 case 1:
005d79fd 16835 printf (_("hard float, "));
34c8bcba
JM
16836 break;
16837 case 2:
005d79fd 16838 printf (_("soft float, "));
34c8bcba 16839 break;
3c7b9897 16840 case 3:
005d79fd 16841 printf (_("single-precision hard float, "));
3c7b9897 16842 break;
005d79fd
AM
16843 }
16844
16845 switch (val & 0xC)
16846 {
16847 case 0:
16848 printf (_("unspecified long double\n"));
16849 break;
16850 case 4:
16851 printf (_("128-bit IBM long double\n"));
16852 break;
16853 case 8:
16854 printf (_("64-bit long double\n"));
16855 break;
16856 case 12:
16857 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16858 break;
16859 }
16860 return p;
005d79fd 16861 }
34c8bcba 16862
c6e65352
DJ
16863 if (tag == Tag_GNU_Power_ABI_Vector)
16864 {
c6e65352 16865 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16866 if (p == end)
005d79fd
AM
16867 {
16868 printf (_("<corrupt>\n"));
16869 return p;
16870 }
cd30bcef 16871 READ_ULEB (val, p, end);
005d79fd
AM
16872
16873 if (val > 3)
16874 printf ("(%#x), ", val);
16875
16876 switch (val & 3)
c6e65352
DJ
16877 {
16878 case 0:
005d79fd 16879 printf (_("unspecified\n"));
c6e65352
DJ
16880 break;
16881 case 1:
005d79fd 16882 printf (_("generic\n"));
c6e65352
DJ
16883 break;
16884 case 2:
16885 printf ("AltiVec\n");
16886 break;
16887 case 3:
16888 printf ("SPE\n");
16889 break;
c6e65352
DJ
16890 }
16891 return p;
005d79fd 16892 }
c6e65352 16893
f82e0623
NF
16894 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16895 {
005d79fd 16896 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16897 if (p == end)
f6f0e17b 16898 {
005d79fd 16899 printf (_("<corrupt>\n"));
f6f0e17b
NC
16900 return p;
16901 }
cd30bcef 16902 READ_ULEB (val, p, end);
0b4362b0 16903
005d79fd
AM
16904 if (val > 2)
16905 printf ("(%#x), ", val);
16906
16907 switch (val & 3)
16908 {
16909 case 0:
16910 printf (_("unspecified\n"));
16911 break;
16912 case 1:
16913 printf ("r3/r4\n");
16914 break;
16915 case 2:
16916 printf (_("memory\n"));
16917 break;
16918 case 3:
16919 printf ("???\n");
16920 break;
16921 }
f82e0623
NF
16922 return p;
16923 }
16924
f6f0e17b 16925 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16926}
16927
643f7afb
AK
16928static unsigned char *
16929display_s390_gnu_attribute (unsigned char * p,
60abdbed 16930 unsigned int tag,
643f7afb
AK
16931 const unsigned char * const end)
16932{
cd30bcef 16933 unsigned int val;
643f7afb
AK
16934
16935 if (tag == Tag_GNU_S390_ABI_Vector)
16936 {
643f7afb 16937 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16938 READ_ULEB (val, p, end);
643f7afb
AK
16939
16940 switch (val)
16941 {
16942 case 0:
16943 printf (_("any\n"));
16944 break;
16945 case 1:
16946 printf (_("software\n"));
16947 break;
16948 case 2:
16949 printf (_("hardware\n"));
16950 break;
16951 default:
16952 printf ("??? (%d)\n", val);
16953 break;
16954 }
16955 return p;
16956 }
16957
16958 return display_tag_value (tag & 1, p, end);
16959}
16960
9e8c70f9 16961static void
60abdbed 16962display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16963{
16964 if (mask)
16965 {
015dc7e1 16966 bool first = true;
071436c6 16967
9e8c70f9 16968 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16969 fputs ("mul32", stdout), first = false;
9e8c70f9 16970 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16971 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16972 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16973 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16974 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16975 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16976 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16977 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16978 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16979 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16980 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16981 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16982 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16983 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16984 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16985 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16986 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16987 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16988 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16989 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16990 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16991 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16992 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16993 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16994 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16995 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16996 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16997 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16998 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16999 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17000 }
17001 else
071436c6
NC
17002 fputc ('0', stdout);
17003 fputc ('\n', stdout);
9e8c70f9
DM
17004}
17005
3d68f91c 17006static void
60abdbed 17007display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17008{
17009 if (mask)
17010 {
015dc7e1 17011 bool first = true;
071436c6 17012
3d68f91c 17013 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17014 fputs ("fjathplus", stdout), first = false;
3d68f91c 17015 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17016 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17017 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17018 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17019 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17020 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17021 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17022 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17023 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17024 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17025 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17026 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17027 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17028 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17029 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17030 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17031 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17032 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17033 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17034 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17035 }
17036 else
071436c6
NC
17037 fputc ('0', stdout);
17038 fputc ('\n', stdout);
3d68f91c
JM
17039}
17040
9e8c70f9 17041static unsigned char *
f6f0e17b 17042display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17043 unsigned int tag,
f6f0e17b 17044 const unsigned char * const end)
9e8c70f9 17045{
cd30bcef 17046 unsigned int val;
3d68f91c 17047
9e8c70f9
DM
17048 if (tag == Tag_GNU_Sparc_HWCAPS)
17049 {
cd30bcef 17050 READ_ULEB (val, p, end);
9e8c70f9 17051 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17052 display_sparc_hwcaps (val);
17053 return p;
3d68f91c
JM
17054 }
17055 if (tag == Tag_GNU_Sparc_HWCAPS2)
17056 {
cd30bcef 17057 READ_ULEB (val, p, end);
3d68f91c
JM
17058 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17059 display_sparc_hwcaps2 (val);
17060 return p;
17061 }
9e8c70f9 17062
f6f0e17b 17063 return display_tag_value (tag, p, end);
9e8c70f9
DM
17064}
17065
351cdf24 17066static void
32ec8896 17067print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17068{
17069 switch (val)
17070 {
17071 case Val_GNU_MIPS_ABI_FP_ANY:
17072 printf (_("Hard or soft float\n"));
17073 break;
17074 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17075 printf (_("Hard float (double precision)\n"));
17076 break;
17077 case Val_GNU_MIPS_ABI_FP_SINGLE:
17078 printf (_("Hard float (single precision)\n"));
17079 break;
17080 case Val_GNU_MIPS_ABI_FP_SOFT:
17081 printf (_("Soft float\n"));
17082 break;
17083 case Val_GNU_MIPS_ABI_FP_OLD_64:
17084 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17085 break;
17086 case Val_GNU_MIPS_ABI_FP_XX:
17087 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17088 break;
17089 case Val_GNU_MIPS_ABI_FP_64:
17090 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17091 break;
17092 case Val_GNU_MIPS_ABI_FP_64A:
17093 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17094 break;
3350cc01
CM
17095 case Val_GNU_MIPS_ABI_FP_NAN2008:
17096 printf (_("NaN 2008 compatibility\n"));
17097 break;
351cdf24
MF
17098 default:
17099 printf ("??? (%d)\n", val);
17100 break;
17101 }
17102}
17103
2cf19d5c 17104static unsigned char *
f6f0e17b 17105display_mips_gnu_attribute (unsigned char * p,
60abdbed 17106 unsigned int tag,
f6f0e17b 17107 const unsigned char * const end)
2cf19d5c 17108{
2cf19d5c
JM
17109 if (tag == Tag_GNU_MIPS_ABI_FP)
17110 {
32ec8896 17111 unsigned int val;
f6f0e17b 17112
2cf19d5c 17113 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17114 READ_ULEB (val, p, end);
351cdf24 17115 print_mips_fp_abi_value (val);
2cf19d5c
JM
17116 return p;
17117 }
17118
a9f58168
CF
17119 if (tag == Tag_GNU_MIPS_ABI_MSA)
17120 {
32ec8896 17121 unsigned int val;
a9f58168 17122
a9f58168 17123 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17124 READ_ULEB (val, p, end);
a9f58168
CF
17125
17126 switch (val)
17127 {
17128 case Val_GNU_MIPS_ABI_MSA_ANY:
17129 printf (_("Any MSA or not\n"));
17130 break;
17131 case Val_GNU_MIPS_ABI_MSA_128:
17132 printf (_("128-bit MSA\n"));
17133 break;
17134 default:
17135 printf ("??? (%d)\n", val);
17136 break;
17137 }
17138 return p;
17139 }
17140
f6f0e17b 17141 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17142}
17143
59e6276b 17144static unsigned char *
f6f0e17b
NC
17145display_tic6x_attribute (unsigned char * p,
17146 const unsigned char * const end)
59e6276b 17147{
60abdbed 17148 unsigned int tag;
cd30bcef 17149 unsigned int val;
59e6276b 17150
cd30bcef 17151 READ_ULEB (tag, p, end);
59e6276b
JM
17152
17153 switch (tag)
17154 {
75fa6dc1 17155 case Tag_ISA:
75fa6dc1 17156 printf (" Tag_ISA: ");
cd30bcef 17157 READ_ULEB (val, p, end);
59e6276b
JM
17158
17159 switch (val)
17160 {
75fa6dc1 17161 case C6XABI_Tag_ISA_none:
59e6276b
JM
17162 printf (_("None\n"));
17163 break;
75fa6dc1 17164 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17165 printf ("C62x\n");
17166 break;
75fa6dc1 17167 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17168 printf ("C67x\n");
17169 break;
75fa6dc1 17170 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17171 printf ("C67x+\n");
17172 break;
75fa6dc1 17173 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17174 printf ("C64x\n");
17175 break;
75fa6dc1 17176 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17177 printf ("C64x+\n");
17178 break;
75fa6dc1 17179 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17180 printf ("C674x\n");
17181 break;
17182 default:
17183 printf ("??? (%d)\n", val);
17184 break;
17185 }
17186 return p;
17187
87779176 17188 case Tag_ABI_wchar_t:
87779176 17189 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17190 READ_ULEB (val, p, end);
87779176
JM
17191 switch (val)
17192 {
17193 case 0:
17194 printf (_("Not used\n"));
17195 break;
17196 case 1:
17197 printf (_("2 bytes\n"));
17198 break;
17199 case 2:
17200 printf (_("4 bytes\n"));
17201 break;
17202 default:
17203 printf ("??? (%d)\n", val);
17204 break;
17205 }
17206 return p;
17207
17208 case Tag_ABI_stack_align_needed:
87779176 17209 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17210 READ_ULEB (val, p, end);
87779176
JM
17211 switch (val)
17212 {
17213 case 0:
17214 printf (_("8-byte\n"));
17215 break;
17216 case 1:
17217 printf (_("16-byte\n"));
17218 break;
17219 default:
17220 printf ("??? (%d)\n", val);
17221 break;
17222 }
17223 return p;
17224
17225 case Tag_ABI_stack_align_preserved:
cd30bcef 17226 READ_ULEB (val, p, end);
87779176
JM
17227 printf (" Tag_ABI_stack_align_preserved: ");
17228 switch (val)
17229 {
17230 case 0:
17231 printf (_("8-byte\n"));
17232 break;
17233 case 1:
17234 printf (_("16-byte\n"));
17235 break;
17236 default:
17237 printf ("??? (%d)\n", val);
17238 break;
17239 }
17240 return p;
17241
b5593623 17242 case Tag_ABI_DSBT:
cd30bcef 17243 READ_ULEB (val, p, end);
b5593623
JM
17244 printf (" Tag_ABI_DSBT: ");
17245 switch (val)
17246 {
17247 case 0:
17248 printf (_("DSBT addressing not used\n"));
17249 break;
17250 case 1:
17251 printf (_("DSBT addressing used\n"));
17252 break;
17253 default:
17254 printf ("??? (%d)\n", val);
17255 break;
17256 }
17257 return p;
17258
87779176 17259 case Tag_ABI_PID:
cd30bcef 17260 READ_ULEB (val, p, end);
87779176
JM
17261 printf (" Tag_ABI_PID: ");
17262 switch (val)
17263 {
17264 case 0:
17265 printf (_("Data addressing position-dependent\n"));
17266 break;
17267 case 1:
17268 printf (_("Data addressing position-independent, GOT near DP\n"));
17269 break;
17270 case 2:
17271 printf (_("Data addressing position-independent, GOT far from DP\n"));
17272 break;
17273 default:
17274 printf ("??? (%d)\n", val);
17275 break;
17276 }
17277 return p;
17278
17279 case Tag_ABI_PIC:
cd30bcef 17280 READ_ULEB (val, p, end);
87779176
JM
17281 printf (" Tag_ABI_PIC: ");
17282 switch (val)
17283 {
17284 case 0:
17285 printf (_("Code addressing position-dependent\n"));
17286 break;
17287 case 1:
17288 printf (_("Code addressing position-independent\n"));
17289 break;
17290 default:
17291 printf ("??? (%d)\n", val);
17292 break;
17293 }
17294 return p;
17295
17296 case Tag_ABI_array_object_alignment:
cd30bcef 17297 READ_ULEB (val, p, end);
87779176
JM
17298 printf (" Tag_ABI_array_object_alignment: ");
17299 switch (val)
17300 {
17301 case 0:
17302 printf (_("8-byte\n"));
17303 break;
17304 case 1:
17305 printf (_("4-byte\n"));
17306 break;
17307 case 2:
17308 printf (_("16-byte\n"));
17309 break;
17310 default:
17311 printf ("??? (%d)\n", val);
17312 break;
17313 }
17314 return p;
17315
17316 case Tag_ABI_array_object_align_expected:
cd30bcef 17317 READ_ULEB (val, p, end);
87779176
JM
17318 printf (" Tag_ABI_array_object_align_expected: ");
17319 switch (val)
17320 {
17321 case 0:
17322 printf (_("8-byte\n"));
17323 break;
17324 case 1:
17325 printf (_("4-byte\n"));
17326 break;
17327 case 2:
17328 printf (_("16-byte\n"));
17329 break;
17330 default:
17331 printf ("??? (%d)\n", val);
17332 break;
17333 }
17334 return p;
17335
3cbd1c06 17336 case Tag_ABI_compatibility:
071436c6 17337 {
cd30bcef 17338 READ_ULEB (val, p, end);
071436c6 17339 printf (" Tag_ABI_compatibility: ");
071436c6 17340 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17341 if (p < end - 1)
17342 {
17343 size_t maxlen = (end - p) - 1;
17344
17345 print_symbol ((int) maxlen, (const char *) p);
17346 p += strnlen ((char *) p, maxlen) + 1;
17347 }
17348 else
17349 {
17350 printf (_("<corrupt>"));
17351 p = (unsigned char *) end;
17352 }
071436c6 17353 putchar ('\n');
071436c6
NC
17354 return p;
17355 }
87779176
JM
17356
17357 case Tag_ABI_conformance:
071436c6 17358 {
4082ef84
NC
17359 printf (" Tag_ABI_conformance: \"");
17360 if (p < end - 1)
17361 {
17362 size_t maxlen = (end - p) - 1;
071436c6 17363
4082ef84
NC
17364 print_symbol ((int) maxlen, (const char *) p);
17365 p += strnlen ((char *) p, maxlen) + 1;
17366 }
17367 else
17368 {
17369 printf (_("<corrupt>"));
17370 p = (unsigned char *) end;
17371 }
071436c6 17372 printf ("\"\n");
071436c6
NC
17373 return p;
17374 }
59e6276b
JM
17375 }
17376
f6f0e17b
NC
17377 return display_tag_value (tag, p, end);
17378}
59e6276b 17379
f6f0e17b 17380static void
60abdbed 17381display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17382{
17383 unsigned long addr = 0;
17384 size_t bytes = end - p;
17385
feceaa59 17386 assert (end >= p);
f6f0e17b 17387 while (bytes)
87779176 17388 {
f6f0e17b
NC
17389 int j;
17390 int k;
17391 int lbytes = (bytes > 16 ? 16 : bytes);
17392
17393 printf (" 0x%8.8lx ", addr);
17394
17395 for (j = 0; j < 16; j++)
17396 {
17397 if (j < lbytes)
17398 printf ("%2.2x", p[j]);
17399 else
17400 printf (" ");
17401
17402 if ((j & 3) == 3)
17403 printf (" ");
17404 }
17405
17406 for (j = 0; j < lbytes; j++)
17407 {
17408 k = p[j];
17409 if (k >= ' ' && k < 0x7f)
17410 printf ("%c", k);
17411 else
17412 printf (".");
17413 }
17414
17415 putchar ('\n');
17416
17417 p += lbytes;
17418 bytes -= lbytes;
17419 addr += lbytes;
87779176 17420 }
59e6276b 17421
f6f0e17b 17422 putchar ('\n');
59e6276b
JM
17423}
17424
13761a11 17425static unsigned char *
b0191216 17426display_msp430_attribute (unsigned char * p,
13761a11
NC
17427 const unsigned char * const end)
17428{
60abdbed
NC
17429 unsigned int val;
17430 unsigned int tag;
13761a11 17431
cd30bcef 17432 READ_ULEB (tag, p, end);
0b4362b0 17433
13761a11
NC
17434 switch (tag)
17435 {
17436 case OFBA_MSPABI_Tag_ISA:
13761a11 17437 printf (" Tag_ISA: ");
cd30bcef 17438 READ_ULEB (val, p, end);
13761a11
NC
17439 switch (val)
17440 {
17441 case 0: printf (_("None\n")); break;
17442 case 1: printf (_("MSP430\n")); break;
17443 case 2: printf (_("MSP430X\n")); break;
17444 default: printf ("??? (%d)\n", val); break;
17445 }
17446 break;
17447
17448 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17449 printf (" Tag_Code_Model: ");
cd30bcef 17450 READ_ULEB (val, p, end);
13761a11
NC
17451 switch (val)
17452 {
17453 case 0: printf (_("None\n")); break;
17454 case 1: printf (_("Small\n")); break;
17455 case 2: printf (_("Large\n")); break;
17456 default: printf ("??? (%d)\n", val); break;
17457 }
17458 break;
17459
17460 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17461 printf (" Tag_Data_Model: ");
cd30bcef 17462 READ_ULEB (val, p, end);
13761a11
NC
17463 switch (val)
17464 {
17465 case 0: printf (_("None\n")); break;
17466 case 1: printf (_("Small\n")); break;
17467 case 2: printf (_("Large\n")); break;
17468 case 3: printf (_("Restricted Large\n")); break;
17469 default: printf ("??? (%d)\n", val); break;
17470 }
17471 break;
17472
17473 default:
17474 printf (_(" <unknown tag %d>: "), tag);
17475
17476 if (tag & 1)
17477 {
071436c6 17478 putchar ('"');
4082ef84
NC
17479 if (p < end - 1)
17480 {
17481 size_t maxlen = (end - p) - 1;
17482
17483 print_symbol ((int) maxlen, (const char *) p);
17484 p += strnlen ((char *) p, maxlen) + 1;
17485 }
17486 else
17487 {
17488 printf (_("<corrupt>"));
17489 p = (unsigned char *) end;
17490 }
071436c6 17491 printf ("\"\n");
13761a11
NC
17492 }
17493 else
17494 {
cd30bcef 17495 READ_ULEB (val, p, end);
13761a11
NC
17496 printf ("%d (0x%x)\n", val, val);
17497 }
17498 break;
17499 }
17500
4082ef84 17501 assert (p <= end);
13761a11
NC
17502 return p;
17503}
17504
c0ea7c52
JL
17505static unsigned char *
17506display_msp430_gnu_attribute (unsigned char * p,
17507 unsigned int tag,
17508 const unsigned char * const end)
17509{
17510 if (tag == Tag_GNU_MSP430_Data_Region)
17511 {
cd30bcef 17512 unsigned int val;
c0ea7c52 17513
c0ea7c52 17514 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17515 READ_ULEB (val, p, end);
c0ea7c52
JL
17516
17517 switch (val)
17518 {
17519 case Val_GNU_MSP430_Data_Region_Any:
17520 printf (_("Any Region\n"));
17521 break;
17522 case Val_GNU_MSP430_Data_Region_Lower:
17523 printf (_("Lower Region Only\n"));
17524 break;
17525 default:
cd30bcef 17526 printf ("??? (%u)\n", val);
c0ea7c52
JL
17527 }
17528 return p;
17529 }
17530 return display_tag_value (tag & 1, p, end);
17531}
17532
2dc8dd17
JW
17533struct riscv_attr_tag_t {
17534 const char *name;
cd30bcef 17535 unsigned int tag;
2dc8dd17
JW
17536};
17537
17538static struct riscv_attr_tag_t riscv_attr_tag[] =
17539{
17540#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17541 T(arch),
17542 T(priv_spec),
17543 T(priv_spec_minor),
17544 T(priv_spec_revision),
17545 T(unaligned_access),
17546 T(stack_align),
17547#undef T
17548};
17549
17550static unsigned char *
17551display_riscv_attribute (unsigned char *p,
17552 const unsigned char * const end)
17553{
cd30bcef
AM
17554 unsigned int val;
17555 unsigned int tag;
2dc8dd17
JW
17556 struct riscv_attr_tag_t *attr = NULL;
17557 unsigned i;
17558
cd30bcef 17559 READ_ULEB (tag, p, end);
2dc8dd17
JW
17560
17561 /* Find the name of attribute. */
17562 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17563 {
17564 if (riscv_attr_tag[i].tag == tag)
17565 {
17566 attr = &riscv_attr_tag[i];
17567 break;
17568 }
17569 }
17570
17571 if (attr)
17572 printf (" %s: ", attr->name);
17573 else
17574 return display_tag_value (tag, p, end);
17575
17576 switch (tag)
17577 {
17578 case Tag_RISCV_priv_spec:
17579 case Tag_RISCV_priv_spec_minor:
17580 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17581 READ_ULEB (val, p, end);
17582 printf (_("%u\n"), val);
2dc8dd17
JW
17583 break;
17584 case Tag_RISCV_unaligned_access:
cd30bcef 17585 READ_ULEB (val, p, end);
2dc8dd17
JW
17586 switch (val)
17587 {
17588 case 0:
17589 printf (_("No unaligned access\n"));
17590 break;
17591 case 1:
17592 printf (_("Unaligned access\n"));
17593 break;
17594 }
17595 break;
17596 case Tag_RISCV_stack_align:
cd30bcef
AM
17597 READ_ULEB (val, p, end);
17598 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17599 break;
17600 case Tag_RISCV_arch:
17601 p = display_tag_value (-1, p, end);
17602 break;
17603 default:
17604 return display_tag_value (tag, p, end);
17605 }
17606
17607 return p;
17608}
17609
0861f561
CQ
17610static unsigned char *
17611display_csky_attribute (unsigned char * p,
17612 const unsigned char * const end)
17613{
17614 unsigned int tag;
17615 unsigned int val;
17616 READ_ULEB (tag, p, end);
17617
17618 if (tag >= Tag_CSKY_MAX)
17619 {
17620 return display_tag_value (-1, p, end);
17621 }
17622
17623 switch (tag)
17624 {
17625 case Tag_CSKY_ARCH_NAME:
17626 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17627 return display_tag_value (-1, p, end);
17628 case Tag_CSKY_CPU_NAME:
17629 printf (" Tag_CSKY_CPU_NAME:\t\t");
17630 return display_tag_value (-1, p, end);
17631
17632 case Tag_CSKY_ISA_FLAGS:
17633 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17634 return display_tag_value (0, p, end);
17635 case Tag_CSKY_ISA_EXT_FLAGS:
17636 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17637 return display_tag_value (0, p, end);
17638
17639 case Tag_CSKY_DSP_VERSION:
17640 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17641 READ_ULEB (val, p, end);
17642 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17643 printf ("DSP Extension\n");
17644 else if (val == VAL_CSKY_DSP_VERSION_2)
17645 printf ("DSP 2.0\n");
17646 break;
17647
17648 case Tag_CSKY_VDSP_VERSION:
17649 printf (" Tag_CSKY_VDSP_VERSION:\t");
17650 READ_ULEB (val, p, end);
17651 printf ("VDSP Version %d\n", val);
17652 break;
17653
17654 case Tag_CSKY_FPU_VERSION:
17655 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17656 READ_ULEB (val, p, end);
17657 if (val == VAL_CSKY_FPU_VERSION_1)
17658 printf ("ABIV1 FPU Version 1\n");
17659 else if (val == VAL_CSKY_FPU_VERSION_2)
17660 printf ("FPU Version 2\n");
17661 break;
17662
17663 case Tag_CSKY_FPU_ABI:
17664 printf (" Tag_CSKY_FPU_ABI:\t\t");
17665 READ_ULEB (val, p, end);
17666 if (val == VAL_CSKY_FPU_ABI_HARD)
17667 printf ("Hard\n");
17668 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17669 printf ("SoftFP\n");
17670 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17671 printf ("Soft\n");
17672 break;
17673 case Tag_CSKY_FPU_ROUNDING:
17674 READ_ULEB (val, p, end);
f253158f
NC
17675 if (val == 1)
17676 {
17677 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17678 printf ("Needed\n");
17679 }
0861f561
CQ
17680 break;
17681 case Tag_CSKY_FPU_DENORMAL:
17682 READ_ULEB (val, p, end);
f253158f
NC
17683 if (val == 1)
17684 {
17685 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17686 printf ("Needed\n");
17687 }
0861f561
CQ
17688 break;
17689 case Tag_CSKY_FPU_Exception:
17690 READ_ULEB (val, p, end);
f253158f
NC
17691 if (val == 1)
17692 {
17693 printf (" Tag_CSKY_FPU_Exception:\t");
17694 printf ("Needed\n");
17695 }
0861f561
CQ
17696 break;
17697 case Tag_CSKY_FPU_NUMBER_MODULE:
17698 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17699 return display_tag_value (-1, p, end);
17700 case Tag_CSKY_FPU_HARDFP:
17701 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17702 READ_ULEB (val, p, end);
17703 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17704 printf (" Half");
17705 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17706 printf (" Single");
17707 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17708 printf (" Double");
17709 printf ("\n");
17710 break;
17711 default:
17712 return display_tag_value (tag, p, end);
17713 }
17714 return p;
17715}
17716
015dc7e1 17717static bool
dda8d76d 17718process_attributes (Filedata * filedata,
60bca95a 17719 const char * public_name,
104d59d1 17720 unsigned int proc_type,
f6f0e17b 17721 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17722 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17723{
2cf0635d 17724 Elf_Internal_Shdr * sect;
11c1ff18 17725 unsigned i;
015dc7e1 17726 bool res = true;
11c1ff18
PB
17727
17728 /* Find the section header so that we get the size. */
dda8d76d
NC
17729 for (i = 0, sect = filedata->section_headers;
17730 i < filedata->file_header.e_shnum;
11c1ff18
PB
17731 i++, sect++)
17732 {
071436c6
NC
17733 unsigned char * contents;
17734 unsigned char * p;
17735
104d59d1 17736 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17737 continue;
17738
dda8d76d 17739 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17740 sect->sh_size, _("attributes"));
60bca95a 17741 if (contents == NULL)
32ec8896 17742 {
015dc7e1 17743 res = false;
32ec8896
NC
17744 continue;
17745 }
60bca95a 17746
11c1ff18 17747 p = contents;
60abdbed
NC
17748 /* The first character is the version of the attributes.
17749 Currently only version 1, (aka 'A') is recognised here. */
17750 if (*p != 'A')
32ec8896
NC
17751 {
17752 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17753 res = false;
32ec8896 17754 }
60abdbed 17755 else
11c1ff18 17756 {
071436c6
NC
17757 bfd_vma section_len;
17758
17759 section_len = sect->sh_size - 1;
11c1ff18 17760 p++;
60bca95a 17761
071436c6 17762 while (section_len > 0)
11c1ff18 17763 {
071436c6 17764 bfd_vma attr_len;
e9847026 17765 unsigned int namelen;
015dc7e1
AM
17766 bool public_section;
17767 bool gnu_section;
11c1ff18 17768
071436c6 17769 if (section_len <= 4)
e0a31db1
NC
17770 {
17771 error (_("Tag section ends prematurely\n"));
015dc7e1 17772 res = false;
e0a31db1
NC
17773 break;
17774 }
071436c6 17775 attr_len = byte_get (p, 4);
11c1ff18 17776 p += 4;
60bca95a 17777
071436c6 17778 if (attr_len > section_len)
11c1ff18 17779 {
071436c6
NC
17780 error (_("Bad attribute length (%u > %u)\n"),
17781 (unsigned) attr_len, (unsigned) section_len);
17782 attr_len = section_len;
015dc7e1 17783 res = false;
11c1ff18 17784 }
74e1a04b 17785 /* PR 17531: file: 001-101425-0.004 */
071436c6 17786 else if (attr_len < 5)
74e1a04b 17787 {
071436c6 17788 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17789 res = false;
74e1a04b
NC
17790 break;
17791 }
e9847026 17792
071436c6
NC
17793 section_len -= attr_len;
17794 attr_len -= 4;
17795
17796 namelen = strnlen ((char *) p, attr_len) + 1;
17797 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17798 {
17799 error (_("Corrupt attribute section name\n"));
015dc7e1 17800 res = false;
e9847026
NC
17801 break;
17802 }
17803
071436c6
NC
17804 printf (_("Attribute Section: "));
17805 print_symbol (INT_MAX, (const char *) p);
17806 putchar ('\n');
60bca95a
NC
17807
17808 if (public_name && streq ((char *) p, public_name))
015dc7e1 17809 public_section = true;
11c1ff18 17810 else
015dc7e1 17811 public_section = false;
60bca95a
NC
17812
17813 if (streq ((char *) p, "gnu"))
015dc7e1 17814 gnu_section = true;
104d59d1 17815 else
015dc7e1 17816 gnu_section = false;
60bca95a 17817
11c1ff18 17818 p += namelen;
071436c6 17819 attr_len -= namelen;
e0a31db1 17820
071436c6 17821 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17822 {
e0a31db1 17823 int tag;
cd30bcef 17824 unsigned int val;
11c1ff18 17825 bfd_vma size;
071436c6 17826 unsigned char * end;
60bca95a 17827
e0a31db1 17828 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17829 if (attr_len < 6)
e0a31db1
NC
17830 {
17831 error (_("Unused bytes at end of section\n"));
015dc7e1 17832 res = false;
e0a31db1
NC
17833 section_len = 0;
17834 break;
17835 }
17836
17837 tag = *(p++);
11c1ff18 17838 size = byte_get (p, 4);
071436c6 17839 if (size > attr_len)
11c1ff18 17840 {
e9847026 17841 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17842 (unsigned) size, (unsigned) attr_len);
015dc7e1 17843 res = false;
071436c6 17844 size = attr_len;
11c1ff18 17845 }
e0a31db1
NC
17846 /* PR binutils/17531: Safe handling of corrupt files. */
17847 if (size < 6)
17848 {
17849 error (_("Bad subsection length (%u < 6)\n"),
17850 (unsigned) size);
015dc7e1 17851 res = false;
e0a31db1
NC
17852 section_len = 0;
17853 break;
17854 }
60bca95a 17855
071436c6 17856 attr_len -= size;
11c1ff18 17857 end = p + size - 1;
071436c6 17858 assert (end <= contents + sect->sh_size);
11c1ff18 17859 p += 4;
60bca95a 17860
11c1ff18
PB
17861 switch (tag)
17862 {
17863 case 1:
2b692964 17864 printf (_("File Attributes\n"));
11c1ff18
PB
17865 break;
17866 case 2:
2b692964 17867 printf (_("Section Attributes:"));
11c1ff18
PB
17868 goto do_numlist;
17869 case 3:
2b692964 17870 printf (_("Symbol Attributes:"));
1a0670f3 17871 /* Fall through. */
11c1ff18
PB
17872 do_numlist:
17873 for (;;)
17874 {
cd30bcef 17875 READ_ULEB (val, p, end);
11c1ff18
PB
17876 if (val == 0)
17877 break;
17878 printf (" %d", val);
17879 }
17880 printf ("\n");
17881 break;
17882 default:
2b692964 17883 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17884 public_section = false;
11c1ff18
PB
17885 break;
17886 }
60bca95a 17887
071436c6 17888 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17889 {
17890 while (p < end)
f6f0e17b 17891 p = display_pub_attribute (p, end);
60abdbed 17892 assert (p == end);
104d59d1 17893 }
071436c6 17894 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17895 {
17896 while (p < end)
17897 p = display_gnu_attribute (p,
f6f0e17b
NC
17898 display_proc_gnu_attribute,
17899 end);
60abdbed 17900 assert (p == end);
11c1ff18 17901 }
071436c6 17902 else if (p < end)
11c1ff18 17903 {
071436c6 17904 printf (_(" Unknown attribute:\n"));
f6f0e17b 17905 display_raw_attribute (p, end);
11c1ff18
PB
17906 p = end;
17907 }
071436c6
NC
17908 else
17909 attr_len = 0;
11c1ff18
PB
17910 }
17911 }
17912 }
d70c5fc7 17913
60bca95a 17914 free (contents);
11c1ff18 17915 }
32ec8896
NC
17916
17917 return res;
11c1ff18
PB
17918}
17919
ccb4c951
RS
17920/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17921 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17922 and return the VMA of the next entry, or -1 if there was a problem.
17923 Does not read from DATA_END or beyond. */
ccb4c951
RS
17924
17925static bfd_vma
82b1b41b
NC
17926print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17927 unsigned char * data_end)
ccb4c951
RS
17928{
17929 printf (" ");
17930 print_vma (addr, LONG_HEX);
17931 printf (" ");
17932 if (addr < pltgot + 0xfff0)
17933 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17934 else
17935 printf ("%10s", "");
17936 printf (" ");
17937 if (data == NULL)
2b692964 17938 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17939 else
17940 {
17941 bfd_vma entry;
82b1b41b 17942 unsigned char * from = data + addr - pltgot;
ccb4c951 17943
82b1b41b
NC
17944 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17945 {
17946 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17947 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17948 return (bfd_vma) -1;
17949 }
17950 else
17951 {
17952 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17953 print_vma (entry, LONG_HEX);
17954 }
ccb4c951
RS
17955 }
17956 return addr + (is_32bit_elf ? 4 : 8);
17957}
17958
861fb55a
DJ
17959/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17960 PLTGOT. Print the Address and Initial fields of an entry at VMA
17961 ADDR and return the VMA of the next entry. */
17962
17963static bfd_vma
2cf0635d 17964print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17965{
17966 printf (" ");
17967 print_vma (addr, LONG_HEX);
17968 printf (" ");
17969 if (data == NULL)
2b692964 17970 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17971 else
17972 {
17973 bfd_vma entry;
17974
17975 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17976 print_vma (entry, LONG_HEX);
17977 }
17978 return addr + (is_32bit_elf ? 4 : 8);
17979}
17980
351cdf24
MF
17981static void
17982print_mips_ases (unsigned int mask)
17983{
17984 if (mask & AFL_ASE_DSP)
17985 fputs ("\n\tDSP ASE", stdout);
17986 if (mask & AFL_ASE_DSPR2)
17987 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17988 if (mask & AFL_ASE_DSPR3)
17989 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17990 if (mask & AFL_ASE_EVA)
17991 fputs ("\n\tEnhanced VA Scheme", stdout);
17992 if (mask & AFL_ASE_MCU)
17993 fputs ("\n\tMCU (MicroController) ASE", stdout);
17994 if (mask & AFL_ASE_MDMX)
17995 fputs ("\n\tMDMX ASE", stdout);
17996 if (mask & AFL_ASE_MIPS3D)
17997 fputs ("\n\tMIPS-3D ASE", stdout);
17998 if (mask & AFL_ASE_MT)
17999 fputs ("\n\tMT ASE", stdout);
18000 if (mask & AFL_ASE_SMARTMIPS)
18001 fputs ("\n\tSmartMIPS ASE", stdout);
18002 if (mask & AFL_ASE_VIRT)
18003 fputs ("\n\tVZ ASE", stdout);
18004 if (mask & AFL_ASE_MSA)
18005 fputs ("\n\tMSA ASE", stdout);
18006 if (mask & AFL_ASE_MIPS16)
18007 fputs ("\n\tMIPS16 ASE", stdout);
18008 if (mask & AFL_ASE_MICROMIPS)
18009 fputs ("\n\tMICROMIPS ASE", stdout);
18010 if (mask & AFL_ASE_XPA)
18011 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18012 if (mask & AFL_ASE_MIPS16E2)
18013 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18014 if (mask & AFL_ASE_CRC)
18015 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18016 if (mask & AFL_ASE_GINV)
18017 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18018 if (mask & AFL_ASE_LOONGSON_MMI)
18019 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18020 if (mask & AFL_ASE_LOONGSON_CAM)
18021 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18022 if (mask & AFL_ASE_LOONGSON_EXT)
18023 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18024 if (mask & AFL_ASE_LOONGSON_EXT2)
18025 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18026 if (mask == 0)
18027 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18028 else if ((mask & ~AFL_ASE_MASK) != 0)
18029 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18030}
18031
18032static void
18033print_mips_isa_ext (unsigned int isa_ext)
18034{
18035 switch (isa_ext)
18036 {
18037 case 0:
18038 fputs (_("None"), stdout);
18039 break;
18040 case AFL_EXT_XLR:
18041 fputs ("RMI XLR", stdout);
18042 break;
2c629856
N
18043 case AFL_EXT_OCTEON3:
18044 fputs ("Cavium Networks Octeon3", stdout);
18045 break;
351cdf24
MF
18046 case AFL_EXT_OCTEON2:
18047 fputs ("Cavium Networks Octeon2", stdout);
18048 break;
18049 case AFL_EXT_OCTEONP:
18050 fputs ("Cavium Networks OcteonP", stdout);
18051 break;
351cdf24
MF
18052 case AFL_EXT_OCTEON:
18053 fputs ("Cavium Networks Octeon", stdout);
18054 break;
18055 case AFL_EXT_5900:
18056 fputs ("Toshiba R5900", stdout);
18057 break;
18058 case AFL_EXT_4650:
18059 fputs ("MIPS R4650", stdout);
18060 break;
18061 case AFL_EXT_4010:
18062 fputs ("LSI R4010", stdout);
18063 break;
18064 case AFL_EXT_4100:
18065 fputs ("NEC VR4100", stdout);
18066 break;
18067 case AFL_EXT_3900:
18068 fputs ("Toshiba R3900", stdout);
18069 break;
18070 case AFL_EXT_10000:
18071 fputs ("MIPS R10000", stdout);
18072 break;
18073 case AFL_EXT_SB1:
18074 fputs ("Broadcom SB-1", stdout);
18075 break;
18076 case AFL_EXT_4111:
18077 fputs ("NEC VR4111/VR4181", stdout);
18078 break;
18079 case AFL_EXT_4120:
18080 fputs ("NEC VR4120", stdout);
18081 break;
18082 case AFL_EXT_5400:
18083 fputs ("NEC VR5400", stdout);
18084 break;
18085 case AFL_EXT_5500:
18086 fputs ("NEC VR5500", stdout);
18087 break;
18088 case AFL_EXT_LOONGSON_2E:
18089 fputs ("ST Microelectronics Loongson 2E", stdout);
18090 break;
18091 case AFL_EXT_LOONGSON_2F:
18092 fputs ("ST Microelectronics Loongson 2F", stdout);
18093 break;
38bf472a
MR
18094 case AFL_EXT_INTERAPTIV_MR2:
18095 fputs ("Imagination interAptiv MR2", stdout);
18096 break;
351cdf24 18097 default:
00ac7aa0 18098 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18099 }
18100}
18101
32ec8896 18102static signed int
351cdf24
MF
18103get_mips_reg_size (int reg_size)
18104{
18105 return (reg_size == AFL_REG_NONE) ? 0
18106 : (reg_size == AFL_REG_32) ? 32
18107 : (reg_size == AFL_REG_64) ? 64
18108 : (reg_size == AFL_REG_128) ? 128
18109 : -1;
18110}
18111
015dc7e1 18112static bool
dda8d76d 18113process_mips_specific (Filedata * filedata)
5b18a4bc 18114{
2cf0635d 18115 Elf_Internal_Dyn * entry;
351cdf24 18116 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18117 size_t liblist_offset = 0;
18118 size_t liblistno = 0;
18119 size_t conflictsno = 0;
18120 size_t options_offset = 0;
18121 size_t conflicts_offset = 0;
861fb55a
DJ
18122 size_t pltrelsz = 0;
18123 size_t pltrel = 0;
ccb4c951 18124 bfd_vma pltgot = 0;
861fb55a
DJ
18125 bfd_vma mips_pltgot = 0;
18126 bfd_vma jmprel = 0;
ccb4c951
RS
18127 bfd_vma local_gotno = 0;
18128 bfd_vma gotsym = 0;
18129 bfd_vma symtabno = 0;
015dc7e1 18130 bool res = true;
103f02d3 18131
dda8d76d 18132 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18133 display_mips_gnu_attribute))
015dc7e1 18134 res = false;
2cf19d5c 18135
dda8d76d 18136 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18137
18138 if (sect != NULL)
18139 {
18140 Elf_External_ABIFlags_v0 *abiflags_ext;
18141 Elf_Internal_ABIFlags_v0 abiflags_in;
18142
18143 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18144 {
18145 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18146 res = false;
32ec8896 18147 }
351cdf24
MF
18148 else
18149 {
dda8d76d 18150 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18151 sect->sh_size, _("MIPS ABI Flags section"));
18152 if (abiflags_ext)
18153 {
18154 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18155 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18156 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18157 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18158 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18159 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18160 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18161 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18162 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18163 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18164 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18165
18166 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18167 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18168 if (abiflags_in.isa_rev > 1)
18169 printf ("r%d", abiflags_in.isa_rev);
18170 printf ("\nGPR size: %d",
18171 get_mips_reg_size (abiflags_in.gpr_size));
18172 printf ("\nCPR1 size: %d",
18173 get_mips_reg_size (abiflags_in.cpr1_size));
18174 printf ("\nCPR2 size: %d",
18175 get_mips_reg_size (abiflags_in.cpr2_size));
18176 fputs ("\nFP ABI: ", stdout);
18177 print_mips_fp_abi_value (abiflags_in.fp_abi);
18178 fputs ("ISA Extension: ", stdout);
18179 print_mips_isa_ext (abiflags_in.isa_ext);
18180 fputs ("\nASEs:", stdout);
18181 print_mips_ases (abiflags_in.ases);
18182 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18183 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18184 fputc ('\n', stdout);
18185 free (abiflags_ext);
18186 }
18187 }
18188 }
18189
19e6b90e 18190 /* We have a lot of special sections. Thanks SGI! */
978c4450 18191 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18192 {
18193 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18194 sect = find_section (filedata, ".got");
bbdd9a68
MR
18195 if (sect != NULL)
18196 {
18197 unsigned char *data_end;
18198 unsigned char *data;
18199 bfd_vma ent, end;
18200 int addr_size;
18201
18202 pltgot = sect->sh_addr;
18203
18204 ent = pltgot;
18205 addr_size = (is_32bit_elf ? 4 : 8);
18206 end = pltgot + sect->sh_size;
18207
dda8d76d 18208 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18209 end - pltgot, 1,
18210 _("Global Offset Table data"));
18211 /* PR 12855: Null data is handled gracefully throughout. */
18212 data_end = data + (end - pltgot);
18213
18214 printf (_("\nStatic GOT:\n"));
18215 printf (_(" Canonical gp value: "));
18216 print_vma (ent + 0x7ff0, LONG_HEX);
18217 printf ("\n\n");
18218
18219 /* In a dynamic binary GOT[0] is reserved for the dynamic
18220 loader to store the lazy resolver pointer, however in
18221 a static binary it may well have been omitted and GOT
18222 reduced to a table of addresses.
18223 PR 21344: Check for the entry being fully available
18224 before fetching it. */
18225 if (data
18226 && data + ent - pltgot + addr_size <= data_end
18227 && byte_get (data + ent - pltgot, addr_size) == 0)
18228 {
18229 printf (_(" Reserved entries:\n"));
18230 printf (_(" %*s %10s %*s\n"),
18231 addr_size * 2, _("Address"), _("Access"),
18232 addr_size * 2, _("Value"));
18233 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18234 printf ("\n");
18235 if (ent == (bfd_vma) -1)
18236 goto sgot_print_fail;
18237
18238 /* Check for the MSB of GOT[1] being set, identifying a
18239 GNU object. This entry will be used by some runtime
18240 loaders, to store the module pointer. Otherwise this
18241 is an ordinary local entry.
18242 PR 21344: Check for the entry being fully available
18243 before fetching it. */
18244 if (data
18245 && data + ent - pltgot + addr_size <= data_end
18246 && (byte_get (data + ent - pltgot, addr_size)
18247 >> (addr_size * 8 - 1)) != 0)
18248 {
18249 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18250 printf ("\n");
18251 if (ent == (bfd_vma) -1)
18252 goto sgot_print_fail;
18253 }
18254 printf ("\n");
18255 }
18256
f17e9d8a 18257 if (data != NULL && ent < end)
bbdd9a68
MR
18258 {
18259 printf (_(" Local entries:\n"));
18260 printf (" %*s %10s %*s\n",
18261 addr_size * 2, _("Address"), _("Access"),
18262 addr_size * 2, _("Value"));
18263 while (ent < end)
18264 {
18265 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18266 printf ("\n");
18267 if (ent == (bfd_vma) -1)
18268 goto sgot_print_fail;
18269 }
18270 printf ("\n");
18271 }
18272
18273 sgot_print_fail:
9db70fc3 18274 free (data);
bbdd9a68
MR
18275 }
18276 return res;
18277 }
252b5132 18278
978c4450 18279 for (entry = filedata->dynamic_section;
071436c6 18280 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18281 (entry < filedata->dynamic_section + filedata->dynamic_nent
18282 && entry->d_tag != DT_NULL);
071436c6 18283 ++entry)
252b5132
RH
18284 switch (entry->d_tag)
18285 {
18286 case DT_MIPS_LIBLIST:
d93f0186 18287 liblist_offset
dda8d76d 18288 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18289 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18290 break;
18291 case DT_MIPS_LIBLISTNO:
18292 liblistno = entry->d_un.d_val;
18293 break;
18294 case DT_MIPS_OPTIONS:
dda8d76d 18295 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18296 break;
18297 case DT_MIPS_CONFLICT:
d93f0186 18298 conflicts_offset
dda8d76d 18299 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18300 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18301 break;
18302 case DT_MIPS_CONFLICTNO:
18303 conflictsno = entry->d_un.d_val;
18304 break;
ccb4c951 18305 case DT_PLTGOT:
861fb55a
DJ
18306 pltgot = entry->d_un.d_ptr;
18307 break;
ccb4c951
RS
18308 case DT_MIPS_LOCAL_GOTNO:
18309 local_gotno = entry->d_un.d_val;
18310 break;
18311 case DT_MIPS_GOTSYM:
18312 gotsym = entry->d_un.d_val;
18313 break;
18314 case DT_MIPS_SYMTABNO:
18315 symtabno = entry->d_un.d_val;
18316 break;
861fb55a
DJ
18317 case DT_MIPS_PLTGOT:
18318 mips_pltgot = entry->d_un.d_ptr;
18319 break;
18320 case DT_PLTREL:
18321 pltrel = entry->d_un.d_val;
18322 break;
18323 case DT_PLTRELSZ:
18324 pltrelsz = entry->d_un.d_val;
18325 break;
18326 case DT_JMPREL:
18327 jmprel = entry->d_un.d_ptr;
18328 break;
252b5132
RH
18329 default:
18330 break;
18331 }
18332
18333 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18334 {
2cf0635d 18335 Elf32_External_Lib * elib;
252b5132
RH
18336 size_t cnt;
18337
dda8d76d 18338 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18339 sizeof (Elf32_External_Lib),
18340 liblistno,
18341 _("liblist section data"));
a6e9f9df 18342 if (elib)
252b5132 18343 {
d3a49aa8
AM
18344 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18345 "\nSection '.liblist' contains %lu entries:\n",
18346 (unsigned long) liblistno),
a6e9f9df 18347 (unsigned long) liblistno);
2b692964 18348 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18349 stdout);
18350
18351 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18352 {
a6e9f9df 18353 Elf32_Lib liblist;
91d6fa6a 18354 time_t atime;
d5b07ef4 18355 char timebuf[128];
2cf0635d 18356 struct tm * tmp;
a6e9f9df
AM
18357
18358 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18359 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18360 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18361 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18362 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18363
91d6fa6a 18364 tmp = gmtime (&atime);
e9e44622
JJ
18365 snprintf (timebuf, sizeof (timebuf),
18366 "%04u-%02u-%02uT%02u:%02u:%02u",
18367 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18368 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18369
31104126 18370 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18371 if (valid_dynamic_name (filedata, liblist.l_name))
18372 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18373 else
2b692964 18374 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18375 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18376 liblist.l_version);
a6e9f9df
AM
18377
18378 if (liblist.l_flags == 0)
2b692964 18379 puts (_(" NONE"));
a6e9f9df
AM
18380 else
18381 {
18382 static const struct
252b5132 18383 {
2cf0635d 18384 const char * name;
a6e9f9df 18385 int bit;
252b5132 18386 }
a6e9f9df
AM
18387 l_flags_vals[] =
18388 {
18389 { " EXACT_MATCH", LL_EXACT_MATCH },
18390 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18391 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18392 { " EXPORTS", LL_EXPORTS },
18393 { " DELAY_LOAD", LL_DELAY_LOAD },
18394 { " DELTA", LL_DELTA }
18395 };
18396 int flags = liblist.l_flags;
18397 size_t fcnt;
18398
60bca95a 18399 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18400 if ((flags & l_flags_vals[fcnt].bit) != 0)
18401 {
18402 fputs (l_flags_vals[fcnt].name, stdout);
18403 flags ^= l_flags_vals[fcnt].bit;
18404 }
18405 if (flags != 0)
18406 printf (" %#x", (unsigned int) flags);
252b5132 18407
a6e9f9df
AM
18408 puts ("");
18409 }
252b5132 18410 }
252b5132 18411
a6e9f9df
AM
18412 free (elib);
18413 }
32ec8896 18414 else
015dc7e1 18415 res = false;
252b5132
RH
18416 }
18417
18418 if (options_offset != 0)
18419 {
2cf0635d 18420 Elf_External_Options * eopt;
252b5132
RH
18421 size_t offset;
18422 int cnt;
18423
18424 /* Find the section header so that we get the size. */
dda8d76d 18425 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18426 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18427 if (sect == NULL)
18428 {
18429 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18430 return false;
071436c6 18431 }
7fc0c668
NC
18432 /* PR 24243 */
18433 if (sect->sh_size < sizeof (* eopt))
18434 {
18435 error (_("The MIPS options section is too small.\n"));
015dc7e1 18436 return false;
7fc0c668 18437 }
252b5132 18438
dda8d76d 18439 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18440 sect->sh_size, _("options"));
a6e9f9df 18441 if (eopt)
252b5132 18442 {
fd17d1e6 18443 Elf_Internal_Options option;
76da6bbe 18444
a6e9f9df 18445 offset = cnt = 0;
82b1b41b 18446 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18447 {
2cf0635d 18448 Elf_External_Options * eoption;
fd17d1e6 18449 unsigned int optsize;
252b5132 18450
a6e9f9df 18451 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18452
fd17d1e6 18453 optsize = BYTE_GET (eoption->size);
76da6bbe 18454
82b1b41b 18455 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18456 if (optsize < sizeof (* eopt)
18457 || optsize > sect->sh_size - offset)
82b1b41b 18458 {
645f43a8 18459 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18460 optsize);
645f43a8 18461 free (eopt);
015dc7e1 18462 return false;
82b1b41b 18463 }
fd17d1e6 18464 offset += optsize;
a6e9f9df
AM
18465 ++cnt;
18466 }
252b5132 18467
d3a49aa8
AM
18468 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18469 "\nSection '%s' contains %d entries:\n",
18470 cnt),
dda8d76d 18471 printable_section_name (filedata, sect), cnt);
76da6bbe 18472
82b1b41b 18473 offset = 0;
a6e9f9df 18474 while (cnt-- > 0)
252b5132 18475 {
a6e9f9df 18476 size_t len;
fd17d1e6
AM
18477 Elf_External_Options * eoption;
18478
18479 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18480
18481 option.kind = BYTE_GET (eoption->kind);
18482 option.size = BYTE_GET (eoption->size);
18483 option.section = BYTE_GET (eoption->section);
18484 option.info = BYTE_GET (eoption->info);
a6e9f9df 18485
fd17d1e6 18486 switch (option.kind)
252b5132 18487 {
a6e9f9df
AM
18488 case ODK_NULL:
18489 /* This shouldn't happen. */
d0c4e780 18490 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18491 option.section, option.info);
a6e9f9df 18492 break;
2e6be59c 18493
a6e9f9df
AM
18494 case ODK_REGINFO:
18495 printf (" REGINFO ");
dda8d76d 18496 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18497 {
2cf0635d 18498 Elf32_External_RegInfo * ereg;
b34976b6 18499 Elf32_RegInfo reginfo;
a6e9f9df 18500
2e6be59c 18501 /* 32bit form. */
fd17d1e6
AM
18502 if (option.size < (sizeof (Elf_External_Options)
18503 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18504 {
18505 printf (_("<corrupt>\n"));
18506 error (_("Truncated MIPS REGINFO option\n"));
18507 cnt = 0;
18508 break;
18509 }
18510
fd17d1e6 18511 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18512
a6e9f9df
AM
18513 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18514 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18515 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18516 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18517 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18518 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18519
d0c4e780
AM
18520 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18521 reginfo.ri_gprmask, reginfo.ri_gp_value);
18522 printf (" "
18523 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18524 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18525 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18526 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18527 }
18528 else
18529 {
18530 /* 64 bit form. */
2cf0635d 18531 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18532 Elf64_Internal_RegInfo reginfo;
18533
fd17d1e6
AM
18534 if (option.size < (sizeof (Elf_External_Options)
18535 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18536 {
18537 printf (_("<corrupt>\n"));
18538 error (_("Truncated MIPS REGINFO option\n"));
18539 cnt = 0;
18540 break;
18541 }
18542
fd17d1e6 18543 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18544 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18545 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18546 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18547 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18548 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18549 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18550
d0c4e780
AM
18551 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18552 reginfo.ri_gprmask, reginfo.ri_gp_value);
18553 printf (" "
18554 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18555 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18556 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18557 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18558 }
fd17d1e6 18559 offset += option.size;
a6e9f9df 18560 continue;
2e6be59c 18561
a6e9f9df
AM
18562 case ODK_EXCEPTIONS:
18563 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18564 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18565 fputs (") fpe_max(", stdout);
fd17d1e6 18566 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18567 fputs (")", stdout);
18568
fd17d1e6 18569 if (option.info & OEX_PAGE0)
a6e9f9df 18570 fputs (" PAGE0", stdout);
fd17d1e6 18571 if (option.info & OEX_SMM)
a6e9f9df 18572 fputs (" SMM", stdout);
fd17d1e6 18573 if (option.info & OEX_FPDBUG)
a6e9f9df 18574 fputs (" FPDBUG", stdout);
fd17d1e6 18575 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18576 fputs (" DISMISS", stdout);
18577 break;
2e6be59c 18578
a6e9f9df
AM
18579 case ODK_PAD:
18580 fputs (" PAD ", stdout);
fd17d1e6 18581 if (option.info & OPAD_PREFIX)
a6e9f9df 18582 fputs (" PREFIX", stdout);
fd17d1e6 18583 if (option.info & OPAD_POSTFIX)
a6e9f9df 18584 fputs (" POSTFIX", stdout);
fd17d1e6 18585 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18586 fputs (" SYMBOL", stdout);
18587 break;
2e6be59c 18588
a6e9f9df
AM
18589 case ODK_HWPATCH:
18590 fputs (" HWPATCH ", stdout);
fd17d1e6 18591 if (option.info & OHW_R4KEOP)
a6e9f9df 18592 fputs (" R4KEOP", stdout);
fd17d1e6 18593 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18594 fputs (" R8KPFETCH", stdout);
fd17d1e6 18595 if (option.info & OHW_R5KEOP)
a6e9f9df 18596 fputs (" R5KEOP", stdout);
fd17d1e6 18597 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18598 fputs (" R5KCVTL", stdout);
18599 break;
2e6be59c 18600
a6e9f9df
AM
18601 case ODK_FILL:
18602 fputs (" FILL ", stdout);
18603 /* XXX Print content of info word? */
18604 break;
2e6be59c 18605
a6e9f9df
AM
18606 case ODK_TAGS:
18607 fputs (" TAGS ", stdout);
18608 /* XXX Print content of info word? */
18609 break;
2e6be59c 18610
a6e9f9df
AM
18611 case ODK_HWAND:
18612 fputs (" HWAND ", stdout);
fd17d1e6 18613 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18614 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18615 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18616 fputs (" R4KEOP_CLEAN", stdout);
18617 break;
2e6be59c 18618
a6e9f9df
AM
18619 case ODK_HWOR:
18620 fputs (" HWOR ", stdout);
fd17d1e6 18621 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18622 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18623 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18624 fputs (" R4KEOP_CLEAN", stdout);
18625 break;
2e6be59c 18626
a6e9f9df 18627 case ODK_GP_GROUP:
d0c4e780 18628 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18629 option.info & OGP_GROUP,
18630 (option.info & OGP_SELF) >> 16);
a6e9f9df 18631 break;
2e6be59c 18632
a6e9f9df 18633 case ODK_IDENT:
d0c4e780 18634 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18635 option.info & OGP_GROUP,
18636 (option.info & OGP_SELF) >> 16);
a6e9f9df 18637 break;
2e6be59c 18638
a6e9f9df
AM
18639 default:
18640 /* This shouldn't happen. */
d0c4e780 18641 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18642 option.kind, option.section, option.info);
a6e9f9df 18643 break;
252b5132 18644 }
a6e9f9df 18645
2cf0635d 18646 len = sizeof (* eopt);
fd17d1e6 18647 while (len < option.size)
82b1b41b 18648 {
fd17d1e6 18649 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18650
82b1b41b
NC
18651 if (ISPRINT (datum))
18652 printf ("%c", datum);
18653 else
18654 printf ("\\%03o", datum);
18655 len ++;
18656 }
a6e9f9df 18657 fputs ("\n", stdout);
82b1b41b 18658
fd17d1e6 18659 offset += option.size;
252b5132 18660 }
a6e9f9df 18661 free (eopt);
252b5132 18662 }
32ec8896 18663 else
015dc7e1 18664 res = false;
252b5132
RH
18665 }
18666
18667 if (conflicts_offset != 0 && conflictsno != 0)
18668 {
2cf0635d 18669 Elf32_Conflict * iconf;
252b5132
RH
18670 size_t cnt;
18671
978c4450 18672 if (filedata->dynamic_symbols == NULL)
252b5132 18673 {
591a748a 18674 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18675 return false;
252b5132
RH
18676 }
18677
7296a62a
NC
18678 /* PR 21345 - print a slightly more helpful error message
18679 if we are sure that the cmalloc will fail. */
645f43a8 18680 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18681 {
18682 error (_("Overlarge number of conflicts detected: %lx\n"),
18683 (long) conflictsno);
015dc7e1 18684 return false;
7296a62a
NC
18685 }
18686
3f5e193b 18687 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18688 if (iconf == NULL)
18689 {
8b73c356 18690 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18691 return false;
252b5132
RH
18692 }
18693
9ea033b2 18694 if (is_32bit_elf)
252b5132 18695 {
2cf0635d 18696 Elf32_External_Conflict * econf32;
a6e9f9df 18697
3f5e193b 18698 econf32 = (Elf32_External_Conflict *)
95099889
AM
18699 get_data (NULL, filedata, conflicts_offset,
18700 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18701 if (!econf32)
5a814d6d
AM
18702 {
18703 free (iconf);
015dc7e1 18704 return false;
5a814d6d 18705 }
252b5132
RH
18706
18707 for (cnt = 0; cnt < conflictsno; ++cnt)
18708 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18709
18710 free (econf32);
252b5132
RH
18711 }
18712 else
18713 {
2cf0635d 18714 Elf64_External_Conflict * econf64;
a6e9f9df 18715
3f5e193b 18716 econf64 = (Elf64_External_Conflict *)
95099889
AM
18717 get_data (NULL, filedata, conflicts_offset,
18718 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18719 if (!econf64)
5a814d6d
AM
18720 {
18721 free (iconf);
015dc7e1 18722 return false;
5a814d6d 18723 }
252b5132
RH
18724
18725 for (cnt = 0; cnt < conflictsno; ++cnt)
18726 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18727
18728 free (econf64);
252b5132
RH
18729 }
18730
d3a49aa8
AM
18731 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18732 "\nSection '.conflict' contains %lu entries:\n",
18733 (unsigned long) conflictsno),
c7e7ca54 18734 (unsigned long) conflictsno);
252b5132
RH
18735 puts (_(" Num: Index Value Name"));
18736
18737 for (cnt = 0; cnt < conflictsno; ++cnt)
18738 {
b34976b6 18739 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18740
978c4450 18741 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18742 printf (_("<corrupt symbol index>"));
d79b3d50 18743 else
e0a31db1
NC
18744 {
18745 Elf_Internal_Sym * psym;
18746
978c4450 18747 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18748 print_vma (psym->st_value, FULL_HEX);
18749 putchar (' ');
84714f86
AM
18750 if (valid_dynamic_name (filedata, psym->st_name))
18751 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18752 else
18753 printf (_("<corrupt: %14ld>"), psym->st_name);
18754 }
31104126 18755 putchar ('\n');
252b5132
RH
18756 }
18757
252b5132
RH
18758 free (iconf);
18759 }
18760
ccb4c951
RS
18761 if (pltgot != 0 && local_gotno != 0)
18762 {
91d6fa6a 18763 bfd_vma ent, local_end, global_end;
bbeee7ea 18764 size_t i, offset;
2cf0635d 18765 unsigned char * data;
82b1b41b 18766 unsigned char * data_end;
bbeee7ea 18767 int addr_size;
ccb4c951 18768
91d6fa6a 18769 ent = pltgot;
ccb4c951
RS
18770 addr_size = (is_32bit_elf ? 4 : 8);
18771 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18772
74e1a04b
NC
18773 /* PR binutils/17533 file: 012-111227-0.004 */
18774 if (symtabno < gotsym)
18775 {
18776 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18777 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18778 return false;
74e1a04b 18779 }
82b1b41b 18780
74e1a04b 18781 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18782 /* PR 17531: file: 54c91a34. */
18783 if (global_end < local_end)
18784 {
18785 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18786 return false;
82b1b41b 18787 }
948f632f 18788
dda8d76d
NC
18789 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18790 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18791 global_end - pltgot, 1,
18792 _("Global Offset Table data"));
919383ac 18793 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18794 data_end = data + (global_end - pltgot);
59245841 18795
ccb4c951
RS
18796 printf (_("\nPrimary GOT:\n"));
18797 printf (_(" Canonical gp value: "));
18798 print_vma (pltgot + 0x7ff0, LONG_HEX);
18799 printf ("\n\n");
18800
18801 printf (_(" Reserved entries:\n"));
18802 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18803 addr_size * 2, _("Address"), _("Access"),
18804 addr_size * 2, _("Initial"));
82b1b41b 18805 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18806 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18807 if (ent == (bfd_vma) -1)
18808 goto got_print_fail;
75ec1fdb 18809
c4ab9505
MR
18810 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18811 This entry will be used by some runtime loaders, to store the
18812 module pointer. Otherwise this is an ordinary local entry.
18813 PR 21344: Check for the entry being fully available before
18814 fetching it. */
18815 if (data
18816 && data + ent - pltgot + addr_size <= data_end
18817 && (byte_get (data + ent - pltgot, addr_size)
18818 >> (addr_size * 8 - 1)) != 0)
18819 {
18820 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18821 printf (_(" Module pointer (GNU extension)\n"));
18822 if (ent == (bfd_vma) -1)
18823 goto got_print_fail;
ccb4c951
RS
18824 }
18825 printf ("\n");
18826
f17e9d8a 18827 if (data != NULL && ent < local_end)
ccb4c951
RS
18828 {
18829 printf (_(" Local entries:\n"));
cc5914eb 18830 printf (" %*s %10s %*s\n",
2b692964
NC
18831 addr_size * 2, _("Address"), _("Access"),
18832 addr_size * 2, _("Initial"));
91d6fa6a 18833 while (ent < local_end)
ccb4c951 18834 {
82b1b41b 18835 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18836 printf ("\n");
82b1b41b
NC
18837 if (ent == (bfd_vma) -1)
18838 goto got_print_fail;
ccb4c951
RS
18839 }
18840 printf ("\n");
18841 }
18842
f17e9d8a 18843 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18844 {
18845 int sym_width;
18846
18847 printf (_(" Global entries:\n"));
cc5914eb 18848 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18849 addr_size * 2, _("Address"),
18850 _("Access"),
2b692964 18851 addr_size * 2, _("Initial"),
9cf03b7e
NC
18852 addr_size * 2, _("Sym.Val."),
18853 _("Type"),
18854 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18855 _("Ndx"), _("Name"));
0b4362b0 18856
ccb4c951 18857 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18858
ccb4c951
RS
18859 for (i = gotsym; i < symtabno; i++)
18860 {
82b1b41b 18861 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18862 printf (" ");
e0a31db1 18863
978c4450 18864 if (filedata->dynamic_symbols == NULL)
e0a31db1 18865 printf (_("<no dynamic symbols>"));
978c4450 18866 else if (i < filedata->num_dynamic_syms)
e0a31db1 18867 {
978c4450 18868 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18869
18870 print_vma (psym->st_value, LONG_HEX);
18871 printf (" %-7s %3s ",
dda8d76d
NC
18872 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18873 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18874
84714f86 18875 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18876 print_symbol (sym_width,
84714f86 18877 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18878 else
18879 printf (_("<corrupt: %14ld>"), psym->st_name);
18880 }
ccb4c951 18881 else
7fc5ac57
JBG
18882 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18883 (unsigned long) i);
e0a31db1 18884
ccb4c951 18885 printf ("\n");
82b1b41b
NC
18886 if (ent == (bfd_vma) -1)
18887 break;
ccb4c951
RS
18888 }
18889 printf ("\n");
18890 }
18891
82b1b41b 18892 got_print_fail:
9db70fc3 18893 free (data);
ccb4c951
RS
18894 }
18895
861fb55a
DJ
18896 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18897 {
91d6fa6a 18898 bfd_vma ent, end;
861fb55a
DJ
18899 size_t offset, rel_offset;
18900 unsigned long count, i;
2cf0635d 18901 unsigned char * data;
861fb55a 18902 int addr_size, sym_width;
2cf0635d 18903 Elf_Internal_Rela * rels;
861fb55a 18904
dda8d76d 18905 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18906 if (pltrel == DT_RELA)
18907 {
dda8d76d 18908 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18909 return false;
861fb55a
DJ
18910 }
18911 else
18912 {
dda8d76d 18913 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18914 return false;
861fb55a
DJ
18915 }
18916
91d6fa6a 18917 ent = mips_pltgot;
861fb55a
DJ
18918 addr_size = (is_32bit_elf ? 4 : 8);
18919 end = mips_pltgot + (2 + count) * addr_size;
18920
dda8d76d
NC
18921 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18922 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18923 1, _("Procedure Linkage Table data"));
59245841 18924 if (data == NULL)
288f0ba2
AM
18925 {
18926 free (rels);
015dc7e1 18927 return false;
288f0ba2 18928 }
59245841 18929
9cf03b7e 18930 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18931 printf (_(" Reserved entries:\n"));
18932 printf (_(" %*s %*s Purpose\n"),
2b692964 18933 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18934 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18935 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18936 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18937 printf (_(" Module pointer\n"));
861fb55a
DJ
18938 printf ("\n");
18939
18940 printf (_(" Entries:\n"));
cc5914eb 18941 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18942 addr_size * 2, _("Address"),
18943 addr_size * 2, _("Initial"),
18944 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18945 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18946 for (i = 0; i < count; i++)
18947 {
df97ab2a 18948 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18949
91d6fa6a 18950 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18951 printf (" ");
e0a31db1 18952
978c4450 18953 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18954 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18955 else
e0a31db1 18956 {
978c4450 18957 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18958
18959 print_vma (psym->st_value, LONG_HEX);
18960 printf (" %-7s %3s ",
dda8d76d
NC
18961 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18962 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 18963 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18964 print_symbol (sym_width,
84714f86 18965 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18966 else
18967 printf (_("<corrupt: %14ld>"), psym->st_name);
18968 }
861fb55a
DJ
18969 printf ("\n");
18970 }
18971 printf ("\n");
18972
9db70fc3 18973 free (data);
861fb55a
DJ
18974 free (rels);
18975 }
18976
32ec8896 18977 return res;
252b5132
RH
18978}
18979
015dc7e1 18980static bool
dda8d76d 18981process_nds32_specific (Filedata * filedata)
35c08157
KLC
18982{
18983 Elf_Internal_Shdr *sect = NULL;
18984
dda8d76d 18985 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18986 if (sect != NULL && sect->sh_size >= 4)
35c08157 18987 {
9c7b8e9b
AM
18988 unsigned char *buf;
18989 unsigned int flag;
35c08157
KLC
18990
18991 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18992 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18993 _("NDS32 elf flags section"));
35c08157 18994
9c7b8e9b 18995 if (buf == NULL)
015dc7e1 18996 return false;
32ec8896 18997
9c7b8e9b
AM
18998 flag = byte_get (buf, 4);
18999 free (buf);
19000 switch (flag & 0x3)
35c08157
KLC
19001 {
19002 case 0:
19003 printf ("(VEC_SIZE):\tNo entry.\n");
19004 break;
19005 case 1:
19006 printf ("(VEC_SIZE):\t4 bytes\n");
19007 break;
19008 case 2:
19009 printf ("(VEC_SIZE):\t16 bytes\n");
19010 break;
19011 case 3:
19012 printf ("(VEC_SIZE):\treserved\n");
19013 break;
19014 }
19015 }
19016
015dc7e1 19017 return true;
35c08157
KLC
19018}
19019
015dc7e1 19020static bool
dda8d76d 19021process_gnu_liblist (Filedata * filedata)
047b2264 19022{
2cf0635d
NC
19023 Elf_Internal_Shdr * section;
19024 Elf_Internal_Shdr * string_sec;
19025 Elf32_External_Lib * elib;
19026 char * strtab;
c256ffe7 19027 size_t strtab_size;
047b2264 19028 size_t cnt;
d3a49aa8 19029 unsigned long num_liblist;
047b2264 19030 unsigned i;
015dc7e1 19031 bool res = true;
047b2264
JJ
19032
19033 if (! do_arch)
015dc7e1 19034 return true;
047b2264 19035
dda8d76d
NC
19036 for (i = 0, section = filedata->section_headers;
19037 i < filedata->file_header.e_shnum;
b34976b6 19038 i++, section++)
047b2264
JJ
19039 {
19040 switch (section->sh_type)
19041 {
19042 case SHT_GNU_LIBLIST:
dda8d76d 19043 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19044 break;
19045
3f5e193b 19046 elib = (Elf32_External_Lib *)
dda8d76d 19047 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19048 _("liblist section data"));
047b2264
JJ
19049
19050 if (elib == NULL)
32ec8896 19051 {
015dc7e1 19052 res = false;
32ec8896
NC
19053 break;
19054 }
047b2264 19055
dda8d76d
NC
19056 string_sec = filedata->section_headers + section->sh_link;
19057 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19058 string_sec->sh_size,
19059 _("liblist string table"));
047b2264
JJ
19060 if (strtab == NULL
19061 || section->sh_entsize != sizeof (Elf32_External_Lib))
19062 {
19063 free (elib);
2842702f 19064 free (strtab);
015dc7e1 19065 res = false;
047b2264
JJ
19066 break;
19067 }
59245841 19068 strtab_size = string_sec->sh_size;
047b2264 19069
d3a49aa8
AM
19070 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19071 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19072 "\nLibrary list section '%s' contains %lu entries:\n",
19073 num_liblist),
dda8d76d 19074 printable_section_name (filedata, section),
d3a49aa8 19075 num_liblist);
047b2264 19076
2b692964 19077 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19078
19079 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19080 ++cnt)
19081 {
19082 Elf32_Lib liblist;
91d6fa6a 19083 time_t atime;
d5b07ef4 19084 char timebuf[128];
2cf0635d 19085 struct tm * tmp;
047b2264
JJ
19086
19087 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19088 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19089 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19090 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19091 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19092
91d6fa6a 19093 tmp = gmtime (&atime);
e9e44622
JJ
19094 snprintf (timebuf, sizeof (timebuf),
19095 "%04u-%02u-%02uT%02u:%02u:%02u",
19096 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19097 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19098
19099 printf ("%3lu: ", (unsigned long) cnt);
19100 if (do_wide)
c256ffe7 19101 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19102 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19103 else
c256ffe7 19104 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19105 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19106 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19107 liblist.l_version, liblist.l_flags);
19108 }
19109
19110 free (elib);
2842702f 19111 free (strtab);
047b2264
JJ
19112 }
19113 }
19114
32ec8896 19115 return res;
047b2264
JJ
19116}
19117
9437c45b 19118static const char *
dda8d76d 19119get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19120{
19121 static char buff[64];
103f02d3 19122
dda8d76d 19123 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19124 switch (e_type)
19125 {
57346661 19126 case NT_AUXV:
1ec5cd37 19127 return _("NT_AUXV (auxiliary vector)");
57346661 19128 case NT_PRSTATUS:
1ec5cd37 19129 return _("NT_PRSTATUS (prstatus structure)");
57346661 19130 case NT_FPREGSET:
1ec5cd37 19131 return _("NT_FPREGSET (floating point registers)");
57346661 19132 case NT_PRPSINFO:
1ec5cd37 19133 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19134 case NT_TASKSTRUCT:
1ec5cd37 19135 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19136 case NT_GDB_TDESC:
19137 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19138 case NT_PRXFPREG:
1ec5cd37 19139 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19140 case NT_PPC_VMX:
19141 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19142 case NT_PPC_VSX:
19143 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19144 case NT_PPC_TAR:
19145 return _("NT_PPC_TAR (ppc TAR register)");
19146 case NT_PPC_PPR:
19147 return _("NT_PPC_PPR (ppc PPR register)");
19148 case NT_PPC_DSCR:
19149 return _("NT_PPC_DSCR (ppc DSCR register)");
19150 case NT_PPC_EBB:
19151 return _("NT_PPC_EBB (ppc EBB registers)");
19152 case NT_PPC_PMU:
19153 return _("NT_PPC_PMU (ppc PMU registers)");
19154 case NT_PPC_TM_CGPR:
19155 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19156 case NT_PPC_TM_CFPR:
19157 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19158 case NT_PPC_TM_CVMX:
19159 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19160 case NT_PPC_TM_CVSX:
3fd21718 19161 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19162 case NT_PPC_TM_SPR:
19163 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19164 case NT_PPC_TM_CTAR:
19165 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19166 case NT_PPC_TM_CPPR:
19167 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19168 case NT_PPC_TM_CDSCR:
19169 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19170 case NT_386_TLS:
19171 return _("NT_386_TLS (x86 TLS information)");
19172 case NT_386_IOPERM:
19173 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19174 case NT_X86_XSTATE:
19175 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19176 case NT_X86_CET:
19177 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19178 case NT_S390_HIGH_GPRS:
19179 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19180 case NT_S390_TIMER:
19181 return _("NT_S390_TIMER (s390 timer register)");
19182 case NT_S390_TODCMP:
19183 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19184 case NT_S390_TODPREG:
19185 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19186 case NT_S390_CTRS:
19187 return _("NT_S390_CTRS (s390 control registers)");
19188 case NT_S390_PREFIX:
19189 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19190 case NT_S390_LAST_BREAK:
19191 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19192 case NT_S390_SYSTEM_CALL:
19193 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19194 case NT_S390_TDB:
19195 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19196 case NT_S390_VXRS_LOW:
19197 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19198 case NT_S390_VXRS_HIGH:
19199 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19200 case NT_S390_GS_CB:
19201 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19202 case NT_S390_GS_BC:
19203 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19204 case NT_ARM_VFP:
19205 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19206 case NT_ARM_TLS:
19207 return _("NT_ARM_TLS (AArch TLS registers)");
19208 case NT_ARM_HW_BREAK:
19209 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19210 case NT_ARM_HW_WATCH:
19211 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
19212 case NT_ARM_SVE:
19213 return _("NT_ARM_SVE (AArch SVE registers)");
19214 case NT_ARM_PAC_MASK:
19215 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19216 case NT_ARM_PACA_KEYS:
19217 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19218 case NT_ARM_PACG_KEYS:
19219 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19220 case NT_ARM_TAGGED_ADDR_CTRL:
19221 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19222 case NT_ARM_PAC_ENABLED_KEYS:
19223 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19224 case NT_ARC_V2:
19225 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19226 case NT_RISCV_CSR:
19227 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19228 case NT_PSTATUS:
1ec5cd37 19229 return _("NT_PSTATUS (pstatus structure)");
57346661 19230 case NT_FPREGS:
1ec5cd37 19231 return _("NT_FPREGS (floating point registers)");
57346661 19232 case NT_PSINFO:
1ec5cd37 19233 return _("NT_PSINFO (psinfo structure)");
57346661 19234 case NT_LWPSTATUS:
1ec5cd37 19235 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19236 case NT_LWPSINFO:
1ec5cd37 19237 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19238 case NT_WIN32PSTATUS:
1ec5cd37 19239 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19240 case NT_SIGINFO:
19241 return _("NT_SIGINFO (siginfo_t data)");
19242 case NT_FILE:
19243 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19244 default:
19245 break;
19246 }
19247 else
19248 switch (e_type)
19249 {
19250 case NT_VERSION:
19251 return _("NT_VERSION (version)");
19252 case NT_ARCH:
19253 return _("NT_ARCH (architecture)");
9ef920e9 19254 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19255 return _("OPEN");
9ef920e9 19256 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19257 return _("func");
c8795e1f
NC
19258 case NT_GO_BUILDID:
19259 return _("GO BUILDID");
3ac925fc
LB
19260 case FDO_PACKAGING_METADATA:
19261 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19262 default:
19263 break;
19264 }
19265
e9e44622 19266 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19267 return buff;
779fe533
NC
19268}
19269
015dc7e1 19270static bool
9ece1fa9
TT
19271print_core_note (Elf_Internal_Note *pnote)
19272{
19273 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19274 bfd_vma count, page_size;
19275 unsigned char *descdata, *filenames, *descend;
19276
19277 if (pnote->type != NT_FILE)
04ac15ab
AS
19278 {
19279 if (do_wide)
19280 printf ("\n");
015dc7e1 19281 return true;
04ac15ab 19282 }
9ece1fa9
TT
19283
19284#ifndef BFD64
19285 if (!is_32bit_elf)
19286 {
19287 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19288 /* Still "successful". */
015dc7e1 19289 return true;
9ece1fa9
TT
19290 }
19291#endif
19292
19293 if (pnote->descsz < 2 * addr_size)
19294 {
32ec8896 19295 error (_(" Malformed note - too short for header\n"));
015dc7e1 19296 return false;
9ece1fa9
TT
19297 }
19298
19299 descdata = (unsigned char *) pnote->descdata;
19300 descend = descdata + pnote->descsz;
19301
19302 if (descdata[pnote->descsz - 1] != '\0')
19303 {
32ec8896 19304 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19305 return false;
9ece1fa9
TT
19306 }
19307
19308 count = byte_get (descdata, addr_size);
19309 descdata += addr_size;
19310
19311 page_size = byte_get (descdata, addr_size);
19312 descdata += addr_size;
19313
5396a86e
AM
19314 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19315 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19316 {
32ec8896 19317 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19318 return false;
9ece1fa9
TT
19319 }
19320
19321 printf (_(" Page size: "));
19322 print_vma (page_size, DEC);
19323 printf ("\n");
19324
19325 printf (_(" %*s%*s%*s\n"),
19326 (int) (2 + 2 * addr_size), _("Start"),
19327 (int) (4 + 2 * addr_size), _("End"),
19328 (int) (4 + 2 * addr_size), _("Page Offset"));
19329 filenames = descdata + count * 3 * addr_size;
595712bb 19330 while (count-- > 0)
9ece1fa9
TT
19331 {
19332 bfd_vma start, end, file_ofs;
19333
19334 if (filenames == descend)
19335 {
32ec8896 19336 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19337 return false;
9ece1fa9
TT
19338 }
19339
19340 start = byte_get (descdata, addr_size);
19341 descdata += addr_size;
19342 end = byte_get (descdata, addr_size);
19343 descdata += addr_size;
19344 file_ofs = byte_get (descdata, addr_size);
19345 descdata += addr_size;
19346
19347 printf (" ");
19348 print_vma (start, FULL_HEX);
19349 printf (" ");
19350 print_vma (end, FULL_HEX);
19351 printf (" ");
19352 print_vma (file_ofs, FULL_HEX);
19353 printf ("\n %s\n", filenames);
19354
19355 filenames += 1 + strlen ((char *) filenames);
19356 }
19357
015dc7e1 19358 return true;
9ece1fa9
TT
19359}
19360
1118d252
RM
19361static const char *
19362get_gnu_elf_note_type (unsigned e_type)
19363{
1449284b 19364 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19365 switch (e_type)
19366 {
19367 case NT_GNU_ABI_TAG:
19368 return _("NT_GNU_ABI_TAG (ABI version tag)");
19369 case NT_GNU_HWCAP:
19370 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19371 case NT_GNU_BUILD_ID:
19372 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19373 case NT_GNU_GOLD_VERSION:
19374 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19375 case NT_GNU_PROPERTY_TYPE_0:
19376 return _("NT_GNU_PROPERTY_TYPE_0");
19377 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19378 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19379 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19380 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19381 default:
1449284b
NC
19382 {
19383 static char buff[64];
1118d252 19384
1449284b
NC
19385 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19386 return buff;
19387 }
19388 }
1118d252
RM
19389}
19390
a9eafb08
L
19391static void
19392decode_x86_compat_isa (unsigned int bitmask)
19393{
19394 while (bitmask)
19395 {
19396 unsigned int bit = bitmask & (- bitmask);
19397
19398 bitmask &= ~ bit;
19399 switch (bit)
19400 {
19401 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19402 printf ("i486");
19403 break;
19404 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19405 printf ("586");
19406 break;
19407 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19408 printf ("686");
19409 break;
19410 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19411 printf ("SSE");
19412 break;
19413 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19414 printf ("SSE2");
19415 break;
19416 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19417 printf ("SSE3");
19418 break;
19419 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19420 printf ("SSSE3");
19421 break;
19422 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19423 printf ("SSE4_1");
19424 break;
19425 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19426 printf ("SSE4_2");
19427 break;
19428 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19429 printf ("AVX");
19430 break;
19431 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19432 printf ("AVX2");
19433 break;
19434 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19435 printf ("AVX512F");
19436 break;
19437 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19438 printf ("AVX512CD");
19439 break;
19440 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19441 printf ("AVX512ER");
19442 break;
19443 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19444 printf ("AVX512PF");
19445 break;
19446 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19447 printf ("AVX512VL");
19448 break;
19449 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19450 printf ("AVX512DQ");
19451 break;
19452 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19453 printf ("AVX512BW");
19454 break;
65b3d26e
L
19455 default:
19456 printf (_("<unknown: %x>"), bit);
19457 break;
a9eafb08
L
19458 }
19459 if (bitmask)
19460 printf (", ");
19461 }
19462}
19463
9ef920e9 19464static void
32930e4e 19465decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19466{
0a59decb 19467 if (!bitmask)
90c745dc
L
19468 {
19469 printf (_("<None>"));
19470 return;
19471 }
90c745dc 19472
9ef920e9
NC
19473 while (bitmask)
19474 {
1fc87489 19475 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19476
19477 bitmask &= ~ bit;
19478 switch (bit)
19479 {
32930e4e 19480 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19481 printf ("CMOV");
19482 break;
32930e4e 19483 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19484 printf ("SSE");
19485 break;
32930e4e 19486 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19487 printf ("SSE2");
19488 break;
32930e4e 19489 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19490 printf ("SSE3");
19491 break;
32930e4e 19492 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19493 printf ("SSSE3");
19494 break;
32930e4e 19495 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19496 printf ("SSE4_1");
19497 break;
32930e4e 19498 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19499 printf ("SSE4_2");
19500 break;
32930e4e 19501 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19502 printf ("AVX");
19503 break;
32930e4e 19504 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19505 printf ("AVX2");
19506 break;
32930e4e 19507 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19508 printf ("FMA");
19509 break;
32930e4e 19510 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19511 printf ("AVX512F");
19512 break;
32930e4e 19513 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19514 printf ("AVX512CD");
19515 break;
32930e4e 19516 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19517 printf ("AVX512ER");
19518 break;
32930e4e 19519 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19520 printf ("AVX512PF");
19521 break;
32930e4e 19522 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19523 printf ("AVX512VL");
19524 break;
32930e4e 19525 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19526 printf ("AVX512DQ");
19527 break;
32930e4e 19528 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19529 printf ("AVX512BW");
19530 break;
32930e4e 19531 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19532 printf ("AVX512_4FMAPS");
19533 break;
32930e4e 19534 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19535 printf ("AVX512_4VNNIW");
19536 break;
32930e4e 19537 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19538 printf ("AVX512_BITALG");
19539 break;
32930e4e 19540 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19541 printf ("AVX512_IFMA");
19542 break;
32930e4e 19543 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19544 printf ("AVX512_VBMI");
19545 break;
32930e4e 19546 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19547 printf ("AVX512_VBMI2");
19548 break;
32930e4e 19549 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19550 printf ("AVX512_VNNI");
19551 break;
32930e4e 19552 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19553 printf ("AVX512_BF16");
19554 break;
65b3d26e
L
19555 default:
19556 printf (_("<unknown: %x>"), bit);
19557 break;
9ef920e9
NC
19558 }
19559 if (bitmask)
19560 printf (", ");
19561 }
19562}
19563
32930e4e
L
19564static void
19565decode_x86_isa (unsigned int bitmask)
19566{
32930e4e
L
19567 while (bitmask)
19568 {
19569 unsigned int bit = bitmask & (- bitmask);
19570
19571 bitmask &= ~ bit;
19572 switch (bit)
19573 {
b0ab0693
L
19574 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19575 printf ("x86-64-baseline");
19576 break;
32930e4e
L
19577 case GNU_PROPERTY_X86_ISA_1_V2:
19578 printf ("x86-64-v2");
19579 break;
19580 case GNU_PROPERTY_X86_ISA_1_V3:
19581 printf ("x86-64-v3");
19582 break;
19583 case GNU_PROPERTY_X86_ISA_1_V4:
19584 printf ("x86-64-v4");
19585 break;
19586 default:
19587 printf (_("<unknown: %x>"), bit);
19588 break;
19589 }
19590 if (bitmask)
19591 printf (", ");
19592 }
19593}
19594
ee2fdd6f 19595static void
a9eafb08 19596decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19597{
0a59decb 19598 if (!bitmask)
90c745dc
L
19599 {
19600 printf (_("<None>"));
19601 return;
19602 }
90c745dc 19603
ee2fdd6f
L
19604 while (bitmask)
19605 {
19606 unsigned int bit = bitmask & (- bitmask);
19607
19608 bitmask &= ~ bit;
19609 switch (bit)
19610 {
19611 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19612 printf ("IBT");
ee2fdd6f 19613 break;
48580982 19614 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19615 printf ("SHSTK");
48580982 19616 break;
279d901e
L
19617 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19618 printf ("LAM_U48");
19619 break;
19620 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19621 printf ("LAM_U57");
19622 break;
ee2fdd6f
L
19623 default:
19624 printf (_("<unknown: %x>"), bit);
19625 break;
19626 }
19627 if (bitmask)
19628 printf (", ");
19629 }
19630}
19631
a9eafb08
L
19632static void
19633decode_x86_feature_2 (unsigned int bitmask)
19634{
0a59decb 19635 if (!bitmask)
90c745dc
L
19636 {
19637 printf (_("<None>"));
19638 return;
19639 }
90c745dc 19640
a9eafb08
L
19641 while (bitmask)
19642 {
19643 unsigned int bit = bitmask & (- bitmask);
19644
19645 bitmask &= ~ bit;
19646 switch (bit)
19647 {
19648 case GNU_PROPERTY_X86_FEATURE_2_X86:
19649 printf ("x86");
19650 break;
19651 case GNU_PROPERTY_X86_FEATURE_2_X87:
19652 printf ("x87");
19653 break;
19654 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19655 printf ("MMX");
19656 break;
19657 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19658 printf ("XMM");
19659 break;
19660 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19661 printf ("YMM");
19662 break;
19663 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19664 printf ("ZMM");
19665 break;
a308b89d
L
19666 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19667 printf ("TMM");
19668 break;
32930e4e
L
19669 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19670 printf ("MASK");
19671 break;
a9eafb08
L
19672 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19673 printf ("FXSR");
19674 break;
19675 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19676 printf ("XSAVE");
19677 break;
19678 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19679 printf ("XSAVEOPT");
19680 break;
19681 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19682 printf ("XSAVEC");
19683 break;
65b3d26e
L
19684 default:
19685 printf (_("<unknown: %x>"), bit);
19686 break;
a9eafb08
L
19687 }
19688 if (bitmask)
19689 printf (", ");
19690 }
19691}
19692
cd702818
SD
19693static void
19694decode_aarch64_feature_1_and (unsigned int bitmask)
19695{
19696 while (bitmask)
19697 {
19698 unsigned int bit = bitmask & (- bitmask);
19699
19700 bitmask &= ~ bit;
19701 switch (bit)
19702 {
19703 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19704 printf ("BTI");
19705 break;
19706
19707 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19708 printf ("PAC");
19709 break;
19710
19711 default:
19712 printf (_("<unknown: %x>"), bit);
19713 break;
19714 }
19715 if (bitmask)
19716 printf (", ");
19717 }
19718}
19719
6320fd00
L
19720static void
19721decode_1_needed (unsigned int bitmask)
19722{
19723 while (bitmask)
19724 {
19725 unsigned int bit = bitmask & (- bitmask);
19726
19727 bitmask &= ~ bit;
19728 switch (bit)
19729 {
19730 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19731 printf ("indirect external access");
19732 break;
19733 default:
19734 printf (_("<unknown: %x>"), bit);
19735 break;
19736 }
19737 if (bitmask)
19738 printf (", ");
19739 }
19740}
19741
9ef920e9 19742static void
dda8d76d 19743print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19744{
19745 unsigned char * ptr = (unsigned char *) pnote->descdata;
19746 unsigned char * ptr_end = ptr + pnote->descsz;
19747 unsigned int size = is_32bit_elf ? 4 : 8;
19748
19749 printf (_(" Properties: "));
19750
1fc87489 19751 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19752 {
19753 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19754 return;
19755 }
19756
6ab2c4ed 19757 while (ptr < ptr_end)
9ef920e9 19758 {
1fc87489 19759 unsigned int j;
6ab2c4ed
MC
19760 unsigned int type;
19761 unsigned int datasz;
19762
19763 if ((size_t) (ptr_end - ptr) < 8)
19764 {
19765 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19766 break;
19767 }
19768
19769 type = byte_get (ptr, 4);
19770 datasz = byte_get (ptr + 4, 4);
9ef920e9 19771
1fc87489 19772 ptr += 8;
9ef920e9 19773
6ab2c4ed 19774 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19775 {
1fc87489
L
19776 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19777 type, datasz);
9ef920e9 19778 break;
1fc87489 19779 }
9ef920e9 19780
1fc87489
L
19781 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19782 {
dda8d76d
NC
19783 if (filedata->file_header.e_machine == EM_X86_64
19784 || filedata->file_header.e_machine == EM_IAMCU
19785 || filedata->file_header.e_machine == EM_386)
1fc87489 19786 {
aa7bca9b
L
19787 unsigned int bitmask;
19788
19789 if (datasz == 4)
0a59decb 19790 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19791 else
19792 bitmask = 0;
19793
1fc87489
L
19794 switch (type)
19795 {
19796 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19797 if (datasz != 4)
aa7bca9b
L
19798 printf (_("x86 ISA used: <corrupt length: %#x> "),
19799 datasz);
1fc87489 19800 else
aa7bca9b
L
19801 {
19802 printf ("x86 ISA used: ");
19803 decode_x86_isa (bitmask);
19804 }
1fc87489 19805 goto next;
9ef920e9 19806
1fc87489 19807 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19808 if (datasz != 4)
aa7bca9b
L
19809 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19810 datasz);
1fc87489 19811 else
aa7bca9b
L
19812 {
19813 printf ("x86 ISA needed: ");
19814 decode_x86_isa (bitmask);
19815 }
1fc87489 19816 goto next;
9ef920e9 19817
ee2fdd6f 19818 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19819 if (datasz != 4)
aa7bca9b
L
19820 printf (_("x86 feature: <corrupt length: %#x> "),
19821 datasz);
ee2fdd6f 19822 else
aa7bca9b
L
19823 {
19824 printf ("x86 feature: ");
a9eafb08
L
19825 decode_x86_feature_1 (bitmask);
19826 }
19827 goto next;
19828
19829 case GNU_PROPERTY_X86_FEATURE_2_USED:
19830 if (datasz != 4)
19831 printf (_("x86 feature used: <corrupt length: %#x> "),
19832 datasz);
19833 else
19834 {
19835 printf ("x86 feature used: ");
19836 decode_x86_feature_2 (bitmask);
19837 }
19838 goto next;
19839
19840 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19841 if (datasz != 4)
19842 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19843 else
19844 {
19845 printf ("x86 feature needed: ");
19846 decode_x86_feature_2 (bitmask);
19847 }
19848 goto next;
19849
19850 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19851 if (datasz != 4)
19852 printf (_("x86 ISA used: <corrupt length: %#x> "),
19853 datasz);
19854 else
19855 {
19856 printf ("x86 ISA used: ");
19857 decode_x86_compat_isa (bitmask);
19858 }
19859 goto next;
19860
19861 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19862 if (datasz != 4)
19863 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19864 datasz);
19865 else
19866 {
19867 printf ("x86 ISA needed: ");
19868 decode_x86_compat_isa (bitmask);
aa7bca9b 19869 }
ee2fdd6f
L
19870 goto next;
19871
32930e4e
L
19872 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19873 if (datasz != 4)
19874 printf (_("x86 ISA used: <corrupt length: %#x> "),
19875 datasz);
19876 else
19877 {
19878 printf ("x86 ISA used: ");
19879 decode_x86_compat_2_isa (bitmask);
19880 }
19881 goto next;
19882
19883 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19884 if (datasz != 4)
19885 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19886 datasz);
19887 else
19888 {
19889 printf ("x86 ISA needed: ");
19890 decode_x86_compat_2_isa (bitmask);
19891 }
19892 goto next;
19893
1fc87489
L
19894 default:
19895 break;
19896 }
19897 }
cd702818
SD
19898 else if (filedata->file_header.e_machine == EM_AARCH64)
19899 {
19900 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19901 {
19902 printf ("AArch64 feature: ");
19903 if (datasz != 4)
19904 printf (_("<corrupt length: %#x> "), datasz);
19905 else
19906 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19907 goto next;
19908 }
19909 }
1fc87489
L
19910 }
19911 else
19912 {
19913 switch (type)
9ef920e9 19914 {
1fc87489
L
19915 case GNU_PROPERTY_STACK_SIZE:
19916 printf (_("stack size: "));
19917 if (datasz != size)
19918 printf (_("<corrupt length: %#x> "), datasz);
19919 else
19920 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19921 goto next;
19922
19923 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19924 printf ("no copy on protected ");
19925 if (datasz)
19926 printf (_("<corrupt length: %#x> "), datasz);
19927 goto next;
19928
19929 default:
5a767724
L
19930 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19931 && type <= GNU_PROPERTY_UINT32_AND_HI)
19932 || (type >= GNU_PROPERTY_UINT32_OR_LO
19933 && type <= GNU_PROPERTY_UINT32_OR_HI))
19934 {
6320fd00
L
19935 switch (type)
19936 {
19937 case GNU_PROPERTY_1_NEEDED:
19938 if (datasz != 4)
19939 printf (_("1_needed: <corrupt length: %#x> "),
19940 datasz);
19941 else
19942 {
19943 unsigned int bitmask = byte_get (ptr, 4);
19944 printf ("1_needed: ");
19945 decode_1_needed (bitmask);
19946 }
19947 goto next;
19948
19949 default:
19950 break;
19951 }
5a767724
L
19952 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19953 printf (_("UINT32_AND (%#x): "), type);
19954 else
19955 printf (_("UINT32_OR (%#x): "), type);
19956 if (datasz != 4)
19957 printf (_("<corrupt length: %#x> "), datasz);
19958 else
19959 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19960 goto next;
19961 }
9ef920e9
NC
19962 break;
19963 }
9ef920e9
NC
19964 }
19965
1fc87489
L
19966 if (type < GNU_PROPERTY_LOPROC)
19967 printf (_("<unknown type %#x data: "), type);
19968 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19969 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19970 else
19971 printf (_("<application-specific type %#x data: "), type);
19972 for (j = 0; j < datasz; ++j)
19973 printf ("%02x ", ptr[j] & 0xff);
19974 printf (">");
19975
dc1e8a47 19976 next:
9ef920e9 19977 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19978 if (ptr == ptr_end)
19979 break;
1fc87489 19980
6ab2c4ed
MC
19981 if (do_wide)
19982 printf (", ");
19983 else
19984 printf ("\n\t");
9ef920e9
NC
19985 }
19986
19987 printf ("\n");
19988}
19989
015dc7e1 19990static bool
dda8d76d 19991print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19992{
1449284b 19993 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19994 switch (pnote->type)
19995 {
19996 case NT_GNU_BUILD_ID:
19997 {
19998 unsigned long i;
19999
20000 printf (_(" Build ID: "));
20001 for (i = 0; i < pnote->descsz; ++i)
20002 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20003 printf ("\n");
664f90a3
TT
20004 }
20005 break;
20006
20007 case NT_GNU_ABI_TAG:
20008 {
20009 unsigned long os, major, minor, subminor;
20010 const char *osname;
20011
3102e897
NC
20012 /* PR 17531: file: 030-599401-0.004. */
20013 if (pnote->descsz < 16)
20014 {
20015 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20016 break;
20017 }
20018
664f90a3
TT
20019 os = byte_get ((unsigned char *) pnote->descdata, 4);
20020 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20021 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20022 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20023
20024 switch (os)
20025 {
20026 case GNU_ABI_TAG_LINUX:
20027 osname = "Linux";
20028 break;
20029 case GNU_ABI_TAG_HURD:
20030 osname = "Hurd";
20031 break;
20032 case GNU_ABI_TAG_SOLARIS:
20033 osname = "Solaris";
20034 break;
20035 case GNU_ABI_TAG_FREEBSD:
20036 osname = "FreeBSD";
20037 break;
20038 case GNU_ABI_TAG_NETBSD:
20039 osname = "NetBSD";
20040 break;
14ae95f2
RM
20041 case GNU_ABI_TAG_SYLLABLE:
20042 osname = "Syllable";
20043 break;
20044 case GNU_ABI_TAG_NACL:
20045 osname = "NaCl";
20046 break;
664f90a3
TT
20047 default:
20048 osname = "Unknown";
20049 break;
20050 }
20051
20052 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20053 major, minor, subminor);
20054 }
20055 break;
926c5385
CC
20056
20057 case NT_GNU_GOLD_VERSION:
20058 {
20059 unsigned long i;
20060
20061 printf (_(" Version: "));
20062 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20063 printf ("%c", pnote->descdata[i]);
20064 printf ("\n");
20065 }
20066 break;
1449284b
NC
20067
20068 case NT_GNU_HWCAP:
20069 {
20070 unsigned long num_entries, mask;
20071
20072 /* Hardware capabilities information. Word 0 is the number of entries.
20073 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20074 is a series of entries, where each entry is a single byte followed
20075 by a nul terminated string. The byte gives the bit number to test
20076 if enabled in the bitmask. */
20077 printf (_(" Hardware Capabilities: "));
20078 if (pnote->descsz < 8)
20079 {
32ec8896 20080 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20081 return false;
1449284b
NC
20082 }
20083 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20084 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20085 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20086 /* FIXME: Add code to display the entries... */
20087 }
20088 break;
20089
9ef920e9 20090 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20091 print_gnu_property_note (filedata, pnote);
9ef920e9 20092 break;
9abca702 20093
1449284b
NC
20094 default:
20095 /* Handle unrecognised types. An error message should have already been
20096 created by get_gnu_elf_note_type(), so all that we need to do is to
20097 display the data. */
20098 {
20099 unsigned long i;
20100
20101 printf (_(" Description data: "));
20102 for (i = 0; i < pnote->descsz; ++i)
20103 printf ("%02x ", pnote->descdata[i] & 0xff);
20104 printf ("\n");
20105 }
20106 break;
664f90a3
TT
20107 }
20108
015dc7e1 20109 return true;
664f90a3
TT
20110}
20111
685080f2
NC
20112static const char *
20113get_v850_elf_note_type (enum v850_notes n_type)
20114{
20115 static char buff[64];
20116
20117 switch (n_type)
20118 {
20119 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20120 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20121 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20122 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20123 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20124 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20125 default:
20126 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20127 return buff;
20128 }
20129}
20130
015dc7e1 20131static bool
685080f2
NC
20132print_v850_note (Elf_Internal_Note * pnote)
20133{
20134 unsigned int val;
20135
20136 if (pnote->descsz != 4)
015dc7e1 20137 return false;
32ec8896 20138
685080f2
NC
20139 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20140
20141 if (val == 0)
20142 {
20143 printf (_("not set\n"));
015dc7e1 20144 return true;
685080f2
NC
20145 }
20146
20147 switch (pnote->type)
20148 {
20149 case V850_NOTE_ALIGNMENT:
20150 switch (val)
20151 {
015dc7e1
AM
20152 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20153 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20154 }
20155 break;
14ae95f2 20156
685080f2
NC
20157 case V850_NOTE_DATA_SIZE:
20158 switch (val)
20159 {
015dc7e1
AM
20160 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20161 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20162 }
20163 break;
14ae95f2 20164
685080f2
NC
20165 case V850_NOTE_FPU_INFO:
20166 switch (val)
20167 {
015dc7e1
AM
20168 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20169 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20170 }
20171 break;
14ae95f2 20172
685080f2
NC
20173 case V850_NOTE_MMU_INFO:
20174 case V850_NOTE_CACHE_INFO:
20175 case V850_NOTE_SIMD_INFO:
20176 if (val == EF_RH850_SIMD)
20177 {
20178 printf (_("yes\n"));
015dc7e1 20179 return true;
685080f2
NC
20180 }
20181 break;
20182
20183 default:
20184 /* An 'unknown note type' message will already have been displayed. */
20185 break;
20186 }
20187
20188 printf (_("unknown value: %x\n"), val);
015dc7e1 20189 return false;
685080f2
NC
20190}
20191
015dc7e1 20192static bool
c6056a74
SF
20193process_netbsd_elf_note (Elf_Internal_Note * pnote)
20194{
20195 unsigned int version;
20196
20197 switch (pnote->type)
20198 {
20199 case NT_NETBSD_IDENT:
b966f55f
AM
20200 if (pnote->descsz < 1)
20201 break;
c6056a74
SF
20202 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20203 if ((version / 10000) % 100)
b966f55f 20204 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20205 version, version / 100000000, (version / 1000000) % 100,
20206 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20207 'A' + (version / 10000) % 26);
c6056a74
SF
20208 else
20209 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20210 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20211 (version / 100) % 100);
015dc7e1 20212 return true;
c6056a74
SF
20213
20214 case NT_NETBSD_MARCH:
9abca702 20215 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20216 pnote->descdata);
015dc7e1 20217 return true;
c6056a74 20218
9abca702 20219 case NT_NETBSD_PAX:
b966f55f
AM
20220 if (pnote->descsz < 1)
20221 break;
9abca702
CZ
20222 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20223 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20224 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20225 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20226 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20227 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20228 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20229 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20230 return true;
c6056a74 20231 }
b966f55f
AM
20232
20233 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20234 pnote->descsz, pnote->type);
015dc7e1 20235 return false;
c6056a74
SF
20236}
20237
f4ddf30f 20238static const char *
dda8d76d 20239get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20240{
f4ddf30f
JB
20241 switch (e_type)
20242 {
20243 case NT_FREEBSD_THRMISC:
20244 return _("NT_THRMISC (thrmisc structure)");
20245 case NT_FREEBSD_PROCSTAT_PROC:
20246 return _("NT_PROCSTAT_PROC (proc data)");
20247 case NT_FREEBSD_PROCSTAT_FILES:
20248 return _("NT_PROCSTAT_FILES (files data)");
20249 case NT_FREEBSD_PROCSTAT_VMMAP:
20250 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20251 case NT_FREEBSD_PROCSTAT_GROUPS:
20252 return _("NT_PROCSTAT_GROUPS (groups data)");
20253 case NT_FREEBSD_PROCSTAT_UMASK:
20254 return _("NT_PROCSTAT_UMASK (umask data)");
20255 case NT_FREEBSD_PROCSTAT_RLIMIT:
20256 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20257 case NT_FREEBSD_PROCSTAT_OSREL:
20258 return _("NT_PROCSTAT_OSREL (osreldate data)");
20259 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20260 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20261 case NT_FREEBSD_PROCSTAT_AUXV:
20262 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20263 case NT_FREEBSD_PTLWPINFO:
20264 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 20265 }
dda8d76d 20266 return get_note_type (filedata, e_type);
f4ddf30f
JB
20267}
20268
9437c45b 20269static const char *
dda8d76d 20270get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20271{
20272 static char buff[64];
20273
540e6170
CZ
20274 switch (e_type)
20275 {
20276 case NT_NETBSDCORE_PROCINFO:
20277 /* NetBSD core "procinfo" structure. */
20278 return _("NetBSD procinfo structure");
9437c45b 20279
540e6170
CZ
20280 case NT_NETBSDCORE_AUXV:
20281 return _("NetBSD ELF auxiliary vector data");
9437c45b 20282
06d949ec
KR
20283 case NT_NETBSDCORE_LWPSTATUS:
20284 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20285
540e6170 20286 default:
06d949ec 20287 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20288 defined for NetBSD core files. If the note type is less
20289 than the start of the machine-dependent note types, we don't
20290 understand it. */
20291
20292 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20293 {
20294 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20295 return buff;
20296 }
20297 break;
9437c45b
JT
20298 }
20299
dda8d76d 20300 switch (filedata->file_header.e_machine)
9437c45b
JT
20301 {
20302 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20303 and PT_GETFPREGS == mach+2. */
20304
20305 case EM_OLD_ALPHA:
20306 case EM_ALPHA:
20307 case EM_SPARC:
20308 case EM_SPARC32PLUS:
20309 case EM_SPARCV9:
20310 switch (e_type)
20311 {
2b692964 20312 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20313 return _("PT_GETREGS (reg structure)");
2b692964 20314 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20315 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20316 default:
20317 break;
20318 }
20319 break;
20320
c0d38b0e
CZ
20321 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20322 There's also old PT___GETREGS40 == mach + 1 for old reg
20323 structure which lacks GBR. */
20324 case EM_SH:
20325 switch (e_type)
20326 {
20327 case NT_NETBSDCORE_FIRSTMACH + 1:
20328 return _("PT___GETREGS40 (old reg structure)");
20329 case NT_NETBSDCORE_FIRSTMACH + 3:
20330 return _("PT_GETREGS (reg structure)");
20331 case NT_NETBSDCORE_FIRSTMACH + 5:
20332 return _("PT_GETFPREGS (fpreg structure)");
20333 default:
20334 break;
20335 }
20336 break;
20337
9437c45b
JT
20338 /* On all other arch's, PT_GETREGS == mach+1 and
20339 PT_GETFPREGS == mach+3. */
20340 default:
20341 switch (e_type)
20342 {
2b692964 20343 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20344 return _("PT_GETREGS (reg structure)");
2b692964 20345 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20346 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20347 default:
20348 break;
20349 }
20350 }
20351
9cf03b7e 20352 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20353 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20354 return buff;
20355}
20356
98ca73af
FC
20357static const char *
20358get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20359{
20360 switch (e_type)
20361 {
20362 case NT_OPENBSD_PROCINFO:
20363 return _("OpenBSD procinfo structure");
20364 case NT_OPENBSD_AUXV:
20365 return _("OpenBSD ELF auxiliary vector data");
20366 case NT_OPENBSD_REGS:
20367 return _("OpenBSD regular registers");
20368 case NT_OPENBSD_FPREGS:
20369 return _("OpenBSD floating point registers");
20370 case NT_OPENBSD_WCOOKIE:
20371 return _("OpenBSD window cookie");
20372 }
20373
20374 return get_note_type (filedata, e_type);
20375}
20376
70616151
TT
20377static const char *
20378get_stapsdt_note_type (unsigned e_type)
20379{
20380 static char buff[64];
20381
20382 switch (e_type)
20383 {
20384 case NT_STAPSDT:
20385 return _("NT_STAPSDT (SystemTap probe descriptors)");
20386
20387 default:
20388 break;
20389 }
20390
20391 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20392 return buff;
20393}
20394
015dc7e1 20395static bool
c6a9fc58
TT
20396print_stapsdt_note (Elf_Internal_Note *pnote)
20397{
3ca60c57
NC
20398 size_t len, maxlen;
20399 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20400 char *data = pnote->descdata;
20401 char *data_end = pnote->descdata + pnote->descsz;
20402 bfd_vma pc, base_addr, semaphore;
20403 char *provider, *probe, *arg_fmt;
20404
3ca60c57
NC
20405 if (pnote->descsz < (addr_size * 3))
20406 goto stapdt_note_too_small;
20407
c6a9fc58
TT
20408 pc = byte_get ((unsigned char *) data, addr_size);
20409 data += addr_size;
3ca60c57 20410
c6a9fc58
TT
20411 base_addr = byte_get ((unsigned char *) data, addr_size);
20412 data += addr_size;
3ca60c57 20413
c6a9fc58
TT
20414 semaphore = byte_get ((unsigned char *) data, addr_size);
20415 data += addr_size;
20416
3ca60c57
NC
20417 if (data >= data_end)
20418 goto stapdt_note_too_small;
20419 maxlen = data_end - data;
20420 len = strnlen (data, maxlen);
20421 if (len < maxlen)
20422 {
20423 provider = data;
20424 data += len + 1;
20425 }
20426 else
20427 goto stapdt_note_too_small;
20428
20429 if (data >= data_end)
20430 goto stapdt_note_too_small;
20431 maxlen = data_end - data;
20432 len = strnlen (data, maxlen);
20433 if (len < maxlen)
20434 {
20435 probe = data;
20436 data += len + 1;
20437 }
20438 else
20439 goto stapdt_note_too_small;
9abca702 20440
3ca60c57
NC
20441 if (data >= data_end)
20442 goto stapdt_note_too_small;
20443 maxlen = data_end - data;
20444 len = strnlen (data, maxlen);
20445 if (len < maxlen)
20446 {
20447 arg_fmt = data;
20448 data += len + 1;
20449 }
20450 else
20451 goto stapdt_note_too_small;
c6a9fc58
TT
20452
20453 printf (_(" Provider: %s\n"), provider);
20454 printf (_(" Name: %s\n"), probe);
20455 printf (_(" Location: "));
20456 print_vma (pc, FULL_HEX);
20457 printf (_(", Base: "));
20458 print_vma (base_addr, FULL_HEX);
20459 printf (_(", Semaphore: "));
20460 print_vma (semaphore, FULL_HEX);
9cf03b7e 20461 printf ("\n");
c6a9fc58
TT
20462 printf (_(" Arguments: %s\n"), arg_fmt);
20463
20464 return data == data_end;
3ca60c57
NC
20465
20466 stapdt_note_too_small:
20467 printf (_(" <corrupt - note is too small>\n"));
20468 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20469 return false;
c6a9fc58
TT
20470}
20471
e5382207
LB
20472static bool
20473print_fdo_note (Elf_Internal_Note * pnote)
20474{
20475 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20476 {
20477 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20478 return true;
20479 }
20480 return false;
20481}
20482
00e98fc7
TG
20483static const char *
20484get_ia64_vms_note_type (unsigned e_type)
20485{
20486 static char buff[64];
20487
20488 switch (e_type)
20489 {
20490 case NT_VMS_MHD:
20491 return _("NT_VMS_MHD (module header)");
20492 case NT_VMS_LNM:
20493 return _("NT_VMS_LNM (language name)");
20494 case NT_VMS_SRC:
20495 return _("NT_VMS_SRC (source files)");
20496 case NT_VMS_TITLE:
9cf03b7e 20497 return "NT_VMS_TITLE";
00e98fc7
TG
20498 case NT_VMS_EIDC:
20499 return _("NT_VMS_EIDC (consistency check)");
20500 case NT_VMS_FPMODE:
20501 return _("NT_VMS_FPMODE (FP mode)");
20502 case NT_VMS_LINKTIME:
9cf03b7e 20503 return "NT_VMS_LINKTIME";
00e98fc7
TG
20504 case NT_VMS_IMGNAM:
20505 return _("NT_VMS_IMGNAM (image name)");
20506 case NT_VMS_IMGID:
20507 return _("NT_VMS_IMGID (image id)");
20508 case NT_VMS_LINKID:
20509 return _("NT_VMS_LINKID (link id)");
20510 case NT_VMS_IMGBID:
20511 return _("NT_VMS_IMGBID (build id)");
20512 case NT_VMS_GSTNAM:
20513 return _("NT_VMS_GSTNAM (sym table name)");
20514 case NT_VMS_ORIG_DYN:
9cf03b7e 20515 return "NT_VMS_ORIG_DYN";
00e98fc7 20516 case NT_VMS_PATCHTIME:
9cf03b7e 20517 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20518 default:
20519 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20520 return buff;
20521 }
20522}
20523
015dc7e1 20524static bool
00e98fc7
TG
20525print_ia64_vms_note (Elf_Internal_Note * pnote)
20526{
8d18bf79
NC
20527 int maxlen = pnote->descsz;
20528
20529 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20530 goto desc_size_fail;
20531
00e98fc7
TG
20532 switch (pnote->type)
20533 {
20534 case NT_VMS_MHD:
8d18bf79
NC
20535 if (maxlen <= 36)
20536 goto desc_size_fail;
20537
20538 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20539
20540 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20541 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20542 if (l + 34 < maxlen)
20543 {
20544 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20545 if (l + 35 < maxlen)
20546 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20547 else
20548 printf (_(" Module version : <missing>\n"));
20549 }
00e98fc7 20550 else
8d18bf79
NC
20551 {
20552 printf (_(" Module name : <missing>\n"));
20553 printf (_(" Module version : <missing>\n"));
20554 }
00e98fc7 20555 break;
8d18bf79 20556
00e98fc7 20557 case NT_VMS_LNM:
8d18bf79 20558 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20559 break;
8d18bf79 20560
00e98fc7
TG
20561#ifdef BFD64
20562 case NT_VMS_FPMODE:
9cf03b7e 20563 printf (_(" Floating Point mode: "));
8d18bf79
NC
20564 if (maxlen < 8)
20565 goto desc_size_fail;
20566 /* FIXME: Generate an error if descsz > 8 ? */
20567
4a5cb34f 20568 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20569 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20570 break;
8d18bf79 20571
00e98fc7
TG
20572 case NT_VMS_LINKTIME:
20573 printf (_(" Link time: "));
8d18bf79
NC
20574 if (maxlen < 8)
20575 goto desc_size_fail;
20576 /* FIXME: Generate an error if descsz > 8 ? */
20577
00e98fc7 20578 print_vms_time
8d18bf79 20579 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20580 printf ("\n");
20581 break;
8d18bf79 20582
00e98fc7
TG
20583 case NT_VMS_PATCHTIME:
20584 printf (_(" Patch time: "));
8d18bf79
NC
20585 if (maxlen < 8)
20586 goto desc_size_fail;
20587 /* FIXME: Generate an error if descsz > 8 ? */
20588
00e98fc7 20589 print_vms_time
8d18bf79 20590 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20591 printf ("\n");
20592 break;
8d18bf79 20593
00e98fc7 20594 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20595 if (maxlen < 34)
20596 goto desc_size_fail;
20597
00e98fc7
TG
20598 printf (_(" Major id: %u, minor id: %u\n"),
20599 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20600 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20601 printf (_(" Last modified : "));
00e98fc7
TG
20602 print_vms_time
20603 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20604 printf (_("\n Link flags : "));
4a5cb34f 20605 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20606 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20607 printf (_(" Header flags: 0x%08x\n"),
948f632f 20608 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20609 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20610 break;
20611#endif
8d18bf79 20612
00e98fc7 20613 case NT_VMS_IMGNAM:
8d18bf79 20614 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20615 break;
8d18bf79 20616
00e98fc7 20617 case NT_VMS_GSTNAM:
8d18bf79 20618 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20619 break;
8d18bf79 20620
00e98fc7 20621 case NT_VMS_IMGID:
8d18bf79 20622 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20623 break;
8d18bf79 20624
00e98fc7 20625 case NT_VMS_LINKID:
8d18bf79 20626 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20627 break;
8d18bf79 20628
00e98fc7 20629 default:
015dc7e1 20630 return false;
00e98fc7 20631 }
8d18bf79 20632
015dc7e1 20633 return true;
8d18bf79
NC
20634
20635 desc_size_fail:
20636 printf (_(" <corrupt - data size is too small>\n"));
20637 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20638 return false;
00e98fc7
TG
20639}
20640
fd486f32
AM
20641struct build_attr_cache {
20642 Filedata *filedata;
20643 char *strtab;
20644 unsigned long strtablen;
20645 Elf_Internal_Sym *symtab;
20646 unsigned long nsyms;
20647} ba_cache;
20648
6f156d7a
NC
20649/* Find the symbol associated with a build attribute that is attached
20650 to address OFFSET. If PNAME is non-NULL then store the name of
20651 the symbol (if found) in the provided pointer, Returns NULL if a
20652 symbol could not be found. */
c799a79d 20653
6f156d7a 20654static Elf_Internal_Sym *
015dc7e1
AM
20655get_symbol_for_build_attribute (Filedata *filedata,
20656 unsigned long offset,
20657 bool is_open_attr,
20658 const char **pname)
9ef920e9 20659{
fd486f32
AM
20660 Elf_Internal_Sym *saved_sym = NULL;
20661 Elf_Internal_Sym *sym;
9ef920e9 20662
dda8d76d 20663 if (filedata->section_headers != NULL
fd486f32 20664 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20665 {
c799a79d 20666 Elf_Internal_Shdr * symsec;
9ef920e9 20667
fd486f32
AM
20668 free (ba_cache.strtab);
20669 ba_cache.strtab = NULL;
20670 free (ba_cache.symtab);
20671 ba_cache.symtab = NULL;
20672
c799a79d 20673 /* Load the symbol and string sections. */
dda8d76d
NC
20674 for (symsec = filedata->section_headers;
20675 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20676 symsec ++)
9ef920e9 20677 {
28d13567
AM
20678 if (symsec->sh_type == SHT_SYMTAB
20679 && get_symtab (filedata, symsec,
20680 &ba_cache.symtab, &ba_cache.nsyms,
20681 &ba_cache.strtab, &ba_cache.strtablen))
20682 break;
9ef920e9 20683 }
fd486f32 20684 ba_cache.filedata = filedata;
9ef920e9
NC
20685 }
20686
fd486f32 20687 if (ba_cache.symtab == NULL)
6f156d7a 20688 return NULL;
9ef920e9 20689
c799a79d 20690 /* Find a symbol whose value matches offset. */
fd486f32 20691 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20692 if (sym->st_value == offset)
20693 {
fd486f32 20694 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20695 /* Huh ? This should not happen. */
20696 continue;
9ef920e9 20697
fd486f32 20698 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20699 continue;
9ef920e9 20700
9b9b1092 20701 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20702 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20703 if (ba_cache.strtab[sym->st_name] == '$'
20704 && ba_cache.strtab[sym->st_name + 1] != 0
20705 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20706 continue;
20707
c799a79d
NC
20708 if (is_open_attr)
20709 {
20710 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20711 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20712 FUNC symbols entirely. */
20713 switch (ELF_ST_TYPE (sym->st_info))
20714 {
c799a79d 20715 case STT_OBJECT:
6f156d7a 20716 case STT_FILE:
c799a79d 20717 saved_sym = sym;
6f156d7a
NC
20718 if (sym->st_size)
20719 {
20720 /* If the symbol has a size associated
20721 with it then we can stop searching. */
fd486f32 20722 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20723 }
c799a79d 20724 continue;
9ef920e9 20725
c799a79d
NC
20726 case STT_FUNC:
20727 /* Ignore function symbols. */
20728 continue;
20729
20730 default:
20731 break;
20732 }
20733
20734 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20735 {
c799a79d
NC
20736 case STB_GLOBAL:
20737 if (saved_sym == NULL
20738 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20739 saved_sym = sym;
20740 break;
c871dade 20741
c799a79d
NC
20742 case STB_LOCAL:
20743 if (saved_sym == NULL)
20744 saved_sym = sym;
20745 break;
20746
20747 default:
9ef920e9
NC
20748 break;
20749 }
20750 }
c799a79d
NC
20751 else
20752 {
20753 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20754 continue;
20755
20756 saved_sym = sym;
20757 break;
20758 }
20759 }
20760
6f156d7a 20761 if (saved_sym && pname)
fd486f32 20762 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20763
20764 return saved_sym;
c799a79d
NC
20765}
20766
d20e98ab
NC
20767/* Returns true iff addr1 and addr2 are in the same section. */
20768
015dc7e1 20769static bool
d20e98ab
NC
20770same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20771{
20772 Elf_Internal_Shdr * a1;
20773 Elf_Internal_Shdr * a2;
20774
20775 a1 = find_section_by_address (filedata, addr1);
20776 a2 = find_section_by_address (filedata, addr2);
9abca702 20777
d20e98ab
NC
20778 return a1 == a2 && a1 != NULL;
20779}
20780
015dc7e1 20781static bool
dda8d76d
NC
20782print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20783 Filedata * filedata)
c799a79d 20784{
015dc7e1
AM
20785 static unsigned long global_offset = 0;
20786 static unsigned long global_end = 0;
20787 static unsigned long func_offset = 0;
20788 static unsigned long func_end = 0;
c871dade 20789
015dc7e1
AM
20790 Elf_Internal_Sym *sym;
20791 const char *name;
20792 unsigned long start;
20793 unsigned long end;
20794 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20795
20796 switch (pnote->descsz)
c799a79d 20797 {
6f156d7a
NC
20798 case 0:
20799 /* A zero-length description means that the range of
20800 the previous note of the same type should be used. */
c799a79d 20801 if (is_open_attr)
c871dade 20802 {
6f156d7a
NC
20803 if (global_end > global_offset)
20804 printf (_(" Applies to region from %#lx to %#lx\n"),
20805 global_offset, global_end);
20806 else
20807 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20808 }
20809 else
20810 {
6f156d7a
NC
20811 if (func_end > func_offset)
20812 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20813 else
20814 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20815 }
015dc7e1 20816 return true;
9ef920e9 20817
6f156d7a
NC
20818 case 4:
20819 start = byte_get ((unsigned char *) pnote->descdata, 4);
20820 end = 0;
20821 break;
20822
20823 case 8:
c74147bb
NC
20824 start = byte_get ((unsigned char *) pnote->descdata, 4);
20825 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20826 break;
20827
20828 case 16:
20829 start = byte_get ((unsigned char *) pnote->descdata, 8);
20830 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20831 break;
9abca702 20832
6f156d7a 20833 default:
c799a79d
NC
20834 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20835 printf (_(" <invalid descsz>"));
015dc7e1 20836 return false;
c799a79d
NC
20837 }
20838
6f156d7a
NC
20839 name = NULL;
20840 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20841 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20842 in order to avoid them being confused with the start address of the
20843 first function in the file... */
20844 if (sym == NULL && is_open_attr)
20845 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20846 & name);
6f156d7a
NC
20847
20848 if (end == 0 && sym != NULL && sym->st_size > 0)
20849 end = start + sym->st_size;
c799a79d
NC
20850
20851 if (is_open_attr)
20852 {
d20e98ab
NC
20853 /* FIXME: Need to properly allow for section alignment.
20854 16 is just the alignment used on x86_64. */
20855 if (global_end > 0
20856 && start > BFD_ALIGN (global_end, 16)
20857 /* Build notes are not guaranteed to be organised in order of
20858 increasing address, but we should find the all of the notes
20859 for one section in the same place. */
20860 && same_section (filedata, start, global_end))
6f156d7a
NC
20861 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20862 global_end + 1, start - 1);
20863
20864 printf (_(" Applies to region from %#lx"), start);
20865 global_offset = start;
20866
20867 if (end)
20868 {
20869 printf (_(" to %#lx"), end);
20870 global_end = end;
20871 }
c799a79d
NC
20872 }
20873 else
20874 {
6f156d7a
NC
20875 printf (_(" Applies to region from %#lx"), start);
20876 func_offset = start;
20877
20878 if (end)
20879 {
20880 printf (_(" to %#lx"), end);
20881 func_end = end;
20882 }
c799a79d
NC
20883 }
20884
6f156d7a
NC
20885 if (sym && name)
20886 printf (_(" (%s)"), name);
20887
20888 printf ("\n");
015dc7e1 20889 return true;
9ef920e9
NC
20890}
20891
015dc7e1 20892static bool
9ef920e9
NC
20893print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20894{
1d15e434
NC
20895 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20896 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20897 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20898 char name_type;
20899 char name_attribute;
1d15e434 20900 const char * expected_types;
9ef920e9
NC
20901 const char * name = pnote->namedata;
20902 const char * text;
88305e1b 20903 signed int left;
9ef920e9
NC
20904
20905 if (name == NULL || pnote->namesz < 2)
20906 {
20907 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20908 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20909 return false;
9ef920e9
NC
20910 }
20911
6f156d7a
NC
20912 if (do_wide)
20913 left = 28;
20914 else
20915 left = 20;
88305e1b
NC
20916
20917 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20918 if (name[0] == 'G' && name[1] == 'A')
20919 {
6f156d7a
NC
20920 if (pnote->namesz < 4)
20921 {
20922 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20923 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20924 return false;
6f156d7a
NC
20925 }
20926
88305e1b
NC
20927 printf ("GA");
20928 name += 2;
20929 left -= 2;
20930 }
20931
9ef920e9
NC
20932 switch ((name_type = * name))
20933 {
20934 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20935 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20936 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20937 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20938 printf ("%c", * name);
88305e1b 20939 left --;
9ef920e9
NC
20940 break;
20941 default:
20942 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20943 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20944 return false;
9ef920e9
NC
20945 }
20946
9ef920e9
NC
20947 ++ name;
20948 text = NULL;
20949
20950 switch ((name_attribute = * name))
20951 {
20952 case GNU_BUILD_ATTRIBUTE_VERSION:
20953 text = _("<version>");
1d15e434 20954 expected_types = string_expected;
9ef920e9
NC
20955 ++ name;
20956 break;
20957 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20958 text = _("<stack prot>");
75d7d298 20959 expected_types = "!+*";
9ef920e9
NC
20960 ++ name;
20961 break;
20962 case GNU_BUILD_ATTRIBUTE_RELRO:
20963 text = _("<relro>");
1d15e434 20964 expected_types = bool_expected;
9ef920e9
NC
20965 ++ name;
20966 break;
20967 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20968 text = _("<stack size>");
1d15e434 20969 expected_types = number_expected;
9ef920e9
NC
20970 ++ name;
20971 break;
20972 case GNU_BUILD_ATTRIBUTE_TOOL:
20973 text = _("<tool>");
1d15e434 20974 expected_types = string_expected;
9ef920e9
NC
20975 ++ name;
20976 break;
20977 case GNU_BUILD_ATTRIBUTE_ABI:
20978 text = _("<ABI>");
20979 expected_types = "$*";
20980 ++ name;
20981 break;
20982 case GNU_BUILD_ATTRIBUTE_PIC:
20983 text = _("<PIC>");
1d15e434 20984 expected_types = number_expected;
9ef920e9
NC
20985 ++ name;
20986 break;
a8be5506
NC
20987 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20988 text = _("<short enum>");
1d15e434 20989 expected_types = bool_expected;
a8be5506
NC
20990 ++ name;
20991 break;
9ef920e9
NC
20992 default:
20993 if (ISPRINT (* name))
20994 {
20995 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20996
20997 if (len > left && ! do_wide)
20998 len = left;
75d7d298 20999 printf ("%.*s:", len, name);
9ef920e9 21000 left -= len;
0dd6ae21 21001 name += len;
9ef920e9
NC
21002 }
21003 else
21004 {
3e6b6445 21005 static char tmpbuf [128];
88305e1b 21006
3e6b6445
NC
21007 error (_("unrecognised byte in name field: %d\n"), * name);
21008 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21009 text = tmpbuf;
21010 name ++;
9ef920e9
NC
21011 }
21012 expected_types = "*$!+";
21013 break;
21014 }
21015
21016 if (text)
88305e1b 21017 left -= printf ("%s", text);
9ef920e9
NC
21018
21019 if (strchr (expected_types, name_type) == NULL)
75d7d298 21020 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21021
21022 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21023 {
21024 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21025 (unsigned long) pnote->namesz,
21026 (long) (name - pnote->namedata));
015dc7e1 21027 return false;
9ef920e9
NC
21028 }
21029
21030 if (left < 1 && ! do_wide)
015dc7e1 21031 return true;
9ef920e9
NC
21032
21033 switch (name_type)
21034 {
21035 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21036 {
b06b2c92 21037 unsigned int bytes;
ddef72cd
NC
21038 unsigned long long val = 0;
21039 unsigned int shift = 0;
21040 char * decoded = NULL;
21041
b06b2c92
NC
21042 bytes = pnote->namesz - (name - pnote->namedata);
21043 if (bytes > 0)
21044 /* The -1 is because the name field is always 0 terminated, and we
21045 want to be able to ensure that the shift in the while loop below
21046 will not overflow. */
21047 -- bytes;
21048
ddef72cd
NC
21049 if (bytes > sizeof (val))
21050 {
3e6b6445
NC
21051 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21052 bytes);
21053 bytes = sizeof (val);
ddef72cd 21054 }
3e6b6445
NC
21055 /* We do not bother to warn if bytes == 0 as this can
21056 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21057
21058 while (bytes --)
21059 {
54b8331d 21060 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21061
21062 val |= byte << shift;
9ef920e9
NC
21063 shift += 8;
21064 }
21065
75d7d298 21066 switch (name_attribute)
9ef920e9 21067 {
75d7d298 21068 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21069 switch (val)
21070 {
75d7d298
NC
21071 case 0: decoded = "static"; break;
21072 case 1: decoded = "pic"; break;
21073 case 2: decoded = "PIC"; break;
21074 case 3: decoded = "pie"; break;
21075 case 4: decoded = "PIE"; break;
21076 default: break;
9ef920e9 21077 }
75d7d298
NC
21078 break;
21079 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21080 switch (val)
9ef920e9 21081 {
75d7d298
NC
21082 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21083 case 0: decoded = "off"; break;
21084 case 1: decoded = "on"; break;
21085 case 2: decoded = "all"; break;
21086 case 3: decoded = "strong"; break;
21087 case 4: decoded = "explicit"; break;
21088 default: break;
9ef920e9 21089 }
75d7d298
NC
21090 break;
21091 default:
21092 break;
9ef920e9
NC
21093 }
21094
75d7d298 21095 if (decoded != NULL)
3e6b6445
NC
21096 {
21097 print_symbol (-left, decoded);
21098 left = 0;
21099 }
21100 else if (val == 0)
21101 {
21102 printf ("0x0");
21103 left -= 3;
21104 }
9ef920e9 21105 else
75d7d298
NC
21106 {
21107 if (do_wide)
ddef72cd 21108 left -= printf ("0x%llx", val);
75d7d298 21109 else
ddef72cd 21110 left -= printf ("0x%-.*llx", left, val);
75d7d298 21111 }
9ef920e9
NC
21112 }
21113 break;
21114 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21115 left -= print_symbol (- left, name);
21116 break;
21117 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21118 left -= print_symbol (- left, "true");
21119 break;
21120 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21121 left -= print_symbol (- left, "false");
21122 break;
21123 }
21124
21125 if (do_wide && left > 0)
21126 printf ("%-*s", left, " ");
9abca702 21127
015dc7e1 21128 return true;
9ef920e9
NC
21129}
21130
6d118b09
NC
21131/* Note that by the ELF standard, the name field is already null byte
21132 terminated, and namesz includes the terminating null byte.
21133 I.E. the value of namesz for the name "FSF" is 4.
21134
e3c8793a 21135 If the value of namesz is zero, there is no name present. */
9ef920e9 21136
015dc7e1 21137static bool
9ef920e9 21138process_note (Elf_Internal_Note * pnote,
dda8d76d 21139 Filedata * filedata)
779fe533 21140{
2cf0635d
NC
21141 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21142 const char * nt;
9437c45b
JT
21143
21144 if (pnote->namesz == 0)
1ec5cd37
NC
21145 /* If there is no note name, then use the default set of
21146 note type strings. */
dda8d76d 21147 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21148
24d127aa 21149 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21150 /* GNU-specific object file notes. */
21151 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21152
24d127aa 21153 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21154 /* FreeBSD-specific core file notes. */
dda8d76d 21155 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21156
24d127aa 21157 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21158 /* NetBSD-specific core file notes. */
dda8d76d 21159 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21160
24d127aa 21161 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21162 /* NetBSD-specific core file notes. */
21163 return process_netbsd_elf_note (pnote);
21164
24d127aa 21165 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21166 /* NetBSD-specific core file notes. */
21167 return process_netbsd_elf_note (pnote);
21168
98ca73af
FC
21169 else if (startswith (pnote->namedata, "OpenBSD"))
21170 /* OpenBSD-specific core file notes. */
21171 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21172
e9b095a5 21173 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21174 {
21175 /* SPU-specific core file notes. */
21176 nt = pnote->namedata + 4;
21177 name = "SPU";
21178 }
21179
24d127aa 21180 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21181 /* VMS/ia64-specific file notes. */
21182 nt = get_ia64_vms_note_type (pnote->type);
21183
24d127aa 21184 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21185 nt = get_stapsdt_note_type (pnote->type);
21186
9437c45b 21187 else
1ec5cd37
NC
21188 /* Don't recognize this note name; just use the default set of
21189 note type strings. */
dda8d76d 21190 nt = get_note_type (filedata, pnote->type);
9437c45b 21191
1449284b 21192 printf (" ");
9ef920e9 21193
24d127aa 21194 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21195 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21196 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21197 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21198 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21199 print_gnu_build_attribute_name (pnote);
21200 else
21201 print_symbol (-20, name);
21202
21203 if (do_wide)
21204 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21205 else
21206 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21207
24d127aa 21208 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21209 return print_ia64_vms_note (pnote);
24d127aa 21210 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21211 return print_gnu_note (filedata, pnote);
24d127aa 21212 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21213 return print_stapsdt_note (pnote);
24d127aa 21214 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21215 return print_core_note (pnote);
e5382207
LB
21216 else if (startswith (pnote->namedata, "FDO"))
21217 return print_fdo_note (pnote);
24d127aa 21218 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21219 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21220 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21221 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21222 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21223 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 21224
9ef920e9 21225 if (pnote->descsz)
1449284b
NC
21226 {
21227 unsigned long i;
21228
21229 printf (_(" description data: "));
21230 for (i = 0; i < pnote->descsz; i++)
178d8719 21231 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
21232 if (!do_wide)
21233 printf ("\n");
1449284b
NC
21234 }
21235
9ef920e9
NC
21236 if (do_wide)
21237 printf ("\n");
21238
015dc7e1 21239 return true;
1449284b 21240}
6d118b09 21241
015dc7e1 21242static bool
dda8d76d
NC
21243process_notes_at (Filedata * filedata,
21244 Elf_Internal_Shdr * section,
21245 bfd_vma offset,
82ed9683
L
21246 bfd_vma length,
21247 bfd_vma align)
779fe533 21248{
015dc7e1
AM
21249 Elf_External_Note *pnotes;
21250 Elf_External_Note *external;
21251 char *end;
21252 bool res = true;
103f02d3 21253
779fe533 21254 if (length <= 0)
015dc7e1 21255 return false;
103f02d3 21256
1449284b
NC
21257 if (section)
21258 {
dda8d76d 21259 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21260 if (pnotes)
32ec8896 21261 {
dda8d76d 21262 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21263 {
21264 free (pnotes);
015dc7e1 21265 return false;
f761cb13 21266 }
32ec8896 21267 }
1449284b
NC
21268 }
21269 else
82ed9683 21270 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21271 _("notes"));
4dff97b2 21272
dd24e3da 21273 if (pnotes == NULL)
015dc7e1 21274 return false;
779fe533 21275
103f02d3 21276 external = pnotes;
103f02d3 21277
ca0e11aa
NC
21278 if (filedata->is_separate)
21279 printf (_("In linked file '%s': "), filedata->file_name);
21280 else
21281 printf ("\n");
1449284b 21282 if (section)
ca0e11aa 21283 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21284 else
ca0e11aa 21285 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21286 (unsigned long) offset, (unsigned long) length);
21287
82ed9683
L
21288 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21289 specifies that notes should be aligned to 4 bytes in 32-bit
21290 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21291 we also support 4 byte alignment in 64-bit objects. If section
21292 alignment is less than 4, we treate alignment as 4 bytes. */
21293 if (align < 4)
21294 align = 4;
21295 else if (align != 4 && align != 8)
21296 {
21297 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21298 (long) align);
a788aedd 21299 free (pnotes);
015dc7e1 21300 return false;
82ed9683
L
21301 }
21302
dbe15e4e 21303 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21304
c8071705
NC
21305 end = (char *) pnotes + length;
21306 while ((char *) external < end)
779fe533 21307 {
b34976b6 21308 Elf_Internal_Note inote;
15b42fb0 21309 size_t min_notesz;
4dff97b2 21310 char * next;
2cf0635d 21311 char * temp = NULL;
c8071705 21312 size_t data_remaining = end - (char *) external;
6d118b09 21313
dda8d76d 21314 if (!is_ia64_vms (filedata))
15b42fb0 21315 {
9dd3a467
NC
21316 /* PR binutils/15191
21317 Make sure that there is enough data to read. */
15b42fb0
AM
21318 min_notesz = offsetof (Elf_External_Note, name);
21319 if (data_remaining < min_notesz)
9dd3a467 21320 {
d3a49aa8
AM
21321 warn (ngettext ("Corrupt note: only %ld byte remains, "
21322 "not enough for a full note\n",
21323 "Corrupt note: only %ld bytes remain, "
21324 "not enough for a full note\n",
21325 data_remaining),
21326 (long) data_remaining);
9dd3a467
NC
21327 break;
21328 }
5396a86e
AM
21329 data_remaining -= min_notesz;
21330
15b42fb0
AM
21331 inote.type = BYTE_GET (external->type);
21332 inote.namesz = BYTE_GET (external->namesz);
21333 inote.namedata = external->name;
21334 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21335 inote.descdata = ((char *) external
4dff97b2 21336 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21337 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21338 next = ((char *) external
4dff97b2 21339 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21340 }
00e98fc7 21341 else
15b42fb0
AM
21342 {
21343 Elf64_External_VMS_Note *vms_external;
00e98fc7 21344
9dd3a467
NC
21345 /* PR binutils/15191
21346 Make sure that there is enough data to read. */
15b42fb0
AM
21347 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21348 if (data_remaining < min_notesz)
9dd3a467 21349 {
d3a49aa8
AM
21350 warn (ngettext ("Corrupt note: only %ld byte remains, "
21351 "not enough for a full note\n",
21352 "Corrupt note: only %ld bytes remain, "
21353 "not enough for a full note\n",
21354 data_remaining),
21355 (long) data_remaining);
9dd3a467
NC
21356 break;
21357 }
5396a86e 21358 data_remaining -= min_notesz;
3e55a963 21359
15b42fb0
AM
21360 vms_external = (Elf64_External_VMS_Note *) external;
21361 inote.type = BYTE_GET (vms_external->type);
21362 inote.namesz = BYTE_GET (vms_external->namesz);
21363 inote.namedata = vms_external->name;
21364 inote.descsz = BYTE_GET (vms_external->descsz);
21365 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21366 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21367 next = inote.descdata + align_power (inote.descsz, 3);
21368 }
21369
5396a86e
AM
21370 /* PR 17531: file: 3443835e. */
21371 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21372 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21373 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21374 || (size_t) (next - inote.descdata) < inote.descsz
21375 || ((size_t) (next - inote.descdata)
21376 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21377 {
15b42fb0 21378 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21379 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21380 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21381 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21382 break;
21383 }
21384
15b42fb0 21385 external = (Elf_External_Note *) next;
dd24e3da 21386
6d118b09
NC
21387 /* Verify that name is null terminated. It appears that at least
21388 one version of Linux (RedHat 6.0) generates corefiles that don't
21389 comply with the ELF spec by failing to include the null byte in
21390 namesz. */
18344509 21391 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21392 {
5396a86e 21393 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21394 {
5396a86e
AM
21395 temp = (char *) malloc (inote.namesz + 1);
21396 if (temp == NULL)
21397 {
21398 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21399 res = false;
5396a86e
AM
21400 break;
21401 }
76da6bbe 21402
5396a86e
AM
21403 memcpy (temp, inote.namedata, inote.namesz);
21404 inote.namedata = temp;
21405 }
21406 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21407 }
21408
dda8d76d 21409 if (! process_note (& inote, filedata))
015dc7e1 21410 res = false;
103f02d3 21411
9db70fc3
AM
21412 free (temp);
21413 temp = NULL;
779fe533
NC
21414 }
21415
21416 free (pnotes);
103f02d3 21417
779fe533
NC
21418 return res;
21419}
21420
015dc7e1 21421static bool
dda8d76d 21422process_corefile_note_segments (Filedata * filedata)
779fe533 21423{
015dc7e1 21424 Elf_Internal_Phdr *segment;
b34976b6 21425 unsigned int i;
015dc7e1 21426 bool res = true;
103f02d3 21427
dda8d76d 21428 if (! get_program_headers (filedata))
015dc7e1 21429 return true;
103f02d3 21430
dda8d76d
NC
21431 for (i = 0, segment = filedata->program_headers;
21432 i < filedata->file_header.e_phnum;
b34976b6 21433 i++, segment++)
779fe533
NC
21434 {
21435 if (segment->p_type == PT_NOTE)
dda8d76d 21436 if (! process_notes_at (filedata, NULL,
32ec8896 21437 (bfd_vma) segment->p_offset,
82ed9683
L
21438 (bfd_vma) segment->p_filesz,
21439 (bfd_vma) segment->p_align))
015dc7e1 21440 res = false;
779fe533 21441 }
103f02d3 21442
779fe533
NC
21443 return res;
21444}
21445
015dc7e1 21446static bool
dda8d76d 21447process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21448{
21449 Elf_External_Note * pnotes;
21450 Elf_External_Note * external;
c8071705 21451 char * end;
015dc7e1 21452 bool res = true;
685080f2
NC
21453
21454 if (length <= 0)
015dc7e1 21455 return false;
685080f2 21456
dda8d76d 21457 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21458 _("v850 notes"));
21459 if (pnotes == NULL)
015dc7e1 21460 return false;
685080f2
NC
21461
21462 external = pnotes;
c8071705 21463 end = (char*) pnotes + length;
685080f2
NC
21464
21465 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21466 (unsigned long) offset, (unsigned long) length);
21467
c8071705 21468 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21469 {
21470 Elf_External_Note * next;
21471 Elf_Internal_Note inote;
21472
21473 inote.type = BYTE_GET (external->type);
21474 inote.namesz = BYTE_GET (external->namesz);
21475 inote.namedata = external->name;
21476 inote.descsz = BYTE_GET (external->descsz);
21477 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21478 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21479
c8071705
NC
21480 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21481 {
21482 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21483 inote.descdata = inote.namedata;
21484 inote.namesz = 0;
21485 }
21486
685080f2
NC
21487 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21488
c8071705 21489 if ( ((char *) next > end)
685080f2
NC
21490 || ((char *) next < (char *) pnotes))
21491 {
21492 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21493 (unsigned long) ((char *) external - (char *) pnotes));
21494 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21495 inote.type, inote.namesz, inote.descsz);
21496 break;
21497 }
21498
21499 external = next;
21500
21501 /* Prevent out-of-bounds indexing. */
c8071705 21502 if ( inote.namedata + inote.namesz > end
685080f2
NC
21503 || inote.namedata + inote.namesz < inote.namedata)
21504 {
21505 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21506 (unsigned long) ((char *) external - (char *) pnotes));
21507 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21508 inote.type, inote.namesz, inote.descsz);
21509 break;
21510 }
21511
21512 printf (" %s: ", get_v850_elf_note_type (inote.type));
21513
21514 if (! print_v850_note (& inote))
21515 {
015dc7e1 21516 res = false;
685080f2
NC
21517 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21518 inote.namesz, inote.descsz);
21519 }
21520 }
21521
21522 free (pnotes);
21523
21524 return res;
21525}
21526
015dc7e1 21527static bool
dda8d76d 21528process_note_sections (Filedata * filedata)
1ec5cd37 21529{
015dc7e1 21530 Elf_Internal_Shdr *section;
1ec5cd37 21531 unsigned long i;
32ec8896 21532 unsigned int n = 0;
015dc7e1 21533 bool res = true;
1ec5cd37 21534
dda8d76d
NC
21535 for (i = 0, section = filedata->section_headers;
21536 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21537 i++, section++)
685080f2
NC
21538 {
21539 if (section->sh_type == SHT_NOTE)
21540 {
dda8d76d 21541 if (! process_notes_at (filedata, section,
32ec8896 21542 (bfd_vma) section->sh_offset,
82ed9683
L
21543 (bfd_vma) section->sh_size,
21544 (bfd_vma) section->sh_addralign))
015dc7e1 21545 res = false;
685080f2
NC
21546 n++;
21547 }
21548
dda8d76d
NC
21549 if (( filedata->file_header.e_machine == EM_V800
21550 || filedata->file_header.e_machine == EM_V850
21551 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21552 && section->sh_type == SHT_RENESAS_INFO)
21553 {
dda8d76d 21554 if (! process_v850_notes (filedata,
32ec8896
NC
21555 (bfd_vma) section->sh_offset,
21556 (bfd_vma) section->sh_size))
015dc7e1 21557 res = false;
685080f2
NC
21558 n++;
21559 }
21560 }
df565f32
NC
21561
21562 if (n == 0)
21563 /* Try processing NOTE segments instead. */
dda8d76d 21564 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21565
21566 return res;
21567}
21568
015dc7e1 21569static bool
dda8d76d 21570process_notes (Filedata * filedata)
779fe533
NC
21571{
21572 /* If we have not been asked to display the notes then do nothing. */
21573 if (! do_notes)
015dc7e1 21574 return true;
103f02d3 21575
dda8d76d
NC
21576 if (filedata->file_header.e_type != ET_CORE)
21577 return process_note_sections (filedata);
103f02d3 21578
779fe533 21579 /* No program headers means no NOTE segment. */
dda8d76d
NC
21580 if (filedata->file_header.e_phnum > 0)
21581 return process_corefile_note_segments (filedata);
779fe533 21582
ca0e11aa
NC
21583 if (filedata->is_separate)
21584 printf (_("No notes found in linked file '%s'.\n"),
21585 filedata->file_name);
21586 else
21587 printf (_("No notes found file.\n"));
21588
015dc7e1 21589 return true;
779fe533
NC
21590}
21591
60abdbed
NC
21592static unsigned char *
21593display_public_gnu_attributes (unsigned char * start,
21594 const unsigned char * const end)
21595{
21596 printf (_(" Unknown GNU attribute: %s\n"), start);
21597
21598 start += strnlen ((char *) start, end - start);
21599 display_raw_attribute (start, end);
21600
21601 return (unsigned char *) end;
21602}
21603
21604static unsigned char *
21605display_generic_attribute (unsigned char * start,
21606 unsigned int tag,
21607 const unsigned char * const end)
21608{
21609 if (tag == 0)
21610 return (unsigned char *) end;
21611
21612 return display_tag_value (tag, start, end);
21613}
21614
015dc7e1 21615static bool
dda8d76d 21616process_arch_specific (Filedata * filedata)
252b5132 21617{
a952a375 21618 if (! do_arch)
015dc7e1 21619 return true;
a952a375 21620
dda8d76d 21621 switch (filedata->file_header.e_machine)
252b5132 21622 {
53a346d8
CZ
21623 case EM_ARC:
21624 case EM_ARC_COMPACT:
21625 case EM_ARC_COMPACT2:
dda8d76d 21626 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21627 display_arc_attribute,
21628 display_generic_attribute);
11c1ff18 21629 case EM_ARM:
dda8d76d 21630 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21631 display_arm_attribute,
21632 display_generic_attribute);
21633
252b5132 21634 case EM_MIPS:
4fe85591 21635 case EM_MIPS_RS3_LE:
dda8d76d 21636 return process_mips_specific (filedata);
60abdbed
NC
21637
21638 case EM_MSP430:
dda8d76d 21639 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21640 display_msp430_attribute,
c0ea7c52 21641 display_msp430_gnu_attribute);
60abdbed 21642
2dc8dd17
JW
21643 case EM_RISCV:
21644 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21645 display_riscv_attribute,
21646 display_generic_attribute);
21647
35c08157 21648 case EM_NDS32:
dda8d76d 21649 return process_nds32_specific (filedata);
60abdbed 21650
85f7484a
PB
21651 case EM_68K:
21652 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21653 display_m68k_gnu_attribute);
21654
34c8bcba 21655 case EM_PPC:
b82317dd 21656 case EM_PPC64:
dda8d76d 21657 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21658 display_power_gnu_attribute);
21659
643f7afb
AK
21660 case EM_S390:
21661 case EM_S390_OLD:
dda8d76d 21662 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21663 display_s390_gnu_attribute);
21664
9e8c70f9
DM
21665 case EM_SPARC:
21666 case EM_SPARC32PLUS:
21667 case EM_SPARCV9:
dda8d76d 21668 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21669 display_sparc_gnu_attribute);
21670
59e6276b 21671 case EM_TI_C6000:
dda8d76d 21672 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21673 display_tic6x_attribute,
21674 display_generic_attribute);
21675
0861f561
CQ
21676 case EM_CSKY:
21677 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21678 display_csky_attribute, NULL);
21679
252b5132 21680 default:
dda8d76d 21681 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21682 display_public_gnu_attributes,
21683 display_generic_attribute);
252b5132 21684 }
252b5132
RH
21685}
21686
015dc7e1 21687static bool
dda8d76d 21688get_file_header (Filedata * filedata)
252b5132 21689{
9ea033b2 21690 /* Read in the identity array. */
dda8d76d 21691 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21692 return false;
252b5132 21693
9ea033b2 21694 /* Determine how to read the rest of the header. */
dda8d76d 21695 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21696 {
1a0670f3
AM
21697 default:
21698 case ELFDATANONE:
adab8cdc
AO
21699 case ELFDATA2LSB:
21700 byte_get = byte_get_little_endian;
21701 byte_put = byte_put_little_endian;
21702 break;
21703 case ELFDATA2MSB:
21704 byte_get = byte_get_big_endian;
21705 byte_put = byte_put_big_endian;
21706 break;
9ea033b2
NC
21707 }
21708
21709 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21710 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21711
21712 /* Read in the rest of the header. */
21713 if (is_32bit_elf)
21714 {
21715 Elf32_External_Ehdr ehdr32;
252b5132 21716
dda8d76d 21717 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21718 return false;
103f02d3 21719
dda8d76d
NC
21720 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21721 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21722 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21723 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21724 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21725 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21726 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21727 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21728 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21729 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21730 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21731 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21732 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21733 }
252b5132 21734 else
9ea033b2
NC
21735 {
21736 Elf64_External_Ehdr ehdr64;
a952a375
NC
21737
21738 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21739 we will not be able to cope with the 64bit data found in
21740 64 ELF files. Detect this now and abort before we start
50c2245b 21741 overwriting things. */
a952a375
NC
21742 if (sizeof (bfd_vma) < 8)
21743 {
e3c8793a
NC
21744 error (_("This instance of readelf has been built without support for a\n\
2174564 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21746 return false;
a952a375 21747 }
103f02d3 21748
dda8d76d 21749 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21750 return false;
103f02d3 21751
dda8d76d
NC
21752 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21753 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21754 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21755 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21756 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21757 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21758 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21759 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21760 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21761 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21762 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21763 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21764 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21765 }
252b5132 21766
015dc7e1 21767 return true;
252b5132
RH
21768}
21769
13acb58d
AM
21770static void
21771free_filedata (Filedata *filedata)
21772{
21773 free (filedata->program_interpreter);
13acb58d 21774 free (filedata->program_headers);
13acb58d 21775 free (filedata->section_headers);
13acb58d 21776 free (filedata->string_table);
13acb58d 21777 free (filedata->dump.dump_sects);
13acb58d 21778 free (filedata->dynamic_strings);
13acb58d 21779 free (filedata->dynamic_symbols);
13acb58d 21780 free (filedata->dynamic_syminfo);
13acb58d 21781 free (filedata->dynamic_section);
13acb58d
AM
21782
21783 while (filedata->symtab_shndx_list != NULL)
21784 {
21785 elf_section_list *next = filedata->symtab_shndx_list->next;
21786 free (filedata->symtab_shndx_list);
21787 filedata->symtab_shndx_list = next;
21788 }
21789
21790 free (filedata->section_headers_groups);
13acb58d
AM
21791
21792 if (filedata->section_groups)
21793 {
21794 size_t i;
21795 struct group_list * g;
21796 struct group_list * next;
21797
21798 for (i = 0; i < filedata->group_count; i++)
21799 {
21800 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21801 {
21802 next = g->next;
21803 free (g);
21804 }
21805 }
21806
21807 free (filedata->section_groups);
13acb58d 21808 }
066f8fbe
AM
21809 memset (&filedata->section_headers, 0,
21810 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21811}
21812
dda8d76d
NC
21813static void
21814close_file (Filedata * filedata)
21815{
21816 if (filedata)
21817 {
21818 if (filedata->handle)
21819 fclose (filedata->handle);
21820 free (filedata);
21821 }
21822}
21823
21824void
21825close_debug_file (void * data)
21826{
13acb58d 21827 free_filedata ((Filedata *) data);
dda8d76d
NC
21828 close_file ((Filedata *) data);
21829}
21830
21831static Filedata *
015dc7e1 21832open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21833{
21834 struct stat statbuf;
21835 Filedata * filedata = NULL;
21836
21837 if (stat (pathname, & statbuf) < 0
21838 || ! S_ISREG (statbuf.st_mode))
21839 goto fail;
21840
21841 filedata = calloc (1, sizeof * filedata);
21842 if (filedata == NULL)
21843 goto fail;
21844
21845 filedata->handle = fopen (pathname, "rb");
21846 if (filedata->handle == NULL)
21847 goto fail;
21848
21849 filedata->file_size = (bfd_size_type) statbuf.st_size;
21850 filedata->file_name = pathname;
ca0e11aa 21851 filedata->is_separate = is_separate;
dda8d76d
NC
21852
21853 if (! get_file_header (filedata))
21854 goto fail;
21855
4de91c10
AM
21856 if (!get_section_headers (filedata, false))
21857 goto fail;
dda8d76d
NC
21858
21859 return filedata;
21860
21861 fail:
21862 if (filedata)
21863 {
21864 if (filedata->handle)
21865 fclose (filedata->handle);
21866 free (filedata);
21867 }
21868 return NULL;
21869}
21870
21871void *
21872open_debug_file (const char * pathname)
21873{
015dc7e1 21874 return open_file (pathname, true);
dda8d76d
NC
21875}
21876
835f2fae
NC
21877static void
21878initialise_dump_sects (Filedata * filedata)
21879{
21880 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21881 Note we do this even if cmdline_dump_sects is empty because we
21882 must make sure that the dump_sets array is zeroed out before each
21883 object file is processed. */
21884 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21885 memset (filedata->dump.dump_sects, 0,
21886 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21887
21888 if (cmdline.num_dump_sects > 0)
21889 {
21890 if (filedata->dump.num_dump_sects == 0)
21891 /* A sneaky way of allocating the dump_sects array. */
21892 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21893
21894 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21895 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21896 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21897 }
21898}
21899
fb52b2f4
NC
21900/* Process one ELF object file according to the command line options.
21901 This file may actually be stored in an archive. The file is
32ec8896
NC
21902 positioned at the start of the ELF object. Returns TRUE if no
21903 problems were encountered, FALSE otherwise. */
fb52b2f4 21904
015dc7e1 21905static bool
dda8d76d 21906process_object (Filedata * filedata)
252b5132 21907{
015dc7e1 21908 bool have_separate_files;
252b5132 21909 unsigned int i;
015dc7e1 21910 bool res;
252b5132 21911
dda8d76d 21912 if (! get_file_header (filedata))
252b5132 21913 {
dda8d76d 21914 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21915 return false;
252b5132
RH
21916 }
21917
21918 /* Initialise per file variables. */
978c4450
AM
21919 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21920 filedata->version_info[i] = 0;
252b5132 21921
978c4450
AM
21922 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21923 filedata->dynamic_info[i] = 0;
21924 filedata->dynamic_info_DT_GNU_HASH = 0;
21925 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21926
21927 /* Process the file. */
21928 if (show_name)
dda8d76d 21929 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21930
835f2fae 21931 initialise_dump_sects (filedata);
d70c5fc7 21932
4de91c10
AM
21933 /* There may be some extensions in the first section header. Don't
21934 bomb if we can't read it. */
21935 get_section_headers (filedata, true);
21936
dda8d76d 21937 if (! process_file_header (filedata))
4de91c10
AM
21938 {
21939 res = false;
21940 goto out;
21941 }
252b5132 21942
e331b18d
AM
21943 /* Throw away the single section header read above, so that we
21944 re-read the entire set. */
21945 free (filedata->section_headers);
21946 filedata->section_headers = NULL;
21947
dda8d76d 21948 if (! process_section_headers (filedata))
2f62977e 21949 {
32ec8896 21950 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21951 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21952
2f62977e 21953 if (! do_using_dynamic)
015dc7e1 21954 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21955 }
252b5132 21956
dda8d76d 21957 if (! process_section_groups (filedata))
32ec8896 21958 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21959 do_unwind = false;
d1f5c6e3 21960
93df3340
AM
21961 process_program_headers (filedata);
21962
21963 res = process_dynamic_section (filedata);
252b5132 21964
dda8d76d 21965 if (! process_relocs (filedata))
015dc7e1 21966 res = false;
252b5132 21967
dda8d76d 21968 if (! process_unwind (filedata))
015dc7e1 21969 res = false;
4d6ed7c8 21970
dda8d76d 21971 if (! process_symbol_table (filedata))
015dc7e1 21972 res = false;
252b5132 21973
0f03783c 21974 if (! process_lto_symbol_tables (filedata))
015dc7e1 21975 res = false;
b9e920ec 21976
dda8d76d 21977 if (! process_syminfo (filedata))
015dc7e1 21978 res = false;
252b5132 21979
dda8d76d 21980 if (! process_version_sections (filedata))
015dc7e1 21981 res = false;
252b5132 21982
82ed9683 21983 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21984 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21985 else
015dc7e1 21986 have_separate_files = false;
dda8d76d
NC
21987
21988 if (! process_section_contents (filedata))
015dc7e1 21989 res = false;
f5842774 21990
24841daa 21991 if (have_separate_files)
dda8d76d 21992 {
24841daa
NC
21993 separate_info * d;
21994
21995 for (d = first_separate_info; d != NULL; d = d->next)
21996 {
835f2fae
NC
21997 initialise_dump_sects (d->handle);
21998
ca0e11aa 21999 if (process_links && ! process_file_header (d->handle))
015dc7e1 22000 res = false;
ca0e11aa 22001 else if (! process_section_headers (d->handle))
015dc7e1 22002 res = false;
d6bfbc39 22003 else if (! process_section_contents (d->handle))
015dc7e1 22004 res = false;
ca0e11aa
NC
22005 else if (process_links)
22006 {
ca0e11aa 22007 if (! process_section_groups (d->handle))
015dc7e1 22008 res = false;
93df3340 22009 process_program_headers (d->handle);
ca0e11aa 22010 if (! process_dynamic_section (d->handle))
015dc7e1 22011 res = false;
ca0e11aa 22012 if (! process_relocs (d->handle))
015dc7e1 22013 res = false;
ca0e11aa 22014 if (! process_unwind (d->handle))
015dc7e1 22015 res = false;
ca0e11aa 22016 if (! process_symbol_table (d->handle))
015dc7e1 22017 res = false;
ca0e11aa 22018 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22019 res = false;
ca0e11aa 22020 if (! process_syminfo (d->handle))
015dc7e1 22021 res = false;
ca0e11aa 22022 if (! process_version_sections (d->handle))
015dc7e1 22023 res = false;
ca0e11aa 22024 if (! process_notes (d->handle))
015dc7e1 22025 res = false;
ca0e11aa 22026 }
24841daa
NC
22027 }
22028
22029 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22030 }
22031
22032 if (! process_notes (filedata))
015dc7e1 22033 res = false;
103f02d3 22034
dda8d76d 22035 if (! process_gnu_liblist (filedata))
015dc7e1 22036 res = false;
047b2264 22037
dda8d76d 22038 if (! process_arch_specific (filedata))
015dc7e1 22039 res = false;
252b5132 22040
4de91c10 22041 out:
13acb58d 22042 free_filedata (filedata);
e4b17d5c 22043
19e6b90e 22044 free_debug_memory ();
18bd398b 22045
32ec8896 22046 return res;
252b5132
RH
22047}
22048
2cf0635d 22049/* Process an ELF archive.
32ec8896
NC
22050 On entry the file is positioned just after the ARMAG string.
22051 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22052
015dc7e1
AM
22053static bool
22054process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22055{
22056 struct archive_info arch;
22057 struct archive_info nested_arch;
22058 size_t got;
015dc7e1 22059 bool ret = true;
2cf0635d 22060
015dc7e1 22061 show_name = true;
2cf0635d
NC
22062
22063 /* The ARCH structure is used to hold information about this archive. */
22064 arch.file_name = NULL;
22065 arch.file = NULL;
22066 arch.index_array = NULL;
22067 arch.sym_table = NULL;
22068 arch.longnames = NULL;
22069
22070 /* The NESTED_ARCH structure is used as a single-item cache of information
22071 about a nested archive (when members of a thin archive reside within
22072 another regular archive file). */
22073 nested_arch.file_name = NULL;
22074 nested_arch.file = NULL;
22075 nested_arch.index_array = NULL;
22076 nested_arch.sym_table = NULL;
22077 nested_arch.longnames = NULL;
22078
dda8d76d 22079 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22080 filedata->file_size, is_thin_archive,
22081 do_archive_index) != 0)
2cf0635d 22082 {
015dc7e1 22083 ret = false;
2cf0635d 22084 goto out;
4145f1d5 22085 }
fb52b2f4 22086
4145f1d5
NC
22087 if (do_archive_index)
22088 {
2cf0635d 22089 if (arch.sym_table == NULL)
1cb7d8b1
AM
22090 error (_("%s: unable to dump the index as none was found\n"),
22091 filedata->file_name);
4145f1d5
NC
22092 else
22093 {
591f7597 22094 unsigned long i, l;
4145f1d5
NC
22095 unsigned long current_pos;
22096
1cb7d8b1
AM
22097 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22098 "in the symbol table)\n"),
22099 filedata->file_name, (unsigned long) arch.index_num,
22100 arch.sym_size);
dda8d76d
NC
22101
22102 current_pos = ftell (filedata->handle);
4145f1d5 22103
2cf0635d 22104 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22105 {
1cb7d8b1
AM
22106 if (i == 0
22107 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22108 {
22109 char * member_name
22110 = get_archive_member_name_at (&arch, arch.index_array[i],
22111 &nested_arch);
2cf0635d 22112
1cb7d8b1
AM
22113 if (member_name != NULL)
22114 {
22115 char * qualified_name
22116 = make_qualified_name (&arch, &nested_arch,
22117 member_name);
2cf0635d 22118
1cb7d8b1
AM
22119 if (qualified_name != NULL)
22120 {
22121 printf (_("Contents of binary %s at offset "),
22122 qualified_name);
c2a7d3f5
NC
22123 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22124 putchar ('\n');
1cb7d8b1
AM
22125 free (qualified_name);
22126 }
fd486f32 22127 free (member_name);
4145f1d5
NC
22128 }
22129 }
2cf0635d
NC
22130
22131 if (l >= arch.sym_size)
4145f1d5 22132 {
1cb7d8b1
AM
22133 error (_("%s: end of the symbol table reached "
22134 "before the end of the index\n"),
dda8d76d 22135 filedata->file_name);
015dc7e1 22136 ret = false;
cb8f3167 22137 break;
4145f1d5 22138 }
591f7597 22139 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22140 printf ("\t%.*s\n",
22141 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22142 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22143 }
22144
67ce483b 22145 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22146 l = (l + 7) & ~ 7;
22147 else
22148 l += l & 1;
22149
2cf0635d 22150 if (l < arch.sym_size)
32ec8896 22151 {
d3a49aa8
AM
22152 error (ngettext ("%s: %ld byte remains in the symbol table, "
22153 "but without corresponding entries in "
22154 "the index table\n",
22155 "%s: %ld bytes remain in the symbol table, "
22156 "but without corresponding entries in "
22157 "the index table\n",
22158 arch.sym_size - l),
dda8d76d 22159 filedata->file_name, arch.sym_size - l);
015dc7e1 22160 ret = false;
32ec8896 22161 }
4145f1d5 22162
dda8d76d 22163 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22164 {
1cb7d8b1
AM
22165 error (_("%s: failed to seek back to start of object files "
22166 "in the archive\n"),
dda8d76d 22167 filedata->file_name);
015dc7e1 22168 ret = false;
2cf0635d 22169 goto out;
4145f1d5 22170 }
fb52b2f4 22171 }
4145f1d5
NC
22172
22173 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22174 && !do_segments && !do_header && !do_dump && !do_version
22175 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22176 && !do_section_groups && !do_dyn_syms)
2cf0635d 22177 {
015dc7e1 22178 ret = true; /* Archive index only. */
2cf0635d
NC
22179 goto out;
22180 }
fb52b2f4
NC
22181 }
22182
fb52b2f4
NC
22183 while (1)
22184 {
2cf0635d
NC
22185 char * name;
22186 size_t namelen;
22187 char * qualified_name;
22188
22189 /* Read the next archive header. */
dda8d76d 22190 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22191 {
22192 error (_("%s: failed to seek to next archive header\n"),
22193 arch.file_name);
015dc7e1 22194 ret = false;
1cb7d8b1
AM
22195 break;
22196 }
dda8d76d 22197 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22198 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22199 {
22200 if (got == 0)
2cf0635d 22201 break;
28e817cc
NC
22202 /* PR 24049 - we cannot use filedata->file_name as this will
22203 have already been freed. */
22204 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22205
015dc7e1 22206 ret = false;
1cb7d8b1
AM
22207 break;
22208 }
2cf0635d 22209 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22210 {
22211 error (_("%s: did not find a valid archive header\n"),
22212 arch.file_name);
015dc7e1 22213 ret = false;
1cb7d8b1
AM
22214 break;
22215 }
2cf0635d
NC
22216
22217 arch.next_arhdr_offset += sizeof arch.arhdr;
22218
978c4450 22219 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22220
22221 name = get_archive_member_name (&arch, &nested_arch);
22222 if (name == NULL)
fb52b2f4 22223 {
28e817cc 22224 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22225 ret = false;
d989285c 22226 break;
fb52b2f4 22227 }
2cf0635d 22228 namelen = strlen (name);
fb52b2f4 22229
2cf0635d
NC
22230 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22231 if (qualified_name == NULL)
fb52b2f4 22232 {
28e817cc 22233 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22234 free (name);
015dc7e1 22235 ret = false;
d989285c 22236 break;
fb52b2f4
NC
22237 }
22238
2cf0635d 22239 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22240 {
22241 /* This is a proxy for an external member of a thin archive. */
22242 Filedata * member_filedata;
22243 char * member_file_name = adjust_relative_path
dda8d76d 22244 (filedata->file_name, name, namelen);
32ec8896 22245
fd486f32 22246 free (name);
1cb7d8b1
AM
22247 if (member_file_name == NULL)
22248 {
fd486f32 22249 free (qualified_name);
015dc7e1 22250 ret = false;
1cb7d8b1
AM
22251 break;
22252 }
2cf0635d 22253
015dc7e1 22254 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22255 if (member_filedata == NULL)
22256 {
22257 error (_("Input file '%s' is not readable.\n"), member_file_name);
22258 free (member_file_name);
fd486f32 22259 free (qualified_name);
015dc7e1 22260 ret = false;
1cb7d8b1
AM
22261 break;
22262 }
2cf0635d 22263
978c4450 22264 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22265 member_filedata->file_name = qualified_name;
2cf0635d 22266
75a2da57
AH
22267 /* The call to process_object() expects the file to be at the beginning. */
22268 rewind (member_filedata->handle);
22269
1cb7d8b1 22270 if (! process_object (member_filedata))
015dc7e1 22271 ret = false;
2cf0635d 22272
1cb7d8b1
AM
22273 close_file (member_filedata);
22274 free (member_file_name);
1cb7d8b1 22275 }
2cf0635d 22276 else if (is_thin_archive)
1cb7d8b1
AM
22277 {
22278 Filedata thin_filedata;
eb02c04d 22279
1cb7d8b1 22280 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22281
a043396b
NC
22282 /* PR 15140: Allow for corrupt thin archives. */
22283 if (nested_arch.file == NULL)
22284 {
22285 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22286 qualified_name, name);
fd486f32
AM
22287 free (qualified_name);
22288 free (name);
015dc7e1 22289 ret = false;
a043396b
NC
22290 break;
22291 }
fd486f32 22292 free (name);
a043396b 22293
1cb7d8b1 22294 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22295 filedata->archive_file_offset
22296 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22297
1cb7d8b1
AM
22298 /* The nested archive file will have been opened and setup by
22299 get_archive_member_name. */
978c4450
AM
22300 if (fseek (nested_arch.file, filedata->archive_file_offset,
22301 SEEK_SET) != 0)
1cb7d8b1
AM
22302 {
22303 error (_("%s: failed to seek to archive member.\n"),
22304 nested_arch.file_name);
fd486f32 22305 free (qualified_name);
015dc7e1 22306 ret = false;
1cb7d8b1
AM
22307 break;
22308 }
2cf0635d 22309
dda8d76d
NC
22310 thin_filedata.handle = nested_arch.file;
22311 thin_filedata.file_name = qualified_name;
9abca702 22312
1cb7d8b1 22313 if (! process_object (& thin_filedata))
015dc7e1 22314 ret = false;
1cb7d8b1 22315 }
2cf0635d 22316 else
1cb7d8b1 22317 {
fd486f32 22318 free (name);
978c4450 22319 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22320 filedata->file_name = qualified_name;
1cb7d8b1 22321 if (! process_object (filedata))
015dc7e1 22322 ret = false;
237877b8 22323 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22324 /* Stop looping with "negative" archive_file_size. */
978c4450 22325 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22326 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22327 }
fb52b2f4 22328
2cf0635d 22329 free (qualified_name);
fb52b2f4
NC
22330 }
22331
4145f1d5 22332 out:
2cf0635d
NC
22333 if (nested_arch.file != NULL)
22334 fclose (nested_arch.file);
22335 release_archive (&nested_arch);
22336 release_archive (&arch);
fb52b2f4 22337
d989285c 22338 return ret;
fb52b2f4
NC
22339}
22340
015dc7e1 22341static bool
2cf0635d 22342process_file (char * file_name)
fb52b2f4 22343{
dda8d76d 22344 Filedata * filedata = NULL;
fb52b2f4
NC
22345 struct stat statbuf;
22346 char armag[SARMAG];
015dc7e1 22347 bool ret = true;
fb52b2f4
NC
22348
22349 if (stat (file_name, &statbuf) < 0)
22350 {
f24ddbdd
NC
22351 if (errno == ENOENT)
22352 error (_("'%s': No such file\n"), file_name);
22353 else
22354 error (_("Could not locate '%s'. System error message: %s\n"),
22355 file_name, strerror (errno));
015dc7e1 22356 return false;
f24ddbdd
NC
22357 }
22358
22359 if (! S_ISREG (statbuf.st_mode))
22360 {
22361 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22362 return false;
fb52b2f4
NC
22363 }
22364
dda8d76d
NC
22365 filedata = calloc (1, sizeof * filedata);
22366 if (filedata == NULL)
22367 {
22368 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22369 return false;
dda8d76d
NC
22370 }
22371
22372 filedata->file_name = file_name;
22373 filedata->handle = fopen (file_name, "rb");
22374 if (filedata->handle == NULL)
fb52b2f4 22375 {
f24ddbdd 22376 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22377 free (filedata);
015dc7e1 22378 return false;
fb52b2f4
NC
22379 }
22380
dda8d76d 22381 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22382 {
4145f1d5 22383 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22384 fclose (filedata->handle);
22385 free (filedata);
015dc7e1 22386 return false;
fb52b2f4
NC
22387 }
22388
dda8d76d 22389 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22390 filedata->is_separate = false;
f54498b4 22391
fb52b2f4 22392 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22393 {
015dc7e1
AM
22394 if (! process_archive (filedata, false))
22395 ret = false;
32ec8896 22396 }
2cf0635d 22397 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22398 {
015dc7e1
AM
22399 if ( ! process_archive (filedata, true))
22400 ret = false;
32ec8896 22401 }
fb52b2f4
NC
22402 else
22403 {
1b513401 22404 if (do_archive_index && !check_all)
4145f1d5
NC
22405 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22406 file_name);
22407
dda8d76d 22408 rewind (filedata->handle);
978c4450 22409 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22410
dda8d76d 22411 if (! process_object (filedata))
015dc7e1 22412 ret = false;
fb52b2f4
NC
22413 }
22414
dda8d76d 22415 fclose (filedata->handle);
8fb879cd
AM
22416 free (filedata->section_headers);
22417 free (filedata->program_headers);
22418 free (filedata->string_table);
6431e409 22419 free (filedata->dump.dump_sects);
dda8d76d 22420 free (filedata);
32ec8896 22421
fd486f32 22422 free (ba_cache.strtab);
1bd6175a 22423 ba_cache.strtab = NULL;
fd486f32 22424 free (ba_cache.symtab);
1bd6175a 22425 ba_cache.symtab = NULL;
fd486f32
AM
22426 ba_cache.filedata = NULL;
22427
fb52b2f4
NC
22428 return ret;
22429}
22430
252b5132
RH
22431#ifdef SUPPORT_DISASSEMBLY
22432/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22433 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22434 symbols. */
252b5132
RH
22435
22436void
2cf0635d 22437print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22438{
22439 fprintf (outfile,"0x%8.8x", addr);
22440}
22441
e3c8793a 22442/* Needed by the i386 disassembler. */
dda8d76d 22443
252b5132
RH
22444void
22445db_task_printsym (unsigned int addr)
22446{
22447 print_address (addr, stderr);
22448}
22449#endif
22450
22451int
2cf0635d 22452main (int argc, char ** argv)
252b5132 22453{
ff78d6d6
L
22454 int err;
22455
87b9f255 22456#ifdef HAVE_LC_MESSAGES
252b5132 22457 setlocale (LC_MESSAGES, "");
3882b010 22458#endif
3882b010 22459 setlocale (LC_CTYPE, "");
252b5132
RH
22460 bindtextdomain (PACKAGE, LOCALEDIR);
22461 textdomain (PACKAGE);
22462
869b9d07
MM
22463 expandargv (&argc, &argv);
22464
dda8d76d 22465 parse_args (& cmdline, argc, argv);
59f14fc0 22466
18bd398b 22467 if (optind < (argc - 1))
1b513401
NC
22468 /* When displaying information for more than one file,
22469 prefix the information with the file name. */
015dc7e1 22470 show_name = true;
5656ba2c
L
22471 else if (optind >= argc)
22472 {
1b513401 22473 /* Ensure that the warning is always displayed. */
015dc7e1 22474 do_checks = true;
1b513401 22475
5656ba2c
L
22476 warn (_("Nothing to do.\n"));
22477 usage (stderr);
22478 }
18bd398b 22479
015dc7e1 22480 err = false;
252b5132 22481 while (optind < argc)
32ec8896 22482 if (! process_file (argv[optind++]))
015dc7e1 22483 err = true;
252b5132 22484
9db70fc3 22485 free (cmdline.dump_sects);
252b5132 22486
7d9813f1
NA
22487 free (dump_ctf_symtab_name);
22488 free (dump_ctf_strtab_name);
22489 free (dump_ctf_parent_name);
22490
32ec8896 22491 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22492}