]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Work around gcc-4 warnings in elf64-ppc.c
[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"));
c46b7066 5129#endif
fd2f0033 5130 fprintf (stream, _("\
d6249f5f
AM
5131 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5132 fprintf (stream, _("\
5133 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5134#ifdef ENABLE_LIBCTF
7d9813f1 5135 fprintf (stream, _("\
d6249f5f
AM
5136 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5137 fprintf (stream, _("\
80b56fad 5138 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5139 fprintf (stream, _("\
7d9813f1 5140 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5141 Use section <number|name> as the CTF external symtab\n"));
5142 fprintf (stream, _("\
7d9813f1 5143 --ctf-strings=<number|name>\n\
d6249f5f 5144 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5145#endif
7d9813f1 5146
252b5132 5147#ifdef SUPPORT_DISASSEMBLY
92f01d61 5148 fprintf (stream, _("\
09c11c86
NC
5149 -i --instruction-dump=<number|name>\n\
5150 Disassemble the contents of section <number|name>\n"));
252b5132 5151#endif
92f01d61 5152 fprintf (stream, _("\
d6249f5f
AM
5153 -I --histogram Display histogram of bucket list lengths\n"));
5154 fprintf (stream, _("\
5155 -W --wide Allow output width to exceed 80 characters\n"));
5156 fprintf (stream, _("\
5157 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5158 fprintf (stream, _("\
5159 @<file> Read options from <file>\n"));
5160 fprintf (stream, _("\
5161 -H --help Display this information\n"));
5162 fprintf (stream, _("\
8b53311e 5163 -v --version Display the version number of readelf\n"));
1118d252 5164
92f01d61
JM
5165 if (REPORT_BUGS_TO[0] && stream == stdout)
5166 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5167
92f01d61 5168 exit (stream == stdout ? 0 : 1);
252b5132
RH
5169}
5170
18bd398b
NC
5171/* Record the fact that the user wants the contents of section number
5172 SECTION to be displayed using the method(s) encoded as flags bits
5173 in TYPE. Note, TYPE can be zero if we are creating the array for
5174 the first time. */
5175
252b5132 5176static void
6431e409
AM
5177request_dump_bynumber (struct dump_data *dumpdata,
5178 unsigned int section, dump_type type)
252b5132 5179{
6431e409 5180 if (section >= dumpdata->num_dump_sects)
252b5132 5181 {
2cf0635d 5182 dump_type * new_dump_sects;
252b5132 5183
3f5e193b 5184 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5185 sizeof (* new_dump_sects));
252b5132
RH
5186
5187 if (new_dump_sects == NULL)
591a748a 5188 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5189 else
5190 {
6431e409 5191 if (dumpdata->dump_sects)
21b65bac
NC
5192 {
5193 /* Copy current flag settings. */
6431e409
AM
5194 memcpy (new_dump_sects, dumpdata->dump_sects,
5195 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5196
6431e409 5197 free (dumpdata->dump_sects);
21b65bac 5198 }
252b5132 5199
6431e409
AM
5200 dumpdata->dump_sects = new_dump_sects;
5201 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5202 }
5203 }
5204
6431e409
AM
5205 if (dumpdata->dump_sects)
5206 dumpdata->dump_sects[section] |= type;
252b5132
RH
5207}
5208
aef1f6d0
DJ
5209/* Request a dump by section name. */
5210
5211static void
2cf0635d 5212request_dump_byname (const char * section, dump_type type)
aef1f6d0 5213{
2cf0635d 5214 struct dump_list_entry * new_request;
aef1f6d0 5215
3f5e193b
NC
5216 new_request = (struct dump_list_entry *)
5217 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5218 if (!new_request)
591a748a 5219 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5220
5221 new_request->name = strdup (section);
5222 if (!new_request->name)
591a748a 5223 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5224
5225 new_request->type = type;
5226
5227 new_request->next = dump_sects_byname;
5228 dump_sects_byname = new_request;
5229}
5230
cf13d699 5231static inline void
6431e409 5232request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5233{
5234 int section;
5235 char * cp;
5236
015dc7e1 5237 do_dump = true;
cf13d699
NC
5238 section = strtoul (optarg, & cp, 0);
5239
5240 if (! *cp && section >= 0)
6431e409 5241 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5242 else
5243 request_dump_byname (optarg, type);
5244}
5245
252b5132 5246static void
6431e409 5247parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5248{
5249 int c;
5250
5251 if (argc < 2)
92f01d61 5252 usage (stderr);
252b5132
RH
5253
5254 while ((c = getopt_long
b3aa80b4 5255 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5256 {
252b5132
RH
5257 switch (c)
5258 {
5259 case 0:
5260 /* Long options. */
5261 break;
5262 case 'H':
92f01d61 5263 usage (stdout);
252b5132
RH
5264 break;
5265
5266 case 'a':
015dc7e1
AM
5267 do_syms = true;
5268 do_reloc = true;
5269 do_unwind = true;
5270 do_dynamic = true;
5271 do_header = true;
5272 do_sections = true;
5273 do_section_groups = true;
5274 do_segments = true;
5275 do_version = true;
5276 do_histogram = true;
5277 do_arch = true;
5278 do_notes = true;
252b5132 5279 break;
79bc120c 5280
f5842774 5281 case 'g':
015dc7e1 5282 do_section_groups = true;
f5842774 5283 break;
5477e8a0 5284 case 't':
595cf52e 5285 case 'N':
015dc7e1
AM
5286 do_sections = true;
5287 do_section_details = true;
595cf52e 5288 break;
252b5132 5289 case 'e':
015dc7e1
AM
5290 do_header = true;
5291 do_sections = true;
5292 do_segments = true;
252b5132 5293 break;
a952a375 5294 case 'A':
015dc7e1 5295 do_arch = true;
a952a375 5296 break;
252b5132 5297 case 'D':
015dc7e1 5298 do_using_dynamic = true;
252b5132
RH
5299 break;
5300 case 'r':
015dc7e1 5301 do_reloc = true;
252b5132 5302 break;
4d6ed7c8 5303 case 'u':
015dc7e1 5304 do_unwind = true;
4d6ed7c8 5305 break;
252b5132 5306 case 'h':
015dc7e1 5307 do_header = true;
252b5132
RH
5308 break;
5309 case 'l':
015dc7e1 5310 do_segments = true;
252b5132
RH
5311 break;
5312 case 's':
015dc7e1 5313 do_syms = true;
252b5132
RH
5314 break;
5315 case 'S':
015dc7e1 5316 do_sections = true;
252b5132
RH
5317 break;
5318 case 'd':
015dc7e1 5319 do_dynamic = true;
252b5132 5320 break;
a952a375 5321 case 'I':
015dc7e1 5322 do_histogram = true;
a952a375 5323 break;
779fe533 5324 case 'n':
015dc7e1 5325 do_notes = true;
779fe533 5326 break;
4145f1d5 5327 case 'c':
015dc7e1 5328 do_archive_index = true;
4145f1d5 5329 break;
1b513401 5330 case 'L':
015dc7e1 5331 do_checks = true;
1b513401 5332 break;
ca0e11aa 5333 case 'P':
015dc7e1
AM
5334 process_links = true;
5335 do_follow_links = true;
e1dbfc17 5336 dump_any_debugging = true;
ca0e11aa 5337 break;
252b5132 5338 case 'x':
6431e409 5339 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5340 break;
09c11c86 5341 case 'p':
6431e409 5342 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5343 break;
5344 case 'R':
6431e409 5345 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5346 break;
0e602686 5347 case 'z':
015dc7e1 5348 decompress_dumps = true;
0e602686 5349 break;
252b5132 5350 case 'w':
015dc7e1 5351 do_dump = true;
e1dbfc17 5352 dump_any_debugging = true;
0f03783c 5353 if (optarg == NULL)
613ff48b 5354 {
015dc7e1 5355 do_debugging = true;
613ff48b
CC
5356 dwarf_select_sections_all ();
5357 }
252b5132
RH
5358 else
5359 {
015dc7e1 5360 do_debugging = false;
4cb93e3b 5361 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5362 }
5363 break;
2979dc34 5364 case OPTION_DEBUG_DUMP:
015dc7e1 5365 do_dump = true;
e1dbfc17 5366 dump_any_debugging = true;
0f03783c 5367 if (optarg == NULL)
d6249f5f
AM
5368 {
5369 do_debugging = true;
5370 dwarf_select_sections_all ();
5371 }
2979dc34
JJ
5372 else
5373 {
015dc7e1 5374 do_debugging = false;
4cb93e3b 5375 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5376 }
5377 break;
fd2f0033
TT
5378 case OPTION_DWARF_DEPTH:
5379 {
5380 char *cp;
5381
5382 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5383 }
5384 break;
5385 case OPTION_DWARF_START:
5386 {
5387 char *cp;
5388
5389 dwarf_start_die = strtoul (optarg, & cp, 0);
5390 }
5391 break;
4723351a 5392 case OPTION_DWARF_CHECK:
015dc7e1 5393 dwarf_check = true;
4723351a 5394 break;
7d9813f1 5395 case OPTION_CTF_DUMP:
015dc7e1 5396 do_ctf = true;
6431e409 5397 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5398 break;
5399 case OPTION_CTF_SYMBOLS:
df16e041 5400 free (dump_ctf_symtab_name);
7d9813f1
NA
5401 dump_ctf_symtab_name = strdup (optarg);
5402 break;
5403 case OPTION_CTF_STRINGS:
df16e041 5404 free (dump_ctf_strtab_name);
7d9813f1
NA
5405 dump_ctf_strtab_name = strdup (optarg);
5406 break;
5407 case OPTION_CTF_PARENT:
df16e041 5408 free (dump_ctf_parent_name);
7d9813f1
NA
5409 dump_ctf_parent_name = strdup (optarg);
5410 break;
2c610e4b 5411 case OPTION_DYN_SYMS:
015dc7e1 5412 do_dyn_syms = true;
2c610e4b 5413 break;
0f03783c 5414 case OPTION_LTO_SYMS:
015dc7e1 5415 do_lto_syms = true;
0f03783c 5416 break;
252b5132
RH
5417#ifdef SUPPORT_DISASSEMBLY
5418 case 'i':
6431e409 5419 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5420 break;
252b5132
RH
5421#endif
5422 case 'v':
5423 print_version (program_name);
5424 break;
5425 case 'V':
015dc7e1 5426 do_version = true;
252b5132 5427 break;
d974e256 5428 case 'W':
015dc7e1 5429 do_wide = true;
d974e256 5430 break;
0942c7ab 5431 case 'T':
015dc7e1 5432 do_not_show_symbol_truncation = true;
0942c7ab 5433 break;
79bc120c 5434 case 'C':
015dc7e1 5435 do_demangle = true;
79bc120c
NC
5436 if (optarg != NULL)
5437 {
5438 enum demangling_styles style;
5439
5440 style = cplus_demangle_name_to_style (optarg);
5441 if (style == unknown_demangling)
5442 error (_("unknown demangling style `%s'"), optarg);
5443
5444 cplus_demangle_set_style (style);
5445 }
5446 break;
5447 case OPTION_NO_DEMANGLING:
015dc7e1 5448 do_demangle = false;
79bc120c
NC
5449 break;
5450 case OPTION_RECURSE_LIMIT:
5451 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5452 break;
5453 case OPTION_NO_RECURSE_LIMIT:
5454 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5455 break;
5456 case OPTION_WITH_SYMBOL_VERSIONS:
5457 /* Ignored for backward compatibility. */
5458 break;
b9e920ec 5459
b3aa80b4
NC
5460 case 'U':
5461 if (optarg == NULL)
5462 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5463 else if (streq (optarg, "default") || streq (optarg, "d"))
5464 unicode_display = unicode_default;
5465 else if (streq (optarg, "locale") || streq (optarg, "l"))
5466 unicode_display = unicode_locale;
5467 else if (streq (optarg, "escape") || streq (optarg, "e"))
5468 unicode_display = unicode_escape;
5469 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5470 unicode_display = unicode_invalid;
5471 else if (streq (optarg, "hex") || streq (optarg, "x"))
5472 unicode_display = unicode_hex;
5473 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5474 unicode_display = unicode_highlight;
5475 else
5476 error (_("invalid argument to -U/--unicode: %s"), optarg);
5477 break;
5478
047c3dbf
NL
5479 case OPTION_SYM_BASE:
5480 sym_base = 0;
5481 if (optarg != NULL)
5482 {
5483 sym_base = strtoul (optarg, NULL, 0);
5484 switch (sym_base)
5485 {
5486 case 0:
5487 case 8:
5488 case 10:
5489 case 16:
5490 break;
5491
5492 default:
5493 sym_base = 0;
5494 break;
5495 }
5496 }
5497 break;
5498
252b5132 5499 default:
252b5132
RH
5500 /* xgettext:c-format */
5501 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5502 /* Fall through. */
252b5132 5503 case '?':
92f01d61 5504 usage (stderr);
252b5132
RH
5505 }
5506 }
5507
4d6ed7c8 5508 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5509 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5510 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5511 && !do_section_groups && !do_archive_index
0f03783c 5512 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5513 {
5514 if (do_checks)
5515 {
015dc7e1
AM
5516 check_all = true;
5517 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5518 do_segments = do_header = do_dump = do_version = true;
5519 do_histogram = do_debugging = do_arch = do_notes = true;
5520 do_section_groups = do_archive_index = do_dyn_syms = true;
5521 do_lto_syms = true;
1b513401
NC
5522 }
5523 else
5524 usage (stderr);
5525 }
252b5132
RH
5526}
5527
5528static const char *
d3ba0551 5529get_elf_class (unsigned int elf_class)
252b5132 5530{
b34976b6 5531 static char buff[32];
103f02d3 5532
252b5132
RH
5533 switch (elf_class)
5534 {
5535 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5536 case ELFCLASS32: return "ELF32";
5537 case ELFCLASS64: return "ELF64";
ab5e7794 5538 default:
e9e44622 5539 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5540 return buff;
252b5132
RH
5541 }
5542}
5543
5544static const char *
d3ba0551 5545get_data_encoding (unsigned int encoding)
252b5132 5546{
b34976b6 5547 static char buff[32];
103f02d3 5548
252b5132
RH
5549 switch (encoding)
5550 {
5551 case ELFDATANONE: return _("none");
33c63f9d
CM
5552 case ELFDATA2LSB: return _("2's complement, little endian");
5553 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5554 default:
e9e44622 5555 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5556 return buff;
252b5132
RH
5557 }
5558}
5559
dda8d76d 5560/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5561
015dc7e1 5562static bool
dda8d76d 5563process_file_header (Filedata * filedata)
252b5132 5564{
dda8d76d
NC
5565 Elf_Internal_Ehdr * header = & filedata->file_header;
5566
5567 if ( header->e_ident[EI_MAG0] != ELFMAG0
5568 || header->e_ident[EI_MAG1] != ELFMAG1
5569 || header->e_ident[EI_MAG2] != ELFMAG2
5570 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5571 {
5572 error
5573 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5574 return false;
252b5132
RH
5575 }
5576
ca0e11aa
NC
5577 if (! filedata->is_separate)
5578 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5579
252b5132
RH
5580 if (do_header)
5581 {
32ec8896 5582 unsigned i;
252b5132 5583
ca0e11aa
NC
5584 if (filedata->is_separate)
5585 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5586 else
5587 printf (_("ELF Header:\n"));
252b5132 5588 printf (_(" Magic: "));
b34976b6 5589 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5590 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5591 printf ("\n");
5592 printf (_(" Class: %s\n"),
dda8d76d 5593 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5594 printf (_(" Data: %s\n"),
dda8d76d 5595 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5596 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5597 header->e_ident[EI_VERSION],
5598 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5599 ? _(" (current)")
dda8d76d 5600 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5601 ? _(" <unknown>")
789be9f7 5602 : "")));
252b5132 5603 printf (_(" OS/ABI: %s\n"),
dda8d76d 5604 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5605 printf (_(" ABI Version: %d\n"),
dda8d76d 5606 header->e_ident[EI_ABIVERSION]);
252b5132 5607 printf (_(" Type: %s\n"),
93df3340 5608 get_file_type (filedata));
252b5132 5609 printf (_(" Machine: %s\n"),
dda8d76d 5610 get_machine_name (header->e_machine));
252b5132 5611 printf (_(" Version: 0x%lx\n"),
e8a64888 5612 header->e_version);
76da6bbe 5613
f7a99963 5614 printf (_(" Entry point address: "));
e8a64888 5615 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5616 printf (_("\n Start of program headers: "));
e8a64888 5617 print_vma (header->e_phoff, DEC);
f7a99963 5618 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5619 print_vma (header->e_shoff, DEC);
f7a99963 5620 printf (_(" (bytes into file)\n"));
76da6bbe 5621
252b5132 5622 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5623 header->e_flags,
dda8d76d 5624 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5625 printf (_(" Size of this header: %u (bytes)\n"),
5626 header->e_ehsize);
5627 printf (_(" Size of program headers: %u (bytes)\n"),
5628 header->e_phentsize);
5629 printf (_(" Number of program headers: %u"),
5630 header->e_phnum);
dda8d76d
NC
5631 if (filedata->section_headers != NULL
5632 && header->e_phnum == PN_XNUM
5633 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5634 {
5635 header->e_phnum = filedata->section_headers[0].sh_info;
5636 printf (" (%u)", header->e_phnum);
5637 }
2046a35d 5638 putc ('\n', stdout);
e8a64888
AM
5639 printf (_(" Size of section headers: %u (bytes)\n"),
5640 header->e_shentsize);
5641 printf (_(" Number of section headers: %u"),
5642 header->e_shnum);
dda8d76d 5643 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5644 {
5645 header->e_shnum = filedata->section_headers[0].sh_size;
5646 printf (" (%u)", header->e_shnum);
5647 }
560f3c1c 5648 putc ('\n', stdout);
e8a64888
AM
5649 printf (_(" Section header string table index: %u"),
5650 header->e_shstrndx);
dda8d76d
NC
5651 if (filedata->section_headers != NULL
5652 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5653 {
5654 header->e_shstrndx = filedata->section_headers[0].sh_link;
5655 printf (" (%u)", header->e_shstrndx);
5656 }
5657 if (header->e_shstrndx != SHN_UNDEF
5658 && header->e_shstrndx >= header->e_shnum)
5659 {
5660 header->e_shstrndx = SHN_UNDEF;
5661 printf (_(" <corrupt: out of range>"));
5662 }
560f3c1c
AM
5663 putc ('\n', stdout);
5664 }
5665
dda8d76d 5666 if (filedata->section_headers != NULL)
560f3c1c 5667 {
dda8d76d
NC
5668 if (header->e_phnum == PN_XNUM
5669 && filedata->section_headers[0].sh_info != 0)
5670 header->e_phnum = filedata->section_headers[0].sh_info;
5671 if (header->e_shnum == SHN_UNDEF)
5672 header->e_shnum = filedata->section_headers[0].sh_size;
5673 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5674 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5675 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5676 header->e_shstrndx = SHN_UNDEF;
252b5132 5677 }
103f02d3 5678
015dc7e1 5679 return true;
9ea033b2
NC
5680}
5681
dda8d76d
NC
5682/* Read in the program headers from FILEDATA and store them in PHEADERS.
5683 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5684
015dc7e1 5685static bool
dda8d76d 5686get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5687{
2cf0635d
NC
5688 Elf32_External_Phdr * phdrs;
5689 Elf32_External_Phdr * external;
5690 Elf_Internal_Phdr * internal;
b34976b6 5691 unsigned int i;
dda8d76d
NC
5692 unsigned int size = filedata->file_header.e_phentsize;
5693 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5694
5695 /* PR binutils/17531: Cope with unexpected section header sizes. */
5696 if (size == 0 || num == 0)
015dc7e1 5697 return false;
e0a31db1
NC
5698 if (size < sizeof * phdrs)
5699 {
5700 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5701 return false;
e0a31db1
NC
5702 }
5703 if (size > sizeof * phdrs)
5704 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5705
dda8d76d 5706 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5707 size, num, _("program headers"));
5708 if (phdrs == NULL)
015dc7e1 5709 return false;
9ea033b2 5710
91d6fa6a 5711 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5712 i < filedata->file_header.e_phnum;
b34976b6 5713 i++, internal++, external++)
252b5132 5714 {
9ea033b2
NC
5715 internal->p_type = BYTE_GET (external->p_type);
5716 internal->p_offset = BYTE_GET (external->p_offset);
5717 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5718 internal->p_paddr = BYTE_GET (external->p_paddr);
5719 internal->p_filesz = BYTE_GET (external->p_filesz);
5720 internal->p_memsz = BYTE_GET (external->p_memsz);
5721 internal->p_flags = BYTE_GET (external->p_flags);
5722 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5723 }
5724
9ea033b2 5725 free (phdrs);
015dc7e1 5726 return true;
252b5132
RH
5727}
5728
dda8d76d
NC
5729/* Read in the program headers from FILEDATA and store them in PHEADERS.
5730 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5731
015dc7e1 5732static bool
dda8d76d 5733get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5734{
2cf0635d
NC
5735 Elf64_External_Phdr * phdrs;
5736 Elf64_External_Phdr * external;
5737 Elf_Internal_Phdr * internal;
b34976b6 5738 unsigned int i;
dda8d76d
NC
5739 unsigned int size = filedata->file_header.e_phentsize;
5740 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5741
5742 /* PR binutils/17531: Cope with unexpected section header sizes. */
5743 if (size == 0 || num == 0)
015dc7e1 5744 return false;
e0a31db1
NC
5745 if (size < sizeof * phdrs)
5746 {
5747 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5748 return false;
e0a31db1
NC
5749 }
5750 if (size > sizeof * phdrs)
5751 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5752
dda8d76d 5753 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5754 size, num, _("program headers"));
a6e9f9df 5755 if (!phdrs)
015dc7e1 5756 return false;
9ea033b2 5757
91d6fa6a 5758 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5759 i < filedata->file_header.e_phnum;
b34976b6 5760 i++, internal++, external++)
9ea033b2
NC
5761 {
5762 internal->p_type = BYTE_GET (external->p_type);
5763 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5764 internal->p_offset = BYTE_GET (external->p_offset);
5765 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5766 internal->p_paddr = BYTE_GET (external->p_paddr);
5767 internal->p_filesz = BYTE_GET (external->p_filesz);
5768 internal->p_memsz = BYTE_GET (external->p_memsz);
5769 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5770 }
5771
5772 free (phdrs);
015dc7e1 5773 return true;
9ea033b2 5774}
252b5132 5775
32ec8896 5776/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5777
015dc7e1 5778static bool
dda8d76d 5779get_program_headers (Filedata * filedata)
d93f0186 5780{
2cf0635d 5781 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5782
5783 /* Check cache of prior read. */
dda8d76d 5784 if (filedata->program_headers != NULL)
015dc7e1 5785 return true;
d93f0186 5786
82156ab7
NC
5787 /* Be kind to memory checkers by looking for
5788 e_phnum values which we know must be invalid. */
dda8d76d 5789 if (filedata->file_header.e_phnum
82156ab7 5790 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5791 >= filedata->file_size)
82156ab7
NC
5792 {
5793 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5794 filedata->file_header.e_phnum);
015dc7e1 5795 return false;
82156ab7 5796 }
d93f0186 5797
dda8d76d 5798 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5799 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5800 if (phdrs == NULL)
5801 {
8b73c356 5802 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5803 filedata->file_header.e_phnum);
015dc7e1 5804 return false;
d93f0186
NC
5805 }
5806
5807 if (is_32bit_elf
dda8d76d
NC
5808 ? get_32bit_program_headers (filedata, phdrs)
5809 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5810 {
dda8d76d 5811 filedata->program_headers = phdrs;
015dc7e1 5812 return true;
d93f0186
NC
5813 }
5814
5815 free (phdrs);
015dc7e1 5816 return false;
d93f0186
NC
5817}
5818
93df3340 5819/* Print program header info and locate dynamic section. */
2f62977e 5820
93df3340 5821static void
dda8d76d 5822process_program_headers (Filedata * filedata)
252b5132 5823{
2cf0635d 5824 Elf_Internal_Phdr * segment;
b34976b6 5825 unsigned int i;
1a9ccd70 5826 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5827
dda8d76d 5828 if (filedata->file_header.e_phnum == 0)
252b5132 5829 {
82f2dbf7 5830 /* PR binutils/12467. */
dda8d76d 5831 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5832 warn (_("possibly corrupt ELF header - it has a non-zero program"
5833 " header offset, but no program headers\n"));
82f2dbf7 5834 else if (do_segments)
ca0e11aa
NC
5835 {
5836 if (filedata->is_separate)
5837 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5838 filedata->file_name);
5839 else
5840 printf (_("\nThere are no program headers in this file.\n"));
5841 }
93df3340 5842 goto no_headers;
252b5132
RH
5843 }
5844
5845 if (do_segments && !do_header)
5846 {
ca0e11aa
NC
5847 if (filedata->is_separate)
5848 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5849 filedata->file_name, get_file_type (filedata));
ca0e11aa 5850 else
93df3340 5851 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5852 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5853 printf (ngettext ("There is %d program header, starting at offset %s\n",
5854 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5855 filedata->file_header.e_phnum),
5856 filedata->file_header.e_phnum,
5857 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5858 }
5859
dda8d76d 5860 if (! get_program_headers (filedata))
93df3340 5861 goto no_headers;
103f02d3 5862
252b5132
RH
5863 if (do_segments)
5864 {
dda8d76d 5865 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5866 printf (_("\nProgram Headers:\n"));
5867 else
5868 printf (_("\nProgram Headers:\n"));
76da6bbe 5869
f7a99963
NC
5870 if (is_32bit_elf)
5871 printf
5872 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5873 else if (do_wide)
5874 printf
5875 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5876 else
5877 {
5878 printf
5879 (_(" Type Offset VirtAddr PhysAddr\n"));
5880 printf
5881 (_(" FileSiz MemSiz Flags Align\n"));
5882 }
252b5132
RH
5883 }
5884
93df3340
AM
5885 unsigned long dynamic_addr = 0;
5886 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5887 for (i = 0, segment = filedata->program_headers;
5888 i < filedata->file_header.e_phnum;
b34976b6 5889 i++, segment++)
252b5132
RH
5890 {
5891 if (do_segments)
5892 {
dda8d76d 5893 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5894
5895 if (is_32bit_elf)
5896 {
5897 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5898 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5899 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5900 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5901 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5902 printf ("%c%c%c ",
5903 (segment->p_flags & PF_R ? 'R' : ' '),
5904 (segment->p_flags & PF_W ? 'W' : ' '),
5905 (segment->p_flags & PF_X ? 'E' : ' '));
5906 printf ("%#lx", (unsigned long) segment->p_align);
5907 }
d974e256
JJ
5908 else if (do_wide)
5909 {
5910 if ((unsigned long) segment->p_offset == segment->p_offset)
5911 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5912 else
5913 {
5914 print_vma (segment->p_offset, FULL_HEX);
5915 putchar (' ');
5916 }
5917
5918 print_vma (segment->p_vaddr, FULL_HEX);
5919 putchar (' ');
5920 print_vma (segment->p_paddr, FULL_HEX);
5921 putchar (' ');
5922
5923 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5924 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5925 else
5926 {
5927 print_vma (segment->p_filesz, FULL_HEX);
5928 putchar (' ');
5929 }
5930
5931 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5932 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5933 else
5934 {
f48e6c45 5935 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5936 }
5937
5938 printf (" %c%c%c ",
5939 (segment->p_flags & PF_R ? 'R' : ' '),
5940 (segment->p_flags & PF_W ? 'W' : ' '),
5941 (segment->p_flags & PF_X ? 'E' : ' '));
5942
5943 if ((unsigned long) segment->p_align == segment->p_align)
5944 printf ("%#lx", (unsigned long) segment->p_align);
5945 else
5946 {
5947 print_vma (segment->p_align, PREFIX_HEX);
5948 }
5949 }
f7a99963
NC
5950 else
5951 {
5952 print_vma (segment->p_offset, FULL_HEX);
5953 putchar (' ');
5954 print_vma (segment->p_vaddr, FULL_HEX);
5955 putchar (' ');
5956 print_vma (segment->p_paddr, FULL_HEX);
5957 printf ("\n ");
5958 print_vma (segment->p_filesz, FULL_HEX);
5959 putchar (' ');
5960 print_vma (segment->p_memsz, FULL_HEX);
5961 printf (" %c%c%c ",
5962 (segment->p_flags & PF_R ? 'R' : ' '),
5963 (segment->p_flags & PF_W ? 'W' : ' '),
5964 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5965 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5966 }
252b5132 5967
1a9ccd70
NC
5968 putc ('\n', stdout);
5969 }
f54498b4 5970
252b5132
RH
5971 switch (segment->p_type)
5972 {
1a9ccd70 5973 case PT_LOAD:
502d895c
NC
5974#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5975 required by the ELF standard, several programs, including the Linux
5976 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5977 if (previous_load
5978 && previous_load->p_vaddr > segment->p_vaddr)
5979 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5980#endif
1a9ccd70
NC
5981 if (segment->p_memsz < segment->p_filesz)
5982 error (_("the segment's file size is larger than its memory size\n"));
5983 previous_load = segment;
5984 break;
5985
5986 case PT_PHDR:
5987 /* PR 20815 - Verify that the program header is loaded into memory. */
5988 if (i > 0 && previous_load != NULL)
5989 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5990 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5991 {
5992 unsigned int j;
5993
dda8d76d 5994 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5995 {
5996 Elf_Internal_Phdr *load = filedata->program_headers + j;
5997 if (load->p_type == PT_LOAD
5998 && load->p_offset <= segment->p_offset
5999 && (load->p_offset + load->p_filesz
6000 >= segment->p_offset + segment->p_filesz)
6001 && load->p_vaddr <= segment->p_vaddr
6002 && (load->p_vaddr + load->p_filesz
6003 >= segment->p_vaddr + segment->p_filesz))
6004 break;
6005 }
dda8d76d 6006 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6007 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6008 }
6009 break;
6010
252b5132 6011 case PT_DYNAMIC:
93df3340 6012 if (dynamic_addr)
252b5132
RH
6013 error (_("more than one dynamic segment\n"));
6014
20737c13
AM
6015 /* By default, assume that the .dynamic section is the first
6016 section in the DYNAMIC segment. */
93df3340
AM
6017 dynamic_addr = segment->p_offset;
6018 dynamic_size = segment->p_filesz;
20737c13 6019
b2d38a17
NC
6020 /* Try to locate the .dynamic section. If there is
6021 a section header table, we can easily locate it. */
dda8d76d 6022 if (filedata->section_headers != NULL)
b2d38a17 6023 {
2cf0635d 6024 Elf_Internal_Shdr * sec;
b2d38a17 6025
dda8d76d 6026 sec = find_section (filedata, ".dynamic");
89fac5e3 6027 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6028 {
93df3340
AM
6029 /* A corresponding .dynamic section is expected, but on
6030 IA-64/OpenVMS it is OK for it to be missing. */
6031 if (!is_ia64_vms (filedata))
6032 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6033 break;
6034 }
6035
42bb2e33 6036 if (sec->sh_type == SHT_NOBITS)
20737c13 6037 {
93df3340
AM
6038 dynamic_addr = 0;
6039 dynamic_size = 0;
20737c13
AM
6040 break;
6041 }
42bb2e33 6042
93df3340
AM
6043 dynamic_addr = sec->sh_offset;
6044 dynamic_size = sec->sh_size;
b2d38a17 6045
8ac10c5b
L
6046 /* The PT_DYNAMIC segment, which is used by the run-time
6047 loader, should exactly match the .dynamic section. */
6048 if (do_checks
93df3340
AM
6049 && (dynamic_addr != segment->p_offset
6050 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6051 warn (_("\
6052the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6053 }
39e224f6
MW
6054
6055 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6056 segment. Check this after matching against the section headers
6057 so we don't warn on debuginfo file (which have NOBITS .dynamic
6058 sections). */
93df3340
AM
6059 if (dynamic_addr > filedata->file_size
6060 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6061 {
6062 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6063 dynamic_addr = 0;
6064 dynamic_size = 0;
39e224f6 6065 }
252b5132
RH
6066 break;
6067
6068 case PT_INTERP:
13acb58d
AM
6069 if (segment->p_offset >= filedata->file_size
6070 || segment->p_filesz > filedata->file_size - segment->p_offset
6071 || segment->p_filesz - 1 >= (size_t) -2
6072 || fseek (filedata->handle,
6073 filedata->archive_file_offset + (long) segment->p_offset,
6074 SEEK_SET))
252b5132
RH
6075 error (_("Unable to find program interpreter name\n"));
6076 else
6077 {
13acb58d
AM
6078 size_t len = segment->p_filesz;
6079 free (filedata->program_interpreter);
6080 filedata->program_interpreter = xmalloc (len + 1);
6081 len = fread (filedata->program_interpreter, 1, len,
6082 filedata->handle);
6083 filedata->program_interpreter[len] = 0;
252b5132
RH
6084
6085 if (do_segments)
f54498b4 6086 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6087 filedata->program_interpreter);
252b5132
RH
6088 }
6089 break;
6090 }
252b5132
RH
6091 }
6092
dda8d76d
NC
6093 if (do_segments
6094 && filedata->section_headers != NULL
6095 && filedata->string_table != NULL)
252b5132
RH
6096 {
6097 printf (_("\n Section to Segment mapping:\n"));
6098 printf (_(" Segment Sections...\n"));
6099
dda8d76d 6100 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6101 {
9ad5cbcf 6102 unsigned int j;
2cf0635d 6103 Elf_Internal_Shdr * section;
252b5132 6104
dda8d76d
NC
6105 segment = filedata->program_headers + i;
6106 section = filedata->section_headers + 1;
252b5132
RH
6107
6108 printf (" %2.2d ", i);
6109
dda8d76d 6110 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6111 {
f4638467
AM
6112 if (!ELF_TBSS_SPECIAL (section, segment)
6113 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6114 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6115 }
6116
6117 putc ('\n',stdout);
6118 }
6119 }
6120
93df3340
AM
6121 filedata->dynamic_addr = dynamic_addr;
6122 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6123 return;
6124
6125 no_headers:
6126 filedata->dynamic_addr = 0;
6127 filedata->dynamic_size = 1;
252b5132
RH
6128}
6129
6130
d93f0186
NC
6131/* Find the file offset corresponding to VMA by using the program headers. */
6132
6133static long
dda8d76d 6134offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6135{
2cf0635d 6136 Elf_Internal_Phdr * seg;
d93f0186 6137
dda8d76d 6138 if (! get_program_headers (filedata))
d93f0186
NC
6139 {
6140 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6141 return (long) vma;
6142 }
6143
dda8d76d
NC
6144 for (seg = filedata->program_headers;
6145 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6146 ++seg)
6147 {
6148 if (seg->p_type != PT_LOAD)
6149 continue;
6150
6151 if (vma >= (seg->p_vaddr & -seg->p_align)
6152 && vma + size <= seg->p_vaddr + seg->p_filesz)
6153 return vma - seg->p_vaddr + seg->p_offset;
6154 }
6155
6156 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6157 (unsigned long) vma);
d93f0186
NC
6158 return (long) vma;
6159}
6160
6161
dda8d76d
NC
6162/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6163 If PROBE is true, this is just a probe and we do not generate any error
6164 messages if the load fails. */
049b0c3a 6165
015dc7e1
AM
6166static bool
6167get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6168{
2cf0635d
NC
6169 Elf32_External_Shdr * shdrs;
6170 Elf_Internal_Shdr * internal;
dda8d76d
NC
6171 unsigned int i;
6172 unsigned int size = filedata->file_header.e_shentsize;
6173 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6174
6175 /* PR binutils/17531: Cope with unexpected section header sizes. */
6176 if (size == 0 || num == 0)
015dc7e1 6177 return false;
049b0c3a
NC
6178 if (size < sizeof * shdrs)
6179 {
6180 if (! probe)
6181 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6182 return false;
049b0c3a
NC
6183 }
6184 if (!probe && size > sizeof * shdrs)
6185 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6186
dda8d76d 6187 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6188 size, num,
6189 probe ? NULL : _("section headers"));
6190 if (shdrs == NULL)
015dc7e1 6191 return false;
252b5132 6192
dda8d76d
NC
6193 filedata->section_headers = (Elf_Internal_Shdr *)
6194 cmalloc (num, sizeof (Elf_Internal_Shdr));
6195 if (filedata->section_headers == NULL)
252b5132 6196 {
049b0c3a 6197 if (!probe)
8b73c356 6198 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6199 free (shdrs);
015dc7e1 6200 return false;
252b5132
RH
6201 }
6202
dda8d76d 6203 for (i = 0, internal = filedata->section_headers;
560f3c1c 6204 i < num;
b34976b6 6205 i++, internal++)
252b5132
RH
6206 {
6207 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6208 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6209 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6210 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6211 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6212 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6213 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6214 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6215 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6216 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6217 if (!probe && internal->sh_link > num)
6218 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6219 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6220 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6221 }
6222
6223 free (shdrs);
015dc7e1 6224 return true;
252b5132
RH
6225}
6226
dda8d76d
NC
6227/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6228
015dc7e1
AM
6229static bool
6230get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6231{
dda8d76d
NC
6232 Elf64_External_Shdr * shdrs;
6233 Elf_Internal_Shdr * internal;
6234 unsigned int i;
6235 unsigned int size = filedata->file_header.e_shentsize;
6236 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6237
6238 /* PR binutils/17531: Cope with unexpected section header sizes. */
6239 if (size == 0 || num == 0)
015dc7e1 6240 return false;
dda8d76d 6241
049b0c3a
NC
6242 if (size < sizeof * shdrs)
6243 {
6244 if (! probe)
6245 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6246 return false;
049b0c3a 6247 }
dda8d76d 6248
049b0c3a
NC
6249 if (! probe && size > sizeof * shdrs)
6250 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6251
dda8d76d
NC
6252 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6253 filedata->file_header.e_shoff,
049b0c3a
NC
6254 size, num,
6255 probe ? NULL : _("section headers"));
6256 if (shdrs == NULL)
015dc7e1 6257 return false;
9ea033b2 6258
dda8d76d
NC
6259 filedata->section_headers = (Elf_Internal_Shdr *)
6260 cmalloc (num, sizeof (Elf_Internal_Shdr));
6261 if (filedata->section_headers == NULL)
9ea033b2 6262 {
049b0c3a 6263 if (! probe)
8b73c356 6264 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6265 free (shdrs);
015dc7e1 6266 return false;
9ea033b2
NC
6267 }
6268
dda8d76d 6269 for (i = 0, internal = filedata->section_headers;
560f3c1c 6270 i < num;
b34976b6 6271 i++, internal++)
9ea033b2
NC
6272 {
6273 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6274 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6275 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6276 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6277 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6278 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6279 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6280 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6281 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6282 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6283 if (!probe && internal->sh_link > num)
6284 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6285 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6286 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6287 }
6288
6289 free (shdrs);
015dc7e1 6290 return true;
9ea033b2
NC
6291}
6292
4de91c10
AM
6293static bool
6294get_section_headers (Filedata *filedata, bool probe)
6295{
6296 if (filedata->section_headers != NULL)
6297 return true;
6298
4de91c10
AM
6299 if (is_32bit_elf)
6300 return get_32bit_section_headers (filedata, probe);
6301 else
6302 return get_64bit_section_headers (filedata, probe);
6303}
6304
252b5132 6305static Elf_Internal_Sym *
dda8d76d
NC
6306get_32bit_elf_symbols (Filedata * filedata,
6307 Elf_Internal_Shdr * section,
6308 unsigned long * num_syms_return)
252b5132 6309{
ba5cdace 6310 unsigned long number = 0;
dd24e3da 6311 Elf32_External_Sym * esyms = NULL;
ba5cdace 6312 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6313 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6314 Elf_Internal_Sym * psym;
b34976b6 6315 unsigned int j;
e3d39609 6316 elf_section_list * entry;
252b5132 6317
c9c1d674
EG
6318 if (section->sh_size == 0)
6319 {
6320 if (num_syms_return != NULL)
6321 * num_syms_return = 0;
6322 return NULL;
6323 }
6324
dd24e3da 6325 /* Run some sanity checks first. */
c9c1d674 6326 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6327 {
c9c1d674 6328 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6329 printable_section_name (filedata, section),
6330 (unsigned long) section->sh_entsize);
ba5cdace 6331 goto exit_point;
dd24e3da
NC
6332 }
6333
dda8d76d 6334 if (section->sh_size > filedata->file_size)
f54498b4
NC
6335 {
6336 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6337 printable_section_name (filedata, section),
6338 (unsigned long) section->sh_size);
f54498b4
NC
6339 goto exit_point;
6340 }
6341
dd24e3da
NC
6342 number = section->sh_size / section->sh_entsize;
6343
6344 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6345 {
c9c1d674 6346 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6347 (unsigned long) section->sh_size,
dda8d76d 6348 printable_section_name (filedata, section),
8066deb1 6349 (unsigned long) section->sh_entsize);
ba5cdace 6350 goto exit_point;
dd24e3da
NC
6351 }
6352
dda8d76d 6353 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6354 section->sh_size, _("symbols"));
dd24e3da 6355 if (esyms == NULL)
ba5cdace 6356 goto exit_point;
252b5132 6357
e3d39609 6358 shndx = NULL;
978c4450 6359 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6360 {
6361 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6362 continue;
6363
6364 if (shndx != NULL)
6365 {
6366 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6367 free (shndx);
6368 }
6369
6370 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6371 entry->hdr->sh_offset,
6372 1, entry->hdr->sh_size,
6373 _("symbol table section indices"));
6374 if (shndx == NULL)
6375 goto exit_point;
6376
6377 /* PR17531: file: heap-buffer-overflow */
6378 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6379 {
6380 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6381 printable_section_name (filedata, entry->hdr),
6382 (unsigned long) entry->hdr->sh_size,
6383 (unsigned long) section->sh_size);
6384 goto exit_point;
c9c1d674 6385 }
e3d39609 6386 }
9ad5cbcf 6387
3f5e193b 6388 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6389
6390 if (isyms == NULL)
6391 {
8b73c356
NC
6392 error (_("Out of memory reading %lu symbols\n"),
6393 (unsigned long) number);
dd24e3da 6394 goto exit_point;
252b5132
RH
6395 }
6396
dd24e3da 6397 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6398 {
6399 psym->st_name = BYTE_GET (esyms[j].st_name);
6400 psym->st_value = BYTE_GET (esyms[j].st_value);
6401 psym->st_size = BYTE_GET (esyms[j].st_size);
6402 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6403 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6404 psym->st_shndx
6405 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6406 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6407 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6408 psym->st_info = BYTE_GET (esyms[j].st_info);
6409 psym->st_other = BYTE_GET (esyms[j].st_other);
6410 }
6411
dd24e3da 6412 exit_point:
e3d39609
NC
6413 free (shndx);
6414 free (esyms);
252b5132 6415
ba5cdace
NC
6416 if (num_syms_return != NULL)
6417 * num_syms_return = isyms == NULL ? 0 : number;
6418
252b5132
RH
6419 return isyms;
6420}
6421
9ea033b2 6422static Elf_Internal_Sym *
dda8d76d
NC
6423get_64bit_elf_symbols (Filedata * filedata,
6424 Elf_Internal_Shdr * section,
6425 unsigned long * num_syms_return)
9ea033b2 6426{
ba5cdace
NC
6427 unsigned long number = 0;
6428 Elf64_External_Sym * esyms = NULL;
6429 Elf_External_Sym_Shndx * shndx = NULL;
6430 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6431 Elf_Internal_Sym * psym;
b34976b6 6432 unsigned int j;
e3d39609 6433 elf_section_list * entry;
9ea033b2 6434
c9c1d674
EG
6435 if (section->sh_size == 0)
6436 {
6437 if (num_syms_return != NULL)
6438 * num_syms_return = 0;
6439 return NULL;
6440 }
6441
dd24e3da 6442 /* Run some sanity checks first. */
c9c1d674 6443 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6444 {
c9c1d674 6445 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6446 printable_section_name (filedata, section),
8066deb1 6447 (unsigned long) section->sh_entsize);
ba5cdace 6448 goto exit_point;
dd24e3da
NC
6449 }
6450
dda8d76d 6451 if (section->sh_size > filedata->file_size)
f54498b4
NC
6452 {
6453 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6454 printable_section_name (filedata, section),
8066deb1 6455 (unsigned long) section->sh_size);
f54498b4
NC
6456 goto exit_point;
6457 }
6458
dd24e3da
NC
6459 number = section->sh_size / section->sh_entsize;
6460
6461 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6462 {
c9c1d674 6463 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6464 (unsigned long) section->sh_size,
dda8d76d 6465 printable_section_name (filedata, section),
8066deb1 6466 (unsigned long) section->sh_entsize);
ba5cdace 6467 goto exit_point;
dd24e3da
NC
6468 }
6469
dda8d76d 6470 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6471 section->sh_size, _("symbols"));
a6e9f9df 6472 if (!esyms)
ba5cdace 6473 goto exit_point;
9ea033b2 6474
e3d39609 6475 shndx = NULL;
978c4450 6476 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6477 {
6478 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6479 continue;
6480
6481 if (shndx != NULL)
6482 {
6483 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6484 free (shndx);
c9c1d674 6485 }
e3d39609
NC
6486
6487 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6488 entry->hdr->sh_offset,
6489 1, entry->hdr->sh_size,
6490 _("symbol table section indices"));
6491 if (shndx == NULL)
6492 goto exit_point;
6493
6494 /* PR17531: file: heap-buffer-overflow */
6495 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6496 {
6497 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6498 printable_section_name (filedata, entry->hdr),
6499 (unsigned long) entry->hdr->sh_size,
6500 (unsigned long) section->sh_size);
6501 goto exit_point;
6502 }
6503 }
9ad5cbcf 6504
3f5e193b 6505 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6506
6507 if (isyms == NULL)
6508 {
8b73c356
NC
6509 error (_("Out of memory reading %lu symbols\n"),
6510 (unsigned long) number);
ba5cdace 6511 goto exit_point;
9ea033b2
NC
6512 }
6513
ba5cdace 6514 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6515 {
6516 psym->st_name = BYTE_GET (esyms[j].st_name);
6517 psym->st_info = BYTE_GET (esyms[j].st_info);
6518 psym->st_other = BYTE_GET (esyms[j].st_other);
6519 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6520
4fbb74a6 6521 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6522 psym->st_shndx
6523 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6524 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6525 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6526
66543521
AM
6527 psym->st_value = BYTE_GET (esyms[j].st_value);
6528 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6529 }
6530
ba5cdace 6531 exit_point:
e3d39609
NC
6532 free (shndx);
6533 free (esyms);
ba5cdace
NC
6534
6535 if (num_syms_return != NULL)
6536 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6537
6538 return isyms;
6539}
6540
4de91c10
AM
6541static Elf_Internal_Sym *
6542get_elf_symbols (Filedata *filedata,
6543 Elf_Internal_Shdr *section,
6544 unsigned long *num_syms_return)
6545{
6546 if (is_32bit_elf)
6547 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6548 else
6549 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6550}
6551
d1133906 6552static const char *
dda8d76d 6553get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6554{
5477e8a0 6555 static char buff[1024];
2cf0635d 6556 char * p = buff;
32ec8896
NC
6557 unsigned int field_size = is_32bit_elf ? 8 : 16;
6558 signed int sindex;
6559 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6560 bfd_vma os_flags = 0;
6561 bfd_vma proc_flags = 0;
6562 bfd_vma unknown_flags = 0;
148b93f2 6563 static const struct
5477e8a0 6564 {
2cf0635d 6565 const char * str;
32ec8896 6566 unsigned int len;
5477e8a0
L
6567 }
6568 flags [] =
6569 {
cfcac11d
NC
6570 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6571 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6572 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6573 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6574 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6575 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6576 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6577 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6578 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6579 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6580 /* IA-64 specific. */
6581 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6582 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6583 /* IA-64 OpenVMS specific. */
6584 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6585 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6586 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6587 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6588 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6589 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6590 /* Generic. */
cfcac11d 6591 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6592 /* SPARC specific. */
77115a4a 6593 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6594 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6595 /* ARM specific. */
6596 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6597 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6598 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6599 /* GNU specific. */
6600 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6601 /* VLE specific. */
6602 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6603 /* GNU specific. */
6604 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6605 };
6606
6607 if (do_section_details)
6608 {
8d5ff12c
L
6609 sprintf (buff, "[%*.*lx]: ",
6610 field_size, field_size, (unsigned long) sh_flags);
6611 p += field_size + 4;
5477e8a0 6612 }
76da6bbe 6613
d1133906
NC
6614 while (sh_flags)
6615 {
6616 bfd_vma flag;
6617
6618 flag = sh_flags & - sh_flags;
6619 sh_flags &= ~ flag;
76da6bbe 6620
5477e8a0 6621 if (do_section_details)
d1133906 6622 {
5477e8a0
L
6623 switch (flag)
6624 {
91d6fa6a
NC
6625 case SHF_WRITE: sindex = 0; break;
6626 case SHF_ALLOC: sindex = 1; break;
6627 case SHF_EXECINSTR: sindex = 2; break;
6628 case SHF_MERGE: sindex = 3; break;
6629 case SHF_STRINGS: sindex = 4; break;
6630 case SHF_INFO_LINK: sindex = 5; break;
6631 case SHF_LINK_ORDER: sindex = 6; break;
6632 case SHF_OS_NONCONFORMING: sindex = 7; break;
6633 case SHF_GROUP: sindex = 8; break;
6634 case SHF_TLS: sindex = 9; break;
18ae9cc1 6635 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6636 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6637
5477e8a0 6638 default:
91d6fa6a 6639 sindex = -1;
dda8d76d 6640 switch (filedata->file_header.e_machine)
148b93f2 6641 {
cfcac11d 6642 case EM_IA_64:
148b93f2 6643 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6644 sindex = 10;
148b93f2 6645 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6646 sindex = 11;
148b93f2 6647#ifdef BFD64
dda8d76d 6648 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6649 switch (flag)
6650 {
91d6fa6a
NC
6651 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6652 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6653 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6654 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6655 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6656 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6657 default: break;
6658 }
6659#endif
cfcac11d
NC
6660 break;
6661
caa83f8b 6662 case EM_386:
22abe556 6663 case EM_IAMCU:
caa83f8b 6664 case EM_X86_64:
7f502d6c 6665 case EM_L1OM:
7a9068fe 6666 case EM_K1OM:
cfcac11d
NC
6667 case EM_OLD_SPARCV9:
6668 case EM_SPARC32PLUS:
6669 case EM_SPARCV9:
6670 case EM_SPARC:
18ae9cc1 6671 if (flag == SHF_ORDERED)
91d6fa6a 6672 sindex = 19;
cfcac11d 6673 break;
ac4c9b04
MG
6674
6675 case EM_ARM:
6676 switch (flag)
6677 {
6678 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6679 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6680 case SHF_COMDEF: sindex = 23; break;
6681 default: break;
6682 }
6683 break;
83eef883
AFB
6684 case EM_PPC:
6685 if (flag == SHF_PPC_VLE)
6686 sindex = 25;
6687 break;
99fabbc9
JL
6688 default:
6689 break;
6690 }
ac4c9b04 6691
99fabbc9
JL
6692 switch (filedata->file_header.e_ident[EI_OSABI])
6693 {
6694 case ELFOSABI_GNU:
6695 case ELFOSABI_FREEBSD:
6696 if (flag == SHF_GNU_RETAIN)
6697 sindex = 26;
6698 /* Fall through */
6699 case ELFOSABI_NONE:
6700 if (flag == SHF_GNU_MBIND)
6701 /* We should not recognize SHF_GNU_MBIND for
6702 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6703 not set the EI_OSABI header byte. */
6704 sindex = 24;
6705 break;
cfcac11d
NC
6706 default:
6707 break;
148b93f2 6708 }
99fabbc9 6709 break;
5477e8a0
L
6710 }
6711
91d6fa6a 6712 if (sindex != -1)
5477e8a0 6713 {
8d5ff12c
L
6714 if (p != buff + field_size + 4)
6715 {
6716 if (size < (10 + 2))
bee0ee85
NC
6717 {
6718 warn (_("Internal error: not enough buffer room for section flag info"));
6719 return _("<unknown>");
6720 }
8d5ff12c
L
6721 size -= 2;
6722 *p++ = ',';
6723 *p++ = ' ';
6724 }
6725
91d6fa6a
NC
6726 size -= flags [sindex].len;
6727 p = stpcpy (p, flags [sindex].str);
5477e8a0 6728 }
3b22753a 6729 else if (flag & SHF_MASKOS)
8d5ff12c 6730 os_flags |= flag;
d1133906 6731 else if (flag & SHF_MASKPROC)
8d5ff12c 6732 proc_flags |= flag;
d1133906 6733 else
8d5ff12c 6734 unknown_flags |= flag;
5477e8a0
L
6735 }
6736 else
6737 {
6738 switch (flag)
6739 {
6740 case SHF_WRITE: *p = 'W'; break;
6741 case SHF_ALLOC: *p = 'A'; break;
6742 case SHF_EXECINSTR: *p = 'X'; break;
6743 case SHF_MERGE: *p = 'M'; break;
6744 case SHF_STRINGS: *p = 'S'; break;
6745 case SHF_INFO_LINK: *p = 'I'; break;
6746 case SHF_LINK_ORDER: *p = 'L'; break;
6747 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6748 case SHF_GROUP: *p = 'G'; break;
6749 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6750 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6751 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6752
6753 default:
dda8d76d
NC
6754 if ((filedata->file_header.e_machine == EM_X86_64
6755 || filedata->file_header.e_machine == EM_L1OM
6756 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6757 && flag == SHF_X86_64_LARGE)
6758 *p = 'l';
dda8d76d 6759 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6760 && flag == SHF_ARM_PURECODE)
99fabbc9 6761 *p = 'y';
dda8d76d 6762 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6763 && flag == SHF_PPC_VLE)
99fabbc9 6764 *p = 'v';
5477e8a0
L
6765 else if (flag & SHF_MASKOS)
6766 {
99fabbc9
JL
6767 switch (filedata->file_header.e_ident[EI_OSABI])
6768 {
6769 case ELFOSABI_GNU:
6770 case ELFOSABI_FREEBSD:
6771 if (flag == SHF_GNU_RETAIN)
6772 {
6773 *p = 'R';
6774 break;
6775 }
6776 /* Fall through */
6777 case ELFOSABI_NONE:
6778 if (flag == SHF_GNU_MBIND)
6779 {
6780 /* We should not recognize SHF_GNU_MBIND for
6781 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6782 not set the EI_OSABI header byte. */
6783 *p = 'D';
6784 break;
6785 }
6786 /* Fall through */
6787 default:
6788 *p = 'o';
6789 sh_flags &= ~SHF_MASKOS;
6790 break;
6791 }
5477e8a0
L
6792 }
6793 else if (flag & SHF_MASKPROC)
6794 {
6795 *p = 'p';
6796 sh_flags &= ~ SHF_MASKPROC;
6797 }
6798 else
6799 *p = 'x';
6800 break;
6801 }
6802 p++;
d1133906
NC
6803 }
6804 }
76da6bbe 6805
8d5ff12c
L
6806 if (do_section_details)
6807 {
6808 if (os_flags)
6809 {
6810 size -= 5 + field_size;
6811 if (p != buff + field_size + 4)
6812 {
6813 if (size < (2 + 1))
bee0ee85
NC
6814 {
6815 warn (_("Internal error: not enough buffer room for section flag info"));
6816 return _("<unknown>");
6817 }
8d5ff12c
L
6818 size -= 2;
6819 *p++ = ',';
6820 *p++ = ' ';
6821 }
6822 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6823 (unsigned long) os_flags);
6824 p += 5 + field_size;
6825 }
6826 if (proc_flags)
6827 {
6828 size -= 7 + field_size;
6829 if (p != buff + field_size + 4)
6830 {
6831 if (size < (2 + 1))
bee0ee85
NC
6832 {
6833 warn (_("Internal error: not enough buffer room for section flag info"));
6834 return _("<unknown>");
6835 }
8d5ff12c
L
6836 size -= 2;
6837 *p++ = ',';
6838 *p++ = ' ';
6839 }
6840 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6841 (unsigned long) proc_flags);
6842 p += 7 + field_size;
6843 }
6844 if (unknown_flags)
6845 {
6846 size -= 10 + field_size;
6847 if (p != buff + field_size + 4)
6848 {
6849 if (size < (2 + 1))
bee0ee85
NC
6850 {
6851 warn (_("Internal error: not enough buffer room for section flag info"));
6852 return _("<unknown>");
6853 }
8d5ff12c
L
6854 size -= 2;
6855 *p++ = ',';
6856 *p++ = ' ';
6857 }
2b692964 6858 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6859 (unsigned long) unknown_flags);
6860 p += 10 + field_size;
6861 }
6862 }
6863
e9e44622 6864 *p = '\0';
d1133906
NC
6865 return buff;
6866}
6867
5844b465 6868static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6869get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6870{
6871 if (is_32bit_elf)
6872 {
6873 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6874
ebdf1ebf
NC
6875 if (size < sizeof (* echdr))
6876 {
6877 error (_("Compressed section is too small even for a compression header\n"));
6878 return 0;
6879 }
6880
77115a4a
L
6881 chdr->ch_type = BYTE_GET (echdr->ch_type);
6882 chdr->ch_size = BYTE_GET (echdr->ch_size);
6883 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6884 return sizeof (*echdr);
6885 }
6886 else
6887 {
6888 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6889
ebdf1ebf
NC
6890 if (size < sizeof (* echdr))
6891 {
6892 error (_("Compressed section is too small even for a compression header\n"));
6893 return 0;
6894 }
6895
77115a4a
L
6896 chdr->ch_type = BYTE_GET (echdr->ch_type);
6897 chdr->ch_size = BYTE_GET (echdr->ch_size);
6898 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6899 return sizeof (*echdr);
6900 }
6901}
6902
015dc7e1 6903static bool
dda8d76d 6904process_section_headers (Filedata * filedata)
252b5132 6905{
2cf0635d 6906 Elf_Internal_Shdr * section;
b34976b6 6907 unsigned int i;
252b5132 6908
dda8d76d 6909 if (filedata->file_header.e_shnum == 0)
252b5132 6910 {
82f2dbf7 6911 /* PR binutils/12467. */
dda8d76d 6912 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6913 {
6914 warn (_("possibly corrupt ELF file header - it has a non-zero"
6915 " section header offset, but no section headers\n"));
015dc7e1 6916 return false;
32ec8896 6917 }
82f2dbf7 6918 else if (do_sections)
252b5132
RH
6919 printf (_("\nThere are no sections in this file.\n"));
6920
015dc7e1 6921 return true;
252b5132
RH
6922 }
6923
6924 if (do_sections && !do_header)
ca0e11aa
NC
6925 {
6926 if (filedata->is_separate && process_links)
6927 printf (_("In linked file '%s': "), filedata->file_name);
6928 if (! filedata->is_separate || process_links)
6929 printf (ngettext ("There is %d section header, "
6930 "starting at offset 0x%lx:\n",
6931 "There are %d section headers, "
6932 "starting at offset 0x%lx:\n",
6933 filedata->file_header.e_shnum),
6934 filedata->file_header.e_shnum,
6935 (unsigned long) filedata->file_header.e_shoff);
6936 }
252b5132 6937
4de91c10
AM
6938 if (!get_section_headers (filedata, false))
6939 return false;
252b5132
RH
6940
6941 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6942 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6943 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6944 {
dda8d76d 6945 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6946
c256ffe7
JJ
6947 if (section->sh_size != 0)
6948 {
dda8d76d
NC
6949 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6950 1, section->sh_size,
6951 _("string table"));
0de14b54 6952
dda8d76d 6953 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6954 }
252b5132
RH
6955 }
6956
6957 /* Scan the sections for the dynamic symbol table
e3c8793a 6958 and dynamic string table and debug sections. */
89fac5e3 6959 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6960 switch (filedata->file_header.e_machine)
89fac5e3
RS
6961 {
6962 case EM_MIPS:
6963 case EM_MIPS_RS3_LE:
6964 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6965 FDE addresses. However, the ABI also has a semi-official ILP32
6966 variant for which the normal FDE address size rules apply.
6967
6968 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6969 section, where XX is the size of longs in bits. Unfortunately,
6970 earlier compilers provided no way of distinguishing ILP32 objects
6971 from LP64 objects, so if there's any doubt, we should assume that
6972 the official LP64 form is being used. */
dda8d76d
NC
6973 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6974 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6975 eh_addr_size = 8;
6976 break;
0f56a26a
DD
6977
6978 case EM_H8_300:
6979 case EM_H8_300H:
dda8d76d 6980 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6981 {
6982 case E_H8_MACH_H8300:
6983 case E_H8_MACH_H8300HN:
6984 case E_H8_MACH_H8300SN:
6985 case E_H8_MACH_H8300SXN:
6986 eh_addr_size = 2;
6987 break;
6988 case E_H8_MACH_H8300H:
6989 case E_H8_MACH_H8300S:
6990 case E_H8_MACH_H8300SX:
6991 eh_addr_size = 4;
6992 break;
6993 }
f4236fe4
DD
6994 break;
6995
ff7eeb89 6996 case EM_M32C_OLD:
f4236fe4 6997 case EM_M32C:
dda8d76d 6998 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6999 {
7000 case EF_M32C_CPU_M16C:
7001 eh_addr_size = 2;
7002 break;
7003 }
7004 break;
89fac5e3
RS
7005 }
7006
76ca31c0
NC
7007#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7008 do \
7009 { \
7010 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7011 if (section->sh_entsize != expected_entsize) \
9dd3a467 7012 { \
76ca31c0
NC
7013 char buf[40]; \
7014 sprintf_vma (buf, section->sh_entsize); \
7015 /* Note: coded this way so that there is a single string for \
7016 translation. */ \
7017 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7018 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7019 (unsigned) expected_entsize); \
9dd3a467 7020 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7021 } \
7022 } \
08d8fa11 7023 while (0)
9dd3a467
NC
7024
7025#define CHECK_ENTSIZE(section, i, type) \
1b513401 7026 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7027 sizeof (Elf64_External_##type))
7028
dda8d76d
NC
7029 for (i = 0, section = filedata->section_headers;
7030 i < filedata->file_header.e_shnum;
b34976b6 7031 i++, section++)
252b5132 7032 {
84714f86 7033 const char *name = section_name_print (filedata, section);
252b5132 7034
1b513401
NC
7035 /* Run some sanity checks on the headers and
7036 possibly fill in some file data as well. */
7037 switch (section->sh_type)
252b5132 7038 {
1b513401 7039 case SHT_DYNSYM:
978c4450 7040 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7041 {
7042 error (_("File contains multiple dynamic symbol tables\n"));
7043 continue;
7044 }
7045
08d8fa11 7046 CHECK_ENTSIZE (section, i, Sym);
978c4450 7047 filedata->dynamic_symbols
4de91c10 7048 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7049 filedata->dynamic_symtab_section = section;
1b513401
NC
7050 break;
7051
7052 case SHT_STRTAB:
7053 if (streq (name, ".dynstr"))
252b5132 7054 {
1b513401
NC
7055 if (filedata->dynamic_strings != NULL)
7056 {
7057 error (_("File contains multiple dynamic string tables\n"));
7058 continue;
7059 }
7060
7061 filedata->dynamic_strings
7062 = (char *) get_data (NULL, filedata, section->sh_offset,
7063 1, section->sh_size, _("dynamic strings"));
7064 filedata->dynamic_strings_length
7065 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7066 filedata->dynamic_strtab_section = section;
252b5132 7067 }
1b513401
NC
7068 break;
7069
7070 case SHT_SYMTAB_SHNDX:
7071 {
7072 elf_section_list * entry = xmalloc (sizeof * entry);
7073
7074 entry->hdr = section;
7075 entry->next = filedata->symtab_shndx_list;
7076 filedata->symtab_shndx_list = entry;
7077 }
7078 break;
7079
7080 case SHT_SYMTAB:
7081 CHECK_ENTSIZE (section, i, Sym);
7082 break;
7083
7084 case SHT_GROUP:
7085 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7086 break;
252b5132 7087
1b513401
NC
7088 case SHT_REL:
7089 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7090 if (do_checks && section->sh_size == 0)
1b513401
NC
7091 warn (_("Section '%s': zero-sized relocation section\n"), name);
7092 break;
7093
7094 case SHT_RELA:
7095 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7096 if (do_checks && section->sh_size == 0)
1b513401
NC
7097 warn (_("Section '%s': zero-sized relocation section\n"), name);
7098 break;
7099
682351b9
AM
7100 case SHT_RELR:
7101 CHECK_ENTSIZE (section, i, Relr);
7102 break;
7103
1b513401
NC
7104 case SHT_NOTE:
7105 case SHT_PROGBITS:
546cb2d8
NC
7106 /* Having a zero sized section is not illegal according to the
7107 ELF standard, but it might be an indication that something
7108 is wrong. So issue a warning if we are running in lint mode. */
7109 if (do_checks && section->sh_size == 0)
1b513401
NC
7110 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7111 break;
7112
7113 default:
7114 break;
7115 }
7116
7117 if ((do_debugging || do_debug_info || do_debug_abbrevs
7118 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7119 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7120 || do_debug_str || do_debug_str_offsets || do_debug_loc
7121 || do_debug_ranges
1b513401 7122 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7123 && (startswith (name, ".debug_")
7124 || startswith (name, ".zdebug_")))
252b5132 7125 {
1b315056
CS
7126 if (name[1] == 'z')
7127 name += sizeof (".zdebug_") - 1;
7128 else
7129 name += sizeof (".debug_") - 1;
252b5132
RH
7130
7131 if (do_debugging
24d127aa
ML
7132 || (do_debug_info && startswith (name, "info"))
7133 || (do_debug_info && startswith (name, "types"))
7134 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7135 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7136 || (do_debug_lines && startswith (name, "line."))
7137 || (do_debug_pubnames && startswith (name, "pubnames"))
7138 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7139 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7140 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7141 || (do_debug_aranges && startswith (name, "aranges"))
7142 || (do_debug_ranges && startswith (name, "ranges"))
7143 || (do_debug_ranges && startswith (name, "rnglists"))
7144 || (do_debug_frames && startswith (name, "frame"))
7145 || (do_debug_macinfo && startswith (name, "macinfo"))
7146 || (do_debug_macinfo && startswith (name, "macro"))
7147 || (do_debug_str && startswith (name, "str"))
7148 || (do_debug_links && startswith (name, "sup"))
7149 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7150 || (do_debug_loc && startswith (name, "loc"))
7151 || (do_debug_loc && startswith (name, "loclists"))
7152 || (do_debug_addr && startswith (name, "addr"))
7153 || (do_debug_cu_index && startswith (name, "cu_index"))
7154 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7155 )
6431e409 7156 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7157 }
a262ae96 7158 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7159 else if ((do_debugging || do_debug_info)
24d127aa 7160 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7161 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7162 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7163 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7164 else if (do_gdb_index && (streq (name, ".gdb_index")
7165 || streq (name, ".debug_names")))
6431e409 7166 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7167 /* Trace sections for Itanium VMS. */
7168 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7169 || do_trace_aranges)
24d127aa 7170 && startswith (name, ".trace_"))
6f875884
TG
7171 {
7172 name += sizeof (".trace_") - 1;
7173
7174 if (do_debugging
7175 || (do_trace_info && streq (name, "info"))
7176 || (do_trace_abbrevs && streq (name, "abbrev"))
7177 || (do_trace_aranges && streq (name, "aranges"))
7178 )
6431e409 7179 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7180 }
dda8d76d 7181 else if ((do_debugging || do_debug_links)
24d127aa
ML
7182 && (startswith (name, ".gnu_debuglink")
7183 || startswith (name, ".gnu_debugaltlink")))
6431e409 7184 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7185 }
7186
7187 if (! do_sections)
015dc7e1 7188 return true;
252b5132 7189
ca0e11aa 7190 if (filedata->is_separate && ! process_links)
015dc7e1 7191 return true;
ca0e11aa
NC
7192
7193 if (filedata->is_separate)
7194 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7195 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7196 printf (_("\nSection Headers:\n"));
7197 else
7198 printf (_("\nSection Header:\n"));
76da6bbe 7199
f7a99963 7200 if (is_32bit_elf)
595cf52e 7201 {
5477e8a0 7202 if (do_section_details)
595cf52e
L
7203 {
7204 printf (_(" [Nr] Name\n"));
5477e8a0 7205 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7206 }
7207 else
7208 printf
7209 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7210 }
d974e256 7211 else if (do_wide)
595cf52e 7212 {
5477e8a0 7213 if (do_section_details)
595cf52e
L
7214 {
7215 printf (_(" [Nr] Name\n"));
5477e8a0 7216 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7217 }
7218 else
7219 printf
7220 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7221 }
f7a99963
NC
7222 else
7223 {
5477e8a0 7224 if (do_section_details)
595cf52e
L
7225 {
7226 printf (_(" [Nr] Name\n"));
5477e8a0
L
7227 printf (_(" Type Address Offset Link\n"));
7228 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7229 }
7230 else
7231 {
7232 printf (_(" [Nr] Name Type Address Offset\n"));
7233 printf (_(" Size EntSize Flags Link Info Align\n"));
7234 }
f7a99963 7235 }
252b5132 7236
5477e8a0
L
7237 if (do_section_details)
7238 printf (_(" Flags\n"));
7239
dda8d76d
NC
7240 for (i = 0, section = filedata->section_headers;
7241 i < filedata->file_header.e_shnum;
b34976b6 7242 i++, section++)
252b5132 7243 {
dd905818
NC
7244 /* Run some sanity checks on the section header. */
7245
7246 /* Check the sh_link field. */
7247 switch (section->sh_type)
7248 {
285e3f99
AM
7249 case SHT_REL:
7250 case SHT_RELA:
7251 if (section->sh_link == 0
7252 && (filedata->file_header.e_type == ET_EXEC
7253 || filedata->file_header.e_type == ET_DYN))
7254 /* A dynamic relocation section where all entries use a
7255 zero symbol index need not specify a symtab section. */
7256 break;
7257 /* Fall through. */
dd905818
NC
7258 case SHT_SYMTAB_SHNDX:
7259 case SHT_GROUP:
7260 case SHT_HASH:
7261 case SHT_GNU_HASH:
7262 case SHT_GNU_versym:
285e3f99 7263 if (section->sh_link == 0
dda8d76d
NC
7264 || section->sh_link >= filedata->file_header.e_shnum
7265 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7266 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7267 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7268 i, section->sh_link);
7269 break;
7270
7271 case SHT_DYNAMIC:
7272 case SHT_SYMTAB:
7273 case SHT_DYNSYM:
7274 case SHT_GNU_verneed:
7275 case SHT_GNU_verdef:
7276 case SHT_GNU_LIBLIST:
285e3f99 7277 if (section->sh_link == 0
dda8d76d
NC
7278 || section->sh_link >= filedata->file_header.e_shnum
7279 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7280 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7281 i, section->sh_link);
7282 break;
7283
7284 case SHT_INIT_ARRAY:
7285 case SHT_FINI_ARRAY:
7286 case SHT_PREINIT_ARRAY:
7287 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7288 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7289 i, section->sh_link);
7290 break;
7291
7292 default:
7293 /* FIXME: Add support for target specific section types. */
7294#if 0 /* Currently we do not check other section types as there are too
7295 many special cases. Stab sections for example have a type
7296 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7297 section. */
7298 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7299 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7300 i, section->sh_link);
7301#endif
7302 break;
7303 }
7304
7305 /* Check the sh_info field. */
7306 switch (section->sh_type)
7307 {
7308 case SHT_REL:
7309 case SHT_RELA:
285e3f99
AM
7310 if (section->sh_info == 0
7311 && (filedata->file_header.e_type == ET_EXEC
7312 || filedata->file_header.e_type == ET_DYN))
7313 /* Dynamic relocations apply to segments, so they do not
7314 need to specify the section they relocate. */
7315 break;
7316 if (section->sh_info == 0
dda8d76d
NC
7317 || section->sh_info >= filedata->file_header.e_shnum
7318 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7319 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7320 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7321 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7322 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7323 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7324 /* FIXME: Are other section types valid ? */
dda8d76d 7325 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7326 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7327 i, section->sh_info);
dd905818
NC
7328 break;
7329
7330 case SHT_DYNAMIC:
7331 case SHT_HASH:
7332 case SHT_SYMTAB_SHNDX:
7333 case SHT_INIT_ARRAY:
7334 case SHT_FINI_ARRAY:
7335 case SHT_PREINIT_ARRAY:
7336 if (section->sh_info != 0)
7337 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7338 i, section->sh_info);
7339 break;
7340
7341 case SHT_GROUP:
7342 case SHT_SYMTAB:
7343 case SHT_DYNSYM:
7344 /* A symbol index - we assume that it is valid. */
7345 break;
7346
7347 default:
7348 /* FIXME: Add support for target specific section types. */
7349 if (section->sh_type == SHT_NOBITS)
7350 /* NOBITS section headers with non-zero sh_info fields can be
7351 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7352 information. The stripped sections have their headers
7353 preserved but their types set to SHT_NOBITS. So do not check
7354 this type of section. */
dd905818
NC
7355 ;
7356 else if (section->sh_flags & SHF_INFO_LINK)
7357 {
dda8d76d 7358 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7359 warn (_("[%2u]: Expected link to another section in info field"), i);
7360 }
a91e1603
L
7361 else if (section->sh_type < SHT_LOOS
7362 && (section->sh_flags & SHF_GNU_MBIND) == 0
7363 && section->sh_info != 0)
dd905818
NC
7364 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7365 i, section->sh_info);
7366 break;
7367 }
7368
3e6b6445 7369 /* Check the sh_size field. */
dda8d76d 7370 if (section->sh_size > filedata->file_size
3e6b6445
NC
7371 && section->sh_type != SHT_NOBITS
7372 && section->sh_type != SHT_NULL
7373 && section->sh_type < SHT_LOOS)
7374 warn (_("Size of section %u is larger than the entire file!\n"), i);
7375
7bfd842d 7376 printf (" [%2u] ", i);
5477e8a0 7377 if (do_section_details)
dda8d76d 7378 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7379 else
84714f86 7380 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7381
ea52a088 7382 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7383 get_section_type_name (filedata, section->sh_type));
0b4362b0 7384
f7a99963
NC
7385 if (is_32bit_elf)
7386 {
cfcac11d
NC
7387 const char * link_too_big = NULL;
7388
f7a99963 7389 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7390
f7a99963
NC
7391 printf ( " %6.6lx %6.6lx %2.2lx",
7392 (unsigned long) section->sh_offset,
7393 (unsigned long) section->sh_size,
7394 (unsigned long) section->sh_entsize);
d1133906 7395
5477e8a0
L
7396 if (do_section_details)
7397 fputs (" ", stdout);
7398 else
dda8d76d 7399 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7400
dda8d76d 7401 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7402 {
7403 link_too_big = "";
7404 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7405 an error but it can have special values in Solaris binaries. */
dda8d76d 7406 switch (filedata->file_header.e_machine)
cfcac11d 7407 {
caa83f8b 7408 case EM_386:
22abe556 7409 case EM_IAMCU:
caa83f8b 7410 case EM_X86_64:
7f502d6c 7411 case EM_L1OM:
7a9068fe 7412 case EM_K1OM:
cfcac11d
NC
7413 case EM_OLD_SPARCV9:
7414 case EM_SPARC32PLUS:
7415 case EM_SPARCV9:
7416 case EM_SPARC:
7417 if (section->sh_link == (SHN_BEFORE & 0xffff))
7418 link_too_big = "BEFORE";
7419 else if (section->sh_link == (SHN_AFTER & 0xffff))
7420 link_too_big = "AFTER";
7421 break;
7422 default:
7423 break;
7424 }
7425 }
7426
7427 if (do_section_details)
7428 {
7429 if (link_too_big != NULL && * link_too_big)
7430 printf ("<%s> ", link_too_big);
7431 else
7432 printf ("%2u ", section->sh_link);
7433 printf ("%3u %2lu\n", section->sh_info,
7434 (unsigned long) section->sh_addralign);
7435 }
7436 else
7437 printf ("%2u %3u %2lu\n",
7438 section->sh_link,
7439 section->sh_info,
7440 (unsigned long) section->sh_addralign);
7441
7442 if (link_too_big && ! * link_too_big)
7443 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7444 i, section->sh_link);
f7a99963 7445 }
d974e256
JJ
7446 else if (do_wide)
7447 {
7448 print_vma (section->sh_addr, LONG_HEX);
7449
7450 if ((long) section->sh_offset == section->sh_offset)
7451 printf (" %6.6lx", (unsigned long) section->sh_offset);
7452 else
7453 {
7454 putchar (' ');
7455 print_vma (section->sh_offset, LONG_HEX);
7456 }
7457
7458 if ((unsigned long) section->sh_size == section->sh_size)
7459 printf (" %6.6lx", (unsigned long) section->sh_size);
7460 else
7461 {
7462 putchar (' ');
7463 print_vma (section->sh_size, LONG_HEX);
7464 }
7465
7466 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7467 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7468 else
7469 {
7470 putchar (' ');
7471 print_vma (section->sh_entsize, LONG_HEX);
7472 }
7473
5477e8a0
L
7474 if (do_section_details)
7475 fputs (" ", stdout);
7476 else
dda8d76d 7477 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7478
72de5009 7479 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7480
7481 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7482 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7483 else
7484 {
7485 print_vma (section->sh_addralign, DEC);
7486 putchar ('\n');
7487 }
7488 }
5477e8a0 7489 else if (do_section_details)
595cf52e 7490 {
55cc53e9 7491 putchar (' ');
595cf52e
L
7492 print_vma (section->sh_addr, LONG_HEX);
7493 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7494 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7495 else
7496 {
7497 printf (" ");
7498 print_vma (section->sh_offset, LONG_HEX);
7499 }
72de5009 7500 printf (" %u\n ", section->sh_link);
595cf52e 7501 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7502 putchar (' ');
595cf52e
L
7503 print_vma (section->sh_entsize, LONG_HEX);
7504
72de5009
AM
7505 printf (" %-16u %lu\n",
7506 section->sh_info,
595cf52e
L
7507 (unsigned long) section->sh_addralign);
7508 }
f7a99963
NC
7509 else
7510 {
7511 putchar (' ');
7512 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7513 if ((long) section->sh_offset == section->sh_offset)
7514 printf (" %8.8lx", (unsigned long) section->sh_offset);
7515 else
7516 {
7517 printf (" ");
7518 print_vma (section->sh_offset, LONG_HEX);
7519 }
f7a99963
NC
7520 printf ("\n ");
7521 print_vma (section->sh_size, LONG_HEX);
7522 printf (" ");
7523 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7524
dda8d76d 7525 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7526
72de5009
AM
7527 printf (" %2u %3u %lu\n",
7528 section->sh_link,
7529 section->sh_info,
f7a99963
NC
7530 (unsigned long) section->sh_addralign);
7531 }
5477e8a0
L
7532
7533 if (do_section_details)
77115a4a 7534 {
dda8d76d 7535 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7536 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7537 {
7538 /* Minimum section size is 12 bytes for 32-bit compression
7539 header + 12 bytes for compressed data header. */
7540 unsigned char buf[24];
d8024a91 7541
77115a4a 7542 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7543 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7544 sizeof (buf), _("compression header")))
7545 {
7546 Elf_Internal_Chdr chdr;
d8024a91 7547
5844b465
NC
7548 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7549 printf (_(" [<corrupt>]\n"));
77115a4a 7550 else
5844b465
NC
7551 {
7552 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7553 printf (" ZLIB, ");
7554 else
7555 printf (_(" [<unknown>: 0x%x], "),
7556 chdr.ch_type);
7557 print_vma (chdr.ch_size, LONG_HEX);
7558 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7559 }
77115a4a
L
7560 }
7561 }
7562 }
252b5132
RH
7563 }
7564
5477e8a0 7565 if (!do_section_details)
3dbcc61d 7566 {
9fb71ee4
NC
7567 /* The ordering of the letters shown here matches the ordering of the
7568 corresponding SHF_xxx values, and hence the order in which these
7569 letters will be displayed to the user. */
7570 printf (_("Key to Flags:\n\
7571 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7572 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7573 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7574 switch (filedata->file_header.e_ident[EI_OSABI])
7575 {
7576 case ELFOSABI_GNU:
7577 case ELFOSABI_FREEBSD:
7578 printf (_("R (retain), "));
7579 /* Fall through */
7580 case ELFOSABI_NONE:
7581 printf (_("D (mbind), "));
7582 break;
7583 default:
7584 break;
7585 }
dda8d76d
NC
7586 if (filedata->file_header.e_machine == EM_X86_64
7587 || filedata->file_header.e_machine == EM_L1OM
7588 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7589 printf (_("l (large), "));
dda8d76d 7590 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7591 printf (_("y (purecode), "));
dda8d76d 7592 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7593 printf (_("v (VLE), "));
9fb71ee4 7594 printf ("p (processor specific)\n");
0b4362b0 7595 }
d1133906 7596
015dc7e1 7597 return true;
252b5132
RH
7598}
7599
015dc7e1 7600static bool
28d13567
AM
7601get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7602 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7603 char **strtab, unsigned long *strtablen)
7604{
7605 *strtab = NULL;
7606 *strtablen = 0;
4de91c10 7607 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7608
7609 if (*symtab == NULL)
015dc7e1 7610 return false;
28d13567
AM
7611
7612 if (symsec->sh_link != 0)
7613 {
7614 Elf_Internal_Shdr *strsec;
7615
7616 if (symsec->sh_link >= filedata->file_header.e_shnum)
7617 {
7618 error (_("Bad sh_link in symbol table section\n"));
7619 free (*symtab);
7620 *symtab = NULL;
7621 *nsyms = 0;
015dc7e1 7622 return false;
28d13567
AM
7623 }
7624
7625 strsec = filedata->section_headers + symsec->sh_link;
7626
7627 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7628 1, strsec->sh_size, _("string table"));
7629 if (*strtab == NULL)
7630 {
7631 free (*symtab);
7632 *symtab = NULL;
7633 *nsyms = 0;
015dc7e1 7634 return false;
28d13567
AM
7635 }
7636 *strtablen = strsec->sh_size;
7637 }
015dc7e1 7638 return true;
28d13567
AM
7639}
7640
f5842774
L
7641static const char *
7642get_group_flags (unsigned int flags)
7643{
1449284b 7644 static char buff[128];
220453ec 7645
6d913794
NC
7646 if (flags == 0)
7647 return "";
7648 else if (flags == GRP_COMDAT)
7649 return "COMDAT ";
f5842774 7650
89246a0e
AM
7651 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7652 flags,
7653 flags & GRP_MASKOS ? _("<OS specific>") : "",
7654 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7655 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7656 ? _("<unknown>") : ""));
6d913794 7657
f5842774
L
7658 return buff;
7659}
7660
015dc7e1 7661static bool
dda8d76d 7662process_section_groups (Filedata * filedata)
f5842774 7663{
2cf0635d 7664 Elf_Internal_Shdr * section;
f5842774 7665 unsigned int i;
2cf0635d
NC
7666 struct group * group;
7667 Elf_Internal_Shdr * symtab_sec;
7668 Elf_Internal_Shdr * strtab_sec;
7669 Elf_Internal_Sym * symtab;
ba5cdace 7670 unsigned long num_syms;
2cf0635d 7671 char * strtab;
c256ffe7 7672 size_t strtab_size;
d1f5c6e3
L
7673
7674 /* Don't process section groups unless needed. */
7675 if (!do_unwind && !do_section_groups)
015dc7e1 7676 return true;
f5842774 7677
dda8d76d 7678 if (filedata->file_header.e_shnum == 0)
f5842774
L
7679 {
7680 if (do_section_groups)
ca0e11aa
NC
7681 {
7682 if (filedata->is_separate)
7683 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7684 filedata->file_name);
7685 else
7686 printf (_("\nThere are no section groups in this file.\n"));
7687 }
015dc7e1 7688 return true;
f5842774
L
7689 }
7690
dda8d76d 7691 if (filedata->section_headers == NULL)
f5842774
L
7692 {
7693 error (_("Section headers are not available!\n"));
fa1908fd 7694 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7695 return false;
f5842774
L
7696 }
7697
978c4450
AM
7698 filedata->section_headers_groups
7699 = (struct group **) calloc (filedata->file_header.e_shnum,
7700 sizeof (struct group *));
e4b17d5c 7701
978c4450 7702 if (filedata->section_headers_groups == NULL)
e4b17d5c 7703 {
8b73c356 7704 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7705 filedata->file_header.e_shnum);
015dc7e1 7706 return false;
e4b17d5c
L
7707 }
7708
f5842774 7709 /* Scan the sections for the group section. */
978c4450 7710 filedata->group_count = 0;
dda8d76d
NC
7711 for (i = 0, section = filedata->section_headers;
7712 i < filedata->file_header.e_shnum;
f5842774 7713 i++, section++)
e4b17d5c 7714 if (section->sh_type == SHT_GROUP)
978c4450 7715 filedata->group_count++;
e4b17d5c 7716
978c4450 7717 if (filedata->group_count == 0)
d1f5c6e3
L
7718 {
7719 if (do_section_groups)
ca0e11aa
NC
7720 {
7721 if (filedata->is_separate)
7722 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7723 filedata->file_name);
7724 else
7725 printf (_("\nThere are no section groups in this file.\n"));
7726 }
d1f5c6e3 7727
015dc7e1 7728 return true;
d1f5c6e3
L
7729 }
7730
978c4450
AM
7731 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7732 sizeof (struct group));
e4b17d5c 7733
978c4450 7734 if (filedata->section_groups == NULL)
e4b17d5c 7735 {
8b73c356 7736 error (_("Out of memory reading %lu groups\n"),
978c4450 7737 (unsigned long) filedata->group_count);
015dc7e1 7738 return false;
e4b17d5c
L
7739 }
7740
d1f5c6e3
L
7741 symtab_sec = NULL;
7742 strtab_sec = NULL;
7743 symtab = NULL;
ba5cdace 7744 num_syms = 0;
d1f5c6e3 7745 strtab = NULL;
c256ffe7 7746 strtab_size = 0;
ca0e11aa
NC
7747
7748 if (filedata->is_separate)
7749 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7750
978c4450 7751 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7752 i < filedata->file_header.e_shnum;
e4b17d5c 7753 i++, section++)
f5842774
L
7754 {
7755 if (section->sh_type == SHT_GROUP)
7756 {
dda8d76d 7757 const char * name = printable_section_name (filedata, section);
74e1a04b 7758 const char * group_name;
2cf0635d
NC
7759 unsigned char * start;
7760 unsigned char * indices;
f5842774 7761 unsigned int entry, j, size;
2cf0635d
NC
7762 Elf_Internal_Shdr * sec;
7763 Elf_Internal_Sym * sym;
f5842774
L
7764
7765 /* Get the symbol table. */
dda8d76d
NC
7766 if (section->sh_link >= filedata->file_header.e_shnum
7767 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7768 != SHT_SYMTAB))
f5842774
L
7769 {
7770 error (_("Bad sh_link in group section `%s'\n"), name);
7771 continue;
7772 }
d1f5c6e3
L
7773
7774 if (symtab_sec != sec)
7775 {
7776 symtab_sec = sec;
9db70fc3 7777 free (symtab);
4de91c10 7778 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7779 }
f5842774 7780
dd24e3da
NC
7781 if (symtab == NULL)
7782 {
7783 error (_("Corrupt header in group section `%s'\n"), name);
7784 continue;
7785 }
7786
ba5cdace
NC
7787 if (section->sh_info >= num_syms)
7788 {
7789 error (_("Bad sh_info in group section `%s'\n"), name);
7790 continue;
7791 }
7792
f5842774
L
7793 sym = symtab + section->sh_info;
7794
7795 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7796 {
4fbb74a6 7797 if (sym->st_shndx == 0
dda8d76d 7798 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7799 {
7800 error (_("Bad sh_info in group section `%s'\n"), name);
7801 continue;
7802 }
ba2685cc 7803
84714f86
AM
7804 group_name = section_name_print (filedata,
7805 filedata->section_headers
b9e920ec 7806 + sym->st_shndx);
c256ffe7 7807 strtab_sec = NULL;
9db70fc3 7808 free (strtab);
f5842774 7809 strtab = NULL;
c256ffe7 7810 strtab_size = 0;
f5842774
L
7811 }
7812 else
7813 {
7814 /* Get the string table. */
dda8d76d 7815 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7816 {
7817 strtab_sec = NULL;
9db70fc3 7818 free (strtab);
c256ffe7
JJ
7819 strtab = NULL;
7820 strtab_size = 0;
7821 }
7822 else if (strtab_sec
dda8d76d 7823 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7824 {
7825 strtab_sec = sec;
9db70fc3 7826 free (strtab);
071436c6 7827
dda8d76d 7828 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7829 1, strtab_sec->sh_size,
7830 _("string table"));
c256ffe7 7831 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7832 }
c256ffe7 7833 group_name = sym->st_name < strtab_size
2b692964 7834 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7835 }
7836
c9c1d674
EG
7837 /* PR 17531: file: loop. */
7838 if (section->sh_entsize > section->sh_size)
7839 {
7840 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7841 printable_section_name (filedata, section),
8066deb1
AM
7842 (unsigned long) section->sh_entsize,
7843 (unsigned long) section->sh_size);
61dd8e19 7844 continue;
c9c1d674
EG
7845 }
7846
dda8d76d 7847 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7848 1, section->sh_size,
7849 _("section data"));
59245841
NC
7850 if (start == NULL)
7851 continue;
f5842774
L
7852
7853 indices = start;
7854 size = (section->sh_size / section->sh_entsize) - 1;
7855 entry = byte_get (indices, 4);
7856 indices += 4;
e4b17d5c
L
7857
7858 if (do_section_groups)
7859 {
2b692964 7860 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7861 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7862
e4b17d5c
L
7863 printf (_(" [Index] Name\n"));
7864 }
7865
7866 group->group_index = i;
7867
f5842774
L
7868 for (j = 0; j < size; j++)
7869 {
2cf0635d 7870 struct group_list * g;
e4b17d5c 7871
f5842774
L
7872 entry = byte_get (indices, 4);
7873 indices += 4;
7874
dda8d76d 7875 if (entry >= filedata->file_header.e_shnum)
391cb864 7876 {
57028622
NC
7877 static unsigned num_group_errors = 0;
7878
7879 if (num_group_errors ++ < 10)
7880 {
7881 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7882 entry, i, filedata->file_header.e_shnum - 1);
57028622 7883 if (num_group_errors == 10)
67ce483b 7884 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7885 }
391cb864
L
7886 continue;
7887 }
391cb864 7888
978c4450 7889 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7890 {
d1f5c6e3
L
7891 if (entry)
7892 {
57028622
NC
7893 static unsigned num_errs = 0;
7894
7895 if (num_errs ++ < 10)
7896 {
7897 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7898 entry, i,
978c4450 7899 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7900 if (num_errs == 10)
7901 warn (_("Further error messages about already contained group sections suppressed\n"));
7902 }
d1f5c6e3
L
7903 continue;
7904 }
7905 else
7906 {
7907 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7908 section group. We just warn it the first time
d1f5c6e3 7909 and ignore it afterwards. */
015dc7e1 7910 static bool warned = false;
d1f5c6e3
L
7911 if (!warned)
7912 {
7913 error (_("section 0 in group section [%5u]\n"),
978c4450 7914 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7915 warned = true;
d1f5c6e3
L
7916 }
7917 }
e4b17d5c
L
7918 }
7919
978c4450 7920 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7921
7922 if (do_section_groups)
7923 {
dda8d76d
NC
7924 sec = filedata->section_headers + entry;
7925 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7926 }
7927
3f5e193b 7928 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7929 g->section_index = entry;
7930 g->next = group->root;
7931 group->root = g;
f5842774
L
7932 }
7933
9db70fc3 7934 free (start);
e4b17d5c
L
7935
7936 group++;
f5842774
L
7937 }
7938 }
7939
9db70fc3
AM
7940 free (symtab);
7941 free (strtab);
015dc7e1 7942 return true;
f5842774
L
7943}
7944
28f997cf
TG
7945/* Data used to display dynamic fixups. */
7946
7947struct ia64_vms_dynfixup
7948{
7949 bfd_vma needed_ident; /* Library ident number. */
7950 bfd_vma needed; /* Index in the dstrtab of the library name. */
7951 bfd_vma fixup_needed; /* Index of the library. */
7952 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7953 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7954};
7955
7956/* Data used to display dynamic relocations. */
7957
7958struct ia64_vms_dynimgrela
7959{
7960 bfd_vma img_rela_cnt; /* Number of relocations. */
7961 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7962};
7963
7964/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7965 library). */
7966
015dc7e1 7967static bool
dda8d76d
NC
7968dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7969 struct ia64_vms_dynfixup * fixup,
7970 const char * strtab,
7971 unsigned int strtab_sz)
28f997cf 7972{
32ec8896 7973 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7974 long i;
32ec8896 7975 const char * lib_name;
28f997cf 7976
978c4450
AM
7977 imfs = get_data (NULL, filedata,
7978 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7979 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7980 _("dynamic section image fixups"));
7981 if (!imfs)
015dc7e1 7982 return false;
28f997cf
TG
7983
7984 if (fixup->needed < strtab_sz)
7985 lib_name = strtab + fixup->needed;
7986 else
7987 {
32ec8896 7988 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7989 (unsigned long) fixup->needed);
28f997cf
TG
7990 lib_name = "???";
7991 }
736990c4 7992
28f997cf
TG
7993 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7994 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7995 printf
7996 (_("Seg Offset Type SymVec DataType\n"));
7997
7998 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7999 {
8000 unsigned int type;
8001 const char *rtype;
8002
8003 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8004 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
8005 type = BYTE_GET (imfs [i].type);
8006 rtype = elf_ia64_reloc_type (type);
8007 if (rtype == NULL)
8008 printf (" 0x%08x ", type);
8009 else
8010 printf (" %-32s ", rtype);
8011 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8012 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8013 }
8014
8015 free (imfs);
015dc7e1 8016 return true;
28f997cf
TG
8017}
8018
8019/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8020
015dc7e1 8021static bool
dda8d76d 8022dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8023{
8024 Elf64_External_VMS_IMAGE_RELA *imrs;
8025 long i;
8026
978c4450
AM
8027 imrs = get_data (NULL, filedata,
8028 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8029 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8030 _("dynamic section image relocations"));
28f997cf 8031 if (!imrs)
015dc7e1 8032 return false;
28f997cf
TG
8033
8034 printf (_("\nImage relocs\n"));
8035 printf
8036 (_("Seg Offset Type Addend Seg Sym Off\n"));
8037
8038 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8039 {
8040 unsigned int type;
8041 const char *rtype;
8042
8043 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8044 printf ("%08" BFD_VMA_FMT "x ",
8045 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8046 type = BYTE_GET (imrs [i].type);
8047 rtype = elf_ia64_reloc_type (type);
8048 if (rtype == NULL)
8049 printf ("0x%08x ", type);
8050 else
8051 printf ("%-31s ", rtype);
8052 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8053 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8054 printf ("%08" BFD_VMA_FMT "x\n",
8055 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8056 }
8057
8058 free (imrs);
015dc7e1 8059 return true;
28f997cf
TG
8060}
8061
8062/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8063
015dc7e1 8064static bool
dda8d76d 8065process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8066{
8067 struct ia64_vms_dynfixup fixup;
8068 struct ia64_vms_dynimgrela imgrela;
8069 Elf_Internal_Dyn *entry;
28f997cf
TG
8070 bfd_vma strtab_off = 0;
8071 bfd_vma strtab_sz = 0;
8072 char *strtab = NULL;
015dc7e1 8073 bool res = true;
28f997cf
TG
8074
8075 memset (&fixup, 0, sizeof (fixup));
8076 memset (&imgrela, 0, sizeof (imgrela));
8077
8078 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8079 for (entry = filedata->dynamic_section;
8080 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8081 entry++)
8082 {
8083 switch (entry->d_tag)
8084 {
8085 case DT_IA_64_VMS_STRTAB_OFFSET:
8086 strtab_off = entry->d_un.d_val;
8087 break;
8088 case DT_STRSZ:
8089 strtab_sz = entry->d_un.d_val;
8090 if (strtab == NULL)
978c4450
AM
8091 strtab = get_data (NULL, filedata,
8092 filedata->dynamic_addr + strtab_off,
28f997cf 8093 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8094 if (strtab == NULL)
8095 strtab_sz = 0;
28f997cf
TG
8096 break;
8097
8098 case DT_IA_64_VMS_NEEDED_IDENT:
8099 fixup.needed_ident = entry->d_un.d_val;
8100 break;
8101 case DT_NEEDED:
8102 fixup.needed = entry->d_un.d_val;
8103 break;
8104 case DT_IA_64_VMS_FIXUP_NEEDED:
8105 fixup.fixup_needed = entry->d_un.d_val;
8106 break;
8107 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8108 fixup.fixup_rela_cnt = entry->d_un.d_val;
8109 break;
8110 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8111 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8112 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8113 res = false;
28f997cf 8114 break;
28f997cf
TG
8115 case DT_IA_64_VMS_IMG_RELA_CNT:
8116 imgrela.img_rela_cnt = entry->d_un.d_val;
8117 break;
8118 case DT_IA_64_VMS_IMG_RELA_OFF:
8119 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8120 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8121 res = false;
28f997cf
TG
8122 break;
8123
8124 default:
8125 break;
8126 }
8127 }
8128
9db70fc3 8129 free (strtab);
28f997cf
TG
8130
8131 return res;
8132}
8133
85b1c36d 8134static struct
566b0d53 8135{
2cf0635d 8136 const char * name;
566b0d53
L
8137 int reloc;
8138 int size;
a7fd1186 8139 relocation_type rel_type;
32ec8896
NC
8140}
8141 dynamic_relocations [] =
566b0d53 8142{
a7fd1186
FS
8143 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8144 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8145 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8146 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8147};
8148
252b5132 8149/* Process the reloc section. */
18bd398b 8150
015dc7e1 8151static bool
dda8d76d 8152process_relocs (Filedata * filedata)
252b5132 8153{
b34976b6
AM
8154 unsigned long rel_size;
8155 unsigned long rel_offset;
252b5132 8156
252b5132 8157 if (!do_reloc)
015dc7e1 8158 return true;
252b5132
RH
8159
8160 if (do_using_dynamic)
8161 {
a7fd1186 8162 relocation_type rel_type;
2cf0635d 8163 const char * name;
015dc7e1 8164 bool has_dynamic_reloc;
566b0d53 8165 unsigned int i;
0de14b54 8166
015dc7e1 8167 has_dynamic_reloc = false;
252b5132 8168
566b0d53 8169 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8170 {
a7fd1186 8171 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8172 name = dynamic_relocations [i].name;
978c4450
AM
8173 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8174 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8175
32ec8896 8176 if (rel_size)
015dc7e1 8177 has_dynamic_reloc = true;
566b0d53 8178
a7fd1186 8179 if (rel_type == reltype_unknown)
aa903cfb 8180 {
566b0d53 8181 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8182 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8183 {
8184 case DT_REL:
a7fd1186 8185 rel_type = reltype_rel;
566b0d53
L
8186 break;
8187 case DT_RELA:
a7fd1186 8188 rel_type = reltype_rela;
566b0d53
L
8189 break;
8190 }
aa903cfb 8191 }
252b5132 8192
566b0d53
L
8193 if (rel_size)
8194 {
ca0e11aa
NC
8195 if (filedata->is_separate)
8196 printf
8197 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8198 filedata->file_name, name, rel_offset, rel_size);
8199 else
8200 printf
8201 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8202 name, rel_offset, rel_size);
252b5132 8203
dda8d76d
NC
8204 dump_relocations (filedata,
8205 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8206 rel_size,
978c4450
AM
8207 filedata->dynamic_symbols,
8208 filedata->num_dynamic_syms,
8209 filedata->dynamic_strings,
8210 filedata->dynamic_strings_length,
a7fd1186 8211 rel_type, true /* is_dynamic */);
566b0d53 8212 }
252b5132 8213 }
566b0d53 8214
dda8d76d
NC
8215 if (is_ia64_vms (filedata))
8216 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8217 has_dynamic_reloc = true;
28f997cf 8218
566b0d53 8219 if (! has_dynamic_reloc)
ca0e11aa
NC
8220 {
8221 if (filedata->is_separate)
8222 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8223 filedata->file_name);
8224 else
8225 printf (_("\nThere are no dynamic relocations in this file.\n"));
8226 }
252b5132
RH
8227 }
8228 else
8229 {
2cf0635d 8230 Elf_Internal_Shdr * section;
b34976b6 8231 unsigned long i;
015dc7e1 8232 bool found = false;
252b5132 8233
dda8d76d
NC
8234 for (i = 0, section = filedata->section_headers;
8235 i < filedata->file_header.e_shnum;
b34976b6 8236 i++, section++)
252b5132
RH
8237 {
8238 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8239 && section->sh_type != SHT_REL
8240 && section->sh_type != SHT_RELR)
252b5132
RH
8241 continue;
8242
8243 rel_offset = section->sh_offset;
8244 rel_size = section->sh_size;
8245
8246 if (rel_size)
8247 {
a7fd1186 8248 relocation_type rel_type;
d3a49aa8 8249 unsigned long num_rela;
103f02d3 8250
ca0e11aa
NC
8251 if (filedata->is_separate)
8252 printf (_("\nIn linked file '%s' relocation section "),
8253 filedata->file_name);
8254 else
8255 printf (_("\nRelocation section "));
252b5132 8256
dda8d76d 8257 if (filedata->string_table == NULL)
19936277 8258 printf ("%d", section->sh_name);
252b5132 8259 else
dda8d76d 8260 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8261
d3a49aa8
AM
8262 num_rela = rel_size / section->sh_entsize;
8263 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8264 " at offset 0x%lx contains %lu entries:\n",
8265 num_rela),
8266 rel_offset, num_rela);
252b5132 8267
a7fd1186
FS
8268 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8269 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8270
4fbb74a6 8271 if (section->sh_link != 0
dda8d76d 8272 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8273 {
2cf0635d
NC
8274 Elf_Internal_Shdr * symsec;
8275 Elf_Internal_Sym * symtab;
d79b3d50 8276 unsigned long nsyms;
c256ffe7 8277 unsigned long strtablen = 0;
2cf0635d 8278 char * strtab = NULL;
57346661 8279
dda8d76d 8280 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8281 if (symsec->sh_type != SHT_SYMTAB
8282 && symsec->sh_type != SHT_DYNSYM)
8283 continue;
8284
28d13567
AM
8285 if (!get_symtab (filedata, symsec,
8286 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8287 continue;
252b5132 8288
dda8d76d 8289 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8290 symtab, nsyms, strtab, strtablen,
a7fd1186 8291 rel_type,
bb4d2ac2 8292 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8293 free (strtab);
d79b3d50
NC
8294 free (symtab);
8295 }
8296 else
dda8d76d 8297 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8298 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8299
015dc7e1 8300 found = true;
252b5132
RH
8301 }
8302 }
8303
8304 if (! found)
45ac8f4f
NC
8305 {
8306 /* Users sometimes forget the -D option, so try to be helpful. */
8307 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8308 {
978c4450 8309 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8310 {
ca0e11aa
NC
8311 if (filedata->is_separate)
8312 printf (_("\nThere are no static relocations in linked file '%s'."),
8313 filedata->file_name);
8314 else
8315 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8316 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8317
8318 break;
8319 }
8320 }
8321 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8322 {
8323 if (filedata->is_separate)
8324 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8325 filedata->file_name);
8326 else
8327 printf (_("\nThere are no relocations in this file.\n"));
8328 }
45ac8f4f 8329 }
252b5132
RH
8330 }
8331
015dc7e1 8332 return true;
252b5132
RH
8333}
8334
4d6ed7c8
NC
8335/* An absolute address consists of a section and an offset. If the
8336 section is NULL, the offset itself is the address, otherwise, the
8337 address equals to LOAD_ADDRESS(section) + offset. */
8338
8339struct absaddr
948f632f
DA
8340{
8341 unsigned short section;
8342 bfd_vma offset;
8343};
4d6ed7c8 8344
948f632f
DA
8345/* Find the nearest symbol at or below ADDR. Returns the symbol
8346 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8347
4d6ed7c8 8348static void
dda8d76d
NC
8349find_symbol_for_address (Filedata * filedata,
8350 Elf_Internal_Sym * symtab,
8351 unsigned long nsyms,
8352 const char * strtab,
8353 unsigned long strtab_size,
8354 struct absaddr addr,
8355 const char ** symname,
8356 bfd_vma * offset)
4d6ed7c8 8357{
d3ba0551 8358 bfd_vma dist = 0x100000;
2cf0635d 8359 Elf_Internal_Sym * sym;
948f632f
DA
8360 Elf_Internal_Sym * beg;
8361 Elf_Internal_Sym * end;
2cf0635d 8362 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8363
0b6ae522 8364 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8365 beg = symtab;
8366 end = symtab + nsyms;
0b6ae522 8367
948f632f 8368 while (beg < end)
4d6ed7c8 8369 {
948f632f
DA
8370 bfd_vma value;
8371
8372 sym = beg + (end - beg) / 2;
0b6ae522 8373
948f632f 8374 value = sym->st_value;
0b6ae522
DJ
8375 REMOVE_ARCH_BITS (value);
8376
948f632f 8377 if (sym->st_name != 0
4d6ed7c8 8378 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8379 && addr.offset >= value
8380 && addr.offset - value < dist)
4d6ed7c8
NC
8381 {
8382 best = sym;
0b6ae522 8383 dist = addr.offset - value;
4d6ed7c8
NC
8384 if (!dist)
8385 break;
8386 }
948f632f
DA
8387
8388 if (addr.offset < value)
8389 end = sym;
8390 else
8391 beg = sym + 1;
4d6ed7c8 8392 }
1b31d05e 8393
4d6ed7c8
NC
8394 if (best)
8395 {
57346661 8396 *symname = (best->st_name >= strtab_size
2b692964 8397 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8398 *offset = dist;
8399 return;
8400 }
1b31d05e 8401
4d6ed7c8
NC
8402 *symname = NULL;
8403 *offset = addr.offset;
8404}
8405
32ec8896 8406static /* signed */ int
948f632f
DA
8407symcmp (const void *p, const void *q)
8408{
8409 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8410 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8411
8412 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8413}
8414
8415/* Process the unwind section. */
8416
8417#include "unwind-ia64.h"
8418
8419struct ia64_unw_table_entry
8420{
8421 struct absaddr start;
8422 struct absaddr end;
8423 struct absaddr info;
8424};
8425
8426struct ia64_unw_aux_info
8427{
32ec8896
NC
8428 struct ia64_unw_table_entry * table; /* Unwind table. */
8429 unsigned long table_len; /* Length of unwind table. */
8430 unsigned char * info; /* Unwind info. */
8431 unsigned long info_size; /* Size of unwind info. */
8432 bfd_vma info_addr; /* Starting address of unwind info. */
8433 bfd_vma seg_base; /* Starting address of segment. */
8434 Elf_Internal_Sym * symtab; /* The symbol table. */
8435 unsigned long nsyms; /* Number of symbols. */
8436 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8437 unsigned long nfuns; /* Number of entries in funtab. */
8438 char * strtab; /* The string table. */
8439 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8440};
8441
015dc7e1 8442static bool
dda8d76d 8443dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8444{
2cf0635d 8445 struct ia64_unw_table_entry * tp;
948f632f 8446 unsigned long j, nfuns;
4d6ed7c8 8447 int in_body;
015dc7e1 8448 bool res = true;
7036c0e1 8449
948f632f
DA
8450 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8451 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8452 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8453 aux->funtab[nfuns++] = aux->symtab[j];
8454 aux->nfuns = nfuns;
8455 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8456
4d6ed7c8
NC
8457 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8458 {
8459 bfd_vma stamp;
8460 bfd_vma offset;
2cf0635d
NC
8461 const unsigned char * dp;
8462 const unsigned char * head;
53774b7e 8463 const unsigned char * end;
2cf0635d 8464 const char * procname;
4d6ed7c8 8465
dda8d76d 8466 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8467 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8468
8469 fputs ("\n<", stdout);
8470
8471 if (procname)
8472 {
8473 fputs (procname, stdout);
8474
8475 if (offset)
8476 printf ("+%lx", (unsigned long) offset);
8477 }
8478
8479 fputs (">: [", stdout);
8480 print_vma (tp->start.offset, PREFIX_HEX);
8481 fputc ('-', stdout);
8482 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8483 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8484 (unsigned long) (tp->info.offset - aux->seg_base));
8485
53774b7e
NC
8486 /* PR 17531: file: 86232b32. */
8487 if (aux->info == NULL)
8488 continue;
8489
97c0a079
AM
8490 offset = tp->info.offset;
8491 if (tp->info.section)
8492 {
8493 if (tp->info.section >= filedata->file_header.e_shnum)
8494 {
8495 warn (_("Invalid section %u in table entry %ld\n"),
8496 tp->info.section, (long) (tp - aux->table));
015dc7e1 8497 res = false;
97c0a079
AM
8498 continue;
8499 }
8500 offset += filedata->section_headers[tp->info.section].sh_addr;
8501 }
8502 offset -= aux->info_addr;
53774b7e 8503 /* PR 17531: file: 0997b4d1. */
90679903
AM
8504 if (offset >= aux->info_size
8505 || aux->info_size - offset < 8)
53774b7e
NC
8506 {
8507 warn (_("Invalid offset %lx in table entry %ld\n"),
8508 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8509 res = false;
53774b7e
NC
8510 continue;
8511 }
8512
97c0a079 8513 head = aux->info + offset;
a4a00738 8514 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8515
86f55779 8516 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8517 (unsigned) UNW_VER (stamp),
8518 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8519 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8520 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8521 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8522
8523 if (UNW_VER (stamp) != 1)
8524 {
2b692964 8525 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8526 continue;
8527 }
8528
8529 in_body = 0;
53774b7e
NC
8530 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8531 /* PR 17531: file: 16ceda89. */
8532 if (end > aux->info + aux->info_size)
8533 end = aux->info + aux->info_size;
8534 for (dp = head + 8; dp < end;)
b4477bc8 8535 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8536 }
948f632f
DA
8537
8538 free (aux->funtab);
32ec8896
NC
8539
8540 return res;
4d6ed7c8
NC
8541}
8542
015dc7e1 8543static bool
dda8d76d
NC
8544slurp_ia64_unwind_table (Filedata * filedata,
8545 struct ia64_unw_aux_info * aux,
8546 Elf_Internal_Shdr * sec)
4d6ed7c8 8547{
89fac5e3 8548 unsigned long size, nrelas, i;
2cf0635d
NC
8549 Elf_Internal_Phdr * seg;
8550 struct ia64_unw_table_entry * tep;
8551 Elf_Internal_Shdr * relsec;
8552 Elf_Internal_Rela * rela;
8553 Elf_Internal_Rela * rp;
8554 unsigned char * table;
8555 unsigned char * tp;
8556 Elf_Internal_Sym * sym;
8557 const char * relname;
4d6ed7c8 8558
53774b7e
NC
8559 aux->table_len = 0;
8560
4d6ed7c8
NC
8561 /* First, find the starting address of the segment that includes
8562 this section: */
8563
dda8d76d 8564 if (filedata->file_header.e_phnum)
4d6ed7c8 8565 {
dda8d76d 8566 if (! get_program_headers (filedata))
015dc7e1 8567 return false;
4d6ed7c8 8568
dda8d76d
NC
8569 for (seg = filedata->program_headers;
8570 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8571 ++seg)
4d6ed7c8
NC
8572 {
8573 if (seg->p_type != PT_LOAD)
8574 continue;
8575
8576 if (sec->sh_addr >= seg->p_vaddr
8577 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8578 {
8579 aux->seg_base = seg->p_vaddr;
8580 break;
8581 }
8582 }
4d6ed7c8
NC
8583 }
8584
8585 /* Second, build the unwind table from the contents of the unwind section: */
8586 size = sec->sh_size;
dda8d76d 8587 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8588 _("unwind table"));
a6e9f9df 8589 if (!table)
015dc7e1 8590 return false;
4d6ed7c8 8591
53774b7e 8592 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8593 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8594 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8595 tep = aux->table;
53774b7e
NC
8596
8597 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8598 {
8599 tep->start.section = SHN_UNDEF;
8600 tep->end.section = SHN_UNDEF;
8601 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8602 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8603 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8604 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8605 tep->start.offset += aux->seg_base;
8606 tep->end.offset += aux->seg_base;
8607 tep->info.offset += aux->seg_base;
8608 }
8609 free (table);
8610
41e92641 8611 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8612 for (relsec = filedata->section_headers;
8613 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8614 ++relsec)
8615 {
8616 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8617 || relsec->sh_info >= filedata->file_header.e_shnum
8618 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8619 continue;
8620
dda8d76d 8621 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8622 & rela, & nrelas))
53774b7e
NC
8623 {
8624 free (aux->table);
8625 aux->table = NULL;
8626 aux->table_len = 0;
015dc7e1 8627 return false;
53774b7e 8628 }
4d6ed7c8
NC
8629
8630 for (rp = rela; rp < rela + nrelas; ++rp)
8631 {
4770fb94 8632 unsigned int sym_ndx;
726bd37d
AM
8633 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8634 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8635
82b1b41b
NC
8636 /* PR 17531: file: 9fa67536. */
8637 if (relname == NULL)
8638 {
726bd37d 8639 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8640 continue;
8641 }
948f632f 8642
24d127aa 8643 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8644 {
82b1b41b 8645 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8646 continue;
8647 }
8648
89fac5e3 8649 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8650
53774b7e
NC
8651 /* PR 17531: file: 5bc8d9bf. */
8652 if (i >= aux->table_len)
8653 {
8654 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8655 continue;
8656 }
8657
4770fb94
AM
8658 sym_ndx = get_reloc_symindex (rp->r_info);
8659 if (sym_ndx >= aux->nsyms)
8660 {
8661 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8662 sym_ndx);
8663 continue;
8664 }
8665 sym = aux->symtab + sym_ndx;
8666
53774b7e 8667 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8668 {
8669 case 0:
8670 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8671 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8672 break;
8673 case 1:
8674 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8675 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8676 break;
8677 case 2:
8678 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8679 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8680 break;
8681 default:
8682 break;
8683 }
8684 }
8685
8686 free (rela);
8687 }
8688
015dc7e1 8689 return true;
4d6ed7c8
NC
8690}
8691
015dc7e1 8692static bool
dda8d76d 8693ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8694{
2cf0635d
NC
8695 Elf_Internal_Shdr * sec;
8696 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8697 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8698 struct ia64_unw_aux_info aux;
015dc7e1 8699 bool res = true;
f1467e33 8700
4d6ed7c8
NC
8701 memset (& aux, 0, sizeof (aux));
8702
dda8d76d 8703 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8704 {
28d13567 8705 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8706 {
28d13567 8707 if (aux.symtab)
4082ef84 8708 {
28d13567
AM
8709 error (_("Multiple symbol tables encountered\n"));
8710 free (aux.symtab);
8711 aux.symtab = NULL;
4082ef84 8712 free (aux.strtab);
28d13567 8713 aux.strtab = NULL;
4082ef84 8714 }
28d13567
AM
8715 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8716 &aux.strtab, &aux.strtab_size))
015dc7e1 8717 return false;
4d6ed7c8
NC
8718 }
8719 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8720 unwcount++;
8721 }
8722
8723 if (!unwcount)
8724 printf (_("\nThere are no unwind sections in this file.\n"));
8725
8726 while (unwcount-- > 0)
8727 {
84714f86 8728 const char *suffix;
579f31ac
JJ
8729 size_t len, len2;
8730
dda8d76d
NC
8731 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8732 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8733 if (sec->sh_type == SHT_IA_64_UNWIND)
8734 {
8735 unwsec = sec;
8736 break;
8737 }
4082ef84
NC
8738 /* We have already counted the number of SHT_IA64_UNWIND
8739 sections so the loop above should never fail. */
8740 assert (unwsec != NULL);
579f31ac
JJ
8741
8742 unwstart = i + 1;
8743 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8744
e4b17d5c
L
8745 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8746 {
8747 /* We need to find which section group it is in. */
4082ef84 8748 struct group_list * g;
e4b17d5c 8749
978c4450
AM
8750 if (filedata->section_headers_groups == NULL
8751 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8752 i = filedata->file_header.e_shnum;
4082ef84 8753 else
e4b17d5c 8754 {
978c4450 8755 g = filedata->section_headers_groups[i]->root;
18bd398b 8756
4082ef84
NC
8757 for (; g != NULL; g = g->next)
8758 {
dda8d76d 8759 sec = filedata->section_headers + g->section_index;
e4b17d5c 8760
84714f86
AM
8761 if (section_name_valid (filedata, sec)
8762 && streq (section_name (filedata, sec),
8763 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8764 break;
8765 }
8766
8767 if (g == NULL)
dda8d76d 8768 i = filedata->file_header.e_shnum;
4082ef84 8769 }
e4b17d5c 8770 }
84714f86
AM
8771 else if (section_name_valid (filedata, unwsec)
8772 && startswith (section_name (filedata, unwsec),
e9b095a5 8773 ELF_STRING_ia64_unwind_once))
579f31ac 8774 {
18bd398b 8775 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8776 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8777 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8778 for (i = 0, sec = filedata->section_headers;
8779 i < filedata->file_header.e_shnum;
579f31ac 8780 ++i, ++sec)
84714f86
AM
8781 if (section_name_valid (filedata, sec)
8782 && startswith (section_name (filedata, sec),
e9b095a5 8783 ELF_STRING_ia64_unwind_info_once)
84714f86 8784 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8785 break;
8786 }
8787 else
8788 {
8789 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8790 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8791 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8792 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8793 suffix = "";
84714f86
AM
8794 if (section_name_valid (filedata, unwsec)
8795 && startswith (section_name (filedata, unwsec),
8796 ELF_STRING_ia64_unwind))
8797 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8798 for (i = 0, sec = filedata->section_headers;
8799 i < filedata->file_header.e_shnum;
579f31ac 8800 ++i, ++sec)
84714f86
AM
8801 if (section_name_valid (filedata, sec)
8802 && startswith (section_name (filedata, sec),
8803 ELF_STRING_ia64_unwind_info)
8804 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8805 break;
8806 }
8807
dda8d76d 8808 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8809 {
8810 printf (_("\nCould not find unwind info section for "));
8811
dda8d76d 8812 if (filedata->string_table == NULL)
579f31ac
JJ
8813 printf ("%d", unwsec->sh_name);
8814 else
dda8d76d 8815 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8816 }
8817 else
4d6ed7c8 8818 {
4d6ed7c8 8819 aux.info_addr = sec->sh_addr;
dda8d76d 8820 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8821 sec->sh_size,
8822 _("unwind info"));
59245841 8823 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8824
579f31ac 8825 printf (_("\nUnwind section "));
4d6ed7c8 8826
dda8d76d 8827 if (filedata->string_table == NULL)
579f31ac
JJ
8828 printf ("%d", unwsec->sh_name);
8829 else
dda8d76d 8830 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8831
579f31ac 8832 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8833 (unsigned long) unwsec->sh_offset,
89fac5e3 8834 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8835
dda8d76d 8836 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8837 && aux.table_len > 0)
dda8d76d 8838 dump_ia64_unwind (filedata, & aux);
579f31ac 8839
9db70fc3
AM
8840 free ((char *) aux.table);
8841 free ((char *) aux.info);
579f31ac
JJ
8842 aux.table = NULL;
8843 aux.info = NULL;
8844 }
4d6ed7c8 8845 }
4d6ed7c8 8846
9db70fc3
AM
8847 free (aux.symtab);
8848 free ((char *) aux.strtab);
32ec8896
NC
8849
8850 return res;
4d6ed7c8
NC
8851}
8852
3f5e193b 8853struct hppa_unw_table_entry
32ec8896
NC
8854{
8855 struct absaddr start;
8856 struct absaddr end;
8857 unsigned int Cannot_unwind:1; /* 0 */
8858 unsigned int Millicode:1; /* 1 */
8859 unsigned int Millicode_save_sr0:1; /* 2 */
8860 unsigned int Region_description:2; /* 3..4 */
8861 unsigned int reserved1:1; /* 5 */
8862 unsigned int Entry_SR:1; /* 6 */
8863 unsigned int Entry_FR:4; /* Number saved 7..10 */
8864 unsigned int Entry_GR:5; /* Number saved 11..15 */
8865 unsigned int Args_stored:1; /* 16 */
8866 unsigned int Variable_Frame:1; /* 17 */
8867 unsigned int Separate_Package_Body:1; /* 18 */
8868 unsigned int Frame_Extension_Millicode:1; /* 19 */
8869 unsigned int Stack_Overflow_Check:1; /* 20 */
8870 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8871 unsigned int Ada_Region:1; /* 22 */
8872 unsigned int cxx_info:1; /* 23 */
8873 unsigned int cxx_try_catch:1; /* 24 */
8874 unsigned int sched_entry_seq:1; /* 25 */
8875 unsigned int reserved2:1; /* 26 */
8876 unsigned int Save_SP:1; /* 27 */
8877 unsigned int Save_RP:1; /* 28 */
8878 unsigned int Save_MRP_in_frame:1; /* 29 */
8879 unsigned int extn_ptr_defined:1; /* 30 */
8880 unsigned int Cleanup_defined:1; /* 31 */
8881
8882 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8883 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8884 unsigned int Large_frame:1; /* 2 */
8885 unsigned int Pseudo_SP_Set:1; /* 3 */
8886 unsigned int reserved4:1; /* 4 */
8887 unsigned int Total_frame_size:27; /* 5..31 */
8888};
3f5e193b 8889
57346661 8890struct hppa_unw_aux_info
948f632f 8891{
32ec8896
NC
8892 struct hppa_unw_table_entry * table; /* Unwind table. */
8893 unsigned long table_len; /* Length of unwind table. */
8894 bfd_vma seg_base; /* Starting address of segment. */
8895 Elf_Internal_Sym * symtab; /* The symbol table. */
8896 unsigned long nsyms; /* Number of symbols. */
8897 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8898 unsigned long nfuns; /* Number of entries in funtab. */
8899 char * strtab; /* The string table. */
8900 unsigned long strtab_size; /* Size of string table. */
948f632f 8901};
57346661 8902
015dc7e1 8903static bool
dda8d76d 8904dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8905{
2cf0635d 8906 struct hppa_unw_table_entry * tp;
948f632f 8907 unsigned long j, nfuns;
015dc7e1 8908 bool res = true;
948f632f
DA
8909
8910 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8911 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8912 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8913 aux->funtab[nfuns++] = aux->symtab[j];
8914 aux->nfuns = nfuns;
8915 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8916
57346661
AM
8917 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8918 {
8919 bfd_vma offset;
2cf0635d 8920 const char * procname;
57346661 8921
dda8d76d 8922 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8923 aux->strtab_size, tp->start, &procname,
8924 &offset);
8925
8926 fputs ("\n<", stdout);
8927
8928 if (procname)
8929 {
8930 fputs (procname, stdout);
8931
8932 if (offset)
8933 printf ("+%lx", (unsigned long) offset);
8934 }
8935
8936 fputs (">: [", stdout);
8937 print_vma (tp->start.offset, PREFIX_HEX);
8938 fputc ('-', stdout);
8939 print_vma (tp->end.offset, PREFIX_HEX);
8940 printf ("]\n\t");
8941
18bd398b
NC
8942#define PF(_m) if (tp->_m) printf (#_m " ");
8943#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8944 PF(Cannot_unwind);
8945 PF(Millicode);
8946 PF(Millicode_save_sr0);
18bd398b 8947 /* PV(Region_description); */
57346661
AM
8948 PF(Entry_SR);
8949 PV(Entry_FR);
8950 PV(Entry_GR);
8951 PF(Args_stored);
8952 PF(Variable_Frame);
8953 PF(Separate_Package_Body);
8954 PF(Frame_Extension_Millicode);
8955 PF(Stack_Overflow_Check);
8956 PF(Two_Instruction_SP_Increment);
8957 PF(Ada_Region);
8958 PF(cxx_info);
8959 PF(cxx_try_catch);
8960 PF(sched_entry_seq);
8961 PF(Save_SP);
8962 PF(Save_RP);
8963 PF(Save_MRP_in_frame);
8964 PF(extn_ptr_defined);
8965 PF(Cleanup_defined);
8966 PF(MPE_XL_interrupt_marker);
8967 PF(HP_UX_interrupt_marker);
8968 PF(Large_frame);
8969 PF(Pseudo_SP_Set);
8970 PV(Total_frame_size);
8971#undef PF
8972#undef PV
8973 }
8974
18bd398b 8975 printf ("\n");
948f632f
DA
8976
8977 free (aux->funtab);
32ec8896
NC
8978
8979 return res;
57346661
AM
8980}
8981
015dc7e1 8982static bool
dda8d76d
NC
8983slurp_hppa_unwind_table (Filedata * filedata,
8984 struct hppa_unw_aux_info * aux,
8985 Elf_Internal_Shdr * sec)
57346661 8986{
1c0751b2 8987 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8988 Elf_Internal_Phdr * seg;
8989 struct hppa_unw_table_entry * tep;
8990 Elf_Internal_Shdr * relsec;
8991 Elf_Internal_Rela * rela;
8992 Elf_Internal_Rela * rp;
8993 unsigned char * table;
8994 unsigned char * tp;
8995 Elf_Internal_Sym * sym;
8996 const char * relname;
57346661 8997
57346661
AM
8998 /* First, find the starting address of the segment that includes
8999 this section. */
dda8d76d 9000 if (filedata->file_header.e_phnum)
57346661 9001 {
dda8d76d 9002 if (! get_program_headers (filedata))
015dc7e1 9003 return false;
57346661 9004
dda8d76d
NC
9005 for (seg = filedata->program_headers;
9006 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9007 ++seg)
9008 {
9009 if (seg->p_type != PT_LOAD)
9010 continue;
9011
9012 if (sec->sh_addr >= seg->p_vaddr
9013 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9014 {
9015 aux->seg_base = seg->p_vaddr;
9016 break;
9017 }
9018 }
9019 }
9020
9021 /* Second, build the unwind table from the contents of the unwind
9022 section. */
9023 size = sec->sh_size;
dda8d76d 9024 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9025 _("unwind table"));
57346661 9026 if (!table)
015dc7e1 9027 return false;
57346661 9028
1c0751b2
DA
9029 unw_ent_size = 16;
9030 nentries = size / unw_ent_size;
9031 size = unw_ent_size * nentries;
57346661 9032
e3fdc001 9033 aux->table_len = nentries;
3f5e193b
NC
9034 tep = aux->table = (struct hppa_unw_table_entry *)
9035 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9036
1c0751b2 9037 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9038 {
9039 unsigned int tmp1, tmp2;
9040
9041 tep->start.section = SHN_UNDEF;
9042 tep->end.section = SHN_UNDEF;
9043
1c0751b2
DA
9044 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9045 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9046 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9047 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9048
9049 tep->start.offset += aux->seg_base;
9050 tep->end.offset += aux->seg_base;
57346661
AM
9051
9052 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9053 tep->Millicode = (tmp1 >> 30) & 0x1;
9054 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9055 tep->Region_description = (tmp1 >> 27) & 0x3;
9056 tep->reserved1 = (tmp1 >> 26) & 0x1;
9057 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9058 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9059 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9060 tep->Args_stored = (tmp1 >> 15) & 0x1;
9061 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9062 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9063 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9064 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9065 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9066 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9067 tep->cxx_info = (tmp1 >> 8) & 0x1;
9068 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9069 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9070 tep->reserved2 = (tmp1 >> 5) & 0x1;
9071 tep->Save_SP = (tmp1 >> 4) & 0x1;
9072 tep->Save_RP = (tmp1 >> 3) & 0x1;
9073 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9074 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9075 tep->Cleanup_defined = tmp1 & 0x1;
9076
9077 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9078 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9079 tep->Large_frame = (tmp2 >> 29) & 0x1;
9080 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9081 tep->reserved4 = (tmp2 >> 27) & 0x1;
9082 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9083 }
9084 free (table);
9085
9086 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9087 for (relsec = filedata->section_headers;
9088 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9089 ++relsec)
9090 {
9091 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9092 || relsec->sh_info >= filedata->file_header.e_shnum
9093 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9094 continue;
9095
dda8d76d 9096 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9097 & rela, & nrelas))
015dc7e1 9098 return false;
57346661
AM
9099
9100 for (rp = rela; rp < rela + nrelas; ++rp)
9101 {
4770fb94 9102 unsigned int sym_ndx;
726bd37d
AM
9103 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9104 relname = elf_hppa_reloc_type (r_type);
57346661 9105
726bd37d
AM
9106 if (relname == NULL)
9107 {
9108 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9109 continue;
9110 }
9111
57346661 9112 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9113 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9114 {
726bd37d 9115 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9116 continue;
9117 }
9118
9119 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9120 if (i >= aux->table_len)
9121 {
9122 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9123 continue;
9124 }
57346661 9125
4770fb94
AM
9126 sym_ndx = get_reloc_symindex (rp->r_info);
9127 if (sym_ndx >= aux->nsyms)
9128 {
9129 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9130 sym_ndx);
9131 continue;
9132 }
9133 sym = aux->symtab + sym_ndx;
9134
43f6cd05 9135 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9136 {
9137 case 0:
9138 aux->table[i].start.section = sym->st_shndx;
1e456d54 9139 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9140 break;
9141 case 1:
9142 aux->table[i].end.section = sym->st_shndx;
1e456d54 9143 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9144 break;
9145 default:
9146 break;
9147 }
9148 }
9149
9150 free (rela);
9151 }
9152
015dc7e1 9153 return true;
57346661
AM
9154}
9155
015dc7e1 9156static bool
dda8d76d 9157hppa_process_unwind (Filedata * filedata)
57346661 9158{
57346661 9159 struct hppa_unw_aux_info aux;
2cf0635d 9160 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9161 Elf_Internal_Shdr * sec;
18bd398b 9162 unsigned long i;
015dc7e1 9163 bool res = true;
57346661 9164
dda8d76d 9165 if (filedata->string_table == NULL)
015dc7e1 9166 return false;
1b31d05e
NC
9167
9168 memset (& aux, 0, sizeof (aux));
57346661 9169
dda8d76d 9170 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9171 {
28d13567 9172 if (sec->sh_type == SHT_SYMTAB)
57346661 9173 {
28d13567 9174 if (aux.symtab)
4082ef84 9175 {
28d13567
AM
9176 error (_("Multiple symbol tables encountered\n"));
9177 free (aux.symtab);
9178 aux.symtab = NULL;
4082ef84 9179 free (aux.strtab);
28d13567 9180 aux.strtab = NULL;
4082ef84 9181 }
28d13567
AM
9182 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9183 &aux.strtab, &aux.strtab_size))
015dc7e1 9184 return false;
57346661 9185 }
84714f86
AM
9186 else if (section_name_valid (filedata, sec)
9187 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9188 unwsec = sec;
9189 }
9190
9191 if (!unwsec)
9192 printf (_("\nThere are no unwind sections in this file.\n"));
9193
dda8d76d 9194 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9195 {
84714f86
AM
9196 if (section_name_valid (filedata, sec)
9197 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9198 {
43f6cd05 9199 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9200
d3a49aa8
AM
9201 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9202 "contains %lu entry:\n",
9203 "\nUnwind section '%s' at offset 0x%lx "
9204 "contains %lu entries:\n",
9205 num_unwind),
dda8d76d 9206 printable_section_name (filedata, sec),
57346661 9207 (unsigned long) sec->sh_offset,
d3a49aa8 9208 num_unwind);
57346661 9209
dda8d76d 9210 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9211 res = false;
66b09c7e
S
9212
9213 if (res && aux.table_len > 0)
32ec8896 9214 {
dda8d76d 9215 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9216 res = false;
32ec8896 9217 }
57346661 9218
9db70fc3 9219 free ((char *) aux.table);
57346661
AM
9220 aux.table = NULL;
9221 }
9222 }
9223
9db70fc3
AM
9224 free (aux.symtab);
9225 free ((char *) aux.strtab);
32ec8896
NC
9226
9227 return res;
57346661
AM
9228}
9229
0b6ae522
DJ
9230struct arm_section
9231{
a734115a
NC
9232 unsigned char * data; /* The unwind data. */
9233 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9234 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9235 unsigned long nrelas; /* The number of relocations. */
9236 unsigned int rel_type; /* REL or RELA ? */
9237 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9238};
9239
9240struct arm_unw_aux_info
9241{
dda8d76d 9242 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9243 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9244 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9245 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9246 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9247 char * strtab; /* The file's string table. */
9248 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9249};
9250
9251static const char *
dda8d76d
NC
9252arm_print_vma_and_name (Filedata * filedata,
9253 struct arm_unw_aux_info * aux,
9254 bfd_vma fn,
9255 struct absaddr addr)
0b6ae522
DJ
9256{
9257 const char *procname;
9258 bfd_vma sym_offset;
9259
9260 if (addr.section == SHN_UNDEF)
9261 addr.offset = fn;
9262
dda8d76d 9263 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9264 aux->strtab_size, addr, &procname,
9265 &sym_offset);
9266
9267 print_vma (fn, PREFIX_HEX);
9268
9269 if (procname)
9270 {
9271 fputs (" <", stdout);
9272 fputs (procname, stdout);
9273
9274 if (sym_offset)
9275 printf ("+0x%lx", (unsigned long) sym_offset);
9276 fputc ('>', stdout);
9277 }
9278
9279 return procname;
9280}
9281
9282static void
9283arm_free_section (struct arm_section *arm_sec)
9284{
9db70fc3
AM
9285 free (arm_sec->data);
9286 free (arm_sec->rela);
0b6ae522
DJ
9287}
9288
a734115a
NC
9289/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9290 cached section and install SEC instead.
9291 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9292 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9293 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9294 relocation's offset in ADDR.
1b31d05e
NC
9295 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9296 into the string table of the symbol associated with the reloc. If no
9297 reloc was applied store -1 there.
9298 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9299
015dc7e1 9300static bool
dda8d76d
NC
9301get_unwind_section_word (Filedata * filedata,
9302 struct arm_unw_aux_info * aux,
1b31d05e
NC
9303 struct arm_section * arm_sec,
9304 Elf_Internal_Shdr * sec,
9305 bfd_vma word_offset,
9306 unsigned int * wordp,
9307 struct absaddr * addr,
9308 bfd_vma * sym_name)
0b6ae522
DJ
9309{
9310 Elf_Internal_Rela *rp;
9311 Elf_Internal_Sym *sym;
9312 const char * relname;
9313 unsigned int word;
015dc7e1 9314 bool wrapped;
0b6ae522 9315
e0a31db1 9316 if (sec == NULL || arm_sec == NULL)
015dc7e1 9317 return false;
e0a31db1 9318
0b6ae522
DJ
9319 addr->section = SHN_UNDEF;
9320 addr->offset = 0;
9321
1b31d05e
NC
9322 if (sym_name != NULL)
9323 *sym_name = (bfd_vma) -1;
9324
a734115a 9325 /* If necessary, update the section cache. */
0b6ae522
DJ
9326 if (sec != arm_sec->sec)
9327 {
9328 Elf_Internal_Shdr *relsec;
9329
9330 arm_free_section (arm_sec);
9331
9332 arm_sec->sec = sec;
dda8d76d 9333 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9334 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9335 arm_sec->rela = NULL;
9336 arm_sec->nrelas = 0;
9337
dda8d76d
NC
9338 for (relsec = filedata->section_headers;
9339 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9340 ++relsec)
9341 {
dda8d76d
NC
9342 if (relsec->sh_info >= filedata->file_header.e_shnum
9343 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9344 /* PR 15745: Check the section type as well. */
9345 || (relsec->sh_type != SHT_REL
9346 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9347 continue;
9348
a734115a 9349 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9350 if (relsec->sh_type == SHT_REL)
9351 {
dda8d76d 9352 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9353 relsec->sh_size,
9354 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9355 return false;
0b6ae522 9356 }
1ae40aa4 9357 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9358 {
dda8d76d 9359 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9360 relsec->sh_size,
9361 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9362 return false;
0b6ae522 9363 }
1ae40aa4 9364 break;
0b6ae522
DJ
9365 }
9366
9367 arm_sec->next_rela = arm_sec->rela;
9368 }
9369
a734115a 9370 /* If there is no unwind data we can do nothing. */
0b6ae522 9371 if (arm_sec->data == NULL)
015dc7e1 9372 return false;
0b6ae522 9373
e0a31db1 9374 /* If the offset is invalid then fail. */
f32ba729
NC
9375 if (/* PR 21343 *//* PR 18879 */
9376 sec->sh_size < 4
9377 || word_offset > (sec->sh_size - 4)
1a915552 9378 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9379 return false;
e0a31db1 9380
a734115a 9381 /* Get the word at the required offset. */
0b6ae522
DJ
9382 word = byte_get (arm_sec->data + word_offset, 4);
9383
0eff7165
NC
9384 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9385 if (arm_sec->rela == NULL)
9386 {
9387 * wordp = word;
015dc7e1 9388 return true;
0eff7165
NC
9389 }
9390
a734115a 9391 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9392 wrapped = false;
0b6ae522
DJ
9393 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9394 {
9395 bfd_vma prelval, offset;
9396
9397 if (rp->r_offset > word_offset && !wrapped)
9398 {
9399 rp = arm_sec->rela;
015dc7e1 9400 wrapped = true;
0b6ae522
DJ
9401 }
9402 if (rp->r_offset > word_offset)
9403 break;
9404
9405 if (rp->r_offset & 3)
9406 {
9407 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9408 (unsigned long) rp->r_offset);
9409 continue;
9410 }
9411
9412 if (rp->r_offset < word_offset)
9413 continue;
9414
74e1a04b
NC
9415 /* PR 17531: file: 027-161405-0.004 */
9416 if (aux->symtab == NULL)
9417 continue;
9418
0b6ae522
DJ
9419 if (arm_sec->rel_type == SHT_REL)
9420 {
9421 offset = word & 0x7fffffff;
9422 if (offset & 0x40000000)
9423 offset |= ~ (bfd_vma) 0x7fffffff;
9424 }
a734115a 9425 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9426 offset = rp->r_addend;
a734115a 9427 else
74e1a04b
NC
9428 {
9429 error (_("Unknown section relocation type %d encountered\n"),
9430 arm_sec->rel_type);
9431 break;
9432 }
0b6ae522 9433
071436c6
NC
9434 /* PR 17531 file: 027-1241568-0.004. */
9435 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9436 {
9437 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9438 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9439 break;
9440 }
9441
9442 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9443 offset += sym->st_value;
9444 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9445
a734115a 9446 /* Check that we are processing the expected reloc type. */
dda8d76d 9447 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9448 {
9449 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9450 if (relname == NULL)
9451 {
9452 warn (_("Skipping unknown ARM relocation type: %d\n"),
9453 (int) ELF32_R_TYPE (rp->r_info));
9454 continue;
9455 }
a734115a
NC
9456
9457 if (streq (relname, "R_ARM_NONE"))
9458 continue;
0b4362b0 9459
a734115a
NC
9460 if (! streq (relname, "R_ARM_PREL31"))
9461 {
071436c6 9462 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9463 continue;
9464 }
9465 }
dda8d76d 9466 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9467 {
9468 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9469 if (relname == NULL)
9470 {
9471 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9472 (int) ELF32_R_TYPE (rp->r_info));
9473 continue;
9474 }
0b4362b0 9475
a734115a
NC
9476 if (streq (relname, "R_C6000_NONE"))
9477 continue;
9478
9479 if (! streq (relname, "R_C6000_PREL31"))
9480 {
071436c6 9481 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9482 continue;
9483 }
9484
9485 prelval >>= 1;
9486 }
9487 else
74e1a04b
NC
9488 {
9489 /* This function currently only supports ARM and TI unwinders. */
9490 warn (_("Only TI and ARM unwinders are currently supported\n"));
9491 break;
9492 }
fa197c1c 9493
0b6ae522
DJ
9494 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9495 addr->section = sym->st_shndx;
9496 addr->offset = offset;
74e1a04b 9497
1b31d05e
NC
9498 if (sym_name)
9499 * sym_name = sym->st_name;
0b6ae522
DJ
9500 break;
9501 }
9502
9503 *wordp = word;
9504 arm_sec->next_rela = rp;
9505
015dc7e1 9506 return true;
0b6ae522
DJ
9507}
9508
a734115a
NC
9509static const char *tic6x_unwind_regnames[16] =
9510{
0b4362b0
RM
9511 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9512 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9513 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9514};
fa197c1c 9515
0b6ae522 9516static void
fa197c1c 9517decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9518{
fa197c1c
PB
9519 int i;
9520
9521 for (i = 12; mask; mask >>= 1, i--)
9522 {
9523 if (mask & 1)
9524 {
9525 fputs (tic6x_unwind_regnames[i], stdout);
9526 if (mask > 1)
9527 fputs (", ", stdout);
9528 }
9529 }
9530}
0b6ae522
DJ
9531
9532#define ADVANCE \
9533 if (remaining == 0 && more_words) \
9534 { \
9535 data_offset += 4; \
dda8d76d 9536 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9537 data_offset, & word, & addr, NULL)) \
015dc7e1 9538 return false; \
0b6ae522
DJ
9539 remaining = 4; \
9540 more_words--; \
9541 } \
9542
9543#define GET_OP(OP) \
9544 ADVANCE; \
9545 if (remaining) \
9546 { \
9547 remaining--; \
9548 (OP) = word >> 24; \
9549 word <<= 8; \
9550 } \
9551 else \
9552 { \
2b692964 9553 printf (_("[Truncated opcode]\n")); \
015dc7e1 9554 return false; \
0b6ae522 9555 } \
cc5914eb 9556 printf ("0x%02x ", OP)
0b6ae522 9557
015dc7e1 9558static bool
dda8d76d
NC
9559decode_arm_unwind_bytecode (Filedata * filedata,
9560 struct arm_unw_aux_info * aux,
948f632f
DA
9561 unsigned int word,
9562 unsigned int remaining,
9563 unsigned int more_words,
9564 bfd_vma data_offset,
9565 Elf_Internal_Shdr * data_sec,
9566 struct arm_section * data_arm_sec)
fa197c1c
PB
9567{
9568 struct absaddr addr;
015dc7e1 9569 bool res = true;
0b6ae522
DJ
9570
9571 /* Decode the unwinding instructions. */
9572 while (1)
9573 {
9574 unsigned int op, op2;
9575
9576 ADVANCE;
9577 if (remaining == 0)
9578 break;
9579 remaining--;
9580 op = word >> 24;
9581 word <<= 8;
9582
cc5914eb 9583 printf (" 0x%02x ", op);
0b6ae522
DJ
9584
9585 if ((op & 0xc0) == 0x00)
9586 {
9587 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9588
cc5914eb 9589 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9590 }
9591 else if ((op & 0xc0) == 0x40)
9592 {
9593 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9594
cc5914eb 9595 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9596 }
9597 else if ((op & 0xf0) == 0x80)
9598 {
9599 GET_OP (op2);
9600 if (op == 0x80 && op2 == 0)
9601 printf (_("Refuse to unwind"));
9602 else
9603 {
9604 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9605 bool first = true;
0b6ae522 9606 int i;
2b692964 9607
0b6ae522
DJ
9608 printf ("pop {");
9609 for (i = 0; i < 12; i++)
9610 if (mask & (1 << i))
9611 {
9612 if (first)
015dc7e1 9613 first = false;
0b6ae522
DJ
9614 else
9615 printf (", ");
9616 printf ("r%d", 4 + i);
9617 }
9618 printf ("}");
9619 }
9620 }
9621 else if ((op & 0xf0) == 0x90)
9622 {
9623 if (op == 0x9d || op == 0x9f)
9624 printf (_(" [Reserved]"));
9625 else
cc5914eb 9626 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9627 }
9628 else if ((op & 0xf0) == 0xa0)
9629 {
9630 int end = 4 + (op & 0x07);
015dc7e1 9631 bool first = true;
0b6ae522 9632 int i;
61865e30 9633
0b6ae522
DJ
9634 printf (" pop {");
9635 for (i = 4; i <= end; i++)
9636 {
9637 if (first)
015dc7e1 9638 first = false;
0b6ae522
DJ
9639 else
9640 printf (", ");
9641 printf ("r%d", i);
9642 }
9643 if (op & 0x08)
9644 {
1b31d05e 9645 if (!first)
0b6ae522
DJ
9646 printf (", ");
9647 printf ("r14");
9648 }
9649 printf ("}");
9650 }
9651 else if (op == 0xb0)
9652 printf (_(" finish"));
9653 else if (op == 0xb1)
9654 {
9655 GET_OP (op2);
9656 if (op2 == 0 || (op2 & 0xf0) != 0)
9657 printf (_("[Spare]"));
9658 else
9659 {
9660 unsigned int mask = op2 & 0x0f;
015dc7e1 9661 bool first = true;
0b6ae522 9662 int i;
61865e30 9663
0b6ae522
DJ
9664 printf ("pop {");
9665 for (i = 0; i < 12; i++)
9666 if (mask & (1 << i))
9667 {
9668 if (first)
015dc7e1 9669 first = false;
0b6ae522
DJ
9670 else
9671 printf (", ");
9672 printf ("r%d", i);
9673 }
9674 printf ("}");
9675 }
9676 }
9677 else if (op == 0xb2)
9678 {
b115cf96 9679 unsigned char buf[9];
0b6ae522
DJ
9680 unsigned int i, len;
9681 unsigned long offset;
61865e30 9682
b115cf96 9683 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9684 {
9685 GET_OP (buf[i]);
9686 if ((buf[i] & 0x80) == 0)
9687 break;
9688 }
4082ef84 9689 if (i == sizeof (buf))
32ec8896 9690 {
27a45f42 9691 error (_("corrupt change to vsp\n"));
015dc7e1 9692 res = false;
32ec8896 9693 }
4082ef84
NC
9694 else
9695 {
015dc7e1 9696 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9697 assert (len == i + 1);
9698 offset = offset * 4 + 0x204;
9699 printf ("vsp = vsp + %ld", offset);
9700 }
0b6ae522 9701 }
61865e30 9702 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9703 {
61865e30
NC
9704 unsigned int first, last;
9705
9706 GET_OP (op2);
9707 first = op2 >> 4;
9708 last = op2 & 0x0f;
9709 if (op == 0xc8)
9710 first = first + 16;
9711 printf ("pop {D%d", first);
9712 if (last)
9713 printf ("-D%d", first + last);
9714 printf ("}");
9715 }
09854a88
TB
9716 else if (op == 0xb4)
9717 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9718 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9719 {
9720 unsigned int count = op & 0x07;
9721
9722 printf ("pop {D8");
9723 if (count)
9724 printf ("-D%d", 8 + count);
9725 printf ("}");
9726 }
9727 else if (op >= 0xc0 && op <= 0xc5)
9728 {
9729 unsigned int count = op & 0x07;
9730
9731 printf (" pop {wR10");
9732 if (count)
9733 printf ("-wR%d", 10 + count);
9734 printf ("}");
9735 }
9736 else if (op == 0xc6)
9737 {
9738 unsigned int first, last;
9739
9740 GET_OP (op2);
9741 first = op2 >> 4;
9742 last = op2 & 0x0f;
9743 printf ("pop {wR%d", first);
9744 if (last)
9745 printf ("-wR%d", first + last);
9746 printf ("}");
9747 }
9748 else if (op == 0xc7)
9749 {
9750 GET_OP (op2);
9751 if (op2 == 0 || (op2 & 0xf0) != 0)
9752 printf (_("[Spare]"));
0b6ae522
DJ
9753 else
9754 {
61865e30 9755 unsigned int mask = op2 & 0x0f;
015dc7e1 9756 bool first = true;
61865e30
NC
9757 int i;
9758
9759 printf ("pop {");
9760 for (i = 0; i < 4; i++)
9761 if (mask & (1 << i))
9762 {
9763 if (first)
015dc7e1 9764 first = false;
61865e30
NC
9765 else
9766 printf (", ");
9767 printf ("wCGR%d", i);
9768 }
9769 printf ("}");
0b6ae522
DJ
9770 }
9771 }
61865e30 9772 else
32ec8896
NC
9773 {
9774 printf (_(" [unsupported opcode]"));
015dc7e1 9775 res = false;
32ec8896
NC
9776 }
9777
0b6ae522
DJ
9778 printf ("\n");
9779 }
32ec8896
NC
9780
9781 return res;
fa197c1c
PB
9782}
9783
015dc7e1 9784static bool
dda8d76d
NC
9785decode_tic6x_unwind_bytecode (Filedata * filedata,
9786 struct arm_unw_aux_info * aux,
948f632f
DA
9787 unsigned int word,
9788 unsigned int remaining,
9789 unsigned int more_words,
9790 bfd_vma data_offset,
9791 Elf_Internal_Shdr * data_sec,
9792 struct arm_section * data_arm_sec)
fa197c1c
PB
9793{
9794 struct absaddr addr;
9795
9796 /* Decode the unwinding instructions. */
9797 while (1)
9798 {
9799 unsigned int op, op2;
9800
9801 ADVANCE;
9802 if (remaining == 0)
9803 break;
9804 remaining--;
9805 op = word >> 24;
9806 word <<= 8;
9807
9cf03b7e 9808 printf (" 0x%02x ", op);
fa197c1c
PB
9809
9810 if ((op & 0xc0) == 0x00)
9811 {
9812 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9813 printf (" sp = sp + %d", offset);
fa197c1c
PB
9814 }
9815 else if ((op & 0xc0) == 0x80)
9816 {
9817 GET_OP (op2);
9818 if (op == 0x80 && op2 == 0)
9819 printf (_("Refuse to unwind"));
9820 else
9821 {
9822 unsigned int mask = ((op & 0x1f) << 8) | op2;
9823 if (op & 0x20)
9824 printf ("pop compact {");
9825 else
9826 printf ("pop {");
9827
9828 decode_tic6x_unwind_regmask (mask);
9829 printf("}");
9830 }
9831 }
9832 else if ((op & 0xf0) == 0xc0)
9833 {
9834 unsigned int reg;
9835 unsigned int nregs;
9836 unsigned int i;
9837 const char *name;
a734115a
NC
9838 struct
9839 {
32ec8896
NC
9840 unsigned int offset;
9841 unsigned int reg;
fa197c1c
PB
9842 } regpos[16];
9843
9844 /* Scan entire instruction first so that GET_OP output is not
9845 interleaved with disassembly. */
9846 nregs = 0;
9847 for (i = 0; nregs < (op & 0xf); i++)
9848 {
9849 GET_OP (op2);
9850 reg = op2 >> 4;
9851 if (reg != 0xf)
9852 {
9853 regpos[nregs].offset = i * 2;
9854 regpos[nregs].reg = reg;
9855 nregs++;
9856 }
9857
9858 reg = op2 & 0xf;
9859 if (reg != 0xf)
9860 {
9861 regpos[nregs].offset = i * 2 + 1;
9862 regpos[nregs].reg = reg;
9863 nregs++;
9864 }
9865 }
9866
9867 printf (_("pop frame {"));
18344509 9868 if (nregs == 0)
fa197c1c 9869 {
18344509
NC
9870 printf (_("*corrupt* - no registers specified"));
9871 }
9872 else
9873 {
9874 reg = nregs - 1;
9875 for (i = i * 2; i > 0; i--)
fa197c1c 9876 {
18344509
NC
9877 if (regpos[reg].offset == i - 1)
9878 {
9879 name = tic6x_unwind_regnames[regpos[reg].reg];
9880 if (reg > 0)
9881 reg--;
9882 }
9883 else
9884 name = _("[pad]");
fa197c1c 9885
18344509
NC
9886 fputs (name, stdout);
9887 if (i > 1)
9888 printf (", ");
9889 }
fa197c1c
PB
9890 }
9891
9892 printf ("}");
9893 }
9894 else if (op == 0xd0)
9895 printf (" MOV FP, SP");
9896 else if (op == 0xd1)
9897 printf (" __c6xabi_pop_rts");
9898 else if (op == 0xd2)
9899 {
9900 unsigned char buf[9];
9901 unsigned int i, len;
9902 unsigned long offset;
a734115a 9903
fa197c1c
PB
9904 for (i = 0; i < sizeof (buf); i++)
9905 {
9906 GET_OP (buf[i]);
9907 if ((buf[i] & 0x80) == 0)
9908 break;
9909 }
0eff7165
NC
9910 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9911 if (i == sizeof (buf))
9912 {
0eff7165 9913 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9914 return false;
0eff7165 9915 }
948f632f 9916
015dc7e1 9917 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9918 assert (len == i + 1);
9919 offset = offset * 8 + 0x408;
9920 printf (_("sp = sp + %ld"), offset);
9921 }
9922 else if ((op & 0xf0) == 0xe0)
9923 {
9924 if ((op & 0x0f) == 7)
9925 printf (" RETURN");
9926 else
9927 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9928 }
9929 else
9930 {
9931 printf (_(" [unsupported opcode]"));
9932 }
9933 putchar ('\n');
9934 }
32ec8896 9935
015dc7e1 9936 return true;
fa197c1c
PB
9937}
9938
9939static bfd_vma
dda8d76d 9940arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9941{
9942 bfd_vma offset;
9943
9944 offset = word & 0x7fffffff;
9945 if (offset & 0x40000000)
9946 offset |= ~ (bfd_vma) 0x7fffffff;
9947
dda8d76d 9948 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9949 offset <<= 1;
9950
9951 return offset + where;
9952}
9953
015dc7e1 9954static bool
dda8d76d
NC
9955decode_arm_unwind (Filedata * filedata,
9956 struct arm_unw_aux_info * aux,
1b31d05e
NC
9957 unsigned int word,
9958 unsigned int remaining,
9959 bfd_vma data_offset,
9960 Elf_Internal_Shdr * data_sec,
9961 struct arm_section * data_arm_sec)
fa197c1c
PB
9962{
9963 int per_index;
9964 unsigned int more_words = 0;
37e14bc3 9965 struct absaddr addr;
1b31d05e 9966 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9967 bool res = true;
fa197c1c
PB
9968
9969 if (remaining == 0)
9970 {
1b31d05e
NC
9971 /* Fetch the first word.
9972 Note - when decoding an object file the address extracted
9973 here will always be 0. So we also pass in the sym_name
9974 parameter so that we can find the symbol associated with
9975 the personality routine. */
dda8d76d 9976 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9977 & word, & addr, & sym_name))
015dc7e1 9978 return false;
1b31d05e 9979
fa197c1c
PB
9980 remaining = 4;
9981 }
c93dbb25
CZ
9982 else
9983 {
9984 addr.section = SHN_UNDEF;
9985 addr.offset = 0;
9986 }
fa197c1c
PB
9987
9988 if ((word & 0x80000000) == 0)
9989 {
9990 /* Expand prel31 for personality routine. */
9991 bfd_vma fn;
9992 const char *procname;
9993
dda8d76d 9994 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9995 printf (_(" Personality routine: "));
1b31d05e
NC
9996 if (fn == 0
9997 && addr.section == SHN_UNDEF && addr.offset == 0
9998 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9999 {
10000 procname = aux->strtab + sym_name;
10001 print_vma (fn, PREFIX_HEX);
10002 if (procname)
10003 {
10004 fputs (" <", stdout);
10005 fputs (procname, stdout);
10006 fputc ('>', stdout);
10007 }
10008 }
10009 else
dda8d76d 10010 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10011 fputc ('\n', stdout);
10012
10013 /* The GCC personality routines use the standard compact
10014 encoding, starting with one byte giving the number of
10015 words. */
10016 if (procname != NULL
24d127aa
ML
10017 && (startswith (procname, "__gcc_personality_v0")
10018 || startswith (procname, "__gxx_personality_v0")
10019 || startswith (procname, "__gcj_personality_v0")
10020 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10021 {
10022 remaining = 0;
10023 more_words = 1;
10024 ADVANCE;
10025 if (!remaining)
10026 {
10027 printf (_(" [Truncated data]\n"));
015dc7e1 10028 return false;
fa197c1c
PB
10029 }
10030 more_words = word >> 24;
10031 word <<= 8;
10032 remaining--;
10033 per_index = -1;
10034 }
10035 else
015dc7e1 10036 return true;
fa197c1c
PB
10037 }
10038 else
10039 {
1b31d05e 10040 /* ARM EHABI Section 6.3:
0b4362b0 10041
1b31d05e 10042 An exception-handling table entry for the compact model looks like:
0b4362b0 10043
1b31d05e
NC
10044 31 30-28 27-24 23-0
10045 -- ----- ----- ----
10046 1 0 index Data for personalityRoutine[index] */
10047
dda8d76d 10048 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10049 && (word & 0x70000000))
32ec8896
NC
10050 {
10051 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10052 res = false;
32ec8896 10053 }
1b31d05e 10054
fa197c1c 10055 per_index = (word >> 24) & 0x7f;
1b31d05e 10056 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10057 if (per_index == 0)
10058 {
10059 more_words = 0;
10060 word <<= 8;
10061 remaining--;
10062 }
10063 else if (per_index < 3)
10064 {
10065 more_words = (word >> 16) & 0xff;
10066 word <<= 16;
10067 remaining -= 2;
10068 }
10069 }
10070
dda8d76d 10071 switch (filedata->file_header.e_machine)
fa197c1c
PB
10072 {
10073 case EM_ARM:
10074 if (per_index < 3)
10075 {
dda8d76d 10076 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10077 data_offset, data_sec, data_arm_sec))
015dc7e1 10078 res = false;
fa197c1c
PB
10079 }
10080 else
1b31d05e
NC
10081 {
10082 warn (_("Unknown ARM compact model index encountered\n"));
10083 printf (_(" [reserved]\n"));
015dc7e1 10084 res = false;
1b31d05e 10085 }
fa197c1c
PB
10086 break;
10087
10088 case EM_TI_C6000:
10089 if (per_index < 3)
10090 {
dda8d76d 10091 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10092 data_offset, data_sec, data_arm_sec))
015dc7e1 10093 res = false;
fa197c1c
PB
10094 }
10095 else if (per_index < 5)
10096 {
10097 if (((word >> 17) & 0x7f) == 0x7f)
10098 printf (_(" Restore stack from frame pointer\n"));
10099 else
10100 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10101 printf (_(" Registers restored: "));
10102 if (per_index == 4)
10103 printf (" (compact) ");
10104 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10105 putchar ('\n');
10106 printf (_(" Return register: %s\n"),
10107 tic6x_unwind_regnames[word & 0xf]);
10108 }
10109 else
1b31d05e 10110 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10111 break;
10112
10113 default:
74e1a04b 10114 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10115 filedata->file_header.e_machine);
015dc7e1 10116 res = false;
fa197c1c 10117 }
0b6ae522
DJ
10118
10119 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10120
10121 return res;
0b6ae522
DJ
10122}
10123
015dc7e1 10124static bool
dda8d76d
NC
10125dump_arm_unwind (Filedata * filedata,
10126 struct arm_unw_aux_info * aux,
10127 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10128{
10129 struct arm_section exidx_arm_sec, extab_arm_sec;
10130 unsigned int i, exidx_len;
948f632f 10131 unsigned long j, nfuns;
015dc7e1 10132 bool res = true;
0b6ae522
DJ
10133
10134 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10135 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10136 exidx_len = exidx_sec->sh_size / 8;
10137
948f632f
DA
10138 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10139 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10140 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10141 aux->funtab[nfuns++] = aux->symtab[j];
10142 aux->nfuns = nfuns;
10143 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10144
0b6ae522
DJ
10145 for (i = 0; i < exidx_len; i++)
10146 {
10147 unsigned int exidx_fn, exidx_entry;
10148 struct absaddr fn_addr, entry_addr;
10149 bfd_vma fn;
10150
10151 fputc ('\n', stdout);
10152
dda8d76d 10153 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10154 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10155 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10156 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10157 {
948f632f 10158 free (aux->funtab);
1b31d05e
NC
10159 arm_free_section (& exidx_arm_sec);
10160 arm_free_section (& extab_arm_sec);
015dc7e1 10161 return false;
0b6ae522
DJ
10162 }
10163
83c257ca
NC
10164 /* ARM EHABI, Section 5:
10165 An index table entry consists of 2 words.
10166 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10167 if (exidx_fn & 0x80000000)
32ec8896
NC
10168 {
10169 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10170 res = false;
32ec8896 10171 }
83c257ca 10172
dda8d76d 10173 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10174
dda8d76d 10175 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10176 fputs (": ", stdout);
10177
10178 if (exidx_entry == 1)
10179 {
10180 print_vma (exidx_entry, PREFIX_HEX);
10181 fputs (" [cantunwind]\n", stdout);
10182 }
10183 else if (exidx_entry & 0x80000000)
10184 {
10185 print_vma (exidx_entry, PREFIX_HEX);
10186 fputc ('\n', stdout);
dda8d76d 10187 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10188 }
10189 else
10190 {
8f73510c 10191 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10192 Elf_Internal_Shdr *table_sec;
10193
10194 fputs ("@", stdout);
dda8d76d 10195 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10196 print_vma (table, PREFIX_HEX);
10197 printf ("\n");
10198
10199 /* Locate the matching .ARM.extab. */
10200 if (entry_addr.section != SHN_UNDEF
dda8d76d 10201 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10202 {
dda8d76d 10203 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10204 table_offset = entry_addr.offset;
1a915552
NC
10205 /* PR 18879 */
10206 if (table_offset > table_sec->sh_size
10207 || ((bfd_signed_vma) table_offset) < 0)
10208 {
10209 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10210 (unsigned long) table_offset,
dda8d76d 10211 printable_section_name (filedata, table_sec));
015dc7e1 10212 res = false;
1a915552
NC
10213 continue;
10214 }
0b6ae522
DJ
10215 }
10216 else
10217 {
dda8d76d 10218 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10219 if (table_sec != NULL)
10220 table_offset = table - table_sec->sh_addr;
10221 }
32ec8896 10222
0b6ae522
DJ
10223 if (table_sec == NULL)
10224 {
10225 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10226 (unsigned long) table);
015dc7e1 10227 res = false;
0b6ae522
DJ
10228 continue;
10229 }
32ec8896 10230
dda8d76d 10231 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10232 &extab_arm_sec))
015dc7e1 10233 res = false;
0b6ae522
DJ
10234 }
10235 }
10236
10237 printf ("\n");
10238
948f632f 10239 free (aux->funtab);
0b6ae522
DJ
10240 arm_free_section (&exidx_arm_sec);
10241 arm_free_section (&extab_arm_sec);
32ec8896
NC
10242
10243 return res;
0b6ae522
DJ
10244}
10245
fa197c1c 10246/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10247
015dc7e1 10248static bool
dda8d76d 10249arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10250{
10251 struct arm_unw_aux_info aux;
10252 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10253 Elf_Internal_Shdr *sec;
10254 unsigned long i;
fa197c1c 10255 unsigned int sec_type;
015dc7e1 10256 bool res = true;
0b6ae522 10257
dda8d76d 10258 switch (filedata->file_header.e_machine)
fa197c1c
PB
10259 {
10260 case EM_ARM:
10261 sec_type = SHT_ARM_EXIDX;
10262 break;
10263
10264 case EM_TI_C6000:
10265 sec_type = SHT_C6000_UNWIND;
10266 break;
10267
0b4362b0 10268 default:
74e1a04b 10269 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10270 filedata->file_header.e_machine);
015dc7e1 10271 return false;
fa197c1c
PB
10272 }
10273
dda8d76d 10274 if (filedata->string_table == NULL)
015dc7e1 10275 return false;
1b31d05e
NC
10276
10277 memset (& aux, 0, sizeof (aux));
dda8d76d 10278 aux.filedata = filedata;
0b6ae522 10279
dda8d76d 10280 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10281 {
28d13567 10282 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10283 {
28d13567 10284 if (aux.symtab)
74e1a04b 10285 {
28d13567
AM
10286 error (_("Multiple symbol tables encountered\n"));
10287 free (aux.symtab);
10288 aux.symtab = NULL;
74e1a04b 10289 free (aux.strtab);
28d13567 10290 aux.strtab = NULL;
74e1a04b 10291 }
28d13567
AM
10292 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10293 &aux.strtab, &aux.strtab_size))
015dc7e1 10294 return false;
0b6ae522 10295 }
fa197c1c 10296 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10297 unwsec = sec;
10298 }
10299
1b31d05e 10300 if (unwsec == NULL)
0b6ae522 10301 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10302 else
dda8d76d 10303 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10304 {
10305 if (sec->sh_type == sec_type)
10306 {
d3a49aa8
AM
10307 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10308 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10309 "contains %lu entry:\n",
10310 "\nUnwind section '%s' at offset 0x%lx "
10311 "contains %lu entries:\n",
10312 num_unwind),
dda8d76d 10313 printable_section_name (filedata, sec),
1b31d05e 10314 (unsigned long) sec->sh_offset,
d3a49aa8 10315 num_unwind);
0b6ae522 10316
dda8d76d 10317 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10318 res = false;
1b31d05e
NC
10319 }
10320 }
0b6ae522 10321
9db70fc3
AM
10322 free (aux.symtab);
10323 free ((char *) aux.strtab);
32ec8896
NC
10324
10325 return res;
0b6ae522
DJ
10326}
10327
3ecc00ec
NC
10328static bool
10329no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10330{
10331 printf (_("No processor specific unwind information to decode\n"));
10332 return true;
10333}
10334
015dc7e1 10335static bool
dda8d76d 10336process_unwind (Filedata * filedata)
57346661 10337{
2cf0635d
NC
10338 struct unwind_handler
10339 {
32ec8896 10340 unsigned int machtype;
015dc7e1 10341 bool (* handler)(Filedata *);
2cf0635d
NC
10342 } handlers[] =
10343 {
0b6ae522 10344 { EM_ARM, arm_process_unwind },
57346661
AM
10345 { EM_IA_64, ia64_process_unwind },
10346 { EM_PARISC, hppa_process_unwind },
fa197c1c 10347 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10348 { EM_386, no_processor_specific_unwind },
10349 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10350 { 0, NULL }
57346661
AM
10351 };
10352 int i;
10353
10354 if (!do_unwind)
015dc7e1 10355 return true;
57346661
AM
10356
10357 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10358 if (filedata->file_header.e_machine == handlers[i].machtype)
10359 return handlers[i].handler (filedata);
57346661 10360
1b31d05e 10361 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10362 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10363 return true;
57346661
AM
10364}
10365
37c18eed
SD
10366static void
10367dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10368{
10369 switch (entry->d_tag)
10370 {
10371 case DT_AARCH64_BTI_PLT:
1dbade74 10372 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10373 break;
10374 default:
10375 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10376 break;
10377 }
10378 putchar ('\n');
10379}
10380
252b5132 10381static void
978c4450 10382dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10383{
10384 switch (entry->d_tag)
10385 {
10386 case DT_MIPS_FLAGS:
10387 if (entry->d_un.d_val == 0)
4b68bca3 10388 printf (_("NONE"));
252b5132
RH
10389 else
10390 {
10391 static const char * opts[] =
10392 {
10393 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10394 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10395 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10396 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10397 "RLD_ORDER_SAFE"
10398 };
10399 unsigned int cnt;
015dc7e1 10400 bool first = true;
2b692964 10401
60bca95a 10402 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10403 if (entry->d_un.d_val & (1 << cnt))
10404 {
10405 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10406 first = false;
252b5132 10407 }
252b5132
RH
10408 }
10409 break;
103f02d3 10410
252b5132 10411 case DT_MIPS_IVERSION:
84714f86 10412 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10413 printf (_("Interface Version: %s"),
84714f86 10414 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10415 else
76ca31c0
NC
10416 {
10417 char buf[40];
10418 sprintf_vma (buf, entry->d_un.d_ptr);
10419 /* Note: coded this way so that there is a single string for translation. */
10420 printf (_("<corrupt: %s>"), buf);
10421 }
252b5132 10422 break;
103f02d3 10423
252b5132
RH
10424 case DT_MIPS_TIME_STAMP:
10425 {
d5b07ef4 10426 char timebuf[128];
2cf0635d 10427 struct tm * tmp;
91d6fa6a 10428 time_t atime = entry->d_un.d_val;
82b1b41b 10429
91d6fa6a 10430 tmp = gmtime (&atime);
82b1b41b
NC
10431 /* PR 17531: file: 6accc532. */
10432 if (tmp == NULL)
10433 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10434 else
10435 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10436 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10437 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10438 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10439 }
10440 break;
103f02d3 10441
252b5132
RH
10442 case DT_MIPS_RLD_VERSION:
10443 case DT_MIPS_LOCAL_GOTNO:
10444 case DT_MIPS_CONFLICTNO:
10445 case DT_MIPS_LIBLISTNO:
10446 case DT_MIPS_SYMTABNO:
10447 case DT_MIPS_UNREFEXTNO:
10448 case DT_MIPS_HIPAGENO:
10449 case DT_MIPS_DELTA_CLASS_NO:
10450 case DT_MIPS_DELTA_INSTANCE_NO:
10451 case DT_MIPS_DELTA_RELOC_NO:
10452 case DT_MIPS_DELTA_SYM_NO:
10453 case DT_MIPS_DELTA_CLASSSYM_NO:
10454 case DT_MIPS_COMPACT_SIZE:
c69075ac 10455 print_vma (entry->d_un.d_val, DEC);
252b5132 10456 break;
103f02d3 10457
f16a9783 10458 case DT_MIPS_XHASH:
978c4450
AM
10459 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10460 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10461 /* Falls through. */
10462
103f02d3 10463 default:
4b68bca3 10464 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10465 }
4b68bca3 10466 putchar ('\n');
103f02d3
UD
10467}
10468
103f02d3 10469static void
2cf0635d 10470dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10471{
10472 switch (entry->d_tag)
10473 {
10474 case DT_HP_DLD_FLAGS:
10475 {
10476 static struct
10477 {
10478 long int bit;
2cf0635d 10479 const char * str;
5e220199
NC
10480 }
10481 flags[] =
10482 {
10483 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10484 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10485 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10486 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10487 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10488 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10489 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10490 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10491 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10492 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10493 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10494 { DT_HP_GST, "HP_GST" },
10495 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10496 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10497 { DT_HP_NODELETE, "HP_NODELETE" },
10498 { DT_HP_GROUP, "HP_GROUP" },
10499 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10500 };
015dc7e1 10501 bool first = true;
5e220199 10502 size_t cnt;
f7a99963 10503 bfd_vma val = entry->d_un.d_val;
103f02d3 10504
60bca95a 10505 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10506 if (val & flags[cnt].bit)
30800947
NC
10507 {
10508 if (! first)
10509 putchar (' ');
10510 fputs (flags[cnt].str, stdout);
015dc7e1 10511 first = false;
30800947
NC
10512 val ^= flags[cnt].bit;
10513 }
76da6bbe 10514
103f02d3 10515 if (val != 0 || first)
f7a99963
NC
10516 {
10517 if (! first)
10518 putchar (' ');
10519 print_vma (val, HEX);
10520 }
103f02d3
UD
10521 }
10522 break;
76da6bbe 10523
252b5132 10524 default:
f7a99963
NC
10525 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10526 break;
252b5132 10527 }
35b1837e 10528 putchar ('\n');
252b5132
RH
10529}
10530
28f997cf
TG
10531#ifdef BFD64
10532
10533/* VMS vs Unix time offset and factor. */
10534
10535#define VMS_EPOCH_OFFSET 35067168000000000LL
10536#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10537#ifndef INT64_MIN
10538#define INT64_MIN (-9223372036854775807LL - 1)
10539#endif
28f997cf
TG
10540
10541/* Display a VMS time in a human readable format. */
10542
10543static void
10544print_vms_time (bfd_int64_t vmstime)
10545{
dccc31de 10546 struct tm *tm = NULL;
28f997cf
TG
10547 time_t unxtime;
10548
dccc31de
AM
10549 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10550 {
10551 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10552 unxtime = vmstime;
10553 if (unxtime == vmstime)
10554 tm = gmtime (&unxtime);
10555 }
10556 if (tm != NULL)
10557 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10558 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10559 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10560}
10561#endif /* BFD64 */
10562
ecc51f48 10563static void
2cf0635d 10564dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10565{
10566 switch (entry->d_tag)
10567 {
0de14b54 10568 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10569 /* First 3 slots reserved. */
ecc51f48
NC
10570 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10571 printf (" -- ");
10572 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10573 break;
10574
28f997cf
TG
10575 case DT_IA_64_VMS_LINKTIME:
10576#ifdef BFD64
10577 print_vms_time (entry->d_un.d_val);
10578#endif
10579 break;
10580
10581 case DT_IA_64_VMS_LNKFLAGS:
10582 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10583 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10584 printf (" CALL_DEBUG");
10585 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10586 printf (" NOP0BUFS");
10587 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10588 printf (" P0IMAGE");
10589 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10590 printf (" MKTHREADS");
10591 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10592 printf (" UPCALLS");
10593 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10594 printf (" IMGSTA");
10595 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10596 printf (" INITIALIZE");
10597 if (entry->d_un.d_val & VMS_LF_MAIN)
10598 printf (" MAIN");
10599 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10600 printf (" EXE_INIT");
10601 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10602 printf (" TBK_IN_IMG");
10603 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10604 printf (" DBG_IN_IMG");
10605 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10606 printf (" TBK_IN_DSF");
10607 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10608 printf (" DBG_IN_DSF");
10609 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10610 printf (" SIGNATURES");
10611 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10612 printf (" REL_SEG_OFF");
10613 break;
10614
bdf4d63a
JJ
10615 default:
10616 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10617 break;
ecc51f48 10618 }
bdf4d63a 10619 putchar ('\n');
ecc51f48
NC
10620}
10621
015dc7e1 10622static bool
dda8d76d 10623get_32bit_dynamic_section (Filedata * filedata)
252b5132 10624{
2cf0635d
NC
10625 Elf32_External_Dyn * edyn;
10626 Elf32_External_Dyn * ext;
10627 Elf_Internal_Dyn * entry;
103f02d3 10628
978c4450
AM
10629 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10630 filedata->dynamic_addr, 1,
10631 filedata->dynamic_size,
10632 _("dynamic section"));
a6e9f9df 10633 if (!edyn)
015dc7e1 10634 return false;
103f02d3 10635
071436c6
NC
10636 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10637 might not have the luxury of section headers. Look for the DT_NULL
10638 terminator to determine the number of entries. */
978c4450
AM
10639 for (ext = edyn, filedata->dynamic_nent = 0;
10640 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10641 ext++)
10642 {
978c4450 10643 filedata->dynamic_nent++;
ba2685cc
AM
10644 if (BYTE_GET (ext->d_tag) == DT_NULL)
10645 break;
10646 }
252b5132 10647
978c4450
AM
10648 filedata->dynamic_section
10649 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10650 if (filedata->dynamic_section == NULL)
252b5132 10651 {
8b73c356 10652 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10653 (unsigned long) filedata->dynamic_nent);
9ea033b2 10654 free (edyn);
015dc7e1 10655 return false;
9ea033b2 10656 }
252b5132 10657
978c4450
AM
10658 for (ext = edyn, entry = filedata->dynamic_section;
10659 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10660 ext++, entry++)
9ea033b2 10661 {
fb514b26
AM
10662 entry->d_tag = BYTE_GET (ext->d_tag);
10663 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10664 }
10665
9ea033b2
NC
10666 free (edyn);
10667
015dc7e1 10668 return true;
9ea033b2
NC
10669}
10670
015dc7e1 10671static bool
dda8d76d 10672get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10673{
2cf0635d
NC
10674 Elf64_External_Dyn * edyn;
10675 Elf64_External_Dyn * ext;
10676 Elf_Internal_Dyn * entry;
103f02d3 10677
071436c6 10678 /* Read in the data. */
978c4450
AM
10679 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10680 filedata->dynamic_addr, 1,
10681 filedata->dynamic_size,
10682 _("dynamic section"));
a6e9f9df 10683 if (!edyn)
015dc7e1 10684 return false;
103f02d3 10685
071436c6
NC
10686 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10687 might not have the luxury of section headers. Look for the DT_NULL
10688 terminator to determine the number of entries. */
978c4450 10689 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10690 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10691 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10692 ext++)
10693 {
978c4450 10694 filedata->dynamic_nent++;
66543521 10695 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10696 break;
10697 }
252b5132 10698
978c4450
AM
10699 filedata->dynamic_section
10700 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10701 if (filedata->dynamic_section == NULL)
252b5132 10702 {
8b73c356 10703 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10704 (unsigned long) filedata->dynamic_nent);
252b5132 10705 free (edyn);
015dc7e1 10706 return false;
252b5132
RH
10707 }
10708
071436c6 10709 /* Convert from external to internal formats. */
978c4450
AM
10710 for (ext = edyn, entry = filedata->dynamic_section;
10711 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10712 ext++, entry++)
252b5132 10713 {
66543521
AM
10714 entry->d_tag = BYTE_GET (ext->d_tag);
10715 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10716 }
10717
10718 free (edyn);
10719
015dc7e1 10720 return true;
9ea033b2
NC
10721}
10722
4de91c10
AM
10723static bool
10724get_dynamic_section (Filedata *filedata)
10725{
10726 if (filedata->dynamic_section)
10727 return true;
10728
10729 if (is_32bit_elf)
10730 return get_32bit_dynamic_section (filedata);
10731 else
10732 return get_64bit_dynamic_section (filedata);
10733}
10734
e9e44622
JJ
10735static void
10736print_dynamic_flags (bfd_vma flags)
d1133906 10737{
015dc7e1 10738 bool first = true;
13ae64f3 10739
d1133906
NC
10740 while (flags)
10741 {
10742 bfd_vma flag;
10743
10744 flag = flags & - flags;
10745 flags &= ~ flag;
10746
e9e44622 10747 if (first)
015dc7e1 10748 first = false;
e9e44622
JJ
10749 else
10750 putc (' ', stdout);
13ae64f3 10751
d1133906
NC
10752 switch (flag)
10753 {
e9e44622
JJ
10754 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10755 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10756 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10757 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10758 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10759 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10760 }
10761 }
e9e44622 10762 puts ("");
d1133906
NC
10763}
10764
10ca4b04
L
10765static bfd_vma *
10766get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10767{
10768 unsigned char * e_data;
10769 bfd_vma * i_data;
10770
10771 /* If the size_t type is smaller than the bfd_size_type, eg because
10772 you are building a 32-bit tool on a 64-bit host, then make sure
10773 that when (number) is cast to (size_t) no information is lost. */
10774 if (sizeof (size_t) < sizeof (bfd_size_type)
10775 && (bfd_size_type) ((size_t) number) != number)
10776 {
10777 error (_("Size truncation prevents reading %s elements of size %u\n"),
10778 bfd_vmatoa ("u", number), ent_size);
10779 return NULL;
10780 }
10781
10782 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10783 attempting to allocate memory when the read is bound to fail. */
10784 if (ent_size * number > filedata->file_size)
10785 {
10786 error (_("Invalid number of dynamic entries: %s\n"),
10787 bfd_vmatoa ("u", number));
10788 return NULL;
10789 }
10790
10791 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10792 if (e_data == NULL)
10793 {
10794 error (_("Out of memory reading %s dynamic entries\n"),
10795 bfd_vmatoa ("u", number));
10796 return NULL;
10797 }
10798
10799 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10800 {
10801 error (_("Unable to read in %s bytes of dynamic data\n"),
10802 bfd_vmatoa ("u", number * ent_size));
10803 free (e_data);
10804 return NULL;
10805 }
10806
10807 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10808 if (i_data == NULL)
10809 {
10810 error (_("Out of memory allocating space for %s dynamic entries\n"),
10811 bfd_vmatoa ("u", number));
10812 free (e_data);
10813 return NULL;
10814 }
10815
10816 while (number--)
10817 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10818
10819 free (e_data);
10820
10821 return i_data;
10822}
10823
10824static unsigned long
10825get_num_dynamic_syms (Filedata * filedata)
10826{
10827 unsigned long num_of_syms = 0;
10828
10829 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10830 return num_of_syms;
10831
978c4450 10832 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10833 {
10834 unsigned char nb[8];
10835 unsigned char nc[8];
10836 unsigned int hash_ent_size = 4;
10837
10838 if ((filedata->file_header.e_machine == EM_ALPHA
10839 || filedata->file_header.e_machine == EM_S390
10840 || filedata->file_header.e_machine == EM_S390_OLD)
10841 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10842 hash_ent_size = 8;
10843
10844 if (fseek (filedata->handle,
978c4450
AM
10845 (filedata->archive_file_offset
10846 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10847 sizeof nb + sizeof nc)),
10848 SEEK_SET))
10849 {
10850 error (_("Unable to seek to start of dynamic information\n"));
10851 goto no_hash;
10852 }
10853
10854 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10855 {
10856 error (_("Failed to read in number of buckets\n"));
10857 goto no_hash;
10858 }
10859
10860 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10861 {
10862 error (_("Failed to read in number of chains\n"));
10863 goto no_hash;
10864 }
10865
978c4450
AM
10866 filedata->nbuckets = byte_get (nb, hash_ent_size);
10867 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10868
2482f306
AM
10869 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10870 {
10871 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10872 hash_ent_size);
10873 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10874 hash_ent_size);
001890e1 10875
2482f306
AM
10876 if (filedata->buckets != NULL && filedata->chains != NULL)
10877 num_of_syms = filedata->nchains;
10878 }
ceb9bf11 10879 no_hash:
10ca4b04
L
10880 if (num_of_syms == 0)
10881 {
9db70fc3
AM
10882 free (filedata->buckets);
10883 filedata->buckets = NULL;
10884 free (filedata->chains);
10885 filedata->chains = NULL;
978c4450 10886 filedata->nbuckets = 0;
10ca4b04
L
10887 }
10888 }
10889
978c4450 10890 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10891 {
10892 unsigned char nb[16];
10893 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10894 bfd_vma buckets_vma;
10895 unsigned long hn;
10ca4b04
L
10896
10897 if (fseek (filedata->handle,
978c4450
AM
10898 (filedata->archive_file_offset
10899 + offset_from_vma (filedata,
10900 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10901 sizeof nb)),
10902 SEEK_SET))
10903 {
10904 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10905 goto no_gnu_hash;
10906 }
10907
10908 if (fread (nb, 16, 1, filedata->handle) != 1)
10909 {
10910 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10911 goto no_gnu_hash;
10912 }
10913
978c4450
AM
10914 filedata->ngnubuckets = byte_get (nb, 4);
10915 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10916 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10917 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10918 if (is_32bit_elf)
10919 buckets_vma += bitmaskwords * 4;
10920 else
10921 buckets_vma += bitmaskwords * 8;
10922
10923 if (fseek (filedata->handle,
978c4450 10924 (filedata->archive_file_offset
10ca4b04
L
10925 + offset_from_vma (filedata, buckets_vma, 4)),
10926 SEEK_SET))
10927 {
10928 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10929 goto no_gnu_hash;
10930 }
10931
978c4450
AM
10932 filedata->gnubuckets
10933 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10934
978c4450 10935 if (filedata->gnubuckets == NULL)
90837ea7 10936 goto no_gnu_hash;
10ca4b04 10937
978c4450
AM
10938 for (i = 0; i < filedata->ngnubuckets; i++)
10939 if (filedata->gnubuckets[i] != 0)
10ca4b04 10940 {
978c4450 10941 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10942 goto no_gnu_hash;
10ca4b04 10943
978c4450
AM
10944 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10945 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10946 }
10947
10948 if (maxchain == 0xffffffff)
90837ea7 10949 goto no_gnu_hash;
10ca4b04 10950
978c4450 10951 maxchain -= filedata->gnusymidx;
10ca4b04
L
10952
10953 if (fseek (filedata->handle,
978c4450
AM
10954 (filedata->archive_file_offset
10955 + offset_from_vma (filedata,
10956 buckets_vma + 4 * (filedata->ngnubuckets
10957 + maxchain),
10958 4)),
10ca4b04
L
10959 SEEK_SET))
10960 {
10961 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10962 goto no_gnu_hash;
10963 }
10964
10965 do
10966 {
10967 if (fread (nb, 4, 1, filedata->handle) != 1)
10968 {
10969 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10970 goto no_gnu_hash;
10971 }
10972
10973 if (maxchain + 1 == 0)
90837ea7 10974 goto no_gnu_hash;
10ca4b04
L
10975
10976 ++maxchain;
10977 }
10978 while ((byte_get (nb, 4) & 1) == 0);
10979
10980 if (fseek (filedata->handle,
978c4450
AM
10981 (filedata->archive_file_offset
10982 + offset_from_vma (filedata, (buckets_vma
10983 + 4 * filedata->ngnubuckets),
10984 4)),
10ca4b04
L
10985 SEEK_SET))
10986 {
10987 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10988 goto no_gnu_hash;
10989 }
10990
978c4450
AM
10991 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10992 filedata->ngnuchains = maxchain;
10ca4b04 10993
978c4450 10994 if (filedata->gnuchains == NULL)
90837ea7 10995 goto no_gnu_hash;
10ca4b04 10996
978c4450 10997 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10998 {
10999 if (fseek (filedata->handle,
978c4450 11000 (filedata->archive_file_offset
10ca4b04 11001 + offset_from_vma (filedata, (buckets_vma
978c4450 11002 + 4 * (filedata->ngnubuckets
10ca4b04
L
11003 + maxchain)), 4)),
11004 SEEK_SET))
11005 {
11006 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11007 goto no_gnu_hash;
11008 }
11009
978c4450 11010 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11011 if (filedata->mipsxlat == NULL)
11012 goto no_gnu_hash;
10ca4b04
L
11013 }
11014
978c4450
AM
11015 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11016 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11017 {
978c4450
AM
11018 bfd_vma si = filedata->gnubuckets[hn];
11019 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11020
11021 do
11022 {
978c4450 11023 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11024 {
c31ab5a0
AM
11025 if (off < filedata->ngnuchains
11026 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11027 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11028 }
11029 else
11030 {
11031 if (si >= num_of_syms)
11032 num_of_syms = si + 1;
11033 }
11034 si++;
11035 }
978c4450
AM
11036 while (off < filedata->ngnuchains
11037 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11038 }
11039
90837ea7 11040 if (num_of_syms == 0)
10ca4b04 11041 {
90837ea7 11042 no_gnu_hash:
9db70fc3
AM
11043 free (filedata->mipsxlat);
11044 filedata->mipsxlat = NULL;
11045 free (filedata->gnuchains);
11046 filedata->gnuchains = NULL;
11047 free (filedata->gnubuckets);
11048 filedata->gnubuckets = NULL;
978c4450
AM
11049 filedata->ngnubuckets = 0;
11050 filedata->ngnuchains = 0;
10ca4b04
L
11051 }
11052 }
11053
11054 return num_of_syms;
11055}
11056
b2d38a17
NC
11057/* Parse and display the contents of the dynamic section. */
11058
015dc7e1 11059static bool
dda8d76d 11060process_dynamic_section (Filedata * filedata)
9ea033b2 11061{
2cf0635d 11062 Elf_Internal_Dyn * entry;
9ea033b2 11063
93df3340 11064 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11065 {
11066 if (do_dynamic)
ca0e11aa
NC
11067 {
11068 if (filedata->is_separate)
11069 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11070 filedata->file_name);
11071 else
11072 printf (_("\nThere is no dynamic section in this file.\n"));
11073 }
9ea033b2 11074
015dc7e1 11075 return true;
9ea033b2
NC
11076 }
11077
4de91c10
AM
11078 if (!get_dynamic_section (filedata))
11079 return false;
9ea033b2 11080
252b5132 11081 /* Find the appropriate symbol table. */
978c4450 11082 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11083 {
2482f306
AM
11084 unsigned long num_of_syms;
11085
978c4450
AM
11086 for (entry = filedata->dynamic_section;
11087 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11088 ++entry)
10ca4b04 11089 if (entry->d_tag == DT_SYMTAB)
978c4450 11090 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11091 else if (entry->d_tag == DT_SYMENT)
978c4450 11092 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11093 else if (entry->d_tag == DT_HASH)
978c4450 11094 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11095 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11096 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11097 else if ((filedata->file_header.e_machine == EM_MIPS
11098 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11099 && entry->d_tag == DT_MIPS_XHASH)
11100 {
978c4450
AM
11101 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11102 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11103 }
252b5132 11104
2482f306
AM
11105 num_of_syms = get_num_dynamic_syms (filedata);
11106
11107 if (num_of_syms != 0
11108 && filedata->dynamic_symbols == NULL
11109 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11110 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11111 {
11112 Elf_Internal_Phdr *seg;
2482f306 11113 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11114
2482f306
AM
11115 if (! get_program_headers (filedata))
11116 {
11117 error (_("Cannot interpret virtual addresses "
11118 "without program headers.\n"));
015dc7e1 11119 return false;
2482f306 11120 }
252b5132 11121
2482f306
AM
11122 for (seg = filedata->program_headers;
11123 seg < filedata->program_headers + filedata->file_header.e_phnum;
11124 ++seg)
11125 {
11126 if (seg->p_type != PT_LOAD)
11127 continue;
252b5132 11128
2482f306
AM
11129 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11130 {
11131 /* See PR 21379 for a reproducer. */
11132 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11133 return false;
2482f306 11134 }
252b5132 11135
2482f306
AM
11136 if (vma >= (seg->p_vaddr & -seg->p_align)
11137 && vma < seg->p_vaddr + seg->p_filesz)
11138 {
11139 /* Since we do not know how big the symbol table is,
11140 we default to reading in up to the end of PT_LOAD
11141 segment and processing that. This is overkill, I
11142 know, but it should work. */
11143 Elf_Internal_Shdr section;
11144 section.sh_offset = (vma - seg->p_vaddr
11145 + seg->p_offset);
11146 section.sh_size = (num_of_syms
11147 * filedata->dynamic_info[DT_SYMENT]);
11148 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11149
11150 if (do_checks
11151 && filedata->dynamic_symtab_section != NULL
11152 && ((filedata->dynamic_symtab_section->sh_offset
11153 != section.sh_offset)
11154 || (filedata->dynamic_symtab_section->sh_size
11155 != section.sh_size)
11156 || (filedata->dynamic_symtab_section->sh_entsize
11157 != section.sh_entsize)))
11158 warn (_("\
11159the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11160
2482f306
AM
11161 section.sh_name = filedata->string_table_length;
11162 filedata->dynamic_symbols
4de91c10 11163 = get_elf_symbols (filedata, &section,
2482f306
AM
11164 &filedata->num_dynamic_syms);
11165 if (filedata->dynamic_symbols == NULL
11166 || filedata->num_dynamic_syms != num_of_syms)
11167 {
11168 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11169 return false;
2482f306
AM
11170 }
11171 break;
11172 }
11173 }
11174 }
11175 }
252b5132
RH
11176
11177 /* Similarly find a string table. */
978c4450
AM
11178 if (filedata->dynamic_strings == NULL)
11179 for (entry = filedata->dynamic_section;
11180 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11181 ++entry)
11182 {
11183 if (entry->d_tag == DT_STRTAB)
978c4450 11184 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11185
10ca4b04 11186 if (entry->d_tag == DT_STRSZ)
978c4450 11187 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11188
978c4450
AM
11189 if (filedata->dynamic_info[DT_STRTAB]
11190 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11191 {
11192 unsigned long offset;
978c4450 11193 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11194
11195 offset = offset_from_vma (filedata,
978c4450 11196 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11197 str_tab_len);
8ac10c5b
L
11198 if (do_checks
11199 && filedata->dynamic_strtab_section
11200 && ((filedata->dynamic_strtab_section->sh_offset
11201 != (file_ptr) offset)
11202 || (filedata->dynamic_strtab_section->sh_size
11203 != str_tab_len)))
11204 warn (_("\
11205the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11206
978c4450
AM
11207 filedata->dynamic_strings
11208 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11209 _("dynamic string table"));
11210 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11211 {
11212 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11213 break;
11214 }
e3d39609 11215
978c4450 11216 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11217 break;
11218 }
11219 }
252b5132
RH
11220
11221 /* And find the syminfo section if available. */
978c4450 11222 if (filedata->dynamic_syminfo == NULL)
252b5132 11223 {
3e8bba36 11224 unsigned long syminsz = 0;
252b5132 11225
978c4450
AM
11226 for (entry = filedata->dynamic_section;
11227 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11228 ++entry)
252b5132
RH
11229 {
11230 if (entry->d_tag == DT_SYMINENT)
11231 {
11232 /* Note: these braces are necessary to avoid a syntax
11233 error from the SunOS4 C compiler. */
049b0c3a
NC
11234 /* PR binutils/17531: A corrupt file can trigger this test.
11235 So do not use an assert, instead generate an error message. */
11236 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11237 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11238 (int) entry->d_un.d_val);
252b5132
RH
11239 }
11240 else if (entry->d_tag == DT_SYMINSZ)
11241 syminsz = entry->d_un.d_val;
11242 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11243 filedata->dynamic_syminfo_offset
11244 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11245 }
11246
978c4450 11247 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11248 {
2cf0635d
NC
11249 Elf_External_Syminfo * extsyminfo;
11250 Elf_External_Syminfo * extsym;
11251 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11252
11253 /* There is a syminfo section. Read the data. */
3f5e193b 11254 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11255 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11256 1, syminsz, _("symbol information"));
a6e9f9df 11257 if (!extsyminfo)
015dc7e1 11258 return false;
252b5132 11259
978c4450 11260 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11261 {
11262 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11263 free (filedata->dynamic_syminfo);
e3d39609 11264 }
978c4450
AM
11265 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11266 if (filedata->dynamic_syminfo == NULL)
252b5132 11267 {
2482f306
AM
11268 error (_("Out of memory allocating %lu bytes "
11269 "for dynamic symbol info\n"),
8b73c356 11270 (unsigned long) syminsz);
015dc7e1 11271 return false;
252b5132
RH
11272 }
11273
2482f306
AM
11274 filedata->dynamic_syminfo_nent
11275 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11276 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11277 syminfo < (filedata->dynamic_syminfo
11278 + filedata->dynamic_syminfo_nent);
86dba8ee 11279 ++syminfo, ++extsym)
252b5132 11280 {
86dba8ee
AM
11281 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11282 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11283 }
11284
11285 free (extsyminfo);
11286 }
11287 }
11288
978c4450 11289 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11290 {
f253158f
NC
11291 if (filedata->is_separate)
11292 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11293 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11294 (unsigned long) filedata->dynamic_nent),
11295 filedata->file_name,
11296 filedata->dynamic_addr,
11297 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11298 else
f253158f
NC
11299 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11300 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11301 (unsigned long) filedata->dynamic_nent),
ca0e11aa
NC
11302 filedata->dynamic_addr,
11303 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11304 }
252b5132
RH
11305 if (do_dynamic)
11306 printf (_(" Tag Type Name/Value\n"));
11307
978c4450
AM
11308 for (entry = filedata->dynamic_section;
11309 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11310 entry++)
252b5132
RH
11311 {
11312 if (do_dynamic)
f7a99963 11313 {
2cf0635d 11314 const char * dtype;
e699b9ff 11315
f7a99963
NC
11316 putchar (' ');
11317 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11318 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11319 printf (" (%s)%*s", dtype,
32ec8896 11320 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11321 }
252b5132
RH
11322
11323 switch (entry->d_tag)
11324 {
d1133906
NC
11325 case DT_FLAGS:
11326 if (do_dynamic)
e9e44622 11327 print_dynamic_flags (entry->d_un.d_val);
d1133906 11328 break;
76da6bbe 11329
252b5132
RH
11330 case DT_AUXILIARY:
11331 case DT_FILTER:
019148e4
L
11332 case DT_CONFIG:
11333 case DT_DEPAUDIT:
11334 case DT_AUDIT:
252b5132
RH
11335 if (do_dynamic)
11336 {
019148e4 11337 switch (entry->d_tag)
b34976b6 11338 {
019148e4
L
11339 case DT_AUXILIARY:
11340 printf (_("Auxiliary library"));
11341 break;
11342
11343 case DT_FILTER:
11344 printf (_("Filter library"));
11345 break;
11346
b34976b6 11347 case DT_CONFIG:
019148e4
L
11348 printf (_("Configuration file"));
11349 break;
11350
11351 case DT_DEPAUDIT:
11352 printf (_("Dependency audit library"));
11353 break;
11354
11355 case DT_AUDIT:
11356 printf (_("Audit library"));
11357 break;
11358 }
252b5132 11359
84714f86 11360 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11361 printf (": [%s]\n",
84714f86 11362 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11363 else
f7a99963
NC
11364 {
11365 printf (": ");
11366 print_vma (entry->d_un.d_val, PREFIX_HEX);
11367 putchar ('\n');
11368 }
252b5132
RH
11369 }
11370 break;
11371
dcefbbbd 11372 case DT_FEATURE:
252b5132
RH
11373 if (do_dynamic)
11374 {
11375 printf (_("Flags:"));
86f55779 11376
252b5132
RH
11377 if (entry->d_un.d_val == 0)
11378 printf (_(" None\n"));
11379 else
11380 {
11381 unsigned long int val = entry->d_un.d_val;
86f55779 11382
252b5132
RH
11383 if (val & DTF_1_PARINIT)
11384 {
11385 printf (" PARINIT");
11386 val ^= DTF_1_PARINIT;
11387 }
dcefbbbd
L
11388 if (val & DTF_1_CONFEXP)
11389 {
11390 printf (" CONFEXP");
11391 val ^= DTF_1_CONFEXP;
11392 }
252b5132
RH
11393 if (val != 0)
11394 printf (" %lx", val);
11395 puts ("");
11396 }
11397 }
11398 break;
11399
11400 case DT_POSFLAG_1:
11401 if (do_dynamic)
11402 {
11403 printf (_("Flags:"));
86f55779 11404
252b5132
RH
11405 if (entry->d_un.d_val == 0)
11406 printf (_(" None\n"));
11407 else
11408 {
11409 unsigned long int val = entry->d_un.d_val;
86f55779 11410
252b5132
RH
11411 if (val & DF_P1_LAZYLOAD)
11412 {
11413 printf (" LAZYLOAD");
11414 val ^= DF_P1_LAZYLOAD;
11415 }
11416 if (val & DF_P1_GROUPPERM)
11417 {
11418 printf (" GROUPPERM");
11419 val ^= DF_P1_GROUPPERM;
11420 }
11421 if (val != 0)
11422 printf (" %lx", val);
11423 puts ("");
11424 }
11425 }
11426 break;
11427
11428 case DT_FLAGS_1:
11429 if (do_dynamic)
11430 {
11431 printf (_("Flags:"));
11432 if (entry->d_un.d_val == 0)
11433 printf (_(" None\n"));
11434 else
11435 {
11436 unsigned long int val = entry->d_un.d_val;
86f55779 11437
252b5132
RH
11438 if (val & DF_1_NOW)
11439 {
11440 printf (" NOW");
11441 val ^= DF_1_NOW;
11442 }
11443 if (val & DF_1_GLOBAL)
11444 {
11445 printf (" GLOBAL");
11446 val ^= DF_1_GLOBAL;
11447 }
11448 if (val & DF_1_GROUP)
11449 {
11450 printf (" GROUP");
11451 val ^= DF_1_GROUP;
11452 }
11453 if (val & DF_1_NODELETE)
11454 {
11455 printf (" NODELETE");
11456 val ^= DF_1_NODELETE;
11457 }
11458 if (val & DF_1_LOADFLTR)
11459 {
11460 printf (" LOADFLTR");
11461 val ^= DF_1_LOADFLTR;
11462 }
11463 if (val & DF_1_INITFIRST)
11464 {
11465 printf (" INITFIRST");
11466 val ^= DF_1_INITFIRST;
11467 }
11468 if (val & DF_1_NOOPEN)
11469 {
11470 printf (" NOOPEN");
11471 val ^= DF_1_NOOPEN;
11472 }
11473 if (val & DF_1_ORIGIN)
11474 {
11475 printf (" ORIGIN");
11476 val ^= DF_1_ORIGIN;
11477 }
11478 if (val & DF_1_DIRECT)
11479 {
11480 printf (" DIRECT");
11481 val ^= DF_1_DIRECT;
11482 }
11483 if (val & DF_1_TRANS)
11484 {
11485 printf (" TRANS");
11486 val ^= DF_1_TRANS;
11487 }
11488 if (val & DF_1_INTERPOSE)
11489 {
11490 printf (" INTERPOSE");
11491 val ^= DF_1_INTERPOSE;
11492 }
f7db6139 11493 if (val & DF_1_NODEFLIB)
dcefbbbd 11494 {
f7db6139
L
11495 printf (" NODEFLIB");
11496 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11497 }
11498 if (val & DF_1_NODUMP)
11499 {
11500 printf (" NODUMP");
11501 val ^= DF_1_NODUMP;
11502 }
34b60028 11503 if (val & DF_1_CONFALT)
dcefbbbd 11504 {
34b60028
L
11505 printf (" CONFALT");
11506 val ^= DF_1_CONFALT;
11507 }
11508 if (val & DF_1_ENDFILTEE)
11509 {
11510 printf (" ENDFILTEE");
11511 val ^= DF_1_ENDFILTEE;
11512 }
11513 if (val & DF_1_DISPRELDNE)
11514 {
11515 printf (" DISPRELDNE");
11516 val ^= DF_1_DISPRELDNE;
11517 }
11518 if (val & DF_1_DISPRELPND)
11519 {
11520 printf (" DISPRELPND");
11521 val ^= DF_1_DISPRELPND;
11522 }
11523 if (val & DF_1_NODIRECT)
11524 {
11525 printf (" NODIRECT");
11526 val ^= DF_1_NODIRECT;
11527 }
11528 if (val & DF_1_IGNMULDEF)
11529 {
11530 printf (" IGNMULDEF");
11531 val ^= DF_1_IGNMULDEF;
11532 }
11533 if (val & DF_1_NOKSYMS)
11534 {
11535 printf (" NOKSYMS");
11536 val ^= DF_1_NOKSYMS;
11537 }
11538 if (val & DF_1_NOHDR)
11539 {
11540 printf (" NOHDR");
11541 val ^= DF_1_NOHDR;
11542 }
11543 if (val & DF_1_EDITED)
11544 {
11545 printf (" EDITED");
11546 val ^= DF_1_EDITED;
11547 }
11548 if (val & DF_1_NORELOC)
11549 {
11550 printf (" NORELOC");
11551 val ^= DF_1_NORELOC;
11552 }
11553 if (val & DF_1_SYMINTPOSE)
11554 {
11555 printf (" SYMINTPOSE");
11556 val ^= DF_1_SYMINTPOSE;
11557 }
11558 if (val & DF_1_GLOBAUDIT)
11559 {
11560 printf (" GLOBAUDIT");
11561 val ^= DF_1_GLOBAUDIT;
11562 }
11563 if (val & DF_1_SINGLETON)
11564 {
11565 printf (" SINGLETON");
11566 val ^= DF_1_SINGLETON;
dcefbbbd 11567 }
5c383f02
RO
11568 if (val & DF_1_STUB)
11569 {
11570 printf (" STUB");
11571 val ^= DF_1_STUB;
11572 }
11573 if (val & DF_1_PIE)
11574 {
11575 printf (" PIE");
11576 val ^= DF_1_PIE;
11577 }
b1202ffa
L
11578 if (val & DF_1_KMOD)
11579 {
11580 printf (" KMOD");
11581 val ^= DF_1_KMOD;
11582 }
11583 if (val & DF_1_WEAKFILTER)
11584 {
11585 printf (" WEAKFILTER");
11586 val ^= DF_1_WEAKFILTER;
11587 }
11588 if (val & DF_1_NOCOMMON)
11589 {
11590 printf (" NOCOMMON");
11591 val ^= DF_1_NOCOMMON;
11592 }
252b5132
RH
11593 if (val != 0)
11594 printf (" %lx", val);
11595 puts ("");
11596 }
11597 }
11598 break;
11599
11600 case DT_PLTREL:
978c4450 11601 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11602 if (do_dynamic)
dda8d76d 11603 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11604 break;
11605
11606 case DT_NULL :
11607 case DT_NEEDED :
11608 case DT_PLTGOT :
11609 case DT_HASH :
11610 case DT_STRTAB :
11611 case DT_SYMTAB :
11612 case DT_RELA :
11613 case DT_INIT :
11614 case DT_FINI :
11615 case DT_SONAME :
11616 case DT_RPATH :
11617 case DT_SYMBOLIC:
11618 case DT_REL :
a7fd1186 11619 case DT_RELR :
252b5132
RH
11620 case DT_DEBUG :
11621 case DT_TEXTREL :
11622 case DT_JMPREL :
019148e4 11623 case DT_RUNPATH :
978c4450 11624 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11625
11626 if (do_dynamic)
11627 {
84714f86 11628 const char *name;
252b5132 11629
84714f86
AM
11630 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11631 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11632 else
d79b3d50 11633 name = NULL;
252b5132
RH
11634
11635 if (name)
11636 {
11637 switch (entry->d_tag)
11638 {
11639 case DT_NEEDED:
11640 printf (_("Shared library: [%s]"), name);
11641
13acb58d
AM
11642 if (filedata->program_interpreter
11643 && streq (name, filedata->program_interpreter))
f7a99963 11644 printf (_(" program interpreter"));
252b5132
RH
11645 break;
11646
11647 case DT_SONAME:
f7a99963 11648 printf (_("Library soname: [%s]"), name);
252b5132
RH
11649 break;
11650
11651 case DT_RPATH:
f7a99963 11652 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11653 break;
11654
019148e4
L
11655 case DT_RUNPATH:
11656 printf (_("Library runpath: [%s]"), name);
11657 break;
11658
252b5132 11659 default:
f7a99963
NC
11660 print_vma (entry->d_un.d_val, PREFIX_HEX);
11661 break;
252b5132
RH
11662 }
11663 }
11664 else
f7a99963
NC
11665 print_vma (entry->d_un.d_val, PREFIX_HEX);
11666
11667 putchar ('\n');
252b5132
RH
11668 }
11669 break;
11670
11671 case DT_PLTRELSZ:
11672 case DT_RELASZ :
11673 case DT_STRSZ :
11674 case DT_RELSZ :
11675 case DT_RELAENT :
a7fd1186
FS
11676 case DT_RELRENT :
11677 case DT_RELRSZ :
252b5132
RH
11678 case DT_SYMENT :
11679 case DT_RELENT :
978c4450 11680 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11681 /* Fall through. */
252b5132
RH
11682 case DT_PLTPADSZ:
11683 case DT_MOVEENT :
11684 case DT_MOVESZ :
04d8355a 11685 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11686 case DT_INIT_ARRAYSZ:
11687 case DT_FINI_ARRAYSZ:
047b2264
JJ
11688 case DT_GNU_CONFLICTSZ:
11689 case DT_GNU_LIBLISTSZ:
252b5132 11690 if (do_dynamic)
f7a99963
NC
11691 {
11692 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11693 printf (_(" (bytes)\n"));
f7a99963 11694 }
252b5132
RH
11695 break;
11696
11697 case DT_VERDEFNUM:
11698 case DT_VERNEEDNUM:
11699 case DT_RELACOUNT:
11700 case DT_RELCOUNT:
11701 if (do_dynamic)
f7a99963
NC
11702 {
11703 print_vma (entry->d_un.d_val, UNSIGNED);
11704 putchar ('\n');
11705 }
252b5132
RH
11706 break;
11707
11708 case DT_SYMINSZ:
11709 case DT_SYMINENT:
11710 case DT_SYMINFO:
11711 case DT_USED:
11712 case DT_INIT_ARRAY:
11713 case DT_FINI_ARRAY:
11714 if (do_dynamic)
11715 {
d79b3d50 11716 if (entry->d_tag == DT_USED
84714f86 11717 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11718 {
84714f86
AM
11719 const char *name
11720 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11721
b34976b6 11722 if (*name)
252b5132
RH
11723 {
11724 printf (_("Not needed object: [%s]\n"), name);
11725 break;
11726 }
11727 }
103f02d3 11728
f7a99963
NC
11729 print_vma (entry->d_un.d_val, PREFIX_HEX);
11730 putchar ('\n');
252b5132
RH
11731 }
11732 break;
11733
11734 case DT_BIND_NOW:
11735 /* The value of this entry is ignored. */
35b1837e
AM
11736 if (do_dynamic)
11737 putchar ('\n');
252b5132 11738 break;
103f02d3 11739
047b2264
JJ
11740 case DT_GNU_PRELINKED:
11741 if (do_dynamic)
11742 {
2cf0635d 11743 struct tm * tmp;
91d6fa6a 11744 time_t atime = entry->d_un.d_val;
047b2264 11745
91d6fa6a 11746 tmp = gmtime (&atime);
071436c6
NC
11747 /* PR 17533 file: 041-1244816-0.004. */
11748 if (tmp == NULL)
5a2cbcf4
L
11749 printf (_("<corrupt time val: %lx"),
11750 (unsigned long) atime);
071436c6
NC
11751 else
11752 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11753 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11754 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11755
11756 }
11757 break;
11758
fdc90cb4 11759 case DT_GNU_HASH:
978c4450 11760 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11761 if (do_dynamic)
11762 {
11763 print_vma (entry->d_un.d_val, PREFIX_HEX);
11764 putchar ('\n');
11765 }
11766 break;
11767
a5da3dee
VDM
11768 case DT_GNU_FLAGS_1:
11769 if (do_dynamic)
11770 {
11771 printf (_("Flags:"));
11772 if (entry->d_un.d_val == 0)
11773 printf (_(" None\n"));
11774 else
11775 {
11776 unsigned long int val = entry->d_un.d_val;
11777
11778 if (val & DF_GNU_1_UNIQUE)
11779 {
11780 printf (" UNIQUE");
11781 val ^= DF_GNU_1_UNIQUE;
11782 }
11783 if (val != 0)
11784 printf (" %lx", val);
11785 puts ("");
11786 }
11787 }
11788 break;
11789
252b5132
RH
11790 default:
11791 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11792 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11793 = entry->d_un.d_val;
252b5132
RH
11794
11795 if (do_dynamic)
11796 {
dda8d76d 11797 switch (filedata->file_header.e_machine)
252b5132 11798 {
37c18eed
SD
11799 case EM_AARCH64:
11800 dynamic_section_aarch64_val (entry);
11801 break;
252b5132 11802 case EM_MIPS:
4fe85591 11803 case EM_MIPS_RS3_LE:
978c4450 11804 dynamic_section_mips_val (filedata, entry);
252b5132 11805 break;
103f02d3 11806 case EM_PARISC:
b2d38a17 11807 dynamic_section_parisc_val (entry);
103f02d3 11808 break;
ecc51f48 11809 case EM_IA_64:
b2d38a17 11810 dynamic_section_ia64_val (entry);
ecc51f48 11811 break;
252b5132 11812 default:
f7a99963
NC
11813 print_vma (entry->d_un.d_val, PREFIX_HEX);
11814 putchar ('\n');
252b5132
RH
11815 }
11816 }
11817 break;
11818 }
11819 }
11820
015dc7e1 11821 return true;
252b5132
RH
11822}
11823
11824static char *
d3ba0551 11825get_ver_flags (unsigned int flags)
252b5132 11826{
6d4f21f6 11827 static char buff[128];
252b5132
RH
11828
11829 buff[0] = 0;
11830
11831 if (flags == 0)
11832 return _("none");
11833
11834 if (flags & VER_FLG_BASE)
7bb1ad17 11835 strcat (buff, "BASE");
252b5132
RH
11836
11837 if (flags & VER_FLG_WEAK)
11838 {
11839 if (flags & VER_FLG_BASE)
7bb1ad17 11840 strcat (buff, " | ");
252b5132 11841
7bb1ad17 11842 strcat (buff, "WEAK");
252b5132
RH
11843 }
11844
44ec90b9
RO
11845 if (flags & VER_FLG_INFO)
11846 {
11847 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11848 strcat (buff, " | ");
44ec90b9 11849
7bb1ad17 11850 strcat (buff, "INFO");
44ec90b9
RO
11851 }
11852
11853 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11854 {
11855 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11856 strcat (buff, " | ");
11857
11858 strcat (buff, _("<unknown>"));
11859 }
252b5132
RH
11860
11861 return buff;
11862}
11863
11864/* Display the contents of the version sections. */
98fb390a 11865
015dc7e1 11866static bool
dda8d76d 11867process_version_sections (Filedata * filedata)
252b5132 11868{
2cf0635d 11869 Elf_Internal_Shdr * section;
b34976b6 11870 unsigned i;
015dc7e1 11871 bool found = false;
252b5132
RH
11872
11873 if (! do_version)
015dc7e1 11874 return true;
252b5132 11875
dda8d76d
NC
11876 for (i = 0, section = filedata->section_headers;
11877 i < filedata->file_header.e_shnum;
b34976b6 11878 i++, section++)
252b5132
RH
11879 {
11880 switch (section->sh_type)
11881 {
11882 case SHT_GNU_verdef:
11883 {
2cf0635d 11884 Elf_External_Verdef * edefs;
452bf675
AM
11885 unsigned long idx;
11886 unsigned long cnt;
2cf0635d 11887 char * endbuf;
252b5132 11888
015dc7e1 11889 found = true;
252b5132 11890
ca0e11aa
NC
11891 if (filedata->is_separate)
11892 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11893 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11894 section->sh_info),
11895 filedata->file_name,
11896 printable_section_name (filedata, section),
11897 section->sh_info);
11898 else
11899 printf (ngettext ("\nVersion definition section '%s' "
11900 "contains %u entry:\n",
11901 "\nVersion definition section '%s' "
11902 "contains %u entries:\n",
11903 section->sh_info),
11904 printable_section_name (filedata, section),
11905 section->sh_info);
047c3dbf 11906
ae9ac79e 11907 printf (_(" Addr: 0x"));
252b5132 11908 printf_vma (section->sh_addr);
233f82cf 11909 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11910 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11911 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11912
3f5e193b 11913 edefs = (Elf_External_Verdef *)
dda8d76d 11914 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11915 _("version definition section"));
a6e9f9df
AM
11916 if (!edefs)
11917 break;
59245841 11918 endbuf = (char *) edefs + section->sh_size;
252b5132 11919
1445030f 11920 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11921 {
2cf0635d
NC
11922 char * vstart;
11923 Elf_External_Verdef * edef;
b34976b6 11924 Elf_Internal_Verdef ent;
2cf0635d 11925 Elf_External_Verdaux * eaux;
b34976b6 11926 Elf_Internal_Verdaux aux;
452bf675 11927 unsigned long isum;
b34976b6 11928 int j;
103f02d3 11929
252b5132 11930 vstart = ((char *) edefs) + idx;
54806181
AM
11931 if (vstart + sizeof (*edef) > endbuf)
11932 break;
252b5132
RH
11933
11934 edef = (Elf_External_Verdef *) vstart;
11935
11936 ent.vd_version = BYTE_GET (edef->vd_version);
11937 ent.vd_flags = BYTE_GET (edef->vd_flags);
11938 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11939 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11940 ent.vd_hash = BYTE_GET (edef->vd_hash);
11941 ent.vd_aux = BYTE_GET (edef->vd_aux);
11942 ent.vd_next = BYTE_GET (edef->vd_next);
11943
452bf675 11944 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11945 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11946
11947 printf (_(" Index: %d Cnt: %d "),
11948 ent.vd_ndx, ent.vd_cnt);
11949
452bf675 11950 /* Check for overflow. */
1445030f 11951 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11952 break;
11953
252b5132
RH
11954 vstart += ent.vd_aux;
11955
1445030f
AM
11956 if (vstart + sizeof (*eaux) > endbuf)
11957 break;
252b5132
RH
11958 eaux = (Elf_External_Verdaux *) vstart;
11959
11960 aux.vda_name = BYTE_GET (eaux->vda_name);
11961 aux.vda_next = BYTE_GET (eaux->vda_next);
11962
84714f86 11963 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 11964 printf (_("Name: %s\n"),
84714f86 11965 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
11966 else
11967 printf (_("Name index: %ld\n"), aux.vda_name);
11968
11969 isum = idx + ent.vd_aux;
11970
b34976b6 11971 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11972 {
1445030f
AM
11973 if (aux.vda_next < sizeof (*eaux)
11974 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11975 {
11976 warn (_("Invalid vda_next field of %lx\n"),
11977 aux.vda_next);
11978 j = ent.vd_cnt;
11979 break;
11980 }
dd24e3da 11981 /* Check for overflow. */
7e26601c 11982 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11983 break;
11984
252b5132
RH
11985 isum += aux.vda_next;
11986 vstart += aux.vda_next;
11987
54806181
AM
11988 if (vstart + sizeof (*eaux) > endbuf)
11989 break;
1445030f 11990 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11991
11992 aux.vda_name = BYTE_GET (eaux->vda_name);
11993 aux.vda_next = BYTE_GET (eaux->vda_next);
11994
84714f86 11995 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 11996 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 11997 isum, j,
84714f86 11998 get_dynamic_name (filedata, aux.vda_name));
252b5132 11999 else
452bf675 12000 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12001 isum, j, aux.vda_name);
12002 }
dd24e3da 12003
54806181
AM
12004 if (j < ent.vd_cnt)
12005 printf (_(" Version def aux past end of section\n"));
252b5132 12006
c9f02c3e
MR
12007 /* PR 17531:
12008 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12009 if (ent.vd_next < sizeof (*edef)
12010 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12011 {
12012 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12013 cnt = section->sh_info;
12014 break;
12015 }
452bf675 12016 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12017 break;
12018
252b5132
RH
12019 idx += ent.vd_next;
12020 }
dd24e3da 12021
54806181
AM
12022 if (cnt < section->sh_info)
12023 printf (_(" Version definition past end of section\n"));
252b5132
RH
12024
12025 free (edefs);
12026 }
12027 break;
103f02d3 12028
252b5132
RH
12029 case SHT_GNU_verneed:
12030 {
2cf0635d 12031 Elf_External_Verneed * eneed;
452bf675
AM
12032 unsigned long idx;
12033 unsigned long cnt;
2cf0635d 12034 char * endbuf;
252b5132 12035
015dc7e1 12036 found = true;
252b5132 12037
ca0e11aa
NC
12038 if (filedata->is_separate)
12039 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12040 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12041 section->sh_info),
12042 filedata->file_name,
12043 printable_section_name (filedata, section),
12044 section->sh_info);
12045 else
12046 printf (ngettext ("\nVersion needs section '%s' "
12047 "contains %u entry:\n",
12048 "\nVersion needs section '%s' "
12049 "contains %u entries:\n",
12050 section->sh_info),
12051 printable_section_name (filedata, section),
12052 section->sh_info);
047c3dbf 12053
252b5132
RH
12054 printf (_(" Addr: 0x"));
12055 printf_vma (section->sh_addr);
72de5009 12056 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12057 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12058 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12059
dda8d76d 12060 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12061 section->sh_offset, 1,
12062 section->sh_size,
9cf03b7e 12063 _("Version Needs section"));
a6e9f9df
AM
12064 if (!eneed)
12065 break;
59245841 12066 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12067
12068 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12069 {
2cf0635d 12070 Elf_External_Verneed * entry;
b34976b6 12071 Elf_Internal_Verneed ent;
452bf675 12072 unsigned long isum;
b34976b6 12073 int j;
2cf0635d 12074 char * vstart;
252b5132
RH
12075
12076 vstart = ((char *) eneed) + idx;
54806181
AM
12077 if (vstart + sizeof (*entry) > endbuf)
12078 break;
252b5132
RH
12079
12080 entry = (Elf_External_Verneed *) vstart;
12081
12082 ent.vn_version = BYTE_GET (entry->vn_version);
12083 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12084 ent.vn_file = BYTE_GET (entry->vn_file);
12085 ent.vn_aux = BYTE_GET (entry->vn_aux);
12086 ent.vn_next = BYTE_GET (entry->vn_next);
12087
452bf675 12088 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12089
84714f86 12090 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12091 printf (_(" File: %s"),
84714f86 12092 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12093 else
12094 printf (_(" File: %lx"), ent.vn_file);
12095
12096 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12097
dd24e3da 12098 /* Check for overflow. */
7e26601c 12099 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12100 break;
252b5132
RH
12101 vstart += ent.vn_aux;
12102
12103 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12104 {
2cf0635d 12105 Elf_External_Vernaux * eaux;
b34976b6 12106 Elf_Internal_Vernaux aux;
252b5132 12107
54806181
AM
12108 if (vstart + sizeof (*eaux) > endbuf)
12109 break;
252b5132
RH
12110 eaux = (Elf_External_Vernaux *) vstart;
12111
12112 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12113 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12114 aux.vna_other = BYTE_GET (eaux->vna_other);
12115 aux.vna_name = BYTE_GET (eaux->vna_name);
12116 aux.vna_next = BYTE_GET (eaux->vna_next);
12117
84714f86 12118 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12119 printf (_(" %#06lx: Name: %s"),
84714f86 12120 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12121 else
452bf675 12122 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12123 isum, aux.vna_name);
12124
12125 printf (_(" Flags: %s Version: %d\n"),
12126 get_ver_flags (aux.vna_flags), aux.vna_other);
12127
1445030f
AM
12128 if (aux.vna_next < sizeof (*eaux)
12129 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12130 {
12131 warn (_("Invalid vna_next field of %lx\n"),
12132 aux.vna_next);
12133 j = ent.vn_cnt;
12134 break;
12135 }
1445030f
AM
12136 /* Check for overflow. */
12137 if (aux.vna_next > (size_t) (endbuf - vstart))
12138 break;
252b5132
RH
12139 isum += aux.vna_next;
12140 vstart += aux.vna_next;
12141 }
9cf03b7e 12142
54806181 12143 if (j < ent.vn_cnt)
f9a6a8f0 12144 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12145
1445030f
AM
12146 if (ent.vn_next < sizeof (*entry)
12147 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12148 {
452bf675 12149 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12150 cnt = section->sh_info;
12151 break;
12152 }
1445030f
AM
12153 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12154 break;
252b5132
RH
12155 idx += ent.vn_next;
12156 }
9cf03b7e 12157
54806181 12158 if (cnt < section->sh_info)
9cf03b7e 12159 warn (_("Missing Version Needs information\n"));
103f02d3 12160
252b5132
RH
12161 free (eneed);
12162 }
12163 break;
12164
12165 case SHT_GNU_versym:
12166 {
2cf0635d 12167 Elf_Internal_Shdr * link_section;
8b73c356
NC
12168 size_t total;
12169 unsigned int cnt;
2cf0635d
NC
12170 unsigned char * edata;
12171 unsigned short * data;
12172 char * strtab;
12173 Elf_Internal_Sym * symbols;
12174 Elf_Internal_Shdr * string_sec;
ba5cdace 12175 unsigned long num_syms;
d3ba0551 12176 long off;
252b5132 12177
dda8d76d 12178 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12179 break;
12180
dda8d76d 12181 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12182 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12183
dda8d76d 12184 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12185 break;
12186
015dc7e1 12187 found = true;
252b5132 12188
4de91c10 12189 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12190 if (symbols == NULL)
12191 break;
252b5132 12192
dda8d76d 12193 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12194
dda8d76d 12195 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12196 string_sec->sh_size,
12197 _("version string table"));
a6e9f9df 12198 if (!strtab)
0429c154
MS
12199 {
12200 free (symbols);
12201 break;
12202 }
252b5132 12203
ca0e11aa
NC
12204 if (filedata->is_separate)
12205 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12206 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12207 total),
12208 filedata->file_name,
12209 printable_section_name (filedata, section),
12210 (unsigned long) total);
12211 else
12212 printf (ngettext ("\nVersion symbols section '%s' "
12213 "contains %lu entry:\n",
12214 "\nVersion symbols section '%s' "
12215 "contains %lu entries:\n",
12216 total),
12217 printable_section_name (filedata, section),
12218 (unsigned long) total);
252b5132 12219
ae9ac79e 12220 printf (_(" Addr: 0x"));
252b5132 12221 printf_vma (section->sh_addr);
72de5009 12222 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12223 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12224 printable_section_name (filedata, link_section));
252b5132 12225
dda8d76d 12226 off = offset_from_vma (filedata,
978c4450 12227 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12228 total * sizeof (short));
95099889
AM
12229 edata = (unsigned char *) get_data (NULL, filedata, off,
12230 sizeof (short), total,
12231 _("version symbol data"));
a6e9f9df
AM
12232 if (!edata)
12233 {
12234 free (strtab);
0429c154 12235 free (symbols);
a6e9f9df
AM
12236 break;
12237 }
252b5132 12238
3f5e193b 12239 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12240
12241 for (cnt = total; cnt --;)
b34976b6
AM
12242 data[cnt] = byte_get (edata + cnt * sizeof (short),
12243 sizeof (short));
252b5132
RH
12244
12245 free (edata);
12246
12247 for (cnt = 0; cnt < total; cnt += 4)
12248 {
12249 int j, nn;
ab273396
AM
12250 char *name;
12251 char *invalid = _("*invalid*");
252b5132
RH
12252
12253 printf (" %03x:", cnt);
12254
12255 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12256 switch (data[cnt + j])
252b5132
RH
12257 {
12258 case 0:
12259 fputs (_(" 0 (*local*) "), stdout);
12260 break;
12261
12262 case 1:
12263 fputs (_(" 1 (*global*) "), stdout);
12264 break;
12265
12266 default:
c244d050
NC
12267 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12268 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12269
dd24e3da 12270 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12271 array, break to avoid an out-of-bounds read. */
12272 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12273 {
12274 warn (_("invalid index into symbol array\n"));
12275 break;
12276 }
12277
ab273396 12278 name = NULL;
978c4450 12279 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12280 {
b34976b6
AM
12281 Elf_Internal_Verneed ivn;
12282 unsigned long offset;
252b5132 12283
d93f0186 12284 offset = offset_from_vma
978c4450
AM
12285 (filedata,
12286 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12287 sizeof (Elf_External_Verneed));
252b5132 12288
b34976b6 12289 do
252b5132 12290 {
b34976b6
AM
12291 Elf_Internal_Vernaux ivna;
12292 Elf_External_Verneed evn;
12293 Elf_External_Vernaux evna;
12294 unsigned long a_off;
252b5132 12295
dda8d76d 12296 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12297 _("version need")) == NULL)
12298 break;
0b4362b0 12299
252b5132
RH
12300 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12301 ivn.vn_next = BYTE_GET (evn.vn_next);
12302
12303 a_off = offset + ivn.vn_aux;
12304
12305 do
12306 {
dda8d76d 12307 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12308 1, _("version need aux (2)")) == NULL)
12309 {
12310 ivna.vna_next = 0;
12311 ivna.vna_other = 0;
12312 }
12313 else
12314 {
12315 ivna.vna_next = BYTE_GET (evna.vna_next);
12316 ivna.vna_other = BYTE_GET (evna.vna_other);
12317 }
252b5132
RH
12318
12319 a_off += ivna.vna_next;
12320 }
b34976b6 12321 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12322 && ivna.vna_next != 0);
12323
b34976b6 12324 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12325 {
12326 ivna.vna_name = BYTE_GET (evna.vna_name);
12327
54806181 12328 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12329 name = invalid;
54806181
AM
12330 else
12331 name = strtab + ivna.vna_name;
252b5132
RH
12332 break;
12333 }
12334
12335 offset += ivn.vn_next;
12336 }
12337 while (ivn.vn_next);
12338 }
00d93f34 12339
ab273396 12340 if (data[cnt + j] != 0x8001
978c4450 12341 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12342 {
b34976b6
AM
12343 Elf_Internal_Verdef ivd;
12344 Elf_External_Verdef evd;
12345 unsigned long offset;
252b5132 12346
d93f0186 12347 offset = offset_from_vma
978c4450
AM
12348 (filedata,
12349 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12350 sizeof evd);
252b5132
RH
12351
12352 do
12353 {
dda8d76d 12354 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12355 _("version def")) == NULL)
12356 {
12357 ivd.vd_next = 0;
948f632f 12358 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12359 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12360 break;
59245841
NC
12361 }
12362 else
12363 {
12364 ivd.vd_next = BYTE_GET (evd.vd_next);
12365 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12366 }
252b5132
RH
12367
12368 offset += ivd.vd_next;
12369 }
c244d050 12370 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12371 && ivd.vd_next != 0);
12372
c244d050 12373 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12374 {
b34976b6
AM
12375 Elf_External_Verdaux evda;
12376 Elf_Internal_Verdaux ivda;
252b5132
RH
12377
12378 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12379
dda8d76d 12380 if (get_data (&evda, filedata,
59245841
NC
12381 offset - ivd.vd_next + ivd.vd_aux,
12382 sizeof (evda), 1,
12383 _("version def aux")) == NULL)
12384 break;
252b5132
RH
12385
12386 ivda.vda_name = BYTE_GET (evda.vda_name);
12387
54806181 12388 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12389 name = invalid;
12390 else if (name != NULL && name != invalid)
12391 name = _("*both*");
54806181
AM
12392 else
12393 name = strtab + ivda.vda_name;
252b5132
RH
12394 }
12395 }
ab273396
AM
12396 if (name != NULL)
12397 nn += printf ("(%s%-*s",
12398 name,
12399 12 - (int) strlen (name),
12400 ")");
252b5132
RH
12401
12402 if (nn < 18)
12403 printf ("%*c", 18 - nn, ' ');
12404 }
12405
12406 putchar ('\n');
12407 }
12408
12409 free (data);
12410 free (strtab);
12411 free (symbols);
12412 }
12413 break;
103f02d3 12414
252b5132
RH
12415 default:
12416 break;
12417 }
12418 }
12419
12420 if (! found)
ca0e11aa
NC
12421 {
12422 if (filedata->is_separate)
12423 printf (_("\nNo version information found in linked file '%s'.\n"),
12424 filedata->file_name);
12425 else
12426 printf (_("\nNo version information found in this file.\n"));
12427 }
252b5132 12428
015dc7e1 12429 return true;
252b5132
RH
12430}
12431
d1133906 12432static const char *
dda8d76d 12433get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12434{
89246a0e 12435 static char buff[64];
252b5132
RH
12436
12437 switch (binding)
12438 {
b34976b6
AM
12439 case STB_LOCAL: return "LOCAL";
12440 case STB_GLOBAL: return "GLOBAL";
12441 case STB_WEAK: return "WEAK";
252b5132
RH
12442 default:
12443 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12444 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12445 binding);
252b5132 12446 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12447 {
12448 if (binding == STB_GNU_UNIQUE
df3a023b 12449 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12450 return "UNIQUE";
12451 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12452 }
252b5132 12453 else
e9e44622 12454 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12455 return buff;
12456 }
12457}
12458
d1133906 12459static const char *
dda8d76d 12460get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12461{
89246a0e 12462 static char buff[64];
252b5132
RH
12463
12464 switch (type)
12465 {
b34976b6
AM
12466 case STT_NOTYPE: return "NOTYPE";
12467 case STT_OBJECT: return "OBJECT";
12468 case STT_FUNC: return "FUNC";
12469 case STT_SECTION: return "SECTION";
12470 case STT_FILE: return "FILE";
12471 case STT_COMMON: return "COMMON";
12472 case STT_TLS: return "TLS";
15ab5209
DB
12473 case STT_RELC: return "RELC";
12474 case STT_SRELC: return "SRELC";
252b5132
RH
12475 default:
12476 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12477 {
dda8d76d 12478 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12479 return "THUMB_FUNC";
103f02d3 12480
dda8d76d 12481 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12482 return "REGISTER";
12483
dda8d76d 12484 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12485 return "PARISC_MILLI";
12486
e9e44622 12487 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12488 }
252b5132 12489 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12490 {
dda8d76d 12491 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12492 {
12493 if (type == STT_HP_OPAQUE)
12494 return "HP_OPAQUE";
12495 if (type == STT_HP_STUB)
12496 return "HP_STUB";
12497 }
12498
d8045f23 12499 if (type == STT_GNU_IFUNC
dda8d76d 12500 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12501 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12502 return "IFUNC";
12503
e9e44622 12504 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12505 }
252b5132 12506 else
e9e44622 12507 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12508 return buff;
12509 }
12510}
12511
d1133906 12512static const char *
d3ba0551 12513get_symbol_visibility (unsigned int visibility)
d1133906
NC
12514{
12515 switch (visibility)
12516 {
b34976b6
AM
12517 case STV_DEFAULT: return "DEFAULT";
12518 case STV_INTERNAL: return "INTERNAL";
12519 case STV_HIDDEN: return "HIDDEN";
d1133906 12520 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12521 default:
27a45f42 12522 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12523 return _("<unknown>");
d1133906
NC
12524 }
12525}
12526
2057d69d
CZ
12527static const char *
12528get_alpha_symbol_other (unsigned int other)
9abca702 12529{
2057d69d
CZ
12530 switch (other)
12531 {
12532 case STO_ALPHA_NOPV: return "NOPV";
12533 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12534 default:
27a45f42 12535 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12536 return _("<unknown>");
9abca702 12537 }
2057d69d
CZ
12538}
12539
fd85a6a1
NC
12540static const char *
12541get_solaris_symbol_visibility (unsigned int visibility)
12542{
12543 switch (visibility)
12544 {
12545 case 4: return "EXPORTED";
12546 case 5: return "SINGLETON";
12547 case 6: return "ELIMINATE";
12548 default: return get_symbol_visibility (visibility);
12549 }
12550}
12551
2301ed1c
SN
12552static const char *
12553get_aarch64_symbol_other (unsigned int other)
12554{
12555 static char buf[32];
12556
12557 if (other & STO_AARCH64_VARIANT_PCS)
12558 {
12559 other &= ~STO_AARCH64_VARIANT_PCS;
12560 if (other == 0)
12561 return "VARIANT_PCS";
12562 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12563 return buf;
12564 }
12565 return NULL;
12566}
12567
5e2b0d47
NC
12568static const char *
12569get_mips_symbol_other (unsigned int other)
12570{
12571 switch (other)
12572 {
32ec8896
NC
12573 case STO_OPTIONAL: return "OPTIONAL";
12574 case STO_MIPS_PLT: return "MIPS PLT";
12575 case STO_MIPS_PIC: return "MIPS PIC";
12576 case STO_MICROMIPS: return "MICROMIPS";
12577 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12578 case STO_MIPS16: return "MIPS16";
12579 default: return NULL;
5e2b0d47
NC
12580 }
12581}
12582
28f997cf 12583static const char *
dda8d76d 12584get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12585{
dda8d76d 12586 if (is_ia64_vms (filedata))
28f997cf
TG
12587 {
12588 static char res[32];
12589
12590 res[0] = 0;
12591
12592 /* Function types is for images and .STB files only. */
dda8d76d 12593 switch (filedata->file_header.e_type)
28f997cf
TG
12594 {
12595 case ET_DYN:
12596 case ET_EXEC:
12597 switch (VMS_ST_FUNC_TYPE (other))
12598 {
12599 case VMS_SFT_CODE_ADDR:
12600 strcat (res, " CA");
12601 break;
12602 case VMS_SFT_SYMV_IDX:
12603 strcat (res, " VEC");
12604 break;
12605 case VMS_SFT_FD:
12606 strcat (res, " FD");
12607 break;
12608 case VMS_SFT_RESERVE:
12609 strcat (res, " RSV");
12610 break;
12611 default:
bee0ee85
NC
12612 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12613 VMS_ST_FUNC_TYPE (other));
12614 strcat (res, " <unknown>");
12615 break;
28f997cf
TG
12616 }
12617 break;
12618 default:
12619 break;
12620 }
12621 switch (VMS_ST_LINKAGE (other))
12622 {
12623 case VMS_STL_IGNORE:
12624 strcat (res, " IGN");
12625 break;
12626 case VMS_STL_RESERVE:
12627 strcat (res, " RSV");
12628 break;
12629 case VMS_STL_STD:
12630 strcat (res, " STD");
12631 break;
12632 case VMS_STL_LNK:
12633 strcat (res, " LNK");
12634 break;
12635 default:
bee0ee85
NC
12636 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12637 VMS_ST_LINKAGE (other));
12638 strcat (res, " <unknown>");
12639 break;
28f997cf
TG
12640 }
12641
12642 if (res[0] != 0)
12643 return res + 1;
12644 else
12645 return res;
12646 }
12647 return NULL;
12648}
12649
6911b7dc
AM
12650static const char *
12651get_ppc64_symbol_other (unsigned int other)
12652{
14732552
AM
12653 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12654 return NULL;
12655
12656 other >>= STO_PPC64_LOCAL_BIT;
12657 if (other <= 6)
6911b7dc 12658 {
89246a0e 12659 static char buf[64];
14732552
AM
12660 if (other >= 2)
12661 other = ppc64_decode_local_entry (other);
12662 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12663 return buf;
12664 }
12665 return NULL;
12666}
12667
8155b853
NC
12668static const char *
12669get_riscv_symbol_other (unsigned int other)
12670{
12671 static char buf[32];
12672 buf[0] = 0;
12673
12674 if (other & STO_RISCV_VARIANT_CC)
12675 {
12676 strcat (buf, _(" VARIANT_CC"));
12677 other &= ~STO_RISCV_VARIANT_CC;
12678 }
12679
12680 if (other != 0)
12681 snprintf (buf, sizeof buf, " %x", other);
12682
12683
12684 if (buf[0] != 0)
12685 return buf + 1;
12686 else
12687 return buf;
12688}
12689
5e2b0d47 12690static const char *
dda8d76d 12691get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12692{
12693 const char * result = NULL;
89246a0e 12694 static char buff [64];
5e2b0d47
NC
12695
12696 if (other == 0)
12697 return "";
12698
dda8d76d 12699 switch (filedata->file_header.e_machine)
5e2b0d47 12700 {
2057d69d
CZ
12701 case EM_ALPHA:
12702 result = get_alpha_symbol_other (other);
12703 break;
2301ed1c
SN
12704 case EM_AARCH64:
12705 result = get_aarch64_symbol_other (other);
12706 break;
5e2b0d47
NC
12707 case EM_MIPS:
12708 result = get_mips_symbol_other (other);
28f997cf
TG
12709 break;
12710 case EM_IA_64:
dda8d76d 12711 result = get_ia64_symbol_other (filedata, other);
28f997cf 12712 break;
6911b7dc
AM
12713 case EM_PPC64:
12714 result = get_ppc64_symbol_other (other);
12715 break;
8155b853
NC
12716 case EM_RISCV:
12717 result = get_riscv_symbol_other (other);
12718 break;
5e2b0d47 12719 default:
fd85a6a1 12720 result = NULL;
5e2b0d47
NC
12721 break;
12722 }
12723
12724 if (result)
12725 return result;
12726
12727 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12728 return buff;
12729}
12730
d1133906 12731static const char *
dda8d76d 12732get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12733{
b34976b6 12734 static char buff[32];
5cf1065c 12735
252b5132
RH
12736 switch (type)
12737 {
b34976b6
AM
12738 case SHN_UNDEF: return "UND";
12739 case SHN_ABS: return "ABS";
12740 case SHN_COMMON: return "COM";
252b5132 12741 default:
9ce701e2 12742 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12743 && filedata->file_header.e_machine == EM_IA_64
12744 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12745 return "ANSI_COM";
12746 else if ((filedata->file_header.e_machine == EM_X86_64
12747 || filedata->file_header.e_machine == EM_L1OM
12748 || filedata->file_header.e_machine == EM_K1OM)
12749 && type == SHN_X86_64_LCOMMON)
12750 return "LARGE_COM";
12751 else if ((type == SHN_MIPS_SCOMMON
12752 && filedata->file_header.e_machine == EM_MIPS)
12753 || (type == SHN_TIC6X_SCOMMON
12754 && filedata->file_header.e_machine == EM_TI_C6000))
12755 return "SCOM";
12756 else if (type == SHN_MIPS_SUNDEFINED
12757 && filedata->file_header.e_machine == EM_MIPS)
12758 return "SUND";
12759 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12760 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12761 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12762 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12763 else if (type >= SHN_LORESERVE)
12764 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12765 else if (filedata->file_header.e_shnum != 0
12766 && type >= filedata->file_header.e_shnum)
12767 sprintf (buff, _("bad section index[%3d]"), type);
12768 else
12769 sprintf (buff, "%3d", type);
12770 break;
fd85a6a1
NC
12771 }
12772
10ca4b04 12773 return buff;
6bd1a22c
L
12774}
12775
bb4d2ac2 12776static const char *
dda8d76d 12777get_symbol_version_string (Filedata * filedata,
015dc7e1 12778 bool is_dynsym,
1449284b
NC
12779 const char * strtab,
12780 unsigned long int strtab_size,
12781 unsigned int si,
12782 Elf_Internal_Sym * psym,
12783 enum versioned_symbol_info * sym_info,
12784 unsigned short * vna_other)
bb4d2ac2 12785{
ab273396
AM
12786 unsigned char data[2];
12787 unsigned short vers_data;
12788 unsigned long offset;
7a815dd5 12789 unsigned short max_vd_ndx;
bb4d2ac2 12790
ab273396 12791 if (!is_dynsym
978c4450 12792 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12793 return NULL;
bb4d2ac2 12794
978c4450
AM
12795 offset = offset_from_vma (filedata,
12796 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12797 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12798
dda8d76d 12799 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12800 sizeof (data), 1, _("version data")) == NULL)
12801 return NULL;
12802
12803 vers_data = byte_get (data, 2);
bb4d2ac2 12804
1f6f5dba 12805 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12806 return NULL;
bb4d2ac2 12807
0b8b7609 12808 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12809 max_vd_ndx = 0;
12810
ab273396
AM
12811 /* Usually we'd only see verdef for defined symbols, and verneed for
12812 undefined symbols. However, symbols defined by the linker in
12813 .dynbss for variables copied from a shared library in order to
12814 avoid text relocations are defined yet have verneed. We could
12815 use a heuristic to detect the special case, for example, check
12816 for verneed first on symbols defined in SHT_NOBITS sections, but
12817 it is simpler and more reliable to just look for both verdef and
12818 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12819
ab273396
AM
12820 if (psym->st_shndx != SHN_UNDEF
12821 && vers_data != 0x8001
978c4450 12822 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12823 {
12824 Elf_Internal_Verdef ivd;
12825 Elf_Internal_Verdaux ivda;
12826 Elf_External_Verdaux evda;
12827 unsigned long off;
bb4d2ac2 12828
dda8d76d 12829 off = offset_from_vma (filedata,
978c4450 12830 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12831 sizeof (Elf_External_Verdef));
12832
12833 do
bb4d2ac2 12834 {
ab273396
AM
12835 Elf_External_Verdef evd;
12836
dda8d76d 12837 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12838 _("version def")) == NULL)
12839 {
12840 ivd.vd_ndx = 0;
12841 ivd.vd_aux = 0;
12842 ivd.vd_next = 0;
1f6f5dba 12843 ivd.vd_flags = 0;
ab273396
AM
12844 }
12845 else
bb4d2ac2 12846 {
ab273396
AM
12847 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12848 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12849 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12850 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12851 }
bb4d2ac2 12852
7a815dd5
L
12853 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12854 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12855
ab273396
AM
12856 off += ivd.vd_next;
12857 }
12858 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12859
ab273396
AM
12860 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12861 {
9abca702 12862 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12863 return NULL;
12864
ab273396
AM
12865 off -= ivd.vd_next;
12866 off += ivd.vd_aux;
bb4d2ac2 12867
dda8d76d 12868 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12869 _("version def aux")) != NULL)
12870 {
12871 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12872
ab273396 12873 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12874 return (ivda.vda_name < strtab_size
12875 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12876 }
12877 }
12878 }
bb4d2ac2 12879
978c4450 12880 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12881 {
12882 Elf_External_Verneed evn;
12883 Elf_Internal_Verneed ivn;
12884 Elf_Internal_Vernaux ivna;
bb4d2ac2 12885
dda8d76d 12886 offset = offset_from_vma (filedata,
978c4450 12887 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12888 sizeof evn);
12889 do
12890 {
12891 unsigned long vna_off;
bb4d2ac2 12892
dda8d76d 12893 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12894 _("version need")) == NULL)
12895 {
12896 ivna.vna_next = 0;
12897 ivna.vna_other = 0;
12898 ivna.vna_name = 0;
12899 break;
12900 }
bb4d2ac2 12901
ab273396
AM
12902 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12903 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12904
ab273396 12905 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12906
ab273396
AM
12907 do
12908 {
12909 Elf_External_Vernaux evna;
bb4d2ac2 12910
dda8d76d 12911 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12912 _("version need aux (3)")) == NULL)
bb4d2ac2 12913 {
ab273396
AM
12914 ivna.vna_next = 0;
12915 ivna.vna_other = 0;
12916 ivna.vna_name = 0;
bb4d2ac2 12917 }
bb4d2ac2 12918 else
bb4d2ac2 12919 {
ab273396
AM
12920 ivna.vna_other = BYTE_GET (evna.vna_other);
12921 ivna.vna_next = BYTE_GET (evna.vna_next);
12922 ivna.vna_name = BYTE_GET (evna.vna_name);
12923 }
bb4d2ac2 12924
ab273396
AM
12925 vna_off += ivna.vna_next;
12926 }
12927 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12928
ab273396
AM
12929 if (ivna.vna_other == vers_data)
12930 break;
bb4d2ac2 12931
ab273396
AM
12932 offset += ivn.vn_next;
12933 }
12934 while (ivn.vn_next != 0);
bb4d2ac2 12935
ab273396
AM
12936 if (ivna.vna_other == vers_data)
12937 {
12938 *sym_info = symbol_undefined;
12939 *vna_other = ivna.vna_other;
12940 return (ivna.vna_name < strtab_size
12941 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12942 }
7a815dd5
L
12943 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12944 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12945 return _("<corrupt>");
bb4d2ac2 12946 }
ab273396 12947 return NULL;
bb4d2ac2
L
12948}
12949
047c3dbf
NL
12950/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12951
12952static unsigned int
12953print_dynamic_symbol_size (bfd_vma vma, int base)
12954{
12955 switch (base)
12956 {
12957 case 8:
12958 return print_vma (vma, OCTAL_5);
12959
12960 case 10:
12961 return print_vma (vma, UNSIGNED_5);
12962
12963 case 16:
12964 return print_vma (vma, PREFIX_HEX_5);
12965
12966 case 0:
12967 default:
12968 return print_vma (vma, DEC_5);
12969 }
12970}
12971
10ca4b04
L
12972static void
12973print_dynamic_symbol (Filedata *filedata, unsigned long si,
12974 Elf_Internal_Sym *symtab,
12975 Elf_Internal_Shdr *section,
12976 char *strtab, size_t strtab_size)
252b5132 12977{
10ca4b04
L
12978 const char *version_string;
12979 enum versioned_symbol_info sym_info;
12980 unsigned short vna_other;
23356397
NC
12981 bool is_valid;
12982 const char * sstr;
10ca4b04 12983 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12984
10ca4b04
L
12985 printf ("%6ld: ", si);
12986 print_vma (psym->st_value, LONG_HEX);
12987 putchar (' ');
047c3dbf 12988 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12989 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12990 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12991 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12992 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12993 else
252b5132 12994 {
10ca4b04 12995 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12996
10ca4b04
L
12997 printf (" %-7s", get_symbol_visibility (vis));
12998 /* Check to see if any other bits in the st_other field are set.
12999 Note - displaying this information disrupts the layout of the
13000 table being generated, but for the moment this case is very rare. */
13001 if (psym->st_other ^ vis)
13002 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13003 }
10ca4b04 13004 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13005
23356397
NC
13006 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13007 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13008 && filedata->section_headers != NULL
23356397
NC
13009 && psym->st_name == 0)
13010 {
84714f86
AM
13011 is_valid
13012 = section_name_valid (filedata,
13013 filedata->section_headers + psym->st_shndx);
23356397 13014 sstr = is_valid ?
84714f86
AM
13015 section_name_print (filedata,
13016 filedata->section_headers + psym->st_shndx)
23356397
NC
13017 : _("<corrupt>");
13018 }
13019 else
13020 {
84714f86 13021 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13022 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13023 }
10ca4b04
L
13024
13025 version_string
13026 = get_symbol_version_string (filedata,
13027 (section == NULL
13028 || section->sh_type == SHT_DYNSYM),
13029 strtab, strtab_size, si,
13030 psym, &sym_info, &vna_other);
b9e920ec 13031
0942c7ab
NC
13032 int len_avail = 21;
13033 if (! do_wide && version_string != NULL)
13034 {
ddb43bab 13035 char buffer[16];
0942c7ab 13036
ddb43bab 13037 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13038
13039 if (sym_info == symbol_undefined)
13040 len_avail -= sprintf (buffer," (%d)", vna_other);
13041 else if (sym_info != symbol_hidden)
13042 len_avail -= 1;
13043 }
13044
13045 print_symbol (len_avail, sstr);
b9e920ec 13046
10ca4b04
L
13047 if (version_string)
13048 {
13049 if (sym_info == symbol_undefined)
13050 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13051 else
10ca4b04
L
13052 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13053 version_string);
13054 }
6bd1a22c 13055
10ca4b04 13056 putchar ('\n');
6bd1a22c 13057
10ca4b04
L
13058 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13059 && section != NULL
13060 && si >= section->sh_info
13061 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13062 && filedata->file_header.e_machine != EM_MIPS
13063 /* Solaris binaries have been found to violate this requirement as
13064 well. Not sure if this is a bug or an ABI requirement. */
13065 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13066 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13067 si, printable_section_name (filedata, section), section->sh_info);
13068}
f16a9783 13069
0f03783c
NC
13070static const char *
13071get_lto_kind (unsigned int kind)
13072{
13073 switch (kind)
13074 {
13075 case 0: return "DEF";
13076 case 1: return "WEAKDEF";
13077 case 2: return "UNDEF";
13078 case 3: return "WEAKUNDEF";
13079 case 4: return "COMMON";
13080 default:
13081 break;
13082 }
13083
13084 static char buffer[30];
13085 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13086 sprintf (buffer, "<unknown: %u>", kind);
13087 return buffer;
13088}
13089
13090static const char *
13091get_lto_visibility (unsigned int visibility)
13092{
13093 switch (visibility)
13094 {
13095 case 0: return "DEFAULT";
13096 case 1: return "PROTECTED";
13097 case 2: return "INTERNAL";
13098 case 3: return "HIDDEN";
13099 default:
13100 break;
13101 }
13102
13103 static char buffer[30];
13104 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13105 sprintf (buffer, "<unknown: %u>", visibility);
13106 return buffer;
13107}
13108
13109static const char *
13110get_lto_sym_type (unsigned int sym_type)
13111{
13112 switch (sym_type)
13113 {
13114 case 0: return "UNKNOWN";
13115 case 1: return "FUNCTION";
13116 case 2: return "VARIABLE";
13117 default:
13118 break;
13119 }
13120
13121 static char buffer[30];
13122 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13123 sprintf (buffer, "<unknown: %u>", sym_type);
13124 return buffer;
13125}
13126
13127/* Display an LTO format symbol table.
13128 FIXME: The format of LTO symbol tables is not formalized.
13129 So this code could need changing in the future. */
13130
015dc7e1 13131static bool
0f03783c
NC
13132display_lto_symtab (Filedata * filedata,
13133 Elf_Internal_Shdr * section)
13134{
13135 if (section->sh_size == 0)
13136 {
ca0e11aa
NC
13137 if (filedata->is_separate)
13138 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13139 printable_section_name (filedata, section),
13140 filedata->file_name);
13141 else
13142 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13143 printable_section_name (filedata, section));
047c3dbf 13144
015dc7e1 13145 return true;
0f03783c
NC
13146 }
13147
13148 if (section->sh_size > filedata->file_size)
13149 {
13150 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13151 printable_section_name (filedata, section),
13152 (unsigned long) section->sh_size);
015dc7e1 13153 return false;
0f03783c
NC
13154 }
13155
13156 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13157 section->sh_size, 1, _("LTO symbols"));
13158 if (alloced_data == NULL)
015dc7e1 13159 return false;
0f03783c
NC
13160
13161 /* Look for extended data for the symbol table. */
13162 Elf_Internal_Shdr * ext;
13163 void * ext_data_orig = NULL;
13164 char * ext_data = NULL;
13165 char * ext_data_end = NULL;
13166 char * ext_name = NULL;
13167
13168 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13169 (section_name (filedata, section)
13170 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13171 && ext_name != NULL /* Paranoia. */
13172 && (ext = find_section (filedata, ext_name)) != NULL)
13173 {
13174 if (ext->sh_size < 3)
13175 error (_("LTO Symbol extension table '%s' is empty!\n"),
13176 printable_section_name (filedata, ext));
13177 else
13178 {
13179 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13180 ext->sh_size, 1,
13181 _("LTO ext symbol data"));
13182 if (ext_data != NULL)
13183 {
13184 ext_data_end = ext_data + ext->sh_size;
13185 if (* ext_data++ != 1)
13186 error (_("Unexpected version number in symbol extension table\n"));
13187 }
13188 }
13189 }
b9e920ec 13190
0f03783c
NC
13191 const unsigned char * data = (const unsigned char *) alloced_data;
13192 const unsigned char * end = data + section->sh_size;
13193
ca0e11aa
NC
13194 if (filedata->is_separate)
13195 printf (_("\nIn linked file '%s': "), filedata->file_name);
13196 else
13197 printf ("\n");
13198
0f03783c
NC
13199 if (ext_data_orig != NULL)
13200 {
13201 if (do_wide)
ca0e11aa 13202 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13203 printable_section_name (filedata, section),
13204 printable_section_name (filedata, ext));
13205 else
13206 {
ca0e11aa 13207 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13208 printable_section_name (filedata, section));
13209 printf (_(" and extension table '%s' contain:\n"),
13210 printable_section_name (filedata, ext));
13211 }
13212 }
13213 else
ca0e11aa 13214 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13215 printable_section_name (filedata, section));
b9e920ec 13216
0f03783c 13217 /* FIXME: Add a wide version. */
b9e920ec 13218 if (ext_data_orig != NULL)
0f03783c
NC
13219 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13220 else
13221 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13222
13223 /* FIXME: We do not handle style prefixes. */
13224
13225 while (data < end)
13226 {
13227 const unsigned char * sym_name = data;
13228 data += strnlen ((const char *) sym_name, end - data) + 1;
13229 if (data >= end)
13230 goto fail;
13231
13232 const unsigned char * comdat_key = data;
13233 data += strnlen ((const char *) comdat_key, end - data) + 1;
13234 if (data >= end)
13235 goto fail;
13236
13237 if (data + 2 + 8 + 4 > end)
13238 goto fail;
13239
13240 unsigned int kind = *data++;
13241 unsigned int visibility = *data++;
13242
13243 elf_vma size = byte_get (data, 8);
13244 data += 8;
13245
13246 elf_vma slot = byte_get (data, 4);
13247 data += 4;
13248
13249 if (ext_data != NULL)
13250 {
13251 if (ext_data < (ext_data_end - 1))
13252 {
13253 unsigned int sym_type = * ext_data ++;
13254 unsigned int sec_kind = * ext_data ++;
13255
13256 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13257 * comdat_key == 0 ? "-" : (char *) comdat_key,
13258 get_lto_kind (kind),
13259 get_lto_visibility (visibility),
13260 (long) size,
13261 (long) slot,
13262 get_lto_sym_type (sym_type),
13263 (long) sec_kind);
13264 print_symbol (6, (const char *) sym_name);
13265 }
13266 else
13267 {
13268 error (_("Ran out of LTO symbol extension data\n"));
13269 ext_data = NULL;
13270 /* FIXME: return FAIL result ? */
13271 }
13272 }
13273 else
13274 {
13275 printf (" %10s %10s %11s %08lx %08lx _",
13276 * comdat_key == 0 ? "-" : (char *) comdat_key,
13277 get_lto_kind (kind),
13278 get_lto_visibility (visibility),
13279 (long) size,
13280 (long) slot);
13281 print_symbol (21, (const char *) sym_name);
13282 }
13283 putchar ('\n');
13284 }
13285
13286 if (ext_data != NULL && ext_data < ext_data_end)
13287 {
13288 error (_("Data remains in the LTO symbol extension table\n"));
13289 goto fail;
13290 }
13291
13292 free (alloced_data);
13293 free (ext_data_orig);
13294 free (ext_name);
015dc7e1 13295 return true;
b9e920ec 13296
0f03783c
NC
13297 fail:
13298 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13299 free (alloced_data);
13300 free (ext_data_orig);
13301 free (ext_name);
015dc7e1 13302 return false;
0f03783c
NC
13303}
13304
13305/* Display LTO symbol tables. */
13306
015dc7e1 13307static bool
0f03783c
NC
13308process_lto_symbol_tables (Filedata * filedata)
13309{
13310 Elf_Internal_Shdr * section;
13311 unsigned int i;
015dc7e1 13312 bool res = true;
0f03783c
NC
13313
13314 if (!do_lto_syms)
015dc7e1 13315 return true;
0f03783c
NC
13316
13317 if (filedata->section_headers == NULL)
015dc7e1 13318 return true;
0f03783c
NC
13319
13320 for (i = 0, section = filedata->section_headers;
13321 i < filedata->file_header.e_shnum;
13322 i++, section++)
84714f86
AM
13323 if (section_name_valid (filedata, section)
13324 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13325 res &= display_lto_symtab (filedata, section);
13326
b9e920ec 13327 return res;
0f03783c
NC
13328}
13329
10ca4b04 13330/* Dump the symbol table. */
0f03783c 13331
015dc7e1 13332static bool
10ca4b04
L
13333process_symbol_table (Filedata * filedata)
13334{
13335 Elf_Internal_Shdr * section;
f16a9783 13336
10ca4b04 13337 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13338 return true;
6bd1a22c 13339
978c4450 13340 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13341 && do_syms
13342 && do_using_dynamic
978c4450
AM
13343 && filedata->dynamic_strings != NULL
13344 && filedata->dynamic_symbols != NULL)
6bd1a22c 13345 {
10ca4b04 13346 unsigned long si;
6bd1a22c 13347
ca0e11aa
NC
13348 if (filedata->is_separate)
13349 {
13350 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13351 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13352 filedata->num_dynamic_syms),
13353 filedata->file_name,
13354 filedata->num_dynamic_syms);
13355 }
13356 else
13357 {
13358 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13359 "\nSymbol table for image contains %lu entries:\n",
13360 filedata->num_dynamic_syms),
13361 filedata->num_dynamic_syms);
13362 }
10ca4b04
L
13363 if (is_32bit_elf)
13364 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13365 else
13366 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13367
978c4450
AM
13368 for (si = 0; si < filedata->num_dynamic_syms; si++)
13369 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13370 filedata->dynamic_strings,
13371 filedata->dynamic_strings_length);
252b5132 13372 }
8b73c356 13373 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13374 && filedata->section_headers != NULL)
252b5132 13375 {
b34976b6 13376 unsigned int i;
252b5132 13377
dda8d76d
NC
13378 for (i = 0, section = filedata->section_headers;
13379 i < filedata->file_header.e_shnum;
252b5132
RH
13380 i++, section++)
13381 {
2cf0635d 13382 char * strtab = NULL;
c256ffe7 13383 unsigned long int strtab_size = 0;
2cf0635d 13384 Elf_Internal_Sym * symtab;
ef3df110 13385 unsigned long si, num_syms;
252b5132 13386
2c610e4b
L
13387 if ((section->sh_type != SHT_SYMTAB
13388 && section->sh_type != SHT_DYNSYM)
13389 || (!do_syms
13390 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13391 continue;
13392
dd24e3da
NC
13393 if (section->sh_entsize == 0)
13394 {
13395 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13396 printable_section_name (filedata, section));
dd24e3da
NC
13397 continue;
13398 }
13399
d3a49aa8 13400 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13401
13402 if (filedata->is_separate)
13403 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13404 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13405 num_syms),
13406 filedata->file_name,
13407 printable_section_name (filedata, section),
13408 num_syms);
13409 else
13410 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13411 "\nSymbol table '%s' contains %lu entries:\n",
13412 num_syms),
13413 printable_section_name (filedata, section),
13414 num_syms);
dd24e3da 13415
f7a99963 13416 if (is_32bit_elf)
ca47b30c 13417 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13418 else
ca47b30c 13419 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13420
4de91c10 13421 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13422 if (symtab == NULL)
13423 continue;
13424
dda8d76d 13425 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13426 {
dda8d76d
NC
13427 strtab = filedata->string_table;
13428 strtab_size = filedata->string_table_length;
c256ffe7 13429 }
dda8d76d 13430 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13431 {
2cf0635d 13432 Elf_Internal_Shdr * string_sec;
252b5132 13433
dda8d76d 13434 string_sec = filedata->section_headers + section->sh_link;
252b5132 13435
dda8d76d 13436 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13437 1, string_sec->sh_size,
13438 _("string table"));
c256ffe7 13439 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13440 }
13441
10ca4b04
L
13442 for (si = 0; si < num_syms; si++)
13443 print_dynamic_symbol (filedata, si, symtab, section,
13444 strtab, strtab_size);
252b5132
RH
13445
13446 free (symtab);
dda8d76d 13447 if (strtab != filedata->string_table)
252b5132
RH
13448 free (strtab);
13449 }
13450 }
13451 else if (do_syms)
13452 printf
13453 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13454
978c4450 13455 if (do_histogram && filedata->buckets != NULL)
252b5132 13456 {
2cf0635d
NC
13457 unsigned long * lengths;
13458 unsigned long * counts;
66543521
AM
13459 unsigned long hn;
13460 bfd_vma si;
13461 unsigned long maxlength = 0;
13462 unsigned long nzero_counts = 0;
13463 unsigned long nsyms = 0;
6bd6a03d 13464 char *visited;
252b5132 13465
d3a49aa8
AM
13466 printf (ngettext ("\nHistogram for bucket list length "
13467 "(total of %lu bucket):\n",
13468 "\nHistogram for bucket list length "
13469 "(total of %lu buckets):\n",
978c4450
AM
13470 (unsigned long) filedata->nbuckets),
13471 (unsigned long) filedata->nbuckets);
252b5132 13472
978c4450
AM
13473 lengths = (unsigned long *) calloc (filedata->nbuckets,
13474 sizeof (*lengths));
252b5132
RH
13475 if (lengths == NULL)
13476 {
8b73c356 13477 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13478 goto err_out;
252b5132 13479 }
978c4450
AM
13480 visited = xcmalloc (filedata->nchains, 1);
13481 memset (visited, 0, filedata->nchains);
8b73c356
NC
13482
13483 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13484 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13485 {
978c4450 13486 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13487 {
b34976b6 13488 ++nsyms;
252b5132 13489 if (maxlength < ++lengths[hn])
b34976b6 13490 ++maxlength;
978c4450 13491 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13492 {
13493 error (_("histogram chain is corrupt\n"));
13494 break;
13495 }
13496 visited[si] = 1;
252b5132
RH
13497 }
13498 }
6bd6a03d 13499 free (visited);
252b5132 13500
3f5e193b 13501 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13502 if (counts == NULL)
13503 {
b2e951ec 13504 free (lengths);
8b73c356 13505 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13506 goto err_out;
252b5132
RH
13507 }
13508
978c4450 13509 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13510 ++counts[lengths[hn]];
252b5132 13511
978c4450 13512 if (filedata->nbuckets > 0)
252b5132 13513 {
66543521
AM
13514 unsigned long i;
13515 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13516 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13517 for (i = 1; i <= maxlength; ++i)
103f02d3 13518 {
66543521
AM
13519 nzero_counts += counts[i] * i;
13520 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13521 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13522 (nzero_counts * 100.0) / nsyms);
13523 }
252b5132
RH
13524 }
13525
13526 free (counts);
13527 free (lengths);
13528 }
13529
978c4450
AM
13530 free (filedata->buckets);
13531 filedata->buckets = NULL;
13532 filedata->nbuckets = 0;
13533 free (filedata->chains);
13534 filedata->chains = NULL;
252b5132 13535
978c4450 13536 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13537 {
2cf0635d
NC
13538 unsigned long * lengths;
13539 unsigned long * counts;
fdc90cb4
JJ
13540 unsigned long hn;
13541 unsigned long maxlength = 0;
13542 unsigned long nzero_counts = 0;
13543 unsigned long nsyms = 0;
fdc90cb4 13544
f16a9783 13545 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13546 "(total of %lu bucket):\n",
f16a9783 13547 "\nHistogram for `%s' bucket list length "
d3a49aa8 13548 "(total of %lu buckets):\n",
978c4450
AM
13549 (unsigned long) filedata->ngnubuckets),
13550 GNU_HASH_SECTION_NAME (filedata),
13551 (unsigned long) filedata->ngnubuckets);
8b73c356 13552
978c4450
AM
13553 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13554 sizeof (*lengths));
fdc90cb4
JJ
13555 if (lengths == NULL)
13556 {
8b73c356 13557 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13558 goto err_out;
fdc90cb4
JJ
13559 }
13560
fdc90cb4
JJ
13561 printf (_(" Length Number %% of total Coverage\n"));
13562
978c4450
AM
13563 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13564 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13565 {
13566 bfd_vma off, length = 1;
13567
978c4450 13568 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13569 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13570 off < filedata->ngnuchains
13571 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13572 ++off)
fdc90cb4
JJ
13573 ++length;
13574 lengths[hn] = length;
13575 if (length > maxlength)
13576 maxlength = length;
13577 nsyms += length;
13578 }
13579
3f5e193b 13580 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13581 if (counts == NULL)
13582 {
b2e951ec 13583 free (lengths);
8b73c356 13584 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13585 goto err_out;
fdc90cb4
JJ
13586 }
13587
978c4450 13588 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13589 ++counts[lengths[hn]];
13590
978c4450 13591 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13592 {
13593 unsigned long j;
13594 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13595 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13596 for (j = 1; j <= maxlength; ++j)
13597 {
13598 nzero_counts += counts[j] * j;
13599 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13600 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13601 (nzero_counts * 100.0) / nsyms);
13602 }
13603 }
13604
13605 free (counts);
13606 free (lengths);
fdc90cb4 13607 }
978c4450
AM
13608 free (filedata->gnubuckets);
13609 filedata->gnubuckets = NULL;
13610 filedata->ngnubuckets = 0;
13611 free (filedata->gnuchains);
13612 filedata->gnuchains = NULL;
13613 filedata->ngnuchains = 0;
13614 free (filedata->mipsxlat);
13615 filedata->mipsxlat = NULL;
015dc7e1 13616 return true;
fd486f32
AM
13617
13618 err_out:
978c4450
AM
13619 free (filedata->gnubuckets);
13620 filedata->gnubuckets = NULL;
13621 filedata->ngnubuckets = 0;
13622 free (filedata->gnuchains);
13623 filedata->gnuchains = NULL;
13624 filedata->ngnuchains = 0;
13625 free (filedata->mipsxlat);
13626 filedata->mipsxlat = NULL;
13627 free (filedata->buckets);
13628 filedata->buckets = NULL;
13629 filedata->nbuckets = 0;
13630 free (filedata->chains);
13631 filedata->chains = NULL;
015dc7e1 13632 return false;
252b5132
RH
13633}
13634
015dc7e1 13635static bool
ca0e11aa 13636process_syminfo (Filedata * filedata)
252b5132 13637{
b4c96d0d 13638 unsigned int i;
252b5132 13639
978c4450 13640 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13641 || !do_dynamic)
13642 /* No syminfo, this is ok. */
015dc7e1 13643 return true;
252b5132
RH
13644
13645 /* There better should be a dynamic symbol section. */
978c4450 13646 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13647 return false;
252b5132 13648
ca0e11aa
NC
13649 if (filedata->is_separate)
13650 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13651 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13652 filedata->dynamic_syminfo_nent),
13653 filedata->file_name,
13654 filedata->dynamic_syminfo_offset,
13655 filedata->dynamic_syminfo_nent);
13656 else
d3a49aa8
AM
13657 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13658 "contains %d entry:\n",
13659 "\nDynamic info segment at offset 0x%lx "
13660 "contains %d entries:\n",
978c4450 13661 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13662 filedata->dynamic_syminfo_offset,
13663 filedata->dynamic_syminfo_nent);
252b5132
RH
13664
13665 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13666 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13667 {
978c4450 13668 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13669
31104126 13670 printf ("%4d: ", i);
978c4450 13671 if (i >= filedata->num_dynamic_syms)
4082ef84 13672 printf (_("<corrupt index>"));
84714f86
AM
13673 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13674 print_symbol (30, get_dynamic_name (filedata,
978c4450 13675 filedata->dynamic_symbols[i].st_name));
d79b3d50 13676 else
978c4450 13677 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13678 putchar (' ');
252b5132 13679
978c4450 13680 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13681 {
13682 case SYMINFO_BT_SELF:
13683 fputs ("SELF ", stdout);
13684 break;
13685 case SYMINFO_BT_PARENT:
13686 fputs ("PARENT ", stdout);
13687 break;
13688 default:
978c4450
AM
13689 if (filedata->dynamic_syminfo[i].si_boundto > 0
13690 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13691 && valid_dynamic_name (filedata,
978c4450 13692 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13693 {
84714f86 13694 print_symbol (10, get_dynamic_name (filedata,
978c4450 13695 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13696 putchar (' ' );
13697 }
252b5132 13698 else
978c4450 13699 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13700 break;
13701 }
13702
13703 if (flags & SYMINFO_FLG_DIRECT)
13704 printf (" DIRECT");
13705 if (flags & SYMINFO_FLG_PASSTHRU)
13706 printf (" PASSTHRU");
13707 if (flags & SYMINFO_FLG_COPY)
13708 printf (" COPY");
13709 if (flags & SYMINFO_FLG_LAZYLOAD)
13710 printf (" LAZYLOAD");
13711
13712 puts ("");
13713 }
13714
015dc7e1 13715 return true;
252b5132
RH
13716}
13717
75802ccb
CE
13718/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13719 is contained by the region START .. END. The types of ADDR, START
13720 and END should all be the same. Note both ADDR + NELEM and END
13721 point to just beyond the end of the regions that are being tested. */
13722#define IN_RANGE(START,END,ADDR,NELEM) \
13723 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13724
cf13d699
NC
13725/* Check to see if the given reloc needs to be handled in a target specific
13726 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13727 FALSE.
13728
13729 If called with reloc == NULL, then this is a signal that reloc processing
13730 for the current section has finished, and any saved state should be
13731 discarded. */
09c11c86 13732
015dc7e1 13733static bool
dda8d76d
NC
13734target_specific_reloc_handling (Filedata * filedata,
13735 Elf_Internal_Rela * reloc,
13736 unsigned char * start,
13737 unsigned char * end,
13738 Elf_Internal_Sym * symtab,
13739 unsigned long num_syms)
252b5132 13740{
f84ce13b
NC
13741 unsigned int reloc_type = 0;
13742 unsigned long sym_index = 0;
13743
13744 if (reloc)
13745 {
dda8d76d 13746 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13747 sym_index = get_reloc_symindex (reloc->r_info);
13748 }
252b5132 13749
dda8d76d 13750 switch (filedata->file_header.e_machine)
252b5132 13751 {
13761a11
NC
13752 case EM_MSP430:
13753 case EM_MSP430_OLD:
13754 {
13755 static Elf_Internal_Sym * saved_sym = NULL;
13756
f84ce13b
NC
13757 if (reloc == NULL)
13758 {
13759 saved_sym = NULL;
015dc7e1 13760 return true;
f84ce13b
NC
13761 }
13762
13761a11
NC
13763 switch (reloc_type)
13764 {
13765 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13766 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13767 if (uses_msp430x_relocs (filedata))
13761a11 13768 break;
1a0670f3 13769 /* Fall through. */
13761a11 13770 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13771 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13772 /* PR 21139. */
13773 if (sym_index >= num_syms)
13774 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13775 sym_index);
13776 else
13777 saved_sym = symtab + sym_index;
015dc7e1 13778 return true;
13761a11
NC
13779
13780 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13781 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13782 goto handle_sym_diff;
0b4362b0 13783
13761a11
NC
13784 case 5: /* R_MSP430_16_BYTE */
13785 case 9: /* R_MSP430_8 */
7d81bc93 13786 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13787 if (uses_msp430x_relocs (filedata))
13761a11
NC
13788 break;
13789 goto handle_sym_diff;
13790
13791 case 2: /* R_MSP430_ABS16 */
13792 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13793 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13794 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13795 break;
13796 goto handle_sym_diff;
0b4362b0 13797
13761a11
NC
13798 handle_sym_diff:
13799 if (saved_sym != NULL)
13800 {
13801 bfd_vma value;
5a805384 13802 unsigned int reloc_size = 0;
7d81bc93
JL
13803 int leb_ret = 0;
13804 switch (reloc_type)
13805 {
13806 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13807 reloc_size = 4;
13808 break;
13809 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13810 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13811 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13812 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13813 &reloc_size, &leb_ret);
7d81bc93
JL
13814 break;
13815 default:
13816 reloc_size = 2;
13817 break;
13818 }
13761a11 13819
5a805384 13820 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13821 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13822 "ULEB128 value\n"),
13823 (long) reloc->r_offset);
13824 else if (sym_index >= num_syms)
f84ce13b
NC
13825 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13826 sym_index);
03f7786e 13827 else
f84ce13b
NC
13828 {
13829 value = reloc->r_addend + (symtab[sym_index].st_value
13830 - saved_sym->st_value);
13831
b32e566b 13832 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13833 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13834 else
13835 /* PR 21137 */
13836 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13837 (long) reloc->r_offset);
f84ce13b 13838 }
13761a11
NC
13839
13840 saved_sym = NULL;
015dc7e1 13841 return true;
13761a11
NC
13842 }
13843 break;
13844
13845 default:
13846 if (saved_sym != NULL)
071436c6 13847 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13848 break;
13849 }
13850 break;
13851 }
13852
cf13d699
NC
13853 case EM_MN10300:
13854 case EM_CYGNUS_MN10300:
13855 {
13856 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13857
f84ce13b
NC
13858 if (reloc == NULL)
13859 {
13860 saved_sym = NULL;
015dc7e1 13861 return true;
f84ce13b
NC
13862 }
13863
cf13d699
NC
13864 switch (reloc_type)
13865 {
13866 case 34: /* R_MN10300_ALIGN */
015dc7e1 13867 return true;
cf13d699 13868 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13869 if (sym_index >= num_syms)
13870 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13871 sym_index);
13872 else
13873 saved_sym = symtab + sym_index;
015dc7e1 13874 return true;
f84ce13b 13875
cf13d699
NC
13876 case 1: /* R_MN10300_32 */
13877 case 2: /* R_MN10300_16 */
13878 if (saved_sym != NULL)
13879 {
03f7786e 13880 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13881 bfd_vma value;
252b5132 13882
f84ce13b
NC
13883 if (sym_index >= num_syms)
13884 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13885 sym_index);
03f7786e 13886 else
f84ce13b
NC
13887 {
13888 value = reloc->r_addend + (symtab[sym_index].st_value
13889 - saved_sym->st_value);
13890
b32e566b 13891 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13892 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13893 else
13894 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13895 (long) reloc->r_offset);
f84ce13b 13896 }
252b5132 13897
cf13d699 13898 saved_sym = NULL;
015dc7e1 13899 return true;
cf13d699
NC
13900 }
13901 break;
13902 default:
13903 if (saved_sym != NULL)
071436c6 13904 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13905 break;
13906 }
13907 break;
13908 }
6ff71e76
NC
13909
13910 case EM_RL78:
13911 {
13912 static bfd_vma saved_sym1 = 0;
13913 static bfd_vma saved_sym2 = 0;
13914 static bfd_vma value;
13915
f84ce13b
NC
13916 if (reloc == NULL)
13917 {
13918 saved_sym1 = saved_sym2 = 0;
015dc7e1 13919 return true;
f84ce13b
NC
13920 }
13921
6ff71e76
NC
13922 switch (reloc_type)
13923 {
13924 case 0x80: /* R_RL78_SYM. */
13925 saved_sym1 = saved_sym2;
f84ce13b
NC
13926 if (sym_index >= num_syms)
13927 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13928 sym_index);
13929 else
13930 {
13931 saved_sym2 = symtab[sym_index].st_value;
13932 saved_sym2 += reloc->r_addend;
13933 }
015dc7e1 13934 return true;
6ff71e76
NC
13935
13936 case 0x83: /* R_RL78_OPsub. */
13937 value = saved_sym1 - saved_sym2;
13938 saved_sym2 = saved_sym1 = 0;
015dc7e1 13939 return true;
6ff71e76
NC
13940 break;
13941
13942 case 0x41: /* R_RL78_ABS32. */
b32e566b 13943 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13944 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13945 else
13946 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13947 (long) reloc->r_offset);
6ff71e76 13948 value = 0;
015dc7e1 13949 return true;
6ff71e76
NC
13950
13951 case 0x43: /* R_RL78_ABS16. */
b32e566b 13952 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13953 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13954 else
13955 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13956 (long) reloc->r_offset);
6ff71e76 13957 value = 0;
015dc7e1 13958 return true;
6ff71e76
NC
13959
13960 default:
13961 break;
13962 }
13963 break;
13964 }
252b5132
RH
13965 }
13966
015dc7e1 13967 return false;
252b5132
RH
13968}
13969
aca88567
NC
13970/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13971 DWARF debug sections. This is a target specific test. Note - we do not
13972 go through the whole including-target-headers-multiple-times route, (as
13973 we have already done with <elf/h8.h>) because this would become very
13974 messy and even then this function would have to contain target specific
13975 information (the names of the relocs instead of their numeric values).
13976 FIXME: This is not the correct way to solve this problem. The proper way
13977 is to have target specific reloc sizing and typing functions created by
13978 the reloc-macros.h header, in the same way that it already creates the
13979 reloc naming functions. */
13980
015dc7e1 13981static bool
dda8d76d 13982is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13983{
d347c9df 13984 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13985 switch (filedata->file_header.e_machine)
aca88567 13986 {
41e92641 13987 case EM_386:
22abe556 13988 case EM_IAMCU:
41e92641 13989 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13990 case EM_68K:
13991 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13992 case EM_860:
13993 return reloc_type == 1; /* R_860_32. */
13994 case EM_960:
13995 return reloc_type == 2; /* R_960_32. */
a06ea964 13996 case EM_AARCH64:
9282b95a
JW
13997 return (reloc_type == 258
13998 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13999 case EM_BPF:
14000 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14001 case EM_ADAPTEVA_EPIPHANY:
14002 return reloc_type == 3;
aca88567 14003 case EM_ALPHA:
137b6b5f 14004 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14005 case EM_ARC:
14006 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14007 case EM_ARC_COMPACT:
14008 case EM_ARC_COMPACT2:
14009 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14010 case EM_ARM:
14011 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14012 case EM_AVR_OLD:
aca88567
NC
14013 case EM_AVR:
14014 return reloc_type == 1;
14015 case EM_BLACKFIN:
14016 return reloc_type == 0x12; /* R_byte4_data. */
14017 case EM_CRIS:
14018 return reloc_type == 3; /* R_CRIS_32. */
14019 case EM_CR16:
14020 return reloc_type == 3; /* R_CR16_NUM32. */
14021 case EM_CRX:
14022 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14023 case EM_CSKY:
14024 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14025 case EM_CYGNUS_FRV:
14026 return reloc_type == 1;
41e92641
NC
14027 case EM_CYGNUS_D10V:
14028 case EM_D10V:
14029 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14030 case EM_CYGNUS_D30V:
14031 case EM_D30V:
14032 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14033 case EM_DLX:
14034 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14035 case EM_CYGNUS_FR30:
14036 case EM_FR30:
14037 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14038 case EM_FT32:
14039 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14040 case EM_H8S:
14041 case EM_H8_300:
14042 case EM_H8_300H:
14043 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14044 case EM_IA_64:
262cdac7
AM
14045 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14046 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14047 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14048 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14049 case EM_IP2K_OLD:
14050 case EM_IP2K:
14051 return reloc_type == 2; /* R_IP2K_32. */
14052 case EM_IQ2000:
14053 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14054 case EM_LATTICEMICO32:
14055 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14056 case EM_LOONGARCH:
14057 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14058 case EM_M32C_OLD:
aca88567
NC
14059 case EM_M32C:
14060 return reloc_type == 3; /* R_M32C_32. */
14061 case EM_M32R:
14062 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14063 case EM_68HC11:
14064 case EM_68HC12:
14065 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14066 case EM_S12Z:
2849d19f
JD
14067 return reloc_type == 7 || /* R_S12Z_EXT32 */
14068 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14069 case EM_MCORE:
14070 return reloc_type == 1; /* R_MCORE_ADDR32. */
14071 case EM_CYGNUS_MEP:
14072 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14073 case EM_METAG:
14074 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14075 case EM_MICROBLAZE:
14076 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14077 case EM_MIPS:
14078 return reloc_type == 2; /* R_MIPS_32. */
14079 case EM_MMIX:
14080 return reloc_type == 4; /* R_MMIX_32. */
14081 case EM_CYGNUS_MN10200:
14082 case EM_MN10200:
14083 return reloc_type == 1; /* R_MN10200_32. */
14084 case EM_CYGNUS_MN10300:
14085 case EM_MN10300:
14086 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14087 case EM_MOXIE:
14088 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14089 case EM_MSP430_OLD:
14090 case EM_MSP430:
13761a11 14091 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14092 case EM_MT:
14093 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
14094 case EM_NDS32:
14095 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 14096 case EM_ALTERA_NIOS2:
36591ba1 14097 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14098 case EM_NIOS32:
14099 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14100 case EM_OR1K:
14101 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14102 case EM_PARISC:
9abca702 14103 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14104 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14105 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14106 case EM_PJ:
14107 case EM_PJ_OLD:
14108 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14109 case EM_PPC64:
14110 return reloc_type == 1; /* R_PPC64_ADDR32. */
14111 case EM_PPC:
14112 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14113 case EM_TI_PRU:
14114 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14115 case EM_RISCV:
14116 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14117 case EM_RL78:
14118 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14119 case EM_RX:
14120 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14121 case EM_S370:
14122 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14123 case EM_S390_OLD:
14124 case EM_S390:
14125 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14126 case EM_SCORE:
14127 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14128 case EM_SH:
14129 return reloc_type == 1; /* R_SH_DIR32. */
14130 case EM_SPARC32PLUS:
14131 case EM_SPARCV9:
14132 case EM_SPARC:
14133 return reloc_type == 3 /* R_SPARC_32. */
14134 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14135 case EM_SPU:
14136 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14137 case EM_TI_C6000:
14138 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14139 case EM_TILEGX:
14140 return reloc_type == 2; /* R_TILEGX_32. */
14141 case EM_TILEPRO:
14142 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14143 case EM_CYGNUS_V850:
14144 case EM_V850:
14145 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14146 case EM_V800:
14147 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14148 case EM_VAX:
14149 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14150 case EM_VISIUM:
14151 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14152 case EM_WEBASSEMBLY:
14153 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14154 case EM_X86_64:
8a9036a4 14155 case EM_L1OM:
7a9068fe 14156 case EM_K1OM:
aca88567 14157 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14158 case EM_XC16X:
14159 case EM_C166:
14160 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14161 case EM_XGATE:
14162 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14163 case EM_XSTORMY16:
14164 return reloc_type == 1; /* R_XSTROMY16_32. */
14165 case EM_XTENSA_OLD:
14166 case EM_XTENSA:
14167 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14168 case EM_Z80:
14169 return reloc_type == 6; /* R_Z80_32. */
aca88567 14170 default:
bee0ee85
NC
14171 {
14172 static unsigned int prev_warn = 0;
14173
14174 /* Avoid repeating the same warning multiple times. */
dda8d76d 14175 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14176 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14177 filedata->file_header.e_machine);
14178 prev_warn = filedata->file_header.e_machine;
015dc7e1 14179 return false;
bee0ee85 14180 }
aca88567
NC
14181 }
14182}
14183
14184/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14185 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14186
015dc7e1 14187static bool
dda8d76d 14188is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14189{
dda8d76d 14190 switch (filedata->file_header.e_machine)
d347c9df 14191 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14192 {
41e92641 14193 case EM_386:
22abe556 14194 case EM_IAMCU:
3e0873ac 14195 return reloc_type == 2; /* R_386_PC32. */
aca88567 14196 case EM_68K:
3e0873ac 14197 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14198 case EM_AARCH64:
14199 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14200 case EM_ADAPTEVA_EPIPHANY:
14201 return reloc_type == 6;
aca88567
NC
14202 case EM_ALPHA:
14203 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14204 case EM_ARC_COMPACT:
14205 case EM_ARC_COMPACT2:
14206 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14207 case EM_ARM:
3e0873ac 14208 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14209 case EM_AVR_OLD:
14210 case EM_AVR:
14211 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14212 case EM_MICROBLAZE:
14213 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14214 case EM_OR1K:
14215 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14216 case EM_PARISC:
85acf597 14217 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14218 case EM_PPC:
14219 return reloc_type == 26; /* R_PPC_REL32. */
14220 case EM_PPC64:
3e0873ac 14221 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14222 case EM_RISCV:
14223 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14224 case EM_S390_OLD:
14225 case EM_S390:
3e0873ac 14226 return reloc_type == 5; /* R_390_PC32. */
aca88567 14227 case EM_SH:
3e0873ac 14228 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14229 case EM_SPARC32PLUS:
14230 case EM_SPARCV9:
14231 case EM_SPARC:
3e0873ac 14232 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14233 case EM_SPU:
14234 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14235 case EM_TILEGX:
14236 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14237 case EM_TILEPRO:
14238 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14239 case EM_VISIUM:
14240 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14241 case EM_X86_64:
8a9036a4 14242 case EM_L1OM:
7a9068fe 14243 case EM_K1OM:
3e0873ac 14244 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14245 case EM_VAX:
14246 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14247 case EM_XTENSA_OLD:
14248 case EM_XTENSA:
14249 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14250 default:
14251 /* Do not abort or issue an error message here. Not all targets use
14252 pc-relative 32-bit relocs in their DWARF debug information and we
14253 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14254 more helpful warning message will be generated by apply_relocations
14255 anyway, so just return. */
015dc7e1 14256 return false;
aca88567
NC
14257 }
14258}
14259
14260/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14261 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14262
015dc7e1 14263static bool
dda8d76d 14264is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14265{
dda8d76d 14266 switch (filedata->file_header.e_machine)
aca88567 14267 {
a06ea964
NC
14268 case EM_AARCH64:
14269 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14270 case EM_ALPHA:
14271 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14272 case EM_IA_64:
262cdac7
AM
14273 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14274 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14275 case EM_LOONGARCH:
14276 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14277 case EM_PARISC:
14278 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14279 case EM_PPC64:
14280 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14281 case EM_RISCV:
14282 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14283 case EM_SPARC32PLUS:
14284 case EM_SPARCV9:
14285 case EM_SPARC:
714da62f
NC
14286 return reloc_type == 32 /* R_SPARC_64. */
14287 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14288 case EM_X86_64:
8a9036a4 14289 case EM_L1OM:
7a9068fe 14290 case EM_K1OM:
aca88567 14291 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14292 case EM_S390_OLD:
14293 case EM_S390:
aa137e4d
NC
14294 return reloc_type == 22; /* R_S390_64. */
14295 case EM_TILEGX:
14296 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14297 case EM_MIPS:
aa137e4d 14298 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14299 default:
015dc7e1 14300 return false;
aca88567
NC
14301 }
14302}
14303
85acf597
RH
14304/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14305 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14306
015dc7e1 14307static bool
dda8d76d 14308is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14309{
dda8d76d 14310 switch (filedata->file_header.e_machine)
85acf597 14311 {
a06ea964
NC
14312 case EM_AARCH64:
14313 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14314 case EM_ALPHA:
aa137e4d 14315 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14316 case EM_IA_64:
262cdac7
AM
14317 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14318 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14319 case EM_PARISC:
aa137e4d 14320 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14321 case EM_PPC64:
aa137e4d 14322 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14323 case EM_SPARC32PLUS:
14324 case EM_SPARCV9:
14325 case EM_SPARC:
aa137e4d 14326 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14327 case EM_X86_64:
8a9036a4 14328 case EM_L1OM:
7a9068fe 14329 case EM_K1OM:
aa137e4d 14330 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14331 case EM_S390_OLD:
14332 case EM_S390:
aa137e4d
NC
14333 return reloc_type == 23; /* R_S390_PC64. */
14334 case EM_TILEGX:
14335 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14336 default:
015dc7e1 14337 return false;
85acf597
RH
14338 }
14339}
14340
4dc3c23d
AM
14341/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14342 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14343
015dc7e1 14344static bool
dda8d76d 14345is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14346{
dda8d76d 14347 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14348 {
14349 case EM_CYGNUS_MN10200:
14350 case EM_MN10200:
14351 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14352 case EM_FT32:
14353 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14354 case EM_Z80:
14355 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14356 default:
015dc7e1 14357 return false;
4dc3c23d
AM
14358 }
14359}
14360
aca88567
NC
14361/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14362 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14363
015dc7e1 14364static bool
dda8d76d 14365is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14366{
d347c9df 14367 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14368 switch (filedata->file_header.e_machine)
4b78141a 14369 {
886a2506
NC
14370 case EM_ARC:
14371 case EM_ARC_COMPACT:
14372 case EM_ARC_COMPACT2:
14373 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14374 case EM_ADAPTEVA_EPIPHANY:
14375 return reloc_type == 5;
aca88567
NC
14376 case EM_AVR_OLD:
14377 case EM_AVR:
14378 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14379 case EM_CYGNUS_D10V:
14380 case EM_D10V:
14381 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14382 case EM_FT32:
14383 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14384 case EM_H8S:
14385 case EM_H8_300:
14386 case EM_H8_300H:
aca88567
NC
14387 return reloc_type == R_H8_DIR16;
14388 case EM_IP2K_OLD:
14389 case EM_IP2K:
14390 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14391 case EM_M32C_OLD:
f4236fe4
DD
14392 case EM_M32C:
14393 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14394 case EM_CYGNUS_MN10200:
14395 case EM_MN10200:
14396 return reloc_type == 2; /* R_MN10200_16. */
14397 case EM_CYGNUS_MN10300:
14398 case EM_MN10300:
14399 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14400 case EM_MSP430:
dda8d76d 14401 if (uses_msp430x_relocs (filedata))
13761a11 14402 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14403 /* Fall through. */
78c8d46c 14404 case EM_MSP430_OLD:
aca88567 14405 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14406 case EM_NDS32:
14407 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14408 case EM_ALTERA_NIOS2:
36591ba1 14409 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14410 case EM_NIOS32:
14411 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14412 case EM_OR1K:
14413 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14414 case EM_RISCV:
14415 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14416 case EM_TI_PRU:
14417 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14418 case EM_TI_C6000:
14419 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14420 case EM_VISIUM:
14421 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14422 case EM_XC16X:
14423 case EM_C166:
14424 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14425 case EM_XGATE:
14426 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14427 case EM_Z80:
14428 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14429 default:
015dc7e1 14430 return false;
4b78141a
NC
14431 }
14432}
14433
39e07931
AS
14434/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14435 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14436
015dc7e1 14437static bool
39e07931
AS
14438is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14439{
14440 switch (filedata->file_header.e_machine)
14441 {
14442 case EM_RISCV:
14443 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14444 case EM_Z80:
14445 return reloc_type == 1; /* R_Z80_8. */
39e07931 14446 default:
015dc7e1 14447 return false;
39e07931
AS
14448 }
14449}
14450
14451/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14452 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14453
015dc7e1 14454static bool
39e07931
AS
14455is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14456{
14457 switch (filedata->file_header.e_machine)
14458 {
14459 case EM_RISCV:
14460 return reloc_type == 53; /* R_RISCV_SET6. */
14461 default:
015dc7e1 14462 return false;
39e07931
AS
14463 }
14464}
14465
03336641
JW
14466/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14467 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14468
015dc7e1 14469static bool
03336641
JW
14470is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14471{
14472 /* Please keep this table alpha-sorted for ease of visual lookup. */
14473 switch (filedata->file_header.e_machine)
14474 {
14475 case EM_RISCV:
14476 return reloc_type == 35; /* R_RISCV_ADD32. */
14477 default:
015dc7e1 14478 return false;
03336641
JW
14479 }
14480}
14481
14482/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14483 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14484
015dc7e1 14485static bool
03336641
JW
14486is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14487{
14488 /* Please keep this table alpha-sorted for ease of visual lookup. */
14489 switch (filedata->file_header.e_machine)
14490 {
14491 case EM_RISCV:
14492 return reloc_type == 39; /* R_RISCV_SUB32. */
14493 default:
015dc7e1 14494 return false;
03336641
JW
14495 }
14496}
14497
14498/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14499 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14500
015dc7e1 14501static bool
03336641
JW
14502is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14503{
14504 /* Please keep this table alpha-sorted for ease of visual lookup. */
14505 switch (filedata->file_header.e_machine)
14506 {
14507 case EM_RISCV:
14508 return reloc_type == 36; /* R_RISCV_ADD64. */
14509 default:
015dc7e1 14510 return false;
03336641
JW
14511 }
14512}
14513
14514/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14515 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14516
015dc7e1 14517static bool
03336641
JW
14518is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14519{
14520 /* Please keep this table alpha-sorted for ease of visual lookup. */
14521 switch (filedata->file_header.e_machine)
14522 {
14523 case EM_RISCV:
14524 return reloc_type == 40; /* R_RISCV_SUB64. */
14525 default:
015dc7e1 14526 return false;
03336641
JW
14527 }
14528}
14529
14530/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14531 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14532
015dc7e1 14533static bool
03336641
JW
14534is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14535{
14536 /* Please keep this table alpha-sorted for ease of visual lookup. */
14537 switch (filedata->file_header.e_machine)
14538 {
14539 case EM_RISCV:
14540 return reloc_type == 34; /* R_RISCV_ADD16. */
14541 default:
015dc7e1 14542 return false;
03336641
JW
14543 }
14544}
14545
14546/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14547 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14548
015dc7e1 14549static bool
03336641
JW
14550is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14551{
14552 /* Please keep this table alpha-sorted for ease of visual lookup. */
14553 switch (filedata->file_header.e_machine)
14554 {
14555 case EM_RISCV:
14556 return reloc_type == 38; /* R_RISCV_SUB16. */
14557 default:
015dc7e1 14558 return false;
03336641
JW
14559 }
14560}
14561
14562/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14563 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14564
015dc7e1 14565static bool
03336641
JW
14566is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14567{
14568 /* Please keep this table alpha-sorted for ease of visual lookup. */
14569 switch (filedata->file_header.e_machine)
14570 {
14571 case EM_RISCV:
14572 return reloc_type == 33; /* R_RISCV_ADD8. */
14573 default:
015dc7e1 14574 return false;
03336641
JW
14575 }
14576}
14577
14578/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14579 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14580
015dc7e1 14581static bool
03336641
JW
14582is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14583{
14584 /* Please keep this table alpha-sorted for ease of visual lookup. */
14585 switch (filedata->file_header.e_machine)
14586 {
14587 case EM_RISCV:
14588 return reloc_type == 37; /* R_RISCV_SUB8. */
14589 default:
015dc7e1 14590 return false;
03336641
JW
14591 }
14592}
14593
39e07931
AS
14594/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14595 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14596
015dc7e1 14597static bool
39e07931
AS
14598is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14599{
14600 switch (filedata->file_header.e_machine)
14601 {
14602 case EM_RISCV:
14603 return reloc_type == 52; /* R_RISCV_SUB6. */
14604 default:
015dc7e1 14605 return false;
39e07931
AS
14606 }
14607}
14608
2a7b2e88
JK
14609/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14610 relocation entries (possibly formerly used for SHT_GROUP sections). */
14611
015dc7e1 14612static bool
dda8d76d 14613is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14614{
dda8d76d 14615 switch (filedata->file_header.e_machine)
2a7b2e88 14616 {
cb8f3167 14617 case EM_386: /* R_386_NONE. */
d347c9df 14618 case EM_68K: /* R_68K_NONE. */
cfb8c092 14619 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14620 case EM_ALPHA: /* R_ALPHA_NONE. */
14621 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14622 case EM_ARC: /* R_ARC_NONE. */
886a2506 14623 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14624 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14625 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14626 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14627 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14628 case EM_FT32: /* R_FT32_NONE. */
14629 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14630 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14631 case EM_L1OM: /* R_X86_64_NONE. */
14632 case EM_M32R: /* R_M32R_NONE. */
14633 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14634 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14635 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14636 case EM_NIOS32: /* R_NIOS_NONE. */
14637 case EM_OR1K: /* R_OR1K_NONE. */
14638 case EM_PARISC: /* R_PARISC_NONE. */
14639 case EM_PPC64: /* R_PPC64_NONE. */
14640 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14641 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14642 case EM_S390: /* R_390_NONE. */
14643 case EM_S390_OLD:
14644 case EM_SH: /* R_SH_NONE. */
14645 case EM_SPARC32PLUS:
14646 case EM_SPARC: /* R_SPARC_NONE. */
14647 case EM_SPARCV9:
aa137e4d
NC
14648 case EM_TILEGX: /* R_TILEGX_NONE. */
14649 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14650 case EM_TI_C6000:/* R_C6000_NONE. */
14651 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14652 case EM_XC16X:
6655dba2 14653 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14654 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14655 return reloc_type == 0;
d347c9df 14656
a06ea964
NC
14657 case EM_AARCH64:
14658 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14659 case EM_AVR_OLD:
14660 case EM_AVR:
14661 return (reloc_type == 0 /* R_AVR_NONE. */
14662 || reloc_type == 30 /* R_AVR_DIFF8. */
14663 || reloc_type == 31 /* R_AVR_DIFF16. */
14664 || reloc_type == 32 /* R_AVR_DIFF32. */);
14665 case EM_METAG:
14666 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14667 case EM_NDS32:
14668 return (reloc_type == 0 /* R_XTENSA_NONE. */
14669 || reloc_type == 204 /* R_NDS32_DIFF8. */
14670 || reloc_type == 205 /* R_NDS32_DIFF16. */
14671 || reloc_type == 206 /* R_NDS32_DIFF32. */
14672 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14673 case EM_TI_PRU:
14674 return (reloc_type == 0 /* R_PRU_NONE. */
14675 || reloc_type == 65 /* R_PRU_DIFF8. */
14676 || reloc_type == 66 /* R_PRU_DIFF16. */
14677 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14678 case EM_XTENSA_OLD:
14679 case EM_XTENSA:
4dc3c23d
AM
14680 return (reloc_type == 0 /* R_XTENSA_NONE. */
14681 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14682 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14683 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14684 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14685 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14686 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14687 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14688 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14689 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14690 }
015dc7e1 14691 return false;
2a7b2e88
JK
14692}
14693
d1c4b12b
NC
14694/* Returns TRUE if there is a relocation against
14695 section NAME at OFFSET bytes. */
14696
015dc7e1 14697bool
d1c4b12b
NC
14698reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14699{
14700 Elf_Internal_Rela * relocs;
14701 Elf_Internal_Rela * rp;
14702
14703 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14704 return false;
d1c4b12b
NC
14705
14706 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14707
14708 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14709 if (rp->r_offset == offset)
015dc7e1 14710 return true;
d1c4b12b 14711
015dc7e1 14712 return false;
d1c4b12b
NC
14713}
14714
cf13d699 14715/* Apply relocations to a section.
32ec8896
NC
14716 Returns TRUE upon success, FALSE otherwise.
14717 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14718 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14719 will be set to the number of relocs loaded.
14720
cf13d699 14721 Note: So far support has been added only for those relocations
32ec8896
NC
14722 which can be found in debug sections. FIXME: Add support for
14723 more relocations ? */
1b315056 14724
015dc7e1 14725static bool
dda8d76d 14726apply_relocations (Filedata * filedata,
d1c4b12b
NC
14727 const Elf_Internal_Shdr * section,
14728 unsigned char * start,
14729 bfd_size_type size,
1449284b 14730 void ** relocs_return,
d1c4b12b 14731 unsigned long * num_relocs_return)
1b315056 14732{
cf13d699 14733 Elf_Internal_Shdr * relsec;
0d2a7a93 14734 unsigned char * end = start + size;
cb8f3167 14735
d1c4b12b
NC
14736 if (relocs_return != NULL)
14737 {
14738 * (Elf_Internal_Rela **) relocs_return = NULL;
14739 * num_relocs_return = 0;
14740 }
14741
dda8d76d 14742 if (filedata->file_header.e_type != ET_REL)
32ec8896 14743 /* No relocs to apply. */
015dc7e1 14744 return true;
1b315056 14745
cf13d699 14746 /* Find the reloc section associated with the section. */
dda8d76d
NC
14747 for (relsec = filedata->section_headers;
14748 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14749 ++relsec)
252b5132 14750 {
015dc7e1 14751 bool is_rela;
41e92641 14752 unsigned long num_relocs;
2cf0635d
NC
14753 Elf_Internal_Rela * relocs;
14754 Elf_Internal_Rela * rp;
14755 Elf_Internal_Shdr * symsec;
14756 Elf_Internal_Sym * symtab;
ba5cdace 14757 unsigned long num_syms;
2cf0635d 14758 Elf_Internal_Sym * sym;
252b5132 14759
41e92641 14760 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14761 || relsec->sh_info >= filedata->file_header.e_shnum
14762 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14763 || relsec->sh_size == 0
dda8d76d 14764 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14765 continue;
428409d5 14766
a788aedd
AM
14767 symsec = filedata->section_headers + relsec->sh_link;
14768 if (symsec->sh_type != SHT_SYMTAB
14769 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14770 return false;
a788aedd 14771
41e92641
NC
14772 is_rela = relsec->sh_type == SHT_RELA;
14773
14774 if (is_rela)
14775 {
dda8d76d 14776 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14777 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14778 return false;
41e92641
NC
14779 }
14780 else
14781 {
dda8d76d 14782 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14783 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14784 return false;
41e92641
NC
14785 }
14786
14787 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14788 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14789 is_rela = false;
428409d5 14790
4de91c10 14791 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14792
41e92641 14793 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14794 {
015dc7e1
AM
14795 bfd_vma addend;
14796 unsigned int reloc_type;
14797 unsigned int reloc_size;
14798 bool reloc_inplace = false;
14799 bool reloc_subtract = false;
14800 unsigned char *rloc;
14801 unsigned long sym_index;
4b78141a 14802
dda8d76d 14803 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14804
dda8d76d 14805 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14806 continue;
dda8d76d 14807 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14808 continue;
dda8d76d
NC
14809 else if (is_32bit_abs_reloc (filedata, reloc_type)
14810 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14811 reloc_size = 4;
dda8d76d
NC
14812 else if (is_64bit_abs_reloc (filedata, reloc_type)
14813 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14814 reloc_size = 8;
dda8d76d 14815 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14816 reloc_size = 3;
dda8d76d 14817 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14818 reloc_size = 2;
39e07931
AS
14819 else if (is_8bit_abs_reloc (filedata, reloc_type)
14820 || is_6bit_abs_reloc (filedata, reloc_type))
14821 reloc_size = 1;
03336641
JW
14822 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14823 reloc_type))
14824 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14825 {
14826 reloc_size = 4;
015dc7e1 14827 reloc_inplace = true;
03336641
JW
14828 }
14829 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14830 reloc_type))
14831 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14832 {
14833 reloc_size = 8;
015dc7e1 14834 reloc_inplace = true;
03336641
JW
14835 }
14836 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14837 reloc_type))
14838 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14839 {
14840 reloc_size = 2;
015dc7e1 14841 reloc_inplace = true;
03336641
JW
14842 }
14843 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14844 reloc_type))
14845 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14846 {
14847 reloc_size = 1;
015dc7e1 14848 reloc_inplace = true;
03336641 14849 }
39e07931
AS
14850 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14851 reloc_type)))
14852 {
14853 reloc_size = 1;
015dc7e1 14854 reloc_inplace = true;
39e07931 14855 }
aca88567 14856 else
4b78141a 14857 {
bee0ee85 14858 static unsigned int prev_reloc = 0;
dda8d76d 14859
bee0ee85
NC
14860 if (reloc_type != prev_reloc)
14861 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14862 reloc_type, printable_section_name (filedata, section));
bee0ee85 14863 prev_reloc = reloc_type;
4b78141a
NC
14864 continue;
14865 }
103f02d3 14866
91d6fa6a 14867 rloc = start + rp->r_offset;
75802ccb 14868 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14869 {
14870 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14871 (unsigned long) rp->r_offset,
dda8d76d 14872 printable_section_name (filedata, section));
700dd8b7
L
14873 continue;
14874 }
103f02d3 14875
ba5cdace
NC
14876 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14877 if (sym_index >= num_syms)
14878 {
14879 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14880 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14881 continue;
14882 }
14883 sym = symtab + sym_index;
41e92641
NC
14884
14885 /* If the reloc has a symbol associated with it,
55f25fc3
L
14886 make sure that it is of an appropriate type.
14887
14888 Relocations against symbols without type can happen.
14889 Gcc -feliminate-dwarf2-dups may generate symbols
14890 without type for debug info.
14891
14892 Icc generates relocations against function symbols
14893 instead of local labels.
14894
14895 Relocations against object symbols can happen, eg when
14896 referencing a global array. For an example of this see
14897 the _clz.o binary in libgcc.a. */
aca88567 14898 if (sym != symtab
b8871f35 14899 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14900 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14901 {
d3a49aa8 14902 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14903 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14904 printable_section_name (filedata, relsec),
d3a49aa8 14905 (long int)(rp - relocs));
aca88567 14906 continue;
5b18a4bc 14907 }
252b5132 14908
4dc3c23d
AM
14909 addend = 0;
14910 if (is_rela)
14911 addend += rp->r_addend;
c47320c3
AM
14912 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14913 partial_inplace. */
4dc3c23d 14914 if (!is_rela
dda8d76d 14915 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14916 && reloc_type == 1)
dda8d76d
NC
14917 || ((filedata->file_header.e_machine == EM_PJ
14918 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14919 && reloc_type == 1)
dda8d76d
NC
14920 || ((filedata->file_header.e_machine == EM_D30V
14921 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14922 && reloc_type == 12)
14923 || reloc_inplace)
39e07931
AS
14924 {
14925 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14926 addend += byte_get (rloc, reloc_size) & 0x3f;
14927 else
14928 addend += byte_get (rloc, reloc_size);
14929 }
cb8f3167 14930
dda8d76d
NC
14931 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14932 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14933 {
14934 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14935 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14936 addend -= 8;
91d6fa6a 14937 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14938 reloc_size);
14939 }
39e07931
AS
14940 else if (is_6bit_abs_reloc (filedata, reloc_type)
14941 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14942 {
14943 if (reloc_subtract)
14944 addend -= sym->st_value;
14945 else
14946 addend += sym->st_value;
14947 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14948 byte_put (rloc, addend, reloc_size);
14949 }
03336641
JW
14950 else if (reloc_subtract)
14951 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14952 else
91d6fa6a 14953 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14954 }
252b5132 14955
5b18a4bc 14956 free (symtab);
f84ce13b
NC
14957 /* Let the target specific reloc processing code know that
14958 we have finished with these relocs. */
dda8d76d 14959 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14960
14961 if (relocs_return)
14962 {
14963 * (Elf_Internal_Rela **) relocs_return = relocs;
14964 * num_relocs_return = num_relocs;
14965 }
14966 else
14967 free (relocs);
14968
5b18a4bc
NC
14969 break;
14970 }
32ec8896 14971
015dc7e1 14972 return true;
5b18a4bc 14973}
103f02d3 14974
cf13d699 14975#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14976static bool
dda8d76d 14977disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14978{
dda8d76d 14979 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14980
74e1a04b 14981 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14982
015dc7e1 14983 return true;
cf13d699
NC
14984}
14985#endif
14986
14987/* Reads in the contents of SECTION from FILE, returning a pointer
14988 to a malloc'ed buffer or NULL if something went wrong. */
14989
14990static char *
dda8d76d 14991get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14992{
dda8d76d 14993 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14994
14995 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14996 {
c6b78c96 14997 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14998 printable_section_name (filedata, section));
cf13d699
NC
14999 return NULL;
15000 }
15001
dda8d76d 15002 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15003 _("section contents"));
cf13d699
NC
15004}
15005
0e602686
NC
15006/* Uncompresses a section that was compressed using zlib, in place. */
15007
015dc7e1 15008static bool
dda8d76d
NC
15009uncompress_section_contents (unsigned char ** buffer,
15010 dwarf_size_type uncompressed_size,
15011 dwarf_size_type * size)
0e602686
NC
15012{
15013 dwarf_size_type compressed_size = *size;
15014 unsigned char * compressed_buffer = *buffer;
15015 unsigned char * uncompressed_buffer;
15016 z_stream strm;
15017 int rc;
15018
15019 /* It is possible the section consists of several compressed
15020 buffers concatenated together, so we uncompress in a loop. */
15021 /* PR 18313: The state field in the z_stream structure is supposed
15022 to be invisible to the user (ie us), but some compilers will
15023 still complain about it being used without initialisation. So
15024 we first zero the entire z_stream structure and then set the fields
15025 that we need. */
15026 memset (& strm, 0, sizeof strm);
15027 strm.avail_in = compressed_size;
15028 strm.next_in = (Bytef *) compressed_buffer;
15029 strm.avail_out = uncompressed_size;
15030 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15031
15032 rc = inflateInit (& strm);
15033 while (strm.avail_in > 0)
15034 {
15035 if (rc != Z_OK)
3624a6c1 15036 break;
0e602686
NC
15037 strm.next_out = ((Bytef *) uncompressed_buffer
15038 + (uncompressed_size - strm.avail_out));
15039 rc = inflate (&strm, Z_FINISH);
15040 if (rc != Z_STREAM_END)
3624a6c1 15041 break;
0e602686
NC
15042 rc = inflateReset (& strm);
15043 }
ad92f33d
AM
15044 if (inflateEnd (& strm) != Z_OK
15045 || rc != Z_OK
0e602686
NC
15046 || strm.avail_out != 0)
15047 goto fail;
15048
15049 *buffer = uncompressed_buffer;
15050 *size = uncompressed_size;
015dc7e1 15051 return true;
0e602686
NC
15052
15053 fail:
15054 free (uncompressed_buffer);
15055 /* Indicate decompression failure. */
15056 *buffer = NULL;
015dc7e1 15057 return false;
0e602686 15058}
dd24e3da 15059
015dc7e1 15060static bool
dda8d76d 15061dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15062{
015dc7e1
AM
15063 Elf_Internal_Shdr *relsec;
15064 bfd_size_type num_bytes;
15065 unsigned char *data;
15066 unsigned char *end;
15067 unsigned char *real_start;
15068 unsigned char *start;
15069 bool some_strings_shown;
cf13d699 15070
dda8d76d 15071 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15072 if (start == NULL)
c6b78c96 15073 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15074 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15075
0e602686 15076 num_bytes = section->sh_size;
cf13d699 15077
835f2fae
NC
15078 if (filedata->is_separate)
15079 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15080 printable_section_name (filedata, section),
15081 filedata->file_name);
15082 else
15083 printf (_("\nString dump of section '%s':\n"),
15084 printable_section_name (filedata, section));
cf13d699 15085
0e602686
NC
15086 if (decompress_dumps)
15087 {
15088 dwarf_size_type new_size = num_bytes;
15089 dwarf_size_type uncompressed_size = 0;
15090
15091 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15092 {
15093 Elf_Internal_Chdr chdr;
15094 unsigned int compression_header_size
ebdf1ebf
NC
15095 = get_compression_header (& chdr, (unsigned char *) start,
15096 num_bytes);
5844b465
NC
15097 if (compression_header_size == 0)
15098 /* An error message will have already been generated
15099 by get_compression_header. */
15100 goto error_out;
0e602686 15101
813dabb9 15102 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15103 {
813dabb9 15104 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15105 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15106 goto error_out;
813dabb9 15107 }
813dabb9
L
15108 uncompressed_size = chdr.ch_size;
15109 start += compression_header_size;
15110 new_size -= compression_header_size;
0e602686
NC
15111 }
15112 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15113 {
15114 /* Read the zlib header. In this case, it should be "ZLIB"
15115 followed by the uncompressed section size, 8 bytes in
15116 big-endian order. */
15117 uncompressed_size = start[4]; uncompressed_size <<= 8;
15118 uncompressed_size += start[5]; uncompressed_size <<= 8;
15119 uncompressed_size += start[6]; uncompressed_size <<= 8;
15120 uncompressed_size += start[7]; uncompressed_size <<= 8;
15121 uncompressed_size += start[8]; uncompressed_size <<= 8;
15122 uncompressed_size += start[9]; uncompressed_size <<= 8;
15123 uncompressed_size += start[10]; uncompressed_size <<= 8;
15124 uncompressed_size += start[11];
15125 start += 12;
15126 new_size -= 12;
15127 }
15128
1835f746
NC
15129 if (uncompressed_size)
15130 {
15131 if (uncompress_section_contents (& start,
15132 uncompressed_size, & new_size))
15133 num_bytes = new_size;
15134 else
15135 {
15136 error (_("Unable to decompress section %s\n"),
dda8d76d 15137 printable_section_name (filedata, section));
f761cb13 15138 goto error_out;
1835f746
NC
15139 }
15140 }
bc303e5d
NC
15141 else
15142 start = real_start;
0e602686 15143 }
fd8008d8 15144
cf13d699
NC
15145 /* If the section being dumped has relocations against it the user might
15146 be expecting these relocations to have been applied. Check for this
15147 case and issue a warning message in order to avoid confusion.
15148 FIXME: Maybe we ought to have an option that dumps a section with
15149 relocs applied ? */
dda8d76d
NC
15150 for (relsec = filedata->section_headers;
15151 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15152 ++relsec)
15153 {
15154 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15155 || relsec->sh_info >= filedata->file_header.e_shnum
15156 || filedata->section_headers + relsec->sh_info != section
cf13d699 15157 || relsec->sh_size == 0
dda8d76d 15158 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15159 continue;
15160
15161 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15162 break;
15163 }
15164
cf13d699
NC
15165 data = start;
15166 end = start + num_bytes;
015dc7e1 15167 some_strings_shown = false;
cf13d699 15168
ba3265d0
NC
15169#ifdef HAVE_MBSTATE_T
15170 mbstate_t state;
15171 /* Initialise the multibyte conversion state. */
15172 memset (& state, 0, sizeof (state));
15173#endif
15174
015dc7e1 15175 bool continuing = false;
ba3265d0 15176
cf13d699
NC
15177 while (data < end)
15178 {
15179 while (!ISPRINT (* data))
15180 if (++ data >= end)
15181 break;
15182
15183 if (data < end)
15184 {
071436c6
NC
15185 size_t maxlen = end - data;
15186
ba3265d0
NC
15187 if (continuing)
15188 {
15189 printf (" ");
015dc7e1 15190 continuing = false;
ba3265d0
NC
15191 }
15192 else
15193 {
d1ce973e 15194 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15195 }
15196
4082ef84
NC
15197 if (maxlen > 0)
15198 {
f3da8a96 15199 char c = 0;
ba3265d0
NC
15200
15201 while (maxlen)
15202 {
15203 c = *data++;
15204
15205 if (c == 0)
15206 break;
15207
15208 /* PR 25543: Treat new-lines as string-ending characters. */
15209 if (c == '\n')
15210 {
15211 printf ("\\n\n");
15212 if (*data != 0)
015dc7e1 15213 continuing = true;
ba3265d0
NC
15214 break;
15215 }
15216
15217 /* Do not print control characters directly as they can affect terminal
15218 settings. Such characters usually appear in the names generated
15219 by the assembler for local labels. */
15220 if (ISCNTRL (c))
15221 {
15222 printf ("^%c", c + 0x40);
15223 }
15224 else if (ISPRINT (c))
15225 {
15226 putchar (c);
15227 }
15228 else
15229 {
15230 size_t n;
15231#ifdef HAVE_MBSTATE_T
15232 wchar_t w;
15233#endif
15234 /* Let printf do the hard work of displaying multibyte characters. */
15235 printf ("%.1s", data - 1);
15236#ifdef HAVE_MBSTATE_T
15237 /* Try to find out how many bytes made up the character that was
15238 just printed. Advance the symbol pointer past the bytes that
15239 were displayed. */
15240 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15241#else
15242 n = 1;
15243#endif
15244 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15245 data += (n - 1);
15246 }
15247 }
15248
15249 if (c != '\n')
15250 putchar ('\n');
4082ef84
NC
15251 }
15252 else
15253 {
15254 printf (_("<corrupt>\n"));
15255 data = end;
15256 }
015dc7e1 15257 some_strings_shown = true;
cf13d699
NC
15258 }
15259 }
15260
15261 if (! some_strings_shown)
15262 printf (_(" No strings found in this section."));
15263
0e602686 15264 free (real_start);
cf13d699
NC
15265
15266 putchar ('\n');
015dc7e1 15267 return true;
f761cb13
AM
15268
15269error_out:
15270 free (real_start);
015dc7e1 15271 return false;
cf13d699
NC
15272}
15273
015dc7e1
AM
15274static bool
15275dump_section_as_bytes (Elf_Internal_Shdr *section,
15276 Filedata *filedata,
15277 bool relocate)
cf13d699
NC
15278{
15279 Elf_Internal_Shdr * relsec;
0e602686
NC
15280 bfd_size_type bytes;
15281 bfd_size_type section_size;
15282 bfd_vma addr;
15283 unsigned char * data;
15284 unsigned char * real_start;
15285 unsigned char * start;
15286
dda8d76d 15287 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15288 if (start == NULL)
c6b78c96 15289 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15290 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15291
0e602686 15292 section_size = section->sh_size;
cf13d699 15293
835f2fae
NC
15294 if (filedata->is_separate)
15295 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15296 printable_section_name (filedata, section),
15297 filedata->file_name);
15298 else
15299 printf (_("\nHex dump of section '%s':\n"),
15300 printable_section_name (filedata, section));
cf13d699 15301
0e602686
NC
15302 if (decompress_dumps)
15303 {
15304 dwarf_size_type new_size = section_size;
15305 dwarf_size_type uncompressed_size = 0;
15306
15307 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15308 {
15309 Elf_Internal_Chdr chdr;
15310 unsigned int compression_header_size
ebdf1ebf 15311 = get_compression_header (& chdr, start, section_size);
0e602686 15312
5844b465
NC
15313 if (compression_header_size == 0)
15314 /* An error message will have already been generated
15315 by get_compression_header. */
15316 goto error_out;
15317
813dabb9 15318 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15319 {
813dabb9 15320 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15321 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15322 goto error_out;
0e602686 15323 }
813dabb9
L
15324 uncompressed_size = chdr.ch_size;
15325 start += compression_header_size;
15326 new_size -= compression_header_size;
0e602686
NC
15327 }
15328 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15329 {
15330 /* Read the zlib header. In this case, it should be "ZLIB"
15331 followed by the uncompressed section size, 8 bytes in
15332 big-endian order. */
15333 uncompressed_size = start[4]; uncompressed_size <<= 8;
15334 uncompressed_size += start[5]; uncompressed_size <<= 8;
15335 uncompressed_size += start[6]; uncompressed_size <<= 8;
15336 uncompressed_size += start[7]; uncompressed_size <<= 8;
15337 uncompressed_size += start[8]; uncompressed_size <<= 8;
15338 uncompressed_size += start[9]; uncompressed_size <<= 8;
15339 uncompressed_size += start[10]; uncompressed_size <<= 8;
15340 uncompressed_size += start[11];
15341 start += 12;
15342 new_size -= 12;
15343 }
15344
f055032e
NC
15345 if (uncompressed_size)
15346 {
15347 if (uncompress_section_contents (& start, uncompressed_size,
15348 & new_size))
bc303e5d
NC
15349 {
15350 section_size = new_size;
15351 }
f055032e
NC
15352 else
15353 {
15354 error (_("Unable to decompress section %s\n"),
dda8d76d 15355 printable_section_name (filedata, section));
bc303e5d 15356 /* FIXME: Print the section anyway ? */
f761cb13 15357 goto error_out;
f055032e
NC
15358 }
15359 }
bc303e5d
NC
15360 else
15361 start = real_start;
0e602686 15362 }
14ae95f2 15363
cf13d699
NC
15364 if (relocate)
15365 {
dda8d76d 15366 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15367 goto error_out;
cf13d699
NC
15368 }
15369 else
15370 {
15371 /* If the section being dumped has relocations against it the user might
15372 be expecting these relocations to have been applied. Check for this
15373 case and issue a warning message in order to avoid confusion.
15374 FIXME: Maybe we ought to have an option that dumps a section with
15375 relocs applied ? */
dda8d76d
NC
15376 for (relsec = filedata->section_headers;
15377 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15378 ++relsec)
15379 {
15380 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15381 || relsec->sh_info >= filedata->file_header.e_shnum
15382 || filedata->section_headers + relsec->sh_info != section
cf13d699 15383 || relsec->sh_size == 0
dda8d76d 15384 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15385 continue;
15386
15387 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15388 break;
15389 }
15390 }
15391
15392 addr = section->sh_addr;
0e602686 15393 bytes = section_size;
cf13d699
NC
15394 data = start;
15395
15396 while (bytes)
15397 {
15398 int j;
15399 int k;
15400 int lbytes;
15401
15402 lbytes = (bytes > 16 ? 16 : bytes);
15403
15404 printf (" 0x%8.8lx ", (unsigned long) addr);
15405
15406 for (j = 0; j < 16; j++)
15407 {
15408 if (j < lbytes)
15409 printf ("%2.2x", data[j]);
15410 else
15411 printf (" ");
15412
15413 if ((j & 3) == 3)
15414 printf (" ");
15415 }
15416
15417 for (j = 0; j < lbytes; j++)
15418 {
15419 k = data[j];
15420 if (k >= ' ' && k < 0x7f)
15421 printf ("%c", k);
15422 else
15423 printf (".");
15424 }
15425
15426 putchar ('\n');
15427
15428 data += lbytes;
15429 addr += lbytes;
15430 bytes -= lbytes;
15431 }
15432
0e602686 15433 free (real_start);
cf13d699
NC
15434
15435 putchar ('\n');
015dc7e1 15436 return true;
f761cb13
AM
15437
15438 error_out:
15439 free (real_start);
015dc7e1 15440 return false;
cf13d699
NC
15441}
15442
094e34f2 15443#ifdef ENABLE_LIBCTF
7d9813f1
NA
15444static ctf_sect_t *
15445shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15446{
84714f86 15447 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15448 buf->cts_size = shdr->sh_size;
15449 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15450
15451 return buf;
15452}
15453
15454/* Formatting callback function passed to ctf_dump. Returns either the pointer
15455 it is passed, or a pointer to newly-allocated storage, in which case
15456 dump_ctf() will free it when it no longer needs it. */
15457
2f6ecaed
NA
15458static char *
15459dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15460 char *s, void *arg)
7d9813f1 15461{
3e50a591 15462 const char *blanks = arg;
7d9813f1
NA
15463 char *new_s;
15464
3e50a591 15465 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15466 return s;
15467 return new_s;
15468}
15469
926c9e76
NA
15470/* Dump CTF errors/warnings. */
15471static void
139633c3 15472dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15473{
15474 ctf_next_t *it = NULL;
15475 char *errtext;
15476 int is_warning;
15477 int err;
15478
15479 /* Dump accumulated errors and warnings. */
15480 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15481 {
5e9b84f7 15482 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15483 errtext);
15484 free (errtext);
15485 }
15486 if (err != ECTF_NEXT_END)
15487 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15488}
15489
2f6ecaed
NA
15490/* Dump one CTF archive member. */
15491
80b56fad
NA
15492static void
15493dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15494 size_t member)
2f6ecaed 15495{
2f6ecaed
NA
15496 const char *things[] = {"Header", "Labels", "Data objects",
15497 "Function objects", "Variables", "Types", "Strings",
15498 ""};
15499 const char **thing;
15500 size_t i;
15501
80b56fad
NA
15502 /* Don't print out the name of the default-named archive member if it appears
15503 first in the list. The name .ctf appears everywhere, even for things that
15504 aren't really archives, so printing it out is liable to be confusing; also,
15505 the common case by far is for only one archive member to exist, and hiding
15506 it in that case seems worthwhile. */
2f6ecaed 15507
80b56fad
NA
15508 if (strcmp (name, ".ctf") != 0 || member != 0)
15509 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15510
80b56fad
NA
15511 if (ctf_parent_name (ctf) != NULL)
15512 ctf_import (ctf, parent);
2f6ecaed
NA
15513
15514 for (i = 0, thing = things; *thing[0]; thing++, i++)
15515 {
15516 ctf_dump_state_t *s = NULL;
15517 char *item;
15518
15519 printf ("\n %s:\n", *thing);
15520 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15521 (void *) " ")) != NULL)
15522 {
15523 printf ("%s\n", item);
15524 free (item);
15525 }
15526
15527 if (ctf_errno (ctf))
15528 {
15529 error (_("Iteration failed: %s, %s\n"), *thing,
15530 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15531 break;
2f6ecaed
NA
15532 }
15533 }
8b37e7b6 15534
926c9e76 15535 dump_ctf_errs (ctf);
2f6ecaed
NA
15536}
15537
015dc7e1 15538static bool
7d9813f1
NA
15539dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15540{
7d9813f1
NA
15541 Elf_Internal_Shdr * symtab_sec = NULL;
15542 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15543 void * data = NULL;
15544 void * symdata = NULL;
15545 void * strdata = NULL;
80b56fad 15546 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15547 ctf_sect_t * symsectp = NULL;
15548 ctf_sect_t * strsectp = NULL;
2f6ecaed 15549 ctf_archive_t * ctfa = NULL;
139633c3 15550 ctf_dict_t * parent = NULL;
80b56fad 15551 ctf_dict_t * fp;
7d9813f1 15552
80b56fad
NA
15553 ctf_next_t *i = NULL;
15554 const char *name;
15555 size_t member = 0;
7d9813f1 15556 int err;
015dc7e1 15557 bool ret = false;
7d9813f1
NA
15558
15559 shdr_to_ctf_sect (&ctfsect, section, filedata);
15560 data = get_section_contents (section, filedata);
15561 ctfsect.cts_data = data;
15562
616febde 15563 if (!dump_ctf_symtab_name)
3d16b64e 15564 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15565
15566 if (!dump_ctf_strtab_name)
3d16b64e 15567 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15568
15569 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15570 {
15571 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15572 {
15573 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15574 goto fail;
15575 }
15576 if ((symdata = (void *) get_data (NULL, filedata,
15577 symtab_sec->sh_offset, 1,
15578 symtab_sec->sh_size,
15579 _("symbols"))) == NULL)
15580 goto fail;
15581 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15582 symsect.cts_data = symdata;
15583 }
835f2fae 15584
df16e041 15585 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15586 {
15587 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15588 {
15589 error (_("No string table section named %s\n"),
15590 dump_ctf_strtab_name);
15591 goto fail;
15592 }
15593 if ((strdata = (void *) get_data (NULL, filedata,
15594 strtab_sec->sh_offset, 1,
15595 strtab_sec->sh_size,
15596 _("strings"))) == NULL)
15597 goto fail;
15598 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15599 strsect.cts_data = strdata;
15600 }
835f2fae 15601
2f6ecaed
NA
15602 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15603 libctf papers over the difference, so we can pretend it is always an
80b56fad 15604 archive. */
7d9813f1 15605
2f6ecaed 15606 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15607 {
926c9e76 15608 dump_ctf_errs (NULL);
7d9813f1
NA
15609 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15610 goto fail;
15611 }
15612
96c61be5
NA
15613 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15614 != ELFDATA2MSB);
15615
80b56fad
NA
15616 /* Preload the parent dict, since it will need to be imported into every
15617 child in turn. */
15618 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15619 {
926c9e76 15620 dump_ctf_errs (NULL);
2f6ecaed
NA
15621 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15622 goto fail;
7d9813f1
NA
15623 }
15624
015dc7e1 15625 ret = true;
7d9813f1 15626
835f2fae
NC
15627 if (filedata->is_separate)
15628 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15629 printable_section_name (filedata, section),
15630 filedata->file_name);
15631 else
15632 printf (_("\nDump of CTF section '%s':\n"),
15633 printable_section_name (filedata, section));
7d9813f1 15634
80b56fad
NA
15635 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15636 dump_ctf_archive_member (fp, name, parent, member++);
15637 if (err != ECTF_NEXT_END)
15638 {
15639 dump_ctf_errs (NULL);
15640 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15641 ret = false;
15642 }
7d9813f1
NA
15643
15644 fail:
139633c3 15645 ctf_dict_close (parent);
2f6ecaed 15646 ctf_close (ctfa);
7d9813f1
NA
15647 free (data);
15648 free (symdata);
15649 free (strdata);
15650 return ret;
15651}
094e34f2 15652#endif
7d9813f1 15653
015dc7e1 15654static bool
dda8d76d
NC
15655load_specific_debug_section (enum dwarf_section_display_enum debug,
15656 const Elf_Internal_Shdr * sec,
15657 void * data)
1007acb3 15658{
2cf0635d 15659 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15660 char buf [64];
dda8d76d 15661 Filedata * filedata = (Filedata *) data;
9abca702 15662
19e6b90e 15663 if (section->start != NULL)
dda8d76d
NC
15664 {
15665 /* If it is already loaded, do nothing. */
15666 if (streq (section->filename, filedata->file_name))
015dc7e1 15667 return true;
dda8d76d
NC
15668 free (section->start);
15669 }
1007acb3 15670
19e6b90e
L
15671 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15672 section->address = sec->sh_addr;
dda8d76d
NC
15673 section->filename = filedata->file_name;
15674 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15675 sec->sh_offset, 1,
15676 sec->sh_size, buf);
59245841
NC
15677 if (section->start == NULL)
15678 section->size = 0;
15679 else
15680 {
77115a4a
L
15681 unsigned char *start = section->start;
15682 dwarf_size_type size = sec->sh_size;
dab394de 15683 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15684
15685 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15686 {
15687 Elf_Internal_Chdr chdr;
d8024a91
NC
15688 unsigned int compression_header_size;
15689
f53be977
L
15690 if (size < (is_32bit_elf
15691 ? sizeof (Elf32_External_Chdr)
15692 : sizeof (Elf64_External_Chdr)))
d8024a91 15693 {
55be8fd0 15694 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15695 section->name);
015dc7e1 15696 return false;
d8024a91
NC
15697 }
15698
ebdf1ebf 15699 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15700 if (compression_header_size == 0)
15701 /* An error message will have already been generated
15702 by get_compression_header. */
015dc7e1 15703 return false;
d8024a91 15704
813dabb9
L
15705 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15706 {
15707 warn (_("section '%s' has unsupported compress type: %d\n"),
15708 section->name, chdr.ch_type);
015dc7e1 15709 return false;
813dabb9 15710 }
dab394de 15711 uncompressed_size = chdr.ch_size;
77115a4a
L
15712 start += compression_header_size;
15713 size -= compression_header_size;
15714 }
dab394de
L
15715 else if (size > 12 && streq ((char *) start, "ZLIB"))
15716 {
15717 /* Read the zlib header. In this case, it should be "ZLIB"
15718 followed by the uncompressed section size, 8 bytes in
15719 big-endian order. */
15720 uncompressed_size = start[4]; uncompressed_size <<= 8;
15721 uncompressed_size += start[5]; uncompressed_size <<= 8;
15722 uncompressed_size += start[6]; uncompressed_size <<= 8;
15723 uncompressed_size += start[7]; uncompressed_size <<= 8;
15724 uncompressed_size += start[8]; uncompressed_size <<= 8;
15725 uncompressed_size += start[9]; uncompressed_size <<= 8;
15726 uncompressed_size += start[10]; uncompressed_size <<= 8;
15727 uncompressed_size += start[11];
15728 start += 12;
15729 size -= 12;
15730 }
15731
1835f746 15732 if (uncompressed_size)
77115a4a 15733 {
1835f746
NC
15734 if (uncompress_section_contents (&start, uncompressed_size,
15735 &size))
15736 {
15737 /* Free the compressed buffer, update the section buffer
15738 and the section size if uncompress is successful. */
15739 free (section->start);
15740 section->start = start;
15741 }
15742 else
15743 {
15744 error (_("Unable to decompress section %s\n"),
dda8d76d 15745 printable_section_name (filedata, sec));
015dc7e1 15746 return false;
1835f746 15747 }
77115a4a 15748 }
bc303e5d 15749
77115a4a 15750 section->size = size;
59245841 15751 }
4a114e3e 15752
1b315056 15753 if (section->start == NULL)
015dc7e1 15754 return false;
1b315056 15755
19e6b90e 15756 if (debug_displays [debug].relocate)
32ec8896 15757 {
dda8d76d 15758 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15759 & section->reloc_info, & section->num_relocs))
015dc7e1 15760 return false;
32ec8896 15761 }
d1c4b12b
NC
15762 else
15763 {
15764 section->reloc_info = NULL;
15765 section->num_relocs = 0;
15766 }
1007acb3 15767
015dc7e1 15768 return true;
1007acb3
L
15769}
15770
301a9420
AM
15771#if HAVE_LIBDEBUGINFOD
15772/* Return a hex string representation of the build-id. */
15773unsigned char *
15774get_build_id (void * data)
15775{
ca0e11aa 15776 Filedata * filedata = (Filedata *) data;
301a9420
AM
15777 Elf_Internal_Shdr * shdr;
15778 unsigned long i;
15779
55be8fd0
NC
15780 /* Iterate through notes to find note.gnu.build-id.
15781 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15782 for (i = 0, shdr = filedata->section_headers;
15783 i < filedata->file_header.e_shnum && shdr != NULL;
15784 i++, shdr++)
15785 {
15786 if (shdr->sh_type != SHT_NOTE)
15787 continue;
15788
15789 char * next;
15790 char * end;
15791 size_t data_remaining;
15792 size_t min_notesz;
15793 Elf_External_Note * enote;
15794 Elf_Internal_Note inote;
15795
15796 bfd_vma offset = shdr->sh_offset;
15797 bfd_vma align = shdr->sh_addralign;
15798 bfd_vma length = shdr->sh_size;
15799
15800 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15801 if (enote == NULL)
15802 continue;
15803
15804 if (align < 4)
15805 align = 4;
15806 else if (align != 4 && align != 8)
f761cb13
AM
15807 {
15808 free (enote);
15809 continue;
15810 }
301a9420
AM
15811
15812 end = (char *) enote + length;
15813 data_remaining = end - (char *) enote;
15814
15815 if (!is_ia64_vms (filedata))
15816 {
15817 min_notesz = offsetof (Elf_External_Note, name);
15818 if (data_remaining < min_notesz)
15819 {
55be8fd0
NC
15820 warn (_("\
15821malformed note encountered in section %s whilst scanning for build-id note\n"),
15822 printable_section_name (filedata, shdr));
f761cb13 15823 free (enote);
55be8fd0 15824 continue;
301a9420
AM
15825 }
15826 data_remaining -= min_notesz;
15827
15828 inote.type = BYTE_GET (enote->type);
15829 inote.namesz = BYTE_GET (enote->namesz);
15830 inote.namedata = enote->name;
15831 inote.descsz = BYTE_GET (enote->descsz);
15832 inote.descdata = ((char *) enote
15833 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15834 inote.descpos = offset + (inote.descdata - (char *) enote);
15835 next = ((char *) enote
15836 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15837 }
15838 else
15839 {
15840 Elf64_External_VMS_Note *vms_enote;
15841
15842 /* PR binutils/15191
15843 Make sure that there is enough data to read. */
15844 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15845 if (data_remaining < min_notesz)
15846 {
55be8fd0
NC
15847 warn (_("\
15848malformed note encountered in section %s whilst scanning for build-id note\n"),
15849 printable_section_name (filedata, shdr));
f761cb13 15850 free (enote);
55be8fd0 15851 continue;
301a9420
AM
15852 }
15853 data_remaining -= min_notesz;
15854
15855 vms_enote = (Elf64_External_VMS_Note *) enote;
15856 inote.type = BYTE_GET (vms_enote->type);
15857 inote.namesz = BYTE_GET (vms_enote->namesz);
15858 inote.namedata = vms_enote->name;
15859 inote.descsz = BYTE_GET (vms_enote->descsz);
15860 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15861 inote.descpos = offset + (inote.descdata - (char *) enote);
15862 next = inote.descdata + align_power (inote.descsz, 3);
15863 }
15864
15865 /* Skip malformed notes. */
15866 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15867 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15868 || (size_t) (next - inote.descdata) < inote.descsz
15869 || ((size_t) (next - inote.descdata)
15870 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15871 {
55be8fd0
NC
15872 warn (_("\
15873malformed note encountered in section %s whilst scanning for build-id note\n"),
15874 printable_section_name (filedata, shdr));
f761cb13 15875 free (enote);
301a9420
AM
15876 continue;
15877 }
15878
15879 /* Check if this is the build-id note. If so then convert the build-id
15880 bytes to a hex string. */
15881 if (inote.namesz > 0
24d127aa 15882 && startswith (inote.namedata, "GNU")
301a9420
AM
15883 && inote.type == NT_GNU_BUILD_ID)
15884 {
15885 unsigned long j;
15886 char * build_id;
15887
15888 build_id = malloc (inote.descsz * 2 + 1);
15889 if (build_id == NULL)
f761cb13
AM
15890 {
15891 free (enote);
15892 return NULL;
15893 }
301a9420
AM
15894
15895 for (j = 0; j < inote.descsz; ++j)
15896 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15897 build_id[inote.descsz * 2] = '\0';
f761cb13 15898 free (enote);
301a9420 15899
55be8fd0 15900 return (unsigned char *) build_id;
301a9420 15901 }
f761cb13 15902 free (enote);
301a9420
AM
15903 }
15904
15905 return NULL;
15906}
15907#endif /* HAVE_LIBDEBUGINFOD */
15908
657d0d47
CC
15909/* If this is not NULL, load_debug_section will only look for sections
15910 within the list of sections given here. */
32ec8896 15911static unsigned int * section_subset = NULL;
657d0d47 15912
015dc7e1 15913bool
dda8d76d 15914load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15915{
2cf0635d
NC
15916 struct dwarf_section * section = &debug_displays [debug].section;
15917 Elf_Internal_Shdr * sec;
dda8d76d
NC
15918 Filedata * filedata = (Filedata *) data;
15919
e1dbfc17
L
15920 if (!dump_any_debugging)
15921 return false;
15922
f425ec66
NC
15923 /* Without section headers we cannot find any sections. */
15924 if (filedata->section_headers == NULL)
015dc7e1 15925 return false;
f425ec66 15926
9c1ce108
AM
15927 if (filedata->string_table == NULL
15928 && filedata->file_header.e_shstrndx != SHN_UNDEF
15929 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15930 {
15931 Elf_Internal_Shdr * strs;
15932
15933 /* Read in the string table, so that we have section names to scan. */
15934 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15935
4dff97b2 15936 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15937 {
9c1ce108
AM
15938 filedata->string_table
15939 = (char *) get_data (NULL, filedata, strs->sh_offset,
15940 1, strs->sh_size, _("string table"));
dda8d76d 15941
9c1ce108
AM
15942 filedata->string_table_length
15943 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15944 }
15945 }
d966045b
DJ
15946
15947 /* Locate the debug section. */
dda8d76d 15948 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15949 if (sec != NULL)
15950 section->name = section->uncompressed_name;
15951 else
15952 {
dda8d76d 15953 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15954 if (sec != NULL)
15955 section->name = section->compressed_name;
15956 }
15957 if (sec == NULL)
015dc7e1 15958 return false;
d966045b 15959
657d0d47
CC
15960 /* If we're loading from a subset of sections, and we've loaded
15961 a section matching this name before, it's likely that it's a
15962 different one. */
15963 if (section_subset != NULL)
15964 free_debug_section (debug);
15965
dda8d76d 15966 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15967}
15968
19e6b90e
L
15969void
15970free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15971{
2cf0635d 15972 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15973
19e6b90e
L
15974 if (section->start == NULL)
15975 return;
1007acb3 15976
19e6b90e
L
15977 free ((char *) section->start);
15978 section->start = NULL;
15979 section->address = 0;
15980 section->size = 0;
a788aedd 15981
9db70fc3
AM
15982 free (section->reloc_info);
15983 section->reloc_info = NULL;
15984 section->num_relocs = 0;
1007acb3
L
15985}
15986
015dc7e1 15987static bool
dda8d76d 15988display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15989{
84714f86
AM
15990 const char *name = (section_name_valid (filedata, section)
15991 ? section_name (filedata, section) : "");
15992 const char *print_name = printable_section_name (filedata, section);
19e6b90e 15993 bfd_size_type length;
015dc7e1 15994 bool result = true;
3f5e193b 15995 int i;
1007acb3 15996
19e6b90e
L
15997 length = section->sh_size;
15998 if (length == 0)
1007acb3 15999 {
74e1a04b 16000 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16001 return true;
1007acb3 16002 }
5dff79d8
NC
16003 if (section->sh_type == SHT_NOBITS)
16004 {
16005 /* There is no point in dumping the contents of a debugging section
16006 which has the NOBITS type - the bits in the file will be random.
16007 This can happen when a file containing a .eh_frame section is
16008 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16009 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16010 print_name);
015dc7e1 16011 return false;
5dff79d8 16012 }
1007acb3 16013
24d127aa 16014 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16015 name = ".debug_info";
1007acb3 16016
19e6b90e
L
16017 /* See if we know how to display the contents of this section. */
16018 for (i = 0; i < max; i++)
d85bf2ba
NC
16019 {
16020 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16021 struct dwarf_section_display * display = debug_displays + i;
16022 struct dwarf_section * sec = & display->section;
d966045b 16023
d85bf2ba 16024 if (streq (sec->uncompressed_name, name)
24d127aa 16025 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16026 || streq (sec->compressed_name, name))
16027 {
015dc7e1 16028 bool secondary = (section != find_section (filedata, name));
1007acb3 16029
d85bf2ba
NC
16030 if (secondary)
16031 free_debug_section (id);
dda8d76d 16032
24d127aa 16033 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16034 sec->name = name;
16035 else if (streq (sec->uncompressed_name, name))
16036 sec->name = sec->uncompressed_name;
16037 else
16038 sec->name = sec->compressed_name;
657d0d47 16039
d85bf2ba
NC
16040 if (load_specific_debug_section (id, section, filedata))
16041 {
16042 /* If this debug section is part of a CU/TU set in a .dwp file,
16043 restrict load_debug_section to the sections in that set. */
16044 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16045
d85bf2ba 16046 result &= display->display (sec, filedata);
657d0d47 16047
d85bf2ba 16048 section_subset = NULL;
1007acb3 16049
44266f36 16050 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16051 free_debug_section (id);
16052 }
16053 break;
16054 }
16055 }
1007acb3 16056
19e6b90e 16057 if (i == max)
1007acb3 16058 {
74e1a04b 16059 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16060 result = false;
1007acb3
L
16061 }
16062
19e6b90e 16063 return result;
5b18a4bc 16064}
103f02d3 16065
aef1f6d0
DJ
16066/* Set DUMP_SECTS for all sections where dumps were requested
16067 based on section name. */
16068
16069static void
dda8d76d 16070initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16071{
2cf0635d 16072 struct dump_list_entry * cur;
aef1f6d0
DJ
16073
16074 for (cur = dump_sects_byname; cur; cur = cur->next)
16075 {
16076 unsigned int i;
015dc7e1 16077 bool any = false;
aef1f6d0 16078
dda8d76d 16079 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16080 if (section_name_valid (filedata, filedata->section_headers + i)
16081 && streq (section_name (filedata, filedata->section_headers + i),
16082 cur->name))
aef1f6d0 16083 {
6431e409 16084 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16085 any = true;
aef1f6d0
DJ
16086 }
16087
835f2fae
NC
16088 if (!any && !filedata->is_separate)
16089 warn (_("Section '%s' was not dumped because it does not exist\n"),
16090 cur->name);
aef1f6d0
DJ
16091 }
16092}
16093
015dc7e1 16094static bool
dda8d76d 16095process_section_contents (Filedata * filedata)
5b18a4bc 16096{
2cf0635d 16097 Elf_Internal_Shdr * section;
19e6b90e 16098 unsigned int i;
015dc7e1 16099 bool res = true;
103f02d3 16100
19e6b90e 16101 if (! do_dump)
015dc7e1 16102 return true;
103f02d3 16103
dda8d76d 16104 initialise_dumps_byname (filedata);
aef1f6d0 16105
dda8d76d 16106 for (i = 0, section = filedata->section_headers;
6431e409 16107 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16108 i++, section++)
16109 {
6431e409 16110 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16111
d6bfbc39
NC
16112 if (filedata->is_separate && ! process_links)
16113 dump &= DEBUG_DUMP;
047c3dbf 16114
19e6b90e 16115#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16116 if (dump & DISASS_DUMP)
16117 {
16118 if (! disassemble_section (section, filedata))
015dc7e1 16119 res = false;
dda8d76d 16120 }
19e6b90e 16121#endif
dda8d76d 16122 if (dump & HEX_DUMP)
32ec8896 16123 {
015dc7e1
AM
16124 if (! dump_section_as_bytes (section, filedata, false))
16125 res = false;
32ec8896 16126 }
103f02d3 16127
dda8d76d 16128 if (dump & RELOC_DUMP)
32ec8896 16129 {
015dc7e1
AM
16130 if (! dump_section_as_bytes (section, filedata, true))
16131 res = false;
32ec8896 16132 }
09c11c86 16133
dda8d76d 16134 if (dump & STRING_DUMP)
32ec8896 16135 {
dda8d76d 16136 if (! dump_section_as_strings (section, filedata))
015dc7e1 16137 res = false;
32ec8896 16138 }
cf13d699 16139
dda8d76d 16140 if (dump & DEBUG_DUMP)
32ec8896 16141 {
dda8d76d 16142 if (! display_debug_section (i, section, filedata))
015dc7e1 16143 res = false;
32ec8896 16144 }
7d9813f1 16145
094e34f2 16146#ifdef ENABLE_LIBCTF
7d9813f1
NA
16147 if (dump & CTF_DUMP)
16148 {
16149 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16150 res = false;
7d9813f1 16151 }
094e34f2 16152#endif
5b18a4bc 16153 }
103f02d3 16154
835f2fae 16155 if (! filedata->is_separate)
0ee3043f 16156 {
835f2fae
NC
16157 /* Check to see if the user requested a
16158 dump of a section that does not exist. */
16159 for (; i < filedata->dump.num_dump_sects; i++)
16160 if (filedata->dump.dump_sects[i])
16161 {
ca0e11aa 16162 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16163 res = false;
835f2fae 16164 }
0ee3043f 16165 }
32ec8896
NC
16166
16167 return res;
5b18a4bc 16168}
103f02d3 16169
5b18a4bc 16170static void
19e6b90e 16171process_mips_fpe_exception (int mask)
5b18a4bc 16172{
19e6b90e
L
16173 if (mask)
16174 {
015dc7e1 16175 bool first = true;
32ec8896 16176
19e6b90e 16177 if (mask & OEX_FPU_INEX)
015dc7e1 16178 fputs ("INEX", stdout), first = false;
19e6b90e 16179 if (mask & OEX_FPU_UFLO)
015dc7e1 16180 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16181 if (mask & OEX_FPU_OFLO)
015dc7e1 16182 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16183 if (mask & OEX_FPU_DIV0)
015dc7e1 16184 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16185 if (mask & OEX_FPU_INVAL)
16186 printf ("%sINVAL", first ? "" : "|");
16187 }
5b18a4bc 16188 else
19e6b90e 16189 fputs ("0", stdout);
5b18a4bc 16190}
103f02d3 16191
f6f0e17b
NC
16192/* Display's the value of TAG at location P. If TAG is
16193 greater than 0 it is assumed to be an unknown tag, and
16194 a message is printed to this effect. Otherwise it is
16195 assumed that a message has already been printed.
16196
16197 If the bottom bit of TAG is set it assumed to have a
16198 string value, otherwise it is assumed to have an integer
16199 value.
16200
16201 Returns an updated P pointing to the first unread byte
16202 beyond the end of TAG's value.
16203
16204 Reads at or beyond END will not be made. */
16205
16206static unsigned char *
60abdbed 16207display_tag_value (signed int tag,
f6f0e17b
NC
16208 unsigned char * p,
16209 const unsigned char * const end)
16210{
16211 unsigned long val;
16212
16213 if (tag > 0)
16214 printf (" Tag_unknown_%d: ", tag);
16215
16216 if (p >= end)
16217 {
4082ef84 16218 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16219 }
16220 else if (tag & 1)
16221 {
071436c6
NC
16222 /* PR 17531 file: 027-19978-0.004. */
16223 size_t maxlen = (end - p) - 1;
16224
16225 putchar ('"');
4082ef84
NC
16226 if (maxlen > 0)
16227 {
16228 print_symbol ((int) maxlen, (const char *) p);
16229 p += strnlen ((char *) p, maxlen) + 1;
16230 }
16231 else
16232 {
16233 printf (_("<corrupt string tag>"));
16234 p = (unsigned char *) end;
16235 }
071436c6 16236 printf ("\"\n");
f6f0e17b
NC
16237 }
16238 else
16239 {
cd30bcef 16240 READ_ULEB (val, p, end);
f6f0e17b
NC
16241 printf ("%ld (0x%lx)\n", val, val);
16242 }
16243
4082ef84 16244 assert (p <= end);
f6f0e17b
NC
16245 return p;
16246}
16247
53a346d8
CZ
16248/* ARC ABI attributes section. */
16249
16250static unsigned char *
16251display_arc_attribute (unsigned char * p,
16252 const unsigned char * const end)
16253{
16254 unsigned int tag;
53a346d8
CZ
16255 unsigned int val;
16256
cd30bcef 16257 READ_ULEB (tag, p, end);
53a346d8
CZ
16258
16259 switch (tag)
16260 {
16261 case Tag_ARC_PCS_config:
cd30bcef 16262 READ_ULEB (val, p, end);
53a346d8
CZ
16263 printf (" Tag_ARC_PCS_config: ");
16264 switch (val)
16265 {
16266 case 0:
16267 printf (_("Absent/Non standard\n"));
16268 break;
16269 case 1:
16270 printf (_("Bare metal/mwdt\n"));
16271 break;
16272 case 2:
16273 printf (_("Bare metal/newlib\n"));
16274 break;
16275 case 3:
16276 printf (_("Linux/uclibc\n"));
16277 break;
16278 case 4:
16279 printf (_("Linux/glibc\n"));
16280 break;
16281 default:
16282 printf (_("Unknown\n"));
16283 break;
16284 }
16285 break;
16286
16287 case Tag_ARC_CPU_base:
cd30bcef 16288 READ_ULEB (val, p, end);
53a346d8
CZ
16289 printf (" Tag_ARC_CPU_base: ");
16290 switch (val)
16291 {
16292 default:
16293 case TAG_CPU_NONE:
16294 printf (_("Absent\n"));
16295 break;
16296 case TAG_CPU_ARC6xx:
16297 printf ("ARC6xx\n");
16298 break;
16299 case TAG_CPU_ARC7xx:
16300 printf ("ARC7xx\n");
16301 break;
16302 case TAG_CPU_ARCEM:
16303 printf ("ARCEM\n");
16304 break;
16305 case TAG_CPU_ARCHS:
16306 printf ("ARCHS\n");
16307 break;
16308 }
16309 break;
16310
16311 case Tag_ARC_CPU_variation:
cd30bcef 16312 READ_ULEB (val, p, end);
53a346d8
CZ
16313 printf (" Tag_ARC_CPU_variation: ");
16314 switch (val)
16315 {
16316 default:
16317 if (val > 0 && val < 16)
53a346d8 16318 printf ("Core%d\n", val);
d8cbc93b
JL
16319 else
16320 printf ("Unknown\n");
16321 break;
16322
53a346d8
CZ
16323 case 0:
16324 printf (_("Absent\n"));
16325 break;
16326 }
16327 break;
16328
16329 case Tag_ARC_CPU_name:
16330 printf (" Tag_ARC_CPU_name: ");
16331 p = display_tag_value (-1, p, end);
16332 break;
16333
16334 case Tag_ARC_ABI_rf16:
cd30bcef 16335 READ_ULEB (val, p, end);
53a346d8
CZ
16336 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16337 break;
16338
16339 case Tag_ARC_ABI_osver:
cd30bcef 16340 READ_ULEB (val, p, end);
53a346d8
CZ
16341 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16342 break;
16343
16344 case Tag_ARC_ABI_pic:
16345 case Tag_ARC_ABI_sda:
cd30bcef 16346 READ_ULEB (val, p, end);
53a346d8
CZ
16347 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16348 : " Tag_ARC_ABI_pic: ");
16349 switch (val)
16350 {
16351 case 0:
16352 printf (_("Absent\n"));
16353 break;
16354 case 1:
16355 printf ("MWDT\n");
16356 break;
16357 case 2:
16358 printf ("GNU\n");
16359 break;
16360 default:
16361 printf (_("Unknown\n"));
16362 break;
16363 }
16364 break;
16365
16366 case Tag_ARC_ABI_tls:
cd30bcef 16367 READ_ULEB (val, p, end);
53a346d8
CZ
16368 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16369 break;
16370
16371 case Tag_ARC_ABI_enumsize:
cd30bcef 16372 READ_ULEB (val, p, end);
53a346d8
CZ
16373 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16374 _("smallest"));
16375 break;
16376
16377 case Tag_ARC_ABI_exceptions:
cd30bcef 16378 READ_ULEB (val, p, end);
53a346d8
CZ
16379 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16380 : _("default"));
16381 break;
16382
16383 case Tag_ARC_ABI_double_size:
cd30bcef 16384 READ_ULEB (val, p, end);
53a346d8
CZ
16385 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16386 break;
16387
16388 case Tag_ARC_ISA_config:
16389 printf (" Tag_ARC_ISA_config: ");
16390 p = display_tag_value (-1, p, end);
16391 break;
16392
16393 case Tag_ARC_ISA_apex:
16394 printf (" Tag_ARC_ISA_apex: ");
16395 p = display_tag_value (-1, p, end);
16396 break;
16397
16398 case Tag_ARC_ISA_mpy_option:
cd30bcef 16399 READ_ULEB (val, p, end);
53a346d8
CZ
16400 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16401 break;
16402
db1e1b45 16403 case Tag_ARC_ATR_version:
cd30bcef 16404 READ_ULEB (val, p, end);
db1e1b45 16405 printf (" Tag_ARC_ATR_version: %d\n", val);
16406 break;
16407
53a346d8
CZ
16408 default:
16409 return display_tag_value (tag & 1, p, end);
16410 }
16411
16412 return p;
16413}
16414
11c1ff18
PB
16415/* ARM EABI attributes section. */
16416typedef struct
16417{
70e99720 16418 unsigned int tag;
2cf0635d 16419 const char * name;
11c1ff18 16420 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16421 unsigned int type;
288f0ba2 16422 const char *const *table;
11c1ff18
PB
16423} arm_attr_public_tag;
16424
288f0ba2 16425static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16426 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16427 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16428 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16429 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16430static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16431static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16432 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16433static const char *const arm_attr_tag_FP_arch[] =
bca38921 16434 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16435 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16436static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16437static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16438 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16439 "NEON for ARMv8.1"};
288f0ba2 16440static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16441 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16442 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16443static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16444 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16445static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16446 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16447static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16448 {"Absolute", "PC-relative", "None"};
288f0ba2 16449static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16450 {"None", "direct", "GOT-indirect"};
288f0ba2 16451static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16452 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16453static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16454static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16455 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16456static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16457static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16458static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16459 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16460static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16461 {"Unused", "small", "int", "forced to int"};
288f0ba2 16462static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16463 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16464static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16465 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16466static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16467 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16468static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16469 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16470 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16471static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16472 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16473 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16474static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16475static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16476 {"Not Allowed", "Allowed"};
288f0ba2 16477static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16478 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16479static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16480 {"Follow architecture", "Allowed"};
288f0ba2 16481static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16482 {"Not Allowed", "Allowed"};
288f0ba2 16483static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16484 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16485 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16486static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16487static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16488 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16489 "TrustZone and Virtualization Extensions"};
288f0ba2 16490static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16491 {"Not Allowed", "Allowed"};
11c1ff18 16492
288f0ba2 16493static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16494 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16495
99db83d0
AC
16496static const char * arm_attr_tag_PAC_extension[] =
16497 {"No PAC/AUT instructions",
16498 "PAC/AUT instructions permitted in the NOP space",
16499 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16500
4b535030
AC
16501static const char * arm_attr_tag_BTI_extension[] =
16502 {"BTI instructions not permitted",
16503 "BTI instructions permitted in the NOP space",
16504 "BTI instructions permitted in the NOP and in the non-NOP space"};
16505
b81ee92f
AC
16506static const char * arm_attr_tag_BTI_use[] =
16507 {"Compiled without branch target enforcement",
16508 "Compiled with branch target enforcement"};
16509
c9fed665
AC
16510static const char * arm_attr_tag_PACRET_use[] =
16511 {"Compiled without return address signing and authentication",
16512 "Compiled with return address signing and authentication"};
16513
11c1ff18
PB
16514#define LOOKUP(id, name) \
16515 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16516static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16517{
16518 {4, "CPU_raw_name", 1, NULL},
16519 {5, "CPU_name", 1, NULL},
16520 LOOKUP(6, CPU_arch),
16521 {7, "CPU_arch_profile", 0, NULL},
16522 LOOKUP(8, ARM_ISA_use),
16523 LOOKUP(9, THUMB_ISA_use),
75375b3e 16524 LOOKUP(10, FP_arch),
11c1ff18 16525 LOOKUP(11, WMMX_arch),
f5f53991
AS
16526 LOOKUP(12, Advanced_SIMD_arch),
16527 LOOKUP(13, PCS_config),
11c1ff18
PB
16528 LOOKUP(14, ABI_PCS_R9_use),
16529 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16530 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16531 LOOKUP(17, ABI_PCS_GOT_use),
16532 LOOKUP(18, ABI_PCS_wchar_t),
16533 LOOKUP(19, ABI_FP_rounding),
16534 LOOKUP(20, ABI_FP_denormal),
16535 LOOKUP(21, ABI_FP_exceptions),
16536 LOOKUP(22, ABI_FP_user_exceptions),
16537 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16538 {24, "ABI_align_needed", 0, NULL},
16539 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16540 LOOKUP(26, ABI_enum_size),
16541 LOOKUP(27, ABI_HardFP_use),
16542 LOOKUP(28, ABI_VFP_args),
16543 LOOKUP(29, ABI_WMMX_args),
16544 LOOKUP(30, ABI_optimization_goals),
16545 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16546 {32, "compatibility", 0, NULL},
f5f53991 16547 LOOKUP(34, CPU_unaligned_access),
75375b3e 16548 LOOKUP(36, FP_HP_extension),
8e79c3df 16549 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16550 LOOKUP(42, MPextension_use),
16551 LOOKUP(44, DIV_use),
15afaa63 16552 LOOKUP(46, DSP_extension),
a7ad558c 16553 LOOKUP(48, MVE_arch),
99db83d0 16554 LOOKUP(50, PAC_extension),
4b535030 16555 LOOKUP(52, BTI_extension),
b81ee92f 16556 LOOKUP(74, BTI_use),
c9fed665 16557 LOOKUP(76, PACRET_use),
f5f53991
AS
16558 {64, "nodefaults", 0, NULL},
16559 {65, "also_compatible_with", 0, NULL},
16560 LOOKUP(66, T2EE_use),
16561 {67, "conformance", 1, NULL},
16562 LOOKUP(68, Virtualization_use),
cd21e546 16563 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16564};
16565#undef LOOKUP
16566
11c1ff18 16567static unsigned char *
f6f0e17b
NC
16568display_arm_attribute (unsigned char * p,
16569 const unsigned char * const end)
11c1ff18 16570{
70e99720 16571 unsigned int tag;
70e99720 16572 unsigned int val;
2cf0635d 16573 arm_attr_public_tag * attr;
11c1ff18 16574 unsigned i;
70e99720 16575 unsigned int type;
11c1ff18 16576
cd30bcef 16577 READ_ULEB (tag, p, end);
11c1ff18 16578 attr = NULL;
2cf0635d 16579 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16580 {
16581 if (arm_attr_public_tags[i].tag == tag)
16582 {
16583 attr = &arm_attr_public_tags[i];
16584 break;
16585 }
16586 }
16587
16588 if (attr)
16589 {
16590 printf (" Tag_%s: ", attr->name);
16591 switch (attr->type)
16592 {
16593 case 0:
16594 switch (tag)
16595 {
16596 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16597 READ_ULEB (val, p, end);
11c1ff18
PB
16598 switch (val)
16599 {
2b692964
NC
16600 case 0: printf (_("None\n")); break;
16601 case 'A': printf (_("Application\n")); break;
16602 case 'R': printf (_("Realtime\n")); break;
16603 case 'M': printf (_("Microcontroller\n")); break;
16604 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16605 default: printf ("??? (%d)\n", val); break;
16606 }
16607 break;
16608
75375b3e 16609 case 24: /* Tag_align_needed. */
cd30bcef 16610 READ_ULEB (val, p, end);
75375b3e
MGD
16611 switch (val)
16612 {
2b692964
NC
16613 case 0: printf (_("None\n")); break;
16614 case 1: printf (_("8-byte\n")); break;
16615 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16616 case 3: printf ("??? 3\n"); break;
16617 default:
16618 if (val <= 12)
dd24e3da 16619 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16620 1 << val);
16621 else
16622 printf ("??? (%d)\n", val);
16623 break;
16624 }
16625 break;
16626
16627 case 25: /* Tag_align_preserved. */
cd30bcef 16628 READ_ULEB (val, p, end);
75375b3e
MGD
16629 switch (val)
16630 {
2b692964
NC
16631 case 0: printf (_("None\n")); break;
16632 case 1: printf (_("8-byte, except leaf SP\n")); break;
16633 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16634 case 3: printf ("??? 3\n"); break;
16635 default:
16636 if (val <= 12)
dd24e3da 16637 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16638 1 << val);
16639 else
16640 printf ("??? (%d)\n", val);
16641 break;
16642 }
16643 break;
16644
11c1ff18 16645 case 32: /* Tag_compatibility. */
071436c6 16646 {
cd30bcef 16647 READ_ULEB (val, p, end);
071436c6 16648 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16649 if (p < end - 1)
16650 {
16651 size_t maxlen = (end - p) - 1;
16652
16653 print_symbol ((int) maxlen, (const char *) p);
16654 p += strnlen ((char *) p, maxlen) + 1;
16655 }
16656 else
16657 {
16658 printf (_("<corrupt>"));
16659 p = (unsigned char *) end;
16660 }
071436c6 16661 putchar ('\n');
071436c6 16662 }
11c1ff18
PB
16663 break;
16664
f5f53991 16665 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16666 /* PR 17531: file: 001-505008-0.01. */
16667 if (p < end)
16668 p++;
2b692964 16669 printf (_("True\n"));
f5f53991
AS
16670 break;
16671
16672 case 65: /* Tag_also_compatible_with. */
cd30bcef 16673 READ_ULEB (val, p, end);
f5f53991
AS
16674 if (val == 6 /* Tag_CPU_arch. */)
16675 {
cd30bcef 16676 READ_ULEB (val, p, end);
071436c6 16677 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16678 printf ("??? (%d)\n", val);
16679 else
16680 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16681 }
16682 else
16683 printf ("???\n");
071436c6
NC
16684 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16685 ;
f5f53991
AS
16686 break;
16687
11c1ff18 16688 default:
bee0ee85
NC
16689 printf (_("<unknown: %d>\n"), tag);
16690 break;
11c1ff18
PB
16691 }
16692 return p;
16693
16694 case 1:
f6f0e17b 16695 return display_tag_value (-1, p, end);
11c1ff18 16696 case 2:
f6f0e17b 16697 return display_tag_value (0, p, end);
11c1ff18
PB
16698
16699 default:
16700 assert (attr->type & 0x80);
cd30bcef 16701 READ_ULEB (val, p, end);
11c1ff18
PB
16702 type = attr->type & 0x7f;
16703 if (val >= type)
16704 printf ("??? (%d)\n", val);
16705 else
16706 printf ("%s\n", attr->table[val]);
16707 return p;
16708 }
16709 }
11c1ff18 16710
f6f0e17b 16711 return display_tag_value (tag, p, end);
11c1ff18
PB
16712}
16713
104d59d1 16714static unsigned char *
60bca95a 16715display_gnu_attribute (unsigned char * p,
60abdbed 16716 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16717 const unsigned char * const end)
104d59d1 16718{
cd30bcef 16719 unsigned int tag;
60abdbed 16720 unsigned int val;
104d59d1 16721
cd30bcef 16722 READ_ULEB (tag, p, end);
104d59d1
JM
16723
16724 /* Tag_compatibility is the only generic GNU attribute defined at
16725 present. */
16726 if (tag == 32)
16727 {
cd30bcef 16728 READ_ULEB (val, p, end);
071436c6
NC
16729
16730 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16731 if (p == end)
16732 {
071436c6 16733 printf (_("<corrupt>\n"));
f6f0e17b
NC
16734 warn (_("corrupt vendor attribute\n"));
16735 }
16736 else
16737 {
4082ef84
NC
16738 if (p < end - 1)
16739 {
16740 size_t maxlen = (end - p) - 1;
071436c6 16741
4082ef84
NC
16742 print_symbol ((int) maxlen, (const char *) p);
16743 p += strnlen ((char *) p, maxlen) + 1;
16744 }
16745 else
16746 {
16747 printf (_("<corrupt>"));
16748 p = (unsigned char *) end;
16749 }
071436c6 16750 putchar ('\n');
f6f0e17b 16751 }
104d59d1
JM
16752 return p;
16753 }
16754
16755 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16756 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16757
f6f0e17b 16758 return display_tag_value (tag, p, end);
104d59d1
JM
16759}
16760
85f7484a
PB
16761static unsigned char *
16762display_m68k_gnu_attribute (unsigned char * p,
16763 unsigned int tag,
16764 const unsigned char * const end)
16765{
16766 unsigned int val;
16767
16768 if (tag == Tag_GNU_M68K_ABI_FP)
16769 {
16770 printf (" Tag_GNU_M68K_ABI_FP: ");
16771 if (p == end)
16772 {
16773 printf (_("<corrupt>\n"));
16774 return p;
16775 }
16776 READ_ULEB (val, p, end);
16777
16778 if (val > 3)
16779 printf ("(%#x), ", val);
16780
16781 switch (val & 3)
16782 {
16783 case 0:
16784 printf (_("unspecified hard/soft float\n"));
16785 break;
16786 case 1:
16787 printf (_("hard float\n"));
16788 break;
16789 case 2:
16790 printf (_("soft float\n"));
16791 break;
16792 }
16793 return p;
16794 }
16795
16796 return display_tag_value (tag & 1, p, end);
16797}
16798
34c8bcba 16799static unsigned char *
f6f0e17b 16800display_power_gnu_attribute (unsigned char * p,
60abdbed 16801 unsigned int tag,
f6f0e17b 16802 const unsigned char * const end)
34c8bcba 16803{
005d79fd 16804 unsigned int val;
34c8bcba
JM
16805
16806 if (tag == Tag_GNU_Power_ABI_FP)
16807 {
34c8bcba 16808 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16809 if (p == end)
005d79fd
AM
16810 {
16811 printf (_("<corrupt>\n"));
16812 return p;
16813 }
cd30bcef 16814 READ_ULEB (val, p, end);
60bca95a 16815
005d79fd
AM
16816 if (val > 15)
16817 printf ("(%#x), ", val);
16818
16819 switch (val & 3)
34c8bcba
JM
16820 {
16821 case 0:
005d79fd 16822 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16823 break;
16824 case 1:
005d79fd 16825 printf (_("hard float, "));
34c8bcba
JM
16826 break;
16827 case 2:
005d79fd 16828 printf (_("soft float, "));
34c8bcba 16829 break;
3c7b9897 16830 case 3:
005d79fd 16831 printf (_("single-precision hard float, "));
3c7b9897 16832 break;
005d79fd
AM
16833 }
16834
16835 switch (val & 0xC)
16836 {
16837 case 0:
16838 printf (_("unspecified long double\n"));
16839 break;
16840 case 4:
16841 printf (_("128-bit IBM long double\n"));
16842 break;
16843 case 8:
16844 printf (_("64-bit long double\n"));
16845 break;
16846 case 12:
16847 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16848 break;
16849 }
16850 return p;
005d79fd 16851 }
34c8bcba 16852
c6e65352
DJ
16853 if (tag == Tag_GNU_Power_ABI_Vector)
16854 {
c6e65352 16855 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16856 if (p == end)
005d79fd
AM
16857 {
16858 printf (_("<corrupt>\n"));
16859 return p;
16860 }
cd30bcef 16861 READ_ULEB (val, p, end);
005d79fd
AM
16862
16863 if (val > 3)
16864 printf ("(%#x), ", val);
16865
16866 switch (val & 3)
c6e65352
DJ
16867 {
16868 case 0:
005d79fd 16869 printf (_("unspecified\n"));
c6e65352
DJ
16870 break;
16871 case 1:
005d79fd 16872 printf (_("generic\n"));
c6e65352
DJ
16873 break;
16874 case 2:
16875 printf ("AltiVec\n");
16876 break;
16877 case 3:
16878 printf ("SPE\n");
16879 break;
c6e65352
DJ
16880 }
16881 return p;
005d79fd 16882 }
c6e65352 16883
f82e0623
NF
16884 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16885 {
005d79fd 16886 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16887 if (p == end)
f6f0e17b 16888 {
005d79fd 16889 printf (_("<corrupt>\n"));
f6f0e17b
NC
16890 return p;
16891 }
cd30bcef 16892 READ_ULEB (val, p, end);
0b4362b0 16893
005d79fd
AM
16894 if (val > 2)
16895 printf ("(%#x), ", val);
16896
16897 switch (val & 3)
16898 {
16899 case 0:
16900 printf (_("unspecified\n"));
16901 break;
16902 case 1:
16903 printf ("r3/r4\n");
16904 break;
16905 case 2:
16906 printf (_("memory\n"));
16907 break;
16908 case 3:
16909 printf ("???\n");
16910 break;
16911 }
f82e0623
NF
16912 return p;
16913 }
16914
f6f0e17b 16915 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16916}
16917
643f7afb
AK
16918static unsigned char *
16919display_s390_gnu_attribute (unsigned char * p,
60abdbed 16920 unsigned int tag,
643f7afb
AK
16921 const unsigned char * const end)
16922{
cd30bcef 16923 unsigned int val;
643f7afb
AK
16924
16925 if (tag == Tag_GNU_S390_ABI_Vector)
16926 {
643f7afb 16927 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16928 READ_ULEB (val, p, end);
643f7afb
AK
16929
16930 switch (val)
16931 {
16932 case 0:
16933 printf (_("any\n"));
16934 break;
16935 case 1:
16936 printf (_("software\n"));
16937 break;
16938 case 2:
16939 printf (_("hardware\n"));
16940 break;
16941 default:
16942 printf ("??? (%d)\n", val);
16943 break;
16944 }
16945 return p;
16946 }
16947
16948 return display_tag_value (tag & 1, p, end);
16949}
16950
9e8c70f9 16951static void
60abdbed 16952display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16953{
16954 if (mask)
16955 {
015dc7e1 16956 bool first = true;
071436c6 16957
9e8c70f9 16958 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16959 fputs ("mul32", stdout), first = false;
9e8c70f9 16960 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16961 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16962 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16963 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16964 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16965 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16966 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16967 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16968 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16969 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16970 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16971 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16972 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16973 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16974 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16975 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16976 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16977 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16978 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16979 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16980 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16981 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16982 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16983 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16984 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16985 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16986 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16987 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16988 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16989 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16990 }
16991 else
071436c6
NC
16992 fputc ('0', stdout);
16993 fputc ('\n', stdout);
9e8c70f9
DM
16994}
16995
3d68f91c 16996static void
60abdbed 16997display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16998{
16999 if (mask)
17000 {
015dc7e1 17001 bool first = true;
071436c6 17002
3d68f91c 17003 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17004 fputs ("fjathplus", stdout), first = false;
3d68f91c 17005 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17006 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17007 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17008 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17009 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17010 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17011 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17012 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17013 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17014 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17015 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17016 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17017 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17018 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17019 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17020 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17021 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17022 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17023 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17024 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17025 }
17026 else
071436c6
NC
17027 fputc ('0', stdout);
17028 fputc ('\n', stdout);
3d68f91c
JM
17029}
17030
9e8c70f9 17031static unsigned char *
f6f0e17b 17032display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17033 unsigned int tag,
f6f0e17b 17034 const unsigned char * const end)
9e8c70f9 17035{
cd30bcef 17036 unsigned int val;
3d68f91c 17037
9e8c70f9
DM
17038 if (tag == Tag_GNU_Sparc_HWCAPS)
17039 {
cd30bcef 17040 READ_ULEB (val, p, end);
9e8c70f9 17041 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17042 display_sparc_hwcaps (val);
17043 return p;
3d68f91c
JM
17044 }
17045 if (tag == Tag_GNU_Sparc_HWCAPS2)
17046 {
cd30bcef 17047 READ_ULEB (val, p, end);
3d68f91c
JM
17048 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17049 display_sparc_hwcaps2 (val);
17050 return p;
17051 }
9e8c70f9 17052
f6f0e17b 17053 return display_tag_value (tag, p, end);
9e8c70f9
DM
17054}
17055
351cdf24 17056static void
32ec8896 17057print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17058{
17059 switch (val)
17060 {
17061 case Val_GNU_MIPS_ABI_FP_ANY:
17062 printf (_("Hard or soft float\n"));
17063 break;
17064 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17065 printf (_("Hard float (double precision)\n"));
17066 break;
17067 case Val_GNU_MIPS_ABI_FP_SINGLE:
17068 printf (_("Hard float (single precision)\n"));
17069 break;
17070 case Val_GNU_MIPS_ABI_FP_SOFT:
17071 printf (_("Soft float\n"));
17072 break;
17073 case Val_GNU_MIPS_ABI_FP_OLD_64:
17074 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17075 break;
17076 case Val_GNU_MIPS_ABI_FP_XX:
17077 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17078 break;
17079 case Val_GNU_MIPS_ABI_FP_64:
17080 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17081 break;
17082 case Val_GNU_MIPS_ABI_FP_64A:
17083 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17084 break;
3350cc01
CM
17085 case Val_GNU_MIPS_ABI_FP_NAN2008:
17086 printf (_("NaN 2008 compatibility\n"));
17087 break;
351cdf24
MF
17088 default:
17089 printf ("??? (%d)\n", val);
17090 break;
17091 }
17092}
17093
2cf19d5c 17094static unsigned char *
f6f0e17b 17095display_mips_gnu_attribute (unsigned char * p,
60abdbed 17096 unsigned int tag,
f6f0e17b 17097 const unsigned char * const end)
2cf19d5c 17098{
2cf19d5c
JM
17099 if (tag == Tag_GNU_MIPS_ABI_FP)
17100 {
32ec8896 17101 unsigned int val;
f6f0e17b 17102
2cf19d5c 17103 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17104 READ_ULEB (val, p, end);
351cdf24 17105 print_mips_fp_abi_value (val);
2cf19d5c
JM
17106 return p;
17107 }
17108
a9f58168
CF
17109 if (tag == Tag_GNU_MIPS_ABI_MSA)
17110 {
32ec8896 17111 unsigned int val;
a9f58168 17112
a9f58168 17113 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17114 READ_ULEB (val, p, end);
a9f58168
CF
17115
17116 switch (val)
17117 {
17118 case Val_GNU_MIPS_ABI_MSA_ANY:
17119 printf (_("Any MSA or not\n"));
17120 break;
17121 case Val_GNU_MIPS_ABI_MSA_128:
17122 printf (_("128-bit MSA\n"));
17123 break;
17124 default:
17125 printf ("??? (%d)\n", val);
17126 break;
17127 }
17128 return p;
17129 }
17130
f6f0e17b 17131 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17132}
17133
59e6276b 17134static unsigned char *
f6f0e17b
NC
17135display_tic6x_attribute (unsigned char * p,
17136 const unsigned char * const end)
59e6276b 17137{
60abdbed 17138 unsigned int tag;
cd30bcef 17139 unsigned int val;
59e6276b 17140
cd30bcef 17141 READ_ULEB (tag, p, end);
59e6276b
JM
17142
17143 switch (tag)
17144 {
75fa6dc1 17145 case Tag_ISA:
75fa6dc1 17146 printf (" Tag_ISA: ");
cd30bcef 17147 READ_ULEB (val, p, end);
59e6276b
JM
17148
17149 switch (val)
17150 {
75fa6dc1 17151 case C6XABI_Tag_ISA_none:
59e6276b
JM
17152 printf (_("None\n"));
17153 break;
75fa6dc1 17154 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17155 printf ("C62x\n");
17156 break;
75fa6dc1 17157 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17158 printf ("C67x\n");
17159 break;
75fa6dc1 17160 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17161 printf ("C67x+\n");
17162 break;
75fa6dc1 17163 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17164 printf ("C64x\n");
17165 break;
75fa6dc1 17166 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17167 printf ("C64x+\n");
17168 break;
75fa6dc1 17169 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17170 printf ("C674x\n");
17171 break;
17172 default:
17173 printf ("??? (%d)\n", val);
17174 break;
17175 }
17176 return p;
17177
87779176 17178 case Tag_ABI_wchar_t:
87779176 17179 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17180 READ_ULEB (val, p, end);
87779176
JM
17181 switch (val)
17182 {
17183 case 0:
17184 printf (_("Not used\n"));
17185 break;
17186 case 1:
17187 printf (_("2 bytes\n"));
17188 break;
17189 case 2:
17190 printf (_("4 bytes\n"));
17191 break;
17192 default:
17193 printf ("??? (%d)\n", val);
17194 break;
17195 }
17196 return p;
17197
17198 case Tag_ABI_stack_align_needed:
87779176 17199 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17200 READ_ULEB (val, p, end);
87779176
JM
17201 switch (val)
17202 {
17203 case 0:
17204 printf (_("8-byte\n"));
17205 break;
17206 case 1:
17207 printf (_("16-byte\n"));
17208 break;
17209 default:
17210 printf ("??? (%d)\n", val);
17211 break;
17212 }
17213 return p;
17214
17215 case Tag_ABI_stack_align_preserved:
cd30bcef 17216 READ_ULEB (val, p, end);
87779176
JM
17217 printf (" Tag_ABI_stack_align_preserved: ");
17218 switch (val)
17219 {
17220 case 0:
17221 printf (_("8-byte\n"));
17222 break;
17223 case 1:
17224 printf (_("16-byte\n"));
17225 break;
17226 default:
17227 printf ("??? (%d)\n", val);
17228 break;
17229 }
17230 return p;
17231
b5593623 17232 case Tag_ABI_DSBT:
cd30bcef 17233 READ_ULEB (val, p, end);
b5593623
JM
17234 printf (" Tag_ABI_DSBT: ");
17235 switch (val)
17236 {
17237 case 0:
17238 printf (_("DSBT addressing not used\n"));
17239 break;
17240 case 1:
17241 printf (_("DSBT addressing used\n"));
17242 break;
17243 default:
17244 printf ("??? (%d)\n", val);
17245 break;
17246 }
17247 return p;
17248
87779176 17249 case Tag_ABI_PID:
cd30bcef 17250 READ_ULEB (val, p, end);
87779176
JM
17251 printf (" Tag_ABI_PID: ");
17252 switch (val)
17253 {
17254 case 0:
17255 printf (_("Data addressing position-dependent\n"));
17256 break;
17257 case 1:
17258 printf (_("Data addressing position-independent, GOT near DP\n"));
17259 break;
17260 case 2:
17261 printf (_("Data addressing position-independent, GOT far from DP\n"));
17262 break;
17263 default:
17264 printf ("??? (%d)\n", val);
17265 break;
17266 }
17267 return p;
17268
17269 case Tag_ABI_PIC:
cd30bcef 17270 READ_ULEB (val, p, end);
87779176
JM
17271 printf (" Tag_ABI_PIC: ");
17272 switch (val)
17273 {
17274 case 0:
17275 printf (_("Code addressing position-dependent\n"));
17276 break;
17277 case 1:
17278 printf (_("Code addressing position-independent\n"));
17279 break;
17280 default:
17281 printf ("??? (%d)\n", val);
17282 break;
17283 }
17284 return p;
17285
17286 case Tag_ABI_array_object_alignment:
cd30bcef 17287 READ_ULEB (val, p, end);
87779176
JM
17288 printf (" Tag_ABI_array_object_alignment: ");
17289 switch (val)
17290 {
17291 case 0:
17292 printf (_("8-byte\n"));
17293 break;
17294 case 1:
17295 printf (_("4-byte\n"));
17296 break;
17297 case 2:
17298 printf (_("16-byte\n"));
17299 break;
17300 default:
17301 printf ("??? (%d)\n", val);
17302 break;
17303 }
17304 return p;
17305
17306 case Tag_ABI_array_object_align_expected:
cd30bcef 17307 READ_ULEB (val, p, end);
87779176
JM
17308 printf (" Tag_ABI_array_object_align_expected: ");
17309 switch (val)
17310 {
17311 case 0:
17312 printf (_("8-byte\n"));
17313 break;
17314 case 1:
17315 printf (_("4-byte\n"));
17316 break;
17317 case 2:
17318 printf (_("16-byte\n"));
17319 break;
17320 default:
17321 printf ("??? (%d)\n", val);
17322 break;
17323 }
17324 return p;
17325
3cbd1c06 17326 case Tag_ABI_compatibility:
071436c6 17327 {
cd30bcef 17328 READ_ULEB (val, p, end);
071436c6 17329 printf (" Tag_ABI_compatibility: ");
071436c6 17330 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17331 if (p < end - 1)
17332 {
17333 size_t maxlen = (end - p) - 1;
17334
17335 print_symbol ((int) maxlen, (const char *) p);
17336 p += strnlen ((char *) p, maxlen) + 1;
17337 }
17338 else
17339 {
17340 printf (_("<corrupt>"));
17341 p = (unsigned char *) end;
17342 }
071436c6 17343 putchar ('\n');
071436c6
NC
17344 return p;
17345 }
87779176
JM
17346
17347 case Tag_ABI_conformance:
071436c6 17348 {
4082ef84
NC
17349 printf (" Tag_ABI_conformance: \"");
17350 if (p < end - 1)
17351 {
17352 size_t maxlen = (end - p) - 1;
071436c6 17353
4082ef84
NC
17354 print_symbol ((int) maxlen, (const char *) p);
17355 p += strnlen ((char *) p, maxlen) + 1;
17356 }
17357 else
17358 {
17359 printf (_("<corrupt>"));
17360 p = (unsigned char *) end;
17361 }
071436c6 17362 printf ("\"\n");
071436c6
NC
17363 return p;
17364 }
59e6276b
JM
17365 }
17366
f6f0e17b
NC
17367 return display_tag_value (tag, p, end);
17368}
59e6276b 17369
f6f0e17b 17370static void
60abdbed 17371display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17372{
17373 unsigned long addr = 0;
17374 size_t bytes = end - p;
17375
feceaa59 17376 assert (end >= p);
f6f0e17b 17377 while (bytes)
87779176 17378 {
f6f0e17b
NC
17379 int j;
17380 int k;
17381 int lbytes = (bytes > 16 ? 16 : bytes);
17382
17383 printf (" 0x%8.8lx ", addr);
17384
17385 for (j = 0; j < 16; j++)
17386 {
17387 if (j < lbytes)
17388 printf ("%2.2x", p[j]);
17389 else
17390 printf (" ");
17391
17392 if ((j & 3) == 3)
17393 printf (" ");
17394 }
17395
17396 for (j = 0; j < lbytes; j++)
17397 {
17398 k = p[j];
17399 if (k >= ' ' && k < 0x7f)
17400 printf ("%c", k);
17401 else
17402 printf (".");
17403 }
17404
17405 putchar ('\n');
17406
17407 p += lbytes;
17408 bytes -= lbytes;
17409 addr += lbytes;
87779176 17410 }
59e6276b 17411
f6f0e17b 17412 putchar ('\n');
59e6276b
JM
17413}
17414
13761a11 17415static unsigned char *
b0191216 17416display_msp430_attribute (unsigned char * p,
13761a11
NC
17417 const unsigned char * const end)
17418{
60abdbed
NC
17419 unsigned int val;
17420 unsigned int tag;
13761a11 17421
cd30bcef 17422 READ_ULEB (tag, p, end);
0b4362b0 17423
13761a11
NC
17424 switch (tag)
17425 {
17426 case OFBA_MSPABI_Tag_ISA:
13761a11 17427 printf (" Tag_ISA: ");
cd30bcef 17428 READ_ULEB (val, p, end);
13761a11
NC
17429 switch (val)
17430 {
17431 case 0: printf (_("None\n")); break;
17432 case 1: printf (_("MSP430\n")); break;
17433 case 2: printf (_("MSP430X\n")); break;
17434 default: printf ("??? (%d)\n", val); break;
17435 }
17436 break;
17437
17438 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17439 printf (" Tag_Code_Model: ");
cd30bcef 17440 READ_ULEB (val, p, end);
13761a11
NC
17441 switch (val)
17442 {
17443 case 0: printf (_("None\n")); break;
17444 case 1: printf (_("Small\n")); break;
17445 case 2: printf (_("Large\n")); break;
17446 default: printf ("??? (%d)\n", val); break;
17447 }
17448 break;
17449
17450 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17451 printf (" Tag_Data_Model: ");
cd30bcef 17452 READ_ULEB (val, p, end);
13761a11
NC
17453 switch (val)
17454 {
17455 case 0: printf (_("None\n")); break;
17456 case 1: printf (_("Small\n")); break;
17457 case 2: printf (_("Large\n")); break;
17458 case 3: printf (_("Restricted Large\n")); break;
17459 default: printf ("??? (%d)\n", val); break;
17460 }
17461 break;
17462
17463 default:
17464 printf (_(" <unknown tag %d>: "), tag);
17465
17466 if (tag & 1)
17467 {
071436c6 17468 putchar ('"');
4082ef84
NC
17469 if (p < end - 1)
17470 {
17471 size_t maxlen = (end - p) - 1;
17472
17473 print_symbol ((int) maxlen, (const char *) p);
17474 p += strnlen ((char *) p, maxlen) + 1;
17475 }
17476 else
17477 {
17478 printf (_("<corrupt>"));
17479 p = (unsigned char *) end;
17480 }
071436c6 17481 printf ("\"\n");
13761a11
NC
17482 }
17483 else
17484 {
cd30bcef 17485 READ_ULEB (val, p, end);
13761a11
NC
17486 printf ("%d (0x%x)\n", val, val);
17487 }
17488 break;
17489 }
17490
4082ef84 17491 assert (p <= end);
13761a11
NC
17492 return p;
17493}
17494
c0ea7c52
JL
17495static unsigned char *
17496display_msp430_gnu_attribute (unsigned char * p,
17497 unsigned int tag,
17498 const unsigned char * const end)
17499{
17500 if (tag == Tag_GNU_MSP430_Data_Region)
17501 {
cd30bcef 17502 unsigned int val;
c0ea7c52 17503
c0ea7c52 17504 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17505 READ_ULEB (val, p, end);
c0ea7c52
JL
17506
17507 switch (val)
17508 {
17509 case Val_GNU_MSP430_Data_Region_Any:
17510 printf (_("Any Region\n"));
17511 break;
17512 case Val_GNU_MSP430_Data_Region_Lower:
17513 printf (_("Lower Region Only\n"));
17514 break;
17515 default:
cd30bcef 17516 printf ("??? (%u)\n", val);
c0ea7c52
JL
17517 }
17518 return p;
17519 }
17520 return display_tag_value (tag & 1, p, end);
17521}
17522
2dc8dd17
JW
17523struct riscv_attr_tag_t {
17524 const char *name;
cd30bcef 17525 unsigned int tag;
2dc8dd17
JW
17526};
17527
17528static struct riscv_attr_tag_t riscv_attr_tag[] =
17529{
17530#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17531 T(arch),
17532 T(priv_spec),
17533 T(priv_spec_minor),
17534 T(priv_spec_revision),
17535 T(unaligned_access),
17536 T(stack_align),
17537#undef T
17538};
17539
17540static unsigned char *
17541display_riscv_attribute (unsigned char *p,
17542 const unsigned char * const end)
17543{
cd30bcef
AM
17544 unsigned int val;
17545 unsigned int tag;
2dc8dd17
JW
17546 struct riscv_attr_tag_t *attr = NULL;
17547 unsigned i;
17548
cd30bcef 17549 READ_ULEB (tag, p, end);
2dc8dd17
JW
17550
17551 /* Find the name of attribute. */
17552 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17553 {
17554 if (riscv_attr_tag[i].tag == tag)
17555 {
17556 attr = &riscv_attr_tag[i];
17557 break;
17558 }
17559 }
17560
17561 if (attr)
17562 printf (" %s: ", attr->name);
17563 else
17564 return display_tag_value (tag, p, end);
17565
17566 switch (tag)
17567 {
17568 case Tag_RISCV_priv_spec:
17569 case Tag_RISCV_priv_spec_minor:
17570 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17571 READ_ULEB (val, p, end);
17572 printf (_("%u\n"), val);
2dc8dd17
JW
17573 break;
17574 case Tag_RISCV_unaligned_access:
cd30bcef 17575 READ_ULEB (val, p, end);
2dc8dd17
JW
17576 switch (val)
17577 {
17578 case 0:
17579 printf (_("No unaligned access\n"));
17580 break;
17581 case 1:
17582 printf (_("Unaligned access\n"));
17583 break;
17584 }
17585 break;
17586 case Tag_RISCV_stack_align:
cd30bcef
AM
17587 READ_ULEB (val, p, end);
17588 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17589 break;
17590 case Tag_RISCV_arch:
17591 p = display_tag_value (-1, p, end);
17592 break;
17593 default:
17594 return display_tag_value (tag, p, end);
17595 }
17596
17597 return p;
17598}
17599
0861f561
CQ
17600static unsigned char *
17601display_csky_attribute (unsigned char * p,
17602 const unsigned char * const end)
17603{
17604 unsigned int tag;
17605 unsigned int val;
17606 READ_ULEB (tag, p, end);
17607
17608 if (tag >= Tag_CSKY_MAX)
17609 {
17610 return display_tag_value (-1, p, end);
17611 }
17612
17613 switch (tag)
17614 {
17615 case Tag_CSKY_ARCH_NAME:
17616 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17617 return display_tag_value (-1, p, end);
17618 case Tag_CSKY_CPU_NAME:
17619 printf (" Tag_CSKY_CPU_NAME:\t\t");
17620 return display_tag_value (-1, p, end);
17621
17622 case Tag_CSKY_ISA_FLAGS:
17623 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17624 return display_tag_value (0, p, end);
17625 case Tag_CSKY_ISA_EXT_FLAGS:
17626 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17627 return display_tag_value (0, p, end);
17628
17629 case Tag_CSKY_DSP_VERSION:
17630 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17631 READ_ULEB (val, p, end);
17632 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17633 printf ("DSP Extension\n");
17634 else if (val == VAL_CSKY_DSP_VERSION_2)
17635 printf ("DSP 2.0\n");
17636 break;
17637
17638 case Tag_CSKY_VDSP_VERSION:
17639 printf (" Tag_CSKY_VDSP_VERSION:\t");
17640 READ_ULEB (val, p, end);
17641 printf ("VDSP Version %d\n", val);
17642 break;
17643
17644 case Tag_CSKY_FPU_VERSION:
17645 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17646 READ_ULEB (val, p, end);
17647 if (val == VAL_CSKY_FPU_VERSION_1)
17648 printf ("ABIV1 FPU Version 1\n");
17649 else if (val == VAL_CSKY_FPU_VERSION_2)
17650 printf ("FPU Version 2\n");
17651 break;
17652
17653 case Tag_CSKY_FPU_ABI:
17654 printf (" Tag_CSKY_FPU_ABI:\t\t");
17655 READ_ULEB (val, p, end);
17656 if (val == VAL_CSKY_FPU_ABI_HARD)
17657 printf ("Hard\n");
17658 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17659 printf ("SoftFP\n");
17660 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17661 printf ("Soft\n");
17662 break;
17663 case Tag_CSKY_FPU_ROUNDING:
17664 READ_ULEB (val, p, end);
f253158f
NC
17665 if (val == 1)
17666 {
17667 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17668 printf ("Needed\n");
17669 }
0861f561
CQ
17670 break;
17671 case Tag_CSKY_FPU_DENORMAL:
17672 READ_ULEB (val, p, end);
f253158f
NC
17673 if (val == 1)
17674 {
17675 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17676 printf ("Needed\n");
17677 }
0861f561
CQ
17678 break;
17679 case Tag_CSKY_FPU_Exception:
17680 READ_ULEB (val, p, end);
f253158f
NC
17681 if (val == 1)
17682 {
17683 printf (" Tag_CSKY_FPU_Exception:\t");
17684 printf ("Needed\n");
17685 }
0861f561
CQ
17686 break;
17687 case Tag_CSKY_FPU_NUMBER_MODULE:
17688 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17689 return display_tag_value (-1, p, end);
17690 case Tag_CSKY_FPU_HARDFP:
17691 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17692 READ_ULEB (val, p, end);
17693 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17694 printf (" Half");
17695 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17696 printf (" Single");
17697 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17698 printf (" Double");
17699 printf ("\n");
17700 break;
17701 default:
17702 return display_tag_value (tag, p, end);
17703 }
17704 return p;
17705}
17706
015dc7e1 17707static bool
dda8d76d 17708process_attributes (Filedata * filedata,
60bca95a 17709 const char * public_name,
104d59d1 17710 unsigned int proc_type,
f6f0e17b 17711 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17712 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17713{
2cf0635d 17714 Elf_Internal_Shdr * sect;
11c1ff18 17715 unsigned i;
015dc7e1 17716 bool res = true;
11c1ff18
PB
17717
17718 /* Find the section header so that we get the size. */
dda8d76d
NC
17719 for (i = 0, sect = filedata->section_headers;
17720 i < filedata->file_header.e_shnum;
11c1ff18
PB
17721 i++, sect++)
17722 {
071436c6
NC
17723 unsigned char * contents;
17724 unsigned char * p;
17725
104d59d1 17726 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17727 continue;
17728
dda8d76d 17729 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17730 sect->sh_size, _("attributes"));
60bca95a 17731 if (contents == NULL)
32ec8896 17732 {
015dc7e1 17733 res = false;
32ec8896
NC
17734 continue;
17735 }
60bca95a 17736
11c1ff18 17737 p = contents;
60abdbed
NC
17738 /* The first character is the version of the attributes.
17739 Currently only version 1, (aka 'A') is recognised here. */
17740 if (*p != 'A')
32ec8896
NC
17741 {
17742 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17743 res = false;
32ec8896 17744 }
60abdbed 17745 else
11c1ff18 17746 {
071436c6
NC
17747 bfd_vma section_len;
17748
17749 section_len = sect->sh_size - 1;
11c1ff18 17750 p++;
60bca95a 17751
071436c6 17752 while (section_len > 0)
11c1ff18 17753 {
071436c6 17754 bfd_vma attr_len;
e9847026 17755 unsigned int namelen;
015dc7e1
AM
17756 bool public_section;
17757 bool gnu_section;
11c1ff18 17758
071436c6 17759 if (section_len <= 4)
e0a31db1
NC
17760 {
17761 error (_("Tag section ends prematurely\n"));
015dc7e1 17762 res = false;
e0a31db1
NC
17763 break;
17764 }
071436c6 17765 attr_len = byte_get (p, 4);
11c1ff18 17766 p += 4;
60bca95a 17767
071436c6 17768 if (attr_len > section_len)
11c1ff18 17769 {
071436c6
NC
17770 error (_("Bad attribute length (%u > %u)\n"),
17771 (unsigned) attr_len, (unsigned) section_len);
17772 attr_len = section_len;
015dc7e1 17773 res = false;
11c1ff18 17774 }
74e1a04b 17775 /* PR 17531: file: 001-101425-0.004 */
071436c6 17776 else if (attr_len < 5)
74e1a04b 17777 {
071436c6 17778 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17779 res = false;
74e1a04b
NC
17780 break;
17781 }
e9847026 17782
071436c6
NC
17783 section_len -= attr_len;
17784 attr_len -= 4;
17785
17786 namelen = strnlen ((char *) p, attr_len) + 1;
17787 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17788 {
17789 error (_("Corrupt attribute section name\n"));
015dc7e1 17790 res = false;
e9847026
NC
17791 break;
17792 }
17793
071436c6
NC
17794 printf (_("Attribute Section: "));
17795 print_symbol (INT_MAX, (const char *) p);
17796 putchar ('\n');
60bca95a
NC
17797
17798 if (public_name && streq ((char *) p, public_name))
015dc7e1 17799 public_section = true;
11c1ff18 17800 else
015dc7e1 17801 public_section = false;
60bca95a
NC
17802
17803 if (streq ((char *) p, "gnu"))
015dc7e1 17804 gnu_section = true;
104d59d1 17805 else
015dc7e1 17806 gnu_section = false;
60bca95a 17807
11c1ff18 17808 p += namelen;
071436c6 17809 attr_len -= namelen;
e0a31db1 17810
071436c6 17811 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17812 {
e0a31db1 17813 int tag;
cd30bcef 17814 unsigned int val;
11c1ff18 17815 bfd_vma size;
071436c6 17816 unsigned char * end;
60bca95a 17817
e0a31db1 17818 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17819 if (attr_len < 6)
e0a31db1
NC
17820 {
17821 error (_("Unused bytes at end of section\n"));
015dc7e1 17822 res = false;
e0a31db1
NC
17823 section_len = 0;
17824 break;
17825 }
17826
17827 tag = *(p++);
11c1ff18 17828 size = byte_get (p, 4);
071436c6 17829 if (size > attr_len)
11c1ff18 17830 {
e9847026 17831 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17832 (unsigned) size, (unsigned) attr_len);
015dc7e1 17833 res = false;
071436c6 17834 size = attr_len;
11c1ff18 17835 }
e0a31db1
NC
17836 /* PR binutils/17531: Safe handling of corrupt files. */
17837 if (size < 6)
17838 {
17839 error (_("Bad subsection length (%u < 6)\n"),
17840 (unsigned) size);
015dc7e1 17841 res = false;
e0a31db1
NC
17842 section_len = 0;
17843 break;
17844 }
60bca95a 17845
071436c6 17846 attr_len -= size;
11c1ff18 17847 end = p + size - 1;
071436c6 17848 assert (end <= contents + sect->sh_size);
11c1ff18 17849 p += 4;
60bca95a 17850
11c1ff18
PB
17851 switch (tag)
17852 {
17853 case 1:
2b692964 17854 printf (_("File Attributes\n"));
11c1ff18
PB
17855 break;
17856 case 2:
2b692964 17857 printf (_("Section Attributes:"));
11c1ff18
PB
17858 goto do_numlist;
17859 case 3:
2b692964 17860 printf (_("Symbol Attributes:"));
1a0670f3 17861 /* Fall through. */
11c1ff18
PB
17862 do_numlist:
17863 for (;;)
17864 {
cd30bcef 17865 READ_ULEB (val, p, end);
11c1ff18
PB
17866 if (val == 0)
17867 break;
17868 printf (" %d", val);
17869 }
17870 printf ("\n");
17871 break;
17872 default:
2b692964 17873 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17874 public_section = false;
11c1ff18
PB
17875 break;
17876 }
60bca95a 17877
071436c6 17878 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17879 {
17880 while (p < end)
f6f0e17b 17881 p = display_pub_attribute (p, end);
60abdbed 17882 assert (p == end);
104d59d1 17883 }
071436c6 17884 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17885 {
17886 while (p < end)
17887 p = display_gnu_attribute (p,
f6f0e17b
NC
17888 display_proc_gnu_attribute,
17889 end);
60abdbed 17890 assert (p == end);
11c1ff18 17891 }
071436c6 17892 else if (p < end)
11c1ff18 17893 {
071436c6 17894 printf (_(" Unknown attribute:\n"));
f6f0e17b 17895 display_raw_attribute (p, end);
11c1ff18
PB
17896 p = end;
17897 }
071436c6
NC
17898 else
17899 attr_len = 0;
11c1ff18
PB
17900 }
17901 }
17902 }
d70c5fc7 17903
60bca95a 17904 free (contents);
11c1ff18 17905 }
32ec8896
NC
17906
17907 return res;
11c1ff18
PB
17908}
17909
ccb4c951
RS
17910/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17911 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17912 and return the VMA of the next entry, or -1 if there was a problem.
17913 Does not read from DATA_END or beyond. */
ccb4c951
RS
17914
17915static bfd_vma
82b1b41b
NC
17916print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17917 unsigned char * data_end)
ccb4c951
RS
17918{
17919 printf (" ");
17920 print_vma (addr, LONG_HEX);
17921 printf (" ");
17922 if (addr < pltgot + 0xfff0)
17923 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17924 else
17925 printf ("%10s", "");
17926 printf (" ");
17927 if (data == NULL)
2b692964 17928 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17929 else
17930 {
17931 bfd_vma entry;
82b1b41b 17932 unsigned char * from = data + addr - pltgot;
ccb4c951 17933
82b1b41b
NC
17934 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17935 {
17936 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17937 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17938 return (bfd_vma) -1;
17939 }
17940 else
17941 {
17942 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17943 print_vma (entry, LONG_HEX);
17944 }
ccb4c951
RS
17945 }
17946 return addr + (is_32bit_elf ? 4 : 8);
17947}
17948
861fb55a
DJ
17949/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17950 PLTGOT. Print the Address and Initial fields of an entry at VMA
17951 ADDR and return the VMA of the next entry. */
17952
17953static bfd_vma
2cf0635d 17954print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17955{
17956 printf (" ");
17957 print_vma (addr, LONG_HEX);
17958 printf (" ");
17959 if (data == NULL)
2b692964 17960 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17961 else
17962 {
17963 bfd_vma entry;
17964
17965 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17966 print_vma (entry, LONG_HEX);
17967 }
17968 return addr + (is_32bit_elf ? 4 : 8);
17969}
17970
351cdf24
MF
17971static void
17972print_mips_ases (unsigned int mask)
17973{
17974 if (mask & AFL_ASE_DSP)
17975 fputs ("\n\tDSP ASE", stdout);
17976 if (mask & AFL_ASE_DSPR2)
17977 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17978 if (mask & AFL_ASE_DSPR3)
17979 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17980 if (mask & AFL_ASE_EVA)
17981 fputs ("\n\tEnhanced VA Scheme", stdout);
17982 if (mask & AFL_ASE_MCU)
17983 fputs ("\n\tMCU (MicroController) ASE", stdout);
17984 if (mask & AFL_ASE_MDMX)
17985 fputs ("\n\tMDMX ASE", stdout);
17986 if (mask & AFL_ASE_MIPS3D)
17987 fputs ("\n\tMIPS-3D ASE", stdout);
17988 if (mask & AFL_ASE_MT)
17989 fputs ("\n\tMT ASE", stdout);
17990 if (mask & AFL_ASE_SMARTMIPS)
17991 fputs ("\n\tSmartMIPS ASE", stdout);
17992 if (mask & AFL_ASE_VIRT)
17993 fputs ("\n\tVZ ASE", stdout);
17994 if (mask & AFL_ASE_MSA)
17995 fputs ("\n\tMSA ASE", stdout);
17996 if (mask & AFL_ASE_MIPS16)
17997 fputs ("\n\tMIPS16 ASE", stdout);
17998 if (mask & AFL_ASE_MICROMIPS)
17999 fputs ("\n\tMICROMIPS ASE", stdout);
18000 if (mask & AFL_ASE_XPA)
18001 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18002 if (mask & AFL_ASE_MIPS16E2)
18003 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18004 if (mask & AFL_ASE_CRC)
18005 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18006 if (mask & AFL_ASE_GINV)
18007 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18008 if (mask & AFL_ASE_LOONGSON_MMI)
18009 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18010 if (mask & AFL_ASE_LOONGSON_CAM)
18011 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18012 if (mask & AFL_ASE_LOONGSON_EXT)
18013 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18014 if (mask & AFL_ASE_LOONGSON_EXT2)
18015 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18016 if (mask == 0)
18017 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18018 else if ((mask & ~AFL_ASE_MASK) != 0)
18019 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18020}
18021
18022static void
18023print_mips_isa_ext (unsigned int isa_ext)
18024{
18025 switch (isa_ext)
18026 {
18027 case 0:
18028 fputs (_("None"), stdout);
18029 break;
18030 case AFL_EXT_XLR:
18031 fputs ("RMI XLR", stdout);
18032 break;
2c629856
N
18033 case AFL_EXT_OCTEON3:
18034 fputs ("Cavium Networks Octeon3", stdout);
18035 break;
351cdf24
MF
18036 case AFL_EXT_OCTEON2:
18037 fputs ("Cavium Networks Octeon2", stdout);
18038 break;
18039 case AFL_EXT_OCTEONP:
18040 fputs ("Cavium Networks OcteonP", stdout);
18041 break;
351cdf24
MF
18042 case AFL_EXT_OCTEON:
18043 fputs ("Cavium Networks Octeon", stdout);
18044 break;
18045 case AFL_EXT_5900:
18046 fputs ("Toshiba R5900", stdout);
18047 break;
18048 case AFL_EXT_4650:
18049 fputs ("MIPS R4650", stdout);
18050 break;
18051 case AFL_EXT_4010:
18052 fputs ("LSI R4010", stdout);
18053 break;
18054 case AFL_EXT_4100:
18055 fputs ("NEC VR4100", stdout);
18056 break;
18057 case AFL_EXT_3900:
18058 fputs ("Toshiba R3900", stdout);
18059 break;
18060 case AFL_EXT_10000:
18061 fputs ("MIPS R10000", stdout);
18062 break;
18063 case AFL_EXT_SB1:
18064 fputs ("Broadcom SB-1", stdout);
18065 break;
18066 case AFL_EXT_4111:
18067 fputs ("NEC VR4111/VR4181", stdout);
18068 break;
18069 case AFL_EXT_4120:
18070 fputs ("NEC VR4120", stdout);
18071 break;
18072 case AFL_EXT_5400:
18073 fputs ("NEC VR5400", stdout);
18074 break;
18075 case AFL_EXT_5500:
18076 fputs ("NEC VR5500", stdout);
18077 break;
18078 case AFL_EXT_LOONGSON_2E:
18079 fputs ("ST Microelectronics Loongson 2E", stdout);
18080 break;
18081 case AFL_EXT_LOONGSON_2F:
18082 fputs ("ST Microelectronics Loongson 2F", stdout);
18083 break;
38bf472a
MR
18084 case AFL_EXT_INTERAPTIV_MR2:
18085 fputs ("Imagination interAptiv MR2", stdout);
18086 break;
351cdf24 18087 default:
00ac7aa0 18088 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18089 }
18090}
18091
32ec8896 18092static signed int
351cdf24
MF
18093get_mips_reg_size (int reg_size)
18094{
18095 return (reg_size == AFL_REG_NONE) ? 0
18096 : (reg_size == AFL_REG_32) ? 32
18097 : (reg_size == AFL_REG_64) ? 64
18098 : (reg_size == AFL_REG_128) ? 128
18099 : -1;
18100}
18101
015dc7e1 18102static bool
dda8d76d 18103process_mips_specific (Filedata * filedata)
5b18a4bc 18104{
2cf0635d 18105 Elf_Internal_Dyn * entry;
351cdf24 18106 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18107 size_t liblist_offset = 0;
18108 size_t liblistno = 0;
18109 size_t conflictsno = 0;
18110 size_t options_offset = 0;
18111 size_t conflicts_offset = 0;
861fb55a
DJ
18112 size_t pltrelsz = 0;
18113 size_t pltrel = 0;
ccb4c951 18114 bfd_vma pltgot = 0;
861fb55a
DJ
18115 bfd_vma mips_pltgot = 0;
18116 bfd_vma jmprel = 0;
ccb4c951
RS
18117 bfd_vma local_gotno = 0;
18118 bfd_vma gotsym = 0;
18119 bfd_vma symtabno = 0;
015dc7e1 18120 bool res = true;
103f02d3 18121
dda8d76d 18122 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18123 display_mips_gnu_attribute))
015dc7e1 18124 res = false;
2cf19d5c 18125
dda8d76d 18126 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18127
18128 if (sect != NULL)
18129 {
18130 Elf_External_ABIFlags_v0 *abiflags_ext;
18131 Elf_Internal_ABIFlags_v0 abiflags_in;
18132
18133 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18134 {
18135 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18136 res = false;
32ec8896 18137 }
351cdf24
MF
18138 else
18139 {
dda8d76d 18140 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18141 sect->sh_size, _("MIPS ABI Flags section"));
18142 if (abiflags_ext)
18143 {
18144 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18145 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18146 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18147 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18148 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18149 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18150 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18151 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18152 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18153 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18154 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18155
18156 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18157 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18158 if (abiflags_in.isa_rev > 1)
18159 printf ("r%d", abiflags_in.isa_rev);
18160 printf ("\nGPR size: %d",
18161 get_mips_reg_size (abiflags_in.gpr_size));
18162 printf ("\nCPR1 size: %d",
18163 get_mips_reg_size (abiflags_in.cpr1_size));
18164 printf ("\nCPR2 size: %d",
18165 get_mips_reg_size (abiflags_in.cpr2_size));
18166 fputs ("\nFP ABI: ", stdout);
18167 print_mips_fp_abi_value (abiflags_in.fp_abi);
18168 fputs ("ISA Extension: ", stdout);
18169 print_mips_isa_ext (abiflags_in.isa_ext);
18170 fputs ("\nASEs:", stdout);
18171 print_mips_ases (abiflags_in.ases);
18172 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18173 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18174 fputc ('\n', stdout);
18175 free (abiflags_ext);
18176 }
18177 }
18178 }
18179
19e6b90e 18180 /* We have a lot of special sections. Thanks SGI! */
978c4450 18181 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18182 {
18183 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18184 sect = find_section (filedata, ".got");
bbdd9a68
MR
18185 if (sect != NULL)
18186 {
18187 unsigned char *data_end;
18188 unsigned char *data;
18189 bfd_vma ent, end;
18190 int addr_size;
18191
18192 pltgot = sect->sh_addr;
18193
18194 ent = pltgot;
18195 addr_size = (is_32bit_elf ? 4 : 8);
18196 end = pltgot + sect->sh_size;
18197
dda8d76d 18198 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18199 end - pltgot, 1,
18200 _("Global Offset Table data"));
18201 /* PR 12855: Null data is handled gracefully throughout. */
18202 data_end = data + (end - pltgot);
18203
18204 printf (_("\nStatic GOT:\n"));
18205 printf (_(" Canonical gp value: "));
18206 print_vma (ent + 0x7ff0, LONG_HEX);
18207 printf ("\n\n");
18208
18209 /* In a dynamic binary GOT[0] is reserved for the dynamic
18210 loader to store the lazy resolver pointer, however in
18211 a static binary it may well have been omitted and GOT
18212 reduced to a table of addresses.
18213 PR 21344: Check for the entry being fully available
18214 before fetching it. */
18215 if (data
18216 && data + ent - pltgot + addr_size <= data_end
18217 && byte_get (data + ent - pltgot, addr_size) == 0)
18218 {
18219 printf (_(" Reserved entries:\n"));
18220 printf (_(" %*s %10s %*s\n"),
18221 addr_size * 2, _("Address"), _("Access"),
18222 addr_size * 2, _("Value"));
18223 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18224 printf ("\n");
18225 if (ent == (bfd_vma) -1)
18226 goto sgot_print_fail;
18227
18228 /* Check for the MSB of GOT[1] being set, identifying a
18229 GNU object. This entry will be used by some runtime
18230 loaders, to store the module pointer. Otherwise this
18231 is an ordinary local entry.
18232 PR 21344: Check for the entry being fully available
18233 before fetching it. */
18234 if (data
18235 && data + ent - pltgot + addr_size <= data_end
18236 && (byte_get (data + ent - pltgot, addr_size)
18237 >> (addr_size * 8 - 1)) != 0)
18238 {
18239 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18240 printf ("\n");
18241 if (ent == (bfd_vma) -1)
18242 goto sgot_print_fail;
18243 }
18244 printf ("\n");
18245 }
18246
f17e9d8a 18247 if (data != NULL && ent < end)
bbdd9a68
MR
18248 {
18249 printf (_(" Local entries:\n"));
18250 printf (" %*s %10s %*s\n",
18251 addr_size * 2, _("Address"), _("Access"),
18252 addr_size * 2, _("Value"));
18253 while (ent < end)
18254 {
18255 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18256 printf ("\n");
18257 if (ent == (bfd_vma) -1)
18258 goto sgot_print_fail;
18259 }
18260 printf ("\n");
18261 }
18262
18263 sgot_print_fail:
9db70fc3 18264 free (data);
bbdd9a68
MR
18265 }
18266 return res;
18267 }
252b5132 18268
978c4450 18269 for (entry = filedata->dynamic_section;
071436c6 18270 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18271 (entry < filedata->dynamic_section + filedata->dynamic_nent
18272 && entry->d_tag != DT_NULL);
071436c6 18273 ++entry)
252b5132
RH
18274 switch (entry->d_tag)
18275 {
18276 case DT_MIPS_LIBLIST:
d93f0186 18277 liblist_offset
dda8d76d 18278 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18279 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18280 break;
18281 case DT_MIPS_LIBLISTNO:
18282 liblistno = entry->d_un.d_val;
18283 break;
18284 case DT_MIPS_OPTIONS:
dda8d76d 18285 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18286 break;
18287 case DT_MIPS_CONFLICT:
d93f0186 18288 conflicts_offset
dda8d76d 18289 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18290 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18291 break;
18292 case DT_MIPS_CONFLICTNO:
18293 conflictsno = entry->d_un.d_val;
18294 break;
ccb4c951 18295 case DT_PLTGOT:
861fb55a
DJ
18296 pltgot = entry->d_un.d_ptr;
18297 break;
ccb4c951
RS
18298 case DT_MIPS_LOCAL_GOTNO:
18299 local_gotno = entry->d_un.d_val;
18300 break;
18301 case DT_MIPS_GOTSYM:
18302 gotsym = entry->d_un.d_val;
18303 break;
18304 case DT_MIPS_SYMTABNO:
18305 symtabno = entry->d_un.d_val;
18306 break;
861fb55a
DJ
18307 case DT_MIPS_PLTGOT:
18308 mips_pltgot = entry->d_un.d_ptr;
18309 break;
18310 case DT_PLTREL:
18311 pltrel = entry->d_un.d_val;
18312 break;
18313 case DT_PLTRELSZ:
18314 pltrelsz = entry->d_un.d_val;
18315 break;
18316 case DT_JMPREL:
18317 jmprel = entry->d_un.d_ptr;
18318 break;
252b5132
RH
18319 default:
18320 break;
18321 }
18322
18323 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18324 {
2cf0635d 18325 Elf32_External_Lib * elib;
252b5132
RH
18326 size_t cnt;
18327
dda8d76d 18328 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18329 sizeof (Elf32_External_Lib),
18330 liblistno,
18331 _("liblist section data"));
a6e9f9df 18332 if (elib)
252b5132 18333 {
d3a49aa8
AM
18334 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18335 "\nSection '.liblist' contains %lu entries:\n",
18336 (unsigned long) liblistno),
a6e9f9df 18337 (unsigned long) liblistno);
2b692964 18338 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18339 stdout);
18340
18341 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18342 {
a6e9f9df 18343 Elf32_Lib liblist;
91d6fa6a 18344 time_t atime;
d5b07ef4 18345 char timebuf[128];
2cf0635d 18346 struct tm * tmp;
a6e9f9df
AM
18347
18348 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18349 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18350 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18351 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18352 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18353
91d6fa6a 18354 tmp = gmtime (&atime);
e9e44622
JJ
18355 snprintf (timebuf, sizeof (timebuf),
18356 "%04u-%02u-%02uT%02u:%02u:%02u",
18357 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18358 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18359
31104126 18360 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18361 if (valid_dynamic_name (filedata, liblist.l_name))
18362 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18363 else
2b692964 18364 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18365 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18366 liblist.l_version);
a6e9f9df
AM
18367
18368 if (liblist.l_flags == 0)
2b692964 18369 puts (_(" NONE"));
a6e9f9df
AM
18370 else
18371 {
18372 static const struct
252b5132 18373 {
2cf0635d 18374 const char * name;
a6e9f9df 18375 int bit;
252b5132 18376 }
a6e9f9df
AM
18377 l_flags_vals[] =
18378 {
18379 { " EXACT_MATCH", LL_EXACT_MATCH },
18380 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18381 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18382 { " EXPORTS", LL_EXPORTS },
18383 { " DELAY_LOAD", LL_DELAY_LOAD },
18384 { " DELTA", LL_DELTA }
18385 };
18386 int flags = liblist.l_flags;
18387 size_t fcnt;
18388
60bca95a 18389 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18390 if ((flags & l_flags_vals[fcnt].bit) != 0)
18391 {
18392 fputs (l_flags_vals[fcnt].name, stdout);
18393 flags ^= l_flags_vals[fcnt].bit;
18394 }
18395 if (flags != 0)
18396 printf (" %#x", (unsigned int) flags);
252b5132 18397
a6e9f9df
AM
18398 puts ("");
18399 }
252b5132 18400 }
252b5132 18401
a6e9f9df
AM
18402 free (elib);
18403 }
32ec8896 18404 else
015dc7e1 18405 res = false;
252b5132
RH
18406 }
18407
18408 if (options_offset != 0)
18409 {
2cf0635d 18410 Elf_External_Options * eopt;
252b5132
RH
18411 size_t offset;
18412 int cnt;
18413
18414 /* Find the section header so that we get the size. */
dda8d76d 18415 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18416 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18417 if (sect == NULL)
18418 {
18419 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18420 return false;
071436c6 18421 }
7fc0c668
NC
18422 /* PR 24243 */
18423 if (sect->sh_size < sizeof (* eopt))
18424 {
18425 error (_("The MIPS options section is too small.\n"));
015dc7e1 18426 return false;
7fc0c668 18427 }
252b5132 18428
dda8d76d 18429 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18430 sect->sh_size, _("options"));
a6e9f9df 18431 if (eopt)
252b5132 18432 {
fd17d1e6 18433 Elf_Internal_Options option;
76da6bbe 18434
a6e9f9df 18435 offset = cnt = 0;
82b1b41b 18436 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18437 {
2cf0635d 18438 Elf_External_Options * eoption;
fd17d1e6 18439 unsigned int optsize;
252b5132 18440
a6e9f9df 18441 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18442
fd17d1e6 18443 optsize = BYTE_GET (eoption->size);
76da6bbe 18444
82b1b41b 18445 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18446 if (optsize < sizeof (* eopt)
18447 || optsize > sect->sh_size - offset)
82b1b41b 18448 {
645f43a8 18449 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18450 optsize);
645f43a8 18451 free (eopt);
015dc7e1 18452 return false;
82b1b41b 18453 }
fd17d1e6 18454 offset += optsize;
a6e9f9df
AM
18455 ++cnt;
18456 }
252b5132 18457
d3a49aa8
AM
18458 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18459 "\nSection '%s' contains %d entries:\n",
18460 cnt),
dda8d76d 18461 printable_section_name (filedata, sect), cnt);
76da6bbe 18462
82b1b41b 18463 offset = 0;
a6e9f9df 18464 while (cnt-- > 0)
252b5132 18465 {
a6e9f9df 18466 size_t len;
fd17d1e6
AM
18467 Elf_External_Options * eoption;
18468
18469 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18470
18471 option.kind = BYTE_GET (eoption->kind);
18472 option.size = BYTE_GET (eoption->size);
18473 option.section = BYTE_GET (eoption->section);
18474 option.info = BYTE_GET (eoption->info);
a6e9f9df 18475
fd17d1e6 18476 switch (option.kind)
252b5132 18477 {
a6e9f9df
AM
18478 case ODK_NULL:
18479 /* This shouldn't happen. */
d0c4e780 18480 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18481 option.section, option.info);
a6e9f9df 18482 break;
2e6be59c 18483
a6e9f9df
AM
18484 case ODK_REGINFO:
18485 printf (" REGINFO ");
dda8d76d 18486 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18487 {
2cf0635d 18488 Elf32_External_RegInfo * ereg;
b34976b6 18489 Elf32_RegInfo reginfo;
a6e9f9df 18490
2e6be59c 18491 /* 32bit form. */
fd17d1e6
AM
18492 if (option.size < (sizeof (Elf_External_Options)
18493 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18494 {
18495 printf (_("<corrupt>\n"));
18496 error (_("Truncated MIPS REGINFO option\n"));
18497 cnt = 0;
18498 break;
18499 }
18500
fd17d1e6 18501 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18502
a6e9f9df
AM
18503 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18504 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18505 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18506 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18507 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18508 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18509
d0c4e780
AM
18510 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18511 reginfo.ri_gprmask, reginfo.ri_gp_value);
18512 printf (" "
18513 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18514 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18515 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18516 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18517 }
18518 else
18519 {
18520 /* 64 bit form. */
2cf0635d 18521 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18522 Elf64_Internal_RegInfo reginfo;
18523
fd17d1e6
AM
18524 if (option.size < (sizeof (Elf_External_Options)
18525 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18526 {
18527 printf (_("<corrupt>\n"));
18528 error (_("Truncated MIPS REGINFO option\n"));
18529 cnt = 0;
18530 break;
18531 }
18532
fd17d1e6 18533 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18534 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18535 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18536 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18537 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18538 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18539 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18540
d0c4e780
AM
18541 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18542 reginfo.ri_gprmask, reginfo.ri_gp_value);
18543 printf (" "
18544 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18545 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18546 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18547 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18548 }
fd17d1e6 18549 offset += option.size;
a6e9f9df 18550 continue;
2e6be59c 18551
a6e9f9df
AM
18552 case ODK_EXCEPTIONS:
18553 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18554 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18555 fputs (") fpe_max(", stdout);
fd17d1e6 18556 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18557 fputs (")", stdout);
18558
fd17d1e6 18559 if (option.info & OEX_PAGE0)
a6e9f9df 18560 fputs (" PAGE0", stdout);
fd17d1e6 18561 if (option.info & OEX_SMM)
a6e9f9df 18562 fputs (" SMM", stdout);
fd17d1e6 18563 if (option.info & OEX_FPDBUG)
a6e9f9df 18564 fputs (" FPDBUG", stdout);
fd17d1e6 18565 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18566 fputs (" DISMISS", stdout);
18567 break;
2e6be59c 18568
a6e9f9df
AM
18569 case ODK_PAD:
18570 fputs (" PAD ", stdout);
fd17d1e6 18571 if (option.info & OPAD_PREFIX)
a6e9f9df 18572 fputs (" PREFIX", stdout);
fd17d1e6 18573 if (option.info & OPAD_POSTFIX)
a6e9f9df 18574 fputs (" POSTFIX", stdout);
fd17d1e6 18575 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18576 fputs (" SYMBOL", stdout);
18577 break;
2e6be59c 18578
a6e9f9df
AM
18579 case ODK_HWPATCH:
18580 fputs (" HWPATCH ", stdout);
fd17d1e6 18581 if (option.info & OHW_R4KEOP)
a6e9f9df 18582 fputs (" R4KEOP", stdout);
fd17d1e6 18583 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18584 fputs (" R8KPFETCH", stdout);
fd17d1e6 18585 if (option.info & OHW_R5KEOP)
a6e9f9df 18586 fputs (" R5KEOP", stdout);
fd17d1e6 18587 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18588 fputs (" R5KCVTL", stdout);
18589 break;
2e6be59c 18590
a6e9f9df
AM
18591 case ODK_FILL:
18592 fputs (" FILL ", stdout);
18593 /* XXX Print content of info word? */
18594 break;
2e6be59c 18595
a6e9f9df
AM
18596 case ODK_TAGS:
18597 fputs (" TAGS ", stdout);
18598 /* XXX Print content of info word? */
18599 break;
2e6be59c 18600
a6e9f9df
AM
18601 case ODK_HWAND:
18602 fputs (" HWAND ", stdout);
fd17d1e6 18603 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18604 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18605 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18606 fputs (" R4KEOP_CLEAN", stdout);
18607 break;
2e6be59c 18608
a6e9f9df
AM
18609 case ODK_HWOR:
18610 fputs (" HWOR ", stdout);
fd17d1e6 18611 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18612 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18613 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18614 fputs (" R4KEOP_CLEAN", stdout);
18615 break;
2e6be59c 18616
a6e9f9df 18617 case ODK_GP_GROUP:
d0c4e780 18618 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18619 option.info & OGP_GROUP,
18620 (option.info & OGP_SELF) >> 16);
a6e9f9df 18621 break;
2e6be59c 18622
a6e9f9df 18623 case ODK_IDENT:
d0c4e780 18624 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18625 option.info & OGP_GROUP,
18626 (option.info & OGP_SELF) >> 16);
a6e9f9df 18627 break;
2e6be59c 18628
a6e9f9df
AM
18629 default:
18630 /* This shouldn't happen. */
d0c4e780 18631 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18632 option.kind, option.section, option.info);
a6e9f9df 18633 break;
252b5132 18634 }
a6e9f9df 18635
2cf0635d 18636 len = sizeof (* eopt);
fd17d1e6 18637 while (len < option.size)
82b1b41b 18638 {
fd17d1e6 18639 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18640
82b1b41b
NC
18641 if (ISPRINT (datum))
18642 printf ("%c", datum);
18643 else
18644 printf ("\\%03o", datum);
18645 len ++;
18646 }
a6e9f9df 18647 fputs ("\n", stdout);
82b1b41b 18648
fd17d1e6 18649 offset += option.size;
252b5132 18650 }
a6e9f9df 18651 free (eopt);
252b5132 18652 }
32ec8896 18653 else
015dc7e1 18654 res = false;
252b5132
RH
18655 }
18656
18657 if (conflicts_offset != 0 && conflictsno != 0)
18658 {
2cf0635d 18659 Elf32_Conflict * iconf;
252b5132
RH
18660 size_t cnt;
18661
978c4450 18662 if (filedata->dynamic_symbols == NULL)
252b5132 18663 {
591a748a 18664 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18665 return false;
252b5132
RH
18666 }
18667
7296a62a
NC
18668 /* PR 21345 - print a slightly more helpful error message
18669 if we are sure that the cmalloc will fail. */
645f43a8 18670 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18671 {
18672 error (_("Overlarge number of conflicts detected: %lx\n"),
18673 (long) conflictsno);
015dc7e1 18674 return false;
7296a62a
NC
18675 }
18676
3f5e193b 18677 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18678 if (iconf == NULL)
18679 {
8b73c356 18680 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18681 return false;
252b5132
RH
18682 }
18683
9ea033b2 18684 if (is_32bit_elf)
252b5132 18685 {
2cf0635d 18686 Elf32_External_Conflict * econf32;
a6e9f9df 18687
3f5e193b 18688 econf32 = (Elf32_External_Conflict *)
95099889
AM
18689 get_data (NULL, filedata, conflicts_offset,
18690 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18691 if (!econf32)
5a814d6d
AM
18692 {
18693 free (iconf);
015dc7e1 18694 return false;
5a814d6d 18695 }
252b5132
RH
18696
18697 for (cnt = 0; cnt < conflictsno; ++cnt)
18698 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18699
18700 free (econf32);
252b5132
RH
18701 }
18702 else
18703 {
2cf0635d 18704 Elf64_External_Conflict * econf64;
a6e9f9df 18705
3f5e193b 18706 econf64 = (Elf64_External_Conflict *)
95099889
AM
18707 get_data (NULL, filedata, conflicts_offset,
18708 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18709 if (!econf64)
5a814d6d
AM
18710 {
18711 free (iconf);
015dc7e1 18712 return false;
5a814d6d 18713 }
252b5132
RH
18714
18715 for (cnt = 0; cnt < conflictsno; ++cnt)
18716 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18717
18718 free (econf64);
252b5132
RH
18719 }
18720
d3a49aa8
AM
18721 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18722 "\nSection '.conflict' contains %lu entries:\n",
18723 (unsigned long) conflictsno),
c7e7ca54 18724 (unsigned long) conflictsno);
252b5132
RH
18725 puts (_(" Num: Index Value Name"));
18726
18727 for (cnt = 0; cnt < conflictsno; ++cnt)
18728 {
b34976b6 18729 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18730
978c4450 18731 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18732 printf (_("<corrupt symbol index>"));
d79b3d50 18733 else
e0a31db1
NC
18734 {
18735 Elf_Internal_Sym * psym;
18736
978c4450 18737 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18738 print_vma (psym->st_value, FULL_HEX);
18739 putchar (' ');
84714f86
AM
18740 if (valid_dynamic_name (filedata, psym->st_name))
18741 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18742 else
18743 printf (_("<corrupt: %14ld>"), psym->st_name);
18744 }
31104126 18745 putchar ('\n');
252b5132
RH
18746 }
18747
252b5132
RH
18748 free (iconf);
18749 }
18750
ccb4c951
RS
18751 if (pltgot != 0 && local_gotno != 0)
18752 {
91d6fa6a 18753 bfd_vma ent, local_end, global_end;
bbeee7ea 18754 size_t i, offset;
2cf0635d 18755 unsigned char * data;
82b1b41b 18756 unsigned char * data_end;
bbeee7ea 18757 int addr_size;
ccb4c951 18758
91d6fa6a 18759 ent = pltgot;
ccb4c951
RS
18760 addr_size = (is_32bit_elf ? 4 : 8);
18761 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18762
74e1a04b
NC
18763 /* PR binutils/17533 file: 012-111227-0.004 */
18764 if (symtabno < gotsym)
18765 {
18766 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18767 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18768 return false;
74e1a04b 18769 }
82b1b41b 18770
74e1a04b 18771 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18772 /* PR 17531: file: 54c91a34. */
18773 if (global_end < local_end)
18774 {
18775 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18776 return false;
82b1b41b 18777 }
948f632f 18778
dda8d76d
NC
18779 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18780 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18781 global_end - pltgot, 1,
18782 _("Global Offset Table data"));
919383ac 18783 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18784 data_end = data + (global_end - pltgot);
59245841 18785
ccb4c951
RS
18786 printf (_("\nPrimary GOT:\n"));
18787 printf (_(" Canonical gp value: "));
18788 print_vma (pltgot + 0x7ff0, LONG_HEX);
18789 printf ("\n\n");
18790
18791 printf (_(" Reserved entries:\n"));
18792 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18793 addr_size * 2, _("Address"), _("Access"),
18794 addr_size * 2, _("Initial"));
82b1b41b 18795 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18796 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18797 if (ent == (bfd_vma) -1)
18798 goto got_print_fail;
75ec1fdb 18799
c4ab9505
MR
18800 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18801 This entry will be used by some runtime loaders, to store the
18802 module pointer. Otherwise this is an ordinary local entry.
18803 PR 21344: Check for the entry being fully available before
18804 fetching it. */
18805 if (data
18806 && data + ent - pltgot + addr_size <= data_end
18807 && (byte_get (data + ent - pltgot, addr_size)
18808 >> (addr_size * 8 - 1)) != 0)
18809 {
18810 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18811 printf (_(" Module pointer (GNU extension)\n"));
18812 if (ent == (bfd_vma) -1)
18813 goto got_print_fail;
ccb4c951
RS
18814 }
18815 printf ("\n");
18816
f17e9d8a 18817 if (data != NULL && ent < local_end)
ccb4c951
RS
18818 {
18819 printf (_(" Local entries:\n"));
cc5914eb 18820 printf (" %*s %10s %*s\n",
2b692964
NC
18821 addr_size * 2, _("Address"), _("Access"),
18822 addr_size * 2, _("Initial"));
91d6fa6a 18823 while (ent < local_end)
ccb4c951 18824 {
82b1b41b 18825 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18826 printf ("\n");
82b1b41b
NC
18827 if (ent == (bfd_vma) -1)
18828 goto got_print_fail;
ccb4c951
RS
18829 }
18830 printf ("\n");
18831 }
18832
f17e9d8a 18833 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18834 {
18835 int sym_width;
18836
18837 printf (_(" Global entries:\n"));
cc5914eb 18838 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18839 addr_size * 2, _("Address"),
18840 _("Access"),
2b692964 18841 addr_size * 2, _("Initial"),
9cf03b7e
NC
18842 addr_size * 2, _("Sym.Val."),
18843 _("Type"),
18844 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18845 _("Ndx"), _("Name"));
0b4362b0 18846
ccb4c951 18847 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18848
ccb4c951
RS
18849 for (i = gotsym; i < symtabno; i++)
18850 {
82b1b41b 18851 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18852 printf (" ");
e0a31db1 18853
978c4450 18854 if (filedata->dynamic_symbols == NULL)
e0a31db1 18855 printf (_("<no dynamic symbols>"));
978c4450 18856 else if (i < filedata->num_dynamic_syms)
e0a31db1 18857 {
978c4450 18858 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18859
18860 print_vma (psym->st_value, LONG_HEX);
18861 printf (" %-7s %3s ",
dda8d76d
NC
18862 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18863 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18864
84714f86 18865 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18866 print_symbol (sym_width,
84714f86 18867 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18868 else
18869 printf (_("<corrupt: %14ld>"), psym->st_name);
18870 }
ccb4c951 18871 else
7fc5ac57
JBG
18872 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18873 (unsigned long) i);
e0a31db1 18874
ccb4c951 18875 printf ("\n");
82b1b41b
NC
18876 if (ent == (bfd_vma) -1)
18877 break;
ccb4c951
RS
18878 }
18879 printf ("\n");
18880 }
18881
82b1b41b 18882 got_print_fail:
9db70fc3 18883 free (data);
ccb4c951
RS
18884 }
18885
861fb55a
DJ
18886 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18887 {
91d6fa6a 18888 bfd_vma ent, end;
861fb55a
DJ
18889 size_t offset, rel_offset;
18890 unsigned long count, i;
2cf0635d 18891 unsigned char * data;
861fb55a 18892 int addr_size, sym_width;
2cf0635d 18893 Elf_Internal_Rela * rels;
861fb55a 18894
dda8d76d 18895 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18896 if (pltrel == DT_RELA)
18897 {
dda8d76d 18898 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18899 return false;
861fb55a
DJ
18900 }
18901 else
18902 {
dda8d76d 18903 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18904 return false;
861fb55a
DJ
18905 }
18906
91d6fa6a 18907 ent = mips_pltgot;
861fb55a
DJ
18908 addr_size = (is_32bit_elf ? 4 : 8);
18909 end = mips_pltgot + (2 + count) * addr_size;
18910
dda8d76d
NC
18911 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18912 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18913 1, _("Procedure Linkage Table data"));
59245841 18914 if (data == NULL)
288f0ba2
AM
18915 {
18916 free (rels);
015dc7e1 18917 return false;
288f0ba2 18918 }
59245841 18919
9cf03b7e 18920 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18921 printf (_(" Reserved entries:\n"));
18922 printf (_(" %*s %*s Purpose\n"),
2b692964 18923 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18924 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18925 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18926 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18927 printf (_(" Module pointer\n"));
861fb55a
DJ
18928 printf ("\n");
18929
18930 printf (_(" Entries:\n"));
cc5914eb 18931 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18932 addr_size * 2, _("Address"),
18933 addr_size * 2, _("Initial"),
18934 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18935 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18936 for (i = 0; i < count; i++)
18937 {
df97ab2a 18938 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18939
91d6fa6a 18940 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18941 printf (" ");
e0a31db1 18942
978c4450 18943 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18944 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18945 else
e0a31db1 18946 {
978c4450 18947 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18948
18949 print_vma (psym->st_value, LONG_HEX);
18950 printf (" %-7s %3s ",
dda8d76d
NC
18951 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18952 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 18953 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18954 print_symbol (sym_width,
84714f86 18955 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18956 else
18957 printf (_("<corrupt: %14ld>"), psym->st_name);
18958 }
861fb55a
DJ
18959 printf ("\n");
18960 }
18961 printf ("\n");
18962
9db70fc3 18963 free (data);
861fb55a
DJ
18964 free (rels);
18965 }
18966
32ec8896 18967 return res;
252b5132
RH
18968}
18969
015dc7e1 18970static bool
dda8d76d 18971process_nds32_specific (Filedata * filedata)
35c08157
KLC
18972{
18973 Elf_Internal_Shdr *sect = NULL;
18974
dda8d76d 18975 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18976 if (sect != NULL && sect->sh_size >= 4)
35c08157 18977 {
9c7b8e9b
AM
18978 unsigned char *buf;
18979 unsigned int flag;
35c08157
KLC
18980
18981 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18982 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18983 _("NDS32 elf flags section"));
35c08157 18984
9c7b8e9b 18985 if (buf == NULL)
015dc7e1 18986 return false;
32ec8896 18987
9c7b8e9b
AM
18988 flag = byte_get (buf, 4);
18989 free (buf);
18990 switch (flag & 0x3)
35c08157
KLC
18991 {
18992 case 0:
18993 printf ("(VEC_SIZE):\tNo entry.\n");
18994 break;
18995 case 1:
18996 printf ("(VEC_SIZE):\t4 bytes\n");
18997 break;
18998 case 2:
18999 printf ("(VEC_SIZE):\t16 bytes\n");
19000 break;
19001 case 3:
19002 printf ("(VEC_SIZE):\treserved\n");
19003 break;
19004 }
19005 }
19006
015dc7e1 19007 return true;
35c08157
KLC
19008}
19009
015dc7e1 19010static bool
dda8d76d 19011process_gnu_liblist (Filedata * filedata)
047b2264 19012{
2cf0635d
NC
19013 Elf_Internal_Shdr * section;
19014 Elf_Internal_Shdr * string_sec;
19015 Elf32_External_Lib * elib;
19016 char * strtab;
c256ffe7 19017 size_t strtab_size;
047b2264 19018 size_t cnt;
d3a49aa8 19019 unsigned long num_liblist;
047b2264 19020 unsigned i;
015dc7e1 19021 bool res = true;
047b2264
JJ
19022
19023 if (! do_arch)
015dc7e1 19024 return true;
047b2264 19025
dda8d76d
NC
19026 for (i = 0, section = filedata->section_headers;
19027 i < filedata->file_header.e_shnum;
b34976b6 19028 i++, section++)
047b2264
JJ
19029 {
19030 switch (section->sh_type)
19031 {
19032 case SHT_GNU_LIBLIST:
dda8d76d 19033 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19034 break;
19035
3f5e193b 19036 elib = (Elf32_External_Lib *)
dda8d76d 19037 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19038 _("liblist section data"));
047b2264
JJ
19039
19040 if (elib == NULL)
32ec8896 19041 {
015dc7e1 19042 res = false;
32ec8896
NC
19043 break;
19044 }
047b2264 19045
dda8d76d
NC
19046 string_sec = filedata->section_headers + section->sh_link;
19047 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19048 string_sec->sh_size,
19049 _("liblist string table"));
047b2264
JJ
19050 if (strtab == NULL
19051 || section->sh_entsize != sizeof (Elf32_External_Lib))
19052 {
19053 free (elib);
2842702f 19054 free (strtab);
015dc7e1 19055 res = false;
047b2264
JJ
19056 break;
19057 }
59245841 19058 strtab_size = string_sec->sh_size;
047b2264 19059
d3a49aa8
AM
19060 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19061 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19062 "\nLibrary list section '%s' contains %lu entries:\n",
19063 num_liblist),
dda8d76d 19064 printable_section_name (filedata, section),
d3a49aa8 19065 num_liblist);
047b2264 19066
2b692964 19067 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19068
19069 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19070 ++cnt)
19071 {
19072 Elf32_Lib liblist;
91d6fa6a 19073 time_t atime;
d5b07ef4 19074 char timebuf[128];
2cf0635d 19075 struct tm * tmp;
047b2264
JJ
19076
19077 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19078 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19079 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19080 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19081 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19082
91d6fa6a 19083 tmp = gmtime (&atime);
e9e44622
JJ
19084 snprintf (timebuf, sizeof (timebuf),
19085 "%04u-%02u-%02uT%02u:%02u:%02u",
19086 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19087 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19088
19089 printf ("%3lu: ", (unsigned long) cnt);
19090 if (do_wide)
c256ffe7 19091 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19092 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19093 else
c256ffe7 19094 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19095 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19096 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19097 liblist.l_version, liblist.l_flags);
19098 }
19099
19100 free (elib);
2842702f 19101 free (strtab);
047b2264
JJ
19102 }
19103 }
19104
32ec8896 19105 return res;
047b2264
JJ
19106}
19107
9437c45b 19108static const char *
dda8d76d 19109get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19110{
19111 static char buff[64];
103f02d3 19112
dda8d76d 19113 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19114 switch (e_type)
19115 {
57346661 19116 case NT_AUXV:
1ec5cd37 19117 return _("NT_AUXV (auxiliary vector)");
57346661 19118 case NT_PRSTATUS:
1ec5cd37 19119 return _("NT_PRSTATUS (prstatus structure)");
57346661 19120 case NT_FPREGSET:
1ec5cd37 19121 return _("NT_FPREGSET (floating point registers)");
57346661 19122 case NT_PRPSINFO:
1ec5cd37 19123 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19124 case NT_TASKSTRUCT:
1ec5cd37 19125 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19126 case NT_GDB_TDESC:
19127 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19128 case NT_PRXFPREG:
1ec5cd37 19129 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19130 case NT_PPC_VMX:
19131 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19132 case NT_PPC_VSX:
19133 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19134 case NT_PPC_TAR:
19135 return _("NT_PPC_TAR (ppc TAR register)");
19136 case NT_PPC_PPR:
19137 return _("NT_PPC_PPR (ppc PPR register)");
19138 case NT_PPC_DSCR:
19139 return _("NT_PPC_DSCR (ppc DSCR register)");
19140 case NT_PPC_EBB:
19141 return _("NT_PPC_EBB (ppc EBB registers)");
19142 case NT_PPC_PMU:
19143 return _("NT_PPC_PMU (ppc PMU registers)");
19144 case NT_PPC_TM_CGPR:
19145 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19146 case NT_PPC_TM_CFPR:
19147 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19148 case NT_PPC_TM_CVMX:
19149 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19150 case NT_PPC_TM_CVSX:
3fd21718 19151 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19152 case NT_PPC_TM_SPR:
19153 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19154 case NT_PPC_TM_CTAR:
19155 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19156 case NT_PPC_TM_CPPR:
19157 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19158 case NT_PPC_TM_CDSCR:
19159 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19160 case NT_386_TLS:
19161 return _("NT_386_TLS (x86 TLS information)");
19162 case NT_386_IOPERM:
19163 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19164 case NT_X86_XSTATE:
19165 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19166 case NT_X86_CET:
19167 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19168 case NT_S390_HIGH_GPRS:
19169 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19170 case NT_S390_TIMER:
19171 return _("NT_S390_TIMER (s390 timer register)");
19172 case NT_S390_TODCMP:
19173 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19174 case NT_S390_TODPREG:
19175 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19176 case NT_S390_CTRS:
19177 return _("NT_S390_CTRS (s390 control registers)");
19178 case NT_S390_PREFIX:
19179 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19180 case NT_S390_LAST_BREAK:
19181 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19182 case NT_S390_SYSTEM_CALL:
19183 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19184 case NT_S390_TDB:
19185 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19186 case NT_S390_VXRS_LOW:
19187 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19188 case NT_S390_VXRS_HIGH:
19189 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19190 case NT_S390_GS_CB:
19191 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19192 case NT_S390_GS_BC:
19193 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19194 case NT_ARM_VFP:
19195 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19196 case NT_ARM_TLS:
19197 return _("NT_ARM_TLS (AArch TLS registers)");
19198 case NT_ARM_HW_BREAK:
19199 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19200 case NT_ARM_HW_WATCH:
19201 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
19202 case NT_ARM_SVE:
19203 return _("NT_ARM_SVE (AArch SVE registers)");
19204 case NT_ARM_PAC_MASK:
19205 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19206 case NT_ARM_PACA_KEYS:
19207 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19208 case NT_ARM_PACG_KEYS:
19209 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19210 case NT_ARM_TAGGED_ADDR_CTRL:
19211 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19212 case NT_ARM_PAC_ENABLED_KEYS:
19213 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19214 case NT_ARC_V2:
19215 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19216 case NT_RISCV_CSR:
19217 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19218 case NT_PSTATUS:
1ec5cd37 19219 return _("NT_PSTATUS (pstatus structure)");
57346661 19220 case NT_FPREGS:
1ec5cd37 19221 return _("NT_FPREGS (floating point registers)");
57346661 19222 case NT_PSINFO:
1ec5cd37 19223 return _("NT_PSINFO (psinfo structure)");
57346661 19224 case NT_LWPSTATUS:
1ec5cd37 19225 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19226 case NT_LWPSINFO:
1ec5cd37 19227 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19228 case NT_WIN32PSTATUS:
1ec5cd37 19229 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19230 case NT_SIGINFO:
19231 return _("NT_SIGINFO (siginfo_t data)");
19232 case NT_FILE:
19233 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19234 default:
19235 break;
19236 }
19237 else
19238 switch (e_type)
19239 {
19240 case NT_VERSION:
19241 return _("NT_VERSION (version)");
19242 case NT_ARCH:
19243 return _("NT_ARCH (architecture)");
9ef920e9 19244 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19245 return _("OPEN");
9ef920e9 19246 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19247 return _("func");
c8795e1f
NC
19248 case NT_GO_BUILDID:
19249 return _("GO BUILDID");
3ac925fc
LB
19250 case FDO_PACKAGING_METADATA:
19251 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19252 default:
19253 break;
19254 }
19255
e9e44622 19256 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19257 return buff;
779fe533
NC
19258}
19259
015dc7e1 19260static bool
9ece1fa9
TT
19261print_core_note (Elf_Internal_Note *pnote)
19262{
19263 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19264 bfd_vma count, page_size;
19265 unsigned char *descdata, *filenames, *descend;
19266
19267 if (pnote->type != NT_FILE)
04ac15ab
AS
19268 {
19269 if (do_wide)
19270 printf ("\n");
015dc7e1 19271 return true;
04ac15ab 19272 }
9ece1fa9
TT
19273
19274#ifndef BFD64
19275 if (!is_32bit_elf)
19276 {
19277 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19278 /* Still "successful". */
015dc7e1 19279 return true;
9ece1fa9
TT
19280 }
19281#endif
19282
19283 if (pnote->descsz < 2 * addr_size)
19284 {
32ec8896 19285 error (_(" Malformed note - too short for header\n"));
015dc7e1 19286 return false;
9ece1fa9
TT
19287 }
19288
19289 descdata = (unsigned char *) pnote->descdata;
19290 descend = descdata + pnote->descsz;
19291
19292 if (descdata[pnote->descsz - 1] != '\0')
19293 {
32ec8896 19294 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19295 return false;
9ece1fa9
TT
19296 }
19297
19298 count = byte_get (descdata, addr_size);
19299 descdata += addr_size;
19300
19301 page_size = byte_get (descdata, addr_size);
19302 descdata += addr_size;
19303
5396a86e
AM
19304 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19305 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19306 {
32ec8896 19307 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19308 return false;
9ece1fa9
TT
19309 }
19310
19311 printf (_(" Page size: "));
19312 print_vma (page_size, DEC);
19313 printf ("\n");
19314
19315 printf (_(" %*s%*s%*s\n"),
19316 (int) (2 + 2 * addr_size), _("Start"),
19317 (int) (4 + 2 * addr_size), _("End"),
19318 (int) (4 + 2 * addr_size), _("Page Offset"));
19319 filenames = descdata + count * 3 * addr_size;
595712bb 19320 while (count-- > 0)
9ece1fa9
TT
19321 {
19322 bfd_vma start, end, file_ofs;
19323
19324 if (filenames == descend)
19325 {
32ec8896 19326 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19327 return false;
9ece1fa9
TT
19328 }
19329
19330 start = byte_get (descdata, addr_size);
19331 descdata += addr_size;
19332 end = byte_get (descdata, addr_size);
19333 descdata += addr_size;
19334 file_ofs = byte_get (descdata, addr_size);
19335 descdata += addr_size;
19336
19337 printf (" ");
19338 print_vma (start, FULL_HEX);
19339 printf (" ");
19340 print_vma (end, FULL_HEX);
19341 printf (" ");
19342 print_vma (file_ofs, FULL_HEX);
19343 printf ("\n %s\n", filenames);
19344
19345 filenames += 1 + strlen ((char *) filenames);
19346 }
19347
015dc7e1 19348 return true;
9ece1fa9
TT
19349}
19350
1118d252
RM
19351static const char *
19352get_gnu_elf_note_type (unsigned e_type)
19353{
1449284b 19354 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19355 switch (e_type)
19356 {
19357 case NT_GNU_ABI_TAG:
19358 return _("NT_GNU_ABI_TAG (ABI version tag)");
19359 case NT_GNU_HWCAP:
19360 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19361 case NT_GNU_BUILD_ID:
19362 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19363 case NT_GNU_GOLD_VERSION:
19364 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19365 case NT_GNU_PROPERTY_TYPE_0:
19366 return _("NT_GNU_PROPERTY_TYPE_0");
19367 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19368 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19369 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19370 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19371 default:
1449284b
NC
19372 {
19373 static char buff[64];
1118d252 19374
1449284b
NC
19375 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19376 return buff;
19377 }
19378 }
1118d252
RM
19379}
19380
a9eafb08
L
19381static void
19382decode_x86_compat_isa (unsigned int bitmask)
19383{
19384 while (bitmask)
19385 {
19386 unsigned int bit = bitmask & (- bitmask);
19387
19388 bitmask &= ~ bit;
19389 switch (bit)
19390 {
19391 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19392 printf ("i486");
19393 break;
19394 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19395 printf ("586");
19396 break;
19397 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19398 printf ("686");
19399 break;
19400 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19401 printf ("SSE");
19402 break;
19403 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19404 printf ("SSE2");
19405 break;
19406 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19407 printf ("SSE3");
19408 break;
19409 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19410 printf ("SSSE3");
19411 break;
19412 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19413 printf ("SSE4_1");
19414 break;
19415 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19416 printf ("SSE4_2");
19417 break;
19418 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19419 printf ("AVX");
19420 break;
19421 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19422 printf ("AVX2");
19423 break;
19424 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19425 printf ("AVX512F");
19426 break;
19427 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19428 printf ("AVX512CD");
19429 break;
19430 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19431 printf ("AVX512ER");
19432 break;
19433 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19434 printf ("AVX512PF");
19435 break;
19436 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19437 printf ("AVX512VL");
19438 break;
19439 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19440 printf ("AVX512DQ");
19441 break;
19442 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19443 printf ("AVX512BW");
19444 break;
65b3d26e
L
19445 default:
19446 printf (_("<unknown: %x>"), bit);
19447 break;
a9eafb08
L
19448 }
19449 if (bitmask)
19450 printf (", ");
19451 }
19452}
19453
9ef920e9 19454static void
32930e4e 19455decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19456{
0a59decb 19457 if (!bitmask)
90c745dc
L
19458 {
19459 printf (_("<None>"));
19460 return;
19461 }
90c745dc 19462
9ef920e9
NC
19463 while (bitmask)
19464 {
1fc87489 19465 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19466
19467 bitmask &= ~ bit;
19468 switch (bit)
19469 {
32930e4e 19470 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19471 printf ("CMOV");
19472 break;
32930e4e 19473 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19474 printf ("SSE");
19475 break;
32930e4e 19476 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19477 printf ("SSE2");
19478 break;
32930e4e 19479 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19480 printf ("SSE3");
19481 break;
32930e4e 19482 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19483 printf ("SSSE3");
19484 break;
32930e4e 19485 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19486 printf ("SSE4_1");
19487 break;
32930e4e 19488 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19489 printf ("SSE4_2");
19490 break;
32930e4e 19491 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19492 printf ("AVX");
19493 break;
32930e4e 19494 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19495 printf ("AVX2");
19496 break;
32930e4e 19497 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19498 printf ("FMA");
19499 break;
32930e4e 19500 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19501 printf ("AVX512F");
19502 break;
32930e4e 19503 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19504 printf ("AVX512CD");
19505 break;
32930e4e 19506 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19507 printf ("AVX512ER");
19508 break;
32930e4e 19509 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19510 printf ("AVX512PF");
19511 break;
32930e4e 19512 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19513 printf ("AVX512VL");
19514 break;
32930e4e 19515 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19516 printf ("AVX512DQ");
19517 break;
32930e4e 19518 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19519 printf ("AVX512BW");
19520 break;
32930e4e 19521 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19522 printf ("AVX512_4FMAPS");
19523 break;
32930e4e 19524 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19525 printf ("AVX512_4VNNIW");
19526 break;
32930e4e 19527 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19528 printf ("AVX512_BITALG");
19529 break;
32930e4e 19530 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19531 printf ("AVX512_IFMA");
19532 break;
32930e4e 19533 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19534 printf ("AVX512_VBMI");
19535 break;
32930e4e 19536 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19537 printf ("AVX512_VBMI2");
19538 break;
32930e4e 19539 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19540 printf ("AVX512_VNNI");
19541 break;
32930e4e 19542 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19543 printf ("AVX512_BF16");
19544 break;
65b3d26e
L
19545 default:
19546 printf (_("<unknown: %x>"), bit);
19547 break;
9ef920e9
NC
19548 }
19549 if (bitmask)
19550 printf (", ");
19551 }
19552}
19553
32930e4e
L
19554static void
19555decode_x86_isa (unsigned int bitmask)
19556{
32930e4e
L
19557 while (bitmask)
19558 {
19559 unsigned int bit = bitmask & (- bitmask);
19560
19561 bitmask &= ~ bit;
19562 switch (bit)
19563 {
b0ab0693
L
19564 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19565 printf ("x86-64-baseline");
19566 break;
32930e4e
L
19567 case GNU_PROPERTY_X86_ISA_1_V2:
19568 printf ("x86-64-v2");
19569 break;
19570 case GNU_PROPERTY_X86_ISA_1_V3:
19571 printf ("x86-64-v3");
19572 break;
19573 case GNU_PROPERTY_X86_ISA_1_V4:
19574 printf ("x86-64-v4");
19575 break;
19576 default:
19577 printf (_("<unknown: %x>"), bit);
19578 break;
19579 }
19580 if (bitmask)
19581 printf (", ");
19582 }
19583}
19584
ee2fdd6f 19585static void
a9eafb08 19586decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19587{
0a59decb 19588 if (!bitmask)
90c745dc
L
19589 {
19590 printf (_("<None>"));
19591 return;
19592 }
90c745dc 19593
ee2fdd6f
L
19594 while (bitmask)
19595 {
19596 unsigned int bit = bitmask & (- bitmask);
19597
19598 bitmask &= ~ bit;
19599 switch (bit)
19600 {
19601 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19602 printf ("IBT");
ee2fdd6f 19603 break;
48580982 19604 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19605 printf ("SHSTK");
48580982 19606 break;
279d901e
L
19607 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19608 printf ("LAM_U48");
19609 break;
19610 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19611 printf ("LAM_U57");
19612 break;
ee2fdd6f
L
19613 default:
19614 printf (_("<unknown: %x>"), bit);
19615 break;
19616 }
19617 if (bitmask)
19618 printf (", ");
19619 }
19620}
19621
a9eafb08
L
19622static void
19623decode_x86_feature_2 (unsigned int bitmask)
19624{
0a59decb 19625 if (!bitmask)
90c745dc
L
19626 {
19627 printf (_("<None>"));
19628 return;
19629 }
90c745dc 19630
a9eafb08
L
19631 while (bitmask)
19632 {
19633 unsigned int bit = bitmask & (- bitmask);
19634
19635 bitmask &= ~ bit;
19636 switch (bit)
19637 {
19638 case GNU_PROPERTY_X86_FEATURE_2_X86:
19639 printf ("x86");
19640 break;
19641 case GNU_PROPERTY_X86_FEATURE_2_X87:
19642 printf ("x87");
19643 break;
19644 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19645 printf ("MMX");
19646 break;
19647 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19648 printf ("XMM");
19649 break;
19650 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19651 printf ("YMM");
19652 break;
19653 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19654 printf ("ZMM");
19655 break;
a308b89d
L
19656 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19657 printf ("TMM");
19658 break;
32930e4e
L
19659 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19660 printf ("MASK");
19661 break;
a9eafb08
L
19662 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19663 printf ("FXSR");
19664 break;
19665 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19666 printf ("XSAVE");
19667 break;
19668 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19669 printf ("XSAVEOPT");
19670 break;
19671 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19672 printf ("XSAVEC");
19673 break;
65b3d26e
L
19674 default:
19675 printf (_("<unknown: %x>"), bit);
19676 break;
a9eafb08
L
19677 }
19678 if (bitmask)
19679 printf (", ");
19680 }
19681}
19682
cd702818
SD
19683static void
19684decode_aarch64_feature_1_and (unsigned int bitmask)
19685{
19686 while (bitmask)
19687 {
19688 unsigned int bit = bitmask & (- bitmask);
19689
19690 bitmask &= ~ bit;
19691 switch (bit)
19692 {
19693 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19694 printf ("BTI");
19695 break;
19696
19697 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19698 printf ("PAC");
19699 break;
19700
19701 default:
19702 printf (_("<unknown: %x>"), bit);
19703 break;
19704 }
19705 if (bitmask)
19706 printf (", ");
19707 }
19708}
19709
6320fd00
L
19710static void
19711decode_1_needed (unsigned int bitmask)
19712{
19713 while (bitmask)
19714 {
19715 unsigned int bit = bitmask & (- bitmask);
19716
19717 bitmask &= ~ bit;
19718 switch (bit)
19719 {
19720 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19721 printf ("indirect external access");
19722 break;
19723 default:
19724 printf (_("<unknown: %x>"), bit);
19725 break;
19726 }
19727 if (bitmask)
19728 printf (", ");
19729 }
19730}
19731
9ef920e9 19732static void
dda8d76d 19733print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19734{
19735 unsigned char * ptr = (unsigned char *) pnote->descdata;
19736 unsigned char * ptr_end = ptr + pnote->descsz;
19737 unsigned int size = is_32bit_elf ? 4 : 8;
19738
19739 printf (_(" Properties: "));
19740
1fc87489 19741 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19742 {
19743 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19744 return;
19745 }
19746
6ab2c4ed 19747 while (ptr < ptr_end)
9ef920e9 19748 {
1fc87489 19749 unsigned int j;
6ab2c4ed
MC
19750 unsigned int type;
19751 unsigned int datasz;
19752
19753 if ((size_t) (ptr_end - ptr) < 8)
19754 {
19755 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19756 break;
19757 }
19758
19759 type = byte_get (ptr, 4);
19760 datasz = byte_get (ptr + 4, 4);
9ef920e9 19761
1fc87489 19762 ptr += 8;
9ef920e9 19763
6ab2c4ed 19764 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19765 {
1fc87489
L
19766 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19767 type, datasz);
9ef920e9 19768 break;
1fc87489 19769 }
9ef920e9 19770
1fc87489
L
19771 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19772 {
dda8d76d
NC
19773 if (filedata->file_header.e_machine == EM_X86_64
19774 || filedata->file_header.e_machine == EM_IAMCU
19775 || filedata->file_header.e_machine == EM_386)
1fc87489 19776 {
aa7bca9b
L
19777 unsigned int bitmask;
19778
19779 if (datasz == 4)
0a59decb 19780 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19781 else
19782 bitmask = 0;
19783
1fc87489
L
19784 switch (type)
19785 {
19786 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19787 if (datasz != 4)
aa7bca9b
L
19788 printf (_("x86 ISA used: <corrupt length: %#x> "),
19789 datasz);
1fc87489 19790 else
aa7bca9b
L
19791 {
19792 printf ("x86 ISA used: ");
19793 decode_x86_isa (bitmask);
19794 }
1fc87489 19795 goto next;
9ef920e9 19796
1fc87489 19797 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19798 if (datasz != 4)
aa7bca9b
L
19799 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19800 datasz);
1fc87489 19801 else
aa7bca9b
L
19802 {
19803 printf ("x86 ISA needed: ");
19804 decode_x86_isa (bitmask);
19805 }
1fc87489 19806 goto next;
9ef920e9 19807
ee2fdd6f 19808 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19809 if (datasz != 4)
aa7bca9b
L
19810 printf (_("x86 feature: <corrupt length: %#x> "),
19811 datasz);
ee2fdd6f 19812 else
aa7bca9b
L
19813 {
19814 printf ("x86 feature: ");
a9eafb08
L
19815 decode_x86_feature_1 (bitmask);
19816 }
19817 goto next;
19818
19819 case GNU_PROPERTY_X86_FEATURE_2_USED:
19820 if (datasz != 4)
19821 printf (_("x86 feature used: <corrupt length: %#x> "),
19822 datasz);
19823 else
19824 {
19825 printf ("x86 feature used: ");
19826 decode_x86_feature_2 (bitmask);
19827 }
19828 goto next;
19829
19830 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19831 if (datasz != 4)
19832 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19833 else
19834 {
19835 printf ("x86 feature needed: ");
19836 decode_x86_feature_2 (bitmask);
19837 }
19838 goto next;
19839
19840 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19841 if (datasz != 4)
19842 printf (_("x86 ISA used: <corrupt length: %#x> "),
19843 datasz);
19844 else
19845 {
19846 printf ("x86 ISA used: ");
19847 decode_x86_compat_isa (bitmask);
19848 }
19849 goto next;
19850
19851 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19852 if (datasz != 4)
19853 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19854 datasz);
19855 else
19856 {
19857 printf ("x86 ISA needed: ");
19858 decode_x86_compat_isa (bitmask);
aa7bca9b 19859 }
ee2fdd6f
L
19860 goto next;
19861
32930e4e
L
19862 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19863 if (datasz != 4)
19864 printf (_("x86 ISA used: <corrupt length: %#x> "),
19865 datasz);
19866 else
19867 {
19868 printf ("x86 ISA used: ");
19869 decode_x86_compat_2_isa (bitmask);
19870 }
19871 goto next;
19872
19873 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19874 if (datasz != 4)
19875 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19876 datasz);
19877 else
19878 {
19879 printf ("x86 ISA needed: ");
19880 decode_x86_compat_2_isa (bitmask);
19881 }
19882 goto next;
19883
1fc87489
L
19884 default:
19885 break;
19886 }
19887 }
cd702818
SD
19888 else if (filedata->file_header.e_machine == EM_AARCH64)
19889 {
19890 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19891 {
19892 printf ("AArch64 feature: ");
19893 if (datasz != 4)
19894 printf (_("<corrupt length: %#x> "), datasz);
19895 else
19896 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19897 goto next;
19898 }
19899 }
1fc87489
L
19900 }
19901 else
19902 {
19903 switch (type)
9ef920e9 19904 {
1fc87489
L
19905 case GNU_PROPERTY_STACK_SIZE:
19906 printf (_("stack size: "));
19907 if (datasz != size)
19908 printf (_("<corrupt length: %#x> "), datasz);
19909 else
19910 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19911 goto next;
19912
19913 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19914 printf ("no copy on protected ");
19915 if (datasz)
19916 printf (_("<corrupt length: %#x> "), datasz);
19917 goto next;
19918
19919 default:
5a767724
L
19920 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19921 && type <= GNU_PROPERTY_UINT32_AND_HI)
19922 || (type >= GNU_PROPERTY_UINT32_OR_LO
19923 && type <= GNU_PROPERTY_UINT32_OR_HI))
19924 {
6320fd00
L
19925 switch (type)
19926 {
19927 case GNU_PROPERTY_1_NEEDED:
19928 if (datasz != 4)
19929 printf (_("1_needed: <corrupt length: %#x> "),
19930 datasz);
19931 else
19932 {
19933 unsigned int bitmask = byte_get (ptr, 4);
19934 printf ("1_needed: ");
19935 decode_1_needed (bitmask);
19936 }
19937 goto next;
19938
19939 default:
19940 break;
19941 }
5a767724
L
19942 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19943 printf (_("UINT32_AND (%#x): "), type);
19944 else
19945 printf (_("UINT32_OR (%#x): "), type);
19946 if (datasz != 4)
19947 printf (_("<corrupt length: %#x> "), datasz);
19948 else
19949 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19950 goto next;
19951 }
9ef920e9
NC
19952 break;
19953 }
9ef920e9
NC
19954 }
19955
1fc87489
L
19956 if (type < GNU_PROPERTY_LOPROC)
19957 printf (_("<unknown type %#x data: "), type);
19958 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19959 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19960 else
19961 printf (_("<application-specific type %#x data: "), type);
19962 for (j = 0; j < datasz; ++j)
19963 printf ("%02x ", ptr[j] & 0xff);
19964 printf (">");
19965
dc1e8a47 19966 next:
9ef920e9 19967 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19968 if (ptr == ptr_end)
19969 break;
1fc87489 19970
6ab2c4ed
MC
19971 if (do_wide)
19972 printf (", ");
19973 else
19974 printf ("\n\t");
9ef920e9
NC
19975 }
19976
19977 printf ("\n");
19978}
19979
015dc7e1 19980static bool
dda8d76d 19981print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19982{
1449284b 19983 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19984 switch (pnote->type)
19985 {
19986 case NT_GNU_BUILD_ID:
19987 {
19988 unsigned long i;
19989
19990 printf (_(" Build ID: "));
19991 for (i = 0; i < pnote->descsz; ++i)
19992 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19993 printf ("\n");
664f90a3
TT
19994 }
19995 break;
19996
19997 case NT_GNU_ABI_TAG:
19998 {
19999 unsigned long os, major, minor, subminor;
20000 const char *osname;
20001
3102e897
NC
20002 /* PR 17531: file: 030-599401-0.004. */
20003 if (pnote->descsz < 16)
20004 {
20005 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20006 break;
20007 }
20008
664f90a3
TT
20009 os = byte_get ((unsigned char *) pnote->descdata, 4);
20010 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20011 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20012 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20013
20014 switch (os)
20015 {
20016 case GNU_ABI_TAG_LINUX:
20017 osname = "Linux";
20018 break;
20019 case GNU_ABI_TAG_HURD:
20020 osname = "Hurd";
20021 break;
20022 case GNU_ABI_TAG_SOLARIS:
20023 osname = "Solaris";
20024 break;
20025 case GNU_ABI_TAG_FREEBSD:
20026 osname = "FreeBSD";
20027 break;
20028 case GNU_ABI_TAG_NETBSD:
20029 osname = "NetBSD";
20030 break;
14ae95f2
RM
20031 case GNU_ABI_TAG_SYLLABLE:
20032 osname = "Syllable";
20033 break;
20034 case GNU_ABI_TAG_NACL:
20035 osname = "NaCl";
20036 break;
664f90a3
TT
20037 default:
20038 osname = "Unknown";
20039 break;
20040 }
20041
20042 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20043 major, minor, subminor);
20044 }
20045 break;
926c5385
CC
20046
20047 case NT_GNU_GOLD_VERSION:
20048 {
20049 unsigned long i;
20050
20051 printf (_(" Version: "));
20052 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20053 printf ("%c", pnote->descdata[i]);
20054 printf ("\n");
20055 }
20056 break;
1449284b
NC
20057
20058 case NT_GNU_HWCAP:
20059 {
20060 unsigned long num_entries, mask;
20061
20062 /* Hardware capabilities information. Word 0 is the number of entries.
20063 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20064 is a series of entries, where each entry is a single byte followed
20065 by a nul terminated string. The byte gives the bit number to test
20066 if enabled in the bitmask. */
20067 printf (_(" Hardware Capabilities: "));
20068 if (pnote->descsz < 8)
20069 {
32ec8896 20070 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20071 return false;
1449284b
NC
20072 }
20073 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20074 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20075 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20076 /* FIXME: Add code to display the entries... */
20077 }
20078 break;
20079
9ef920e9 20080 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20081 print_gnu_property_note (filedata, pnote);
9ef920e9 20082 break;
9abca702 20083
1449284b
NC
20084 default:
20085 /* Handle unrecognised types. An error message should have already been
20086 created by get_gnu_elf_note_type(), so all that we need to do is to
20087 display the data. */
20088 {
20089 unsigned long i;
20090
20091 printf (_(" Description data: "));
20092 for (i = 0; i < pnote->descsz; ++i)
20093 printf ("%02x ", pnote->descdata[i] & 0xff);
20094 printf ("\n");
20095 }
20096 break;
664f90a3
TT
20097 }
20098
015dc7e1 20099 return true;
664f90a3
TT
20100}
20101
685080f2
NC
20102static const char *
20103get_v850_elf_note_type (enum v850_notes n_type)
20104{
20105 static char buff[64];
20106
20107 switch (n_type)
20108 {
20109 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20110 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20111 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20112 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20113 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20114 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20115 default:
20116 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20117 return buff;
20118 }
20119}
20120
015dc7e1 20121static bool
685080f2
NC
20122print_v850_note (Elf_Internal_Note * pnote)
20123{
20124 unsigned int val;
20125
20126 if (pnote->descsz != 4)
015dc7e1 20127 return false;
32ec8896 20128
685080f2
NC
20129 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20130
20131 if (val == 0)
20132 {
20133 printf (_("not set\n"));
015dc7e1 20134 return true;
685080f2
NC
20135 }
20136
20137 switch (pnote->type)
20138 {
20139 case V850_NOTE_ALIGNMENT:
20140 switch (val)
20141 {
015dc7e1
AM
20142 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20143 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20144 }
20145 break;
14ae95f2 20146
685080f2
NC
20147 case V850_NOTE_DATA_SIZE:
20148 switch (val)
20149 {
015dc7e1
AM
20150 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20151 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20152 }
20153 break;
14ae95f2 20154
685080f2
NC
20155 case V850_NOTE_FPU_INFO:
20156 switch (val)
20157 {
015dc7e1
AM
20158 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20159 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20160 }
20161 break;
14ae95f2 20162
685080f2
NC
20163 case V850_NOTE_MMU_INFO:
20164 case V850_NOTE_CACHE_INFO:
20165 case V850_NOTE_SIMD_INFO:
20166 if (val == EF_RH850_SIMD)
20167 {
20168 printf (_("yes\n"));
015dc7e1 20169 return true;
685080f2
NC
20170 }
20171 break;
20172
20173 default:
20174 /* An 'unknown note type' message will already have been displayed. */
20175 break;
20176 }
20177
20178 printf (_("unknown value: %x\n"), val);
015dc7e1 20179 return false;
685080f2
NC
20180}
20181
015dc7e1 20182static bool
c6056a74
SF
20183process_netbsd_elf_note (Elf_Internal_Note * pnote)
20184{
20185 unsigned int version;
20186
20187 switch (pnote->type)
20188 {
20189 case NT_NETBSD_IDENT:
b966f55f
AM
20190 if (pnote->descsz < 1)
20191 break;
c6056a74
SF
20192 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20193 if ((version / 10000) % 100)
b966f55f 20194 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20195 version, version / 100000000, (version / 1000000) % 100,
20196 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20197 'A' + (version / 10000) % 26);
c6056a74
SF
20198 else
20199 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20200 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20201 (version / 100) % 100);
015dc7e1 20202 return true;
c6056a74
SF
20203
20204 case NT_NETBSD_MARCH:
9abca702 20205 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20206 pnote->descdata);
015dc7e1 20207 return true;
c6056a74 20208
9abca702 20209 case NT_NETBSD_PAX:
b966f55f
AM
20210 if (pnote->descsz < 1)
20211 break;
9abca702
CZ
20212 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20213 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20214 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20215 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20216 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20217 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20218 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20219 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20220 return true;
c6056a74 20221 }
b966f55f
AM
20222
20223 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20224 pnote->descsz, pnote->type);
015dc7e1 20225 return false;
c6056a74
SF
20226}
20227
f4ddf30f 20228static const char *
dda8d76d 20229get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20230{
f4ddf30f
JB
20231 switch (e_type)
20232 {
20233 case NT_FREEBSD_THRMISC:
20234 return _("NT_THRMISC (thrmisc structure)");
20235 case NT_FREEBSD_PROCSTAT_PROC:
20236 return _("NT_PROCSTAT_PROC (proc data)");
20237 case NT_FREEBSD_PROCSTAT_FILES:
20238 return _("NT_PROCSTAT_FILES (files data)");
20239 case NT_FREEBSD_PROCSTAT_VMMAP:
20240 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20241 case NT_FREEBSD_PROCSTAT_GROUPS:
20242 return _("NT_PROCSTAT_GROUPS (groups data)");
20243 case NT_FREEBSD_PROCSTAT_UMASK:
20244 return _("NT_PROCSTAT_UMASK (umask data)");
20245 case NT_FREEBSD_PROCSTAT_RLIMIT:
20246 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20247 case NT_FREEBSD_PROCSTAT_OSREL:
20248 return _("NT_PROCSTAT_OSREL (osreldate data)");
20249 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20250 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20251 case NT_FREEBSD_PROCSTAT_AUXV:
20252 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20253 case NT_FREEBSD_PTLWPINFO:
20254 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 20255 }
dda8d76d 20256 return get_note_type (filedata, e_type);
f4ddf30f
JB
20257}
20258
9437c45b 20259static const char *
dda8d76d 20260get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20261{
20262 static char buff[64];
20263
540e6170
CZ
20264 switch (e_type)
20265 {
20266 case NT_NETBSDCORE_PROCINFO:
20267 /* NetBSD core "procinfo" structure. */
20268 return _("NetBSD procinfo structure");
9437c45b 20269
540e6170
CZ
20270 case NT_NETBSDCORE_AUXV:
20271 return _("NetBSD ELF auxiliary vector data");
9437c45b 20272
06d949ec
KR
20273 case NT_NETBSDCORE_LWPSTATUS:
20274 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20275
540e6170 20276 default:
06d949ec 20277 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20278 defined for NetBSD core files. If the note type is less
20279 than the start of the machine-dependent note types, we don't
20280 understand it. */
20281
20282 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20283 {
20284 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20285 return buff;
20286 }
20287 break;
9437c45b
JT
20288 }
20289
dda8d76d 20290 switch (filedata->file_header.e_machine)
9437c45b
JT
20291 {
20292 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20293 and PT_GETFPREGS == mach+2. */
20294
20295 case EM_OLD_ALPHA:
20296 case EM_ALPHA:
20297 case EM_SPARC:
20298 case EM_SPARC32PLUS:
20299 case EM_SPARCV9:
20300 switch (e_type)
20301 {
2b692964 20302 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20303 return _("PT_GETREGS (reg structure)");
2b692964 20304 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20305 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20306 default:
20307 break;
20308 }
20309 break;
20310
c0d38b0e
CZ
20311 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20312 There's also old PT___GETREGS40 == mach + 1 for old reg
20313 structure which lacks GBR. */
20314 case EM_SH:
20315 switch (e_type)
20316 {
20317 case NT_NETBSDCORE_FIRSTMACH + 1:
20318 return _("PT___GETREGS40 (old reg structure)");
20319 case NT_NETBSDCORE_FIRSTMACH + 3:
20320 return _("PT_GETREGS (reg structure)");
20321 case NT_NETBSDCORE_FIRSTMACH + 5:
20322 return _("PT_GETFPREGS (fpreg structure)");
20323 default:
20324 break;
20325 }
20326 break;
20327
9437c45b
JT
20328 /* On all other arch's, PT_GETREGS == mach+1 and
20329 PT_GETFPREGS == mach+3. */
20330 default:
20331 switch (e_type)
20332 {
2b692964 20333 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20334 return _("PT_GETREGS (reg structure)");
2b692964 20335 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20336 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20337 default:
20338 break;
20339 }
20340 }
20341
9cf03b7e 20342 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20343 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20344 return buff;
20345}
20346
98ca73af
FC
20347static const char *
20348get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20349{
20350 switch (e_type)
20351 {
20352 case NT_OPENBSD_PROCINFO:
20353 return _("OpenBSD procinfo structure");
20354 case NT_OPENBSD_AUXV:
20355 return _("OpenBSD ELF auxiliary vector data");
20356 case NT_OPENBSD_REGS:
20357 return _("OpenBSD regular registers");
20358 case NT_OPENBSD_FPREGS:
20359 return _("OpenBSD floating point registers");
20360 case NT_OPENBSD_WCOOKIE:
20361 return _("OpenBSD window cookie");
20362 }
20363
20364 return get_note_type (filedata, e_type);
20365}
20366
70616151
TT
20367static const char *
20368get_stapsdt_note_type (unsigned e_type)
20369{
20370 static char buff[64];
20371
20372 switch (e_type)
20373 {
20374 case NT_STAPSDT:
20375 return _("NT_STAPSDT (SystemTap probe descriptors)");
20376
20377 default:
20378 break;
20379 }
20380
20381 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20382 return buff;
20383}
20384
015dc7e1 20385static bool
c6a9fc58
TT
20386print_stapsdt_note (Elf_Internal_Note *pnote)
20387{
3ca60c57
NC
20388 size_t len, maxlen;
20389 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20390 char *data = pnote->descdata;
20391 char *data_end = pnote->descdata + pnote->descsz;
20392 bfd_vma pc, base_addr, semaphore;
20393 char *provider, *probe, *arg_fmt;
20394
3ca60c57
NC
20395 if (pnote->descsz < (addr_size * 3))
20396 goto stapdt_note_too_small;
20397
c6a9fc58
TT
20398 pc = byte_get ((unsigned char *) data, addr_size);
20399 data += addr_size;
3ca60c57 20400
c6a9fc58
TT
20401 base_addr = byte_get ((unsigned char *) data, addr_size);
20402 data += addr_size;
3ca60c57 20403
c6a9fc58
TT
20404 semaphore = byte_get ((unsigned char *) data, addr_size);
20405 data += addr_size;
20406
3ca60c57
NC
20407 if (data >= data_end)
20408 goto stapdt_note_too_small;
20409 maxlen = data_end - data;
20410 len = strnlen (data, maxlen);
20411 if (len < maxlen)
20412 {
20413 provider = data;
20414 data += len + 1;
20415 }
20416 else
20417 goto stapdt_note_too_small;
20418
20419 if (data >= data_end)
20420 goto stapdt_note_too_small;
20421 maxlen = data_end - data;
20422 len = strnlen (data, maxlen);
20423 if (len < maxlen)
20424 {
20425 probe = data;
20426 data += len + 1;
20427 }
20428 else
20429 goto stapdt_note_too_small;
9abca702 20430
3ca60c57
NC
20431 if (data >= data_end)
20432 goto stapdt_note_too_small;
20433 maxlen = data_end - data;
20434 len = strnlen (data, maxlen);
20435 if (len < maxlen)
20436 {
20437 arg_fmt = data;
20438 data += len + 1;
20439 }
20440 else
20441 goto stapdt_note_too_small;
c6a9fc58
TT
20442
20443 printf (_(" Provider: %s\n"), provider);
20444 printf (_(" Name: %s\n"), probe);
20445 printf (_(" Location: "));
20446 print_vma (pc, FULL_HEX);
20447 printf (_(", Base: "));
20448 print_vma (base_addr, FULL_HEX);
20449 printf (_(", Semaphore: "));
20450 print_vma (semaphore, FULL_HEX);
9cf03b7e 20451 printf ("\n");
c6a9fc58
TT
20452 printf (_(" Arguments: %s\n"), arg_fmt);
20453
20454 return data == data_end;
3ca60c57
NC
20455
20456 stapdt_note_too_small:
20457 printf (_(" <corrupt - note is too small>\n"));
20458 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20459 return false;
c6a9fc58
TT
20460}
20461
e5382207
LB
20462static bool
20463print_fdo_note (Elf_Internal_Note * pnote)
20464{
20465 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20466 {
20467 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20468 return true;
20469 }
20470 return false;
20471}
20472
00e98fc7
TG
20473static const char *
20474get_ia64_vms_note_type (unsigned e_type)
20475{
20476 static char buff[64];
20477
20478 switch (e_type)
20479 {
20480 case NT_VMS_MHD:
20481 return _("NT_VMS_MHD (module header)");
20482 case NT_VMS_LNM:
20483 return _("NT_VMS_LNM (language name)");
20484 case NT_VMS_SRC:
20485 return _("NT_VMS_SRC (source files)");
20486 case NT_VMS_TITLE:
9cf03b7e 20487 return "NT_VMS_TITLE";
00e98fc7
TG
20488 case NT_VMS_EIDC:
20489 return _("NT_VMS_EIDC (consistency check)");
20490 case NT_VMS_FPMODE:
20491 return _("NT_VMS_FPMODE (FP mode)");
20492 case NT_VMS_LINKTIME:
9cf03b7e 20493 return "NT_VMS_LINKTIME";
00e98fc7
TG
20494 case NT_VMS_IMGNAM:
20495 return _("NT_VMS_IMGNAM (image name)");
20496 case NT_VMS_IMGID:
20497 return _("NT_VMS_IMGID (image id)");
20498 case NT_VMS_LINKID:
20499 return _("NT_VMS_LINKID (link id)");
20500 case NT_VMS_IMGBID:
20501 return _("NT_VMS_IMGBID (build id)");
20502 case NT_VMS_GSTNAM:
20503 return _("NT_VMS_GSTNAM (sym table name)");
20504 case NT_VMS_ORIG_DYN:
9cf03b7e 20505 return "NT_VMS_ORIG_DYN";
00e98fc7 20506 case NT_VMS_PATCHTIME:
9cf03b7e 20507 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20508 default:
20509 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20510 return buff;
20511 }
20512}
20513
015dc7e1 20514static bool
00e98fc7
TG
20515print_ia64_vms_note (Elf_Internal_Note * pnote)
20516{
8d18bf79
NC
20517 int maxlen = pnote->descsz;
20518
20519 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20520 goto desc_size_fail;
20521
00e98fc7
TG
20522 switch (pnote->type)
20523 {
20524 case NT_VMS_MHD:
8d18bf79
NC
20525 if (maxlen <= 36)
20526 goto desc_size_fail;
20527
20528 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20529
20530 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20531 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20532 if (l + 34 < maxlen)
20533 {
20534 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20535 if (l + 35 < maxlen)
20536 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20537 else
20538 printf (_(" Module version : <missing>\n"));
20539 }
00e98fc7 20540 else
8d18bf79
NC
20541 {
20542 printf (_(" Module name : <missing>\n"));
20543 printf (_(" Module version : <missing>\n"));
20544 }
00e98fc7 20545 break;
8d18bf79 20546
00e98fc7 20547 case NT_VMS_LNM:
8d18bf79 20548 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20549 break;
8d18bf79 20550
00e98fc7
TG
20551#ifdef BFD64
20552 case NT_VMS_FPMODE:
9cf03b7e 20553 printf (_(" Floating Point mode: "));
8d18bf79
NC
20554 if (maxlen < 8)
20555 goto desc_size_fail;
20556 /* FIXME: Generate an error if descsz > 8 ? */
20557
4a5cb34f 20558 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20559 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20560 break;
8d18bf79 20561
00e98fc7
TG
20562 case NT_VMS_LINKTIME:
20563 printf (_(" Link time: "));
8d18bf79
NC
20564 if (maxlen < 8)
20565 goto desc_size_fail;
20566 /* FIXME: Generate an error if descsz > 8 ? */
20567
00e98fc7 20568 print_vms_time
8d18bf79 20569 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20570 printf ("\n");
20571 break;
8d18bf79 20572
00e98fc7
TG
20573 case NT_VMS_PATCHTIME:
20574 printf (_(" Patch time: "));
8d18bf79
NC
20575 if (maxlen < 8)
20576 goto desc_size_fail;
20577 /* FIXME: Generate an error if descsz > 8 ? */
20578
00e98fc7 20579 print_vms_time
8d18bf79 20580 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20581 printf ("\n");
20582 break;
8d18bf79 20583
00e98fc7 20584 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20585 if (maxlen < 34)
20586 goto desc_size_fail;
20587
00e98fc7
TG
20588 printf (_(" Major id: %u, minor id: %u\n"),
20589 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20590 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20591 printf (_(" Last modified : "));
00e98fc7
TG
20592 print_vms_time
20593 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20594 printf (_("\n Link flags : "));
4a5cb34f 20595 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20596 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20597 printf (_(" Header flags: 0x%08x\n"),
948f632f 20598 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20599 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20600 break;
20601#endif
8d18bf79 20602
00e98fc7 20603 case NT_VMS_IMGNAM:
8d18bf79 20604 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20605 break;
8d18bf79 20606
00e98fc7 20607 case NT_VMS_GSTNAM:
8d18bf79 20608 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20609 break;
8d18bf79 20610
00e98fc7 20611 case NT_VMS_IMGID:
8d18bf79 20612 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20613 break;
8d18bf79 20614
00e98fc7 20615 case NT_VMS_LINKID:
8d18bf79 20616 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20617 break;
8d18bf79 20618
00e98fc7 20619 default:
015dc7e1 20620 return false;
00e98fc7 20621 }
8d18bf79 20622
015dc7e1 20623 return true;
8d18bf79
NC
20624
20625 desc_size_fail:
20626 printf (_(" <corrupt - data size is too small>\n"));
20627 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20628 return false;
00e98fc7
TG
20629}
20630
fd486f32
AM
20631struct build_attr_cache {
20632 Filedata *filedata;
20633 char *strtab;
20634 unsigned long strtablen;
20635 Elf_Internal_Sym *symtab;
20636 unsigned long nsyms;
20637} ba_cache;
20638
6f156d7a
NC
20639/* Find the symbol associated with a build attribute that is attached
20640 to address OFFSET. If PNAME is non-NULL then store the name of
20641 the symbol (if found) in the provided pointer, Returns NULL if a
20642 symbol could not be found. */
c799a79d 20643
6f156d7a 20644static Elf_Internal_Sym *
015dc7e1
AM
20645get_symbol_for_build_attribute (Filedata *filedata,
20646 unsigned long offset,
20647 bool is_open_attr,
20648 const char **pname)
9ef920e9 20649{
fd486f32
AM
20650 Elf_Internal_Sym *saved_sym = NULL;
20651 Elf_Internal_Sym *sym;
9ef920e9 20652
dda8d76d 20653 if (filedata->section_headers != NULL
fd486f32 20654 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20655 {
c799a79d 20656 Elf_Internal_Shdr * symsec;
9ef920e9 20657
fd486f32
AM
20658 free (ba_cache.strtab);
20659 ba_cache.strtab = NULL;
20660 free (ba_cache.symtab);
20661 ba_cache.symtab = NULL;
20662
c799a79d 20663 /* Load the symbol and string sections. */
dda8d76d
NC
20664 for (symsec = filedata->section_headers;
20665 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20666 symsec ++)
9ef920e9 20667 {
28d13567
AM
20668 if (symsec->sh_type == SHT_SYMTAB
20669 && get_symtab (filedata, symsec,
20670 &ba_cache.symtab, &ba_cache.nsyms,
20671 &ba_cache.strtab, &ba_cache.strtablen))
20672 break;
9ef920e9 20673 }
fd486f32 20674 ba_cache.filedata = filedata;
9ef920e9
NC
20675 }
20676
fd486f32 20677 if (ba_cache.symtab == NULL)
6f156d7a 20678 return NULL;
9ef920e9 20679
c799a79d 20680 /* Find a symbol whose value matches offset. */
fd486f32 20681 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20682 if (sym->st_value == offset)
20683 {
fd486f32 20684 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20685 /* Huh ? This should not happen. */
20686 continue;
9ef920e9 20687
fd486f32 20688 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20689 continue;
9ef920e9 20690
9b9b1092 20691 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20692 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20693 if (ba_cache.strtab[sym->st_name] == '$'
20694 && ba_cache.strtab[sym->st_name + 1] != 0
20695 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20696 continue;
20697
c799a79d
NC
20698 if (is_open_attr)
20699 {
20700 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20701 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20702 FUNC symbols entirely. */
20703 switch (ELF_ST_TYPE (sym->st_info))
20704 {
c799a79d 20705 case STT_OBJECT:
6f156d7a 20706 case STT_FILE:
c799a79d 20707 saved_sym = sym;
6f156d7a
NC
20708 if (sym->st_size)
20709 {
20710 /* If the symbol has a size associated
20711 with it then we can stop searching. */
fd486f32 20712 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20713 }
c799a79d 20714 continue;
9ef920e9 20715
c799a79d
NC
20716 case STT_FUNC:
20717 /* Ignore function symbols. */
20718 continue;
20719
20720 default:
20721 break;
20722 }
20723
20724 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20725 {
c799a79d
NC
20726 case STB_GLOBAL:
20727 if (saved_sym == NULL
20728 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20729 saved_sym = sym;
20730 break;
c871dade 20731
c799a79d
NC
20732 case STB_LOCAL:
20733 if (saved_sym == NULL)
20734 saved_sym = sym;
20735 break;
20736
20737 default:
9ef920e9
NC
20738 break;
20739 }
20740 }
c799a79d
NC
20741 else
20742 {
20743 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20744 continue;
20745
20746 saved_sym = sym;
20747 break;
20748 }
20749 }
20750
6f156d7a 20751 if (saved_sym && pname)
fd486f32 20752 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20753
20754 return saved_sym;
c799a79d
NC
20755}
20756
d20e98ab
NC
20757/* Returns true iff addr1 and addr2 are in the same section. */
20758
015dc7e1 20759static bool
d20e98ab
NC
20760same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20761{
20762 Elf_Internal_Shdr * a1;
20763 Elf_Internal_Shdr * a2;
20764
20765 a1 = find_section_by_address (filedata, addr1);
20766 a2 = find_section_by_address (filedata, addr2);
9abca702 20767
d20e98ab
NC
20768 return a1 == a2 && a1 != NULL;
20769}
20770
015dc7e1 20771static bool
dda8d76d
NC
20772print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20773 Filedata * filedata)
c799a79d 20774{
015dc7e1
AM
20775 static unsigned long global_offset = 0;
20776 static unsigned long global_end = 0;
20777 static unsigned long func_offset = 0;
20778 static unsigned long func_end = 0;
c871dade 20779
015dc7e1
AM
20780 Elf_Internal_Sym *sym;
20781 const char *name;
20782 unsigned long start;
20783 unsigned long end;
20784 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20785
20786 switch (pnote->descsz)
c799a79d 20787 {
6f156d7a
NC
20788 case 0:
20789 /* A zero-length description means that the range of
20790 the previous note of the same type should be used. */
c799a79d 20791 if (is_open_attr)
c871dade 20792 {
6f156d7a
NC
20793 if (global_end > global_offset)
20794 printf (_(" Applies to region from %#lx to %#lx\n"),
20795 global_offset, global_end);
20796 else
20797 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20798 }
20799 else
20800 {
6f156d7a
NC
20801 if (func_end > func_offset)
20802 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20803 else
20804 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20805 }
015dc7e1 20806 return true;
9ef920e9 20807
6f156d7a
NC
20808 case 4:
20809 start = byte_get ((unsigned char *) pnote->descdata, 4);
20810 end = 0;
20811 break;
20812
20813 case 8:
c74147bb
NC
20814 start = byte_get ((unsigned char *) pnote->descdata, 4);
20815 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20816 break;
20817
20818 case 16:
20819 start = byte_get ((unsigned char *) pnote->descdata, 8);
20820 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20821 break;
9abca702 20822
6f156d7a 20823 default:
c799a79d
NC
20824 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20825 printf (_(" <invalid descsz>"));
015dc7e1 20826 return false;
c799a79d
NC
20827 }
20828
6f156d7a
NC
20829 name = NULL;
20830 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20831 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20832 in order to avoid them being confused with the start address of the
20833 first function in the file... */
20834 if (sym == NULL && is_open_attr)
20835 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20836 & name);
6f156d7a
NC
20837
20838 if (end == 0 && sym != NULL && sym->st_size > 0)
20839 end = start + sym->st_size;
c799a79d
NC
20840
20841 if (is_open_attr)
20842 {
d20e98ab
NC
20843 /* FIXME: Need to properly allow for section alignment.
20844 16 is just the alignment used on x86_64. */
20845 if (global_end > 0
20846 && start > BFD_ALIGN (global_end, 16)
20847 /* Build notes are not guaranteed to be organised in order of
20848 increasing address, but we should find the all of the notes
20849 for one section in the same place. */
20850 && same_section (filedata, start, global_end))
6f156d7a
NC
20851 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20852 global_end + 1, start - 1);
20853
20854 printf (_(" Applies to region from %#lx"), start);
20855 global_offset = start;
20856
20857 if (end)
20858 {
20859 printf (_(" to %#lx"), end);
20860 global_end = end;
20861 }
c799a79d
NC
20862 }
20863 else
20864 {
6f156d7a
NC
20865 printf (_(" Applies to region from %#lx"), start);
20866 func_offset = start;
20867
20868 if (end)
20869 {
20870 printf (_(" to %#lx"), end);
20871 func_end = end;
20872 }
c799a79d
NC
20873 }
20874
6f156d7a
NC
20875 if (sym && name)
20876 printf (_(" (%s)"), name);
20877
20878 printf ("\n");
015dc7e1 20879 return true;
9ef920e9
NC
20880}
20881
015dc7e1 20882static bool
9ef920e9
NC
20883print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20884{
1d15e434
NC
20885 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20886 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20887 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20888 char name_type;
20889 char name_attribute;
1d15e434 20890 const char * expected_types;
9ef920e9
NC
20891 const char * name = pnote->namedata;
20892 const char * text;
88305e1b 20893 signed int left;
9ef920e9
NC
20894
20895 if (name == NULL || pnote->namesz < 2)
20896 {
20897 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20898 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20899 return false;
9ef920e9
NC
20900 }
20901
6f156d7a
NC
20902 if (do_wide)
20903 left = 28;
20904 else
20905 left = 20;
88305e1b
NC
20906
20907 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20908 if (name[0] == 'G' && name[1] == 'A')
20909 {
6f156d7a
NC
20910 if (pnote->namesz < 4)
20911 {
20912 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20913 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20914 return false;
6f156d7a
NC
20915 }
20916
88305e1b
NC
20917 printf ("GA");
20918 name += 2;
20919 left -= 2;
20920 }
20921
9ef920e9
NC
20922 switch ((name_type = * name))
20923 {
20924 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20925 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20926 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20927 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20928 printf ("%c", * name);
88305e1b 20929 left --;
9ef920e9
NC
20930 break;
20931 default:
20932 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20933 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20934 return false;
9ef920e9
NC
20935 }
20936
9ef920e9
NC
20937 ++ name;
20938 text = NULL;
20939
20940 switch ((name_attribute = * name))
20941 {
20942 case GNU_BUILD_ATTRIBUTE_VERSION:
20943 text = _("<version>");
1d15e434 20944 expected_types = string_expected;
9ef920e9
NC
20945 ++ name;
20946 break;
20947 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20948 text = _("<stack prot>");
75d7d298 20949 expected_types = "!+*";
9ef920e9
NC
20950 ++ name;
20951 break;
20952 case GNU_BUILD_ATTRIBUTE_RELRO:
20953 text = _("<relro>");
1d15e434 20954 expected_types = bool_expected;
9ef920e9
NC
20955 ++ name;
20956 break;
20957 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20958 text = _("<stack size>");
1d15e434 20959 expected_types = number_expected;
9ef920e9
NC
20960 ++ name;
20961 break;
20962 case GNU_BUILD_ATTRIBUTE_TOOL:
20963 text = _("<tool>");
1d15e434 20964 expected_types = string_expected;
9ef920e9
NC
20965 ++ name;
20966 break;
20967 case GNU_BUILD_ATTRIBUTE_ABI:
20968 text = _("<ABI>");
20969 expected_types = "$*";
20970 ++ name;
20971 break;
20972 case GNU_BUILD_ATTRIBUTE_PIC:
20973 text = _("<PIC>");
1d15e434 20974 expected_types = number_expected;
9ef920e9
NC
20975 ++ name;
20976 break;
a8be5506
NC
20977 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20978 text = _("<short enum>");
1d15e434 20979 expected_types = bool_expected;
a8be5506
NC
20980 ++ name;
20981 break;
9ef920e9
NC
20982 default:
20983 if (ISPRINT (* name))
20984 {
20985 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20986
20987 if (len > left && ! do_wide)
20988 len = left;
75d7d298 20989 printf ("%.*s:", len, name);
9ef920e9 20990 left -= len;
0dd6ae21 20991 name += len;
9ef920e9
NC
20992 }
20993 else
20994 {
3e6b6445 20995 static char tmpbuf [128];
88305e1b 20996
3e6b6445
NC
20997 error (_("unrecognised byte in name field: %d\n"), * name);
20998 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20999 text = tmpbuf;
21000 name ++;
9ef920e9
NC
21001 }
21002 expected_types = "*$!+";
21003 break;
21004 }
21005
21006 if (text)
88305e1b 21007 left -= printf ("%s", text);
9ef920e9
NC
21008
21009 if (strchr (expected_types, name_type) == NULL)
75d7d298 21010 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21011
21012 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21013 {
21014 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21015 (unsigned long) pnote->namesz,
21016 (long) (name - pnote->namedata));
015dc7e1 21017 return false;
9ef920e9
NC
21018 }
21019
21020 if (left < 1 && ! do_wide)
015dc7e1 21021 return true;
9ef920e9
NC
21022
21023 switch (name_type)
21024 {
21025 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21026 {
b06b2c92 21027 unsigned int bytes;
ddef72cd
NC
21028 unsigned long long val = 0;
21029 unsigned int shift = 0;
21030 char * decoded = NULL;
21031
b06b2c92
NC
21032 bytes = pnote->namesz - (name - pnote->namedata);
21033 if (bytes > 0)
21034 /* The -1 is because the name field is always 0 terminated, and we
21035 want to be able to ensure that the shift in the while loop below
21036 will not overflow. */
21037 -- bytes;
21038
ddef72cd
NC
21039 if (bytes > sizeof (val))
21040 {
3e6b6445
NC
21041 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21042 bytes);
21043 bytes = sizeof (val);
ddef72cd 21044 }
3e6b6445
NC
21045 /* We do not bother to warn if bytes == 0 as this can
21046 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21047
21048 while (bytes --)
21049 {
54b8331d 21050 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21051
21052 val |= byte << shift;
9ef920e9
NC
21053 shift += 8;
21054 }
21055
75d7d298 21056 switch (name_attribute)
9ef920e9 21057 {
75d7d298 21058 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21059 switch (val)
21060 {
75d7d298
NC
21061 case 0: decoded = "static"; break;
21062 case 1: decoded = "pic"; break;
21063 case 2: decoded = "PIC"; break;
21064 case 3: decoded = "pie"; break;
21065 case 4: decoded = "PIE"; break;
21066 default: break;
9ef920e9 21067 }
75d7d298
NC
21068 break;
21069 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21070 switch (val)
9ef920e9 21071 {
75d7d298
NC
21072 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21073 case 0: decoded = "off"; break;
21074 case 1: decoded = "on"; break;
21075 case 2: decoded = "all"; break;
21076 case 3: decoded = "strong"; break;
21077 case 4: decoded = "explicit"; break;
21078 default: break;
9ef920e9 21079 }
75d7d298
NC
21080 break;
21081 default:
21082 break;
9ef920e9
NC
21083 }
21084
75d7d298 21085 if (decoded != NULL)
3e6b6445
NC
21086 {
21087 print_symbol (-left, decoded);
21088 left = 0;
21089 }
21090 else if (val == 0)
21091 {
21092 printf ("0x0");
21093 left -= 3;
21094 }
9ef920e9 21095 else
75d7d298
NC
21096 {
21097 if (do_wide)
ddef72cd 21098 left -= printf ("0x%llx", val);
75d7d298 21099 else
ddef72cd 21100 left -= printf ("0x%-.*llx", left, val);
75d7d298 21101 }
9ef920e9
NC
21102 }
21103 break;
21104 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21105 left -= print_symbol (- left, name);
21106 break;
21107 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21108 left -= print_symbol (- left, "true");
21109 break;
21110 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21111 left -= print_symbol (- left, "false");
21112 break;
21113 }
21114
21115 if (do_wide && left > 0)
21116 printf ("%-*s", left, " ");
9abca702 21117
015dc7e1 21118 return true;
9ef920e9
NC
21119}
21120
6d118b09
NC
21121/* Note that by the ELF standard, the name field is already null byte
21122 terminated, and namesz includes the terminating null byte.
21123 I.E. the value of namesz for the name "FSF" is 4.
21124
e3c8793a 21125 If the value of namesz is zero, there is no name present. */
9ef920e9 21126
015dc7e1 21127static bool
9ef920e9 21128process_note (Elf_Internal_Note * pnote,
dda8d76d 21129 Filedata * filedata)
779fe533 21130{
2cf0635d
NC
21131 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21132 const char * nt;
9437c45b
JT
21133
21134 if (pnote->namesz == 0)
1ec5cd37
NC
21135 /* If there is no note name, then use the default set of
21136 note type strings. */
dda8d76d 21137 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21138
24d127aa 21139 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21140 /* GNU-specific object file notes. */
21141 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21142
24d127aa 21143 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21144 /* FreeBSD-specific core file notes. */
dda8d76d 21145 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21146
24d127aa 21147 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21148 /* NetBSD-specific core file notes. */
dda8d76d 21149 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21150
24d127aa 21151 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21152 /* NetBSD-specific core file notes. */
21153 return process_netbsd_elf_note (pnote);
21154
24d127aa 21155 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21156 /* NetBSD-specific core file notes. */
21157 return process_netbsd_elf_note (pnote);
21158
98ca73af
FC
21159 else if (startswith (pnote->namedata, "OpenBSD"))
21160 /* OpenBSD-specific core file notes. */
21161 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21162
e9b095a5 21163 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21164 {
21165 /* SPU-specific core file notes. */
21166 nt = pnote->namedata + 4;
21167 name = "SPU";
21168 }
21169
24d127aa 21170 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21171 /* VMS/ia64-specific file notes. */
21172 nt = get_ia64_vms_note_type (pnote->type);
21173
24d127aa 21174 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21175 nt = get_stapsdt_note_type (pnote->type);
21176
9437c45b 21177 else
1ec5cd37
NC
21178 /* Don't recognize this note name; just use the default set of
21179 note type strings. */
dda8d76d 21180 nt = get_note_type (filedata, pnote->type);
9437c45b 21181
1449284b 21182 printf (" ");
9ef920e9 21183
24d127aa 21184 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21185 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21186 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21187 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21188 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21189 print_gnu_build_attribute_name (pnote);
21190 else
21191 print_symbol (-20, name);
21192
21193 if (do_wide)
21194 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21195 else
21196 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21197
24d127aa 21198 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21199 return print_ia64_vms_note (pnote);
24d127aa 21200 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21201 return print_gnu_note (filedata, pnote);
24d127aa 21202 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21203 return print_stapsdt_note (pnote);
24d127aa 21204 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21205 return print_core_note (pnote);
e5382207
LB
21206 else if (startswith (pnote->namedata, "FDO"))
21207 return print_fdo_note (pnote);
24d127aa 21208 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21209 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21210 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21211 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21212 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21213 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 21214
9ef920e9 21215 if (pnote->descsz)
1449284b
NC
21216 {
21217 unsigned long i;
21218
21219 printf (_(" description data: "));
21220 for (i = 0; i < pnote->descsz; i++)
178d8719 21221 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
21222 if (!do_wide)
21223 printf ("\n");
1449284b
NC
21224 }
21225
9ef920e9
NC
21226 if (do_wide)
21227 printf ("\n");
21228
015dc7e1 21229 return true;
1449284b 21230}
6d118b09 21231
015dc7e1 21232static bool
dda8d76d
NC
21233process_notes_at (Filedata * filedata,
21234 Elf_Internal_Shdr * section,
21235 bfd_vma offset,
82ed9683
L
21236 bfd_vma length,
21237 bfd_vma align)
779fe533 21238{
015dc7e1
AM
21239 Elf_External_Note *pnotes;
21240 Elf_External_Note *external;
21241 char *end;
21242 bool res = true;
103f02d3 21243
779fe533 21244 if (length <= 0)
015dc7e1 21245 return false;
103f02d3 21246
1449284b
NC
21247 if (section)
21248 {
dda8d76d 21249 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21250 if (pnotes)
32ec8896 21251 {
dda8d76d 21252 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21253 {
21254 free (pnotes);
015dc7e1 21255 return false;
f761cb13 21256 }
32ec8896 21257 }
1449284b
NC
21258 }
21259 else
82ed9683 21260 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21261 _("notes"));
4dff97b2 21262
dd24e3da 21263 if (pnotes == NULL)
015dc7e1 21264 return false;
779fe533 21265
103f02d3 21266 external = pnotes;
103f02d3 21267
ca0e11aa
NC
21268 if (filedata->is_separate)
21269 printf (_("In linked file '%s': "), filedata->file_name);
21270 else
21271 printf ("\n");
1449284b 21272 if (section)
ca0e11aa 21273 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21274 else
ca0e11aa 21275 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21276 (unsigned long) offset, (unsigned long) length);
21277
82ed9683
L
21278 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21279 specifies that notes should be aligned to 4 bytes in 32-bit
21280 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21281 we also support 4 byte alignment in 64-bit objects. If section
21282 alignment is less than 4, we treate alignment as 4 bytes. */
21283 if (align < 4)
21284 align = 4;
21285 else if (align != 4 && align != 8)
21286 {
21287 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21288 (long) align);
a788aedd 21289 free (pnotes);
015dc7e1 21290 return false;
82ed9683
L
21291 }
21292
dbe15e4e 21293 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21294
c8071705
NC
21295 end = (char *) pnotes + length;
21296 while ((char *) external < end)
779fe533 21297 {
b34976b6 21298 Elf_Internal_Note inote;
15b42fb0 21299 size_t min_notesz;
4dff97b2 21300 char * next;
2cf0635d 21301 char * temp = NULL;
c8071705 21302 size_t data_remaining = end - (char *) external;
6d118b09 21303
dda8d76d 21304 if (!is_ia64_vms (filedata))
15b42fb0 21305 {
9dd3a467
NC
21306 /* PR binutils/15191
21307 Make sure that there is enough data to read. */
15b42fb0
AM
21308 min_notesz = offsetof (Elf_External_Note, name);
21309 if (data_remaining < min_notesz)
9dd3a467 21310 {
d3a49aa8
AM
21311 warn (ngettext ("Corrupt note: only %ld byte remains, "
21312 "not enough for a full note\n",
21313 "Corrupt note: only %ld bytes remain, "
21314 "not enough for a full note\n",
21315 data_remaining),
21316 (long) data_remaining);
9dd3a467
NC
21317 break;
21318 }
5396a86e
AM
21319 data_remaining -= min_notesz;
21320
15b42fb0
AM
21321 inote.type = BYTE_GET (external->type);
21322 inote.namesz = BYTE_GET (external->namesz);
21323 inote.namedata = external->name;
21324 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21325 inote.descdata = ((char *) external
4dff97b2 21326 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21327 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21328 next = ((char *) external
4dff97b2 21329 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21330 }
00e98fc7 21331 else
15b42fb0
AM
21332 {
21333 Elf64_External_VMS_Note *vms_external;
00e98fc7 21334
9dd3a467
NC
21335 /* PR binutils/15191
21336 Make sure that there is enough data to read. */
15b42fb0
AM
21337 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21338 if (data_remaining < min_notesz)
9dd3a467 21339 {
d3a49aa8
AM
21340 warn (ngettext ("Corrupt note: only %ld byte remains, "
21341 "not enough for a full note\n",
21342 "Corrupt note: only %ld bytes remain, "
21343 "not enough for a full note\n",
21344 data_remaining),
21345 (long) data_remaining);
9dd3a467
NC
21346 break;
21347 }
5396a86e 21348 data_remaining -= min_notesz;
3e55a963 21349
15b42fb0
AM
21350 vms_external = (Elf64_External_VMS_Note *) external;
21351 inote.type = BYTE_GET (vms_external->type);
21352 inote.namesz = BYTE_GET (vms_external->namesz);
21353 inote.namedata = vms_external->name;
21354 inote.descsz = BYTE_GET (vms_external->descsz);
21355 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21356 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21357 next = inote.descdata + align_power (inote.descsz, 3);
21358 }
21359
5396a86e
AM
21360 /* PR 17531: file: 3443835e. */
21361 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21362 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21363 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21364 || (size_t) (next - inote.descdata) < inote.descsz
21365 || ((size_t) (next - inote.descdata)
21366 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21367 {
15b42fb0 21368 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21369 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21370 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21371 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21372 break;
21373 }
21374
15b42fb0 21375 external = (Elf_External_Note *) next;
dd24e3da 21376
6d118b09
NC
21377 /* Verify that name is null terminated. It appears that at least
21378 one version of Linux (RedHat 6.0) generates corefiles that don't
21379 comply with the ELF spec by failing to include the null byte in
21380 namesz. */
18344509 21381 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21382 {
5396a86e 21383 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21384 {
5396a86e
AM
21385 temp = (char *) malloc (inote.namesz + 1);
21386 if (temp == NULL)
21387 {
21388 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21389 res = false;
5396a86e
AM
21390 break;
21391 }
76da6bbe 21392
5396a86e
AM
21393 memcpy (temp, inote.namedata, inote.namesz);
21394 inote.namedata = temp;
21395 }
21396 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21397 }
21398
dda8d76d 21399 if (! process_note (& inote, filedata))
015dc7e1 21400 res = false;
103f02d3 21401
9db70fc3
AM
21402 free (temp);
21403 temp = NULL;
779fe533
NC
21404 }
21405
21406 free (pnotes);
103f02d3 21407
779fe533
NC
21408 return res;
21409}
21410
015dc7e1 21411static bool
dda8d76d 21412process_corefile_note_segments (Filedata * filedata)
779fe533 21413{
015dc7e1 21414 Elf_Internal_Phdr *segment;
b34976b6 21415 unsigned int i;
015dc7e1 21416 bool res = true;
103f02d3 21417
dda8d76d 21418 if (! get_program_headers (filedata))
015dc7e1 21419 return true;
103f02d3 21420
dda8d76d
NC
21421 for (i = 0, segment = filedata->program_headers;
21422 i < filedata->file_header.e_phnum;
b34976b6 21423 i++, segment++)
779fe533
NC
21424 {
21425 if (segment->p_type == PT_NOTE)
dda8d76d 21426 if (! process_notes_at (filedata, NULL,
32ec8896 21427 (bfd_vma) segment->p_offset,
82ed9683
L
21428 (bfd_vma) segment->p_filesz,
21429 (bfd_vma) segment->p_align))
015dc7e1 21430 res = false;
779fe533 21431 }
103f02d3 21432
779fe533
NC
21433 return res;
21434}
21435
015dc7e1 21436static bool
dda8d76d 21437process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21438{
21439 Elf_External_Note * pnotes;
21440 Elf_External_Note * external;
c8071705 21441 char * end;
015dc7e1 21442 bool res = true;
685080f2
NC
21443
21444 if (length <= 0)
015dc7e1 21445 return false;
685080f2 21446
dda8d76d 21447 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21448 _("v850 notes"));
21449 if (pnotes == NULL)
015dc7e1 21450 return false;
685080f2
NC
21451
21452 external = pnotes;
c8071705 21453 end = (char*) pnotes + length;
685080f2
NC
21454
21455 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21456 (unsigned long) offset, (unsigned long) length);
21457
c8071705 21458 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21459 {
21460 Elf_External_Note * next;
21461 Elf_Internal_Note inote;
21462
21463 inote.type = BYTE_GET (external->type);
21464 inote.namesz = BYTE_GET (external->namesz);
21465 inote.namedata = external->name;
21466 inote.descsz = BYTE_GET (external->descsz);
21467 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21468 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21469
c8071705
NC
21470 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21471 {
21472 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21473 inote.descdata = inote.namedata;
21474 inote.namesz = 0;
21475 }
21476
685080f2
NC
21477 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21478
c8071705 21479 if ( ((char *) next > end)
685080f2
NC
21480 || ((char *) next < (char *) pnotes))
21481 {
21482 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21483 (unsigned long) ((char *) external - (char *) pnotes));
21484 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21485 inote.type, inote.namesz, inote.descsz);
21486 break;
21487 }
21488
21489 external = next;
21490
21491 /* Prevent out-of-bounds indexing. */
c8071705 21492 if ( inote.namedata + inote.namesz > end
685080f2
NC
21493 || inote.namedata + inote.namesz < inote.namedata)
21494 {
21495 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21496 (unsigned long) ((char *) external - (char *) pnotes));
21497 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21498 inote.type, inote.namesz, inote.descsz);
21499 break;
21500 }
21501
21502 printf (" %s: ", get_v850_elf_note_type (inote.type));
21503
21504 if (! print_v850_note (& inote))
21505 {
015dc7e1 21506 res = false;
685080f2
NC
21507 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21508 inote.namesz, inote.descsz);
21509 }
21510 }
21511
21512 free (pnotes);
21513
21514 return res;
21515}
21516
015dc7e1 21517static bool
dda8d76d 21518process_note_sections (Filedata * filedata)
1ec5cd37 21519{
015dc7e1 21520 Elf_Internal_Shdr *section;
1ec5cd37 21521 unsigned long i;
32ec8896 21522 unsigned int n = 0;
015dc7e1 21523 bool res = true;
1ec5cd37 21524
dda8d76d
NC
21525 for (i = 0, section = filedata->section_headers;
21526 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21527 i++, section++)
685080f2
NC
21528 {
21529 if (section->sh_type == SHT_NOTE)
21530 {
dda8d76d 21531 if (! process_notes_at (filedata, section,
32ec8896 21532 (bfd_vma) section->sh_offset,
82ed9683
L
21533 (bfd_vma) section->sh_size,
21534 (bfd_vma) section->sh_addralign))
015dc7e1 21535 res = false;
685080f2
NC
21536 n++;
21537 }
21538
dda8d76d
NC
21539 if (( filedata->file_header.e_machine == EM_V800
21540 || filedata->file_header.e_machine == EM_V850
21541 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21542 && section->sh_type == SHT_RENESAS_INFO)
21543 {
dda8d76d 21544 if (! process_v850_notes (filedata,
32ec8896
NC
21545 (bfd_vma) section->sh_offset,
21546 (bfd_vma) section->sh_size))
015dc7e1 21547 res = false;
685080f2
NC
21548 n++;
21549 }
21550 }
df565f32
NC
21551
21552 if (n == 0)
21553 /* Try processing NOTE segments instead. */
dda8d76d 21554 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21555
21556 return res;
21557}
21558
015dc7e1 21559static bool
dda8d76d 21560process_notes (Filedata * filedata)
779fe533
NC
21561{
21562 /* If we have not been asked to display the notes then do nothing. */
21563 if (! do_notes)
015dc7e1 21564 return true;
103f02d3 21565
dda8d76d
NC
21566 if (filedata->file_header.e_type != ET_CORE)
21567 return process_note_sections (filedata);
103f02d3 21568
779fe533 21569 /* No program headers means no NOTE segment. */
dda8d76d
NC
21570 if (filedata->file_header.e_phnum > 0)
21571 return process_corefile_note_segments (filedata);
779fe533 21572
ca0e11aa
NC
21573 if (filedata->is_separate)
21574 printf (_("No notes found in linked file '%s'.\n"),
21575 filedata->file_name);
21576 else
21577 printf (_("No notes found file.\n"));
21578
015dc7e1 21579 return true;
779fe533
NC
21580}
21581
60abdbed
NC
21582static unsigned char *
21583display_public_gnu_attributes (unsigned char * start,
21584 const unsigned char * const end)
21585{
21586 printf (_(" Unknown GNU attribute: %s\n"), start);
21587
21588 start += strnlen ((char *) start, end - start);
21589 display_raw_attribute (start, end);
21590
21591 return (unsigned char *) end;
21592}
21593
21594static unsigned char *
21595display_generic_attribute (unsigned char * start,
21596 unsigned int tag,
21597 const unsigned char * const end)
21598{
21599 if (tag == 0)
21600 return (unsigned char *) end;
21601
21602 return display_tag_value (tag, start, end);
21603}
21604
015dc7e1 21605static bool
dda8d76d 21606process_arch_specific (Filedata * filedata)
252b5132 21607{
a952a375 21608 if (! do_arch)
015dc7e1 21609 return true;
a952a375 21610
dda8d76d 21611 switch (filedata->file_header.e_machine)
252b5132 21612 {
53a346d8
CZ
21613 case EM_ARC:
21614 case EM_ARC_COMPACT:
21615 case EM_ARC_COMPACT2:
dda8d76d 21616 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21617 display_arc_attribute,
21618 display_generic_attribute);
11c1ff18 21619 case EM_ARM:
dda8d76d 21620 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21621 display_arm_attribute,
21622 display_generic_attribute);
21623
252b5132 21624 case EM_MIPS:
4fe85591 21625 case EM_MIPS_RS3_LE:
dda8d76d 21626 return process_mips_specific (filedata);
60abdbed
NC
21627
21628 case EM_MSP430:
dda8d76d 21629 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21630 display_msp430_attribute,
c0ea7c52 21631 display_msp430_gnu_attribute);
60abdbed 21632
2dc8dd17
JW
21633 case EM_RISCV:
21634 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21635 display_riscv_attribute,
21636 display_generic_attribute);
21637
35c08157 21638 case EM_NDS32:
dda8d76d 21639 return process_nds32_specific (filedata);
60abdbed 21640
85f7484a
PB
21641 case EM_68K:
21642 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21643 display_m68k_gnu_attribute);
21644
34c8bcba 21645 case EM_PPC:
b82317dd 21646 case EM_PPC64:
dda8d76d 21647 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21648 display_power_gnu_attribute);
21649
643f7afb
AK
21650 case EM_S390:
21651 case EM_S390_OLD:
dda8d76d 21652 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21653 display_s390_gnu_attribute);
21654
9e8c70f9
DM
21655 case EM_SPARC:
21656 case EM_SPARC32PLUS:
21657 case EM_SPARCV9:
dda8d76d 21658 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21659 display_sparc_gnu_attribute);
21660
59e6276b 21661 case EM_TI_C6000:
dda8d76d 21662 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21663 display_tic6x_attribute,
21664 display_generic_attribute);
21665
0861f561
CQ
21666 case EM_CSKY:
21667 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21668 display_csky_attribute, NULL);
21669
252b5132 21670 default:
dda8d76d 21671 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21672 display_public_gnu_attributes,
21673 display_generic_attribute);
252b5132 21674 }
252b5132
RH
21675}
21676
015dc7e1 21677static bool
dda8d76d 21678get_file_header (Filedata * filedata)
252b5132 21679{
9ea033b2 21680 /* Read in the identity array. */
dda8d76d 21681 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21682 return false;
252b5132 21683
9ea033b2 21684 /* Determine how to read the rest of the header. */
dda8d76d 21685 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21686 {
1a0670f3
AM
21687 default:
21688 case ELFDATANONE:
adab8cdc
AO
21689 case ELFDATA2LSB:
21690 byte_get = byte_get_little_endian;
21691 byte_put = byte_put_little_endian;
21692 break;
21693 case ELFDATA2MSB:
21694 byte_get = byte_get_big_endian;
21695 byte_put = byte_put_big_endian;
21696 break;
9ea033b2
NC
21697 }
21698
21699 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21700 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21701
21702 /* Read in the rest of the header. */
21703 if (is_32bit_elf)
21704 {
21705 Elf32_External_Ehdr ehdr32;
252b5132 21706
dda8d76d 21707 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21708 return false;
103f02d3 21709
dda8d76d
NC
21710 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21711 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21712 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21713 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21714 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21715 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21716 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21717 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21718 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21719 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21720 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21721 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21722 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21723 }
252b5132 21724 else
9ea033b2
NC
21725 {
21726 Elf64_External_Ehdr ehdr64;
a952a375
NC
21727
21728 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21729 we will not be able to cope with the 64bit data found in
21730 64 ELF files. Detect this now and abort before we start
50c2245b 21731 overwriting things. */
a952a375
NC
21732 if (sizeof (bfd_vma) < 8)
21733 {
e3c8793a
NC
21734 error (_("This instance of readelf has been built without support for a\n\
2173564 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21736 return false;
a952a375 21737 }
103f02d3 21738
dda8d76d 21739 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21740 return false;
103f02d3 21741
dda8d76d
NC
21742 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21743 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21744 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21745 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21746 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21747 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21748 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21749 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21750 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21751 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21752 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21753 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21754 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21755 }
252b5132 21756
015dc7e1 21757 return true;
252b5132
RH
21758}
21759
13acb58d
AM
21760static void
21761free_filedata (Filedata *filedata)
21762{
21763 free (filedata->program_interpreter);
13acb58d 21764 free (filedata->program_headers);
13acb58d 21765 free (filedata->section_headers);
13acb58d 21766 free (filedata->string_table);
13acb58d 21767 free (filedata->dump.dump_sects);
13acb58d 21768 free (filedata->dynamic_strings);
13acb58d 21769 free (filedata->dynamic_symbols);
13acb58d 21770 free (filedata->dynamic_syminfo);
13acb58d 21771 free (filedata->dynamic_section);
13acb58d
AM
21772
21773 while (filedata->symtab_shndx_list != NULL)
21774 {
21775 elf_section_list *next = filedata->symtab_shndx_list->next;
21776 free (filedata->symtab_shndx_list);
21777 filedata->symtab_shndx_list = next;
21778 }
21779
21780 free (filedata->section_headers_groups);
13acb58d
AM
21781
21782 if (filedata->section_groups)
21783 {
21784 size_t i;
21785 struct group_list * g;
21786 struct group_list * next;
21787
21788 for (i = 0; i < filedata->group_count; i++)
21789 {
21790 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21791 {
21792 next = g->next;
21793 free (g);
21794 }
21795 }
21796
21797 free (filedata->section_groups);
13acb58d 21798 }
066f8fbe
AM
21799 memset (&filedata->section_headers, 0,
21800 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21801}
21802
dda8d76d
NC
21803static void
21804close_file (Filedata * filedata)
21805{
21806 if (filedata)
21807 {
21808 if (filedata->handle)
21809 fclose (filedata->handle);
21810 free (filedata);
21811 }
21812}
21813
21814void
21815close_debug_file (void * data)
21816{
13acb58d 21817 free_filedata ((Filedata *) data);
dda8d76d
NC
21818 close_file ((Filedata *) data);
21819}
21820
21821static Filedata *
015dc7e1 21822open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21823{
21824 struct stat statbuf;
21825 Filedata * filedata = NULL;
21826
21827 if (stat (pathname, & statbuf) < 0
21828 || ! S_ISREG (statbuf.st_mode))
21829 goto fail;
21830
21831 filedata = calloc (1, sizeof * filedata);
21832 if (filedata == NULL)
21833 goto fail;
21834
21835 filedata->handle = fopen (pathname, "rb");
21836 if (filedata->handle == NULL)
21837 goto fail;
21838
21839 filedata->file_size = (bfd_size_type) statbuf.st_size;
21840 filedata->file_name = pathname;
ca0e11aa 21841 filedata->is_separate = is_separate;
dda8d76d
NC
21842
21843 if (! get_file_header (filedata))
21844 goto fail;
21845
4de91c10
AM
21846 if (!get_section_headers (filedata, false))
21847 goto fail;
dda8d76d
NC
21848
21849 return filedata;
21850
21851 fail:
21852 if (filedata)
21853 {
21854 if (filedata->handle)
21855 fclose (filedata->handle);
21856 free (filedata);
21857 }
21858 return NULL;
21859}
21860
21861void *
21862open_debug_file (const char * pathname)
21863{
015dc7e1 21864 return open_file (pathname, true);
dda8d76d
NC
21865}
21866
835f2fae
NC
21867static void
21868initialise_dump_sects (Filedata * filedata)
21869{
21870 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21871 Note we do this even if cmdline_dump_sects is empty because we
21872 must make sure that the dump_sets array is zeroed out before each
21873 object file is processed. */
21874 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21875 memset (filedata->dump.dump_sects, 0,
21876 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21877
21878 if (cmdline.num_dump_sects > 0)
21879 {
21880 if (filedata->dump.num_dump_sects == 0)
21881 /* A sneaky way of allocating the dump_sects array. */
21882 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21883
21884 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21885 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21886 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21887 }
21888}
21889
fb52b2f4
NC
21890/* Process one ELF object file according to the command line options.
21891 This file may actually be stored in an archive. The file is
32ec8896
NC
21892 positioned at the start of the ELF object. Returns TRUE if no
21893 problems were encountered, FALSE otherwise. */
fb52b2f4 21894
015dc7e1 21895static bool
dda8d76d 21896process_object (Filedata * filedata)
252b5132 21897{
015dc7e1 21898 bool have_separate_files;
252b5132 21899 unsigned int i;
015dc7e1 21900 bool res;
252b5132 21901
dda8d76d 21902 if (! get_file_header (filedata))
252b5132 21903 {
dda8d76d 21904 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21905 return false;
252b5132
RH
21906 }
21907
21908 /* Initialise per file variables. */
978c4450
AM
21909 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21910 filedata->version_info[i] = 0;
252b5132 21911
978c4450
AM
21912 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21913 filedata->dynamic_info[i] = 0;
21914 filedata->dynamic_info_DT_GNU_HASH = 0;
21915 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21916
21917 /* Process the file. */
21918 if (show_name)
dda8d76d 21919 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21920
835f2fae 21921 initialise_dump_sects (filedata);
d70c5fc7 21922
4de91c10
AM
21923 /* There may be some extensions in the first section header. Don't
21924 bomb if we can't read it. */
21925 get_section_headers (filedata, true);
21926
dda8d76d 21927 if (! process_file_header (filedata))
4de91c10
AM
21928 {
21929 res = false;
21930 goto out;
21931 }
252b5132 21932
e331b18d
AM
21933 /* Throw away the single section header read above, so that we
21934 re-read the entire set. */
21935 free (filedata->section_headers);
21936 filedata->section_headers = NULL;
21937
dda8d76d 21938 if (! process_section_headers (filedata))
2f62977e 21939 {
32ec8896 21940 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21941 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21942
2f62977e 21943 if (! do_using_dynamic)
015dc7e1 21944 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21945 }
252b5132 21946
dda8d76d 21947 if (! process_section_groups (filedata))
32ec8896 21948 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21949 do_unwind = false;
d1f5c6e3 21950
93df3340
AM
21951 process_program_headers (filedata);
21952
21953 res = process_dynamic_section (filedata);
252b5132 21954
dda8d76d 21955 if (! process_relocs (filedata))
015dc7e1 21956 res = false;
252b5132 21957
dda8d76d 21958 if (! process_unwind (filedata))
015dc7e1 21959 res = false;
4d6ed7c8 21960
dda8d76d 21961 if (! process_symbol_table (filedata))
015dc7e1 21962 res = false;
252b5132 21963
0f03783c 21964 if (! process_lto_symbol_tables (filedata))
015dc7e1 21965 res = false;
b9e920ec 21966
dda8d76d 21967 if (! process_syminfo (filedata))
015dc7e1 21968 res = false;
252b5132 21969
dda8d76d 21970 if (! process_version_sections (filedata))
015dc7e1 21971 res = false;
252b5132 21972
82ed9683 21973 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21974 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21975 else
015dc7e1 21976 have_separate_files = false;
dda8d76d
NC
21977
21978 if (! process_section_contents (filedata))
015dc7e1 21979 res = false;
f5842774 21980
24841daa 21981 if (have_separate_files)
dda8d76d 21982 {
24841daa
NC
21983 separate_info * d;
21984
21985 for (d = first_separate_info; d != NULL; d = d->next)
21986 {
835f2fae
NC
21987 initialise_dump_sects (d->handle);
21988
ca0e11aa 21989 if (process_links && ! process_file_header (d->handle))
015dc7e1 21990 res = false;
ca0e11aa 21991 else if (! process_section_headers (d->handle))
015dc7e1 21992 res = false;
d6bfbc39 21993 else if (! process_section_contents (d->handle))
015dc7e1 21994 res = false;
ca0e11aa
NC
21995 else if (process_links)
21996 {
ca0e11aa 21997 if (! process_section_groups (d->handle))
015dc7e1 21998 res = false;
93df3340 21999 process_program_headers (d->handle);
ca0e11aa 22000 if (! process_dynamic_section (d->handle))
015dc7e1 22001 res = false;
ca0e11aa 22002 if (! process_relocs (d->handle))
015dc7e1 22003 res = false;
ca0e11aa 22004 if (! process_unwind (d->handle))
015dc7e1 22005 res = false;
ca0e11aa 22006 if (! process_symbol_table (d->handle))
015dc7e1 22007 res = false;
ca0e11aa 22008 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22009 res = false;
ca0e11aa 22010 if (! process_syminfo (d->handle))
015dc7e1 22011 res = false;
ca0e11aa 22012 if (! process_version_sections (d->handle))
015dc7e1 22013 res = false;
ca0e11aa 22014 if (! process_notes (d->handle))
015dc7e1 22015 res = false;
ca0e11aa 22016 }
24841daa
NC
22017 }
22018
22019 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22020 }
22021
22022 if (! process_notes (filedata))
015dc7e1 22023 res = false;
103f02d3 22024
dda8d76d 22025 if (! process_gnu_liblist (filedata))
015dc7e1 22026 res = false;
047b2264 22027
dda8d76d 22028 if (! process_arch_specific (filedata))
015dc7e1 22029 res = false;
252b5132 22030
4de91c10 22031 out:
13acb58d 22032 free_filedata (filedata);
e4b17d5c 22033
19e6b90e 22034 free_debug_memory ();
18bd398b 22035
32ec8896 22036 return res;
252b5132
RH
22037}
22038
2cf0635d 22039/* Process an ELF archive.
32ec8896
NC
22040 On entry the file is positioned just after the ARMAG string.
22041 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22042
015dc7e1
AM
22043static bool
22044process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22045{
22046 struct archive_info arch;
22047 struct archive_info nested_arch;
22048 size_t got;
015dc7e1 22049 bool ret = true;
2cf0635d 22050
015dc7e1 22051 show_name = true;
2cf0635d
NC
22052
22053 /* The ARCH structure is used to hold information about this archive. */
22054 arch.file_name = NULL;
22055 arch.file = NULL;
22056 arch.index_array = NULL;
22057 arch.sym_table = NULL;
22058 arch.longnames = NULL;
22059
22060 /* The NESTED_ARCH structure is used as a single-item cache of information
22061 about a nested archive (when members of a thin archive reside within
22062 another regular archive file). */
22063 nested_arch.file_name = NULL;
22064 nested_arch.file = NULL;
22065 nested_arch.index_array = NULL;
22066 nested_arch.sym_table = NULL;
22067 nested_arch.longnames = NULL;
22068
dda8d76d 22069 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22070 filedata->file_size, is_thin_archive,
22071 do_archive_index) != 0)
2cf0635d 22072 {
015dc7e1 22073 ret = false;
2cf0635d 22074 goto out;
4145f1d5 22075 }
fb52b2f4 22076
4145f1d5
NC
22077 if (do_archive_index)
22078 {
2cf0635d 22079 if (arch.sym_table == NULL)
1cb7d8b1
AM
22080 error (_("%s: unable to dump the index as none was found\n"),
22081 filedata->file_name);
4145f1d5
NC
22082 else
22083 {
591f7597 22084 unsigned long i, l;
4145f1d5
NC
22085 unsigned long current_pos;
22086
1cb7d8b1
AM
22087 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22088 "in the symbol table)\n"),
22089 filedata->file_name, (unsigned long) arch.index_num,
22090 arch.sym_size);
dda8d76d
NC
22091
22092 current_pos = ftell (filedata->handle);
4145f1d5 22093
2cf0635d 22094 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22095 {
1cb7d8b1
AM
22096 if (i == 0
22097 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22098 {
22099 char * member_name
22100 = get_archive_member_name_at (&arch, arch.index_array[i],
22101 &nested_arch);
2cf0635d 22102
1cb7d8b1
AM
22103 if (member_name != NULL)
22104 {
22105 char * qualified_name
22106 = make_qualified_name (&arch, &nested_arch,
22107 member_name);
2cf0635d 22108
1cb7d8b1
AM
22109 if (qualified_name != NULL)
22110 {
22111 printf (_("Contents of binary %s at offset "),
22112 qualified_name);
c2a7d3f5
NC
22113 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22114 putchar ('\n');
1cb7d8b1
AM
22115 free (qualified_name);
22116 }
fd486f32 22117 free (member_name);
4145f1d5
NC
22118 }
22119 }
2cf0635d
NC
22120
22121 if (l >= arch.sym_size)
4145f1d5 22122 {
1cb7d8b1
AM
22123 error (_("%s: end of the symbol table reached "
22124 "before the end of the index\n"),
dda8d76d 22125 filedata->file_name);
015dc7e1 22126 ret = false;
cb8f3167 22127 break;
4145f1d5 22128 }
591f7597 22129 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22130 printf ("\t%.*s\n",
22131 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22132 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22133 }
22134
67ce483b 22135 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22136 l = (l + 7) & ~ 7;
22137 else
22138 l += l & 1;
22139
2cf0635d 22140 if (l < arch.sym_size)
32ec8896 22141 {
d3a49aa8
AM
22142 error (ngettext ("%s: %ld byte remains in the symbol table, "
22143 "but without corresponding entries in "
22144 "the index table\n",
22145 "%s: %ld bytes remain in the symbol table, "
22146 "but without corresponding entries in "
22147 "the index table\n",
22148 arch.sym_size - l),
dda8d76d 22149 filedata->file_name, arch.sym_size - l);
015dc7e1 22150 ret = false;
32ec8896 22151 }
4145f1d5 22152
dda8d76d 22153 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22154 {
1cb7d8b1
AM
22155 error (_("%s: failed to seek back to start of object files "
22156 "in the archive\n"),
dda8d76d 22157 filedata->file_name);
015dc7e1 22158 ret = false;
2cf0635d 22159 goto out;
4145f1d5 22160 }
fb52b2f4 22161 }
4145f1d5
NC
22162
22163 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22164 && !do_segments && !do_header && !do_dump && !do_version
22165 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22166 && !do_section_groups && !do_dyn_syms)
2cf0635d 22167 {
015dc7e1 22168 ret = true; /* Archive index only. */
2cf0635d
NC
22169 goto out;
22170 }
fb52b2f4
NC
22171 }
22172
fb52b2f4
NC
22173 while (1)
22174 {
2cf0635d
NC
22175 char * name;
22176 size_t namelen;
22177 char * qualified_name;
22178
22179 /* Read the next archive header. */
dda8d76d 22180 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22181 {
22182 error (_("%s: failed to seek to next archive header\n"),
22183 arch.file_name);
015dc7e1 22184 ret = false;
1cb7d8b1
AM
22185 break;
22186 }
dda8d76d 22187 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22188 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22189 {
22190 if (got == 0)
2cf0635d 22191 break;
28e817cc
NC
22192 /* PR 24049 - we cannot use filedata->file_name as this will
22193 have already been freed. */
22194 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22195
015dc7e1 22196 ret = false;
1cb7d8b1
AM
22197 break;
22198 }
2cf0635d 22199 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22200 {
22201 error (_("%s: did not find a valid archive header\n"),
22202 arch.file_name);
015dc7e1 22203 ret = false;
1cb7d8b1
AM
22204 break;
22205 }
2cf0635d
NC
22206
22207 arch.next_arhdr_offset += sizeof arch.arhdr;
22208
978c4450 22209 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22210
22211 name = get_archive_member_name (&arch, &nested_arch);
22212 if (name == NULL)
fb52b2f4 22213 {
28e817cc 22214 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22215 ret = false;
d989285c 22216 break;
fb52b2f4 22217 }
2cf0635d 22218 namelen = strlen (name);
fb52b2f4 22219
2cf0635d
NC
22220 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22221 if (qualified_name == NULL)
fb52b2f4 22222 {
28e817cc 22223 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22224 free (name);
015dc7e1 22225 ret = false;
d989285c 22226 break;
fb52b2f4
NC
22227 }
22228
2cf0635d 22229 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22230 {
22231 /* This is a proxy for an external member of a thin archive. */
22232 Filedata * member_filedata;
22233 char * member_file_name = adjust_relative_path
dda8d76d 22234 (filedata->file_name, name, namelen);
32ec8896 22235
fd486f32 22236 free (name);
1cb7d8b1
AM
22237 if (member_file_name == NULL)
22238 {
fd486f32 22239 free (qualified_name);
015dc7e1 22240 ret = false;
1cb7d8b1
AM
22241 break;
22242 }
2cf0635d 22243
015dc7e1 22244 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22245 if (member_filedata == NULL)
22246 {
22247 error (_("Input file '%s' is not readable.\n"), member_file_name);
22248 free (member_file_name);
fd486f32 22249 free (qualified_name);
015dc7e1 22250 ret = false;
1cb7d8b1
AM
22251 break;
22252 }
2cf0635d 22253
978c4450 22254 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22255 member_filedata->file_name = qualified_name;
2cf0635d 22256
75a2da57
AH
22257 /* The call to process_object() expects the file to be at the beginning. */
22258 rewind (member_filedata->handle);
22259
1cb7d8b1 22260 if (! process_object (member_filedata))
015dc7e1 22261 ret = false;
2cf0635d 22262
1cb7d8b1
AM
22263 close_file (member_filedata);
22264 free (member_file_name);
1cb7d8b1 22265 }
2cf0635d 22266 else if (is_thin_archive)
1cb7d8b1
AM
22267 {
22268 Filedata thin_filedata;
eb02c04d 22269
1cb7d8b1 22270 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22271
a043396b
NC
22272 /* PR 15140: Allow for corrupt thin archives. */
22273 if (nested_arch.file == NULL)
22274 {
22275 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22276 qualified_name, name);
fd486f32
AM
22277 free (qualified_name);
22278 free (name);
015dc7e1 22279 ret = false;
a043396b
NC
22280 break;
22281 }
fd486f32 22282 free (name);
a043396b 22283
1cb7d8b1 22284 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22285 filedata->archive_file_offset
22286 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22287
1cb7d8b1
AM
22288 /* The nested archive file will have been opened and setup by
22289 get_archive_member_name. */
978c4450
AM
22290 if (fseek (nested_arch.file, filedata->archive_file_offset,
22291 SEEK_SET) != 0)
1cb7d8b1
AM
22292 {
22293 error (_("%s: failed to seek to archive member.\n"),
22294 nested_arch.file_name);
fd486f32 22295 free (qualified_name);
015dc7e1 22296 ret = false;
1cb7d8b1
AM
22297 break;
22298 }
2cf0635d 22299
dda8d76d
NC
22300 thin_filedata.handle = nested_arch.file;
22301 thin_filedata.file_name = qualified_name;
9abca702 22302
1cb7d8b1 22303 if (! process_object (& thin_filedata))
015dc7e1 22304 ret = false;
1cb7d8b1 22305 }
2cf0635d 22306 else
1cb7d8b1 22307 {
fd486f32 22308 free (name);
978c4450 22309 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22310 filedata->file_name = qualified_name;
1cb7d8b1 22311 if (! process_object (filedata))
015dc7e1 22312 ret = false;
237877b8 22313 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22314 /* Stop looping with "negative" archive_file_size. */
978c4450 22315 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22316 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22317 }
fb52b2f4 22318
2cf0635d 22319 free (qualified_name);
fb52b2f4
NC
22320 }
22321
4145f1d5 22322 out:
2cf0635d
NC
22323 if (nested_arch.file != NULL)
22324 fclose (nested_arch.file);
22325 release_archive (&nested_arch);
22326 release_archive (&arch);
fb52b2f4 22327
d989285c 22328 return ret;
fb52b2f4
NC
22329}
22330
015dc7e1 22331static bool
2cf0635d 22332process_file (char * file_name)
fb52b2f4 22333{
dda8d76d 22334 Filedata * filedata = NULL;
fb52b2f4
NC
22335 struct stat statbuf;
22336 char armag[SARMAG];
015dc7e1 22337 bool ret = true;
fb52b2f4
NC
22338
22339 if (stat (file_name, &statbuf) < 0)
22340 {
f24ddbdd
NC
22341 if (errno == ENOENT)
22342 error (_("'%s': No such file\n"), file_name);
22343 else
22344 error (_("Could not locate '%s'. System error message: %s\n"),
22345 file_name, strerror (errno));
015dc7e1 22346 return false;
f24ddbdd
NC
22347 }
22348
22349 if (! S_ISREG (statbuf.st_mode))
22350 {
22351 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22352 return false;
fb52b2f4
NC
22353 }
22354
dda8d76d
NC
22355 filedata = calloc (1, sizeof * filedata);
22356 if (filedata == NULL)
22357 {
22358 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22359 return false;
dda8d76d
NC
22360 }
22361
22362 filedata->file_name = file_name;
22363 filedata->handle = fopen (file_name, "rb");
22364 if (filedata->handle == NULL)
fb52b2f4 22365 {
f24ddbdd 22366 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22367 free (filedata);
015dc7e1 22368 return false;
fb52b2f4
NC
22369 }
22370
dda8d76d 22371 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22372 {
4145f1d5 22373 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22374 fclose (filedata->handle);
22375 free (filedata);
015dc7e1 22376 return false;
fb52b2f4
NC
22377 }
22378
dda8d76d 22379 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22380 filedata->is_separate = false;
f54498b4 22381
fb52b2f4 22382 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22383 {
015dc7e1
AM
22384 if (! process_archive (filedata, false))
22385 ret = false;
32ec8896 22386 }
2cf0635d 22387 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22388 {
015dc7e1
AM
22389 if ( ! process_archive (filedata, true))
22390 ret = false;
32ec8896 22391 }
fb52b2f4
NC
22392 else
22393 {
1b513401 22394 if (do_archive_index && !check_all)
4145f1d5
NC
22395 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22396 file_name);
22397
dda8d76d 22398 rewind (filedata->handle);
978c4450 22399 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22400
dda8d76d 22401 if (! process_object (filedata))
015dc7e1 22402 ret = false;
fb52b2f4
NC
22403 }
22404
dda8d76d 22405 fclose (filedata->handle);
8fb879cd
AM
22406 free (filedata->section_headers);
22407 free (filedata->program_headers);
22408 free (filedata->string_table);
6431e409 22409 free (filedata->dump.dump_sects);
dda8d76d 22410 free (filedata);
32ec8896 22411
fd486f32 22412 free (ba_cache.strtab);
1bd6175a 22413 ba_cache.strtab = NULL;
fd486f32 22414 free (ba_cache.symtab);
1bd6175a 22415 ba_cache.symtab = NULL;
fd486f32
AM
22416 ba_cache.filedata = NULL;
22417
fb52b2f4
NC
22418 return ret;
22419}
22420
252b5132
RH
22421#ifdef SUPPORT_DISASSEMBLY
22422/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22423 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22424 symbols. */
252b5132
RH
22425
22426void
2cf0635d 22427print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22428{
22429 fprintf (outfile,"0x%8.8x", addr);
22430}
22431
e3c8793a 22432/* Needed by the i386 disassembler. */
dda8d76d 22433
252b5132
RH
22434void
22435db_task_printsym (unsigned int addr)
22436{
22437 print_address (addr, stderr);
22438}
22439#endif
22440
22441int
2cf0635d 22442main (int argc, char ** argv)
252b5132 22443{
ff78d6d6
L
22444 int err;
22445
87b9f255 22446#ifdef HAVE_LC_MESSAGES
252b5132 22447 setlocale (LC_MESSAGES, "");
3882b010 22448#endif
3882b010 22449 setlocale (LC_CTYPE, "");
252b5132
RH
22450 bindtextdomain (PACKAGE, LOCALEDIR);
22451 textdomain (PACKAGE);
22452
869b9d07
MM
22453 expandargv (&argc, &argv);
22454
dda8d76d 22455 parse_args (& cmdline, argc, argv);
59f14fc0 22456
18bd398b 22457 if (optind < (argc - 1))
1b513401
NC
22458 /* When displaying information for more than one file,
22459 prefix the information with the file name. */
015dc7e1 22460 show_name = true;
5656ba2c
L
22461 else if (optind >= argc)
22462 {
1b513401 22463 /* Ensure that the warning is always displayed. */
015dc7e1 22464 do_checks = true;
1b513401 22465
5656ba2c
L
22466 warn (_("Nothing to do.\n"));
22467 usage (stderr);
22468 }
18bd398b 22469
015dc7e1 22470 err = false;
252b5132 22471 while (optind < argc)
32ec8896 22472 if (! process_file (argv[optind++]))
015dc7e1 22473 err = true;
252b5132 22474
9db70fc3 22475 free (cmdline.dump_sects);
252b5132 22476
7d9813f1
NA
22477 free (dump_ctf_symtab_name);
22478 free (dump_ctf_strtab_name);
22479 free (dump_ctf_parent_name);
22480
32ec8896 22481 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22482}