]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
binutils/readelf: handle AMDGPU OS ABIs
[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 4286 {
37870be8
SM
4287 case EM_AMDGPU:
4288 switch (osabi)
4289 {
4290 case ELFOSABI_AMDGPU_HSA: return "AMD HSA";
4291 case ELFOSABI_AMDGPU_PAL: return "AMD PAL";
4292 case ELFOSABI_AMDGPU_MESA3D: return "AMD Mesa3D";
4293 default:
4294 break;
4295 }
4296 break;
4297
40b36596
JM
4298 case EM_ARM:
4299 switch (osabi)
4300 {
4301 case ELFOSABI_ARM: return "ARM";
18a20338 4302 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
4303 default:
4304 break;
4305 }
4306 break;
4307
4308 case EM_MSP430:
4309 case EM_MSP430_OLD:
619ed720 4310 case EM_VISIUM:
40b36596
JM
4311 switch (osabi)
4312 {
4313 case ELFOSABI_STANDALONE: return _("Standalone App");
4314 default:
4315 break;
4316 }
4317 break;
4318
4319 case EM_TI_C6000:
4320 switch (osabi)
4321 {
4322 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4323 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4324 default:
4325 break;
4326 }
4327 break;
4328
4329 default:
4330 break;
4331 }
e9e44622 4332 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4333 return buff;
4334 }
4335}
4336
a06ea964
NC
4337static const char *
4338get_aarch64_segment_type (unsigned long type)
4339{
4340 switch (type)
4341 {
32ec8896
NC
4342 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4343 default: return NULL;
a06ea964 4344 }
a06ea964
NC
4345}
4346
b294bdf8
MM
4347static const char *
4348get_arm_segment_type (unsigned long type)
4349{
4350 switch (type)
4351 {
32ec8896
NC
4352 case PT_ARM_EXIDX: return "EXIDX";
4353 default: return NULL;
b294bdf8 4354 }
b294bdf8
MM
4355}
4356
b4cbbe8f
AK
4357static const char *
4358get_s390_segment_type (unsigned long type)
4359{
4360 switch (type)
4361 {
4362 case PT_S390_PGSTE: return "S390_PGSTE";
4363 default: return NULL;
4364 }
4365}
4366
d3ba0551
AM
4367static const char *
4368get_mips_segment_type (unsigned long type)
252b5132
RH
4369{
4370 switch (type)
4371 {
32ec8896
NC
4372 case PT_MIPS_REGINFO: return "REGINFO";
4373 case PT_MIPS_RTPROC: return "RTPROC";
4374 case PT_MIPS_OPTIONS: return "OPTIONS";
4375 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4376 default: return NULL;
252b5132 4377 }
252b5132
RH
4378}
4379
103f02d3 4380static const char *
d3ba0551 4381get_parisc_segment_type (unsigned long type)
103f02d3
UD
4382{
4383 switch (type)
4384 {
103f02d3
UD
4385 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4386 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4387 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4388 default: return NULL;
103f02d3 4389 }
103f02d3
UD
4390}
4391
4d6ed7c8 4392static const char *
d3ba0551 4393get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4394{
4395 switch (type)
4396 {
4397 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4398 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4399 default: return NULL;
4d6ed7c8 4400 }
4d6ed7c8
NC
4401}
4402
40b36596
JM
4403static const char *
4404get_tic6x_segment_type (unsigned long type)
4405{
4406 switch (type)
4407 {
32ec8896
NC
4408 case PT_C6000_PHATTR: return "C6000_PHATTR";
4409 default: return NULL;
40b36596 4410 }
40b36596
JM
4411}
4412
fbc95f1e
KC
4413static const char *
4414get_riscv_segment_type (unsigned long type)
4415{
4416 switch (type)
4417 {
4418 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4419 default: return NULL;
4420 }
4421}
4422
df3a023b
AM
4423static const char *
4424get_hpux_segment_type (unsigned long type, unsigned e_machine)
4425{
4426 if (e_machine == EM_PARISC)
4427 switch (type)
4428 {
4429 case PT_HP_TLS: return "HP_TLS";
4430 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4431 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4432 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4433 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4434 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4435 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4436 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4437 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4438 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4439 case PT_HP_PARALLEL: return "HP_PARALLEL";
4440 case PT_HP_FASTBIND: return "HP_FASTBIND";
4441 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4442 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4443 case PT_HP_STACK: return "HP_STACK";
4444 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4445 default: return NULL;
4446 }
4447
4448 if (e_machine == EM_IA_64)
4449 switch (type)
4450 {
4451 case PT_HP_TLS: return "HP_TLS";
4452 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4453 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4454 case PT_IA_64_HP_STACK: return "HP_STACK";
4455 default: return NULL;
4456 }
4457
4458 return NULL;
4459}
4460
5522f910
NC
4461static const char *
4462get_solaris_segment_type (unsigned long type)
4463{
4464 switch (type)
4465 {
4466 case 0x6464e550: return "PT_SUNW_UNWIND";
4467 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4468 case 0x6ffffff7: return "PT_LOSUNW";
4469 case 0x6ffffffa: return "PT_SUNWBSS";
4470 case 0x6ffffffb: return "PT_SUNWSTACK";
4471 case 0x6ffffffc: return "PT_SUNWDTRACE";
4472 case 0x6ffffffd: return "PT_SUNWCAP";
4473 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4474 default: return NULL;
5522f910
NC
4475 }
4476}
4477
252b5132 4478static const char *
dda8d76d 4479get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4480{
b34976b6 4481 static char buff[32];
252b5132
RH
4482
4483 switch (p_type)
4484 {
b34976b6
AM
4485 case PT_NULL: return "NULL";
4486 case PT_LOAD: return "LOAD";
252b5132 4487 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4488 case PT_INTERP: return "INTERP";
4489 case PT_NOTE: return "NOTE";
4490 case PT_SHLIB: return "SHLIB";
4491 case PT_PHDR: return "PHDR";
13ae64f3 4492 case PT_TLS: return "TLS";
32ec8896 4493 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4494 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4495 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4496 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4497
3eba3ef3
NC
4498 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4499 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4500 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4501
252b5132 4502 default:
df3a023b 4503 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4504 {
2cf0635d 4505 const char * result;
103f02d3 4506
dda8d76d 4507 switch (filedata->file_header.e_machine)
252b5132 4508 {
a06ea964
NC
4509 case EM_AARCH64:
4510 result = get_aarch64_segment_type (p_type);
4511 break;
b294bdf8
MM
4512 case EM_ARM:
4513 result = get_arm_segment_type (p_type);
4514 break;
252b5132 4515 case EM_MIPS:
4fe85591 4516 case EM_MIPS_RS3_LE:
252b5132
RH
4517 result = get_mips_segment_type (p_type);
4518 break;
103f02d3
UD
4519 case EM_PARISC:
4520 result = get_parisc_segment_type (p_type);
4521 break;
4d6ed7c8
NC
4522 case EM_IA_64:
4523 result = get_ia64_segment_type (p_type);
4524 break;
40b36596
JM
4525 case EM_TI_C6000:
4526 result = get_tic6x_segment_type (p_type);
4527 break;
b4cbbe8f
AK
4528 case EM_S390:
4529 case EM_S390_OLD:
4530 result = get_s390_segment_type (p_type);
4531 break;
fbc95f1e
KC
4532 case EM_RISCV:
4533 result = get_riscv_segment_type (p_type);
4534 break;
252b5132
RH
4535 default:
4536 result = NULL;
4537 break;
4538 }
103f02d3 4539
252b5132
RH
4540 if (result != NULL)
4541 return result;
103f02d3 4542
1a9ccd70 4543 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4544 }
4545 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4546 {
df3a023b 4547 const char * result = NULL;
103f02d3 4548
df3a023b 4549 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4550 {
df3a023b
AM
4551 case ELFOSABI_GNU:
4552 case ELFOSABI_FREEBSD:
4553 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4554 {
4555 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4556 result = buff;
4557 }
103f02d3 4558 break;
df3a023b
AM
4559 case ELFOSABI_HPUX:
4560 result = get_hpux_segment_type (p_type,
4561 filedata->file_header.e_machine);
4562 break;
4563 case ELFOSABI_SOLARIS:
4564 result = get_solaris_segment_type (p_type);
00428cca 4565 break;
103f02d3 4566 default:
103f02d3
UD
4567 break;
4568 }
103f02d3
UD
4569 if (result != NULL)
4570 return result;
4571
1a9ccd70 4572 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4573 }
252b5132 4574 else
e9e44622 4575 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4576
4577 return buff;
4578 }
4579}
4580
53a346d8
CZ
4581static const char *
4582get_arc_section_type_name (unsigned int sh_type)
4583{
4584 switch (sh_type)
4585 {
4586 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4587 default:
4588 break;
4589 }
4590 return NULL;
4591}
4592
252b5132 4593static const char *
d3ba0551 4594get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4595{
4596 switch (sh_type)
4597 {
b34976b6
AM
4598 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4599 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4600 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4601 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4602 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4603 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4604 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4605 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4606 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4607 case SHT_MIPS_RELD: return "MIPS_RELD";
4608 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4609 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4610 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4611 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4612 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4613 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4614 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4615 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4616 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4617 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4618 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4619 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4620 case SHT_MIPS_LINE: return "MIPS_LINE";
4621 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4622 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4623 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4624 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4625 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4626 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4627 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4628 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4629 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4630 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4631 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4632 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4633 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4634 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4635 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4636 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4637 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4638 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4639 default:
4640 break;
4641 }
4642 return NULL;
4643}
4644
103f02d3 4645static const char *
d3ba0551 4646get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4647{
4648 switch (sh_type)
4649 {
4650 case SHT_PARISC_EXT: return "PARISC_EXT";
4651 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4652 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4653 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4654 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4655 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4656 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4657 default: return NULL;
103f02d3 4658 }
103f02d3
UD
4659}
4660
4d6ed7c8 4661static const char *
dda8d76d 4662get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4663{
18bd398b 4664 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4665 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4666 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4667
4d6ed7c8
NC
4668 switch (sh_type)
4669 {
148b93f2
NC
4670 case SHT_IA_64_EXT: return "IA_64_EXT";
4671 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4672 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4673 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4674 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4675 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4676 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4677 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4678 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4679 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4680 default:
4681 break;
4682 }
4683 return NULL;
4684}
4685
d2b2c203
DJ
4686static const char *
4687get_x86_64_section_type_name (unsigned int sh_type)
4688{
4689 switch (sh_type)
4690 {
4691 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4692 default: return NULL;
d2b2c203 4693 }
d2b2c203
DJ
4694}
4695
a06ea964
NC
4696static const char *
4697get_aarch64_section_type_name (unsigned int sh_type)
4698{
4699 switch (sh_type)
4700 {
32ec8896
NC
4701 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4702 default: return NULL;
a06ea964 4703 }
a06ea964
NC
4704}
4705
40a18ebd
NC
4706static const char *
4707get_arm_section_type_name (unsigned int sh_type)
4708{
4709 switch (sh_type)
4710 {
7f6fed87
NC
4711 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4712 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4713 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4714 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4715 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4716 default: return NULL;
40a18ebd 4717 }
40a18ebd
NC
4718}
4719
40b36596
JM
4720static const char *
4721get_tic6x_section_type_name (unsigned int sh_type)
4722{
4723 switch (sh_type)
4724 {
32ec8896
NC
4725 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4726 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4727 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4728 case SHT_TI_ICODE: return "TI_ICODE";
4729 case SHT_TI_XREF: return "TI_XREF";
4730 case SHT_TI_HANDLER: return "TI_HANDLER";
4731 case SHT_TI_INITINFO: return "TI_INITINFO";
4732 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4733 default: return NULL;
40b36596 4734 }
40b36596
JM
4735}
4736
13761a11 4737static const char *
b0191216 4738get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4739{
4740 switch (sh_type)
4741 {
32ec8896
NC
4742 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4743 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4744 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4745 default: return NULL;
13761a11
NC
4746 }
4747}
4748
fe944acf
FT
4749static const char *
4750get_nfp_section_type_name (unsigned int sh_type)
4751{
4752 switch (sh_type)
4753 {
4754 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4755 case SHT_NFP_INITREG: return "NFP_INITREG";
4756 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4757 default: return NULL;
4758 }
4759}
4760
685080f2
NC
4761static const char *
4762get_v850_section_type_name (unsigned int sh_type)
4763{
4764 switch (sh_type)
4765 {
32ec8896
NC
4766 case SHT_V850_SCOMMON: return "V850 Small Common";
4767 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4768 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4769 case SHT_RENESAS_IOP: return "RENESAS IOP";
4770 case SHT_RENESAS_INFO: return "RENESAS INFO";
4771 default: return NULL;
685080f2
NC
4772 }
4773}
4774
2dc8dd17
JW
4775static const char *
4776get_riscv_section_type_name (unsigned int sh_type)
4777{
4778 switch (sh_type)
4779 {
4780 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4781 default: return NULL;
4782 }
4783}
4784
0861f561
CQ
4785static const char *
4786get_csky_section_type_name (unsigned int sh_type)
4787{
4788 switch (sh_type)
4789 {
4790 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4791 default: return NULL;
4792 }
4793}
4794
252b5132 4795static const char *
dda8d76d 4796get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4797{
b34976b6 4798 static char buff[32];
9fb71ee4 4799 const char * result;
252b5132
RH
4800
4801 switch (sh_type)
4802 {
4803 case SHT_NULL: return "NULL";
4804 case SHT_PROGBITS: return "PROGBITS";
4805 case SHT_SYMTAB: return "SYMTAB";
4806 case SHT_STRTAB: return "STRTAB";
4807 case SHT_RELA: return "RELA";
dd207c13 4808 case SHT_RELR: return "RELR";
252b5132
RH
4809 case SHT_HASH: return "HASH";
4810 case SHT_DYNAMIC: return "DYNAMIC";
4811 case SHT_NOTE: return "NOTE";
4812 case SHT_NOBITS: return "NOBITS";
4813 case SHT_REL: return "REL";
4814 case SHT_SHLIB: return "SHLIB";
4815 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4816 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4817 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4818 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4819 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4820 case SHT_GROUP: return "GROUP";
67ce483b 4821 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4822 case SHT_GNU_verdef: return "VERDEF";
4823 case SHT_GNU_verneed: return "VERNEED";
4824 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4825 case 0x6ffffff0: return "VERSYM";
4826 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4827 case 0x7ffffffd: return "AUXILIARY";
4828 case 0x7fffffff: return "FILTER";
047b2264 4829 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4830
4831 default:
4832 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4833 {
dda8d76d 4834 switch (filedata->file_header.e_machine)
252b5132 4835 {
53a346d8
CZ
4836 case EM_ARC:
4837 case EM_ARC_COMPACT:
4838 case EM_ARC_COMPACT2:
4839 result = get_arc_section_type_name (sh_type);
4840 break;
252b5132 4841 case EM_MIPS:
4fe85591 4842 case EM_MIPS_RS3_LE:
252b5132
RH
4843 result = get_mips_section_type_name (sh_type);
4844 break;
103f02d3
UD
4845 case EM_PARISC:
4846 result = get_parisc_section_type_name (sh_type);
4847 break;
4d6ed7c8 4848 case EM_IA_64:
dda8d76d 4849 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4850 break;
d2b2c203 4851 case EM_X86_64:
8a9036a4 4852 case EM_L1OM:
7a9068fe 4853 case EM_K1OM:
d2b2c203
DJ
4854 result = get_x86_64_section_type_name (sh_type);
4855 break;
a06ea964
NC
4856 case EM_AARCH64:
4857 result = get_aarch64_section_type_name (sh_type);
4858 break;
40a18ebd
NC
4859 case EM_ARM:
4860 result = get_arm_section_type_name (sh_type);
4861 break;
40b36596
JM
4862 case EM_TI_C6000:
4863 result = get_tic6x_section_type_name (sh_type);
4864 break;
13761a11 4865 case EM_MSP430:
b0191216 4866 result = get_msp430_section_type_name (sh_type);
13761a11 4867 break;
fe944acf
FT
4868 case EM_NFP:
4869 result = get_nfp_section_type_name (sh_type);
4870 break;
685080f2
NC
4871 case EM_V800:
4872 case EM_V850:
4873 case EM_CYGNUS_V850:
4874 result = get_v850_section_type_name (sh_type);
4875 break;
2dc8dd17
JW
4876 case EM_RISCV:
4877 result = get_riscv_section_type_name (sh_type);
4878 break;
0861f561
CQ
4879 case EM_CSKY:
4880 result = get_csky_section_type_name (sh_type);
4881 break;
252b5132
RH
4882 default:
4883 result = NULL;
4884 break;
4885 }
4886
4887 if (result != NULL)
4888 return result;
4889
9fb71ee4 4890 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4891 }
4892 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4893 {
dda8d76d 4894 switch (filedata->file_header.e_machine)
148b93f2
NC
4895 {
4896 case EM_IA_64:
dda8d76d 4897 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4898 break;
4899 default:
dda8d76d 4900 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4901 result = get_solaris_section_type (sh_type);
4902 else
1b4b80bf
NC
4903 {
4904 switch (sh_type)
4905 {
4906 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4907 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4908 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4909 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4910 default:
4911 result = NULL;
4912 break;
4913 }
4914 }
148b93f2
NC
4915 break;
4916 }
4917
4918 if (result != NULL)
4919 return result;
4920
9fb71ee4 4921 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4922 }
252b5132 4923 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4924 {
dda8d76d 4925 switch (filedata->file_header.e_machine)
685080f2
NC
4926 {
4927 case EM_V800:
4928 case EM_V850:
4929 case EM_CYGNUS_V850:
9fb71ee4 4930 result = get_v850_section_type_name (sh_type);
a9fb83be 4931 break;
685080f2 4932 default:
9fb71ee4 4933 result = NULL;
685080f2
NC
4934 break;
4935 }
4936
9fb71ee4
NC
4937 if (result != NULL)
4938 return result;
4939
4940 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4941 }
252b5132 4942 else
a7dbfd1c
NC
4943 /* This message is probably going to be displayed in a 15
4944 character wide field, so put the hex value first. */
4945 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4946
252b5132
RH
4947 return buff;
4948 }
4949}
4950
79bc120c
NC
4951enum long_option_values
4952{
4953 OPTION_DEBUG_DUMP = 512,
4954 OPTION_DYN_SYMS,
0f03783c 4955 OPTION_LTO_SYMS,
79bc120c
NC
4956 OPTION_DWARF_DEPTH,
4957 OPTION_DWARF_START,
4958 OPTION_DWARF_CHECK,
4959 OPTION_CTF_DUMP,
4960 OPTION_CTF_PARENT,
4961 OPTION_CTF_SYMBOLS,
4962 OPTION_CTF_STRINGS,
4963 OPTION_WITH_SYMBOL_VERSIONS,
4964 OPTION_RECURSE_LIMIT,
4965 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4966 OPTION_NO_DEMANGLING,
4967 OPTION_SYM_BASE
79bc120c 4968};
2979dc34 4969
85b1c36d 4970static struct option options[] =
252b5132 4971{
79bc120c
NC
4972 /* Note - This table is alpha-sorted on the 'val'
4973 field in order to make adding new options easier. */
4974 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4975 {"all", no_argument, 0, 'a'},
79bc120c
NC
4976 {"demangle", optional_argument, 0, 'C'},
4977 {"archive-index", no_argument, 0, 'c'},
4978 {"use-dynamic", no_argument, 0, 'D'},
4979 {"dynamic", no_argument, 0, 'd'},
b34976b6 4980 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4981 {"section-groups", no_argument, 0, 'g'},
4982 {"help", no_argument, 0, 'H'},
4983 {"file-header", no_argument, 0, 'h'},
b34976b6 4984 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4985 {"lint", no_argument, 0, 'L'},
4986 {"enable-checks", no_argument, 0, 'L'},
4987 {"program-headers", no_argument, 0, 'l'},
b34976b6 4988 {"segments", no_argument, 0, 'l'},
595cf52e 4989 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4990 {"notes", no_argument, 0, 'n'},
ca0e11aa 4991 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4992 {"string-dump", required_argument, 0, 'p'},
4993 {"relocated-dump", required_argument, 0, 'R'},
4994 {"relocs", no_argument, 0, 'r'},
4995 {"section-headers", no_argument, 0, 'S'},
4996 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4997 {"symbols", no_argument, 0, 's'},
4998 {"syms", no_argument, 0, 's'},
79bc120c
NC
4999 {"silent-truncation",no_argument, 0, 'T'},
5000 {"section-details", no_argument, 0, 't'},
b3aa80b4 5001 {"unicode", required_argument, NULL, 'U'},
09c11c86 5002 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
5003 {"version-info", no_argument, 0, 'V'},
5004 {"version", no_argument, 0, 'v'},
5005 {"wide", no_argument, 0, 'W'},
b34976b6 5006 {"hex-dump", required_argument, 0, 'x'},
0e602686 5007 {"decompress", no_argument, 0, 'z'},
252b5132 5008
79bc120c
NC
5009 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
5010 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
5011 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5012 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
5013 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 5014 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 5015 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
5016 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
5017 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 5018 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 5019#ifdef ENABLE_LIBCTF
d344b407 5020 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
5021 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
5022 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
5023 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 5024#endif
047c3dbf 5025 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 5026
b34976b6 5027 {0, no_argument, 0, 0}
252b5132
RH
5028};
5029
5030static void
2cf0635d 5031usage (FILE * stream)
252b5132 5032{
92f01d61
JM
5033 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
5034 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
5035 fprintf (stream, _(" Options are:\n"));
5036 fprintf (stream, _("\
5037 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
5038 fprintf (stream, _("\
5039 -h --file-header Display the ELF file header\n"));
5040 fprintf (stream, _("\
5041 -l --program-headers Display the program headers\n"));
5042 fprintf (stream, _("\
5043 --segments An alias for --program-headers\n"));
5044 fprintf (stream, _("\
5045 -S --section-headers Display the sections' header\n"));
5046 fprintf (stream, _("\
5047 --sections An alias for --section-headers\n"));
5048 fprintf (stream, _("\
5049 -g --section-groups Display the section groups\n"));
5050 fprintf (stream, _("\
5051 -t --section-details Display the section details\n"));
5052 fprintf (stream, _("\
5053 -e --headers Equivalent to: -h -l -S\n"));
5054 fprintf (stream, _("\
5055 -s --syms Display the symbol table\n"));
5056 fprintf (stream, _("\
5057 --symbols An alias for --syms\n"));
5058 fprintf (stream, _("\
5059 --dyn-syms Display the dynamic symbol table\n"));
5060 fprintf (stream, _("\
5061 --lto-syms Display LTO symbol tables\n"));
5062 fprintf (stream, _("\
047c3dbf
NL
5063 --sym-base=[0|8|10|16] \n\
5064 Force base for symbol sizes. The options are \n\
d6249f5f
AM
5065 mixed (the default), octal, decimal, hexadecimal.\n"));
5066 fprintf (stream, _("\
0d646226
AM
5067 -C --demangle[=STYLE] Decode mangled/processed symbol names\n"));
5068 display_demangler_styles (stream, _("\
5069 STYLE can be "));
d6249f5f
AM
5070 fprintf (stream, _("\
5071 --no-demangle Do not demangle low-level symbol names. (default)\n"));
5072 fprintf (stream, _("\
5073 --recurse-limit Enable a demangling recursion limit. (default)\n"));
5074 fprintf (stream, _("\
5075 --no-recurse-limit Disable a demangling recursion limit\n"));
b3aa80b4
NC
5076 fprintf (stream, _("\
5077 -U[dlexhi] --unicode=[default|locale|escape|hex|highlight|invalid]\n\
5078 Display unicode characters as determined by the current locale\n\
5079 (default), escape sequences, \"<hex sequences>\", highlighted\n\
5080 escape sequences, or treat them as invalid and display as\n\
5081 \"{hex sequences}\"\n"));
d6249f5f
AM
5082 fprintf (stream, _("\
5083 -n --notes Display the core notes (if present)\n"));
5084 fprintf (stream, _("\
5085 -r --relocs Display the relocations (if present)\n"));
5086 fprintf (stream, _("\
5087 -u --unwind Display the unwind info (if present)\n"));
5088 fprintf (stream, _("\
5089 -d --dynamic Display the dynamic section (if present)\n"));
5090 fprintf (stream, _("\
5091 -V --version-info Display the version sections (if present)\n"));
5092 fprintf (stream, _("\
5093 -A --arch-specific Display architecture specific information (if any)\n"));
5094 fprintf (stream, _("\
5095 -c --archive-index Display the symbol/file index in an archive\n"));
5096 fprintf (stream, _("\
5097 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
5098 fprintf (stream, _("\
5099 -L --lint|--enable-checks\n\
5100 Display warning messages for possible problems\n"));
5101 fprintf (stream, _("\
09c11c86 5102 -x --hex-dump=<number|name>\n\
d6249f5f
AM
5103 Dump the contents of section <number|name> as bytes\n"));
5104 fprintf (stream, _("\
09c11c86 5105 -p --string-dump=<number|name>\n\
d6249f5f
AM
5106 Dump the contents of section <number|name> as strings\n"));
5107 fprintf (stream, _("\
cf13d699 5108 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
5109 Dump the relocated contents of section <number|name>\n"));
5110 fprintf (stream, _("\
5111 -z --decompress Decompress section before dumping it\n"));
5112 fprintf (stream, _("\
5113 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
5114 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
5115 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
5116 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
5117 U/=trace_info]\n\
5118 Display the contents of DWARF debug sections\n"));
5119 fprintf (stream, _("\
5120 -wk --debug-dump=links Display the contents of sections that link to separate\n\
5121 debuginfo files\n"));
5122 fprintf (stream, _("\
5123 -P --process-links Display the contents of non-debug sections in separate\n\
5124 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
5125#if DEFAULT_FOR_FOLLOW_LINKS
5126 fprintf (stream, _("\
d6249f5f
AM
5127 -wK --debug-dump=follow-links\n\
5128 Follow links to separate debug info files (default)\n"));
5129 fprintf (stream, _("\
5130 -wN --debug-dump=no-follow-links\n\
5131 Do not follow links to separate debug info files\n"));
c46b7066
NC
5132#else
5133 fprintf (stream, _("\
d6249f5f
AM
5134 -wK --debug-dump=follow-links\n\
5135 Follow links to separate debug info files\n"));
5136 fprintf (stream, _("\
5137 -wN --debug-dump=no-follow-links\n\
5138 Do not follow links to separate debug info files\n\
5139 (default)\n"));
bed566bb
NC
5140#endif
5141#if HAVE_LIBDEBUGINFOD
5142 fprintf (stream, _("\
5143 -wD --debug-dump=use-debuginfod\n\
5144 When following links, also query debuginfod servers (default)\n"));
5145 fprintf (stream, _("\
5146 -wE --debug-dump=do-not-use-debuginfod\n\
5147 When following links, do not query debuginfod servers\n"));
c46b7066 5148#endif
fd2f0033 5149 fprintf (stream, _("\
d6249f5f
AM
5150 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
5151 fprintf (stream, _("\
5152 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 5153#ifdef ENABLE_LIBCTF
7d9813f1 5154 fprintf (stream, _("\
d6249f5f
AM
5155 --ctf=<number|name> Display CTF info from section <number|name>\n"));
5156 fprintf (stream, _("\
80b56fad 5157 --ctf-parent=<name> Use CTF archive member <name> as the CTF parent\n"));
d6249f5f 5158 fprintf (stream, _("\
7d9813f1 5159 --ctf-symbols=<number|name>\n\
d6249f5f
AM
5160 Use section <number|name> as the CTF external symtab\n"));
5161 fprintf (stream, _("\
7d9813f1 5162 --ctf-strings=<number|name>\n\
d6249f5f 5163 Use section <number|name> as the CTF external strtab\n"));
094e34f2 5164#endif
7d9813f1 5165
252b5132 5166#ifdef SUPPORT_DISASSEMBLY
92f01d61 5167 fprintf (stream, _("\
09c11c86
NC
5168 -i --instruction-dump=<number|name>\n\
5169 Disassemble the contents of section <number|name>\n"));
252b5132 5170#endif
92f01d61 5171 fprintf (stream, _("\
d6249f5f
AM
5172 -I --histogram Display histogram of bucket list lengths\n"));
5173 fprintf (stream, _("\
5174 -W --wide Allow output width to exceed 80 characters\n"));
5175 fprintf (stream, _("\
5176 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
5177 fprintf (stream, _("\
5178 @<file> Read options from <file>\n"));
5179 fprintf (stream, _("\
5180 -H --help Display this information\n"));
5181 fprintf (stream, _("\
8b53311e 5182 -v --version Display the version number of readelf\n"));
1118d252 5183
92f01d61
JM
5184 if (REPORT_BUGS_TO[0] && stream == stdout)
5185 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 5186
92f01d61 5187 exit (stream == stdout ? 0 : 1);
252b5132
RH
5188}
5189
18bd398b
NC
5190/* Record the fact that the user wants the contents of section number
5191 SECTION to be displayed using the method(s) encoded as flags bits
5192 in TYPE. Note, TYPE can be zero if we are creating the array for
5193 the first time. */
5194
252b5132 5195static void
6431e409
AM
5196request_dump_bynumber (struct dump_data *dumpdata,
5197 unsigned int section, dump_type type)
252b5132 5198{
6431e409 5199 if (section >= dumpdata->num_dump_sects)
252b5132 5200 {
2cf0635d 5201 dump_type * new_dump_sects;
252b5132 5202
3f5e193b 5203 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 5204 sizeof (* new_dump_sects));
252b5132
RH
5205
5206 if (new_dump_sects == NULL)
591a748a 5207 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
5208 else
5209 {
6431e409 5210 if (dumpdata->dump_sects)
21b65bac
NC
5211 {
5212 /* Copy current flag settings. */
6431e409
AM
5213 memcpy (new_dump_sects, dumpdata->dump_sects,
5214 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 5215
6431e409 5216 free (dumpdata->dump_sects);
21b65bac 5217 }
252b5132 5218
6431e409
AM
5219 dumpdata->dump_sects = new_dump_sects;
5220 dumpdata->num_dump_sects = section + 1;
252b5132
RH
5221 }
5222 }
5223
6431e409
AM
5224 if (dumpdata->dump_sects)
5225 dumpdata->dump_sects[section] |= type;
252b5132
RH
5226}
5227
aef1f6d0
DJ
5228/* Request a dump by section name. */
5229
5230static void
2cf0635d 5231request_dump_byname (const char * section, dump_type type)
aef1f6d0 5232{
2cf0635d 5233 struct dump_list_entry * new_request;
aef1f6d0 5234
3f5e193b
NC
5235 new_request = (struct dump_list_entry *)
5236 malloc (sizeof (struct dump_list_entry));
aef1f6d0 5237 if (!new_request)
591a748a 5238 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5239
5240 new_request->name = strdup (section);
5241 if (!new_request->name)
591a748a 5242 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
5243
5244 new_request->type = type;
5245
5246 new_request->next = dump_sects_byname;
5247 dump_sects_byname = new_request;
5248}
5249
cf13d699 5250static inline void
6431e409 5251request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
5252{
5253 int section;
5254 char * cp;
5255
015dc7e1 5256 do_dump = true;
cf13d699
NC
5257 section = strtoul (optarg, & cp, 0);
5258
5259 if (! *cp && section >= 0)
6431e409 5260 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
5261 else
5262 request_dump_byname (optarg, type);
5263}
5264
252b5132 5265static void
6431e409 5266parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
5267{
5268 int c;
5269
5270 if (argc < 2)
92f01d61 5271 usage (stderr);
252b5132
RH
5272
5273 while ((c = getopt_long
b3aa80b4 5274 (argc, argv, "ACDHILNPR:STU:VWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 5275 {
252b5132
RH
5276 switch (c)
5277 {
5278 case 0:
5279 /* Long options. */
5280 break;
5281 case 'H':
92f01d61 5282 usage (stdout);
252b5132
RH
5283 break;
5284
5285 case 'a':
015dc7e1
AM
5286 do_syms = true;
5287 do_reloc = true;
5288 do_unwind = true;
5289 do_dynamic = true;
5290 do_header = true;
5291 do_sections = true;
5292 do_section_groups = true;
5293 do_segments = true;
5294 do_version = true;
5295 do_histogram = true;
5296 do_arch = true;
5297 do_notes = true;
252b5132 5298 break;
79bc120c 5299
f5842774 5300 case 'g':
015dc7e1 5301 do_section_groups = true;
f5842774 5302 break;
5477e8a0 5303 case 't':
595cf52e 5304 case 'N':
015dc7e1
AM
5305 do_sections = true;
5306 do_section_details = true;
595cf52e 5307 break;
252b5132 5308 case 'e':
015dc7e1
AM
5309 do_header = true;
5310 do_sections = true;
5311 do_segments = true;
252b5132 5312 break;
a952a375 5313 case 'A':
015dc7e1 5314 do_arch = true;
a952a375 5315 break;
252b5132 5316 case 'D':
015dc7e1 5317 do_using_dynamic = true;
252b5132
RH
5318 break;
5319 case 'r':
015dc7e1 5320 do_reloc = true;
252b5132 5321 break;
4d6ed7c8 5322 case 'u':
015dc7e1 5323 do_unwind = true;
4d6ed7c8 5324 break;
252b5132 5325 case 'h':
015dc7e1 5326 do_header = true;
252b5132
RH
5327 break;
5328 case 'l':
015dc7e1 5329 do_segments = true;
252b5132
RH
5330 break;
5331 case 's':
015dc7e1 5332 do_syms = true;
252b5132
RH
5333 break;
5334 case 'S':
015dc7e1 5335 do_sections = true;
252b5132
RH
5336 break;
5337 case 'd':
015dc7e1 5338 do_dynamic = true;
252b5132 5339 break;
a952a375 5340 case 'I':
015dc7e1 5341 do_histogram = true;
a952a375 5342 break;
779fe533 5343 case 'n':
015dc7e1 5344 do_notes = true;
779fe533 5345 break;
4145f1d5 5346 case 'c':
015dc7e1 5347 do_archive_index = true;
4145f1d5 5348 break;
1b513401 5349 case 'L':
015dc7e1 5350 do_checks = true;
1b513401 5351 break;
ca0e11aa 5352 case 'P':
015dc7e1
AM
5353 process_links = true;
5354 do_follow_links = true;
e1dbfc17 5355 dump_any_debugging = true;
ca0e11aa 5356 break;
252b5132 5357 case 'x':
6431e409 5358 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5359 break;
09c11c86 5360 case 'p':
6431e409 5361 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5362 break;
5363 case 'R':
6431e409 5364 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5365 break;
0e602686 5366 case 'z':
015dc7e1 5367 decompress_dumps = true;
0e602686 5368 break;
252b5132 5369 case 'w':
015dc7e1 5370 do_dump = true;
e1dbfc17 5371 dump_any_debugging = true;
0f03783c 5372 if (optarg == NULL)
613ff48b 5373 {
015dc7e1 5374 do_debugging = true;
613ff48b
CC
5375 dwarf_select_sections_all ();
5376 }
252b5132
RH
5377 else
5378 {
015dc7e1 5379 do_debugging = false;
4cb93e3b 5380 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5381 }
5382 break;
2979dc34 5383 case OPTION_DEBUG_DUMP:
015dc7e1 5384 do_dump = true;
e1dbfc17 5385 dump_any_debugging = true;
0f03783c 5386 if (optarg == NULL)
d6249f5f
AM
5387 {
5388 do_debugging = true;
5389 dwarf_select_sections_all ();
5390 }
2979dc34
JJ
5391 else
5392 {
015dc7e1 5393 do_debugging = false;
4cb93e3b 5394 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5395 }
5396 break;
fd2f0033
TT
5397 case OPTION_DWARF_DEPTH:
5398 {
5399 char *cp;
5400
5401 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5402 }
5403 break;
5404 case OPTION_DWARF_START:
5405 {
5406 char *cp;
5407
5408 dwarf_start_die = strtoul (optarg, & cp, 0);
5409 }
5410 break;
4723351a 5411 case OPTION_DWARF_CHECK:
015dc7e1 5412 dwarf_check = true;
4723351a 5413 break;
7d9813f1 5414 case OPTION_CTF_DUMP:
015dc7e1 5415 do_ctf = true;
6431e409 5416 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5417 break;
5418 case OPTION_CTF_SYMBOLS:
df16e041 5419 free (dump_ctf_symtab_name);
7d9813f1
NA
5420 dump_ctf_symtab_name = strdup (optarg);
5421 break;
5422 case OPTION_CTF_STRINGS:
df16e041 5423 free (dump_ctf_strtab_name);
7d9813f1
NA
5424 dump_ctf_strtab_name = strdup (optarg);
5425 break;
5426 case OPTION_CTF_PARENT:
df16e041 5427 free (dump_ctf_parent_name);
7d9813f1
NA
5428 dump_ctf_parent_name = strdup (optarg);
5429 break;
2c610e4b 5430 case OPTION_DYN_SYMS:
015dc7e1 5431 do_dyn_syms = true;
2c610e4b 5432 break;
0f03783c 5433 case OPTION_LTO_SYMS:
015dc7e1 5434 do_lto_syms = true;
0f03783c 5435 break;
252b5132
RH
5436#ifdef SUPPORT_DISASSEMBLY
5437 case 'i':
6431e409 5438 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5439 break;
252b5132
RH
5440#endif
5441 case 'v':
5442 print_version (program_name);
5443 break;
5444 case 'V':
015dc7e1 5445 do_version = true;
252b5132 5446 break;
d974e256 5447 case 'W':
015dc7e1 5448 do_wide = true;
d974e256 5449 break;
0942c7ab 5450 case 'T':
015dc7e1 5451 do_not_show_symbol_truncation = true;
0942c7ab 5452 break;
79bc120c 5453 case 'C':
015dc7e1 5454 do_demangle = true;
79bc120c
NC
5455 if (optarg != NULL)
5456 {
5457 enum demangling_styles style;
5458
5459 style = cplus_demangle_name_to_style (optarg);
5460 if (style == unknown_demangling)
5461 error (_("unknown demangling style `%s'"), optarg);
5462
5463 cplus_demangle_set_style (style);
5464 }
5465 break;
5466 case OPTION_NO_DEMANGLING:
015dc7e1 5467 do_demangle = false;
79bc120c
NC
5468 break;
5469 case OPTION_RECURSE_LIMIT:
5470 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5471 break;
5472 case OPTION_NO_RECURSE_LIMIT:
5473 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5474 break;
5475 case OPTION_WITH_SYMBOL_VERSIONS:
5476 /* Ignored for backward compatibility. */
5477 break;
b9e920ec 5478
b3aa80b4
NC
5479 case 'U':
5480 if (optarg == NULL)
5481 error (_("Missing arg to -U/--unicode")); /* Can this happen ? */
5482 else if (streq (optarg, "default") || streq (optarg, "d"))
5483 unicode_display = unicode_default;
5484 else if (streq (optarg, "locale") || streq (optarg, "l"))
5485 unicode_display = unicode_locale;
5486 else if (streq (optarg, "escape") || streq (optarg, "e"))
5487 unicode_display = unicode_escape;
5488 else if (streq (optarg, "invalid") || streq (optarg, "i"))
5489 unicode_display = unicode_invalid;
5490 else if (streq (optarg, "hex") || streq (optarg, "x"))
5491 unicode_display = unicode_hex;
5492 else if (streq (optarg, "highlight") || streq (optarg, "h"))
5493 unicode_display = unicode_highlight;
5494 else
5495 error (_("invalid argument to -U/--unicode: %s"), optarg);
5496 break;
5497
047c3dbf
NL
5498 case OPTION_SYM_BASE:
5499 sym_base = 0;
5500 if (optarg != NULL)
5501 {
5502 sym_base = strtoul (optarg, NULL, 0);
5503 switch (sym_base)
5504 {
5505 case 0:
5506 case 8:
5507 case 10:
5508 case 16:
5509 break;
5510
5511 default:
5512 sym_base = 0;
5513 break;
5514 }
5515 }
5516 break;
5517
252b5132 5518 default:
252b5132
RH
5519 /* xgettext:c-format */
5520 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5521 /* Fall through. */
252b5132 5522 case '?':
92f01d61 5523 usage (stderr);
252b5132
RH
5524 }
5525 }
5526
4d6ed7c8 5527 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5528 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5529 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5530 && !do_section_groups && !do_archive_index
0f03783c 5531 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5532 {
5533 if (do_checks)
5534 {
015dc7e1
AM
5535 check_all = true;
5536 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5537 do_segments = do_header = do_dump = do_version = true;
5538 do_histogram = do_debugging = do_arch = do_notes = true;
5539 do_section_groups = do_archive_index = do_dyn_syms = true;
5540 do_lto_syms = true;
1b513401
NC
5541 }
5542 else
5543 usage (stderr);
5544 }
252b5132
RH
5545}
5546
5547static const char *
d3ba0551 5548get_elf_class (unsigned int elf_class)
252b5132 5549{
b34976b6 5550 static char buff[32];
103f02d3 5551
252b5132
RH
5552 switch (elf_class)
5553 {
5554 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5555 case ELFCLASS32: return "ELF32";
5556 case ELFCLASS64: return "ELF64";
ab5e7794 5557 default:
e9e44622 5558 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5559 return buff;
252b5132
RH
5560 }
5561}
5562
5563static const char *
d3ba0551 5564get_data_encoding (unsigned int encoding)
252b5132 5565{
b34976b6 5566 static char buff[32];
103f02d3 5567
252b5132
RH
5568 switch (encoding)
5569 {
5570 case ELFDATANONE: return _("none");
33c63f9d
CM
5571 case ELFDATA2LSB: return _("2's complement, little endian");
5572 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5573 default:
e9e44622 5574 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5575 return buff;
252b5132
RH
5576 }
5577}
5578
dda8d76d 5579/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5580
015dc7e1 5581static bool
dda8d76d 5582process_file_header (Filedata * filedata)
252b5132 5583{
dda8d76d
NC
5584 Elf_Internal_Ehdr * header = & filedata->file_header;
5585
5586 if ( header->e_ident[EI_MAG0] != ELFMAG0
5587 || header->e_ident[EI_MAG1] != ELFMAG1
5588 || header->e_ident[EI_MAG2] != ELFMAG2
5589 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5590 {
5591 error
5592 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5593 return false;
252b5132
RH
5594 }
5595
ca0e11aa
NC
5596 if (! filedata->is_separate)
5597 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5598
252b5132
RH
5599 if (do_header)
5600 {
32ec8896 5601 unsigned i;
252b5132 5602
ca0e11aa
NC
5603 if (filedata->is_separate)
5604 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5605 else
5606 printf (_("ELF Header:\n"));
252b5132 5607 printf (_(" Magic: "));
b34976b6 5608 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5609 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5610 printf ("\n");
5611 printf (_(" Class: %s\n"),
dda8d76d 5612 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5613 printf (_(" Data: %s\n"),
dda8d76d 5614 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5615 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5616 header->e_ident[EI_VERSION],
5617 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5618 ? _(" (current)")
dda8d76d 5619 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5620 ? _(" <unknown>")
789be9f7 5621 : "")));
252b5132 5622 printf (_(" OS/ABI: %s\n"),
dda8d76d 5623 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5624 printf (_(" ABI Version: %d\n"),
dda8d76d 5625 header->e_ident[EI_ABIVERSION]);
252b5132 5626 printf (_(" Type: %s\n"),
93df3340 5627 get_file_type (filedata));
252b5132 5628 printf (_(" Machine: %s\n"),
dda8d76d 5629 get_machine_name (header->e_machine));
252b5132 5630 printf (_(" Version: 0x%lx\n"),
e8a64888 5631 header->e_version);
76da6bbe 5632
f7a99963 5633 printf (_(" Entry point address: "));
e8a64888 5634 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5635 printf (_("\n Start of program headers: "));
e8a64888 5636 print_vma (header->e_phoff, DEC);
f7a99963 5637 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5638 print_vma (header->e_shoff, DEC);
f7a99963 5639 printf (_(" (bytes into file)\n"));
76da6bbe 5640
252b5132 5641 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5642 header->e_flags,
dda8d76d 5643 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5644 printf (_(" Size of this header: %u (bytes)\n"),
5645 header->e_ehsize);
5646 printf (_(" Size of program headers: %u (bytes)\n"),
5647 header->e_phentsize);
5648 printf (_(" Number of program headers: %u"),
5649 header->e_phnum);
dda8d76d
NC
5650 if (filedata->section_headers != NULL
5651 && header->e_phnum == PN_XNUM
5652 && filedata->section_headers[0].sh_info != 0)
2969c3b3 5653 printf (" (%u)", filedata->section_headers[0].sh_info);
2046a35d 5654 putc ('\n', stdout);
e8a64888
AM
5655 printf (_(" Size of section headers: %u (bytes)\n"),
5656 header->e_shentsize);
5657 printf (_(" Number of section headers: %u"),
5658 header->e_shnum);
dda8d76d 5659 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5660 {
5661 header->e_shnum = filedata->section_headers[0].sh_size;
5662 printf (" (%u)", header->e_shnum);
5663 }
560f3c1c 5664 putc ('\n', stdout);
e8a64888
AM
5665 printf (_(" Section header string table index: %u"),
5666 header->e_shstrndx);
dda8d76d
NC
5667 if (filedata->section_headers != NULL
5668 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5669 {
5670 header->e_shstrndx = filedata->section_headers[0].sh_link;
5671 printf (" (%u)", header->e_shstrndx);
5672 }
5673 if (header->e_shstrndx != SHN_UNDEF
5674 && header->e_shstrndx >= header->e_shnum)
5675 {
5676 header->e_shstrndx = SHN_UNDEF;
5677 printf (_(" <corrupt: out of range>"));
5678 }
560f3c1c
AM
5679 putc ('\n', stdout);
5680 }
5681
dda8d76d 5682 if (filedata->section_headers != NULL)
560f3c1c 5683 {
dda8d76d
NC
5684 if (header->e_phnum == PN_XNUM
5685 && filedata->section_headers[0].sh_info != 0)
2969c3b3
AM
5686 {
5687 /* Throw away any cached read of PN_XNUM headers. */
5688 free (filedata->program_headers);
5689 filedata->program_headers = NULL;
5690 header->e_phnum = filedata->section_headers[0].sh_info;
5691 }
dda8d76d
NC
5692 if (header->e_shnum == SHN_UNDEF)
5693 header->e_shnum = filedata->section_headers[0].sh_size;
5694 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5695 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5696 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5697 header->e_shstrndx = SHN_UNDEF;
252b5132 5698 }
103f02d3 5699
015dc7e1 5700 return true;
9ea033b2
NC
5701}
5702
dda8d76d
NC
5703/* Read in the program headers from FILEDATA and store them in PHEADERS.
5704 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5705
015dc7e1 5706static bool
dda8d76d 5707get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5708{
2cf0635d
NC
5709 Elf32_External_Phdr * phdrs;
5710 Elf32_External_Phdr * external;
5711 Elf_Internal_Phdr * internal;
b34976b6 5712 unsigned int i;
dda8d76d
NC
5713 unsigned int size = filedata->file_header.e_phentsize;
5714 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5715
5716 /* PR binutils/17531: Cope with unexpected section header sizes. */
5717 if (size == 0 || num == 0)
015dc7e1 5718 return false;
e0a31db1
NC
5719 if (size < sizeof * phdrs)
5720 {
5721 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5722 return false;
e0a31db1
NC
5723 }
5724 if (size > sizeof * phdrs)
5725 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5726
dda8d76d 5727 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5728 size, num, _("program headers"));
5729 if (phdrs == NULL)
015dc7e1 5730 return false;
9ea033b2 5731
91d6fa6a 5732 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5733 i < filedata->file_header.e_phnum;
b34976b6 5734 i++, internal++, external++)
252b5132 5735 {
9ea033b2
NC
5736 internal->p_type = BYTE_GET (external->p_type);
5737 internal->p_offset = BYTE_GET (external->p_offset);
5738 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5739 internal->p_paddr = BYTE_GET (external->p_paddr);
5740 internal->p_filesz = BYTE_GET (external->p_filesz);
5741 internal->p_memsz = BYTE_GET (external->p_memsz);
5742 internal->p_flags = BYTE_GET (external->p_flags);
5743 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5744 }
5745
9ea033b2 5746 free (phdrs);
015dc7e1 5747 return true;
252b5132
RH
5748}
5749
dda8d76d
NC
5750/* Read in the program headers from FILEDATA and store them in PHEADERS.
5751 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5752
015dc7e1 5753static bool
dda8d76d 5754get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5755{
2cf0635d
NC
5756 Elf64_External_Phdr * phdrs;
5757 Elf64_External_Phdr * external;
5758 Elf_Internal_Phdr * internal;
b34976b6 5759 unsigned int i;
dda8d76d
NC
5760 unsigned int size = filedata->file_header.e_phentsize;
5761 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5762
5763 /* PR binutils/17531: Cope with unexpected section header sizes. */
5764 if (size == 0 || num == 0)
015dc7e1 5765 return false;
e0a31db1
NC
5766 if (size < sizeof * phdrs)
5767 {
5768 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5769 return false;
e0a31db1
NC
5770 }
5771 if (size > sizeof * phdrs)
5772 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5773
dda8d76d 5774 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5775 size, num, _("program headers"));
a6e9f9df 5776 if (!phdrs)
015dc7e1 5777 return false;
9ea033b2 5778
91d6fa6a 5779 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5780 i < filedata->file_header.e_phnum;
b34976b6 5781 i++, internal++, external++)
9ea033b2
NC
5782 {
5783 internal->p_type = BYTE_GET (external->p_type);
5784 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5785 internal->p_offset = BYTE_GET (external->p_offset);
5786 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5787 internal->p_paddr = BYTE_GET (external->p_paddr);
5788 internal->p_filesz = BYTE_GET (external->p_filesz);
5789 internal->p_memsz = BYTE_GET (external->p_memsz);
5790 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5791 }
5792
5793 free (phdrs);
015dc7e1 5794 return true;
9ea033b2 5795}
252b5132 5796
32ec8896 5797/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5798
015dc7e1 5799static bool
dda8d76d 5800get_program_headers (Filedata * filedata)
d93f0186 5801{
2cf0635d 5802 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5803
5804 /* Check cache of prior read. */
dda8d76d 5805 if (filedata->program_headers != NULL)
015dc7e1 5806 return true;
d93f0186 5807
82156ab7
NC
5808 /* Be kind to memory checkers by looking for
5809 e_phnum values which we know must be invalid. */
dda8d76d 5810 if (filedata->file_header.e_phnum
82156ab7 5811 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5812 >= filedata->file_size)
82156ab7
NC
5813 {
5814 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5815 filedata->file_header.e_phnum);
015dc7e1 5816 return false;
82156ab7 5817 }
d93f0186 5818
dda8d76d 5819 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5820 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5821 if (phdrs == NULL)
5822 {
8b73c356 5823 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5824 filedata->file_header.e_phnum);
015dc7e1 5825 return false;
d93f0186
NC
5826 }
5827
5828 if (is_32bit_elf
dda8d76d
NC
5829 ? get_32bit_program_headers (filedata, phdrs)
5830 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5831 {
dda8d76d 5832 filedata->program_headers = phdrs;
015dc7e1 5833 return true;
d93f0186
NC
5834 }
5835
5836 free (phdrs);
015dc7e1 5837 return false;
d93f0186
NC
5838}
5839
93df3340 5840/* Print program header info and locate dynamic section. */
2f62977e 5841
93df3340 5842static void
dda8d76d 5843process_program_headers (Filedata * filedata)
252b5132 5844{
2cf0635d 5845 Elf_Internal_Phdr * segment;
b34976b6 5846 unsigned int i;
1a9ccd70 5847 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5848
dda8d76d 5849 if (filedata->file_header.e_phnum == 0)
252b5132 5850 {
82f2dbf7 5851 /* PR binutils/12467. */
dda8d76d 5852 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5853 warn (_("possibly corrupt ELF header - it has a non-zero program"
5854 " header offset, but no program headers\n"));
82f2dbf7 5855 else if (do_segments)
ca0e11aa
NC
5856 {
5857 if (filedata->is_separate)
5858 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5859 filedata->file_name);
5860 else
5861 printf (_("\nThere are no program headers in this file.\n"));
5862 }
93df3340 5863 goto no_headers;
252b5132
RH
5864 }
5865
5866 if (do_segments && !do_header)
5867 {
ca0e11aa
NC
5868 if (filedata->is_separate)
5869 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5870 filedata->file_name, get_file_type (filedata));
ca0e11aa 5871 else
93df3340 5872 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5873 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5874 printf (ngettext ("There is %d program header, starting at offset %s\n",
5875 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5876 filedata->file_header.e_phnum),
5877 filedata->file_header.e_phnum,
5878 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5879 }
5880
dda8d76d 5881 if (! get_program_headers (filedata))
93df3340 5882 goto no_headers;
103f02d3 5883
252b5132
RH
5884 if (do_segments)
5885 {
dda8d76d 5886 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5887 printf (_("\nProgram Headers:\n"));
5888 else
5889 printf (_("\nProgram Headers:\n"));
76da6bbe 5890
f7a99963
NC
5891 if (is_32bit_elf)
5892 printf
5893 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5894 else if (do_wide)
5895 printf
5896 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5897 else
5898 {
5899 printf
5900 (_(" Type Offset VirtAddr PhysAddr\n"));
5901 printf
5902 (_(" FileSiz MemSiz Flags Align\n"));
5903 }
252b5132
RH
5904 }
5905
93df3340
AM
5906 unsigned long dynamic_addr = 0;
5907 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5908 for (i = 0, segment = filedata->program_headers;
5909 i < filedata->file_header.e_phnum;
b34976b6 5910 i++, segment++)
252b5132
RH
5911 {
5912 if (do_segments)
5913 {
dda8d76d 5914 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5915
5916 if (is_32bit_elf)
5917 {
5918 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5919 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5920 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5921 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5922 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5923 printf ("%c%c%c ",
5924 (segment->p_flags & PF_R ? 'R' : ' '),
5925 (segment->p_flags & PF_W ? 'W' : ' '),
5926 (segment->p_flags & PF_X ? 'E' : ' '));
5927 printf ("%#lx", (unsigned long) segment->p_align);
5928 }
d974e256
JJ
5929 else if (do_wide)
5930 {
5931 if ((unsigned long) segment->p_offset == segment->p_offset)
5932 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5933 else
5934 {
5935 print_vma (segment->p_offset, FULL_HEX);
5936 putchar (' ');
5937 }
5938
5939 print_vma (segment->p_vaddr, FULL_HEX);
5940 putchar (' ');
5941 print_vma (segment->p_paddr, FULL_HEX);
5942 putchar (' ');
5943
5944 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5945 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5946 else
5947 {
5948 print_vma (segment->p_filesz, FULL_HEX);
5949 putchar (' ');
5950 }
5951
5952 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5953 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5954 else
5955 {
f48e6c45 5956 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5957 }
5958
5959 printf (" %c%c%c ",
5960 (segment->p_flags & PF_R ? 'R' : ' '),
5961 (segment->p_flags & PF_W ? 'W' : ' '),
5962 (segment->p_flags & PF_X ? 'E' : ' '));
5963
5964 if ((unsigned long) segment->p_align == segment->p_align)
5965 printf ("%#lx", (unsigned long) segment->p_align);
5966 else
5967 {
5968 print_vma (segment->p_align, PREFIX_HEX);
5969 }
5970 }
f7a99963
NC
5971 else
5972 {
5973 print_vma (segment->p_offset, FULL_HEX);
5974 putchar (' ');
5975 print_vma (segment->p_vaddr, FULL_HEX);
5976 putchar (' ');
5977 print_vma (segment->p_paddr, FULL_HEX);
5978 printf ("\n ");
5979 print_vma (segment->p_filesz, FULL_HEX);
5980 putchar (' ');
5981 print_vma (segment->p_memsz, FULL_HEX);
5982 printf (" %c%c%c ",
5983 (segment->p_flags & PF_R ? 'R' : ' '),
5984 (segment->p_flags & PF_W ? 'W' : ' '),
5985 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5986 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5987 }
252b5132 5988
1a9ccd70
NC
5989 putc ('\n', stdout);
5990 }
f54498b4 5991
252b5132
RH
5992 switch (segment->p_type)
5993 {
1a9ccd70 5994 case PT_LOAD:
502d895c
NC
5995#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5996 required by the ELF standard, several programs, including the Linux
5997 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5998 if (previous_load
5999 && previous_load->p_vaddr > segment->p_vaddr)
6000 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 6001#endif
1a9ccd70
NC
6002 if (segment->p_memsz < segment->p_filesz)
6003 error (_("the segment's file size is larger than its memory size\n"));
6004 previous_load = segment;
6005 break;
6006
6007 case PT_PHDR:
6008 /* PR 20815 - Verify that the program header is loaded into memory. */
6009 if (i > 0 && previous_load != NULL)
6010 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 6011 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
6012 {
6013 unsigned int j;
6014
dda8d76d 6015 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
6016 {
6017 Elf_Internal_Phdr *load = filedata->program_headers + j;
6018 if (load->p_type == PT_LOAD
6019 && load->p_offset <= segment->p_offset
6020 && (load->p_offset + load->p_filesz
6021 >= segment->p_offset + segment->p_filesz)
6022 && load->p_vaddr <= segment->p_vaddr
6023 && (load->p_vaddr + load->p_filesz
6024 >= segment->p_vaddr + segment->p_filesz))
6025 break;
6026 }
dda8d76d 6027 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
6028 error (_("the PHDR segment is not covered by a LOAD segment\n"));
6029 }
6030 break;
6031
252b5132 6032 case PT_DYNAMIC:
93df3340 6033 if (dynamic_addr)
252b5132
RH
6034 error (_("more than one dynamic segment\n"));
6035
20737c13
AM
6036 /* By default, assume that the .dynamic section is the first
6037 section in the DYNAMIC segment. */
93df3340
AM
6038 dynamic_addr = segment->p_offset;
6039 dynamic_size = segment->p_filesz;
20737c13 6040
b2d38a17
NC
6041 /* Try to locate the .dynamic section. If there is
6042 a section header table, we can easily locate it. */
dda8d76d 6043 if (filedata->section_headers != NULL)
b2d38a17 6044 {
2cf0635d 6045 Elf_Internal_Shdr * sec;
b2d38a17 6046
dda8d76d 6047 sec = find_section (filedata, ".dynamic");
89fac5e3 6048 if (sec == NULL || sec->sh_size == 0)
b2d38a17 6049 {
93df3340
AM
6050 /* A corresponding .dynamic section is expected, but on
6051 IA-64/OpenVMS it is OK for it to be missing. */
6052 if (!is_ia64_vms (filedata))
6053 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
6054 break;
6055 }
6056
42bb2e33 6057 if (sec->sh_type == SHT_NOBITS)
20737c13 6058 {
93df3340
AM
6059 dynamic_addr = 0;
6060 dynamic_size = 0;
20737c13
AM
6061 break;
6062 }
42bb2e33 6063
93df3340
AM
6064 dynamic_addr = sec->sh_offset;
6065 dynamic_size = sec->sh_size;
b2d38a17 6066
8ac10c5b
L
6067 /* The PT_DYNAMIC segment, which is used by the run-time
6068 loader, should exactly match the .dynamic section. */
6069 if (do_checks
93df3340
AM
6070 && (dynamic_addr != segment->p_offset
6071 || dynamic_size != segment->p_filesz))
8ac10c5b
L
6072 warn (_("\
6073the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 6074 }
39e224f6
MW
6075
6076 /* PR binutils/17512: Avoid corrupt dynamic section info in the
6077 segment. Check this after matching against the section headers
6078 so we don't warn on debuginfo file (which have NOBITS .dynamic
6079 sections). */
93df3340
AM
6080 if (dynamic_addr > filedata->file_size
6081 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
6082 {
6083 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
6084 dynamic_addr = 0;
6085 dynamic_size = 0;
39e224f6 6086 }
252b5132
RH
6087 break;
6088
6089 case PT_INTERP:
13acb58d
AM
6090 if (segment->p_offset >= filedata->file_size
6091 || segment->p_filesz > filedata->file_size - segment->p_offset
6092 || segment->p_filesz - 1 >= (size_t) -2
6093 || fseek (filedata->handle,
6094 filedata->archive_file_offset + (long) segment->p_offset,
6095 SEEK_SET))
252b5132
RH
6096 error (_("Unable to find program interpreter name\n"));
6097 else
6098 {
13acb58d
AM
6099 size_t len = segment->p_filesz;
6100 free (filedata->program_interpreter);
6101 filedata->program_interpreter = xmalloc (len + 1);
6102 len = fread (filedata->program_interpreter, 1, len,
6103 filedata->handle);
6104 filedata->program_interpreter[len] = 0;
252b5132
RH
6105
6106 if (do_segments)
f54498b4 6107 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 6108 filedata->program_interpreter);
252b5132
RH
6109 }
6110 break;
6111 }
252b5132
RH
6112 }
6113
dda8d76d
NC
6114 if (do_segments
6115 && filedata->section_headers != NULL
6116 && filedata->string_table != NULL)
252b5132
RH
6117 {
6118 printf (_("\n Section to Segment mapping:\n"));
6119 printf (_(" Segment Sections...\n"));
6120
dda8d76d 6121 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 6122 {
9ad5cbcf 6123 unsigned int j;
2cf0635d 6124 Elf_Internal_Shdr * section;
252b5132 6125
dda8d76d
NC
6126 segment = filedata->program_headers + i;
6127 section = filedata->section_headers + 1;
252b5132
RH
6128
6129 printf (" %2.2d ", i);
6130
dda8d76d 6131 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 6132 {
f4638467
AM
6133 if (!ELF_TBSS_SPECIAL (section, segment)
6134 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 6135 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
6136 }
6137
6138 putc ('\n',stdout);
6139 }
6140 }
6141
93df3340
AM
6142 filedata->dynamic_addr = dynamic_addr;
6143 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
6144 return;
6145
6146 no_headers:
6147 filedata->dynamic_addr = 0;
6148 filedata->dynamic_size = 1;
252b5132
RH
6149}
6150
6151
d93f0186
NC
6152/* Find the file offset corresponding to VMA by using the program headers. */
6153
6154static long
dda8d76d 6155offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 6156{
2cf0635d 6157 Elf_Internal_Phdr * seg;
d93f0186 6158
dda8d76d 6159 if (! get_program_headers (filedata))
d93f0186
NC
6160 {
6161 warn (_("Cannot interpret virtual addresses without program headers.\n"));
6162 return (long) vma;
6163 }
6164
dda8d76d
NC
6165 for (seg = filedata->program_headers;
6166 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
6167 ++seg)
6168 {
6169 if (seg->p_type != PT_LOAD)
6170 continue;
6171
6172 if (vma >= (seg->p_vaddr & -seg->p_align)
6173 && vma + size <= seg->p_vaddr + seg->p_filesz)
6174 return vma - seg->p_vaddr + seg->p_offset;
6175 }
6176
6177 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 6178 (unsigned long) vma);
d93f0186
NC
6179 return (long) vma;
6180}
6181
6182
dda8d76d
NC
6183/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
6184 If PROBE is true, this is just a probe and we do not generate any error
6185 messages if the load fails. */
049b0c3a 6186
015dc7e1
AM
6187static bool
6188get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 6189{
2cf0635d
NC
6190 Elf32_External_Shdr * shdrs;
6191 Elf_Internal_Shdr * internal;
dda8d76d
NC
6192 unsigned int i;
6193 unsigned int size = filedata->file_header.e_shentsize;
6194 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6195
6196 /* PR binutils/17531: Cope with unexpected section header sizes. */
6197 if (size == 0 || num == 0)
015dc7e1 6198 return false;
049b0c3a
NC
6199 if (size < sizeof * shdrs)
6200 {
6201 if (! probe)
6202 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6203 return false;
049b0c3a
NC
6204 }
6205 if (!probe && size > sizeof * shdrs)
6206 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 6207
dda8d76d 6208 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
6209 size, num,
6210 probe ? NULL : _("section headers"));
6211 if (shdrs == NULL)
015dc7e1 6212 return false;
252b5132 6213
dda8d76d
NC
6214 filedata->section_headers = (Elf_Internal_Shdr *)
6215 cmalloc (num, sizeof (Elf_Internal_Shdr));
6216 if (filedata->section_headers == NULL)
252b5132 6217 {
049b0c3a 6218 if (!probe)
8b73c356 6219 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6220 free (shdrs);
015dc7e1 6221 return false;
252b5132
RH
6222 }
6223
dda8d76d 6224 for (i = 0, internal = filedata->section_headers;
560f3c1c 6225 i < num;
b34976b6 6226 i++, internal++)
252b5132
RH
6227 {
6228 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6229 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
6230 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6231 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6232 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6233 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6234 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6235 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6236 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
6237 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
6238 if (!probe && internal->sh_link > num)
6239 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6240 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6241 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
6242 }
6243
6244 free (shdrs);
015dc7e1 6245 return true;
252b5132
RH
6246}
6247
dda8d76d
NC
6248/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
6249
015dc7e1
AM
6250static bool
6251get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 6252{
dda8d76d
NC
6253 Elf64_External_Shdr * shdrs;
6254 Elf_Internal_Shdr * internal;
6255 unsigned int i;
6256 unsigned int size = filedata->file_header.e_shentsize;
6257 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
6258
6259 /* PR binutils/17531: Cope with unexpected section header sizes. */
6260 if (size == 0 || num == 0)
015dc7e1 6261 return false;
dda8d76d 6262
049b0c3a
NC
6263 if (size < sizeof * shdrs)
6264 {
6265 if (! probe)
6266 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 6267 return false;
049b0c3a 6268 }
dda8d76d 6269
049b0c3a
NC
6270 if (! probe && size > sizeof * shdrs)
6271 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 6272
dda8d76d
NC
6273 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
6274 filedata->file_header.e_shoff,
049b0c3a
NC
6275 size, num,
6276 probe ? NULL : _("section headers"));
6277 if (shdrs == NULL)
015dc7e1 6278 return false;
9ea033b2 6279
dda8d76d
NC
6280 filedata->section_headers = (Elf_Internal_Shdr *)
6281 cmalloc (num, sizeof (Elf_Internal_Shdr));
6282 if (filedata->section_headers == NULL)
9ea033b2 6283 {
049b0c3a 6284 if (! probe)
8b73c356 6285 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 6286 free (shdrs);
015dc7e1 6287 return false;
9ea033b2
NC
6288 }
6289
dda8d76d 6290 for (i = 0, internal = filedata->section_headers;
560f3c1c 6291 i < num;
b34976b6 6292 i++, internal++)
9ea033b2
NC
6293 {
6294 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
6295 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
6296 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
6297 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
6298 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
6299 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
6300 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
6301 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
6302 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
6303 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
6304 if (!probe && internal->sh_link > num)
6305 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
6306 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
6307 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
6308 }
6309
6310 free (shdrs);
015dc7e1 6311 return true;
9ea033b2
NC
6312}
6313
4de91c10
AM
6314static bool
6315get_section_headers (Filedata *filedata, bool probe)
6316{
6317 if (filedata->section_headers != NULL)
6318 return true;
6319
4de91c10
AM
6320 if (is_32bit_elf)
6321 return get_32bit_section_headers (filedata, probe);
6322 else
6323 return get_64bit_section_headers (filedata, probe);
6324}
6325
252b5132 6326static Elf_Internal_Sym *
dda8d76d
NC
6327get_32bit_elf_symbols (Filedata * filedata,
6328 Elf_Internal_Shdr * section,
6329 unsigned long * num_syms_return)
252b5132 6330{
ba5cdace 6331 unsigned long number = 0;
dd24e3da 6332 Elf32_External_Sym * esyms = NULL;
ba5cdace 6333 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 6334 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6335 Elf_Internal_Sym * psym;
b34976b6 6336 unsigned int j;
e3d39609 6337 elf_section_list * entry;
252b5132 6338
c9c1d674
EG
6339 if (section->sh_size == 0)
6340 {
6341 if (num_syms_return != NULL)
6342 * num_syms_return = 0;
6343 return NULL;
6344 }
6345
dd24e3da 6346 /* Run some sanity checks first. */
c9c1d674 6347 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6348 {
c9c1d674 6349 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
6350 printable_section_name (filedata, section),
6351 (unsigned long) section->sh_entsize);
ba5cdace 6352 goto exit_point;
dd24e3da
NC
6353 }
6354
dda8d76d 6355 if (section->sh_size > filedata->file_size)
f54498b4
NC
6356 {
6357 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6358 printable_section_name (filedata, section),
6359 (unsigned long) section->sh_size);
f54498b4
NC
6360 goto exit_point;
6361 }
6362
dd24e3da
NC
6363 number = section->sh_size / section->sh_entsize;
6364
6365 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6366 {
c9c1d674 6367 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6368 (unsigned long) section->sh_size,
dda8d76d 6369 printable_section_name (filedata, section),
8066deb1 6370 (unsigned long) section->sh_entsize);
ba5cdace 6371 goto exit_point;
dd24e3da
NC
6372 }
6373
dda8d76d 6374 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6375 section->sh_size, _("symbols"));
dd24e3da 6376 if (esyms == NULL)
ba5cdace 6377 goto exit_point;
252b5132 6378
e3d39609 6379 shndx = NULL;
978c4450 6380 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6381 {
6382 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6383 continue;
6384
6385 if (shndx != NULL)
6386 {
6387 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6388 free (shndx);
6389 }
6390
6391 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6392 entry->hdr->sh_offset,
6393 1, entry->hdr->sh_size,
6394 _("symbol table section indices"));
6395 if (shndx == NULL)
6396 goto exit_point;
6397
6398 /* PR17531: file: heap-buffer-overflow */
6399 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6400 {
6401 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6402 printable_section_name (filedata, entry->hdr),
6403 (unsigned long) entry->hdr->sh_size,
6404 (unsigned long) section->sh_size);
6405 goto exit_point;
c9c1d674 6406 }
e3d39609 6407 }
9ad5cbcf 6408
3f5e193b 6409 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6410
6411 if (isyms == NULL)
6412 {
8b73c356
NC
6413 error (_("Out of memory reading %lu symbols\n"),
6414 (unsigned long) number);
dd24e3da 6415 goto exit_point;
252b5132
RH
6416 }
6417
dd24e3da 6418 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6419 {
6420 psym->st_name = BYTE_GET (esyms[j].st_name);
6421 psym->st_value = BYTE_GET (esyms[j].st_value);
6422 psym->st_size = BYTE_GET (esyms[j].st_size);
6423 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6424 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6425 psym->st_shndx
6426 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6427 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6428 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6429 psym->st_info = BYTE_GET (esyms[j].st_info);
6430 psym->st_other = BYTE_GET (esyms[j].st_other);
6431 }
6432
dd24e3da 6433 exit_point:
e3d39609
NC
6434 free (shndx);
6435 free (esyms);
252b5132 6436
ba5cdace
NC
6437 if (num_syms_return != NULL)
6438 * num_syms_return = isyms == NULL ? 0 : number;
6439
252b5132
RH
6440 return isyms;
6441}
6442
9ea033b2 6443static Elf_Internal_Sym *
dda8d76d
NC
6444get_64bit_elf_symbols (Filedata * filedata,
6445 Elf_Internal_Shdr * section,
6446 unsigned long * num_syms_return)
9ea033b2 6447{
ba5cdace
NC
6448 unsigned long number = 0;
6449 Elf64_External_Sym * esyms = NULL;
6450 Elf_External_Sym_Shndx * shndx = NULL;
6451 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6452 Elf_Internal_Sym * psym;
b34976b6 6453 unsigned int j;
e3d39609 6454 elf_section_list * entry;
9ea033b2 6455
c9c1d674
EG
6456 if (section->sh_size == 0)
6457 {
6458 if (num_syms_return != NULL)
6459 * num_syms_return = 0;
6460 return NULL;
6461 }
6462
dd24e3da 6463 /* Run some sanity checks first. */
c9c1d674 6464 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6465 {
c9c1d674 6466 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6467 printable_section_name (filedata, section),
8066deb1 6468 (unsigned long) section->sh_entsize);
ba5cdace 6469 goto exit_point;
dd24e3da
NC
6470 }
6471
dda8d76d 6472 if (section->sh_size > filedata->file_size)
f54498b4
NC
6473 {
6474 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6475 printable_section_name (filedata, section),
8066deb1 6476 (unsigned long) section->sh_size);
f54498b4
NC
6477 goto exit_point;
6478 }
6479
dd24e3da
NC
6480 number = section->sh_size / section->sh_entsize;
6481
6482 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6483 {
c9c1d674 6484 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6485 (unsigned long) section->sh_size,
dda8d76d 6486 printable_section_name (filedata, section),
8066deb1 6487 (unsigned long) section->sh_entsize);
ba5cdace 6488 goto exit_point;
dd24e3da
NC
6489 }
6490
dda8d76d 6491 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6492 section->sh_size, _("symbols"));
a6e9f9df 6493 if (!esyms)
ba5cdace 6494 goto exit_point;
9ea033b2 6495
e3d39609 6496 shndx = NULL;
978c4450 6497 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6498 {
6499 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6500 continue;
6501
6502 if (shndx != NULL)
6503 {
6504 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6505 free (shndx);
c9c1d674 6506 }
e3d39609
NC
6507
6508 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6509 entry->hdr->sh_offset,
6510 1, entry->hdr->sh_size,
6511 _("symbol table section indices"));
6512 if (shndx == NULL)
6513 goto exit_point;
6514
6515 /* PR17531: file: heap-buffer-overflow */
6516 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6517 {
6518 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6519 printable_section_name (filedata, entry->hdr),
6520 (unsigned long) entry->hdr->sh_size,
6521 (unsigned long) section->sh_size);
6522 goto exit_point;
6523 }
6524 }
9ad5cbcf 6525
3f5e193b 6526 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6527
6528 if (isyms == NULL)
6529 {
8b73c356
NC
6530 error (_("Out of memory reading %lu symbols\n"),
6531 (unsigned long) number);
ba5cdace 6532 goto exit_point;
9ea033b2
NC
6533 }
6534
ba5cdace 6535 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6536 {
6537 psym->st_name = BYTE_GET (esyms[j].st_name);
6538 psym->st_info = BYTE_GET (esyms[j].st_info);
6539 psym->st_other = BYTE_GET (esyms[j].st_other);
6540 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6541
4fbb74a6 6542 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6543 psym->st_shndx
6544 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6545 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6546 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6547
66543521
AM
6548 psym->st_value = BYTE_GET (esyms[j].st_value);
6549 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6550 }
6551
ba5cdace 6552 exit_point:
e3d39609
NC
6553 free (shndx);
6554 free (esyms);
ba5cdace
NC
6555
6556 if (num_syms_return != NULL)
6557 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6558
6559 return isyms;
6560}
6561
4de91c10
AM
6562static Elf_Internal_Sym *
6563get_elf_symbols (Filedata *filedata,
6564 Elf_Internal_Shdr *section,
6565 unsigned long *num_syms_return)
6566{
6567 if (is_32bit_elf)
6568 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6569 else
6570 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6571}
6572
d1133906 6573static const char *
dda8d76d 6574get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6575{
5477e8a0 6576 static char buff[1024];
2cf0635d 6577 char * p = buff;
32ec8896
NC
6578 unsigned int field_size = is_32bit_elf ? 8 : 16;
6579 signed int sindex;
6580 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6581 bfd_vma os_flags = 0;
6582 bfd_vma proc_flags = 0;
6583 bfd_vma unknown_flags = 0;
148b93f2 6584 static const struct
5477e8a0 6585 {
2cf0635d 6586 const char * str;
32ec8896 6587 unsigned int len;
5477e8a0
L
6588 }
6589 flags [] =
6590 {
cfcac11d
NC
6591 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6592 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6593 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6594 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6595 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6596 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6597 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6598 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6599 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6600 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6601 /* IA-64 specific. */
6602 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6603 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6604 /* IA-64 OpenVMS specific. */
6605 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6606 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6607 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6608 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6609 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6610 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6611 /* Generic. */
cfcac11d 6612 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6613 /* SPARC specific. */
77115a4a 6614 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6615 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6616 /* ARM specific. */
6617 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6618 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6619 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6620 /* GNU specific. */
6621 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6622 /* VLE specific. */
6623 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6624 /* GNU specific. */
6625 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6626 };
6627
6628 if (do_section_details)
6629 {
8d5ff12c
L
6630 sprintf (buff, "[%*.*lx]: ",
6631 field_size, field_size, (unsigned long) sh_flags);
6632 p += field_size + 4;
5477e8a0 6633 }
76da6bbe 6634
d1133906
NC
6635 while (sh_flags)
6636 {
6637 bfd_vma flag;
6638
6639 flag = sh_flags & - sh_flags;
6640 sh_flags &= ~ flag;
76da6bbe 6641
5477e8a0 6642 if (do_section_details)
d1133906 6643 {
5477e8a0
L
6644 switch (flag)
6645 {
91d6fa6a
NC
6646 case SHF_WRITE: sindex = 0; break;
6647 case SHF_ALLOC: sindex = 1; break;
6648 case SHF_EXECINSTR: sindex = 2; break;
6649 case SHF_MERGE: sindex = 3; break;
6650 case SHF_STRINGS: sindex = 4; break;
6651 case SHF_INFO_LINK: sindex = 5; break;
6652 case SHF_LINK_ORDER: sindex = 6; break;
6653 case SHF_OS_NONCONFORMING: sindex = 7; break;
6654 case SHF_GROUP: sindex = 8; break;
6655 case SHF_TLS: sindex = 9; break;
18ae9cc1 6656 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6657 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6658
5477e8a0 6659 default:
91d6fa6a 6660 sindex = -1;
dda8d76d 6661 switch (filedata->file_header.e_machine)
148b93f2 6662 {
cfcac11d 6663 case EM_IA_64:
148b93f2 6664 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6665 sindex = 10;
148b93f2 6666 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6667 sindex = 11;
148b93f2 6668#ifdef BFD64
dda8d76d 6669 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6670 switch (flag)
6671 {
91d6fa6a
NC
6672 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6673 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6674 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6675 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6676 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6677 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6678 default: break;
6679 }
6680#endif
cfcac11d
NC
6681 break;
6682
caa83f8b 6683 case EM_386:
22abe556 6684 case EM_IAMCU:
caa83f8b 6685 case EM_X86_64:
7f502d6c 6686 case EM_L1OM:
7a9068fe 6687 case EM_K1OM:
cfcac11d
NC
6688 case EM_OLD_SPARCV9:
6689 case EM_SPARC32PLUS:
6690 case EM_SPARCV9:
6691 case EM_SPARC:
18ae9cc1 6692 if (flag == SHF_ORDERED)
91d6fa6a 6693 sindex = 19;
cfcac11d 6694 break;
ac4c9b04
MG
6695
6696 case EM_ARM:
6697 switch (flag)
6698 {
6699 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6700 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6701 case SHF_COMDEF: sindex = 23; break;
6702 default: break;
6703 }
6704 break;
83eef883
AFB
6705 case EM_PPC:
6706 if (flag == SHF_PPC_VLE)
6707 sindex = 25;
6708 break;
99fabbc9
JL
6709 default:
6710 break;
6711 }
ac4c9b04 6712
99fabbc9
JL
6713 switch (filedata->file_header.e_ident[EI_OSABI])
6714 {
6715 case ELFOSABI_GNU:
6716 case ELFOSABI_FREEBSD:
6717 if (flag == SHF_GNU_RETAIN)
6718 sindex = 26;
6719 /* Fall through */
6720 case ELFOSABI_NONE:
6721 if (flag == SHF_GNU_MBIND)
6722 /* We should not recognize SHF_GNU_MBIND for
6723 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6724 not set the EI_OSABI header byte. */
6725 sindex = 24;
6726 break;
cfcac11d
NC
6727 default:
6728 break;
148b93f2 6729 }
99fabbc9 6730 break;
5477e8a0
L
6731 }
6732
91d6fa6a 6733 if (sindex != -1)
5477e8a0 6734 {
8d5ff12c
L
6735 if (p != buff + field_size + 4)
6736 {
6737 if (size < (10 + 2))
bee0ee85
NC
6738 {
6739 warn (_("Internal error: not enough buffer room for section flag info"));
6740 return _("<unknown>");
6741 }
8d5ff12c
L
6742 size -= 2;
6743 *p++ = ',';
6744 *p++ = ' ';
6745 }
6746
91d6fa6a
NC
6747 size -= flags [sindex].len;
6748 p = stpcpy (p, flags [sindex].str);
5477e8a0 6749 }
3b22753a 6750 else if (flag & SHF_MASKOS)
8d5ff12c 6751 os_flags |= flag;
d1133906 6752 else if (flag & SHF_MASKPROC)
8d5ff12c 6753 proc_flags |= flag;
d1133906 6754 else
8d5ff12c 6755 unknown_flags |= flag;
5477e8a0
L
6756 }
6757 else
6758 {
6759 switch (flag)
6760 {
6761 case SHF_WRITE: *p = 'W'; break;
6762 case SHF_ALLOC: *p = 'A'; break;
6763 case SHF_EXECINSTR: *p = 'X'; break;
6764 case SHF_MERGE: *p = 'M'; break;
6765 case SHF_STRINGS: *p = 'S'; break;
6766 case SHF_INFO_LINK: *p = 'I'; break;
6767 case SHF_LINK_ORDER: *p = 'L'; break;
6768 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6769 case SHF_GROUP: *p = 'G'; break;
6770 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6771 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6772 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6773
6774 default:
dda8d76d
NC
6775 if ((filedata->file_header.e_machine == EM_X86_64
6776 || filedata->file_header.e_machine == EM_L1OM
6777 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6778 && flag == SHF_X86_64_LARGE)
6779 *p = 'l';
dda8d76d 6780 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6781 && flag == SHF_ARM_PURECODE)
99fabbc9 6782 *p = 'y';
dda8d76d 6783 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6784 && flag == SHF_PPC_VLE)
99fabbc9 6785 *p = 'v';
5477e8a0
L
6786 else if (flag & SHF_MASKOS)
6787 {
99fabbc9
JL
6788 switch (filedata->file_header.e_ident[EI_OSABI])
6789 {
6790 case ELFOSABI_GNU:
6791 case ELFOSABI_FREEBSD:
6792 if (flag == SHF_GNU_RETAIN)
6793 {
6794 *p = 'R';
6795 break;
6796 }
6797 /* Fall through */
6798 case ELFOSABI_NONE:
6799 if (flag == SHF_GNU_MBIND)
6800 {
6801 /* We should not recognize SHF_GNU_MBIND for
6802 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6803 not set the EI_OSABI header byte. */
6804 *p = 'D';
6805 break;
6806 }
6807 /* Fall through */
6808 default:
6809 *p = 'o';
6810 sh_flags &= ~SHF_MASKOS;
6811 break;
6812 }
5477e8a0
L
6813 }
6814 else if (flag & SHF_MASKPROC)
6815 {
6816 *p = 'p';
6817 sh_flags &= ~ SHF_MASKPROC;
6818 }
6819 else
6820 *p = 'x';
6821 break;
6822 }
6823 p++;
d1133906
NC
6824 }
6825 }
76da6bbe 6826
8d5ff12c
L
6827 if (do_section_details)
6828 {
6829 if (os_flags)
6830 {
6831 size -= 5 + field_size;
6832 if (p != buff + field_size + 4)
6833 {
6834 if (size < (2 + 1))
bee0ee85
NC
6835 {
6836 warn (_("Internal error: not enough buffer room for section flag info"));
6837 return _("<unknown>");
6838 }
8d5ff12c
L
6839 size -= 2;
6840 *p++ = ',';
6841 *p++ = ' ';
6842 }
6843 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6844 (unsigned long) os_flags);
6845 p += 5 + field_size;
6846 }
6847 if (proc_flags)
6848 {
6849 size -= 7 + field_size;
6850 if (p != buff + field_size + 4)
6851 {
6852 if (size < (2 + 1))
bee0ee85
NC
6853 {
6854 warn (_("Internal error: not enough buffer room for section flag info"));
6855 return _("<unknown>");
6856 }
8d5ff12c
L
6857 size -= 2;
6858 *p++ = ',';
6859 *p++ = ' ';
6860 }
6861 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6862 (unsigned long) proc_flags);
6863 p += 7 + field_size;
6864 }
6865 if (unknown_flags)
6866 {
6867 size -= 10 + field_size;
6868 if (p != buff + field_size + 4)
6869 {
6870 if (size < (2 + 1))
bee0ee85
NC
6871 {
6872 warn (_("Internal error: not enough buffer room for section flag info"));
6873 return _("<unknown>");
6874 }
8d5ff12c
L
6875 size -= 2;
6876 *p++ = ',';
6877 *p++ = ' ';
6878 }
2b692964 6879 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6880 (unsigned long) unknown_flags);
6881 p += 10 + field_size;
6882 }
6883 }
6884
e9e44622 6885 *p = '\0';
d1133906
NC
6886 return buff;
6887}
6888
5844b465 6889static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6890get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6891{
6892 if (is_32bit_elf)
6893 {
6894 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6895
ebdf1ebf
NC
6896 if (size < sizeof (* echdr))
6897 {
6898 error (_("Compressed section is too small even for a compression header\n"));
6899 return 0;
6900 }
6901
77115a4a
L
6902 chdr->ch_type = BYTE_GET (echdr->ch_type);
6903 chdr->ch_size = BYTE_GET (echdr->ch_size);
6904 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6905 return sizeof (*echdr);
6906 }
6907 else
6908 {
6909 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6910
ebdf1ebf
NC
6911 if (size < sizeof (* echdr))
6912 {
6913 error (_("Compressed section is too small even for a compression header\n"));
6914 return 0;
6915 }
6916
77115a4a
L
6917 chdr->ch_type = BYTE_GET (echdr->ch_type);
6918 chdr->ch_size = BYTE_GET (echdr->ch_size);
6919 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6920 return sizeof (*echdr);
6921 }
6922}
6923
015dc7e1 6924static bool
dda8d76d 6925process_section_headers (Filedata * filedata)
252b5132 6926{
2cf0635d 6927 Elf_Internal_Shdr * section;
b34976b6 6928 unsigned int i;
252b5132 6929
dda8d76d 6930 if (filedata->file_header.e_shnum == 0)
252b5132 6931 {
82f2dbf7 6932 /* PR binutils/12467. */
dda8d76d 6933 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6934 {
6935 warn (_("possibly corrupt ELF file header - it has a non-zero"
6936 " section header offset, but no section headers\n"));
015dc7e1 6937 return false;
32ec8896 6938 }
82f2dbf7 6939 else if (do_sections)
252b5132
RH
6940 printf (_("\nThere are no sections in this file.\n"));
6941
015dc7e1 6942 return true;
252b5132
RH
6943 }
6944
6945 if (do_sections && !do_header)
ca0e11aa
NC
6946 {
6947 if (filedata->is_separate && process_links)
6948 printf (_("In linked file '%s': "), filedata->file_name);
6949 if (! filedata->is_separate || process_links)
6950 printf (ngettext ("There is %d section header, "
6951 "starting at offset 0x%lx:\n",
6952 "There are %d section headers, "
6953 "starting at offset 0x%lx:\n",
6954 filedata->file_header.e_shnum),
6955 filedata->file_header.e_shnum,
6956 (unsigned long) filedata->file_header.e_shoff);
6957 }
252b5132 6958
4de91c10
AM
6959 if (!get_section_headers (filedata, false))
6960 return false;
252b5132
RH
6961
6962 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6963 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6964 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6965 {
dda8d76d 6966 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6967
c256ffe7
JJ
6968 if (section->sh_size != 0)
6969 {
dda8d76d
NC
6970 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6971 1, section->sh_size,
6972 _("string table"));
0de14b54 6973
dda8d76d 6974 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6975 }
252b5132
RH
6976 }
6977
6978 /* Scan the sections for the dynamic symbol table
e3c8793a 6979 and dynamic string table and debug sections. */
89fac5e3 6980 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6981 switch (filedata->file_header.e_machine)
89fac5e3
RS
6982 {
6983 case EM_MIPS:
6984 case EM_MIPS_RS3_LE:
6985 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6986 FDE addresses. However, the ABI also has a semi-official ILP32
6987 variant for which the normal FDE address size rules apply.
6988
6989 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6990 section, where XX is the size of longs in bits. Unfortunately,
6991 earlier compilers provided no way of distinguishing ILP32 objects
6992 from LP64 objects, so if there's any doubt, we should assume that
6993 the official LP64 form is being used. */
dda8d76d
NC
6994 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6995 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6996 eh_addr_size = 8;
6997 break;
0f56a26a
DD
6998
6999 case EM_H8_300:
7000 case EM_H8_300H:
dda8d76d 7001 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
7002 {
7003 case E_H8_MACH_H8300:
7004 case E_H8_MACH_H8300HN:
7005 case E_H8_MACH_H8300SN:
7006 case E_H8_MACH_H8300SXN:
7007 eh_addr_size = 2;
7008 break;
7009 case E_H8_MACH_H8300H:
7010 case E_H8_MACH_H8300S:
7011 case E_H8_MACH_H8300SX:
7012 eh_addr_size = 4;
7013 break;
7014 }
f4236fe4
DD
7015 break;
7016
ff7eeb89 7017 case EM_M32C_OLD:
f4236fe4 7018 case EM_M32C:
dda8d76d 7019 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
7020 {
7021 case EF_M32C_CPU_M16C:
7022 eh_addr_size = 2;
7023 break;
7024 }
7025 break;
89fac5e3
RS
7026 }
7027
76ca31c0
NC
7028#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
7029 do \
7030 { \
7031 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
7032 if (section->sh_entsize != expected_entsize) \
9dd3a467 7033 { \
76ca31c0
NC
7034 char buf[40]; \
7035 sprintf_vma (buf, section->sh_entsize); \
7036 /* Note: coded this way so that there is a single string for \
7037 translation. */ \
7038 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
7039 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
7040 (unsigned) expected_entsize); \
9dd3a467 7041 section->sh_entsize = expected_entsize; \
76ca31c0
NC
7042 } \
7043 } \
08d8fa11 7044 while (0)
9dd3a467
NC
7045
7046#define CHECK_ENTSIZE(section, i, type) \
1b513401 7047 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
7048 sizeof (Elf64_External_##type))
7049
dda8d76d
NC
7050 for (i = 0, section = filedata->section_headers;
7051 i < filedata->file_header.e_shnum;
b34976b6 7052 i++, section++)
252b5132 7053 {
84714f86 7054 const char *name = section_name_print (filedata, section);
252b5132 7055
1b513401
NC
7056 /* Run some sanity checks on the headers and
7057 possibly fill in some file data as well. */
7058 switch (section->sh_type)
252b5132 7059 {
1b513401 7060 case SHT_DYNSYM:
978c4450 7061 if (filedata->dynamic_symbols != NULL)
252b5132
RH
7062 {
7063 error (_("File contains multiple dynamic symbol tables\n"));
7064 continue;
7065 }
7066
08d8fa11 7067 CHECK_ENTSIZE (section, i, Sym);
978c4450 7068 filedata->dynamic_symbols
4de91c10 7069 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 7070 filedata->dynamic_symtab_section = section;
1b513401
NC
7071 break;
7072
7073 case SHT_STRTAB:
7074 if (streq (name, ".dynstr"))
252b5132 7075 {
1b513401
NC
7076 if (filedata->dynamic_strings != NULL)
7077 {
7078 error (_("File contains multiple dynamic string tables\n"));
7079 continue;
7080 }
7081
7082 filedata->dynamic_strings
7083 = (char *) get_data (NULL, filedata, section->sh_offset,
7084 1, section->sh_size, _("dynamic strings"));
7085 filedata->dynamic_strings_length
7086 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 7087 filedata->dynamic_strtab_section = section;
252b5132 7088 }
1b513401
NC
7089 break;
7090
7091 case SHT_SYMTAB_SHNDX:
7092 {
7093 elf_section_list * entry = xmalloc (sizeof * entry);
7094
7095 entry->hdr = section;
7096 entry->next = filedata->symtab_shndx_list;
7097 filedata->symtab_shndx_list = entry;
7098 }
7099 break;
7100
7101 case SHT_SYMTAB:
7102 CHECK_ENTSIZE (section, i, Sym);
7103 break;
7104
7105 case SHT_GROUP:
7106 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
7107 break;
252b5132 7108
1b513401
NC
7109 case SHT_REL:
7110 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 7111 if (do_checks && section->sh_size == 0)
1b513401
NC
7112 warn (_("Section '%s': zero-sized relocation section\n"), name);
7113 break;
7114
7115 case SHT_RELA:
7116 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 7117 if (do_checks && section->sh_size == 0)
1b513401
NC
7118 warn (_("Section '%s': zero-sized relocation section\n"), name);
7119 break;
7120
682351b9
AM
7121 case SHT_RELR:
7122 CHECK_ENTSIZE (section, i, Relr);
7123 break;
7124
1b513401
NC
7125 case SHT_NOTE:
7126 case SHT_PROGBITS:
546cb2d8
NC
7127 /* Having a zero sized section is not illegal according to the
7128 ELF standard, but it might be an indication that something
7129 is wrong. So issue a warning if we are running in lint mode. */
7130 if (do_checks && section->sh_size == 0)
1b513401
NC
7131 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
7132 break;
7133
7134 default:
7135 break;
7136 }
7137
7138 if ((do_debugging || do_debug_info || do_debug_abbrevs
7139 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
7140 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
7141 || do_debug_str || do_debug_str_offsets || do_debug_loc
7142 || do_debug_ranges
1b513401 7143 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
7144 && (startswith (name, ".debug_")
7145 || startswith (name, ".zdebug_")))
252b5132 7146 {
1b315056
CS
7147 if (name[1] == 'z')
7148 name += sizeof (".zdebug_") - 1;
7149 else
7150 name += sizeof (".debug_") - 1;
252b5132
RH
7151
7152 if (do_debugging
24d127aa
ML
7153 || (do_debug_info && startswith (name, "info"))
7154 || (do_debug_info && startswith (name, "types"))
7155 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 7156 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
7157 || (do_debug_lines && startswith (name, "line."))
7158 || (do_debug_pubnames && startswith (name, "pubnames"))
7159 || (do_debug_pubtypes && startswith (name, "pubtypes"))
7160 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
7161 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
7162 || (do_debug_aranges && startswith (name, "aranges"))
7163 || (do_debug_ranges && startswith (name, "ranges"))
7164 || (do_debug_ranges && startswith (name, "rnglists"))
7165 || (do_debug_frames && startswith (name, "frame"))
7166 || (do_debug_macinfo && startswith (name, "macinfo"))
7167 || (do_debug_macinfo && startswith (name, "macro"))
7168 || (do_debug_str && startswith (name, "str"))
7169 || (do_debug_links && startswith (name, "sup"))
7170 || (do_debug_str_offsets && startswith (name, "str_offsets"))
7171 || (do_debug_loc && startswith (name, "loc"))
7172 || (do_debug_loc && startswith (name, "loclists"))
7173 || (do_debug_addr && startswith (name, "addr"))
7174 || (do_debug_cu_index && startswith (name, "cu_index"))
7175 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 7176 )
6431e409 7177 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 7178 }
a262ae96 7179 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 7180 else if ((do_debugging || do_debug_info)
24d127aa 7181 && startswith (name, ".gnu.linkonce.wi."))
6431e409 7182 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 7183 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 7184 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
7185 else if (do_gdb_index && (streq (name, ".gdb_index")
7186 || streq (name, ".debug_names")))
6431e409 7187 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
7188 /* Trace sections for Itanium VMS. */
7189 else if ((do_debugging || do_trace_info || do_trace_abbrevs
7190 || do_trace_aranges)
24d127aa 7191 && startswith (name, ".trace_"))
6f875884
TG
7192 {
7193 name += sizeof (".trace_") - 1;
7194
7195 if (do_debugging
7196 || (do_trace_info && streq (name, "info"))
7197 || (do_trace_abbrevs && streq (name, "abbrev"))
7198 || (do_trace_aranges && streq (name, "aranges"))
7199 )
6431e409 7200 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 7201 }
dda8d76d 7202 else if ((do_debugging || do_debug_links)
24d127aa
ML
7203 && (startswith (name, ".gnu_debuglink")
7204 || startswith (name, ".gnu_debugaltlink")))
6431e409 7205 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
7206 }
7207
7208 if (! do_sections)
015dc7e1 7209 return true;
252b5132 7210
ca0e11aa 7211 if (filedata->is_separate && ! process_links)
015dc7e1 7212 return true;
ca0e11aa
NC
7213
7214 if (filedata->is_separate)
7215 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
7216 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
7217 printf (_("\nSection Headers:\n"));
7218 else
7219 printf (_("\nSection Header:\n"));
76da6bbe 7220
f7a99963 7221 if (is_32bit_elf)
595cf52e 7222 {
5477e8a0 7223 if (do_section_details)
595cf52e
L
7224 {
7225 printf (_(" [Nr] Name\n"));
5477e8a0 7226 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
7227 }
7228 else
7229 printf
7230 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
7231 }
d974e256 7232 else if (do_wide)
595cf52e 7233 {
5477e8a0 7234 if (do_section_details)
595cf52e
L
7235 {
7236 printf (_(" [Nr] Name\n"));
5477e8a0 7237 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
7238 }
7239 else
7240 printf
7241 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
7242 }
f7a99963
NC
7243 else
7244 {
5477e8a0 7245 if (do_section_details)
595cf52e
L
7246 {
7247 printf (_(" [Nr] Name\n"));
5477e8a0
L
7248 printf (_(" Type Address Offset Link\n"));
7249 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
7250 }
7251 else
7252 {
7253 printf (_(" [Nr] Name Type Address Offset\n"));
7254 printf (_(" Size EntSize Flags Link Info Align\n"));
7255 }
f7a99963 7256 }
252b5132 7257
5477e8a0
L
7258 if (do_section_details)
7259 printf (_(" Flags\n"));
7260
dda8d76d
NC
7261 for (i = 0, section = filedata->section_headers;
7262 i < filedata->file_header.e_shnum;
b34976b6 7263 i++, section++)
252b5132 7264 {
dd905818
NC
7265 /* Run some sanity checks on the section header. */
7266
7267 /* Check the sh_link field. */
7268 switch (section->sh_type)
7269 {
285e3f99
AM
7270 case SHT_REL:
7271 case SHT_RELA:
7272 if (section->sh_link == 0
7273 && (filedata->file_header.e_type == ET_EXEC
7274 || filedata->file_header.e_type == ET_DYN))
7275 /* A dynamic relocation section where all entries use a
7276 zero symbol index need not specify a symtab section. */
7277 break;
7278 /* Fall through. */
dd905818
NC
7279 case SHT_SYMTAB_SHNDX:
7280 case SHT_GROUP:
7281 case SHT_HASH:
7282 case SHT_GNU_HASH:
7283 case SHT_GNU_versym:
285e3f99 7284 if (section->sh_link == 0
dda8d76d
NC
7285 || section->sh_link >= filedata->file_header.e_shnum
7286 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
7287 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
7288 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
7289 i, section->sh_link);
7290 break;
7291
7292 case SHT_DYNAMIC:
7293 case SHT_SYMTAB:
7294 case SHT_DYNSYM:
7295 case SHT_GNU_verneed:
7296 case SHT_GNU_verdef:
7297 case SHT_GNU_LIBLIST:
285e3f99 7298 if (section->sh_link == 0
dda8d76d
NC
7299 || section->sh_link >= filedata->file_header.e_shnum
7300 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
7301 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
7302 i, section->sh_link);
7303 break;
7304
7305 case SHT_INIT_ARRAY:
7306 case SHT_FINI_ARRAY:
7307 case SHT_PREINIT_ARRAY:
7308 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7309 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7310 i, section->sh_link);
7311 break;
7312
7313 default:
7314 /* FIXME: Add support for target specific section types. */
7315#if 0 /* Currently we do not check other section types as there are too
7316 many special cases. Stab sections for example have a type
7317 of SHT_PROGBITS but an sh_link field that links to the .stabstr
7318 section. */
7319 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
7320 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
7321 i, section->sh_link);
7322#endif
7323 break;
7324 }
7325
7326 /* Check the sh_info field. */
7327 switch (section->sh_type)
7328 {
7329 case SHT_REL:
7330 case SHT_RELA:
285e3f99
AM
7331 if (section->sh_info == 0
7332 && (filedata->file_header.e_type == ET_EXEC
7333 || filedata->file_header.e_type == ET_DYN))
7334 /* Dynamic relocations apply to segments, so they do not
7335 need to specify the section they relocate. */
7336 break;
7337 if (section->sh_info == 0
dda8d76d
NC
7338 || section->sh_info >= filedata->file_header.e_shnum
7339 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
7340 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
7341 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
7342 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
7343 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
7344 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 7345 /* FIXME: Are other section types valid ? */
dda8d76d 7346 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
7347 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
7348 i, section->sh_info);
dd905818
NC
7349 break;
7350
7351 case SHT_DYNAMIC:
7352 case SHT_HASH:
7353 case SHT_SYMTAB_SHNDX:
7354 case SHT_INIT_ARRAY:
7355 case SHT_FINI_ARRAY:
7356 case SHT_PREINIT_ARRAY:
7357 if (section->sh_info != 0)
7358 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7359 i, section->sh_info);
7360 break;
7361
7362 case SHT_GROUP:
7363 case SHT_SYMTAB:
7364 case SHT_DYNSYM:
7365 /* A symbol index - we assume that it is valid. */
7366 break;
7367
7368 default:
7369 /* FIXME: Add support for target specific section types. */
7370 if (section->sh_type == SHT_NOBITS)
7371 /* NOBITS section headers with non-zero sh_info fields can be
7372 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7373 information. The stripped sections have their headers
7374 preserved but their types set to SHT_NOBITS. So do not check
7375 this type of section. */
dd905818
NC
7376 ;
7377 else if (section->sh_flags & SHF_INFO_LINK)
7378 {
dda8d76d 7379 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7380 warn (_("[%2u]: Expected link to another section in info field"), i);
7381 }
a91e1603
L
7382 else if (section->sh_type < SHT_LOOS
7383 && (section->sh_flags & SHF_GNU_MBIND) == 0
7384 && section->sh_info != 0)
dd905818
NC
7385 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7386 i, section->sh_info);
7387 break;
7388 }
7389
3e6b6445 7390 /* Check the sh_size field. */
dda8d76d 7391 if (section->sh_size > filedata->file_size
3e6b6445
NC
7392 && section->sh_type != SHT_NOBITS
7393 && section->sh_type != SHT_NULL
7394 && section->sh_type < SHT_LOOS)
7395 warn (_("Size of section %u is larger than the entire file!\n"), i);
7396
7bfd842d 7397 printf (" [%2u] ", i);
5477e8a0 7398 if (do_section_details)
dda8d76d 7399 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7400 else
84714f86 7401 print_symbol (-17, section_name_print (filedata, section));
0b4362b0 7402
ea52a088 7403 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7404 get_section_type_name (filedata, section->sh_type));
0b4362b0 7405
f7a99963
NC
7406 if (is_32bit_elf)
7407 {
cfcac11d
NC
7408 const char * link_too_big = NULL;
7409
f7a99963 7410 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7411
f7a99963
NC
7412 printf ( " %6.6lx %6.6lx %2.2lx",
7413 (unsigned long) section->sh_offset,
7414 (unsigned long) section->sh_size,
7415 (unsigned long) section->sh_entsize);
d1133906 7416
5477e8a0
L
7417 if (do_section_details)
7418 fputs (" ", stdout);
7419 else
dda8d76d 7420 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7421
dda8d76d 7422 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7423 {
7424 link_too_big = "";
7425 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7426 an error but it can have special values in Solaris binaries. */
dda8d76d 7427 switch (filedata->file_header.e_machine)
cfcac11d 7428 {
caa83f8b 7429 case EM_386:
22abe556 7430 case EM_IAMCU:
caa83f8b 7431 case EM_X86_64:
7f502d6c 7432 case EM_L1OM:
7a9068fe 7433 case EM_K1OM:
cfcac11d
NC
7434 case EM_OLD_SPARCV9:
7435 case EM_SPARC32PLUS:
7436 case EM_SPARCV9:
7437 case EM_SPARC:
7438 if (section->sh_link == (SHN_BEFORE & 0xffff))
7439 link_too_big = "BEFORE";
7440 else if (section->sh_link == (SHN_AFTER & 0xffff))
7441 link_too_big = "AFTER";
7442 break;
7443 default:
7444 break;
7445 }
7446 }
7447
7448 if (do_section_details)
7449 {
7450 if (link_too_big != NULL && * link_too_big)
7451 printf ("<%s> ", link_too_big);
7452 else
7453 printf ("%2u ", section->sh_link);
7454 printf ("%3u %2lu\n", section->sh_info,
7455 (unsigned long) section->sh_addralign);
7456 }
7457 else
7458 printf ("%2u %3u %2lu\n",
7459 section->sh_link,
7460 section->sh_info,
7461 (unsigned long) section->sh_addralign);
7462
7463 if (link_too_big && ! * link_too_big)
7464 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7465 i, section->sh_link);
f7a99963 7466 }
d974e256
JJ
7467 else if (do_wide)
7468 {
7469 print_vma (section->sh_addr, LONG_HEX);
7470
7471 if ((long) section->sh_offset == section->sh_offset)
7472 printf (" %6.6lx", (unsigned long) section->sh_offset);
7473 else
7474 {
7475 putchar (' ');
7476 print_vma (section->sh_offset, LONG_HEX);
7477 }
7478
7479 if ((unsigned long) section->sh_size == section->sh_size)
7480 printf (" %6.6lx", (unsigned long) section->sh_size);
7481 else
7482 {
7483 putchar (' ');
7484 print_vma (section->sh_size, LONG_HEX);
7485 }
7486
7487 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7488 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7489 else
7490 {
7491 putchar (' ');
7492 print_vma (section->sh_entsize, LONG_HEX);
7493 }
7494
5477e8a0
L
7495 if (do_section_details)
7496 fputs (" ", stdout);
7497 else
dda8d76d 7498 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7499
72de5009 7500 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7501
7502 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7503 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7504 else
7505 {
7506 print_vma (section->sh_addralign, DEC);
7507 putchar ('\n');
7508 }
7509 }
5477e8a0 7510 else if (do_section_details)
595cf52e 7511 {
55cc53e9 7512 putchar (' ');
595cf52e
L
7513 print_vma (section->sh_addr, LONG_HEX);
7514 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7515 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7516 else
7517 {
7518 printf (" ");
7519 print_vma (section->sh_offset, LONG_HEX);
7520 }
72de5009 7521 printf (" %u\n ", section->sh_link);
595cf52e 7522 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7523 putchar (' ');
595cf52e
L
7524 print_vma (section->sh_entsize, LONG_HEX);
7525
72de5009
AM
7526 printf (" %-16u %lu\n",
7527 section->sh_info,
595cf52e
L
7528 (unsigned long) section->sh_addralign);
7529 }
f7a99963
NC
7530 else
7531 {
7532 putchar (' ');
7533 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7534 if ((long) section->sh_offset == section->sh_offset)
7535 printf (" %8.8lx", (unsigned long) section->sh_offset);
7536 else
7537 {
7538 printf (" ");
7539 print_vma (section->sh_offset, LONG_HEX);
7540 }
f7a99963
NC
7541 printf ("\n ");
7542 print_vma (section->sh_size, LONG_HEX);
7543 printf (" ");
7544 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7545
dda8d76d 7546 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7547
72de5009
AM
7548 printf (" %2u %3u %lu\n",
7549 section->sh_link,
7550 section->sh_info,
f7a99963
NC
7551 (unsigned long) section->sh_addralign);
7552 }
5477e8a0
L
7553
7554 if (do_section_details)
77115a4a 7555 {
dda8d76d 7556 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7557 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7558 {
7559 /* Minimum section size is 12 bytes for 32-bit compression
7560 header + 12 bytes for compressed data header. */
7561 unsigned char buf[24];
d8024a91 7562
77115a4a 7563 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7564 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7565 sizeof (buf), _("compression header")))
7566 {
7567 Elf_Internal_Chdr chdr;
d8024a91 7568
5844b465
NC
7569 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7570 printf (_(" [<corrupt>]\n"));
77115a4a 7571 else
5844b465
NC
7572 {
7573 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7574 printf (" ZLIB, ");
7575 else
7576 printf (_(" [<unknown>: 0x%x], "),
7577 chdr.ch_type);
7578 print_vma (chdr.ch_size, LONG_HEX);
7579 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7580 }
77115a4a
L
7581 }
7582 }
7583 }
252b5132
RH
7584 }
7585
5477e8a0 7586 if (!do_section_details)
3dbcc61d 7587 {
9fb71ee4
NC
7588 /* The ordering of the letters shown here matches the ordering of the
7589 corresponding SHF_xxx values, and hence the order in which these
7590 letters will be displayed to the user. */
7591 printf (_("Key to Flags:\n\
7592 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7593 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7594 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7595 switch (filedata->file_header.e_ident[EI_OSABI])
7596 {
7597 case ELFOSABI_GNU:
7598 case ELFOSABI_FREEBSD:
7599 printf (_("R (retain), "));
7600 /* Fall through */
7601 case ELFOSABI_NONE:
7602 printf (_("D (mbind), "));
7603 break;
7604 default:
7605 break;
7606 }
dda8d76d
NC
7607 if (filedata->file_header.e_machine == EM_X86_64
7608 || filedata->file_header.e_machine == EM_L1OM
7609 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7610 printf (_("l (large), "));
dda8d76d 7611 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7612 printf (_("y (purecode), "));
dda8d76d 7613 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7614 printf (_("v (VLE), "));
9fb71ee4 7615 printf ("p (processor specific)\n");
0b4362b0 7616 }
d1133906 7617
015dc7e1 7618 return true;
252b5132
RH
7619}
7620
015dc7e1 7621static bool
28d13567
AM
7622get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7623 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7624 char **strtab, unsigned long *strtablen)
7625{
7626 *strtab = NULL;
7627 *strtablen = 0;
4de91c10 7628 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7629
7630 if (*symtab == NULL)
015dc7e1 7631 return false;
28d13567
AM
7632
7633 if (symsec->sh_link != 0)
7634 {
7635 Elf_Internal_Shdr *strsec;
7636
7637 if (symsec->sh_link >= filedata->file_header.e_shnum)
7638 {
7639 error (_("Bad sh_link in symbol table section\n"));
7640 free (*symtab);
7641 *symtab = NULL;
7642 *nsyms = 0;
015dc7e1 7643 return false;
28d13567
AM
7644 }
7645
7646 strsec = filedata->section_headers + symsec->sh_link;
7647
7648 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7649 1, strsec->sh_size, _("string table"));
7650 if (*strtab == NULL)
7651 {
7652 free (*symtab);
7653 *symtab = NULL;
7654 *nsyms = 0;
015dc7e1 7655 return false;
28d13567
AM
7656 }
7657 *strtablen = strsec->sh_size;
7658 }
015dc7e1 7659 return true;
28d13567
AM
7660}
7661
f5842774
L
7662static const char *
7663get_group_flags (unsigned int flags)
7664{
1449284b 7665 static char buff[128];
220453ec 7666
6d913794
NC
7667 if (flags == 0)
7668 return "";
7669 else if (flags == GRP_COMDAT)
7670 return "COMDAT ";
f5842774 7671
89246a0e
AM
7672 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7673 flags,
7674 flags & GRP_MASKOS ? _("<OS specific>") : "",
7675 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7676 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7677 ? _("<unknown>") : ""));
6d913794 7678
f5842774
L
7679 return buff;
7680}
7681
015dc7e1 7682static bool
dda8d76d 7683process_section_groups (Filedata * filedata)
f5842774 7684{
2cf0635d 7685 Elf_Internal_Shdr * section;
f5842774 7686 unsigned int i;
2cf0635d
NC
7687 struct group * group;
7688 Elf_Internal_Shdr * symtab_sec;
7689 Elf_Internal_Shdr * strtab_sec;
7690 Elf_Internal_Sym * symtab;
ba5cdace 7691 unsigned long num_syms;
2cf0635d 7692 char * strtab;
c256ffe7 7693 size_t strtab_size;
d1f5c6e3
L
7694
7695 /* Don't process section groups unless needed. */
7696 if (!do_unwind && !do_section_groups)
015dc7e1 7697 return true;
f5842774 7698
dda8d76d 7699 if (filedata->file_header.e_shnum == 0)
f5842774
L
7700 {
7701 if (do_section_groups)
ca0e11aa
NC
7702 {
7703 if (filedata->is_separate)
7704 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7705 filedata->file_name);
7706 else
7707 printf (_("\nThere are no section groups in this file.\n"));
7708 }
015dc7e1 7709 return true;
f5842774
L
7710 }
7711
dda8d76d 7712 if (filedata->section_headers == NULL)
f5842774
L
7713 {
7714 error (_("Section headers are not available!\n"));
fa1908fd 7715 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7716 return false;
f5842774
L
7717 }
7718
978c4450
AM
7719 filedata->section_headers_groups
7720 = (struct group **) calloc (filedata->file_header.e_shnum,
7721 sizeof (struct group *));
e4b17d5c 7722
978c4450 7723 if (filedata->section_headers_groups == NULL)
e4b17d5c 7724 {
8b73c356 7725 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7726 filedata->file_header.e_shnum);
015dc7e1 7727 return false;
e4b17d5c
L
7728 }
7729
f5842774 7730 /* Scan the sections for the group section. */
978c4450 7731 filedata->group_count = 0;
dda8d76d
NC
7732 for (i = 0, section = filedata->section_headers;
7733 i < filedata->file_header.e_shnum;
f5842774 7734 i++, section++)
e4b17d5c 7735 if (section->sh_type == SHT_GROUP)
978c4450 7736 filedata->group_count++;
e4b17d5c 7737
978c4450 7738 if (filedata->group_count == 0)
d1f5c6e3
L
7739 {
7740 if (do_section_groups)
ca0e11aa
NC
7741 {
7742 if (filedata->is_separate)
7743 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7744 filedata->file_name);
7745 else
7746 printf (_("\nThere are no section groups in this file.\n"));
7747 }
d1f5c6e3 7748
015dc7e1 7749 return true;
d1f5c6e3
L
7750 }
7751
978c4450
AM
7752 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7753 sizeof (struct group));
e4b17d5c 7754
978c4450 7755 if (filedata->section_groups == NULL)
e4b17d5c 7756 {
8b73c356 7757 error (_("Out of memory reading %lu groups\n"),
978c4450 7758 (unsigned long) filedata->group_count);
015dc7e1 7759 return false;
e4b17d5c
L
7760 }
7761
d1f5c6e3
L
7762 symtab_sec = NULL;
7763 strtab_sec = NULL;
7764 symtab = NULL;
ba5cdace 7765 num_syms = 0;
d1f5c6e3 7766 strtab = NULL;
c256ffe7 7767 strtab_size = 0;
ca0e11aa
NC
7768
7769 if (filedata->is_separate)
7770 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7771
978c4450 7772 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7773 i < filedata->file_header.e_shnum;
e4b17d5c 7774 i++, section++)
f5842774
L
7775 {
7776 if (section->sh_type == SHT_GROUP)
7777 {
dda8d76d 7778 const char * name = printable_section_name (filedata, section);
74e1a04b 7779 const char * group_name;
2cf0635d
NC
7780 unsigned char * start;
7781 unsigned char * indices;
f5842774 7782 unsigned int entry, j, size;
2cf0635d
NC
7783 Elf_Internal_Shdr * sec;
7784 Elf_Internal_Sym * sym;
f5842774
L
7785
7786 /* Get the symbol table. */
dda8d76d
NC
7787 if (section->sh_link >= filedata->file_header.e_shnum
7788 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7789 != SHT_SYMTAB))
f5842774
L
7790 {
7791 error (_("Bad sh_link in group section `%s'\n"), name);
7792 continue;
7793 }
d1f5c6e3
L
7794
7795 if (symtab_sec != sec)
7796 {
7797 symtab_sec = sec;
9db70fc3 7798 free (symtab);
4de91c10 7799 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7800 }
f5842774 7801
dd24e3da
NC
7802 if (symtab == NULL)
7803 {
7804 error (_("Corrupt header in group section `%s'\n"), name);
7805 continue;
7806 }
7807
ba5cdace
NC
7808 if (section->sh_info >= num_syms)
7809 {
7810 error (_("Bad sh_info in group section `%s'\n"), name);
7811 continue;
7812 }
7813
f5842774
L
7814 sym = symtab + section->sh_info;
7815
7816 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7817 {
4fbb74a6 7818 if (sym->st_shndx == 0
dda8d76d 7819 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7820 {
7821 error (_("Bad sh_info in group section `%s'\n"), name);
7822 continue;
7823 }
ba2685cc 7824
84714f86
AM
7825 group_name = section_name_print (filedata,
7826 filedata->section_headers
b9e920ec 7827 + sym->st_shndx);
c256ffe7 7828 strtab_sec = NULL;
9db70fc3 7829 free (strtab);
f5842774 7830 strtab = NULL;
c256ffe7 7831 strtab_size = 0;
f5842774
L
7832 }
7833 else
7834 {
7835 /* Get the string table. */
dda8d76d 7836 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7837 {
7838 strtab_sec = NULL;
9db70fc3 7839 free (strtab);
c256ffe7
JJ
7840 strtab = NULL;
7841 strtab_size = 0;
7842 }
7843 else if (strtab_sec
dda8d76d 7844 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7845 {
7846 strtab_sec = sec;
9db70fc3 7847 free (strtab);
071436c6 7848
dda8d76d 7849 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7850 1, strtab_sec->sh_size,
7851 _("string table"));
c256ffe7 7852 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7853 }
c256ffe7 7854 group_name = sym->st_name < strtab_size
2b692964 7855 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7856 }
7857
c9c1d674
EG
7858 /* PR 17531: file: loop. */
7859 if (section->sh_entsize > section->sh_size)
7860 {
7861 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7862 printable_section_name (filedata, section),
8066deb1
AM
7863 (unsigned long) section->sh_entsize,
7864 (unsigned long) section->sh_size);
61dd8e19 7865 continue;
c9c1d674
EG
7866 }
7867
dda8d76d 7868 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7869 1, section->sh_size,
7870 _("section data"));
59245841
NC
7871 if (start == NULL)
7872 continue;
f5842774
L
7873
7874 indices = start;
7875 size = (section->sh_size / section->sh_entsize) - 1;
7876 entry = byte_get (indices, 4);
7877 indices += 4;
e4b17d5c
L
7878
7879 if (do_section_groups)
7880 {
2b692964 7881 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7882 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7883
e4b17d5c
L
7884 printf (_(" [Index] Name\n"));
7885 }
7886
7887 group->group_index = i;
7888
f5842774
L
7889 for (j = 0; j < size; j++)
7890 {
2cf0635d 7891 struct group_list * g;
e4b17d5c 7892
f5842774
L
7893 entry = byte_get (indices, 4);
7894 indices += 4;
7895
dda8d76d 7896 if (entry >= filedata->file_header.e_shnum)
391cb864 7897 {
57028622
NC
7898 static unsigned num_group_errors = 0;
7899
7900 if (num_group_errors ++ < 10)
7901 {
7902 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7903 entry, i, filedata->file_header.e_shnum - 1);
57028622 7904 if (num_group_errors == 10)
67ce483b 7905 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7906 }
391cb864
L
7907 continue;
7908 }
391cb864 7909
978c4450 7910 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7911 {
d1f5c6e3
L
7912 if (entry)
7913 {
57028622
NC
7914 static unsigned num_errs = 0;
7915
7916 if (num_errs ++ < 10)
7917 {
7918 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7919 entry, i,
978c4450 7920 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7921 if (num_errs == 10)
7922 warn (_("Further error messages about already contained group sections suppressed\n"));
7923 }
d1f5c6e3
L
7924 continue;
7925 }
7926 else
7927 {
7928 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7929 section group. We just warn it the first time
d1f5c6e3 7930 and ignore it afterwards. */
015dc7e1 7931 static bool warned = false;
d1f5c6e3
L
7932 if (!warned)
7933 {
7934 error (_("section 0 in group section [%5u]\n"),
978c4450 7935 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7936 warned = true;
d1f5c6e3
L
7937 }
7938 }
e4b17d5c
L
7939 }
7940
978c4450 7941 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7942
7943 if (do_section_groups)
7944 {
dda8d76d
NC
7945 sec = filedata->section_headers + entry;
7946 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7947 }
7948
3f5e193b 7949 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7950 g->section_index = entry;
7951 g->next = group->root;
7952 group->root = g;
f5842774
L
7953 }
7954
9db70fc3 7955 free (start);
e4b17d5c
L
7956
7957 group++;
f5842774
L
7958 }
7959 }
7960
9db70fc3
AM
7961 free (symtab);
7962 free (strtab);
015dc7e1 7963 return true;
f5842774
L
7964}
7965
28f997cf
TG
7966/* Data used to display dynamic fixups. */
7967
7968struct ia64_vms_dynfixup
7969{
7970 bfd_vma needed_ident; /* Library ident number. */
7971 bfd_vma needed; /* Index in the dstrtab of the library name. */
7972 bfd_vma fixup_needed; /* Index of the library. */
7973 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7974 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7975};
7976
7977/* Data used to display dynamic relocations. */
7978
7979struct ia64_vms_dynimgrela
7980{
7981 bfd_vma img_rela_cnt; /* Number of relocations. */
7982 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7983};
7984
7985/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7986 library). */
7987
015dc7e1 7988static bool
dda8d76d
NC
7989dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7990 struct ia64_vms_dynfixup * fixup,
7991 const char * strtab,
7992 unsigned int strtab_sz)
28f997cf 7993{
32ec8896 7994 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7995 long i;
32ec8896 7996 const char * lib_name;
28f997cf 7997
978c4450
AM
7998 imfs = get_data (NULL, filedata,
7999 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 8000 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
8001 _("dynamic section image fixups"));
8002 if (!imfs)
015dc7e1 8003 return false;
28f997cf
TG
8004
8005 if (fixup->needed < strtab_sz)
8006 lib_name = strtab + fixup->needed;
8007 else
8008 {
32ec8896 8009 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 8010 (unsigned long) fixup->needed);
28f997cf
TG
8011 lib_name = "???";
8012 }
736990c4 8013
28f997cf
TG
8014 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
8015 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
8016 printf
8017 (_("Seg Offset Type SymVec DataType\n"));
8018
8019 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
8020 {
8021 unsigned int type;
8022 const char *rtype;
8023
8024 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
8025 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
8026 type = BYTE_GET (imfs [i].type);
8027 rtype = elf_ia64_reloc_type (type);
8028 if (rtype == NULL)
8029 printf (" 0x%08x ", type);
8030 else
8031 printf (" %-32s ", rtype);
8032 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
8033 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
8034 }
8035
8036 free (imfs);
015dc7e1 8037 return true;
28f997cf
TG
8038}
8039
8040/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
8041
015dc7e1 8042static bool
dda8d76d 8043dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
8044{
8045 Elf64_External_VMS_IMAGE_RELA *imrs;
8046 long i;
8047
978c4450
AM
8048 imrs = get_data (NULL, filedata,
8049 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 8050 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 8051 _("dynamic section image relocations"));
28f997cf 8052 if (!imrs)
015dc7e1 8053 return false;
28f997cf
TG
8054
8055 printf (_("\nImage relocs\n"));
8056 printf
8057 (_("Seg Offset Type Addend Seg Sym Off\n"));
8058
8059 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
8060 {
8061 unsigned int type;
8062 const char *rtype;
8063
8064 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
8065 printf ("%08" BFD_VMA_FMT "x ",
8066 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
8067 type = BYTE_GET (imrs [i].type);
8068 rtype = elf_ia64_reloc_type (type);
8069 if (rtype == NULL)
8070 printf ("0x%08x ", type);
8071 else
8072 printf ("%-31s ", rtype);
8073 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
8074 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
8075 printf ("%08" BFD_VMA_FMT "x\n",
8076 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
8077 }
8078
8079 free (imrs);
015dc7e1 8080 return true;
28f997cf
TG
8081}
8082
8083/* Display IA-64 OpenVMS dynamic relocations and fixups. */
8084
015dc7e1 8085static bool
dda8d76d 8086process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
8087{
8088 struct ia64_vms_dynfixup fixup;
8089 struct ia64_vms_dynimgrela imgrela;
8090 Elf_Internal_Dyn *entry;
28f997cf
TG
8091 bfd_vma strtab_off = 0;
8092 bfd_vma strtab_sz = 0;
8093 char *strtab = NULL;
015dc7e1 8094 bool res = true;
28f997cf
TG
8095
8096 memset (&fixup, 0, sizeof (fixup));
8097 memset (&imgrela, 0, sizeof (imgrela));
8098
8099 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
8100 for (entry = filedata->dynamic_section;
8101 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
8102 entry++)
8103 {
8104 switch (entry->d_tag)
8105 {
8106 case DT_IA_64_VMS_STRTAB_OFFSET:
8107 strtab_off = entry->d_un.d_val;
8108 break;
8109 case DT_STRSZ:
8110 strtab_sz = entry->d_un.d_val;
8111 if (strtab == NULL)
978c4450
AM
8112 strtab = get_data (NULL, filedata,
8113 filedata->dynamic_addr + strtab_off,
28f997cf 8114 1, strtab_sz, _("dynamic string section"));
736990c4
NC
8115 if (strtab == NULL)
8116 strtab_sz = 0;
28f997cf
TG
8117 break;
8118
8119 case DT_IA_64_VMS_NEEDED_IDENT:
8120 fixup.needed_ident = entry->d_un.d_val;
8121 break;
8122 case DT_NEEDED:
8123 fixup.needed = entry->d_un.d_val;
8124 break;
8125 case DT_IA_64_VMS_FIXUP_NEEDED:
8126 fixup.fixup_needed = entry->d_un.d_val;
8127 break;
8128 case DT_IA_64_VMS_FIXUP_RELA_CNT:
8129 fixup.fixup_rela_cnt = entry->d_un.d_val;
8130 break;
8131 case DT_IA_64_VMS_FIXUP_RELA_OFF:
8132 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 8133 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 8134 res = false;
28f997cf 8135 break;
28f997cf
TG
8136 case DT_IA_64_VMS_IMG_RELA_CNT:
8137 imgrela.img_rela_cnt = entry->d_un.d_val;
8138 break;
8139 case DT_IA_64_VMS_IMG_RELA_OFF:
8140 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 8141 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 8142 res = false;
28f997cf
TG
8143 break;
8144
8145 default:
8146 break;
8147 }
8148 }
8149
9db70fc3 8150 free (strtab);
28f997cf
TG
8151
8152 return res;
8153}
8154
85b1c36d 8155static struct
566b0d53 8156{
2cf0635d 8157 const char * name;
566b0d53
L
8158 int reloc;
8159 int size;
a7fd1186 8160 relocation_type rel_type;
32ec8896
NC
8161}
8162 dynamic_relocations [] =
566b0d53 8163{
a7fd1186
FS
8164 { "REL", DT_REL, DT_RELSZ, reltype_rel },
8165 { "RELA", DT_RELA, DT_RELASZ, reltype_rela },
8166 { "RELR", DT_RELR, DT_RELRSZ, reltype_relr },
8167 { "PLT", DT_JMPREL, DT_PLTRELSZ, reltype_unknown }
566b0d53
L
8168};
8169
252b5132 8170/* Process the reloc section. */
18bd398b 8171
015dc7e1 8172static bool
dda8d76d 8173process_relocs (Filedata * filedata)
252b5132 8174{
b34976b6
AM
8175 unsigned long rel_size;
8176 unsigned long rel_offset;
252b5132 8177
252b5132 8178 if (!do_reloc)
015dc7e1 8179 return true;
252b5132
RH
8180
8181 if (do_using_dynamic)
8182 {
a7fd1186 8183 relocation_type rel_type;
2cf0635d 8184 const char * name;
015dc7e1 8185 bool has_dynamic_reloc;
566b0d53 8186 unsigned int i;
0de14b54 8187
015dc7e1 8188 has_dynamic_reloc = false;
252b5132 8189
566b0d53 8190 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 8191 {
a7fd1186 8192 rel_type = dynamic_relocations [i].rel_type;
566b0d53 8193 name = dynamic_relocations [i].name;
978c4450
AM
8194 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
8195 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 8196
32ec8896 8197 if (rel_size)
015dc7e1 8198 has_dynamic_reloc = true;
566b0d53 8199
a7fd1186 8200 if (rel_type == reltype_unknown)
aa903cfb 8201 {
566b0d53 8202 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 8203 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
8204 {
8205 case DT_REL:
a7fd1186 8206 rel_type = reltype_rel;
566b0d53
L
8207 break;
8208 case DT_RELA:
a7fd1186 8209 rel_type = reltype_rela;
566b0d53
L
8210 break;
8211 }
aa903cfb 8212 }
252b5132 8213
566b0d53
L
8214 if (rel_size)
8215 {
ca0e11aa
NC
8216 if (filedata->is_separate)
8217 printf
8218 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
8219 filedata->file_name, name, rel_offset, rel_size);
8220 else
8221 printf
8222 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
8223 name, rel_offset, rel_size);
252b5132 8224
dda8d76d
NC
8225 dump_relocations (filedata,
8226 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 8227 rel_size,
978c4450
AM
8228 filedata->dynamic_symbols,
8229 filedata->num_dynamic_syms,
8230 filedata->dynamic_strings,
8231 filedata->dynamic_strings_length,
a7fd1186 8232 rel_type, true /* is_dynamic */);
566b0d53 8233 }
252b5132 8234 }
566b0d53 8235
dda8d76d
NC
8236 if (is_ia64_vms (filedata))
8237 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 8238 has_dynamic_reloc = true;
28f997cf 8239
566b0d53 8240 if (! has_dynamic_reloc)
ca0e11aa
NC
8241 {
8242 if (filedata->is_separate)
8243 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
8244 filedata->file_name);
8245 else
8246 printf (_("\nThere are no dynamic relocations in this file.\n"));
8247 }
252b5132
RH
8248 }
8249 else
8250 {
2cf0635d 8251 Elf_Internal_Shdr * section;
b34976b6 8252 unsigned long i;
015dc7e1 8253 bool found = false;
252b5132 8254
dda8d76d
NC
8255 for (i = 0, section = filedata->section_headers;
8256 i < filedata->file_header.e_shnum;
b34976b6 8257 i++, section++)
252b5132
RH
8258 {
8259 if ( section->sh_type != SHT_RELA
a7fd1186
FS
8260 && section->sh_type != SHT_REL
8261 && section->sh_type != SHT_RELR)
252b5132
RH
8262 continue;
8263
8264 rel_offset = section->sh_offset;
8265 rel_size = section->sh_size;
8266
8267 if (rel_size)
8268 {
a7fd1186 8269 relocation_type rel_type;
d3a49aa8 8270 unsigned long num_rela;
103f02d3 8271
ca0e11aa
NC
8272 if (filedata->is_separate)
8273 printf (_("\nIn linked file '%s' relocation section "),
8274 filedata->file_name);
8275 else
8276 printf (_("\nRelocation section "));
252b5132 8277
dda8d76d 8278 if (filedata->string_table == NULL)
19936277 8279 printf ("%d", section->sh_name);
252b5132 8280 else
dda8d76d 8281 printf ("'%s'", printable_section_name (filedata, section));
252b5132 8282
d3a49aa8
AM
8283 num_rela = rel_size / section->sh_entsize;
8284 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
8285 " at offset 0x%lx contains %lu entries:\n",
8286 num_rela),
8287 rel_offset, num_rela);
252b5132 8288
a7fd1186
FS
8289 rel_type = section->sh_type == SHT_RELA ? reltype_rela :
8290 section->sh_type == SHT_REL ? reltype_rel : reltype_relr;
d79b3d50 8291
4fbb74a6 8292 if (section->sh_link != 0
dda8d76d 8293 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 8294 {
2cf0635d
NC
8295 Elf_Internal_Shdr * symsec;
8296 Elf_Internal_Sym * symtab;
d79b3d50 8297 unsigned long nsyms;
c256ffe7 8298 unsigned long strtablen = 0;
2cf0635d 8299 char * strtab = NULL;
57346661 8300
dda8d76d 8301 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
8302 if (symsec->sh_type != SHT_SYMTAB
8303 && symsec->sh_type != SHT_DYNSYM)
8304 continue;
8305
28d13567
AM
8306 if (!get_symtab (filedata, symsec,
8307 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 8308 continue;
252b5132 8309
dda8d76d 8310 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2 8311 symtab, nsyms, strtab, strtablen,
a7fd1186 8312 rel_type,
bb4d2ac2 8313 symsec->sh_type == SHT_DYNSYM);
9db70fc3 8314 free (strtab);
d79b3d50
NC
8315 free (symtab);
8316 }
8317 else
dda8d76d 8318 dump_relocations (filedata, rel_offset, rel_size,
a7fd1186 8319 NULL, 0, NULL, 0, rel_type, false /* is_dynamic */);
252b5132 8320
015dc7e1 8321 found = true;
252b5132
RH
8322 }
8323 }
8324
8325 if (! found)
45ac8f4f
NC
8326 {
8327 /* Users sometimes forget the -D option, so try to be helpful. */
8328 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
8329 {
978c4450 8330 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 8331 {
ca0e11aa
NC
8332 if (filedata->is_separate)
8333 printf (_("\nThere are no static relocations in linked file '%s'."),
8334 filedata->file_name);
8335 else
8336 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
8337 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
8338
8339 break;
8340 }
8341 }
8342 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
8343 {
8344 if (filedata->is_separate)
8345 printf (_("\nThere are no relocations in linked file '%s'.\n"),
8346 filedata->file_name);
8347 else
8348 printf (_("\nThere are no relocations in this file.\n"));
8349 }
45ac8f4f 8350 }
252b5132
RH
8351 }
8352
015dc7e1 8353 return true;
252b5132
RH
8354}
8355
4d6ed7c8
NC
8356/* An absolute address consists of a section and an offset. If the
8357 section is NULL, the offset itself is the address, otherwise, the
8358 address equals to LOAD_ADDRESS(section) + offset. */
8359
8360struct absaddr
948f632f
DA
8361{
8362 unsigned short section;
8363 bfd_vma offset;
8364};
4d6ed7c8 8365
948f632f
DA
8366/* Find the nearest symbol at or below ADDR. Returns the symbol
8367 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8368
4d6ed7c8 8369static void
dda8d76d
NC
8370find_symbol_for_address (Filedata * filedata,
8371 Elf_Internal_Sym * symtab,
8372 unsigned long nsyms,
8373 const char * strtab,
8374 unsigned long strtab_size,
8375 struct absaddr addr,
8376 const char ** symname,
8377 bfd_vma * offset)
4d6ed7c8 8378{
d3ba0551 8379 bfd_vma dist = 0x100000;
2cf0635d 8380 Elf_Internal_Sym * sym;
948f632f
DA
8381 Elf_Internal_Sym * beg;
8382 Elf_Internal_Sym * end;
2cf0635d 8383 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8384
0b6ae522 8385 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8386 beg = symtab;
8387 end = symtab + nsyms;
0b6ae522 8388
948f632f 8389 while (beg < end)
4d6ed7c8 8390 {
948f632f
DA
8391 bfd_vma value;
8392
8393 sym = beg + (end - beg) / 2;
0b6ae522 8394
948f632f 8395 value = sym->st_value;
0b6ae522
DJ
8396 REMOVE_ARCH_BITS (value);
8397
948f632f 8398 if (sym->st_name != 0
4d6ed7c8 8399 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8400 && addr.offset >= value
8401 && addr.offset - value < dist)
4d6ed7c8
NC
8402 {
8403 best = sym;
0b6ae522 8404 dist = addr.offset - value;
4d6ed7c8
NC
8405 if (!dist)
8406 break;
8407 }
948f632f
DA
8408
8409 if (addr.offset < value)
8410 end = sym;
8411 else
8412 beg = sym + 1;
4d6ed7c8 8413 }
1b31d05e 8414
4d6ed7c8
NC
8415 if (best)
8416 {
57346661 8417 *symname = (best->st_name >= strtab_size
2b692964 8418 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8419 *offset = dist;
8420 return;
8421 }
1b31d05e 8422
4d6ed7c8
NC
8423 *symname = NULL;
8424 *offset = addr.offset;
8425}
8426
32ec8896 8427static /* signed */ int
948f632f
DA
8428symcmp (const void *p, const void *q)
8429{
8430 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8431 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8432
8433 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8434}
8435
8436/* Process the unwind section. */
8437
8438#include "unwind-ia64.h"
8439
8440struct ia64_unw_table_entry
8441{
8442 struct absaddr start;
8443 struct absaddr end;
8444 struct absaddr info;
8445};
8446
8447struct ia64_unw_aux_info
8448{
32ec8896
NC
8449 struct ia64_unw_table_entry * table; /* Unwind table. */
8450 unsigned long table_len; /* Length of unwind table. */
8451 unsigned char * info; /* Unwind info. */
8452 unsigned long info_size; /* Size of unwind info. */
8453 bfd_vma info_addr; /* Starting address of unwind info. */
8454 bfd_vma seg_base; /* Starting address of segment. */
8455 Elf_Internal_Sym * symtab; /* The symbol table. */
8456 unsigned long nsyms; /* Number of symbols. */
8457 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8458 unsigned long nfuns; /* Number of entries in funtab. */
8459 char * strtab; /* The string table. */
8460 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8461};
8462
015dc7e1 8463static bool
dda8d76d 8464dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8465{
2cf0635d 8466 struct ia64_unw_table_entry * tp;
948f632f 8467 unsigned long j, nfuns;
4d6ed7c8 8468 int in_body;
015dc7e1 8469 bool res = true;
7036c0e1 8470
948f632f
DA
8471 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8472 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8473 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8474 aux->funtab[nfuns++] = aux->symtab[j];
8475 aux->nfuns = nfuns;
8476 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8477
4d6ed7c8
NC
8478 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8479 {
8480 bfd_vma stamp;
8481 bfd_vma offset;
2cf0635d
NC
8482 const unsigned char * dp;
8483 const unsigned char * head;
53774b7e 8484 const unsigned char * end;
2cf0635d 8485 const char * procname;
4d6ed7c8 8486
dda8d76d 8487 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8488 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8489
8490 fputs ("\n<", stdout);
8491
8492 if (procname)
8493 {
8494 fputs (procname, stdout);
8495
8496 if (offset)
8497 printf ("+%lx", (unsigned long) offset);
8498 }
8499
8500 fputs (">: [", stdout);
8501 print_vma (tp->start.offset, PREFIX_HEX);
8502 fputc ('-', stdout);
8503 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8504 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8505 (unsigned long) (tp->info.offset - aux->seg_base));
8506
53774b7e
NC
8507 /* PR 17531: file: 86232b32. */
8508 if (aux->info == NULL)
8509 continue;
8510
97c0a079
AM
8511 offset = tp->info.offset;
8512 if (tp->info.section)
8513 {
8514 if (tp->info.section >= filedata->file_header.e_shnum)
8515 {
8516 warn (_("Invalid section %u in table entry %ld\n"),
8517 tp->info.section, (long) (tp - aux->table));
015dc7e1 8518 res = false;
97c0a079
AM
8519 continue;
8520 }
8521 offset += filedata->section_headers[tp->info.section].sh_addr;
8522 }
8523 offset -= aux->info_addr;
53774b7e 8524 /* PR 17531: file: 0997b4d1. */
90679903
AM
8525 if (offset >= aux->info_size
8526 || aux->info_size - offset < 8)
53774b7e
NC
8527 {
8528 warn (_("Invalid offset %lx in table entry %ld\n"),
8529 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8530 res = false;
53774b7e
NC
8531 continue;
8532 }
8533
97c0a079 8534 head = aux->info + offset;
a4a00738 8535 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8536
86f55779 8537 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8538 (unsigned) UNW_VER (stamp),
8539 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8540 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8541 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8542 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8543
8544 if (UNW_VER (stamp) != 1)
8545 {
2b692964 8546 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8547 continue;
8548 }
8549
8550 in_body = 0;
53774b7e
NC
8551 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8552 /* PR 17531: file: 16ceda89. */
8553 if (end > aux->info + aux->info_size)
8554 end = aux->info + aux->info_size;
8555 for (dp = head + 8; dp < end;)
b4477bc8 8556 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8557 }
948f632f
DA
8558
8559 free (aux->funtab);
32ec8896
NC
8560
8561 return res;
4d6ed7c8
NC
8562}
8563
015dc7e1 8564static bool
dda8d76d
NC
8565slurp_ia64_unwind_table (Filedata * filedata,
8566 struct ia64_unw_aux_info * aux,
8567 Elf_Internal_Shdr * sec)
4d6ed7c8 8568{
89fac5e3 8569 unsigned long size, nrelas, i;
2cf0635d
NC
8570 Elf_Internal_Phdr * seg;
8571 struct ia64_unw_table_entry * tep;
8572 Elf_Internal_Shdr * relsec;
8573 Elf_Internal_Rela * rela;
8574 Elf_Internal_Rela * rp;
8575 unsigned char * table;
8576 unsigned char * tp;
8577 Elf_Internal_Sym * sym;
8578 const char * relname;
4d6ed7c8 8579
53774b7e
NC
8580 aux->table_len = 0;
8581
4d6ed7c8
NC
8582 /* First, find the starting address of the segment that includes
8583 this section: */
8584
dda8d76d 8585 if (filedata->file_header.e_phnum)
4d6ed7c8 8586 {
dda8d76d 8587 if (! get_program_headers (filedata))
015dc7e1 8588 return false;
4d6ed7c8 8589
dda8d76d
NC
8590 for (seg = filedata->program_headers;
8591 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8592 ++seg)
4d6ed7c8
NC
8593 {
8594 if (seg->p_type != PT_LOAD)
8595 continue;
8596
8597 if (sec->sh_addr >= seg->p_vaddr
8598 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8599 {
8600 aux->seg_base = seg->p_vaddr;
8601 break;
8602 }
8603 }
4d6ed7c8
NC
8604 }
8605
8606 /* Second, build the unwind table from the contents of the unwind section: */
8607 size = sec->sh_size;
dda8d76d 8608 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8609 _("unwind table"));
a6e9f9df 8610 if (!table)
015dc7e1 8611 return false;
4d6ed7c8 8612
53774b7e 8613 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8614 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8615 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8616 tep = aux->table;
53774b7e
NC
8617
8618 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8619 {
8620 tep->start.section = SHN_UNDEF;
8621 tep->end.section = SHN_UNDEF;
8622 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8623 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8624 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8625 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8626 tep->start.offset += aux->seg_base;
8627 tep->end.offset += aux->seg_base;
8628 tep->info.offset += aux->seg_base;
8629 }
8630 free (table);
8631
41e92641 8632 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8633 for (relsec = filedata->section_headers;
8634 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8635 ++relsec)
8636 {
8637 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8638 || relsec->sh_info >= filedata->file_header.e_shnum
8639 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8640 continue;
8641
dda8d76d 8642 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8643 & rela, & nrelas))
53774b7e
NC
8644 {
8645 free (aux->table);
8646 aux->table = NULL;
8647 aux->table_len = 0;
015dc7e1 8648 return false;
53774b7e 8649 }
4d6ed7c8
NC
8650
8651 for (rp = rela; rp < rela + nrelas; ++rp)
8652 {
4770fb94 8653 unsigned int sym_ndx;
726bd37d
AM
8654 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8655 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8656
82b1b41b
NC
8657 /* PR 17531: file: 9fa67536. */
8658 if (relname == NULL)
8659 {
726bd37d 8660 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8661 continue;
8662 }
948f632f 8663
24d127aa 8664 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8665 {
82b1b41b 8666 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8667 continue;
8668 }
8669
89fac5e3 8670 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8671
53774b7e
NC
8672 /* PR 17531: file: 5bc8d9bf. */
8673 if (i >= aux->table_len)
8674 {
8675 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8676 continue;
8677 }
8678
4770fb94
AM
8679 sym_ndx = get_reloc_symindex (rp->r_info);
8680 if (sym_ndx >= aux->nsyms)
8681 {
8682 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8683 sym_ndx);
8684 continue;
8685 }
8686 sym = aux->symtab + sym_ndx;
8687
53774b7e 8688 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8689 {
8690 case 0:
8691 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8692 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8693 break;
8694 case 1:
8695 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8696 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8697 break;
8698 case 2:
8699 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8700 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8701 break;
8702 default:
8703 break;
8704 }
8705 }
8706
8707 free (rela);
8708 }
8709
015dc7e1 8710 return true;
4d6ed7c8
NC
8711}
8712
015dc7e1 8713static bool
dda8d76d 8714ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8715{
2cf0635d
NC
8716 Elf_Internal_Shdr * sec;
8717 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8718 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8719 struct ia64_unw_aux_info aux;
015dc7e1 8720 bool res = true;
f1467e33 8721
4d6ed7c8
NC
8722 memset (& aux, 0, sizeof (aux));
8723
dda8d76d 8724 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8725 {
28d13567 8726 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8727 {
28d13567 8728 if (aux.symtab)
4082ef84 8729 {
28d13567
AM
8730 error (_("Multiple symbol tables encountered\n"));
8731 free (aux.symtab);
8732 aux.symtab = NULL;
4082ef84 8733 free (aux.strtab);
28d13567 8734 aux.strtab = NULL;
4082ef84 8735 }
28d13567
AM
8736 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8737 &aux.strtab, &aux.strtab_size))
015dc7e1 8738 return false;
4d6ed7c8
NC
8739 }
8740 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8741 unwcount++;
8742 }
8743
8744 if (!unwcount)
8745 printf (_("\nThere are no unwind sections in this file.\n"));
8746
8747 while (unwcount-- > 0)
8748 {
84714f86 8749 const char *suffix;
579f31ac
JJ
8750 size_t len, len2;
8751
dda8d76d
NC
8752 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8753 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8754 if (sec->sh_type == SHT_IA_64_UNWIND)
8755 {
8756 unwsec = sec;
8757 break;
8758 }
4082ef84
NC
8759 /* We have already counted the number of SHT_IA64_UNWIND
8760 sections so the loop above should never fail. */
8761 assert (unwsec != NULL);
579f31ac
JJ
8762
8763 unwstart = i + 1;
8764 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8765
e4b17d5c
L
8766 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8767 {
8768 /* We need to find which section group it is in. */
4082ef84 8769 struct group_list * g;
e4b17d5c 8770
978c4450
AM
8771 if (filedata->section_headers_groups == NULL
8772 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8773 i = filedata->file_header.e_shnum;
4082ef84 8774 else
e4b17d5c 8775 {
978c4450 8776 g = filedata->section_headers_groups[i]->root;
18bd398b 8777
4082ef84
NC
8778 for (; g != NULL; g = g->next)
8779 {
dda8d76d 8780 sec = filedata->section_headers + g->section_index;
e4b17d5c 8781
84714f86
AM
8782 if (section_name_valid (filedata, sec)
8783 && streq (section_name (filedata, sec),
8784 ELF_STRING_ia64_unwind_info))
4082ef84
NC
8785 break;
8786 }
8787
8788 if (g == NULL)
dda8d76d 8789 i = filedata->file_header.e_shnum;
4082ef84 8790 }
e4b17d5c 8791 }
84714f86
AM
8792 else if (section_name_valid (filedata, unwsec)
8793 && startswith (section_name (filedata, unwsec),
e9b095a5 8794 ELF_STRING_ia64_unwind_once))
579f31ac 8795 {
18bd398b 8796 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac 8797 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
84714f86 8798 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8799 for (i = 0, sec = filedata->section_headers;
8800 i < filedata->file_header.e_shnum;
579f31ac 8801 ++i, ++sec)
84714f86
AM
8802 if (section_name_valid (filedata, sec)
8803 && startswith (section_name (filedata, sec),
e9b095a5 8804 ELF_STRING_ia64_unwind_info_once)
84714f86 8805 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8806 break;
8807 }
8808 else
8809 {
8810 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8811 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8812 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8813 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8814 suffix = "";
84714f86
AM
8815 if (section_name_valid (filedata, unwsec)
8816 && startswith (section_name (filedata, unwsec),
8817 ELF_STRING_ia64_unwind))
8818 suffix = section_name (filedata, unwsec) + len;
b9e920ec
AM
8819 for (i = 0, sec = filedata->section_headers;
8820 i < filedata->file_header.e_shnum;
579f31ac 8821 ++i, ++sec)
84714f86
AM
8822 if (section_name_valid (filedata, sec)
8823 && startswith (section_name (filedata, sec),
8824 ELF_STRING_ia64_unwind_info)
8825 && streq (section_name (filedata, sec) + len2, suffix))
579f31ac
JJ
8826 break;
8827 }
8828
dda8d76d 8829 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8830 {
8831 printf (_("\nCould not find unwind info section for "));
8832
dda8d76d 8833 if (filedata->string_table == NULL)
579f31ac
JJ
8834 printf ("%d", unwsec->sh_name);
8835 else
dda8d76d 8836 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8837 }
8838 else
4d6ed7c8 8839 {
4d6ed7c8 8840 aux.info_addr = sec->sh_addr;
dda8d76d 8841 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8842 sec->sh_size,
8843 _("unwind info"));
59245841 8844 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8845
579f31ac 8846 printf (_("\nUnwind section "));
4d6ed7c8 8847
dda8d76d 8848 if (filedata->string_table == NULL)
579f31ac
JJ
8849 printf ("%d", unwsec->sh_name);
8850 else
dda8d76d 8851 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8852
579f31ac 8853 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8854 (unsigned long) unwsec->sh_offset,
89fac5e3 8855 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8856
dda8d76d 8857 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8858 && aux.table_len > 0)
dda8d76d 8859 dump_ia64_unwind (filedata, & aux);
579f31ac 8860
9db70fc3
AM
8861 free ((char *) aux.table);
8862 free ((char *) aux.info);
579f31ac
JJ
8863 aux.table = NULL;
8864 aux.info = NULL;
8865 }
4d6ed7c8 8866 }
4d6ed7c8 8867
9db70fc3
AM
8868 free (aux.symtab);
8869 free ((char *) aux.strtab);
32ec8896
NC
8870
8871 return res;
4d6ed7c8
NC
8872}
8873
3f5e193b 8874struct hppa_unw_table_entry
32ec8896
NC
8875{
8876 struct absaddr start;
8877 struct absaddr end;
8878 unsigned int Cannot_unwind:1; /* 0 */
8879 unsigned int Millicode:1; /* 1 */
8880 unsigned int Millicode_save_sr0:1; /* 2 */
8881 unsigned int Region_description:2; /* 3..4 */
8882 unsigned int reserved1:1; /* 5 */
8883 unsigned int Entry_SR:1; /* 6 */
8884 unsigned int Entry_FR:4; /* Number saved 7..10 */
8885 unsigned int Entry_GR:5; /* Number saved 11..15 */
8886 unsigned int Args_stored:1; /* 16 */
8887 unsigned int Variable_Frame:1; /* 17 */
8888 unsigned int Separate_Package_Body:1; /* 18 */
8889 unsigned int Frame_Extension_Millicode:1; /* 19 */
8890 unsigned int Stack_Overflow_Check:1; /* 20 */
8891 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8892 unsigned int Ada_Region:1; /* 22 */
8893 unsigned int cxx_info:1; /* 23 */
8894 unsigned int cxx_try_catch:1; /* 24 */
8895 unsigned int sched_entry_seq:1; /* 25 */
8896 unsigned int reserved2:1; /* 26 */
8897 unsigned int Save_SP:1; /* 27 */
8898 unsigned int Save_RP:1; /* 28 */
8899 unsigned int Save_MRP_in_frame:1; /* 29 */
8900 unsigned int extn_ptr_defined:1; /* 30 */
8901 unsigned int Cleanup_defined:1; /* 31 */
8902
8903 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8904 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8905 unsigned int Large_frame:1; /* 2 */
8906 unsigned int Pseudo_SP_Set:1; /* 3 */
8907 unsigned int reserved4:1; /* 4 */
8908 unsigned int Total_frame_size:27; /* 5..31 */
8909};
3f5e193b 8910
57346661 8911struct hppa_unw_aux_info
948f632f 8912{
32ec8896
NC
8913 struct hppa_unw_table_entry * table; /* Unwind table. */
8914 unsigned long table_len; /* Length of unwind table. */
8915 bfd_vma seg_base; /* Starting address of segment. */
8916 Elf_Internal_Sym * symtab; /* The symbol table. */
8917 unsigned long nsyms; /* Number of symbols. */
8918 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8919 unsigned long nfuns; /* Number of entries in funtab. */
8920 char * strtab; /* The string table. */
8921 unsigned long strtab_size; /* Size of string table. */
948f632f 8922};
57346661 8923
015dc7e1 8924static bool
dda8d76d 8925dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8926{
2cf0635d 8927 struct hppa_unw_table_entry * tp;
948f632f 8928 unsigned long j, nfuns;
015dc7e1 8929 bool res = true;
948f632f
DA
8930
8931 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8932 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8933 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8934 aux->funtab[nfuns++] = aux->symtab[j];
8935 aux->nfuns = nfuns;
8936 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8937
57346661
AM
8938 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8939 {
8940 bfd_vma offset;
2cf0635d 8941 const char * procname;
57346661 8942
dda8d76d 8943 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8944 aux->strtab_size, tp->start, &procname,
8945 &offset);
8946
8947 fputs ("\n<", stdout);
8948
8949 if (procname)
8950 {
8951 fputs (procname, stdout);
8952
8953 if (offset)
8954 printf ("+%lx", (unsigned long) offset);
8955 }
8956
8957 fputs (">: [", stdout);
8958 print_vma (tp->start.offset, PREFIX_HEX);
8959 fputc ('-', stdout);
8960 print_vma (tp->end.offset, PREFIX_HEX);
8961 printf ("]\n\t");
8962
18bd398b
NC
8963#define PF(_m) if (tp->_m) printf (#_m " ");
8964#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8965 PF(Cannot_unwind);
8966 PF(Millicode);
8967 PF(Millicode_save_sr0);
18bd398b 8968 /* PV(Region_description); */
57346661
AM
8969 PF(Entry_SR);
8970 PV(Entry_FR);
8971 PV(Entry_GR);
8972 PF(Args_stored);
8973 PF(Variable_Frame);
8974 PF(Separate_Package_Body);
8975 PF(Frame_Extension_Millicode);
8976 PF(Stack_Overflow_Check);
8977 PF(Two_Instruction_SP_Increment);
8978 PF(Ada_Region);
8979 PF(cxx_info);
8980 PF(cxx_try_catch);
8981 PF(sched_entry_seq);
8982 PF(Save_SP);
8983 PF(Save_RP);
8984 PF(Save_MRP_in_frame);
8985 PF(extn_ptr_defined);
8986 PF(Cleanup_defined);
8987 PF(MPE_XL_interrupt_marker);
8988 PF(HP_UX_interrupt_marker);
8989 PF(Large_frame);
8990 PF(Pseudo_SP_Set);
8991 PV(Total_frame_size);
8992#undef PF
8993#undef PV
8994 }
8995
18bd398b 8996 printf ("\n");
948f632f
DA
8997
8998 free (aux->funtab);
32ec8896
NC
8999
9000 return res;
57346661
AM
9001}
9002
015dc7e1 9003static bool
dda8d76d
NC
9004slurp_hppa_unwind_table (Filedata * filedata,
9005 struct hppa_unw_aux_info * aux,
9006 Elf_Internal_Shdr * sec)
57346661 9007{
1c0751b2 9008 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
9009 Elf_Internal_Phdr * seg;
9010 struct hppa_unw_table_entry * tep;
9011 Elf_Internal_Shdr * relsec;
9012 Elf_Internal_Rela * rela;
9013 Elf_Internal_Rela * rp;
9014 unsigned char * table;
9015 unsigned char * tp;
9016 Elf_Internal_Sym * sym;
9017 const char * relname;
57346661 9018
57346661
AM
9019 /* First, find the starting address of the segment that includes
9020 this section. */
dda8d76d 9021 if (filedata->file_header.e_phnum)
57346661 9022 {
dda8d76d 9023 if (! get_program_headers (filedata))
015dc7e1 9024 return false;
57346661 9025
dda8d76d
NC
9026 for (seg = filedata->program_headers;
9027 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
9028 ++seg)
9029 {
9030 if (seg->p_type != PT_LOAD)
9031 continue;
9032
9033 if (sec->sh_addr >= seg->p_vaddr
9034 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
9035 {
9036 aux->seg_base = seg->p_vaddr;
9037 break;
9038 }
9039 }
9040 }
9041
9042 /* Second, build the unwind table from the contents of the unwind
9043 section. */
9044 size = sec->sh_size;
dda8d76d 9045 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 9046 _("unwind table"));
57346661 9047 if (!table)
015dc7e1 9048 return false;
57346661 9049
1c0751b2
DA
9050 unw_ent_size = 16;
9051 nentries = size / unw_ent_size;
9052 size = unw_ent_size * nentries;
57346661 9053
e3fdc001 9054 aux->table_len = nentries;
3f5e193b
NC
9055 tep = aux->table = (struct hppa_unw_table_entry *)
9056 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 9057
1c0751b2 9058 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
9059 {
9060 unsigned int tmp1, tmp2;
9061
9062 tep->start.section = SHN_UNDEF;
9063 tep->end.section = SHN_UNDEF;
9064
1c0751b2
DA
9065 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
9066 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
9067 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
9068 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
9069
9070 tep->start.offset += aux->seg_base;
9071 tep->end.offset += aux->seg_base;
57346661
AM
9072
9073 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
9074 tep->Millicode = (tmp1 >> 30) & 0x1;
9075 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
9076 tep->Region_description = (tmp1 >> 27) & 0x3;
9077 tep->reserved1 = (tmp1 >> 26) & 0x1;
9078 tep->Entry_SR = (tmp1 >> 25) & 0x1;
9079 tep->Entry_FR = (tmp1 >> 21) & 0xf;
9080 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
9081 tep->Args_stored = (tmp1 >> 15) & 0x1;
9082 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
9083 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
9084 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
9085 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
9086 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
9087 tep->Ada_Region = (tmp1 >> 9) & 0x1;
9088 tep->cxx_info = (tmp1 >> 8) & 0x1;
9089 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
9090 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
9091 tep->reserved2 = (tmp1 >> 5) & 0x1;
9092 tep->Save_SP = (tmp1 >> 4) & 0x1;
9093 tep->Save_RP = (tmp1 >> 3) & 0x1;
9094 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
9095 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
9096 tep->Cleanup_defined = tmp1 & 0x1;
9097
9098 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
9099 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
9100 tep->Large_frame = (tmp2 >> 29) & 0x1;
9101 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
9102 tep->reserved4 = (tmp2 >> 27) & 0x1;
9103 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
9104 }
9105 free (table);
9106
9107 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
9108 for (relsec = filedata->section_headers;
9109 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
9110 ++relsec)
9111 {
9112 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
9113 || relsec->sh_info >= filedata->file_header.e_shnum
9114 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
9115 continue;
9116
dda8d76d 9117 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 9118 & rela, & nrelas))
015dc7e1 9119 return false;
57346661
AM
9120
9121 for (rp = rela; rp < rela + nrelas; ++rp)
9122 {
4770fb94 9123 unsigned int sym_ndx;
726bd37d
AM
9124 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
9125 relname = elf_hppa_reloc_type (r_type);
57346661 9126
726bd37d
AM
9127 if (relname == NULL)
9128 {
9129 warn (_("Skipping unknown relocation type: %u\n"), r_type);
9130 continue;
9131 }
9132
57346661 9133 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 9134 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 9135 {
726bd37d 9136 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
9137 continue;
9138 }
9139
9140 i = rp->r_offset / unw_ent_size;
726bd37d
AM
9141 if (i >= aux->table_len)
9142 {
9143 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
9144 continue;
9145 }
57346661 9146
4770fb94
AM
9147 sym_ndx = get_reloc_symindex (rp->r_info);
9148 if (sym_ndx >= aux->nsyms)
9149 {
9150 warn (_("Skipping reloc with invalid symbol index: %u\n"),
9151 sym_ndx);
9152 continue;
9153 }
9154 sym = aux->symtab + sym_ndx;
9155
43f6cd05 9156 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
9157 {
9158 case 0:
9159 aux->table[i].start.section = sym->st_shndx;
1e456d54 9160 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
9161 break;
9162 case 1:
9163 aux->table[i].end.section = sym->st_shndx;
1e456d54 9164 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
9165 break;
9166 default:
9167 break;
9168 }
9169 }
9170
9171 free (rela);
9172 }
9173
015dc7e1 9174 return true;
57346661
AM
9175}
9176
015dc7e1 9177static bool
dda8d76d 9178hppa_process_unwind (Filedata * filedata)
57346661 9179{
57346661 9180 struct hppa_unw_aux_info aux;
2cf0635d 9181 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 9182 Elf_Internal_Shdr * sec;
18bd398b 9183 unsigned long i;
015dc7e1 9184 bool res = true;
57346661 9185
dda8d76d 9186 if (filedata->string_table == NULL)
015dc7e1 9187 return false;
1b31d05e
NC
9188
9189 memset (& aux, 0, sizeof (aux));
57346661 9190
dda8d76d 9191 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9192 {
28d13567 9193 if (sec->sh_type == SHT_SYMTAB)
57346661 9194 {
28d13567 9195 if (aux.symtab)
4082ef84 9196 {
28d13567
AM
9197 error (_("Multiple symbol tables encountered\n"));
9198 free (aux.symtab);
9199 aux.symtab = NULL;
4082ef84 9200 free (aux.strtab);
28d13567 9201 aux.strtab = NULL;
4082ef84 9202 }
28d13567
AM
9203 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9204 &aux.strtab, &aux.strtab_size))
015dc7e1 9205 return false;
57346661 9206 }
84714f86
AM
9207 else if (section_name_valid (filedata, sec)
9208 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661
AM
9209 unwsec = sec;
9210 }
9211
9212 if (!unwsec)
9213 printf (_("\nThere are no unwind sections in this file.\n"));
9214
dda8d76d 9215 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 9216 {
84714f86
AM
9217 if (section_name_valid (filedata, sec)
9218 && streq (section_name (filedata, sec), ".PARISC.unwind"))
57346661 9219 {
43f6cd05 9220 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 9221
d3a49aa8
AM
9222 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9223 "contains %lu entry:\n",
9224 "\nUnwind section '%s' at offset 0x%lx "
9225 "contains %lu entries:\n",
9226 num_unwind),
dda8d76d 9227 printable_section_name (filedata, sec),
57346661 9228 (unsigned long) sec->sh_offset,
d3a49aa8 9229 num_unwind);
57346661 9230
dda8d76d 9231 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 9232 res = false;
66b09c7e
S
9233
9234 if (res && aux.table_len > 0)
32ec8896 9235 {
dda8d76d 9236 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 9237 res = false;
32ec8896 9238 }
57346661 9239
9db70fc3 9240 free ((char *) aux.table);
57346661
AM
9241 aux.table = NULL;
9242 }
9243 }
9244
9db70fc3
AM
9245 free (aux.symtab);
9246 free ((char *) aux.strtab);
32ec8896
NC
9247
9248 return res;
57346661
AM
9249}
9250
0b6ae522
DJ
9251struct arm_section
9252{
a734115a
NC
9253 unsigned char * data; /* The unwind data. */
9254 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
9255 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
9256 unsigned long nrelas; /* The number of relocations. */
9257 unsigned int rel_type; /* REL or RELA ? */
9258 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
9259};
9260
9261struct arm_unw_aux_info
9262{
dda8d76d 9263 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
9264 Elf_Internal_Sym * symtab; /* The file's symbol table. */
9265 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
9266 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
9267 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
9268 char * strtab; /* The file's string table. */
9269 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
9270};
9271
9272static const char *
dda8d76d
NC
9273arm_print_vma_and_name (Filedata * filedata,
9274 struct arm_unw_aux_info * aux,
9275 bfd_vma fn,
9276 struct absaddr addr)
0b6ae522
DJ
9277{
9278 const char *procname;
9279 bfd_vma sym_offset;
9280
9281 if (addr.section == SHN_UNDEF)
9282 addr.offset = fn;
9283
dda8d76d 9284 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
9285 aux->strtab_size, addr, &procname,
9286 &sym_offset);
9287
9288 print_vma (fn, PREFIX_HEX);
9289
9290 if (procname)
9291 {
9292 fputs (" <", stdout);
9293 fputs (procname, stdout);
9294
9295 if (sym_offset)
9296 printf ("+0x%lx", (unsigned long) sym_offset);
9297 fputc ('>', stdout);
9298 }
9299
9300 return procname;
9301}
9302
9303static void
9304arm_free_section (struct arm_section *arm_sec)
9305{
9db70fc3
AM
9306 free (arm_sec->data);
9307 free (arm_sec->rela);
0b6ae522
DJ
9308}
9309
a734115a
NC
9310/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
9311 cached section and install SEC instead.
9312 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
9313 and return its valued in * WORDP, relocating if necessary.
1b31d05e 9314 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 9315 relocation's offset in ADDR.
1b31d05e
NC
9316 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
9317 into the string table of the symbol associated with the reloc. If no
9318 reloc was applied store -1 there.
9319 5) Return TRUE upon success, FALSE otherwise. */
a734115a 9320
015dc7e1 9321static bool
dda8d76d
NC
9322get_unwind_section_word (Filedata * filedata,
9323 struct arm_unw_aux_info * aux,
1b31d05e
NC
9324 struct arm_section * arm_sec,
9325 Elf_Internal_Shdr * sec,
9326 bfd_vma word_offset,
9327 unsigned int * wordp,
9328 struct absaddr * addr,
9329 bfd_vma * sym_name)
0b6ae522
DJ
9330{
9331 Elf_Internal_Rela *rp;
9332 Elf_Internal_Sym *sym;
9333 const char * relname;
9334 unsigned int word;
015dc7e1 9335 bool wrapped;
0b6ae522 9336
e0a31db1 9337 if (sec == NULL || arm_sec == NULL)
015dc7e1 9338 return false;
e0a31db1 9339
0b6ae522
DJ
9340 addr->section = SHN_UNDEF;
9341 addr->offset = 0;
9342
1b31d05e
NC
9343 if (sym_name != NULL)
9344 *sym_name = (bfd_vma) -1;
9345
a734115a 9346 /* If necessary, update the section cache. */
0b6ae522
DJ
9347 if (sec != arm_sec->sec)
9348 {
9349 Elf_Internal_Shdr *relsec;
9350
9351 arm_free_section (arm_sec);
9352
9353 arm_sec->sec = sec;
dda8d76d 9354 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 9355 sec->sh_size, _("unwind data"));
0b6ae522
DJ
9356 arm_sec->rela = NULL;
9357 arm_sec->nrelas = 0;
9358
dda8d76d
NC
9359 for (relsec = filedata->section_headers;
9360 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
9361 ++relsec)
9362 {
dda8d76d
NC
9363 if (relsec->sh_info >= filedata->file_header.e_shnum
9364 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9365 /* PR 15745: Check the section type as well. */
9366 || (relsec->sh_type != SHT_REL
9367 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9368 continue;
9369
a734115a 9370 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9371 if (relsec->sh_type == SHT_REL)
9372 {
dda8d76d 9373 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9374 relsec->sh_size,
9375 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9376 return false;
0b6ae522 9377 }
1ae40aa4 9378 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9379 {
dda8d76d 9380 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9381 relsec->sh_size,
9382 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9383 return false;
0b6ae522 9384 }
1ae40aa4 9385 break;
0b6ae522
DJ
9386 }
9387
9388 arm_sec->next_rela = arm_sec->rela;
9389 }
9390
a734115a 9391 /* If there is no unwind data we can do nothing. */
0b6ae522 9392 if (arm_sec->data == NULL)
015dc7e1 9393 return false;
0b6ae522 9394
e0a31db1 9395 /* If the offset is invalid then fail. */
f32ba729
NC
9396 if (/* PR 21343 *//* PR 18879 */
9397 sec->sh_size < 4
9398 || word_offset > (sec->sh_size - 4)
1a915552 9399 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9400 return false;
e0a31db1 9401
a734115a 9402 /* Get the word at the required offset. */
0b6ae522
DJ
9403 word = byte_get (arm_sec->data + word_offset, 4);
9404
0eff7165
NC
9405 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9406 if (arm_sec->rela == NULL)
9407 {
9408 * wordp = word;
015dc7e1 9409 return true;
0eff7165
NC
9410 }
9411
a734115a 9412 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9413 wrapped = false;
0b6ae522
DJ
9414 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9415 {
9416 bfd_vma prelval, offset;
9417
9418 if (rp->r_offset > word_offset && !wrapped)
9419 {
9420 rp = arm_sec->rela;
015dc7e1 9421 wrapped = true;
0b6ae522
DJ
9422 }
9423 if (rp->r_offset > word_offset)
9424 break;
9425
9426 if (rp->r_offset & 3)
9427 {
9428 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9429 (unsigned long) rp->r_offset);
9430 continue;
9431 }
9432
9433 if (rp->r_offset < word_offset)
9434 continue;
9435
74e1a04b
NC
9436 /* PR 17531: file: 027-161405-0.004 */
9437 if (aux->symtab == NULL)
9438 continue;
9439
0b6ae522
DJ
9440 if (arm_sec->rel_type == SHT_REL)
9441 {
9442 offset = word & 0x7fffffff;
9443 if (offset & 0x40000000)
9444 offset |= ~ (bfd_vma) 0x7fffffff;
9445 }
a734115a 9446 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9447 offset = rp->r_addend;
a734115a 9448 else
74e1a04b
NC
9449 {
9450 error (_("Unknown section relocation type %d encountered\n"),
9451 arm_sec->rel_type);
9452 break;
9453 }
0b6ae522 9454
071436c6
NC
9455 /* PR 17531 file: 027-1241568-0.004. */
9456 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9457 {
9458 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9459 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9460 break;
9461 }
9462
9463 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9464 offset += sym->st_value;
9465 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9466
a734115a 9467 /* Check that we are processing the expected reloc type. */
dda8d76d 9468 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9469 {
9470 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9471 if (relname == NULL)
9472 {
9473 warn (_("Skipping unknown ARM relocation type: %d\n"),
9474 (int) ELF32_R_TYPE (rp->r_info));
9475 continue;
9476 }
a734115a
NC
9477
9478 if (streq (relname, "R_ARM_NONE"))
9479 continue;
0b4362b0 9480
a734115a
NC
9481 if (! streq (relname, "R_ARM_PREL31"))
9482 {
071436c6 9483 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9484 continue;
9485 }
9486 }
dda8d76d 9487 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9488 {
9489 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9490 if (relname == NULL)
9491 {
9492 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9493 (int) ELF32_R_TYPE (rp->r_info));
9494 continue;
9495 }
0b4362b0 9496
a734115a
NC
9497 if (streq (relname, "R_C6000_NONE"))
9498 continue;
9499
9500 if (! streq (relname, "R_C6000_PREL31"))
9501 {
071436c6 9502 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9503 continue;
9504 }
9505
9506 prelval >>= 1;
9507 }
9508 else
74e1a04b
NC
9509 {
9510 /* This function currently only supports ARM and TI unwinders. */
9511 warn (_("Only TI and ARM unwinders are currently supported\n"));
9512 break;
9513 }
fa197c1c 9514
0b6ae522
DJ
9515 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9516 addr->section = sym->st_shndx;
9517 addr->offset = offset;
74e1a04b 9518
1b31d05e
NC
9519 if (sym_name)
9520 * sym_name = sym->st_name;
0b6ae522
DJ
9521 break;
9522 }
9523
9524 *wordp = word;
9525 arm_sec->next_rela = rp;
9526
015dc7e1 9527 return true;
0b6ae522
DJ
9528}
9529
a734115a
NC
9530static const char *tic6x_unwind_regnames[16] =
9531{
0b4362b0
RM
9532 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9533 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9534 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9535};
fa197c1c 9536
0b6ae522 9537static void
fa197c1c 9538decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9539{
fa197c1c
PB
9540 int i;
9541
9542 for (i = 12; mask; mask >>= 1, i--)
9543 {
9544 if (mask & 1)
9545 {
9546 fputs (tic6x_unwind_regnames[i], stdout);
9547 if (mask > 1)
9548 fputs (", ", stdout);
9549 }
9550 }
9551}
0b6ae522
DJ
9552
9553#define ADVANCE \
9554 if (remaining == 0 && more_words) \
9555 { \
9556 data_offset += 4; \
dda8d76d 9557 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9558 data_offset, & word, & addr, NULL)) \
015dc7e1 9559 return false; \
0b6ae522
DJ
9560 remaining = 4; \
9561 more_words--; \
9562 } \
9563
9564#define GET_OP(OP) \
9565 ADVANCE; \
9566 if (remaining) \
9567 { \
9568 remaining--; \
9569 (OP) = word >> 24; \
9570 word <<= 8; \
9571 } \
9572 else \
9573 { \
2b692964 9574 printf (_("[Truncated opcode]\n")); \
015dc7e1 9575 return false; \
0b6ae522 9576 } \
cc5914eb 9577 printf ("0x%02x ", OP)
0b6ae522 9578
015dc7e1 9579static bool
dda8d76d
NC
9580decode_arm_unwind_bytecode (Filedata * filedata,
9581 struct arm_unw_aux_info * aux,
948f632f
DA
9582 unsigned int word,
9583 unsigned int remaining,
9584 unsigned int more_words,
9585 bfd_vma data_offset,
9586 Elf_Internal_Shdr * data_sec,
9587 struct arm_section * data_arm_sec)
fa197c1c
PB
9588{
9589 struct absaddr addr;
015dc7e1 9590 bool res = true;
0b6ae522
DJ
9591
9592 /* Decode the unwinding instructions. */
9593 while (1)
9594 {
9595 unsigned int op, op2;
9596
9597 ADVANCE;
9598 if (remaining == 0)
9599 break;
9600 remaining--;
9601 op = word >> 24;
9602 word <<= 8;
9603
cc5914eb 9604 printf (" 0x%02x ", op);
0b6ae522
DJ
9605
9606 if ((op & 0xc0) == 0x00)
9607 {
9608 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9609
cc5914eb 9610 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9611 }
9612 else if ((op & 0xc0) == 0x40)
9613 {
9614 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9615
cc5914eb 9616 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9617 }
9618 else if ((op & 0xf0) == 0x80)
9619 {
9620 GET_OP (op2);
9621 if (op == 0x80 && op2 == 0)
9622 printf (_("Refuse to unwind"));
9623 else
9624 {
9625 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9626 bool first = true;
0b6ae522 9627 int i;
2b692964 9628
0b6ae522
DJ
9629 printf ("pop {");
9630 for (i = 0; i < 12; i++)
9631 if (mask & (1 << i))
9632 {
9633 if (first)
015dc7e1 9634 first = false;
0b6ae522
DJ
9635 else
9636 printf (", ");
9637 printf ("r%d", 4 + i);
9638 }
9639 printf ("}");
9640 }
9641 }
9642 else if ((op & 0xf0) == 0x90)
9643 {
9644 if (op == 0x9d || op == 0x9f)
9645 printf (_(" [Reserved]"));
9646 else
cc5914eb 9647 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9648 }
9649 else if ((op & 0xf0) == 0xa0)
9650 {
9651 int end = 4 + (op & 0x07);
015dc7e1 9652 bool first = true;
0b6ae522 9653 int i;
61865e30 9654
0b6ae522
DJ
9655 printf (" pop {");
9656 for (i = 4; i <= end; i++)
9657 {
9658 if (first)
015dc7e1 9659 first = false;
0b6ae522
DJ
9660 else
9661 printf (", ");
9662 printf ("r%d", i);
9663 }
9664 if (op & 0x08)
9665 {
1b31d05e 9666 if (!first)
0b6ae522
DJ
9667 printf (", ");
9668 printf ("r14");
9669 }
9670 printf ("}");
9671 }
9672 else if (op == 0xb0)
9673 printf (_(" finish"));
9674 else if (op == 0xb1)
9675 {
9676 GET_OP (op2);
9677 if (op2 == 0 || (op2 & 0xf0) != 0)
9678 printf (_("[Spare]"));
9679 else
9680 {
9681 unsigned int mask = op2 & 0x0f;
015dc7e1 9682 bool first = true;
0b6ae522 9683 int i;
61865e30 9684
0b6ae522
DJ
9685 printf ("pop {");
9686 for (i = 0; i < 12; i++)
9687 if (mask & (1 << i))
9688 {
9689 if (first)
015dc7e1 9690 first = false;
0b6ae522
DJ
9691 else
9692 printf (", ");
9693 printf ("r%d", i);
9694 }
9695 printf ("}");
9696 }
9697 }
9698 else if (op == 0xb2)
9699 {
b115cf96 9700 unsigned char buf[9];
0b6ae522
DJ
9701 unsigned int i, len;
9702 unsigned long offset;
61865e30 9703
b115cf96 9704 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9705 {
9706 GET_OP (buf[i]);
9707 if ((buf[i] & 0x80) == 0)
9708 break;
9709 }
4082ef84 9710 if (i == sizeof (buf))
32ec8896 9711 {
27a45f42 9712 error (_("corrupt change to vsp\n"));
015dc7e1 9713 res = false;
32ec8896 9714 }
4082ef84
NC
9715 else
9716 {
015dc7e1 9717 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9718 assert (len == i + 1);
9719 offset = offset * 4 + 0x204;
9720 printf ("vsp = vsp + %ld", offset);
9721 }
0b6ae522 9722 }
61865e30 9723 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9724 {
61865e30
NC
9725 unsigned int first, last;
9726
9727 GET_OP (op2);
9728 first = op2 >> 4;
9729 last = op2 & 0x0f;
9730 if (op == 0xc8)
9731 first = first + 16;
9732 printf ("pop {D%d", first);
9733 if (last)
9734 printf ("-D%d", first + last);
9735 printf ("}");
9736 }
09854a88
TB
9737 else if (op == 0xb4)
9738 printf (_(" pop {ra_auth_code}"));
61865e30
NC
9739 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9740 {
9741 unsigned int count = op & 0x07;
9742
9743 printf ("pop {D8");
9744 if (count)
9745 printf ("-D%d", 8 + count);
9746 printf ("}");
9747 }
9748 else if (op >= 0xc0 && op <= 0xc5)
9749 {
9750 unsigned int count = op & 0x07;
9751
9752 printf (" pop {wR10");
9753 if (count)
9754 printf ("-wR%d", 10 + count);
9755 printf ("}");
9756 }
9757 else if (op == 0xc6)
9758 {
9759 unsigned int first, last;
9760
9761 GET_OP (op2);
9762 first = op2 >> 4;
9763 last = op2 & 0x0f;
9764 printf ("pop {wR%d", first);
9765 if (last)
9766 printf ("-wR%d", first + last);
9767 printf ("}");
9768 }
9769 else if (op == 0xc7)
9770 {
9771 GET_OP (op2);
9772 if (op2 == 0 || (op2 & 0xf0) != 0)
9773 printf (_("[Spare]"));
0b6ae522
DJ
9774 else
9775 {
61865e30 9776 unsigned int mask = op2 & 0x0f;
015dc7e1 9777 bool first = true;
61865e30
NC
9778 int i;
9779
9780 printf ("pop {");
9781 for (i = 0; i < 4; i++)
9782 if (mask & (1 << i))
9783 {
9784 if (first)
015dc7e1 9785 first = false;
61865e30
NC
9786 else
9787 printf (", ");
9788 printf ("wCGR%d", i);
9789 }
9790 printf ("}");
0b6ae522
DJ
9791 }
9792 }
61865e30 9793 else
32ec8896
NC
9794 {
9795 printf (_(" [unsupported opcode]"));
015dc7e1 9796 res = false;
32ec8896
NC
9797 }
9798
0b6ae522
DJ
9799 printf ("\n");
9800 }
32ec8896
NC
9801
9802 return res;
fa197c1c
PB
9803}
9804
015dc7e1 9805static bool
dda8d76d
NC
9806decode_tic6x_unwind_bytecode (Filedata * filedata,
9807 struct arm_unw_aux_info * aux,
948f632f
DA
9808 unsigned int word,
9809 unsigned int remaining,
9810 unsigned int more_words,
9811 bfd_vma data_offset,
9812 Elf_Internal_Shdr * data_sec,
9813 struct arm_section * data_arm_sec)
fa197c1c
PB
9814{
9815 struct absaddr addr;
9816
9817 /* Decode the unwinding instructions. */
9818 while (1)
9819 {
9820 unsigned int op, op2;
9821
9822 ADVANCE;
9823 if (remaining == 0)
9824 break;
9825 remaining--;
9826 op = word >> 24;
9827 word <<= 8;
9828
9cf03b7e 9829 printf (" 0x%02x ", op);
fa197c1c
PB
9830
9831 if ((op & 0xc0) == 0x00)
9832 {
9833 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9834 printf (" sp = sp + %d", offset);
fa197c1c
PB
9835 }
9836 else if ((op & 0xc0) == 0x80)
9837 {
9838 GET_OP (op2);
9839 if (op == 0x80 && op2 == 0)
9840 printf (_("Refuse to unwind"));
9841 else
9842 {
9843 unsigned int mask = ((op & 0x1f) << 8) | op2;
9844 if (op & 0x20)
9845 printf ("pop compact {");
9846 else
9847 printf ("pop {");
9848
9849 decode_tic6x_unwind_regmask (mask);
9850 printf("}");
9851 }
9852 }
9853 else if ((op & 0xf0) == 0xc0)
9854 {
9855 unsigned int reg;
9856 unsigned int nregs;
9857 unsigned int i;
9858 const char *name;
a734115a
NC
9859 struct
9860 {
32ec8896
NC
9861 unsigned int offset;
9862 unsigned int reg;
fa197c1c
PB
9863 } regpos[16];
9864
9865 /* Scan entire instruction first so that GET_OP output is not
9866 interleaved with disassembly. */
9867 nregs = 0;
9868 for (i = 0; nregs < (op & 0xf); i++)
9869 {
9870 GET_OP (op2);
9871 reg = op2 >> 4;
9872 if (reg != 0xf)
9873 {
9874 regpos[nregs].offset = i * 2;
9875 regpos[nregs].reg = reg;
9876 nregs++;
9877 }
9878
9879 reg = op2 & 0xf;
9880 if (reg != 0xf)
9881 {
9882 regpos[nregs].offset = i * 2 + 1;
9883 regpos[nregs].reg = reg;
9884 nregs++;
9885 }
9886 }
9887
9888 printf (_("pop frame {"));
18344509 9889 if (nregs == 0)
fa197c1c 9890 {
18344509
NC
9891 printf (_("*corrupt* - no registers specified"));
9892 }
9893 else
9894 {
9895 reg = nregs - 1;
9896 for (i = i * 2; i > 0; i--)
fa197c1c 9897 {
18344509
NC
9898 if (regpos[reg].offset == i - 1)
9899 {
9900 name = tic6x_unwind_regnames[regpos[reg].reg];
9901 if (reg > 0)
9902 reg--;
9903 }
9904 else
9905 name = _("[pad]");
fa197c1c 9906
18344509
NC
9907 fputs (name, stdout);
9908 if (i > 1)
9909 printf (", ");
9910 }
fa197c1c
PB
9911 }
9912
9913 printf ("}");
9914 }
9915 else if (op == 0xd0)
9916 printf (" MOV FP, SP");
9917 else if (op == 0xd1)
9918 printf (" __c6xabi_pop_rts");
9919 else if (op == 0xd2)
9920 {
9921 unsigned char buf[9];
9922 unsigned int i, len;
9923 unsigned long offset;
a734115a 9924
fa197c1c
PB
9925 for (i = 0; i < sizeof (buf); i++)
9926 {
9927 GET_OP (buf[i]);
9928 if ((buf[i] & 0x80) == 0)
9929 break;
9930 }
0eff7165
NC
9931 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9932 if (i == sizeof (buf))
9933 {
0eff7165 9934 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9935 return false;
0eff7165 9936 }
948f632f 9937
015dc7e1 9938 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9939 assert (len == i + 1);
9940 offset = offset * 8 + 0x408;
9941 printf (_("sp = sp + %ld"), offset);
9942 }
9943 else if ((op & 0xf0) == 0xe0)
9944 {
9945 if ((op & 0x0f) == 7)
9946 printf (" RETURN");
9947 else
9948 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9949 }
9950 else
9951 {
9952 printf (_(" [unsupported opcode]"));
9953 }
9954 putchar ('\n');
9955 }
32ec8896 9956
015dc7e1 9957 return true;
fa197c1c
PB
9958}
9959
9960static bfd_vma
dda8d76d 9961arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9962{
9963 bfd_vma offset;
9964
9965 offset = word & 0x7fffffff;
9966 if (offset & 0x40000000)
9967 offset |= ~ (bfd_vma) 0x7fffffff;
9968
dda8d76d 9969 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9970 offset <<= 1;
9971
9972 return offset + where;
9973}
9974
015dc7e1 9975static bool
dda8d76d
NC
9976decode_arm_unwind (Filedata * filedata,
9977 struct arm_unw_aux_info * aux,
1b31d05e
NC
9978 unsigned int word,
9979 unsigned int remaining,
9980 bfd_vma data_offset,
9981 Elf_Internal_Shdr * data_sec,
9982 struct arm_section * data_arm_sec)
fa197c1c
PB
9983{
9984 int per_index;
9985 unsigned int more_words = 0;
37e14bc3 9986 struct absaddr addr;
1b31d05e 9987 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9988 bool res = true;
fa197c1c
PB
9989
9990 if (remaining == 0)
9991 {
1b31d05e
NC
9992 /* Fetch the first word.
9993 Note - when decoding an object file the address extracted
9994 here will always be 0. So we also pass in the sym_name
9995 parameter so that we can find the symbol associated with
9996 the personality routine. */
dda8d76d 9997 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9998 & word, & addr, & sym_name))
015dc7e1 9999 return false;
1b31d05e 10000
fa197c1c
PB
10001 remaining = 4;
10002 }
c93dbb25
CZ
10003 else
10004 {
10005 addr.section = SHN_UNDEF;
10006 addr.offset = 0;
10007 }
fa197c1c
PB
10008
10009 if ((word & 0x80000000) == 0)
10010 {
10011 /* Expand prel31 for personality routine. */
10012 bfd_vma fn;
10013 const char *procname;
10014
dda8d76d 10015 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 10016 printf (_(" Personality routine: "));
1b31d05e
NC
10017 if (fn == 0
10018 && addr.section == SHN_UNDEF && addr.offset == 0
10019 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
10020 {
10021 procname = aux->strtab + sym_name;
10022 print_vma (fn, PREFIX_HEX);
10023 if (procname)
10024 {
10025 fputs (" <", stdout);
10026 fputs (procname, stdout);
10027 fputc ('>', stdout);
10028 }
10029 }
10030 else
dda8d76d 10031 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
10032 fputc ('\n', stdout);
10033
10034 /* The GCC personality routines use the standard compact
10035 encoding, starting with one byte giving the number of
10036 words. */
10037 if (procname != NULL
24d127aa
ML
10038 && (startswith (procname, "__gcc_personality_v0")
10039 || startswith (procname, "__gxx_personality_v0")
10040 || startswith (procname, "__gcj_personality_v0")
10041 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
10042 {
10043 remaining = 0;
10044 more_words = 1;
10045 ADVANCE;
10046 if (!remaining)
10047 {
10048 printf (_(" [Truncated data]\n"));
015dc7e1 10049 return false;
fa197c1c
PB
10050 }
10051 more_words = word >> 24;
10052 word <<= 8;
10053 remaining--;
10054 per_index = -1;
10055 }
10056 else
015dc7e1 10057 return true;
fa197c1c
PB
10058 }
10059 else
10060 {
1b31d05e 10061 /* ARM EHABI Section 6.3:
0b4362b0 10062
1b31d05e 10063 An exception-handling table entry for the compact model looks like:
0b4362b0 10064
1b31d05e
NC
10065 31 30-28 27-24 23-0
10066 -- ----- ----- ----
10067 1 0 index Data for personalityRoutine[index] */
10068
dda8d76d 10069 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 10070 && (word & 0x70000000))
32ec8896
NC
10071 {
10072 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 10073 res = false;
32ec8896 10074 }
1b31d05e 10075
fa197c1c 10076 per_index = (word >> 24) & 0x7f;
1b31d05e 10077 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
10078 if (per_index == 0)
10079 {
10080 more_words = 0;
10081 word <<= 8;
10082 remaining--;
10083 }
10084 else if (per_index < 3)
10085 {
10086 more_words = (word >> 16) & 0xff;
10087 word <<= 16;
10088 remaining -= 2;
10089 }
10090 }
10091
dda8d76d 10092 switch (filedata->file_header.e_machine)
fa197c1c
PB
10093 {
10094 case EM_ARM:
10095 if (per_index < 3)
10096 {
dda8d76d 10097 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10098 data_offset, data_sec, data_arm_sec))
015dc7e1 10099 res = false;
fa197c1c
PB
10100 }
10101 else
1b31d05e
NC
10102 {
10103 warn (_("Unknown ARM compact model index encountered\n"));
10104 printf (_(" [reserved]\n"));
015dc7e1 10105 res = false;
1b31d05e 10106 }
fa197c1c
PB
10107 break;
10108
10109 case EM_TI_C6000:
10110 if (per_index < 3)
10111 {
dda8d76d 10112 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 10113 data_offset, data_sec, data_arm_sec))
015dc7e1 10114 res = false;
fa197c1c
PB
10115 }
10116 else if (per_index < 5)
10117 {
10118 if (((word >> 17) & 0x7f) == 0x7f)
10119 printf (_(" Restore stack from frame pointer\n"));
10120 else
10121 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
10122 printf (_(" Registers restored: "));
10123 if (per_index == 4)
10124 printf (" (compact) ");
10125 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
10126 putchar ('\n');
10127 printf (_(" Return register: %s\n"),
10128 tic6x_unwind_regnames[word & 0xf]);
10129 }
10130 else
1b31d05e 10131 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
10132 break;
10133
10134 default:
74e1a04b 10135 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 10136 filedata->file_header.e_machine);
015dc7e1 10137 res = false;
fa197c1c 10138 }
0b6ae522
DJ
10139
10140 /* Decode the descriptors. Not implemented. */
32ec8896
NC
10141
10142 return res;
0b6ae522
DJ
10143}
10144
015dc7e1 10145static bool
dda8d76d
NC
10146dump_arm_unwind (Filedata * filedata,
10147 struct arm_unw_aux_info * aux,
10148 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
10149{
10150 struct arm_section exidx_arm_sec, extab_arm_sec;
10151 unsigned int i, exidx_len;
948f632f 10152 unsigned long j, nfuns;
015dc7e1 10153 bool res = true;
0b6ae522
DJ
10154
10155 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
10156 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
10157 exidx_len = exidx_sec->sh_size / 8;
10158
948f632f
DA
10159 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
10160 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
10161 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
10162 aux->funtab[nfuns++] = aux->symtab[j];
10163 aux->nfuns = nfuns;
10164 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
10165
0b6ae522
DJ
10166 for (i = 0; i < exidx_len; i++)
10167 {
10168 unsigned int exidx_fn, exidx_entry;
10169 struct absaddr fn_addr, entry_addr;
10170 bfd_vma fn;
10171
10172 fputc ('\n', stdout);
10173
dda8d76d 10174 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10175 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 10176 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 10177 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 10178 {
948f632f 10179 free (aux->funtab);
1b31d05e
NC
10180 arm_free_section (& exidx_arm_sec);
10181 arm_free_section (& extab_arm_sec);
015dc7e1 10182 return false;
0b6ae522
DJ
10183 }
10184
83c257ca
NC
10185 /* ARM EHABI, Section 5:
10186 An index table entry consists of 2 words.
10187 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
10188 if (exidx_fn & 0x80000000)
32ec8896
NC
10189 {
10190 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 10191 res = false;
32ec8896 10192 }
83c257ca 10193
dda8d76d 10194 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 10195
dda8d76d 10196 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
10197 fputs (": ", stdout);
10198
10199 if (exidx_entry == 1)
10200 {
10201 print_vma (exidx_entry, PREFIX_HEX);
10202 fputs (" [cantunwind]\n", stdout);
10203 }
10204 else if (exidx_entry & 0x80000000)
10205 {
10206 print_vma (exidx_entry, PREFIX_HEX);
10207 fputc ('\n', stdout);
dda8d76d 10208 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
10209 }
10210 else
10211 {
8f73510c 10212 bfd_vma table, table_offset = 0;
0b6ae522
DJ
10213 Elf_Internal_Shdr *table_sec;
10214
10215 fputs ("@", stdout);
dda8d76d 10216 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
10217 print_vma (table, PREFIX_HEX);
10218 printf ("\n");
10219
10220 /* Locate the matching .ARM.extab. */
10221 if (entry_addr.section != SHN_UNDEF
dda8d76d 10222 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 10223 {
dda8d76d 10224 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 10225 table_offset = entry_addr.offset;
1a915552
NC
10226 /* PR 18879 */
10227 if (table_offset > table_sec->sh_size
10228 || ((bfd_signed_vma) table_offset) < 0)
10229 {
10230 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
10231 (unsigned long) table_offset,
dda8d76d 10232 printable_section_name (filedata, table_sec));
015dc7e1 10233 res = false;
1a915552
NC
10234 continue;
10235 }
0b6ae522
DJ
10236 }
10237 else
10238 {
dda8d76d 10239 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
10240 if (table_sec != NULL)
10241 table_offset = table - table_sec->sh_addr;
10242 }
32ec8896 10243
0b6ae522
DJ
10244 if (table_sec == NULL)
10245 {
10246 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
10247 (unsigned long) table);
015dc7e1 10248 res = false;
0b6ae522
DJ
10249 continue;
10250 }
32ec8896 10251
dda8d76d 10252 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 10253 &extab_arm_sec))
015dc7e1 10254 res = false;
0b6ae522
DJ
10255 }
10256 }
10257
10258 printf ("\n");
10259
948f632f 10260 free (aux->funtab);
0b6ae522
DJ
10261 arm_free_section (&exidx_arm_sec);
10262 arm_free_section (&extab_arm_sec);
32ec8896
NC
10263
10264 return res;
0b6ae522
DJ
10265}
10266
fa197c1c 10267/* Used for both ARM and C6X unwinding tables. */
1b31d05e 10268
015dc7e1 10269static bool
dda8d76d 10270arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
10271{
10272 struct arm_unw_aux_info aux;
10273 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
10274 Elf_Internal_Shdr *sec;
10275 unsigned long i;
fa197c1c 10276 unsigned int sec_type;
015dc7e1 10277 bool res = true;
0b6ae522 10278
dda8d76d 10279 switch (filedata->file_header.e_machine)
fa197c1c
PB
10280 {
10281 case EM_ARM:
10282 sec_type = SHT_ARM_EXIDX;
10283 break;
10284
10285 case EM_TI_C6000:
10286 sec_type = SHT_C6000_UNWIND;
10287 break;
10288
0b4362b0 10289 default:
74e1a04b 10290 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 10291 filedata->file_header.e_machine);
015dc7e1 10292 return false;
fa197c1c
PB
10293 }
10294
dda8d76d 10295 if (filedata->string_table == NULL)
015dc7e1 10296 return false;
1b31d05e
NC
10297
10298 memset (& aux, 0, sizeof (aux));
dda8d76d 10299 aux.filedata = filedata;
0b6ae522 10300
dda8d76d 10301 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 10302 {
28d13567 10303 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 10304 {
28d13567 10305 if (aux.symtab)
74e1a04b 10306 {
28d13567
AM
10307 error (_("Multiple symbol tables encountered\n"));
10308 free (aux.symtab);
10309 aux.symtab = NULL;
74e1a04b 10310 free (aux.strtab);
28d13567 10311 aux.strtab = NULL;
74e1a04b 10312 }
28d13567
AM
10313 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
10314 &aux.strtab, &aux.strtab_size))
015dc7e1 10315 return false;
0b6ae522 10316 }
fa197c1c 10317 else if (sec->sh_type == sec_type)
0b6ae522
DJ
10318 unwsec = sec;
10319 }
10320
1b31d05e 10321 if (unwsec == NULL)
0b6ae522 10322 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 10323 else
dda8d76d 10324 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
10325 {
10326 if (sec->sh_type == sec_type)
10327 {
d3a49aa8
AM
10328 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
10329 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
10330 "contains %lu entry:\n",
10331 "\nUnwind section '%s' at offset 0x%lx "
10332 "contains %lu entries:\n",
10333 num_unwind),
dda8d76d 10334 printable_section_name (filedata, sec),
1b31d05e 10335 (unsigned long) sec->sh_offset,
d3a49aa8 10336 num_unwind);
0b6ae522 10337
dda8d76d 10338 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 10339 res = false;
1b31d05e
NC
10340 }
10341 }
0b6ae522 10342
9db70fc3
AM
10343 free (aux.symtab);
10344 free ((char *) aux.strtab);
32ec8896
NC
10345
10346 return res;
0b6ae522
DJ
10347}
10348
3ecc00ec
NC
10349static bool
10350no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
10351{
10352 printf (_("No processor specific unwind information to decode\n"));
10353 return true;
10354}
10355
015dc7e1 10356static bool
dda8d76d 10357process_unwind (Filedata * filedata)
57346661 10358{
2cf0635d
NC
10359 struct unwind_handler
10360 {
32ec8896 10361 unsigned int machtype;
015dc7e1 10362 bool (* handler)(Filedata *);
2cf0635d
NC
10363 } handlers[] =
10364 {
0b6ae522 10365 { EM_ARM, arm_process_unwind },
57346661
AM
10366 { EM_IA_64, ia64_process_unwind },
10367 { EM_PARISC, hppa_process_unwind },
fa197c1c 10368 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10369 { EM_386, no_processor_specific_unwind },
10370 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10371 { 0, NULL }
57346661
AM
10372 };
10373 int i;
10374
10375 if (!do_unwind)
015dc7e1 10376 return true;
57346661
AM
10377
10378 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10379 if (filedata->file_header.e_machine == handlers[i].machtype)
10380 return handlers[i].handler (filedata);
57346661 10381
1b31d05e 10382 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10383 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10384 return true;
57346661
AM
10385}
10386
37c18eed
SD
10387static void
10388dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10389{
10390 switch (entry->d_tag)
10391 {
10392 case DT_AARCH64_BTI_PLT:
1dbade74 10393 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10394 break;
10395 default:
10396 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10397 break;
10398 }
10399 putchar ('\n');
10400}
10401
252b5132 10402static void
978c4450 10403dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10404{
10405 switch (entry->d_tag)
10406 {
10407 case DT_MIPS_FLAGS:
10408 if (entry->d_un.d_val == 0)
4b68bca3 10409 printf (_("NONE"));
252b5132
RH
10410 else
10411 {
10412 static const char * opts[] =
10413 {
10414 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10415 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10416 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10417 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10418 "RLD_ORDER_SAFE"
10419 };
10420 unsigned int cnt;
015dc7e1 10421 bool first = true;
2b692964 10422
60bca95a 10423 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10424 if (entry->d_un.d_val & (1 << cnt))
10425 {
10426 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10427 first = false;
252b5132 10428 }
252b5132
RH
10429 }
10430 break;
103f02d3 10431
252b5132 10432 case DT_MIPS_IVERSION:
84714f86 10433 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 10434 printf (_("Interface Version: %s"),
84714f86 10435 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 10436 else
76ca31c0
NC
10437 {
10438 char buf[40];
10439 sprintf_vma (buf, entry->d_un.d_ptr);
10440 /* Note: coded this way so that there is a single string for translation. */
10441 printf (_("<corrupt: %s>"), buf);
10442 }
252b5132 10443 break;
103f02d3 10444
252b5132
RH
10445 case DT_MIPS_TIME_STAMP:
10446 {
d5b07ef4 10447 char timebuf[128];
2cf0635d 10448 struct tm * tmp;
91d6fa6a 10449 time_t atime = entry->d_un.d_val;
82b1b41b 10450
91d6fa6a 10451 tmp = gmtime (&atime);
82b1b41b
NC
10452 /* PR 17531: file: 6accc532. */
10453 if (tmp == NULL)
10454 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10455 else
10456 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10457 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10458 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10459 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10460 }
10461 break;
103f02d3 10462
252b5132
RH
10463 case DT_MIPS_RLD_VERSION:
10464 case DT_MIPS_LOCAL_GOTNO:
10465 case DT_MIPS_CONFLICTNO:
10466 case DT_MIPS_LIBLISTNO:
10467 case DT_MIPS_SYMTABNO:
10468 case DT_MIPS_UNREFEXTNO:
10469 case DT_MIPS_HIPAGENO:
10470 case DT_MIPS_DELTA_CLASS_NO:
10471 case DT_MIPS_DELTA_INSTANCE_NO:
10472 case DT_MIPS_DELTA_RELOC_NO:
10473 case DT_MIPS_DELTA_SYM_NO:
10474 case DT_MIPS_DELTA_CLASSSYM_NO:
10475 case DT_MIPS_COMPACT_SIZE:
c69075ac 10476 print_vma (entry->d_un.d_val, DEC);
252b5132 10477 break;
103f02d3 10478
f16a9783 10479 case DT_MIPS_XHASH:
978c4450
AM
10480 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10481 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10482 /* Falls through. */
10483
103f02d3 10484 default:
4b68bca3 10485 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10486 }
4b68bca3 10487 putchar ('\n');
103f02d3
UD
10488}
10489
103f02d3 10490static void
2cf0635d 10491dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10492{
10493 switch (entry->d_tag)
10494 {
10495 case DT_HP_DLD_FLAGS:
10496 {
10497 static struct
10498 {
10499 long int bit;
2cf0635d 10500 const char * str;
5e220199
NC
10501 }
10502 flags[] =
10503 {
10504 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10505 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10506 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10507 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10508 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10509 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10510 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10511 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10512 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10513 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10514 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10515 { DT_HP_GST, "HP_GST" },
10516 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10517 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10518 { DT_HP_NODELETE, "HP_NODELETE" },
10519 { DT_HP_GROUP, "HP_GROUP" },
10520 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10521 };
015dc7e1 10522 bool first = true;
5e220199 10523 size_t cnt;
f7a99963 10524 bfd_vma val = entry->d_un.d_val;
103f02d3 10525
60bca95a 10526 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10527 if (val & flags[cnt].bit)
30800947
NC
10528 {
10529 if (! first)
10530 putchar (' ');
10531 fputs (flags[cnt].str, stdout);
015dc7e1 10532 first = false;
30800947
NC
10533 val ^= flags[cnt].bit;
10534 }
76da6bbe 10535
103f02d3 10536 if (val != 0 || first)
f7a99963
NC
10537 {
10538 if (! first)
10539 putchar (' ');
10540 print_vma (val, HEX);
10541 }
103f02d3
UD
10542 }
10543 break;
76da6bbe 10544
252b5132 10545 default:
f7a99963
NC
10546 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10547 break;
252b5132 10548 }
35b1837e 10549 putchar ('\n');
252b5132
RH
10550}
10551
28f997cf
TG
10552#ifdef BFD64
10553
10554/* VMS vs Unix time offset and factor. */
10555
10556#define VMS_EPOCH_OFFSET 35067168000000000LL
10557#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10558#ifndef INT64_MIN
10559#define INT64_MIN (-9223372036854775807LL - 1)
10560#endif
28f997cf
TG
10561
10562/* Display a VMS time in a human readable format. */
10563
10564static void
10565print_vms_time (bfd_int64_t vmstime)
10566{
dccc31de 10567 struct tm *tm = NULL;
28f997cf
TG
10568 time_t unxtime;
10569
dccc31de
AM
10570 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10571 {
10572 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10573 unxtime = vmstime;
10574 if (unxtime == vmstime)
10575 tm = gmtime (&unxtime);
10576 }
10577 if (tm != NULL)
10578 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10579 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10580 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10581}
10582#endif /* BFD64 */
10583
ecc51f48 10584static void
2cf0635d 10585dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10586{
10587 switch (entry->d_tag)
10588 {
0de14b54 10589 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10590 /* First 3 slots reserved. */
ecc51f48
NC
10591 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10592 printf (" -- ");
10593 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10594 break;
10595
28f997cf
TG
10596 case DT_IA_64_VMS_LINKTIME:
10597#ifdef BFD64
10598 print_vms_time (entry->d_un.d_val);
10599#endif
10600 break;
10601
10602 case DT_IA_64_VMS_LNKFLAGS:
10603 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10604 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10605 printf (" CALL_DEBUG");
10606 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10607 printf (" NOP0BUFS");
10608 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10609 printf (" P0IMAGE");
10610 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10611 printf (" MKTHREADS");
10612 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10613 printf (" UPCALLS");
10614 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10615 printf (" IMGSTA");
10616 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10617 printf (" INITIALIZE");
10618 if (entry->d_un.d_val & VMS_LF_MAIN)
10619 printf (" MAIN");
10620 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10621 printf (" EXE_INIT");
10622 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10623 printf (" TBK_IN_IMG");
10624 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10625 printf (" DBG_IN_IMG");
10626 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10627 printf (" TBK_IN_DSF");
10628 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10629 printf (" DBG_IN_DSF");
10630 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10631 printf (" SIGNATURES");
10632 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10633 printf (" REL_SEG_OFF");
10634 break;
10635
bdf4d63a
JJ
10636 default:
10637 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10638 break;
ecc51f48 10639 }
bdf4d63a 10640 putchar ('\n');
ecc51f48
NC
10641}
10642
015dc7e1 10643static bool
dda8d76d 10644get_32bit_dynamic_section (Filedata * filedata)
252b5132 10645{
2cf0635d
NC
10646 Elf32_External_Dyn * edyn;
10647 Elf32_External_Dyn * ext;
10648 Elf_Internal_Dyn * entry;
103f02d3 10649
978c4450
AM
10650 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10651 filedata->dynamic_addr, 1,
10652 filedata->dynamic_size,
10653 _("dynamic section"));
a6e9f9df 10654 if (!edyn)
015dc7e1 10655 return false;
103f02d3 10656
071436c6
NC
10657 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10658 might not have the luxury of section headers. Look for the DT_NULL
10659 terminator to determine the number of entries. */
978c4450
AM
10660 for (ext = edyn, filedata->dynamic_nent = 0;
10661 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10662 ext++)
10663 {
978c4450 10664 filedata->dynamic_nent++;
ba2685cc
AM
10665 if (BYTE_GET (ext->d_tag) == DT_NULL)
10666 break;
10667 }
252b5132 10668
978c4450
AM
10669 filedata->dynamic_section
10670 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10671 if (filedata->dynamic_section == NULL)
252b5132 10672 {
8b73c356 10673 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10674 (unsigned long) filedata->dynamic_nent);
9ea033b2 10675 free (edyn);
015dc7e1 10676 return false;
9ea033b2 10677 }
252b5132 10678
978c4450
AM
10679 for (ext = edyn, entry = filedata->dynamic_section;
10680 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10681 ext++, entry++)
9ea033b2 10682 {
fb514b26
AM
10683 entry->d_tag = BYTE_GET (ext->d_tag);
10684 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10685 }
10686
9ea033b2
NC
10687 free (edyn);
10688
015dc7e1 10689 return true;
9ea033b2
NC
10690}
10691
015dc7e1 10692static bool
dda8d76d 10693get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10694{
2cf0635d
NC
10695 Elf64_External_Dyn * edyn;
10696 Elf64_External_Dyn * ext;
10697 Elf_Internal_Dyn * entry;
103f02d3 10698
071436c6 10699 /* Read in the data. */
978c4450
AM
10700 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10701 filedata->dynamic_addr, 1,
10702 filedata->dynamic_size,
10703 _("dynamic section"));
a6e9f9df 10704 if (!edyn)
015dc7e1 10705 return false;
103f02d3 10706
071436c6
NC
10707 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10708 might not have the luxury of section headers. Look for the DT_NULL
10709 terminator to determine the number of entries. */
978c4450 10710 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10711 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10712 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10713 ext++)
10714 {
978c4450 10715 filedata->dynamic_nent++;
66543521 10716 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10717 break;
10718 }
252b5132 10719
978c4450
AM
10720 filedata->dynamic_section
10721 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10722 if (filedata->dynamic_section == NULL)
252b5132 10723 {
8b73c356 10724 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10725 (unsigned long) filedata->dynamic_nent);
252b5132 10726 free (edyn);
015dc7e1 10727 return false;
252b5132
RH
10728 }
10729
071436c6 10730 /* Convert from external to internal formats. */
978c4450
AM
10731 for (ext = edyn, entry = filedata->dynamic_section;
10732 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10733 ext++, entry++)
252b5132 10734 {
66543521
AM
10735 entry->d_tag = BYTE_GET (ext->d_tag);
10736 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10737 }
10738
10739 free (edyn);
10740
015dc7e1 10741 return true;
9ea033b2
NC
10742}
10743
4de91c10
AM
10744static bool
10745get_dynamic_section (Filedata *filedata)
10746{
10747 if (filedata->dynamic_section)
10748 return true;
10749
10750 if (is_32bit_elf)
10751 return get_32bit_dynamic_section (filedata);
10752 else
10753 return get_64bit_dynamic_section (filedata);
10754}
10755
e9e44622
JJ
10756static void
10757print_dynamic_flags (bfd_vma flags)
d1133906 10758{
015dc7e1 10759 bool first = true;
13ae64f3 10760
d1133906
NC
10761 while (flags)
10762 {
10763 bfd_vma flag;
10764
10765 flag = flags & - flags;
10766 flags &= ~ flag;
10767
e9e44622 10768 if (first)
015dc7e1 10769 first = false;
e9e44622
JJ
10770 else
10771 putc (' ', stdout);
13ae64f3 10772
d1133906
NC
10773 switch (flag)
10774 {
e9e44622
JJ
10775 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10776 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10777 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10778 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10779 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10780 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10781 }
10782 }
e9e44622 10783 puts ("");
d1133906
NC
10784}
10785
10ca4b04
L
10786static bfd_vma *
10787get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10788{
10789 unsigned char * e_data;
10790 bfd_vma * i_data;
10791
10792 /* If the size_t type is smaller than the bfd_size_type, eg because
10793 you are building a 32-bit tool on a 64-bit host, then make sure
10794 that when (number) is cast to (size_t) no information is lost. */
10795 if (sizeof (size_t) < sizeof (bfd_size_type)
10796 && (bfd_size_type) ((size_t) number) != number)
10797 {
10798 error (_("Size truncation prevents reading %s elements of size %u\n"),
10799 bfd_vmatoa ("u", number), ent_size);
10800 return NULL;
10801 }
10802
10803 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10804 attempting to allocate memory when the read is bound to fail. */
10805 if (ent_size * number > filedata->file_size)
10806 {
10807 error (_("Invalid number of dynamic entries: %s\n"),
10808 bfd_vmatoa ("u", number));
10809 return NULL;
10810 }
10811
10812 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10813 if (e_data == NULL)
10814 {
10815 error (_("Out of memory reading %s dynamic entries\n"),
10816 bfd_vmatoa ("u", number));
10817 return NULL;
10818 }
10819
10820 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10821 {
10822 error (_("Unable to read in %s bytes of dynamic data\n"),
10823 bfd_vmatoa ("u", number * ent_size));
10824 free (e_data);
10825 return NULL;
10826 }
10827
10828 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10829 if (i_data == NULL)
10830 {
10831 error (_("Out of memory allocating space for %s dynamic entries\n"),
10832 bfd_vmatoa ("u", number));
10833 free (e_data);
10834 return NULL;
10835 }
10836
10837 while (number--)
10838 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10839
10840 free (e_data);
10841
10842 return i_data;
10843}
10844
10845static unsigned long
10846get_num_dynamic_syms (Filedata * filedata)
10847{
10848 unsigned long num_of_syms = 0;
10849
10850 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10851 return num_of_syms;
10852
978c4450 10853 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10854 {
10855 unsigned char nb[8];
10856 unsigned char nc[8];
10857 unsigned int hash_ent_size = 4;
10858
10859 if ((filedata->file_header.e_machine == EM_ALPHA
10860 || filedata->file_header.e_machine == EM_S390
10861 || filedata->file_header.e_machine == EM_S390_OLD)
10862 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10863 hash_ent_size = 8;
10864
10865 if (fseek (filedata->handle,
978c4450
AM
10866 (filedata->archive_file_offset
10867 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10868 sizeof nb + sizeof nc)),
10869 SEEK_SET))
10870 {
10871 error (_("Unable to seek to start of dynamic information\n"));
10872 goto no_hash;
10873 }
10874
10875 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10876 {
10877 error (_("Failed to read in number of buckets\n"));
10878 goto no_hash;
10879 }
10880
10881 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10882 {
10883 error (_("Failed to read in number of chains\n"));
10884 goto no_hash;
10885 }
10886
978c4450
AM
10887 filedata->nbuckets = byte_get (nb, hash_ent_size);
10888 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10889
2482f306
AM
10890 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10891 {
10892 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10893 hash_ent_size);
10894 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10895 hash_ent_size);
001890e1 10896
2482f306
AM
10897 if (filedata->buckets != NULL && filedata->chains != NULL)
10898 num_of_syms = filedata->nchains;
10899 }
ceb9bf11 10900 no_hash:
10ca4b04
L
10901 if (num_of_syms == 0)
10902 {
9db70fc3
AM
10903 free (filedata->buckets);
10904 filedata->buckets = NULL;
10905 free (filedata->chains);
10906 filedata->chains = NULL;
978c4450 10907 filedata->nbuckets = 0;
10ca4b04
L
10908 }
10909 }
10910
978c4450 10911 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10912 {
10913 unsigned char nb[16];
10914 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10915 bfd_vma buckets_vma;
10916 unsigned long hn;
10ca4b04
L
10917
10918 if (fseek (filedata->handle,
978c4450
AM
10919 (filedata->archive_file_offset
10920 + offset_from_vma (filedata,
10921 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10922 sizeof nb)),
10923 SEEK_SET))
10924 {
10925 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10926 goto no_gnu_hash;
10927 }
10928
10929 if (fread (nb, 16, 1, filedata->handle) != 1)
10930 {
10931 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10932 goto no_gnu_hash;
10933 }
10934
978c4450
AM
10935 filedata->ngnubuckets = byte_get (nb, 4);
10936 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10937 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10938 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10939 if (is_32bit_elf)
10940 buckets_vma += bitmaskwords * 4;
10941 else
10942 buckets_vma += bitmaskwords * 8;
10943
10944 if (fseek (filedata->handle,
978c4450 10945 (filedata->archive_file_offset
10ca4b04
L
10946 + offset_from_vma (filedata, buckets_vma, 4)),
10947 SEEK_SET))
10948 {
10949 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10950 goto no_gnu_hash;
10951 }
10952
978c4450
AM
10953 filedata->gnubuckets
10954 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10955
978c4450 10956 if (filedata->gnubuckets == NULL)
90837ea7 10957 goto no_gnu_hash;
10ca4b04 10958
978c4450
AM
10959 for (i = 0; i < filedata->ngnubuckets; i++)
10960 if (filedata->gnubuckets[i] != 0)
10ca4b04 10961 {
978c4450 10962 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10963 goto no_gnu_hash;
10ca4b04 10964
978c4450
AM
10965 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10966 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10967 }
10968
10969 if (maxchain == 0xffffffff)
90837ea7 10970 goto no_gnu_hash;
10ca4b04 10971
978c4450 10972 maxchain -= filedata->gnusymidx;
10ca4b04
L
10973
10974 if (fseek (filedata->handle,
978c4450
AM
10975 (filedata->archive_file_offset
10976 + offset_from_vma (filedata,
10977 buckets_vma + 4 * (filedata->ngnubuckets
10978 + maxchain),
10979 4)),
10ca4b04
L
10980 SEEK_SET))
10981 {
10982 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10983 goto no_gnu_hash;
10984 }
10985
10986 do
10987 {
10988 if (fread (nb, 4, 1, filedata->handle) != 1)
10989 {
10990 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10991 goto no_gnu_hash;
10992 }
10993
10994 if (maxchain + 1 == 0)
90837ea7 10995 goto no_gnu_hash;
10ca4b04
L
10996
10997 ++maxchain;
10998 }
10999 while ((byte_get (nb, 4) & 1) == 0);
11000
11001 if (fseek (filedata->handle,
978c4450
AM
11002 (filedata->archive_file_offset
11003 + offset_from_vma (filedata, (buckets_vma
11004 + 4 * filedata->ngnubuckets),
11005 4)),
10ca4b04
L
11006 SEEK_SET))
11007 {
11008 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11009 goto no_gnu_hash;
11010 }
11011
978c4450
AM
11012 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
11013 filedata->ngnuchains = maxchain;
10ca4b04 11014
978c4450 11015 if (filedata->gnuchains == NULL)
90837ea7 11016 goto no_gnu_hash;
10ca4b04 11017
978c4450 11018 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
11019 {
11020 if (fseek (filedata->handle,
978c4450 11021 (filedata->archive_file_offset
10ca4b04 11022 + offset_from_vma (filedata, (buckets_vma
978c4450 11023 + 4 * (filedata->ngnubuckets
10ca4b04
L
11024 + maxchain)), 4)),
11025 SEEK_SET))
11026 {
11027 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
11028 goto no_gnu_hash;
11029 }
11030
978c4450 11031 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
11032 if (filedata->mipsxlat == NULL)
11033 goto no_gnu_hash;
10ca4b04
L
11034 }
11035
978c4450
AM
11036 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
11037 if (filedata->gnubuckets[hn] != 0)
10ca4b04 11038 {
978c4450
AM
11039 bfd_vma si = filedata->gnubuckets[hn];
11040 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
11041
11042 do
11043 {
978c4450 11044 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 11045 {
c31ab5a0
AM
11046 if (off < filedata->ngnuchains
11047 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 11048 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
11049 }
11050 else
11051 {
11052 if (si >= num_of_syms)
11053 num_of_syms = si + 1;
11054 }
11055 si++;
11056 }
978c4450
AM
11057 while (off < filedata->ngnuchains
11058 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
11059 }
11060
90837ea7 11061 if (num_of_syms == 0)
10ca4b04 11062 {
90837ea7 11063 no_gnu_hash:
9db70fc3
AM
11064 free (filedata->mipsxlat);
11065 filedata->mipsxlat = NULL;
11066 free (filedata->gnuchains);
11067 filedata->gnuchains = NULL;
11068 free (filedata->gnubuckets);
11069 filedata->gnubuckets = NULL;
978c4450
AM
11070 filedata->ngnubuckets = 0;
11071 filedata->ngnuchains = 0;
10ca4b04
L
11072 }
11073 }
11074
11075 return num_of_syms;
11076}
11077
b2d38a17
NC
11078/* Parse and display the contents of the dynamic section. */
11079
015dc7e1 11080static bool
dda8d76d 11081process_dynamic_section (Filedata * filedata)
9ea033b2 11082{
2cf0635d 11083 Elf_Internal_Dyn * entry;
9ea033b2 11084
93df3340 11085 if (filedata->dynamic_size <= 1)
9ea033b2
NC
11086 {
11087 if (do_dynamic)
ca0e11aa
NC
11088 {
11089 if (filedata->is_separate)
11090 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
11091 filedata->file_name);
11092 else
11093 printf (_("\nThere is no dynamic section in this file.\n"));
11094 }
9ea033b2 11095
015dc7e1 11096 return true;
9ea033b2
NC
11097 }
11098
4de91c10
AM
11099 if (!get_dynamic_section (filedata))
11100 return false;
9ea033b2 11101
252b5132 11102 /* Find the appropriate symbol table. */
978c4450 11103 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 11104 {
2482f306
AM
11105 unsigned long num_of_syms;
11106
978c4450
AM
11107 for (entry = filedata->dynamic_section;
11108 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11109 ++entry)
10ca4b04 11110 if (entry->d_tag == DT_SYMTAB)
978c4450 11111 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 11112 else if (entry->d_tag == DT_SYMENT)
978c4450 11113 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 11114 else if (entry->d_tag == DT_HASH)
978c4450 11115 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 11116 else if (entry->d_tag == DT_GNU_HASH)
978c4450 11117 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
11118 else if ((filedata->file_header.e_machine == EM_MIPS
11119 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
11120 && entry->d_tag == DT_MIPS_XHASH)
11121 {
978c4450
AM
11122 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
11123 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 11124 }
252b5132 11125
2482f306
AM
11126 num_of_syms = get_num_dynamic_syms (filedata);
11127
11128 if (num_of_syms != 0
11129 && filedata->dynamic_symbols == NULL
11130 && filedata->dynamic_info[DT_SYMTAB]
978c4450 11131 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
11132 {
11133 Elf_Internal_Phdr *seg;
2482f306 11134 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 11135
2482f306
AM
11136 if (! get_program_headers (filedata))
11137 {
11138 error (_("Cannot interpret virtual addresses "
11139 "without program headers.\n"));
015dc7e1 11140 return false;
2482f306 11141 }
252b5132 11142
2482f306
AM
11143 for (seg = filedata->program_headers;
11144 seg < filedata->program_headers + filedata->file_header.e_phnum;
11145 ++seg)
11146 {
11147 if (seg->p_type != PT_LOAD)
11148 continue;
252b5132 11149
2482f306
AM
11150 if (seg->p_offset + seg->p_filesz > filedata->file_size)
11151 {
11152 /* See PR 21379 for a reproducer. */
11153 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 11154 return false;
2482f306 11155 }
252b5132 11156
2482f306
AM
11157 if (vma >= (seg->p_vaddr & -seg->p_align)
11158 && vma < seg->p_vaddr + seg->p_filesz)
11159 {
11160 /* Since we do not know how big the symbol table is,
11161 we default to reading in up to the end of PT_LOAD
11162 segment and processing that. This is overkill, I
11163 know, but it should work. */
11164 Elf_Internal_Shdr section;
11165 section.sh_offset = (vma - seg->p_vaddr
11166 + seg->p_offset);
11167 section.sh_size = (num_of_syms
11168 * filedata->dynamic_info[DT_SYMENT]);
11169 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
11170
11171 if (do_checks
11172 && filedata->dynamic_symtab_section != NULL
11173 && ((filedata->dynamic_symtab_section->sh_offset
11174 != section.sh_offset)
11175 || (filedata->dynamic_symtab_section->sh_size
11176 != section.sh_size)
11177 || (filedata->dynamic_symtab_section->sh_entsize
11178 != section.sh_entsize)))
11179 warn (_("\
11180the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
11181
2482f306
AM
11182 section.sh_name = filedata->string_table_length;
11183 filedata->dynamic_symbols
4de91c10 11184 = get_elf_symbols (filedata, &section,
2482f306
AM
11185 &filedata->num_dynamic_syms);
11186 if (filedata->dynamic_symbols == NULL
11187 || filedata->num_dynamic_syms != num_of_syms)
11188 {
11189 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 11190 return false;
2482f306
AM
11191 }
11192 break;
11193 }
11194 }
11195 }
11196 }
252b5132
RH
11197
11198 /* Similarly find a string table. */
978c4450
AM
11199 if (filedata->dynamic_strings == NULL)
11200 for (entry = filedata->dynamic_section;
11201 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
11202 ++entry)
11203 {
11204 if (entry->d_tag == DT_STRTAB)
978c4450 11205 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 11206
10ca4b04 11207 if (entry->d_tag == DT_STRSZ)
978c4450 11208 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 11209
978c4450
AM
11210 if (filedata->dynamic_info[DT_STRTAB]
11211 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
11212 {
11213 unsigned long offset;
978c4450 11214 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
11215
11216 offset = offset_from_vma (filedata,
978c4450 11217 filedata->dynamic_info[DT_STRTAB],
10ca4b04 11218 str_tab_len);
8ac10c5b
L
11219 if (do_checks
11220 && filedata->dynamic_strtab_section
11221 && ((filedata->dynamic_strtab_section->sh_offset
11222 != (file_ptr) offset)
11223 || (filedata->dynamic_strtab_section->sh_size
11224 != str_tab_len)))
11225 warn (_("\
11226the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
11227
978c4450
AM
11228 filedata->dynamic_strings
11229 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
11230 _("dynamic string table"));
11231 if (filedata->dynamic_strings == NULL)
10ca4b04
L
11232 {
11233 error (_("Corrupt DT_STRTAB dynamic entry\n"));
11234 break;
11235 }
e3d39609 11236
978c4450 11237 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
11238 break;
11239 }
11240 }
252b5132
RH
11241
11242 /* And find the syminfo section if available. */
978c4450 11243 if (filedata->dynamic_syminfo == NULL)
252b5132 11244 {
3e8bba36 11245 unsigned long syminsz = 0;
252b5132 11246
978c4450
AM
11247 for (entry = filedata->dynamic_section;
11248 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11249 ++entry)
252b5132
RH
11250 {
11251 if (entry->d_tag == DT_SYMINENT)
11252 {
11253 /* Note: these braces are necessary to avoid a syntax
11254 error from the SunOS4 C compiler. */
049b0c3a
NC
11255 /* PR binutils/17531: A corrupt file can trigger this test.
11256 So do not use an assert, instead generate an error message. */
11257 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 11258 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 11259 (int) entry->d_un.d_val);
252b5132
RH
11260 }
11261 else if (entry->d_tag == DT_SYMINSZ)
11262 syminsz = entry->d_un.d_val;
11263 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
11264 filedata->dynamic_syminfo_offset
11265 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
11266 }
11267
978c4450 11268 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 11269 {
2cf0635d
NC
11270 Elf_External_Syminfo * extsyminfo;
11271 Elf_External_Syminfo * extsym;
11272 Elf_Internal_Syminfo * syminfo;
252b5132
RH
11273
11274 /* There is a syminfo section. Read the data. */
3f5e193b 11275 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
11276 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
11277 1, syminsz, _("symbol information"));
a6e9f9df 11278 if (!extsyminfo)
015dc7e1 11279 return false;
252b5132 11280
978c4450 11281 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
11282 {
11283 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 11284 free (filedata->dynamic_syminfo);
e3d39609 11285 }
978c4450
AM
11286 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
11287 if (filedata->dynamic_syminfo == NULL)
252b5132 11288 {
2482f306
AM
11289 error (_("Out of memory allocating %lu bytes "
11290 "for dynamic symbol info\n"),
8b73c356 11291 (unsigned long) syminsz);
015dc7e1 11292 return false;
252b5132
RH
11293 }
11294
2482f306
AM
11295 filedata->dynamic_syminfo_nent
11296 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 11297 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
11298 syminfo < (filedata->dynamic_syminfo
11299 + filedata->dynamic_syminfo_nent);
86dba8ee 11300 ++syminfo, ++extsym)
252b5132 11301 {
86dba8ee
AM
11302 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
11303 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
11304 }
11305
11306 free (extsyminfo);
11307 }
11308 }
11309
978c4450 11310 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 11311 {
f253158f
NC
11312 if (filedata->is_separate)
11313 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
11314 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
11315 (unsigned long) filedata->dynamic_nent),
11316 filedata->file_name,
11317 filedata->dynamic_addr,
11318 (unsigned long) filedata->dynamic_nent);
84a9f195
SM
11319 else
11320 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
11321 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
11322 (unsigned long) filedata->dynamic_nent),
11323 filedata->dynamic_addr,
11324 (unsigned long) filedata->dynamic_nent);
ca0e11aa 11325 }
252b5132
RH
11326 if (do_dynamic)
11327 printf (_(" Tag Type Name/Value\n"));
11328
978c4450
AM
11329 for (entry = filedata->dynamic_section;
11330 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 11331 entry++)
252b5132
RH
11332 {
11333 if (do_dynamic)
f7a99963 11334 {
2cf0635d 11335 const char * dtype;
e699b9ff 11336
f7a99963
NC
11337 putchar (' ');
11338 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 11339 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 11340 printf (" (%s)%*s", dtype,
32ec8896 11341 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 11342 }
252b5132
RH
11343
11344 switch (entry->d_tag)
11345 {
d1133906
NC
11346 case DT_FLAGS:
11347 if (do_dynamic)
e9e44622 11348 print_dynamic_flags (entry->d_un.d_val);
d1133906 11349 break;
76da6bbe 11350
252b5132
RH
11351 case DT_AUXILIARY:
11352 case DT_FILTER:
019148e4
L
11353 case DT_CONFIG:
11354 case DT_DEPAUDIT:
11355 case DT_AUDIT:
252b5132
RH
11356 if (do_dynamic)
11357 {
019148e4 11358 switch (entry->d_tag)
b34976b6 11359 {
019148e4
L
11360 case DT_AUXILIARY:
11361 printf (_("Auxiliary library"));
11362 break;
11363
11364 case DT_FILTER:
11365 printf (_("Filter library"));
11366 break;
11367
b34976b6 11368 case DT_CONFIG:
019148e4
L
11369 printf (_("Configuration file"));
11370 break;
11371
11372 case DT_DEPAUDIT:
11373 printf (_("Dependency audit library"));
11374 break;
11375
11376 case DT_AUDIT:
11377 printf (_("Audit library"));
11378 break;
11379 }
252b5132 11380
84714f86 11381 if (valid_dynamic_name (filedata, entry->d_un.d_val))
978c4450 11382 printf (": [%s]\n",
84714f86 11383 get_dynamic_name (filedata, entry->d_un.d_val));
252b5132 11384 else
f7a99963
NC
11385 {
11386 printf (": ");
11387 print_vma (entry->d_un.d_val, PREFIX_HEX);
11388 putchar ('\n');
11389 }
252b5132
RH
11390 }
11391 break;
11392
dcefbbbd 11393 case DT_FEATURE:
252b5132
RH
11394 if (do_dynamic)
11395 {
11396 printf (_("Flags:"));
86f55779 11397
252b5132
RH
11398 if (entry->d_un.d_val == 0)
11399 printf (_(" None\n"));
11400 else
11401 {
11402 unsigned long int val = entry->d_un.d_val;
86f55779 11403
252b5132
RH
11404 if (val & DTF_1_PARINIT)
11405 {
11406 printf (" PARINIT");
11407 val ^= DTF_1_PARINIT;
11408 }
dcefbbbd
L
11409 if (val & DTF_1_CONFEXP)
11410 {
11411 printf (" CONFEXP");
11412 val ^= DTF_1_CONFEXP;
11413 }
252b5132
RH
11414 if (val != 0)
11415 printf (" %lx", val);
11416 puts ("");
11417 }
11418 }
11419 break;
11420
11421 case DT_POSFLAG_1:
11422 if (do_dynamic)
11423 {
11424 printf (_("Flags:"));
86f55779 11425
252b5132
RH
11426 if (entry->d_un.d_val == 0)
11427 printf (_(" None\n"));
11428 else
11429 {
11430 unsigned long int val = entry->d_un.d_val;
86f55779 11431
252b5132
RH
11432 if (val & DF_P1_LAZYLOAD)
11433 {
11434 printf (" LAZYLOAD");
11435 val ^= DF_P1_LAZYLOAD;
11436 }
11437 if (val & DF_P1_GROUPPERM)
11438 {
11439 printf (" GROUPPERM");
11440 val ^= DF_P1_GROUPPERM;
11441 }
11442 if (val != 0)
11443 printf (" %lx", val);
11444 puts ("");
11445 }
11446 }
11447 break;
11448
11449 case DT_FLAGS_1:
11450 if (do_dynamic)
11451 {
11452 printf (_("Flags:"));
11453 if (entry->d_un.d_val == 0)
11454 printf (_(" None\n"));
11455 else
11456 {
11457 unsigned long int val = entry->d_un.d_val;
86f55779 11458
252b5132
RH
11459 if (val & DF_1_NOW)
11460 {
11461 printf (" NOW");
11462 val ^= DF_1_NOW;
11463 }
11464 if (val & DF_1_GLOBAL)
11465 {
11466 printf (" GLOBAL");
11467 val ^= DF_1_GLOBAL;
11468 }
11469 if (val & DF_1_GROUP)
11470 {
11471 printf (" GROUP");
11472 val ^= DF_1_GROUP;
11473 }
11474 if (val & DF_1_NODELETE)
11475 {
11476 printf (" NODELETE");
11477 val ^= DF_1_NODELETE;
11478 }
11479 if (val & DF_1_LOADFLTR)
11480 {
11481 printf (" LOADFLTR");
11482 val ^= DF_1_LOADFLTR;
11483 }
11484 if (val & DF_1_INITFIRST)
11485 {
11486 printf (" INITFIRST");
11487 val ^= DF_1_INITFIRST;
11488 }
11489 if (val & DF_1_NOOPEN)
11490 {
11491 printf (" NOOPEN");
11492 val ^= DF_1_NOOPEN;
11493 }
11494 if (val & DF_1_ORIGIN)
11495 {
11496 printf (" ORIGIN");
11497 val ^= DF_1_ORIGIN;
11498 }
11499 if (val & DF_1_DIRECT)
11500 {
11501 printf (" DIRECT");
11502 val ^= DF_1_DIRECT;
11503 }
11504 if (val & DF_1_TRANS)
11505 {
11506 printf (" TRANS");
11507 val ^= DF_1_TRANS;
11508 }
11509 if (val & DF_1_INTERPOSE)
11510 {
11511 printf (" INTERPOSE");
11512 val ^= DF_1_INTERPOSE;
11513 }
f7db6139 11514 if (val & DF_1_NODEFLIB)
dcefbbbd 11515 {
f7db6139
L
11516 printf (" NODEFLIB");
11517 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11518 }
11519 if (val & DF_1_NODUMP)
11520 {
11521 printf (" NODUMP");
11522 val ^= DF_1_NODUMP;
11523 }
34b60028 11524 if (val & DF_1_CONFALT)
dcefbbbd 11525 {
34b60028
L
11526 printf (" CONFALT");
11527 val ^= DF_1_CONFALT;
11528 }
11529 if (val & DF_1_ENDFILTEE)
11530 {
11531 printf (" ENDFILTEE");
11532 val ^= DF_1_ENDFILTEE;
11533 }
11534 if (val & DF_1_DISPRELDNE)
11535 {
11536 printf (" DISPRELDNE");
11537 val ^= DF_1_DISPRELDNE;
11538 }
11539 if (val & DF_1_DISPRELPND)
11540 {
11541 printf (" DISPRELPND");
11542 val ^= DF_1_DISPRELPND;
11543 }
11544 if (val & DF_1_NODIRECT)
11545 {
11546 printf (" NODIRECT");
11547 val ^= DF_1_NODIRECT;
11548 }
11549 if (val & DF_1_IGNMULDEF)
11550 {
11551 printf (" IGNMULDEF");
11552 val ^= DF_1_IGNMULDEF;
11553 }
11554 if (val & DF_1_NOKSYMS)
11555 {
11556 printf (" NOKSYMS");
11557 val ^= DF_1_NOKSYMS;
11558 }
11559 if (val & DF_1_NOHDR)
11560 {
11561 printf (" NOHDR");
11562 val ^= DF_1_NOHDR;
11563 }
11564 if (val & DF_1_EDITED)
11565 {
11566 printf (" EDITED");
11567 val ^= DF_1_EDITED;
11568 }
11569 if (val & DF_1_NORELOC)
11570 {
11571 printf (" NORELOC");
11572 val ^= DF_1_NORELOC;
11573 }
11574 if (val & DF_1_SYMINTPOSE)
11575 {
11576 printf (" SYMINTPOSE");
11577 val ^= DF_1_SYMINTPOSE;
11578 }
11579 if (val & DF_1_GLOBAUDIT)
11580 {
11581 printf (" GLOBAUDIT");
11582 val ^= DF_1_GLOBAUDIT;
11583 }
11584 if (val & DF_1_SINGLETON)
11585 {
11586 printf (" SINGLETON");
11587 val ^= DF_1_SINGLETON;
dcefbbbd 11588 }
5c383f02
RO
11589 if (val & DF_1_STUB)
11590 {
11591 printf (" STUB");
11592 val ^= DF_1_STUB;
11593 }
11594 if (val & DF_1_PIE)
11595 {
11596 printf (" PIE");
11597 val ^= DF_1_PIE;
11598 }
b1202ffa
L
11599 if (val & DF_1_KMOD)
11600 {
11601 printf (" KMOD");
11602 val ^= DF_1_KMOD;
11603 }
11604 if (val & DF_1_WEAKFILTER)
11605 {
11606 printf (" WEAKFILTER");
11607 val ^= DF_1_WEAKFILTER;
11608 }
11609 if (val & DF_1_NOCOMMON)
11610 {
11611 printf (" NOCOMMON");
11612 val ^= DF_1_NOCOMMON;
11613 }
252b5132
RH
11614 if (val != 0)
11615 printf (" %lx", val);
11616 puts ("");
11617 }
11618 }
11619 break;
11620
11621 case DT_PLTREL:
978c4450 11622 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11623 if (do_dynamic)
dda8d76d 11624 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11625 break;
11626
11627 case DT_NULL :
11628 case DT_NEEDED :
11629 case DT_PLTGOT :
11630 case DT_HASH :
11631 case DT_STRTAB :
11632 case DT_SYMTAB :
11633 case DT_RELA :
11634 case DT_INIT :
11635 case DT_FINI :
11636 case DT_SONAME :
11637 case DT_RPATH :
11638 case DT_SYMBOLIC:
11639 case DT_REL :
a7fd1186 11640 case DT_RELR :
252b5132
RH
11641 case DT_DEBUG :
11642 case DT_TEXTREL :
11643 case DT_JMPREL :
019148e4 11644 case DT_RUNPATH :
978c4450 11645 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11646
11647 if (do_dynamic)
11648 {
84714f86 11649 const char *name;
252b5132 11650
84714f86
AM
11651 if (valid_dynamic_name (filedata, entry->d_un.d_val))
11652 name = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11653 else
d79b3d50 11654 name = NULL;
252b5132
RH
11655
11656 if (name)
11657 {
11658 switch (entry->d_tag)
11659 {
11660 case DT_NEEDED:
11661 printf (_("Shared library: [%s]"), name);
11662
13acb58d
AM
11663 if (filedata->program_interpreter
11664 && streq (name, filedata->program_interpreter))
f7a99963 11665 printf (_(" program interpreter"));
252b5132
RH
11666 break;
11667
11668 case DT_SONAME:
f7a99963 11669 printf (_("Library soname: [%s]"), name);
252b5132
RH
11670 break;
11671
11672 case DT_RPATH:
f7a99963 11673 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11674 break;
11675
019148e4
L
11676 case DT_RUNPATH:
11677 printf (_("Library runpath: [%s]"), name);
11678 break;
11679
252b5132 11680 default:
f7a99963
NC
11681 print_vma (entry->d_un.d_val, PREFIX_HEX);
11682 break;
252b5132
RH
11683 }
11684 }
11685 else
f7a99963
NC
11686 print_vma (entry->d_un.d_val, PREFIX_HEX);
11687
11688 putchar ('\n');
252b5132
RH
11689 }
11690 break;
11691
11692 case DT_PLTRELSZ:
11693 case DT_RELASZ :
11694 case DT_STRSZ :
11695 case DT_RELSZ :
11696 case DT_RELAENT :
a7fd1186
FS
11697 case DT_RELRENT :
11698 case DT_RELRSZ :
252b5132
RH
11699 case DT_SYMENT :
11700 case DT_RELENT :
978c4450 11701 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11702 /* Fall through. */
252b5132
RH
11703 case DT_PLTPADSZ:
11704 case DT_MOVEENT :
11705 case DT_MOVESZ :
04d8355a 11706 case DT_PREINIT_ARRAYSZ:
252b5132
RH
11707 case DT_INIT_ARRAYSZ:
11708 case DT_FINI_ARRAYSZ:
047b2264
JJ
11709 case DT_GNU_CONFLICTSZ:
11710 case DT_GNU_LIBLISTSZ:
252b5132 11711 if (do_dynamic)
f7a99963
NC
11712 {
11713 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11714 printf (_(" (bytes)\n"));
f7a99963 11715 }
252b5132
RH
11716 break;
11717
11718 case DT_VERDEFNUM:
11719 case DT_VERNEEDNUM:
11720 case DT_RELACOUNT:
11721 case DT_RELCOUNT:
11722 if (do_dynamic)
f7a99963
NC
11723 {
11724 print_vma (entry->d_un.d_val, UNSIGNED);
11725 putchar ('\n');
11726 }
252b5132
RH
11727 break;
11728
11729 case DT_SYMINSZ:
11730 case DT_SYMINENT:
11731 case DT_SYMINFO:
11732 case DT_USED:
11733 case DT_INIT_ARRAY:
11734 case DT_FINI_ARRAY:
11735 if (do_dynamic)
11736 {
d79b3d50 11737 if (entry->d_tag == DT_USED
84714f86 11738 && valid_dynamic_name (filedata, entry->d_un.d_val))
252b5132 11739 {
84714f86
AM
11740 const char *name
11741 = get_dynamic_name (filedata, entry->d_un.d_val);
252b5132 11742
b34976b6 11743 if (*name)
252b5132
RH
11744 {
11745 printf (_("Not needed object: [%s]\n"), name);
11746 break;
11747 }
11748 }
103f02d3 11749
f7a99963
NC
11750 print_vma (entry->d_un.d_val, PREFIX_HEX);
11751 putchar ('\n');
252b5132
RH
11752 }
11753 break;
11754
11755 case DT_BIND_NOW:
11756 /* The value of this entry is ignored. */
35b1837e
AM
11757 if (do_dynamic)
11758 putchar ('\n');
252b5132 11759 break;
103f02d3 11760
047b2264
JJ
11761 case DT_GNU_PRELINKED:
11762 if (do_dynamic)
11763 {
2cf0635d 11764 struct tm * tmp;
91d6fa6a 11765 time_t atime = entry->d_un.d_val;
047b2264 11766
91d6fa6a 11767 tmp = gmtime (&atime);
071436c6
NC
11768 /* PR 17533 file: 041-1244816-0.004. */
11769 if (tmp == NULL)
5a2cbcf4
L
11770 printf (_("<corrupt time val: %lx"),
11771 (unsigned long) atime);
071436c6
NC
11772 else
11773 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11774 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11775 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11776
11777 }
11778 break;
11779
fdc90cb4 11780 case DT_GNU_HASH:
978c4450 11781 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11782 if (do_dynamic)
11783 {
11784 print_vma (entry->d_un.d_val, PREFIX_HEX);
11785 putchar ('\n');
11786 }
11787 break;
11788
a5da3dee
VDM
11789 case DT_GNU_FLAGS_1:
11790 if (do_dynamic)
11791 {
11792 printf (_("Flags:"));
11793 if (entry->d_un.d_val == 0)
11794 printf (_(" None\n"));
11795 else
11796 {
11797 unsigned long int val = entry->d_un.d_val;
11798
11799 if (val & DF_GNU_1_UNIQUE)
11800 {
11801 printf (" UNIQUE");
11802 val ^= DF_GNU_1_UNIQUE;
11803 }
11804 if (val != 0)
11805 printf (" %lx", val);
11806 puts ("");
11807 }
11808 }
11809 break;
11810
252b5132
RH
11811 default:
11812 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11813 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11814 = entry->d_un.d_val;
252b5132
RH
11815
11816 if (do_dynamic)
11817 {
dda8d76d 11818 switch (filedata->file_header.e_machine)
252b5132 11819 {
37c18eed
SD
11820 case EM_AARCH64:
11821 dynamic_section_aarch64_val (entry);
11822 break;
252b5132 11823 case EM_MIPS:
4fe85591 11824 case EM_MIPS_RS3_LE:
978c4450 11825 dynamic_section_mips_val (filedata, entry);
252b5132 11826 break;
103f02d3 11827 case EM_PARISC:
b2d38a17 11828 dynamic_section_parisc_val (entry);
103f02d3 11829 break;
ecc51f48 11830 case EM_IA_64:
b2d38a17 11831 dynamic_section_ia64_val (entry);
ecc51f48 11832 break;
252b5132 11833 default:
f7a99963
NC
11834 print_vma (entry->d_un.d_val, PREFIX_HEX);
11835 putchar ('\n');
252b5132
RH
11836 }
11837 }
11838 break;
11839 }
11840 }
11841
015dc7e1 11842 return true;
252b5132
RH
11843}
11844
11845static char *
d3ba0551 11846get_ver_flags (unsigned int flags)
252b5132 11847{
6d4f21f6 11848 static char buff[128];
252b5132
RH
11849
11850 buff[0] = 0;
11851
11852 if (flags == 0)
11853 return _("none");
11854
11855 if (flags & VER_FLG_BASE)
7bb1ad17 11856 strcat (buff, "BASE");
252b5132
RH
11857
11858 if (flags & VER_FLG_WEAK)
11859 {
11860 if (flags & VER_FLG_BASE)
7bb1ad17 11861 strcat (buff, " | ");
252b5132 11862
7bb1ad17 11863 strcat (buff, "WEAK");
252b5132
RH
11864 }
11865
44ec90b9
RO
11866 if (flags & VER_FLG_INFO)
11867 {
11868 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11869 strcat (buff, " | ");
44ec90b9 11870
7bb1ad17 11871 strcat (buff, "INFO");
44ec90b9
RO
11872 }
11873
11874 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11875 {
11876 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11877 strcat (buff, " | ");
11878
11879 strcat (buff, _("<unknown>"));
11880 }
252b5132
RH
11881
11882 return buff;
11883}
11884
11885/* Display the contents of the version sections. */
98fb390a 11886
015dc7e1 11887static bool
dda8d76d 11888process_version_sections (Filedata * filedata)
252b5132 11889{
2cf0635d 11890 Elf_Internal_Shdr * section;
b34976b6 11891 unsigned i;
015dc7e1 11892 bool found = false;
252b5132
RH
11893
11894 if (! do_version)
015dc7e1 11895 return true;
252b5132 11896
dda8d76d
NC
11897 for (i = 0, section = filedata->section_headers;
11898 i < filedata->file_header.e_shnum;
b34976b6 11899 i++, section++)
252b5132
RH
11900 {
11901 switch (section->sh_type)
11902 {
11903 case SHT_GNU_verdef:
11904 {
2cf0635d 11905 Elf_External_Verdef * edefs;
452bf675
AM
11906 unsigned long idx;
11907 unsigned long cnt;
2cf0635d 11908 char * endbuf;
252b5132 11909
015dc7e1 11910 found = true;
252b5132 11911
ca0e11aa
NC
11912 if (filedata->is_separate)
11913 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11914 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11915 section->sh_info),
11916 filedata->file_name,
11917 printable_section_name (filedata, section),
11918 section->sh_info);
11919 else
11920 printf (ngettext ("\nVersion definition section '%s' "
11921 "contains %u entry:\n",
11922 "\nVersion definition section '%s' "
11923 "contains %u entries:\n",
11924 section->sh_info),
11925 printable_section_name (filedata, section),
11926 section->sh_info);
047c3dbf 11927
ae9ac79e 11928 printf (_(" Addr: 0x"));
252b5132 11929 printf_vma (section->sh_addr);
233f82cf 11930 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11931 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11932 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11933
3f5e193b 11934 edefs = (Elf_External_Verdef *)
dda8d76d 11935 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11936 _("version definition section"));
a6e9f9df
AM
11937 if (!edefs)
11938 break;
59245841 11939 endbuf = (char *) edefs + section->sh_size;
252b5132 11940
1445030f 11941 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11942 {
2cf0635d
NC
11943 char * vstart;
11944 Elf_External_Verdef * edef;
b34976b6 11945 Elf_Internal_Verdef ent;
2cf0635d 11946 Elf_External_Verdaux * eaux;
b34976b6 11947 Elf_Internal_Verdaux aux;
452bf675 11948 unsigned long isum;
b34976b6 11949 int j;
103f02d3 11950
252b5132 11951 vstart = ((char *) edefs) + idx;
54806181
AM
11952 if (vstart + sizeof (*edef) > endbuf)
11953 break;
252b5132
RH
11954
11955 edef = (Elf_External_Verdef *) vstart;
11956
11957 ent.vd_version = BYTE_GET (edef->vd_version);
11958 ent.vd_flags = BYTE_GET (edef->vd_flags);
11959 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11960 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11961 ent.vd_hash = BYTE_GET (edef->vd_hash);
11962 ent.vd_aux = BYTE_GET (edef->vd_aux);
11963 ent.vd_next = BYTE_GET (edef->vd_next);
11964
452bf675 11965 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11966 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11967
11968 printf (_(" Index: %d Cnt: %d "),
11969 ent.vd_ndx, ent.vd_cnt);
11970
452bf675 11971 /* Check for overflow. */
1445030f 11972 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11973 break;
11974
252b5132
RH
11975 vstart += ent.vd_aux;
11976
1445030f
AM
11977 if (vstart + sizeof (*eaux) > endbuf)
11978 break;
252b5132
RH
11979 eaux = (Elf_External_Verdaux *) vstart;
11980
11981 aux.vda_name = BYTE_GET (eaux->vda_name);
11982 aux.vda_next = BYTE_GET (eaux->vda_next);
11983
84714f86 11984 if (valid_dynamic_name (filedata, aux.vda_name))
978c4450 11985 printf (_("Name: %s\n"),
84714f86 11986 get_dynamic_name (filedata, aux.vda_name));
252b5132
RH
11987 else
11988 printf (_("Name index: %ld\n"), aux.vda_name);
11989
11990 isum = idx + ent.vd_aux;
11991
b34976b6 11992 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11993 {
1445030f
AM
11994 if (aux.vda_next < sizeof (*eaux)
11995 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11996 {
11997 warn (_("Invalid vda_next field of %lx\n"),
11998 aux.vda_next);
11999 j = ent.vd_cnt;
12000 break;
12001 }
dd24e3da 12002 /* Check for overflow. */
7e26601c 12003 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
12004 break;
12005
252b5132
RH
12006 isum += aux.vda_next;
12007 vstart += aux.vda_next;
12008
54806181
AM
12009 if (vstart + sizeof (*eaux) > endbuf)
12010 break;
1445030f 12011 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
12012
12013 aux.vda_name = BYTE_GET (eaux->vda_name);
12014 aux.vda_next = BYTE_GET (eaux->vda_next);
12015
84714f86 12016 if (valid_dynamic_name (filedata, aux.vda_name))
452bf675 12017 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450 12018 isum, j,
84714f86 12019 get_dynamic_name (filedata, aux.vda_name));
252b5132 12020 else
452bf675 12021 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
12022 isum, j, aux.vda_name);
12023 }
dd24e3da 12024
54806181
AM
12025 if (j < ent.vd_cnt)
12026 printf (_(" Version def aux past end of section\n"));
252b5132 12027
c9f02c3e
MR
12028 /* PR 17531:
12029 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
12030 if (ent.vd_next < sizeof (*edef)
12031 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
12032 {
12033 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
12034 cnt = section->sh_info;
12035 break;
12036 }
452bf675 12037 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
12038 break;
12039
252b5132
RH
12040 idx += ent.vd_next;
12041 }
dd24e3da 12042
54806181
AM
12043 if (cnt < section->sh_info)
12044 printf (_(" Version definition past end of section\n"));
252b5132
RH
12045
12046 free (edefs);
12047 }
12048 break;
103f02d3 12049
252b5132
RH
12050 case SHT_GNU_verneed:
12051 {
2cf0635d 12052 Elf_External_Verneed * eneed;
452bf675
AM
12053 unsigned long idx;
12054 unsigned long cnt;
2cf0635d 12055 char * endbuf;
252b5132 12056
015dc7e1 12057 found = true;
252b5132 12058
ca0e11aa
NC
12059 if (filedata->is_separate)
12060 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
12061 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
12062 section->sh_info),
12063 filedata->file_name,
12064 printable_section_name (filedata, section),
12065 section->sh_info);
12066 else
12067 printf (ngettext ("\nVersion needs section '%s' "
12068 "contains %u entry:\n",
12069 "\nVersion needs section '%s' "
12070 "contains %u entries:\n",
12071 section->sh_info),
12072 printable_section_name (filedata, section),
12073 section->sh_info);
047c3dbf 12074
252b5132
RH
12075 printf (_(" Addr: 0x"));
12076 printf_vma (section->sh_addr);
72de5009 12077 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12078 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12079 printable_section_name_from_index (filedata, section->sh_link));
252b5132 12080
dda8d76d 12081 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
12082 section->sh_offset, 1,
12083 section->sh_size,
9cf03b7e 12084 _("Version Needs section"));
a6e9f9df
AM
12085 if (!eneed)
12086 break;
59245841 12087 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
12088
12089 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
12090 {
2cf0635d 12091 Elf_External_Verneed * entry;
b34976b6 12092 Elf_Internal_Verneed ent;
452bf675 12093 unsigned long isum;
b34976b6 12094 int j;
2cf0635d 12095 char * vstart;
252b5132
RH
12096
12097 vstart = ((char *) eneed) + idx;
54806181
AM
12098 if (vstart + sizeof (*entry) > endbuf)
12099 break;
252b5132
RH
12100
12101 entry = (Elf_External_Verneed *) vstart;
12102
12103 ent.vn_version = BYTE_GET (entry->vn_version);
12104 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
12105 ent.vn_file = BYTE_GET (entry->vn_file);
12106 ent.vn_aux = BYTE_GET (entry->vn_aux);
12107 ent.vn_next = BYTE_GET (entry->vn_next);
12108
452bf675 12109 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 12110
84714f86 12111 if (valid_dynamic_name (filedata, ent.vn_file))
978c4450 12112 printf (_(" File: %s"),
84714f86 12113 get_dynamic_name (filedata, ent.vn_file));
252b5132
RH
12114 else
12115 printf (_(" File: %lx"), ent.vn_file);
12116
12117 printf (_(" Cnt: %d\n"), ent.vn_cnt);
12118
dd24e3da 12119 /* Check for overflow. */
7e26601c 12120 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 12121 break;
252b5132
RH
12122 vstart += ent.vn_aux;
12123
12124 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
12125 {
2cf0635d 12126 Elf_External_Vernaux * eaux;
b34976b6 12127 Elf_Internal_Vernaux aux;
252b5132 12128
54806181
AM
12129 if (vstart + sizeof (*eaux) > endbuf)
12130 break;
252b5132
RH
12131 eaux = (Elf_External_Vernaux *) vstart;
12132
12133 aux.vna_hash = BYTE_GET (eaux->vna_hash);
12134 aux.vna_flags = BYTE_GET (eaux->vna_flags);
12135 aux.vna_other = BYTE_GET (eaux->vna_other);
12136 aux.vna_name = BYTE_GET (eaux->vna_name);
12137 aux.vna_next = BYTE_GET (eaux->vna_next);
12138
84714f86 12139 if (valid_dynamic_name (filedata, aux.vna_name))
452bf675 12140 printf (_(" %#06lx: Name: %s"),
84714f86 12141 isum, get_dynamic_name (filedata, aux.vna_name));
252b5132 12142 else
452bf675 12143 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
12144 isum, aux.vna_name);
12145
12146 printf (_(" Flags: %s Version: %d\n"),
12147 get_ver_flags (aux.vna_flags), aux.vna_other);
12148
1445030f
AM
12149 if (aux.vna_next < sizeof (*eaux)
12150 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
12151 {
12152 warn (_("Invalid vna_next field of %lx\n"),
12153 aux.vna_next);
12154 j = ent.vn_cnt;
12155 break;
12156 }
1445030f
AM
12157 /* Check for overflow. */
12158 if (aux.vna_next > (size_t) (endbuf - vstart))
12159 break;
252b5132
RH
12160 isum += aux.vna_next;
12161 vstart += aux.vna_next;
12162 }
9cf03b7e 12163
54806181 12164 if (j < ent.vn_cnt)
f9a6a8f0 12165 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 12166
1445030f
AM
12167 if (ent.vn_next < sizeof (*entry)
12168 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 12169 {
452bf675 12170 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
12171 cnt = section->sh_info;
12172 break;
12173 }
1445030f
AM
12174 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
12175 break;
252b5132
RH
12176 idx += ent.vn_next;
12177 }
9cf03b7e 12178
54806181 12179 if (cnt < section->sh_info)
9cf03b7e 12180 warn (_("Missing Version Needs information\n"));
103f02d3 12181
252b5132
RH
12182 free (eneed);
12183 }
12184 break;
12185
12186 case SHT_GNU_versym:
12187 {
2cf0635d 12188 Elf_Internal_Shdr * link_section;
8b73c356
NC
12189 size_t total;
12190 unsigned int cnt;
2cf0635d
NC
12191 unsigned char * edata;
12192 unsigned short * data;
12193 char * strtab;
12194 Elf_Internal_Sym * symbols;
12195 Elf_Internal_Shdr * string_sec;
ba5cdace 12196 unsigned long num_syms;
d3ba0551 12197 long off;
252b5132 12198
dda8d76d 12199 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12200 break;
12201
dda8d76d 12202 link_section = filedata->section_headers + section->sh_link;
08d8fa11 12203 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 12204
dda8d76d 12205 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
12206 break;
12207
015dc7e1 12208 found = true;
252b5132 12209
4de91c10 12210 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
12211 if (symbols == NULL)
12212 break;
252b5132 12213
dda8d76d 12214 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 12215
dda8d76d 12216 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
12217 string_sec->sh_size,
12218 _("version string table"));
a6e9f9df 12219 if (!strtab)
0429c154
MS
12220 {
12221 free (symbols);
12222 break;
12223 }
252b5132 12224
ca0e11aa
NC
12225 if (filedata->is_separate)
12226 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
12227 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
12228 total),
12229 filedata->file_name,
12230 printable_section_name (filedata, section),
12231 (unsigned long) total);
12232 else
12233 printf (ngettext ("\nVersion symbols section '%s' "
12234 "contains %lu entry:\n",
12235 "\nVersion symbols section '%s' "
12236 "contains %lu entries:\n",
12237 total),
12238 printable_section_name (filedata, section),
12239 (unsigned long) total);
252b5132 12240
ae9ac79e 12241 printf (_(" Addr: 0x"));
252b5132 12242 printf_vma (section->sh_addr);
72de5009 12243 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 12244 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 12245 printable_section_name (filedata, link_section));
252b5132 12246
dda8d76d 12247 off = offset_from_vma (filedata,
978c4450 12248 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 12249 total * sizeof (short));
95099889
AM
12250 edata = (unsigned char *) get_data (NULL, filedata, off,
12251 sizeof (short), total,
12252 _("version symbol data"));
a6e9f9df
AM
12253 if (!edata)
12254 {
12255 free (strtab);
0429c154 12256 free (symbols);
a6e9f9df
AM
12257 break;
12258 }
252b5132 12259
3f5e193b 12260 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
12261
12262 for (cnt = total; cnt --;)
b34976b6
AM
12263 data[cnt] = byte_get (edata + cnt * sizeof (short),
12264 sizeof (short));
252b5132
RH
12265
12266 free (edata);
12267
12268 for (cnt = 0; cnt < total; cnt += 4)
12269 {
12270 int j, nn;
ab273396
AM
12271 char *name;
12272 char *invalid = _("*invalid*");
252b5132
RH
12273
12274 printf (" %03x:", cnt);
12275
12276 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 12277 switch (data[cnt + j])
252b5132
RH
12278 {
12279 case 0:
12280 fputs (_(" 0 (*local*) "), stdout);
12281 break;
12282
12283 case 1:
12284 fputs (_(" 1 (*global*) "), stdout);
12285 break;
12286
12287 default:
c244d050
NC
12288 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
12289 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 12290
dd24e3da 12291 /* If this index value is greater than the size of the symbols
ba5cdace
NC
12292 array, break to avoid an out-of-bounds read. */
12293 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
12294 {
12295 warn (_("invalid index into symbol array\n"));
12296 break;
12297 }
12298
ab273396 12299 name = NULL;
978c4450 12300 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 12301 {
b34976b6
AM
12302 Elf_Internal_Verneed ivn;
12303 unsigned long offset;
252b5132 12304
d93f0186 12305 offset = offset_from_vma
978c4450
AM
12306 (filedata,
12307 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 12308 sizeof (Elf_External_Verneed));
252b5132 12309
b34976b6 12310 do
252b5132 12311 {
b34976b6
AM
12312 Elf_Internal_Vernaux ivna;
12313 Elf_External_Verneed evn;
12314 Elf_External_Vernaux evna;
12315 unsigned long a_off;
252b5132 12316
dda8d76d 12317 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
12318 _("version need")) == NULL)
12319 break;
0b4362b0 12320
252b5132
RH
12321 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12322 ivn.vn_next = BYTE_GET (evn.vn_next);
12323
12324 a_off = offset + ivn.vn_aux;
12325
12326 do
12327 {
dda8d76d 12328 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
12329 1, _("version need aux (2)")) == NULL)
12330 {
12331 ivna.vna_next = 0;
12332 ivna.vna_other = 0;
12333 }
12334 else
12335 {
12336 ivna.vna_next = BYTE_GET (evna.vna_next);
12337 ivna.vna_other = BYTE_GET (evna.vna_other);
12338 }
252b5132
RH
12339
12340 a_off += ivna.vna_next;
12341 }
b34976b6 12342 while (ivna.vna_other != data[cnt + j]
252b5132
RH
12343 && ivna.vna_next != 0);
12344
b34976b6 12345 if (ivna.vna_other == data[cnt + j])
252b5132
RH
12346 {
12347 ivna.vna_name = BYTE_GET (evna.vna_name);
12348
54806181 12349 if (ivna.vna_name >= string_sec->sh_size)
ab273396 12350 name = invalid;
54806181
AM
12351 else
12352 name = strtab + ivna.vna_name;
252b5132
RH
12353 break;
12354 }
12355
12356 offset += ivn.vn_next;
12357 }
12358 while (ivn.vn_next);
12359 }
00d93f34 12360
ab273396 12361 if (data[cnt + j] != 0x8001
978c4450 12362 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12363 {
b34976b6
AM
12364 Elf_Internal_Verdef ivd;
12365 Elf_External_Verdef evd;
12366 unsigned long offset;
252b5132 12367
d93f0186 12368 offset = offset_from_vma
978c4450
AM
12369 (filedata,
12370 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12371 sizeof evd);
252b5132
RH
12372
12373 do
12374 {
dda8d76d 12375 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12376 _("version def")) == NULL)
12377 {
12378 ivd.vd_next = 0;
948f632f 12379 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12380 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12381 break;
59245841
NC
12382 }
12383 else
12384 {
12385 ivd.vd_next = BYTE_GET (evd.vd_next);
12386 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12387 }
252b5132
RH
12388
12389 offset += ivd.vd_next;
12390 }
c244d050 12391 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12392 && ivd.vd_next != 0);
12393
c244d050 12394 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12395 {
b34976b6
AM
12396 Elf_External_Verdaux evda;
12397 Elf_Internal_Verdaux ivda;
252b5132
RH
12398
12399 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12400
dda8d76d 12401 if (get_data (&evda, filedata,
59245841
NC
12402 offset - ivd.vd_next + ivd.vd_aux,
12403 sizeof (evda), 1,
12404 _("version def aux")) == NULL)
12405 break;
252b5132
RH
12406
12407 ivda.vda_name = BYTE_GET (evda.vda_name);
12408
54806181 12409 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12410 name = invalid;
12411 else if (name != NULL && name != invalid)
12412 name = _("*both*");
54806181
AM
12413 else
12414 name = strtab + ivda.vda_name;
252b5132
RH
12415 }
12416 }
ab273396
AM
12417 if (name != NULL)
12418 nn += printf ("(%s%-*s",
12419 name,
12420 12 - (int) strlen (name),
12421 ")");
252b5132
RH
12422
12423 if (nn < 18)
12424 printf ("%*c", 18 - nn, ' ');
12425 }
12426
12427 putchar ('\n');
12428 }
12429
12430 free (data);
12431 free (strtab);
12432 free (symbols);
12433 }
12434 break;
103f02d3 12435
252b5132
RH
12436 default:
12437 break;
12438 }
12439 }
12440
12441 if (! found)
ca0e11aa
NC
12442 {
12443 if (filedata->is_separate)
12444 printf (_("\nNo version information found in linked file '%s'.\n"),
12445 filedata->file_name);
12446 else
12447 printf (_("\nNo version information found in this file.\n"));
12448 }
252b5132 12449
015dc7e1 12450 return true;
252b5132
RH
12451}
12452
d1133906 12453static const char *
dda8d76d 12454get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12455{
89246a0e 12456 static char buff[64];
252b5132
RH
12457
12458 switch (binding)
12459 {
b34976b6
AM
12460 case STB_LOCAL: return "LOCAL";
12461 case STB_GLOBAL: return "GLOBAL";
12462 case STB_WEAK: return "WEAK";
252b5132
RH
12463 default:
12464 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12465 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12466 binding);
252b5132 12467 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12468 {
12469 if (binding == STB_GNU_UNIQUE
df3a023b 12470 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12471 return "UNIQUE";
12472 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12473 }
252b5132 12474 else
e9e44622 12475 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12476 return buff;
12477 }
12478}
12479
d1133906 12480static const char *
dda8d76d 12481get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12482{
89246a0e 12483 static char buff[64];
252b5132
RH
12484
12485 switch (type)
12486 {
b34976b6
AM
12487 case STT_NOTYPE: return "NOTYPE";
12488 case STT_OBJECT: return "OBJECT";
12489 case STT_FUNC: return "FUNC";
12490 case STT_SECTION: return "SECTION";
12491 case STT_FILE: return "FILE";
12492 case STT_COMMON: return "COMMON";
12493 case STT_TLS: return "TLS";
15ab5209
DB
12494 case STT_RELC: return "RELC";
12495 case STT_SRELC: return "SRELC";
252b5132
RH
12496 default:
12497 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12498 {
dda8d76d 12499 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12500 return "THUMB_FUNC";
103f02d3 12501
dda8d76d 12502 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12503 return "REGISTER";
12504
dda8d76d 12505 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12506 return "PARISC_MILLI";
12507
e9e44622 12508 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12509 }
252b5132 12510 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12511 {
dda8d76d 12512 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12513 {
12514 if (type == STT_HP_OPAQUE)
12515 return "HP_OPAQUE";
12516 if (type == STT_HP_STUB)
12517 return "HP_STUB";
12518 }
12519
d8045f23 12520 if (type == STT_GNU_IFUNC
dda8d76d 12521 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12522 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12523 return "IFUNC";
12524
e9e44622 12525 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12526 }
252b5132 12527 else
e9e44622 12528 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12529 return buff;
12530 }
12531}
12532
d1133906 12533static const char *
d3ba0551 12534get_symbol_visibility (unsigned int visibility)
d1133906
NC
12535{
12536 switch (visibility)
12537 {
b34976b6
AM
12538 case STV_DEFAULT: return "DEFAULT";
12539 case STV_INTERNAL: return "INTERNAL";
12540 case STV_HIDDEN: return "HIDDEN";
d1133906 12541 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12542 default:
27a45f42 12543 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12544 return _("<unknown>");
d1133906
NC
12545 }
12546}
12547
2057d69d
CZ
12548static const char *
12549get_alpha_symbol_other (unsigned int other)
9abca702 12550{
2057d69d
CZ
12551 switch (other)
12552 {
12553 case STO_ALPHA_NOPV: return "NOPV";
12554 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12555 default:
27a45f42 12556 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12557 return _("<unknown>");
9abca702 12558 }
2057d69d
CZ
12559}
12560
fd85a6a1
NC
12561static const char *
12562get_solaris_symbol_visibility (unsigned int visibility)
12563{
12564 switch (visibility)
12565 {
12566 case 4: return "EXPORTED";
12567 case 5: return "SINGLETON";
12568 case 6: return "ELIMINATE";
12569 default: return get_symbol_visibility (visibility);
12570 }
12571}
12572
2301ed1c
SN
12573static const char *
12574get_aarch64_symbol_other (unsigned int other)
12575{
12576 static char buf[32];
12577
12578 if (other & STO_AARCH64_VARIANT_PCS)
12579 {
12580 other &= ~STO_AARCH64_VARIANT_PCS;
12581 if (other == 0)
12582 return "VARIANT_PCS";
12583 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12584 return buf;
12585 }
12586 return NULL;
12587}
12588
5e2b0d47
NC
12589static const char *
12590get_mips_symbol_other (unsigned int other)
12591{
12592 switch (other)
12593 {
32ec8896
NC
12594 case STO_OPTIONAL: return "OPTIONAL";
12595 case STO_MIPS_PLT: return "MIPS PLT";
12596 case STO_MIPS_PIC: return "MIPS PIC";
12597 case STO_MICROMIPS: return "MICROMIPS";
12598 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12599 case STO_MIPS16: return "MIPS16";
12600 default: return NULL;
5e2b0d47
NC
12601 }
12602}
12603
28f997cf 12604static const char *
dda8d76d 12605get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12606{
dda8d76d 12607 if (is_ia64_vms (filedata))
28f997cf
TG
12608 {
12609 static char res[32];
12610
12611 res[0] = 0;
12612
12613 /* Function types is for images and .STB files only. */
dda8d76d 12614 switch (filedata->file_header.e_type)
28f997cf
TG
12615 {
12616 case ET_DYN:
12617 case ET_EXEC:
12618 switch (VMS_ST_FUNC_TYPE (other))
12619 {
12620 case VMS_SFT_CODE_ADDR:
12621 strcat (res, " CA");
12622 break;
12623 case VMS_SFT_SYMV_IDX:
12624 strcat (res, " VEC");
12625 break;
12626 case VMS_SFT_FD:
12627 strcat (res, " FD");
12628 break;
12629 case VMS_SFT_RESERVE:
12630 strcat (res, " RSV");
12631 break;
12632 default:
bee0ee85
NC
12633 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12634 VMS_ST_FUNC_TYPE (other));
12635 strcat (res, " <unknown>");
12636 break;
28f997cf
TG
12637 }
12638 break;
12639 default:
12640 break;
12641 }
12642 switch (VMS_ST_LINKAGE (other))
12643 {
12644 case VMS_STL_IGNORE:
12645 strcat (res, " IGN");
12646 break;
12647 case VMS_STL_RESERVE:
12648 strcat (res, " RSV");
12649 break;
12650 case VMS_STL_STD:
12651 strcat (res, " STD");
12652 break;
12653 case VMS_STL_LNK:
12654 strcat (res, " LNK");
12655 break;
12656 default:
bee0ee85
NC
12657 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12658 VMS_ST_LINKAGE (other));
12659 strcat (res, " <unknown>");
12660 break;
28f997cf
TG
12661 }
12662
12663 if (res[0] != 0)
12664 return res + 1;
12665 else
12666 return res;
12667 }
12668 return NULL;
12669}
12670
6911b7dc
AM
12671static const char *
12672get_ppc64_symbol_other (unsigned int other)
12673{
14732552
AM
12674 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12675 return NULL;
12676
12677 other >>= STO_PPC64_LOCAL_BIT;
12678 if (other <= 6)
6911b7dc 12679 {
89246a0e 12680 static char buf[64];
14732552
AM
12681 if (other >= 2)
12682 other = ppc64_decode_local_entry (other);
12683 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12684 return buf;
12685 }
12686 return NULL;
12687}
12688
8155b853
NC
12689static const char *
12690get_riscv_symbol_other (unsigned int other)
12691{
12692 static char buf[32];
12693 buf[0] = 0;
12694
12695 if (other & STO_RISCV_VARIANT_CC)
12696 {
12697 strcat (buf, _(" VARIANT_CC"));
12698 other &= ~STO_RISCV_VARIANT_CC;
12699 }
12700
12701 if (other != 0)
12702 snprintf (buf, sizeof buf, " %x", other);
12703
12704
12705 if (buf[0] != 0)
12706 return buf + 1;
12707 else
12708 return buf;
12709}
12710
5e2b0d47 12711static const char *
dda8d76d 12712get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12713{
12714 const char * result = NULL;
89246a0e 12715 static char buff [64];
5e2b0d47
NC
12716
12717 if (other == 0)
12718 return "";
12719
dda8d76d 12720 switch (filedata->file_header.e_machine)
5e2b0d47 12721 {
2057d69d
CZ
12722 case EM_ALPHA:
12723 result = get_alpha_symbol_other (other);
12724 break;
2301ed1c
SN
12725 case EM_AARCH64:
12726 result = get_aarch64_symbol_other (other);
12727 break;
5e2b0d47
NC
12728 case EM_MIPS:
12729 result = get_mips_symbol_other (other);
28f997cf
TG
12730 break;
12731 case EM_IA_64:
dda8d76d 12732 result = get_ia64_symbol_other (filedata, other);
28f997cf 12733 break;
6911b7dc
AM
12734 case EM_PPC64:
12735 result = get_ppc64_symbol_other (other);
12736 break;
8155b853
NC
12737 case EM_RISCV:
12738 result = get_riscv_symbol_other (other);
12739 break;
5e2b0d47 12740 default:
fd85a6a1 12741 result = NULL;
5e2b0d47
NC
12742 break;
12743 }
12744
12745 if (result)
12746 return result;
12747
12748 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12749 return buff;
12750}
12751
d1133906 12752static const char *
dda8d76d 12753get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12754{
b34976b6 12755 static char buff[32];
5cf1065c 12756
252b5132
RH
12757 switch (type)
12758 {
b34976b6
AM
12759 case SHN_UNDEF: return "UND";
12760 case SHN_ABS: return "ABS";
12761 case SHN_COMMON: return "COM";
252b5132 12762 default:
9ce701e2 12763 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12764 && filedata->file_header.e_machine == EM_IA_64
12765 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12766 return "ANSI_COM";
12767 else if ((filedata->file_header.e_machine == EM_X86_64
12768 || filedata->file_header.e_machine == EM_L1OM
12769 || filedata->file_header.e_machine == EM_K1OM)
12770 && type == SHN_X86_64_LCOMMON)
12771 return "LARGE_COM";
12772 else if ((type == SHN_MIPS_SCOMMON
12773 && filedata->file_header.e_machine == EM_MIPS)
12774 || (type == SHN_TIC6X_SCOMMON
12775 && filedata->file_header.e_machine == EM_TI_C6000))
12776 return "SCOM";
12777 else if (type == SHN_MIPS_SUNDEFINED
12778 && filedata->file_header.e_machine == EM_MIPS)
12779 return "SUND";
12780 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12781 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12782 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12783 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12784 else if (type >= SHN_LORESERVE)
12785 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12786 else if (filedata->file_header.e_shnum != 0
12787 && type >= filedata->file_header.e_shnum)
12788 sprintf (buff, _("bad section index[%3d]"), type);
12789 else
12790 sprintf (buff, "%3d", type);
12791 break;
fd85a6a1
NC
12792 }
12793
10ca4b04 12794 return buff;
6bd1a22c
L
12795}
12796
bb4d2ac2 12797static const char *
dda8d76d 12798get_symbol_version_string (Filedata * filedata,
015dc7e1 12799 bool is_dynsym,
1449284b
NC
12800 const char * strtab,
12801 unsigned long int strtab_size,
12802 unsigned int si,
12803 Elf_Internal_Sym * psym,
12804 enum versioned_symbol_info * sym_info,
12805 unsigned short * vna_other)
bb4d2ac2 12806{
ab273396
AM
12807 unsigned char data[2];
12808 unsigned short vers_data;
12809 unsigned long offset;
7a815dd5 12810 unsigned short max_vd_ndx;
bb4d2ac2 12811
ab273396 12812 if (!is_dynsym
978c4450 12813 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12814 return NULL;
bb4d2ac2 12815
978c4450
AM
12816 offset = offset_from_vma (filedata,
12817 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12818 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12819
dda8d76d 12820 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12821 sizeof (data), 1, _("version data")) == NULL)
12822 return NULL;
12823
12824 vers_data = byte_get (data, 2);
bb4d2ac2 12825
1f6f5dba 12826 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12827 return NULL;
bb4d2ac2 12828
0b8b7609 12829 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12830 max_vd_ndx = 0;
12831
ab273396
AM
12832 /* Usually we'd only see verdef for defined symbols, and verneed for
12833 undefined symbols. However, symbols defined by the linker in
12834 .dynbss for variables copied from a shared library in order to
12835 avoid text relocations are defined yet have verneed. We could
12836 use a heuristic to detect the special case, for example, check
12837 for verneed first on symbols defined in SHT_NOBITS sections, but
12838 it is simpler and more reliable to just look for both verdef and
12839 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12840
ab273396
AM
12841 if (psym->st_shndx != SHN_UNDEF
12842 && vers_data != 0x8001
978c4450 12843 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12844 {
12845 Elf_Internal_Verdef ivd;
12846 Elf_Internal_Verdaux ivda;
12847 Elf_External_Verdaux evda;
12848 unsigned long off;
bb4d2ac2 12849
dda8d76d 12850 off = offset_from_vma (filedata,
978c4450 12851 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12852 sizeof (Elf_External_Verdef));
12853
12854 do
bb4d2ac2 12855 {
ab273396
AM
12856 Elf_External_Verdef evd;
12857
dda8d76d 12858 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12859 _("version def")) == NULL)
12860 {
12861 ivd.vd_ndx = 0;
12862 ivd.vd_aux = 0;
12863 ivd.vd_next = 0;
1f6f5dba 12864 ivd.vd_flags = 0;
ab273396
AM
12865 }
12866 else
bb4d2ac2 12867 {
ab273396
AM
12868 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12869 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12870 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12871 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12872 }
bb4d2ac2 12873
7a815dd5
L
12874 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12875 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12876
ab273396
AM
12877 off += ivd.vd_next;
12878 }
12879 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12880
ab273396
AM
12881 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12882 {
9abca702 12883 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12884 return NULL;
12885
ab273396
AM
12886 off -= ivd.vd_next;
12887 off += ivd.vd_aux;
bb4d2ac2 12888
dda8d76d 12889 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12890 _("version def aux")) != NULL)
12891 {
12892 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12893
ab273396 12894 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12895 return (ivda.vda_name < strtab_size
12896 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12897 }
12898 }
12899 }
bb4d2ac2 12900
978c4450 12901 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12902 {
12903 Elf_External_Verneed evn;
12904 Elf_Internal_Verneed ivn;
12905 Elf_Internal_Vernaux ivna;
bb4d2ac2 12906
dda8d76d 12907 offset = offset_from_vma (filedata,
978c4450 12908 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12909 sizeof evn);
12910 do
12911 {
12912 unsigned long vna_off;
bb4d2ac2 12913
dda8d76d 12914 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12915 _("version need")) == NULL)
12916 {
12917 ivna.vna_next = 0;
12918 ivna.vna_other = 0;
12919 ivna.vna_name = 0;
12920 break;
12921 }
bb4d2ac2 12922
ab273396
AM
12923 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12924 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12925
ab273396 12926 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12927
ab273396
AM
12928 do
12929 {
12930 Elf_External_Vernaux evna;
bb4d2ac2 12931
dda8d76d 12932 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12933 _("version need aux (3)")) == NULL)
bb4d2ac2 12934 {
ab273396
AM
12935 ivna.vna_next = 0;
12936 ivna.vna_other = 0;
12937 ivna.vna_name = 0;
bb4d2ac2 12938 }
bb4d2ac2 12939 else
bb4d2ac2 12940 {
ab273396
AM
12941 ivna.vna_other = BYTE_GET (evna.vna_other);
12942 ivna.vna_next = BYTE_GET (evna.vna_next);
12943 ivna.vna_name = BYTE_GET (evna.vna_name);
12944 }
bb4d2ac2 12945
ab273396
AM
12946 vna_off += ivna.vna_next;
12947 }
12948 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12949
ab273396
AM
12950 if (ivna.vna_other == vers_data)
12951 break;
bb4d2ac2 12952
ab273396
AM
12953 offset += ivn.vn_next;
12954 }
12955 while (ivn.vn_next != 0);
bb4d2ac2 12956
ab273396
AM
12957 if (ivna.vna_other == vers_data)
12958 {
12959 *sym_info = symbol_undefined;
12960 *vna_other = ivna.vna_other;
12961 return (ivna.vna_name < strtab_size
12962 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12963 }
7a815dd5
L
12964 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12965 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12966 return _("<corrupt>");
bb4d2ac2 12967 }
ab273396 12968 return NULL;
bb4d2ac2
L
12969}
12970
047c3dbf
NL
12971/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12972
12973static unsigned int
12974print_dynamic_symbol_size (bfd_vma vma, int base)
12975{
12976 switch (base)
12977 {
12978 case 8:
12979 return print_vma (vma, OCTAL_5);
12980
12981 case 10:
12982 return print_vma (vma, UNSIGNED_5);
12983
12984 case 16:
12985 return print_vma (vma, PREFIX_HEX_5);
12986
12987 case 0:
12988 default:
12989 return print_vma (vma, DEC_5);
12990 }
12991}
12992
10ca4b04
L
12993static void
12994print_dynamic_symbol (Filedata *filedata, unsigned long si,
12995 Elf_Internal_Sym *symtab,
12996 Elf_Internal_Shdr *section,
12997 char *strtab, size_t strtab_size)
252b5132 12998{
10ca4b04
L
12999 const char *version_string;
13000 enum versioned_symbol_info sym_info;
13001 unsigned short vna_other;
23356397
NC
13002 bool is_valid;
13003 const char * sstr;
10ca4b04 13004 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 13005
10ca4b04
L
13006 printf ("%6ld: ", si);
13007 print_vma (psym->st_value, LONG_HEX);
13008 putchar (' ');
047c3dbf 13009 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
13010 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
13011 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
13012 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
13013 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
13014 else
252b5132 13015 {
10ca4b04 13016 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 13017
10ca4b04
L
13018 printf (" %-7s", get_symbol_visibility (vis));
13019 /* Check to see if any other bits in the st_other field are set.
13020 Note - displaying this information disrupts the layout of the
13021 table being generated, but for the moment this case is very rare. */
13022 if (psym->st_other ^ vis)
13023 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 13024 }
10ca4b04 13025 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 13026
23356397
NC
13027 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
13028 && psym->st_shndx < filedata->file_header.e_shnum
b9af6379 13029 && filedata->section_headers != NULL
23356397
NC
13030 && psym->st_name == 0)
13031 {
84714f86
AM
13032 is_valid
13033 = section_name_valid (filedata,
13034 filedata->section_headers + psym->st_shndx);
23356397 13035 sstr = is_valid ?
84714f86
AM
13036 section_name_print (filedata,
13037 filedata->section_headers + psym->st_shndx)
23356397
NC
13038 : _("<corrupt>");
13039 }
13040 else
13041 {
84714f86 13042 is_valid = valid_symbol_name (strtab, strtab_size, psym->st_name);
23356397
NC
13043 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
13044 }
10ca4b04
L
13045
13046 version_string
13047 = get_symbol_version_string (filedata,
13048 (section == NULL
13049 || section->sh_type == SHT_DYNSYM),
13050 strtab, strtab_size, si,
13051 psym, &sym_info, &vna_other);
b9e920ec 13052
0942c7ab
NC
13053 int len_avail = 21;
13054 if (! do_wide && version_string != NULL)
13055 {
ddb43bab 13056 char buffer[16];
0942c7ab 13057
ddb43bab 13058 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
13059
13060 if (sym_info == symbol_undefined)
13061 len_avail -= sprintf (buffer," (%d)", vna_other);
13062 else if (sym_info != symbol_hidden)
13063 len_avail -= 1;
13064 }
13065
13066 print_symbol (len_avail, sstr);
b9e920ec 13067
10ca4b04
L
13068 if (version_string)
13069 {
13070 if (sym_info == symbol_undefined)
13071 printf ("@%s (%d)", version_string, vna_other);
f7a99963 13072 else
10ca4b04
L
13073 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
13074 version_string);
13075 }
6bd1a22c 13076
10ca4b04 13077 putchar ('\n');
6bd1a22c 13078
10ca4b04
L
13079 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
13080 && section != NULL
13081 && si >= section->sh_info
13082 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
13083 && filedata->file_header.e_machine != EM_MIPS
13084 /* Solaris binaries have been found to violate this requirement as
13085 well. Not sure if this is a bug or an ABI requirement. */
13086 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
13087 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
13088 si, printable_section_name (filedata, section), section->sh_info);
13089}
f16a9783 13090
0f03783c
NC
13091static const char *
13092get_lto_kind (unsigned int kind)
13093{
13094 switch (kind)
13095 {
13096 case 0: return "DEF";
13097 case 1: return "WEAKDEF";
13098 case 2: return "UNDEF";
13099 case 3: return "WEAKUNDEF";
13100 case 4: return "COMMON";
13101 default:
13102 break;
13103 }
13104
13105 static char buffer[30];
13106 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
13107 sprintf (buffer, "<unknown: %u>", kind);
13108 return buffer;
13109}
13110
13111static const char *
13112get_lto_visibility (unsigned int visibility)
13113{
13114 switch (visibility)
13115 {
13116 case 0: return "DEFAULT";
13117 case 1: return "PROTECTED";
13118 case 2: return "INTERNAL";
13119 case 3: return "HIDDEN";
13120 default:
13121 break;
13122 }
13123
13124 static char buffer[30];
13125 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
13126 sprintf (buffer, "<unknown: %u>", visibility);
13127 return buffer;
13128}
13129
13130static const char *
13131get_lto_sym_type (unsigned int sym_type)
13132{
13133 switch (sym_type)
13134 {
13135 case 0: return "UNKNOWN";
13136 case 1: return "FUNCTION";
13137 case 2: return "VARIABLE";
13138 default:
13139 break;
13140 }
13141
13142 static char buffer[30];
13143 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
13144 sprintf (buffer, "<unknown: %u>", sym_type);
13145 return buffer;
13146}
13147
13148/* Display an LTO format symbol table.
13149 FIXME: The format of LTO symbol tables is not formalized.
13150 So this code could need changing in the future. */
13151
015dc7e1 13152static bool
0f03783c
NC
13153display_lto_symtab (Filedata * filedata,
13154 Elf_Internal_Shdr * section)
13155{
13156 if (section->sh_size == 0)
13157 {
ca0e11aa
NC
13158 if (filedata->is_separate)
13159 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
13160 printable_section_name (filedata, section),
13161 filedata->file_name);
13162 else
13163 printf (_("\nLTO Symbol table '%s' is empty!\n"),
13164 printable_section_name (filedata, section));
047c3dbf 13165
015dc7e1 13166 return true;
0f03783c
NC
13167 }
13168
13169 if (section->sh_size > filedata->file_size)
13170 {
13171 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
13172 printable_section_name (filedata, section),
13173 (unsigned long) section->sh_size);
015dc7e1 13174 return false;
0f03783c
NC
13175 }
13176
13177 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
13178 section->sh_size, 1, _("LTO symbols"));
13179 if (alloced_data == NULL)
015dc7e1 13180 return false;
0f03783c
NC
13181
13182 /* Look for extended data for the symbol table. */
13183 Elf_Internal_Shdr * ext;
13184 void * ext_data_orig = NULL;
13185 char * ext_data = NULL;
13186 char * ext_data_end = NULL;
13187 char * ext_name = NULL;
13188
13189 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
84714f86
AM
13190 (section_name (filedata, section)
13191 + sizeof (".gnu.lto_.symtab.") - 1)) > 0
0f03783c
NC
13192 && ext_name != NULL /* Paranoia. */
13193 && (ext = find_section (filedata, ext_name)) != NULL)
13194 {
13195 if (ext->sh_size < 3)
13196 error (_("LTO Symbol extension table '%s' is empty!\n"),
13197 printable_section_name (filedata, ext));
13198 else
13199 {
13200 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
13201 ext->sh_size, 1,
13202 _("LTO ext symbol data"));
13203 if (ext_data != NULL)
13204 {
13205 ext_data_end = ext_data + ext->sh_size;
13206 if (* ext_data++ != 1)
13207 error (_("Unexpected version number in symbol extension table\n"));
13208 }
13209 }
13210 }
b9e920ec 13211
0f03783c
NC
13212 const unsigned char * data = (const unsigned char *) alloced_data;
13213 const unsigned char * end = data + section->sh_size;
13214
ca0e11aa
NC
13215 if (filedata->is_separate)
13216 printf (_("\nIn linked file '%s': "), filedata->file_name);
13217 else
13218 printf ("\n");
13219
0f03783c
NC
13220 if (ext_data_orig != NULL)
13221 {
13222 if (do_wide)
ca0e11aa 13223 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
13224 printable_section_name (filedata, section),
13225 printable_section_name (filedata, ext));
13226 else
13227 {
ca0e11aa 13228 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
13229 printable_section_name (filedata, section));
13230 printf (_(" and extension table '%s' contain:\n"),
13231 printable_section_name (filedata, ext));
13232 }
13233 }
13234 else
ca0e11aa 13235 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 13236 printable_section_name (filedata, section));
b9e920ec 13237
0f03783c 13238 /* FIXME: Add a wide version. */
b9e920ec 13239 if (ext_data_orig != NULL)
0f03783c
NC
13240 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
13241 else
13242 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
13243
13244 /* FIXME: We do not handle style prefixes. */
13245
13246 while (data < end)
13247 {
13248 const unsigned char * sym_name = data;
13249 data += strnlen ((const char *) sym_name, end - data) + 1;
13250 if (data >= end)
13251 goto fail;
13252
13253 const unsigned char * comdat_key = data;
13254 data += strnlen ((const char *) comdat_key, end - data) + 1;
13255 if (data >= end)
13256 goto fail;
13257
13258 if (data + 2 + 8 + 4 > end)
13259 goto fail;
13260
13261 unsigned int kind = *data++;
13262 unsigned int visibility = *data++;
13263
13264 elf_vma size = byte_get (data, 8);
13265 data += 8;
13266
13267 elf_vma slot = byte_get (data, 4);
13268 data += 4;
13269
13270 if (ext_data != NULL)
13271 {
13272 if (ext_data < (ext_data_end - 1))
13273 {
13274 unsigned int sym_type = * ext_data ++;
13275 unsigned int sec_kind = * ext_data ++;
13276
13277 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
13278 * comdat_key == 0 ? "-" : (char *) comdat_key,
13279 get_lto_kind (kind),
13280 get_lto_visibility (visibility),
13281 (long) size,
13282 (long) slot,
13283 get_lto_sym_type (sym_type),
13284 (long) sec_kind);
13285 print_symbol (6, (const char *) sym_name);
13286 }
13287 else
13288 {
13289 error (_("Ran out of LTO symbol extension data\n"));
13290 ext_data = NULL;
13291 /* FIXME: return FAIL result ? */
13292 }
13293 }
13294 else
13295 {
13296 printf (" %10s %10s %11s %08lx %08lx _",
13297 * comdat_key == 0 ? "-" : (char *) comdat_key,
13298 get_lto_kind (kind),
13299 get_lto_visibility (visibility),
13300 (long) size,
13301 (long) slot);
13302 print_symbol (21, (const char *) sym_name);
13303 }
13304 putchar ('\n');
13305 }
13306
13307 if (ext_data != NULL && ext_data < ext_data_end)
13308 {
13309 error (_("Data remains in the LTO symbol extension table\n"));
13310 goto fail;
13311 }
13312
13313 free (alloced_data);
13314 free (ext_data_orig);
13315 free (ext_name);
015dc7e1 13316 return true;
b9e920ec 13317
0f03783c
NC
13318 fail:
13319 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
13320 free (alloced_data);
13321 free (ext_data_orig);
13322 free (ext_name);
015dc7e1 13323 return false;
0f03783c
NC
13324}
13325
13326/* Display LTO symbol tables. */
13327
015dc7e1 13328static bool
0f03783c
NC
13329process_lto_symbol_tables (Filedata * filedata)
13330{
13331 Elf_Internal_Shdr * section;
13332 unsigned int i;
015dc7e1 13333 bool res = true;
0f03783c
NC
13334
13335 if (!do_lto_syms)
015dc7e1 13336 return true;
0f03783c
NC
13337
13338 if (filedata->section_headers == NULL)
015dc7e1 13339 return true;
0f03783c
NC
13340
13341 for (i = 0, section = filedata->section_headers;
13342 i < filedata->file_header.e_shnum;
13343 i++, section++)
84714f86
AM
13344 if (section_name_valid (filedata, section)
13345 && startswith (section_name (filedata, section), ".gnu.lto_.symtab."))
0f03783c
NC
13346 res &= display_lto_symtab (filedata, section);
13347
b9e920ec 13348 return res;
0f03783c
NC
13349}
13350
10ca4b04 13351/* Dump the symbol table. */
0f03783c 13352
015dc7e1 13353static bool
10ca4b04
L
13354process_symbol_table (Filedata * filedata)
13355{
13356 Elf_Internal_Shdr * section;
f16a9783 13357
10ca4b04 13358 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 13359 return true;
6bd1a22c 13360
978c4450 13361 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
13362 && do_syms
13363 && do_using_dynamic
978c4450
AM
13364 && filedata->dynamic_strings != NULL
13365 && filedata->dynamic_symbols != NULL)
6bd1a22c 13366 {
10ca4b04 13367 unsigned long si;
6bd1a22c 13368
ca0e11aa
NC
13369 if (filedata->is_separate)
13370 {
13371 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
13372 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
13373 filedata->num_dynamic_syms),
13374 filedata->file_name,
13375 filedata->num_dynamic_syms);
13376 }
13377 else
13378 {
13379 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
13380 "\nSymbol table for image contains %lu entries:\n",
13381 filedata->num_dynamic_syms),
13382 filedata->num_dynamic_syms);
13383 }
10ca4b04
L
13384 if (is_32bit_elf)
13385 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
13386 else
13387 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 13388
978c4450
AM
13389 for (si = 0; si < filedata->num_dynamic_syms; si++)
13390 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
13391 filedata->dynamic_strings,
13392 filedata->dynamic_strings_length);
252b5132 13393 }
8b73c356 13394 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13395 && filedata->section_headers != NULL)
252b5132 13396 {
b34976b6 13397 unsigned int i;
252b5132 13398
dda8d76d
NC
13399 for (i = 0, section = filedata->section_headers;
13400 i < filedata->file_header.e_shnum;
252b5132
RH
13401 i++, section++)
13402 {
2cf0635d 13403 char * strtab = NULL;
c256ffe7 13404 unsigned long int strtab_size = 0;
2cf0635d 13405 Elf_Internal_Sym * symtab;
ef3df110 13406 unsigned long si, num_syms;
252b5132 13407
2c610e4b
L
13408 if ((section->sh_type != SHT_SYMTAB
13409 && section->sh_type != SHT_DYNSYM)
13410 || (!do_syms
13411 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13412 continue;
13413
dd24e3da
NC
13414 if (section->sh_entsize == 0)
13415 {
13416 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13417 printable_section_name (filedata, section));
dd24e3da
NC
13418 continue;
13419 }
13420
d3a49aa8 13421 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13422
13423 if (filedata->is_separate)
13424 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13425 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13426 num_syms),
13427 filedata->file_name,
13428 printable_section_name (filedata, section),
13429 num_syms);
13430 else
13431 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13432 "\nSymbol table '%s' contains %lu entries:\n",
13433 num_syms),
13434 printable_section_name (filedata, section),
13435 num_syms);
dd24e3da 13436
f7a99963 13437 if (is_32bit_elf)
ca47b30c 13438 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13439 else
ca47b30c 13440 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13441
4de91c10 13442 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13443 if (symtab == NULL)
13444 continue;
13445
dda8d76d 13446 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13447 {
dda8d76d
NC
13448 strtab = filedata->string_table;
13449 strtab_size = filedata->string_table_length;
c256ffe7 13450 }
dda8d76d 13451 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13452 {
2cf0635d 13453 Elf_Internal_Shdr * string_sec;
252b5132 13454
dda8d76d 13455 string_sec = filedata->section_headers + section->sh_link;
252b5132 13456
dda8d76d 13457 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13458 1, string_sec->sh_size,
13459 _("string table"));
c256ffe7 13460 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13461 }
13462
10ca4b04
L
13463 for (si = 0; si < num_syms; si++)
13464 print_dynamic_symbol (filedata, si, symtab, section,
13465 strtab, strtab_size);
252b5132
RH
13466
13467 free (symtab);
dda8d76d 13468 if (strtab != filedata->string_table)
252b5132
RH
13469 free (strtab);
13470 }
13471 }
13472 else if (do_syms)
13473 printf
13474 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13475
978c4450 13476 if (do_histogram && filedata->buckets != NULL)
252b5132 13477 {
2cf0635d
NC
13478 unsigned long * lengths;
13479 unsigned long * counts;
66543521
AM
13480 unsigned long hn;
13481 bfd_vma si;
13482 unsigned long maxlength = 0;
13483 unsigned long nzero_counts = 0;
13484 unsigned long nsyms = 0;
6bd6a03d 13485 char *visited;
252b5132 13486
d3a49aa8
AM
13487 printf (ngettext ("\nHistogram for bucket list length "
13488 "(total of %lu bucket):\n",
13489 "\nHistogram for bucket list length "
13490 "(total of %lu buckets):\n",
978c4450
AM
13491 (unsigned long) filedata->nbuckets),
13492 (unsigned long) filedata->nbuckets);
252b5132 13493
978c4450
AM
13494 lengths = (unsigned long *) calloc (filedata->nbuckets,
13495 sizeof (*lengths));
252b5132
RH
13496 if (lengths == NULL)
13497 {
8b73c356 13498 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13499 goto err_out;
252b5132 13500 }
978c4450
AM
13501 visited = xcmalloc (filedata->nchains, 1);
13502 memset (visited, 0, filedata->nchains);
8b73c356
NC
13503
13504 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13505 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13506 {
978c4450 13507 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13508 {
b34976b6 13509 ++nsyms;
252b5132 13510 if (maxlength < ++lengths[hn])
b34976b6 13511 ++maxlength;
978c4450 13512 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13513 {
13514 error (_("histogram chain is corrupt\n"));
13515 break;
13516 }
13517 visited[si] = 1;
252b5132
RH
13518 }
13519 }
6bd6a03d 13520 free (visited);
252b5132 13521
3f5e193b 13522 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13523 if (counts == NULL)
13524 {
b2e951ec 13525 free (lengths);
8b73c356 13526 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13527 goto err_out;
252b5132
RH
13528 }
13529
978c4450 13530 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13531 ++counts[lengths[hn]];
252b5132 13532
978c4450 13533 if (filedata->nbuckets > 0)
252b5132 13534 {
66543521
AM
13535 unsigned long i;
13536 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13537 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13538 for (i = 1; i <= maxlength; ++i)
103f02d3 13539 {
66543521
AM
13540 nzero_counts += counts[i] * i;
13541 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13542 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13543 (nzero_counts * 100.0) / nsyms);
13544 }
252b5132
RH
13545 }
13546
13547 free (counts);
13548 free (lengths);
13549 }
13550
978c4450
AM
13551 free (filedata->buckets);
13552 filedata->buckets = NULL;
13553 filedata->nbuckets = 0;
13554 free (filedata->chains);
13555 filedata->chains = NULL;
252b5132 13556
978c4450 13557 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13558 {
2cf0635d
NC
13559 unsigned long * lengths;
13560 unsigned long * counts;
fdc90cb4
JJ
13561 unsigned long hn;
13562 unsigned long maxlength = 0;
13563 unsigned long nzero_counts = 0;
13564 unsigned long nsyms = 0;
fdc90cb4 13565
f16a9783 13566 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13567 "(total of %lu bucket):\n",
f16a9783 13568 "\nHistogram for `%s' bucket list length "
d3a49aa8 13569 "(total of %lu buckets):\n",
978c4450
AM
13570 (unsigned long) filedata->ngnubuckets),
13571 GNU_HASH_SECTION_NAME (filedata),
13572 (unsigned long) filedata->ngnubuckets);
8b73c356 13573
978c4450
AM
13574 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13575 sizeof (*lengths));
fdc90cb4
JJ
13576 if (lengths == NULL)
13577 {
8b73c356 13578 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13579 goto err_out;
fdc90cb4
JJ
13580 }
13581
fdc90cb4
JJ
13582 printf (_(" Length Number %% of total Coverage\n"));
13583
978c4450
AM
13584 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13585 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13586 {
13587 bfd_vma off, length = 1;
13588
978c4450 13589 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13590 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13591 off < filedata->ngnuchains
13592 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13593 ++off)
fdc90cb4
JJ
13594 ++length;
13595 lengths[hn] = length;
13596 if (length > maxlength)
13597 maxlength = length;
13598 nsyms += length;
13599 }
13600
3f5e193b 13601 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13602 if (counts == NULL)
13603 {
b2e951ec 13604 free (lengths);
8b73c356 13605 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13606 goto err_out;
fdc90cb4
JJ
13607 }
13608
978c4450 13609 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13610 ++counts[lengths[hn]];
13611
978c4450 13612 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13613 {
13614 unsigned long j;
13615 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13616 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13617 for (j = 1; j <= maxlength; ++j)
13618 {
13619 nzero_counts += counts[j] * j;
13620 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13621 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13622 (nzero_counts * 100.0) / nsyms);
13623 }
13624 }
13625
13626 free (counts);
13627 free (lengths);
fdc90cb4 13628 }
978c4450
AM
13629 free (filedata->gnubuckets);
13630 filedata->gnubuckets = NULL;
13631 filedata->ngnubuckets = 0;
13632 free (filedata->gnuchains);
13633 filedata->gnuchains = NULL;
13634 filedata->ngnuchains = 0;
13635 free (filedata->mipsxlat);
13636 filedata->mipsxlat = NULL;
015dc7e1 13637 return true;
fd486f32
AM
13638
13639 err_out:
978c4450
AM
13640 free (filedata->gnubuckets);
13641 filedata->gnubuckets = NULL;
13642 filedata->ngnubuckets = 0;
13643 free (filedata->gnuchains);
13644 filedata->gnuchains = NULL;
13645 filedata->ngnuchains = 0;
13646 free (filedata->mipsxlat);
13647 filedata->mipsxlat = NULL;
13648 free (filedata->buckets);
13649 filedata->buckets = NULL;
13650 filedata->nbuckets = 0;
13651 free (filedata->chains);
13652 filedata->chains = NULL;
015dc7e1 13653 return false;
252b5132
RH
13654}
13655
015dc7e1 13656static bool
ca0e11aa 13657process_syminfo (Filedata * filedata)
252b5132 13658{
b4c96d0d 13659 unsigned int i;
252b5132 13660
978c4450 13661 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13662 || !do_dynamic)
13663 /* No syminfo, this is ok. */
015dc7e1 13664 return true;
252b5132
RH
13665
13666 /* There better should be a dynamic symbol section. */
978c4450 13667 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13668 return false;
252b5132 13669
ca0e11aa
NC
13670 if (filedata->is_separate)
13671 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13672 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13673 filedata->dynamic_syminfo_nent),
13674 filedata->file_name,
13675 filedata->dynamic_syminfo_offset,
13676 filedata->dynamic_syminfo_nent);
13677 else
d3a49aa8
AM
13678 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13679 "contains %d entry:\n",
13680 "\nDynamic info segment at offset 0x%lx "
13681 "contains %d entries:\n",
978c4450 13682 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13683 filedata->dynamic_syminfo_offset,
13684 filedata->dynamic_syminfo_nent);
252b5132
RH
13685
13686 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13687 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13688 {
978c4450 13689 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13690
31104126 13691 printf ("%4d: ", i);
978c4450 13692 if (i >= filedata->num_dynamic_syms)
4082ef84 13693 printf (_("<corrupt index>"));
84714f86
AM
13694 else if (valid_dynamic_name (filedata, filedata->dynamic_symbols[i].st_name))
13695 print_symbol (30, get_dynamic_name (filedata,
978c4450 13696 filedata->dynamic_symbols[i].st_name));
d79b3d50 13697 else
978c4450 13698 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13699 putchar (' ');
252b5132 13700
978c4450 13701 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13702 {
13703 case SYMINFO_BT_SELF:
13704 fputs ("SELF ", stdout);
13705 break;
13706 case SYMINFO_BT_PARENT:
13707 fputs ("PARENT ", stdout);
13708 break;
13709 default:
978c4450
AM
13710 if (filedata->dynamic_syminfo[i].si_boundto > 0
13711 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
84714f86 13712 && valid_dynamic_name (filedata,
978c4450 13713 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13714 {
84714f86 13715 print_symbol (10, get_dynamic_name (filedata,
978c4450 13716 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13717 putchar (' ' );
13718 }
252b5132 13719 else
978c4450 13720 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13721 break;
13722 }
13723
13724 if (flags & SYMINFO_FLG_DIRECT)
13725 printf (" DIRECT");
13726 if (flags & SYMINFO_FLG_PASSTHRU)
13727 printf (" PASSTHRU");
13728 if (flags & SYMINFO_FLG_COPY)
13729 printf (" COPY");
13730 if (flags & SYMINFO_FLG_LAZYLOAD)
13731 printf (" LAZYLOAD");
13732
13733 puts ("");
13734 }
13735
015dc7e1 13736 return true;
252b5132
RH
13737}
13738
75802ccb
CE
13739/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13740 is contained by the region START .. END. The types of ADDR, START
13741 and END should all be the same. Note both ADDR + NELEM and END
13742 point to just beyond the end of the regions that are being tested. */
13743#define IN_RANGE(START,END,ADDR,NELEM) \
13744 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13745
cf13d699
NC
13746/* Check to see if the given reloc needs to be handled in a target specific
13747 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13748 FALSE.
13749
13750 If called with reloc == NULL, then this is a signal that reloc processing
13751 for the current section has finished, and any saved state should be
13752 discarded. */
09c11c86 13753
015dc7e1 13754static bool
dda8d76d
NC
13755target_specific_reloc_handling (Filedata * filedata,
13756 Elf_Internal_Rela * reloc,
13757 unsigned char * start,
13758 unsigned char * end,
13759 Elf_Internal_Sym * symtab,
13760 unsigned long num_syms)
252b5132 13761{
f84ce13b
NC
13762 unsigned int reloc_type = 0;
13763 unsigned long sym_index = 0;
13764
13765 if (reloc)
13766 {
dda8d76d 13767 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13768 sym_index = get_reloc_symindex (reloc->r_info);
13769 }
252b5132 13770
dda8d76d 13771 switch (filedata->file_header.e_machine)
252b5132 13772 {
13761a11
NC
13773 case EM_MSP430:
13774 case EM_MSP430_OLD:
13775 {
13776 static Elf_Internal_Sym * saved_sym = NULL;
13777
f84ce13b
NC
13778 if (reloc == NULL)
13779 {
13780 saved_sym = NULL;
015dc7e1 13781 return true;
f84ce13b
NC
13782 }
13783
13761a11
NC
13784 switch (reloc_type)
13785 {
13786 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13787 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13788 if (uses_msp430x_relocs (filedata))
13761a11 13789 break;
1a0670f3 13790 /* Fall through. */
13761a11 13791 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13792 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13793 /* PR 21139. */
13794 if (sym_index >= num_syms)
13795 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13796 sym_index);
13797 else
13798 saved_sym = symtab + sym_index;
015dc7e1 13799 return true;
13761a11
NC
13800
13801 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13802 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13803 goto handle_sym_diff;
0b4362b0 13804
13761a11
NC
13805 case 5: /* R_MSP430_16_BYTE */
13806 case 9: /* R_MSP430_8 */
7d81bc93 13807 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13808 if (uses_msp430x_relocs (filedata))
13761a11
NC
13809 break;
13810 goto handle_sym_diff;
13811
13812 case 2: /* R_MSP430_ABS16 */
13813 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13814 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13815 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13816 break;
13817 goto handle_sym_diff;
0b4362b0 13818
13761a11
NC
13819 handle_sym_diff:
13820 if (saved_sym != NULL)
13821 {
13822 bfd_vma value;
5a805384 13823 unsigned int reloc_size = 0;
7d81bc93
JL
13824 int leb_ret = 0;
13825 switch (reloc_type)
13826 {
13827 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13828 reloc_size = 4;
13829 break;
13830 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13831 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13832 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13833 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13834 &reloc_size, &leb_ret);
7d81bc93
JL
13835 break;
13836 default:
13837 reloc_size = 2;
13838 break;
13839 }
13761a11 13840
5a805384 13841 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13842 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13843 "ULEB128 value\n"),
13844 (long) reloc->r_offset);
13845 else if (sym_index >= num_syms)
f84ce13b
NC
13846 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13847 sym_index);
03f7786e 13848 else
f84ce13b
NC
13849 {
13850 value = reloc->r_addend + (symtab[sym_index].st_value
13851 - saved_sym->st_value);
13852
b32e566b 13853 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13854 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13855 else
13856 /* PR 21137 */
13857 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13858 (long) reloc->r_offset);
f84ce13b 13859 }
13761a11
NC
13860
13861 saved_sym = NULL;
015dc7e1 13862 return true;
13761a11
NC
13863 }
13864 break;
13865
13866 default:
13867 if (saved_sym != NULL)
071436c6 13868 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13869 break;
13870 }
13871 break;
13872 }
13873
cf13d699
NC
13874 case EM_MN10300:
13875 case EM_CYGNUS_MN10300:
13876 {
13877 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13878
f84ce13b
NC
13879 if (reloc == NULL)
13880 {
13881 saved_sym = NULL;
015dc7e1 13882 return true;
f84ce13b
NC
13883 }
13884
cf13d699
NC
13885 switch (reloc_type)
13886 {
13887 case 34: /* R_MN10300_ALIGN */
015dc7e1 13888 return true;
cf13d699 13889 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13890 if (sym_index >= num_syms)
13891 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13892 sym_index);
13893 else
13894 saved_sym = symtab + sym_index;
015dc7e1 13895 return true;
f84ce13b 13896
cf13d699
NC
13897 case 1: /* R_MN10300_32 */
13898 case 2: /* R_MN10300_16 */
13899 if (saved_sym != NULL)
13900 {
03f7786e 13901 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13902 bfd_vma value;
252b5132 13903
f84ce13b
NC
13904 if (sym_index >= num_syms)
13905 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13906 sym_index);
03f7786e 13907 else
f84ce13b
NC
13908 {
13909 value = reloc->r_addend + (symtab[sym_index].st_value
13910 - saved_sym->st_value);
13911
b32e566b 13912 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13913 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13914 else
13915 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13916 (long) reloc->r_offset);
f84ce13b 13917 }
252b5132 13918
cf13d699 13919 saved_sym = NULL;
015dc7e1 13920 return true;
cf13d699
NC
13921 }
13922 break;
13923 default:
13924 if (saved_sym != NULL)
071436c6 13925 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13926 break;
13927 }
13928 break;
13929 }
6ff71e76
NC
13930
13931 case EM_RL78:
13932 {
13933 static bfd_vma saved_sym1 = 0;
13934 static bfd_vma saved_sym2 = 0;
13935 static bfd_vma value;
13936
f84ce13b
NC
13937 if (reloc == NULL)
13938 {
13939 saved_sym1 = saved_sym2 = 0;
015dc7e1 13940 return true;
f84ce13b
NC
13941 }
13942
6ff71e76
NC
13943 switch (reloc_type)
13944 {
13945 case 0x80: /* R_RL78_SYM. */
13946 saved_sym1 = saved_sym2;
f84ce13b
NC
13947 if (sym_index >= num_syms)
13948 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13949 sym_index);
13950 else
13951 {
13952 saved_sym2 = symtab[sym_index].st_value;
13953 saved_sym2 += reloc->r_addend;
13954 }
015dc7e1 13955 return true;
6ff71e76
NC
13956
13957 case 0x83: /* R_RL78_OPsub. */
13958 value = saved_sym1 - saved_sym2;
13959 saved_sym2 = saved_sym1 = 0;
015dc7e1 13960 return true;
6ff71e76
NC
13961 break;
13962
13963 case 0x41: /* R_RL78_ABS32. */
b32e566b 13964 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13965 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13966 else
13967 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13968 (long) reloc->r_offset);
6ff71e76 13969 value = 0;
015dc7e1 13970 return true;
6ff71e76
NC
13971
13972 case 0x43: /* R_RL78_ABS16. */
b32e566b 13973 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13974 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13975 else
13976 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13977 (long) reloc->r_offset);
6ff71e76 13978 value = 0;
015dc7e1 13979 return true;
6ff71e76
NC
13980
13981 default:
13982 break;
13983 }
13984 break;
13985 }
252b5132
RH
13986 }
13987
015dc7e1 13988 return false;
252b5132
RH
13989}
13990
aca88567
NC
13991/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13992 DWARF debug sections. This is a target specific test. Note - we do not
13993 go through the whole including-target-headers-multiple-times route, (as
13994 we have already done with <elf/h8.h>) because this would become very
13995 messy and even then this function would have to contain target specific
13996 information (the names of the relocs instead of their numeric values).
13997 FIXME: This is not the correct way to solve this problem. The proper way
13998 is to have target specific reloc sizing and typing functions created by
13999 the reloc-macros.h header, in the same way that it already creates the
14000 reloc naming functions. */
14001
015dc7e1 14002static bool
dda8d76d 14003is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14004{
d347c9df 14005 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14006 switch (filedata->file_header.e_machine)
aca88567 14007 {
41e92641 14008 case EM_386:
22abe556 14009 case EM_IAMCU:
41e92641 14010 return reloc_type == 1; /* R_386_32. */
aca88567
NC
14011 case EM_68K:
14012 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
14013 case EM_860:
14014 return reloc_type == 1; /* R_860_32. */
14015 case EM_960:
14016 return reloc_type == 2; /* R_960_32. */
a06ea964 14017 case EM_AARCH64:
9282b95a
JW
14018 return (reloc_type == 258
14019 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
14020 case EM_BPF:
14021 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
14022 case EM_ADAPTEVA_EPIPHANY:
14023 return reloc_type == 3;
aca88567 14024 case EM_ALPHA:
137b6b5f 14025 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
14026 case EM_ARC:
14027 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
14028 case EM_ARC_COMPACT:
14029 case EM_ARC_COMPACT2:
14030 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
14031 case EM_ARM:
14032 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 14033 case EM_AVR_OLD:
aca88567
NC
14034 case EM_AVR:
14035 return reloc_type == 1;
14036 case EM_BLACKFIN:
14037 return reloc_type == 0x12; /* R_byte4_data. */
14038 case EM_CRIS:
14039 return reloc_type == 3; /* R_CRIS_32. */
14040 case EM_CR16:
14041 return reloc_type == 3; /* R_CR16_NUM32. */
14042 case EM_CRX:
14043 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
14044 case EM_CSKY:
14045 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
14046 case EM_CYGNUS_FRV:
14047 return reloc_type == 1;
41e92641
NC
14048 case EM_CYGNUS_D10V:
14049 case EM_D10V:
14050 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
14051 case EM_CYGNUS_D30V:
14052 case EM_D30V:
14053 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
14054 case EM_DLX:
14055 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
14056 case EM_CYGNUS_FR30:
14057 case EM_FR30:
14058 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
14059 case EM_FT32:
14060 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
14061 case EM_H8S:
14062 case EM_H8_300:
14063 case EM_H8_300H:
14064 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 14065 case EM_IA_64:
262cdac7
AM
14066 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
14067 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
14068 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
14069 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
14070 case EM_IP2K_OLD:
14071 case EM_IP2K:
14072 return reloc_type == 2; /* R_IP2K_32. */
14073 case EM_IQ2000:
14074 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
14075 case EM_LATTICEMICO32:
14076 return reloc_type == 3; /* R_LM32_32. */
e9a0721f 14077 case EM_LOONGARCH:
14078 return reloc_type == 1; /* R_LARCH_32. */
ff7eeb89 14079 case EM_M32C_OLD:
aca88567
NC
14080 case EM_M32C:
14081 return reloc_type == 3; /* R_M32C_32. */
14082 case EM_M32R:
14083 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
14084 case EM_68HC11:
14085 case EM_68HC12:
14086 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 14087 case EM_S12Z:
2849d19f
JD
14088 return reloc_type == 7 || /* R_S12Z_EXT32 */
14089 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
14090 case EM_MCORE:
14091 return reloc_type == 1; /* R_MCORE_ADDR32. */
14092 case EM_CYGNUS_MEP:
14093 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
14094 case EM_METAG:
14095 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
14096 case EM_MICROBLAZE:
14097 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
14098 case EM_MIPS:
14099 return reloc_type == 2; /* R_MIPS_32. */
14100 case EM_MMIX:
14101 return reloc_type == 4; /* R_MMIX_32. */
14102 case EM_CYGNUS_MN10200:
14103 case EM_MN10200:
14104 return reloc_type == 1; /* R_MN10200_32. */
14105 case EM_CYGNUS_MN10300:
14106 case EM_MN10300:
14107 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
14108 case EM_MOXIE:
14109 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
14110 case EM_MSP430_OLD:
14111 case EM_MSP430:
13761a11 14112 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
14113 case EM_MT:
14114 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
14115 case EM_NDS32:
14116 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 14117 case EM_ALTERA_NIOS2:
36591ba1 14118 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
14119 case EM_NIOS32:
14120 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
14121 case EM_OR1K:
14122 return reloc_type == 1; /* R_OR1K_32. */
aca88567 14123 case EM_PARISC:
9abca702 14124 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 14125 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 14126 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
14127 case EM_PJ:
14128 case EM_PJ_OLD:
14129 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
14130 case EM_PPC64:
14131 return reloc_type == 1; /* R_PPC64_ADDR32. */
14132 case EM_PPC:
14133 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
14134 case EM_TI_PRU:
14135 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
14136 case EM_RISCV:
14137 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
14138 case EM_RL78:
14139 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
14140 case EM_RX:
14141 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
14142 case EM_S370:
14143 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
14144 case EM_S390_OLD:
14145 case EM_S390:
14146 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
14147 case EM_SCORE:
14148 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
14149 case EM_SH:
14150 return reloc_type == 1; /* R_SH_DIR32. */
14151 case EM_SPARC32PLUS:
14152 case EM_SPARCV9:
14153 case EM_SPARC:
14154 return reloc_type == 3 /* R_SPARC_32. */
14155 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
14156 case EM_SPU:
14157 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
14158 case EM_TI_C6000:
14159 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
14160 case EM_TILEGX:
14161 return reloc_type == 2; /* R_TILEGX_32. */
14162 case EM_TILEPRO:
14163 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
14164 case EM_CYGNUS_V850:
14165 case EM_V850:
14166 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
14167 case EM_V800:
14168 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
14169 case EM_VAX:
14170 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
14171 case EM_VISIUM:
14172 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
14173 case EM_WEBASSEMBLY:
14174 return reloc_type == 1; /* R_WASM32_32. */
aca88567 14175 case EM_X86_64:
8a9036a4 14176 case EM_L1OM:
7a9068fe 14177 case EM_K1OM:
aca88567 14178 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
14179 case EM_XC16X:
14180 case EM_C166:
14181 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
14182 case EM_XGATE:
14183 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
14184 case EM_XSTORMY16:
14185 return reloc_type == 1; /* R_XSTROMY16_32. */
14186 case EM_XTENSA_OLD:
14187 case EM_XTENSA:
14188 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
14189 case EM_Z80:
14190 return reloc_type == 6; /* R_Z80_32. */
aca88567 14191 default:
bee0ee85
NC
14192 {
14193 static unsigned int prev_warn = 0;
14194
14195 /* Avoid repeating the same warning multiple times. */
dda8d76d 14196 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 14197 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
14198 filedata->file_header.e_machine);
14199 prev_warn = filedata->file_header.e_machine;
015dc7e1 14200 return false;
bee0ee85 14201 }
aca88567
NC
14202 }
14203}
14204
14205/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14206 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
14207
015dc7e1 14208static bool
dda8d76d 14209is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14210{
dda8d76d 14211 switch (filedata->file_header.e_machine)
d347c9df 14212 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 14213 {
41e92641 14214 case EM_386:
22abe556 14215 case EM_IAMCU:
3e0873ac 14216 return reloc_type == 2; /* R_386_PC32. */
aca88567 14217 case EM_68K:
3e0873ac 14218 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
14219 case EM_AARCH64:
14220 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
14221 case EM_ADAPTEVA_EPIPHANY:
14222 return reloc_type == 6;
aca88567
NC
14223 case EM_ALPHA:
14224 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
14225 case EM_ARC_COMPACT:
14226 case EM_ARC_COMPACT2:
14227 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 14228 case EM_ARM:
3e0873ac 14229 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
14230 case EM_AVR_OLD:
14231 case EM_AVR:
14232 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
14233 case EM_MICROBLAZE:
14234 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
14235 case EM_OR1K:
14236 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 14237 case EM_PARISC:
85acf597 14238 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
14239 case EM_PPC:
14240 return reloc_type == 26; /* R_PPC_REL32. */
14241 case EM_PPC64:
3e0873ac 14242 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
14243 case EM_RISCV:
14244 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
14245 case EM_S390_OLD:
14246 case EM_S390:
3e0873ac 14247 return reloc_type == 5; /* R_390_PC32. */
aca88567 14248 case EM_SH:
3e0873ac 14249 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
14250 case EM_SPARC32PLUS:
14251 case EM_SPARCV9:
14252 case EM_SPARC:
3e0873ac 14253 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
14254 case EM_SPU:
14255 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
14256 case EM_TILEGX:
14257 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
14258 case EM_TILEPRO:
14259 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
14260 case EM_VISIUM:
14261 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 14262 case EM_X86_64:
8a9036a4 14263 case EM_L1OM:
7a9068fe 14264 case EM_K1OM:
3e0873ac 14265 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
14266 case EM_VAX:
14267 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
14268 case EM_XTENSA_OLD:
14269 case EM_XTENSA:
14270 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
14271 default:
14272 /* Do not abort or issue an error message here. Not all targets use
14273 pc-relative 32-bit relocs in their DWARF debug information and we
14274 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
14275 more helpful warning message will be generated by apply_relocations
14276 anyway, so just return. */
015dc7e1 14277 return false;
aca88567
NC
14278 }
14279}
14280
14281/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14282 a 64-bit absolute RELA relocation used in DWARF debug sections. */
14283
015dc7e1 14284static bool
dda8d76d 14285is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 14286{
dda8d76d 14287 switch (filedata->file_header.e_machine)
aca88567 14288 {
a06ea964
NC
14289 case EM_AARCH64:
14290 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
14291 case EM_ALPHA:
14292 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 14293 case EM_IA_64:
262cdac7
AM
14294 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
14295 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
e9a0721f 14296 case EM_LOONGARCH:
14297 return reloc_type == 2; /* R_LARCH_64 */
3e0873ac
NC
14298 case EM_PARISC:
14299 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
14300 case EM_PPC64:
14301 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
14302 case EM_RISCV:
14303 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
14304 case EM_SPARC32PLUS:
14305 case EM_SPARCV9:
14306 case EM_SPARC:
714da62f
NC
14307 return reloc_type == 32 /* R_SPARC_64. */
14308 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 14309 case EM_X86_64:
8a9036a4 14310 case EM_L1OM:
7a9068fe 14311 case EM_K1OM:
aca88567 14312 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
14313 case EM_S390_OLD:
14314 case EM_S390:
aa137e4d
NC
14315 return reloc_type == 22; /* R_S390_64. */
14316 case EM_TILEGX:
14317 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 14318 case EM_MIPS:
aa137e4d 14319 return reloc_type == 18; /* R_MIPS_64. */
aca88567 14320 default:
015dc7e1 14321 return false;
aca88567
NC
14322 }
14323}
14324
85acf597
RH
14325/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
14326 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
14327
015dc7e1 14328static bool
dda8d76d 14329is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 14330{
dda8d76d 14331 switch (filedata->file_header.e_machine)
85acf597 14332 {
a06ea964
NC
14333 case EM_AARCH64:
14334 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 14335 case EM_ALPHA:
aa137e4d 14336 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 14337 case EM_IA_64:
262cdac7
AM
14338 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
14339 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 14340 case EM_PARISC:
aa137e4d 14341 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 14342 case EM_PPC64:
aa137e4d 14343 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
14344 case EM_SPARC32PLUS:
14345 case EM_SPARCV9:
14346 case EM_SPARC:
aa137e4d 14347 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 14348 case EM_X86_64:
8a9036a4 14349 case EM_L1OM:
7a9068fe 14350 case EM_K1OM:
aa137e4d 14351 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
14352 case EM_S390_OLD:
14353 case EM_S390:
aa137e4d
NC
14354 return reloc_type == 23; /* R_S390_PC64. */
14355 case EM_TILEGX:
14356 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 14357 default:
015dc7e1 14358 return false;
85acf597
RH
14359 }
14360}
14361
4dc3c23d
AM
14362/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14363 a 24-bit absolute RELA relocation used in DWARF debug sections. */
14364
015dc7e1 14365static bool
dda8d76d 14366is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 14367{
dda8d76d 14368 switch (filedata->file_header.e_machine)
4dc3c23d
AM
14369 {
14370 case EM_CYGNUS_MN10200:
14371 case EM_MN10200:
14372 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
14373 case EM_FT32:
14374 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
14375 case EM_Z80:
14376 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 14377 default:
015dc7e1 14378 return false;
4dc3c23d
AM
14379 }
14380}
14381
aca88567
NC
14382/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14383 a 16-bit absolute RELA relocation used in DWARF debug sections. */
14384
015dc7e1 14385static bool
dda8d76d 14386is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 14387{
d347c9df 14388 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 14389 switch (filedata->file_header.e_machine)
4b78141a 14390 {
886a2506
NC
14391 case EM_ARC:
14392 case EM_ARC_COMPACT:
14393 case EM_ARC_COMPACT2:
14394 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
14395 case EM_ADAPTEVA_EPIPHANY:
14396 return reloc_type == 5;
aca88567
NC
14397 case EM_AVR_OLD:
14398 case EM_AVR:
14399 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14400 case EM_CYGNUS_D10V:
14401 case EM_D10V:
14402 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14403 case EM_FT32:
14404 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14405 case EM_H8S:
14406 case EM_H8_300:
14407 case EM_H8_300H:
aca88567
NC
14408 return reloc_type == R_H8_DIR16;
14409 case EM_IP2K_OLD:
14410 case EM_IP2K:
14411 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14412 case EM_M32C_OLD:
f4236fe4
DD
14413 case EM_M32C:
14414 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14415 case EM_CYGNUS_MN10200:
14416 case EM_MN10200:
14417 return reloc_type == 2; /* R_MN10200_16. */
14418 case EM_CYGNUS_MN10300:
14419 case EM_MN10300:
14420 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14421 case EM_MSP430:
dda8d76d 14422 if (uses_msp430x_relocs (filedata))
13761a11 14423 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14424 /* Fall through. */
78c8d46c 14425 case EM_MSP430_OLD:
aca88567 14426 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14427 case EM_NDS32:
14428 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14429 case EM_ALTERA_NIOS2:
36591ba1 14430 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14431 case EM_NIOS32:
14432 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14433 case EM_OR1K:
14434 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14435 case EM_RISCV:
14436 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14437 case EM_TI_PRU:
14438 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14439 case EM_TI_C6000:
14440 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14441 case EM_VISIUM:
14442 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14443 case EM_XC16X:
14444 case EM_C166:
14445 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14446 case EM_XGATE:
14447 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14448 case EM_Z80:
14449 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14450 default:
015dc7e1 14451 return false;
4b78141a
NC
14452 }
14453}
14454
39e07931
AS
14455/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14456 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14457
015dc7e1 14458static bool
39e07931
AS
14459is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14460{
14461 switch (filedata->file_header.e_machine)
14462 {
14463 case EM_RISCV:
14464 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14465 case EM_Z80:
14466 return reloc_type == 1; /* R_Z80_8. */
39e07931 14467 default:
015dc7e1 14468 return false;
39e07931
AS
14469 }
14470}
14471
14472/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14473 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14474
015dc7e1 14475static bool
39e07931
AS
14476is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14477{
14478 switch (filedata->file_header.e_machine)
14479 {
14480 case EM_RISCV:
14481 return reloc_type == 53; /* R_RISCV_SET6. */
14482 default:
015dc7e1 14483 return false;
39e07931
AS
14484 }
14485}
14486
03336641
JW
14487/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14488 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14489
015dc7e1 14490static bool
03336641
JW
14491is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14492{
14493 /* Please keep this table alpha-sorted for ease of visual lookup. */
14494 switch (filedata->file_header.e_machine)
14495 {
14496 case EM_RISCV:
14497 return reloc_type == 35; /* R_RISCV_ADD32. */
14498 default:
015dc7e1 14499 return false;
03336641
JW
14500 }
14501}
14502
14503/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14504 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14505
015dc7e1 14506static bool
03336641
JW
14507is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14508{
14509 /* Please keep this table alpha-sorted for ease of visual lookup. */
14510 switch (filedata->file_header.e_machine)
14511 {
14512 case EM_RISCV:
14513 return reloc_type == 39; /* R_RISCV_SUB32. */
14514 default:
015dc7e1 14515 return false;
03336641
JW
14516 }
14517}
14518
14519/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14520 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14521
015dc7e1 14522static bool
03336641
JW
14523is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14524{
14525 /* Please keep this table alpha-sorted for ease of visual lookup. */
14526 switch (filedata->file_header.e_machine)
14527 {
14528 case EM_RISCV:
14529 return reloc_type == 36; /* R_RISCV_ADD64. */
14530 default:
015dc7e1 14531 return false;
03336641
JW
14532 }
14533}
14534
14535/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14536 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14537
015dc7e1 14538static bool
03336641
JW
14539is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14540{
14541 /* Please keep this table alpha-sorted for ease of visual lookup. */
14542 switch (filedata->file_header.e_machine)
14543 {
14544 case EM_RISCV:
14545 return reloc_type == 40; /* R_RISCV_SUB64. */
14546 default:
015dc7e1 14547 return false;
03336641
JW
14548 }
14549}
14550
14551/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14552 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14553
015dc7e1 14554static bool
03336641
JW
14555is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14556{
14557 /* Please keep this table alpha-sorted for ease of visual lookup. */
14558 switch (filedata->file_header.e_machine)
14559 {
14560 case EM_RISCV:
14561 return reloc_type == 34; /* R_RISCV_ADD16. */
14562 default:
015dc7e1 14563 return false;
03336641
JW
14564 }
14565}
14566
14567/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14568 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14569
015dc7e1 14570static bool
03336641
JW
14571is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14572{
14573 /* Please keep this table alpha-sorted for ease of visual lookup. */
14574 switch (filedata->file_header.e_machine)
14575 {
14576 case EM_RISCV:
14577 return reloc_type == 38; /* R_RISCV_SUB16. */
14578 default:
015dc7e1 14579 return false;
03336641
JW
14580 }
14581}
14582
14583/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14584 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14585
015dc7e1 14586static bool
03336641
JW
14587is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14588{
14589 /* Please keep this table alpha-sorted for ease of visual lookup. */
14590 switch (filedata->file_header.e_machine)
14591 {
14592 case EM_RISCV:
14593 return reloc_type == 33; /* R_RISCV_ADD8. */
14594 default:
015dc7e1 14595 return false;
03336641
JW
14596 }
14597}
14598
14599/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14600 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14601
015dc7e1 14602static bool
03336641
JW
14603is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14604{
14605 /* Please keep this table alpha-sorted for ease of visual lookup. */
14606 switch (filedata->file_header.e_machine)
14607 {
14608 case EM_RISCV:
14609 return reloc_type == 37; /* R_RISCV_SUB8. */
14610 default:
015dc7e1 14611 return false;
03336641
JW
14612 }
14613}
14614
39e07931
AS
14615/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14616 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14617
015dc7e1 14618static bool
39e07931
AS
14619is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14620{
14621 switch (filedata->file_header.e_machine)
14622 {
14623 case EM_RISCV:
14624 return reloc_type == 52; /* R_RISCV_SUB6. */
14625 default:
015dc7e1 14626 return false;
39e07931
AS
14627 }
14628}
14629
2a7b2e88
JK
14630/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14631 relocation entries (possibly formerly used for SHT_GROUP sections). */
14632
015dc7e1 14633static bool
dda8d76d 14634is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14635{
dda8d76d 14636 switch (filedata->file_header.e_machine)
2a7b2e88 14637 {
cb8f3167 14638 case EM_386: /* R_386_NONE. */
d347c9df 14639 case EM_68K: /* R_68K_NONE. */
cfb8c092 14640 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14641 case EM_ALPHA: /* R_ALPHA_NONE. */
14642 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14643 case EM_ARC: /* R_ARC_NONE. */
886a2506 14644 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14645 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14646 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14647 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14648 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14649 case EM_FT32: /* R_FT32_NONE. */
14650 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14651 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14652 case EM_L1OM: /* R_X86_64_NONE. */
14653 case EM_M32R: /* R_M32R_NONE. */
14654 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14655 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14656 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14657 case EM_NIOS32: /* R_NIOS_NONE. */
14658 case EM_OR1K: /* R_OR1K_NONE. */
14659 case EM_PARISC: /* R_PARISC_NONE. */
14660 case EM_PPC64: /* R_PPC64_NONE. */
14661 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14662 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14663 case EM_S390: /* R_390_NONE. */
14664 case EM_S390_OLD:
14665 case EM_SH: /* R_SH_NONE. */
14666 case EM_SPARC32PLUS:
14667 case EM_SPARC: /* R_SPARC_NONE. */
14668 case EM_SPARCV9:
aa137e4d
NC
14669 case EM_TILEGX: /* R_TILEGX_NONE. */
14670 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14671 case EM_TI_C6000:/* R_C6000_NONE. */
14672 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14673 case EM_XC16X:
6655dba2 14674 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14675 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14676 return reloc_type == 0;
d347c9df 14677
a06ea964
NC
14678 case EM_AARCH64:
14679 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14680 case EM_AVR_OLD:
14681 case EM_AVR:
14682 return (reloc_type == 0 /* R_AVR_NONE. */
14683 || reloc_type == 30 /* R_AVR_DIFF8. */
14684 || reloc_type == 31 /* R_AVR_DIFF16. */
14685 || reloc_type == 32 /* R_AVR_DIFF32. */);
14686 case EM_METAG:
14687 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14688 case EM_NDS32:
14689 return (reloc_type == 0 /* R_XTENSA_NONE. */
14690 || reloc_type == 204 /* R_NDS32_DIFF8. */
14691 || reloc_type == 205 /* R_NDS32_DIFF16. */
14692 || reloc_type == 206 /* R_NDS32_DIFF32. */
14693 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14694 case EM_TI_PRU:
14695 return (reloc_type == 0 /* R_PRU_NONE. */
14696 || reloc_type == 65 /* R_PRU_DIFF8. */
14697 || reloc_type == 66 /* R_PRU_DIFF16. */
14698 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14699 case EM_XTENSA_OLD:
14700 case EM_XTENSA:
4dc3c23d
AM
14701 return (reloc_type == 0 /* R_XTENSA_NONE. */
14702 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14703 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14704 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14705 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14706 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14707 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14708 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14709 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14710 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14711 }
015dc7e1 14712 return false;
2a7b2e88
JK
14713}
14714
d1c4b12b
NC
14715/* Returns TRUE if there is a relocation against
14716 section NAME at OFFSET bytes. */
14717
015dc7e1 14718bool
d1c4b12b
NC
14719reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14720{
14721 Elf_Internal_Rela * relocs;
14722 Elf_Internal_Rela * rp;
14723
14724 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14725 return false;
d1c4b12b
NC
14726
14727 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14728
14729 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14730 if (rp->r_offset == offset)
015dc7e1 14731 return true;
d1c4b12b 14732
015dc7e1 14733 return false;
d1c4b12b
NC
14734}
14735
cf13d699 14736/* Apply relocations to a section.
32ec8896
NC
14737 Returns TRUE upon success, FALSE otherwise.
14738 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14739 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14740 will be set to the number of relocs loaded.
14741
cf13d699 14742 Note: So far support has been added only for those relocations
32ec8896
NC
14743 which can be found in debug sections. FIXME: Add support for
14744 more relocations ? */
1b315056 14745
015dc7e1 14746static bool
dda8d76d 14747apply_relocations (Filedata * filedata,
d1c4b12b
NC
14748 const Elf_Internal_Shdr * section,
14749 unsigned char * start,
14750 bfd_size_type size,
1449284b 14751 void ** relocs_return,
d1c4b12b 14752 unsigned long * num_relocs_return)
1b315056 14753{
cf13d699 14754 Elf_Internal_Shdr * relsec;
0d2a7a93 14755 unsigned char * end = start + size;
cb8f3167 14756
d1c4b12b
NC
14757 if (relocs_return != NULL)
14758 {
14759 * (Elf_Internal_Rela **) relocs_return = NULL;
14760 * num_relocs_return = 0;
14761 }
14762
dda8d76d 14763 if (filedata->file_header.e_type != ET_REL)
32ec8896 14764 /* No relocs to apply. */
015dc7e1 14765 return true;
1b315056 14766
cf13d699 14767 /* Find the reloc section associated with the section. */
dda8d76d
NC
14768 for (relsec = filedata->section_headers;
14769 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14770 ++relsec)
252b5132 14771 {
015dc7e1 14772 bool is_rela;
41e92641 14773 unsigned long num_relocs;
2cf0635d
NC
14774 Elf_Internal_Rela * relocs;
14775 Elf_Internal_Rela * rp;
14776 Elf_Internal_Shdr * symsec;
14777 Elf_Internal_Sym * symtab;
ba5cdace 14778 unsigned long num_syms;
2cf0635d 14779 Elf_Internal_Sym * sym;
252b5132 14780
41e92641 14781 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14782 || relsec->sh_info >= filedata->file_header.e_shnum
14783 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14784 || relsec->sh_size == 0
dda8d76d 14785 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14786 continue;
428409d5 14787
a788aedd
AM
14788 symsec = filedata->section_headers + relsec->sh_link;
14789 if (symsec->sh_type != SHT_SYMTAB
14790 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14791 return false;
a788aedd 14792
41e92641
NC
14793 is_rela = relsec->sh_type == SHT_RELA;
14794
14795 if (is_rela)
14796 {
dda8d76d 14797 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14798 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14799 return false;
41e92641
NC
14800 }
14801 else
14802 {
dda8d76d 14803 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14804 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14805 return false;
41e92641
NC
14806 }
14807
14808 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14809 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14810 is_rela = false;
428409d5 14811
4de91c10 14812 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14813
41e92641 14814 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14815 {
015dc7e1
AM
14816 bfd_vma addend;
14817 unsigned int reloc_type;
14818 unsigned int reloc_size;
14819 bool reloc_inplace = false;
14820 bool reloc_subtract = false;
14821 unsigned char *rloc;
14822 unsigned long sym_index;
4b78141a 14823
dda8d76d 14824 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14825
dda8d76d 14826 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14827 continue;
dda8d76d 14828 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14829 continue;
dda8d76d
NC
14830 else if (is_32bit_abs_reloc (filedata, reloc_type)
14831 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14832 reloc_size = 4;
dda8d76d
NC
14833 else if (is_64bit_abs_reloc (filedata, reloc_type)
14834 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14835 reloc_size = 8;
dda8d76d 14836 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14837 reloc_size = 3;
dda8d76d 14838 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14839 reloc_size = 2;
39e07931
AS
14840 else if (is_8bit_abs_reloc (filedata, reloc_type)
14841 || is_6bit_abs_reloc (filedata, reloc_type))
14842 reloc_size = 1;
03336641
JW
14843 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14844 reloc_type))
14845 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14846 {
14847 reloc_size = 4;
015dc7e1 14848 reloc_inplace = true;
03336641
JW
14849 }
14850 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14851 reloc_type))
14852 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14853 {
14854 reloc_size = 8;
015dc7e1 14855 reloc_inplace = true;
03336641
JW
14856 }
14857 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14858 reloc_type))
14859 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14860 {
14861 reloc_size = 2;
015dc7e1 14862 reloc_inplace = true;
03336641
JW
14863 }
14864 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14865 reloc_type))
14866 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14867 {
14868 reloc_size = 1;
015dc7e1 14869 reloc_inplace = true;
03336641 14870 }
39e07931
AS
14871 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14872 reloc_type)))
14873 {
14874 reloc_size = 1;
015dc7e1 14875 reloc_inplace = true;
39e07931 14876 }
aca88567 14877 else
4b78141a 14878 {
bee0ee85 14879 static unsigned int prev_reloc = 0;
dda8d76d 14880
bee0ee85
NC
14881 if (reloc_type != prev_reloc)
14882 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14883 reloc_type, printable_section_name (filedata, section));
bee0ee85 14884 prev_reloc = reloc_type;
4b78141a
NC
14885 continue;
14886 }
103f02d3 14887
91d6fa6a 14888 rloc = start + rp->r_offset;
75802ccb 14889 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14890 {
14891 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14892 (unsigned long) rp->r_offset,
dda8d76d 14893 printable_section_name (filedata, section));
700dd8b7
L
14894 continue;
14895 }
103f02d3 14896
ba5cdace
NC
14897 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14898 if (sym_index >= num_syms)
14899 {
14900 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14901 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14902 continue;
14903 }
14904 sym = symtab + sym_index;
41e92641
NC
14905
14906 /* If the reloc has a symbol associated with it,
55f25fc3
L
14907 make sure that it is of an appropriate type.
14908
14909 Relocations against symbols without type can happen.
14910 Gcc -feliminate-dwarf2-dups may generate symbols
14911 without type for debug info.
14912
14913 Icc generates relocations against function symbols
14914 instead of local labels.
14915
14916 Relocations against object symbols can happen, eg when
14917 referencing a global array. For an example of this see
14918 the _clz.o binary in libgcc.a. */
aca88567 14919 if (sym != symtab
b8871f35 14920 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14921 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14922 {
d3a49aa8 14923 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14924 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14925 printable_section_name (filedata, relsec),
d3a49aa8 14926 (long int)(rp - relocs));
aca88567 14927 continue;
5b18a4bc 14928 }
252b5132 14929
4dc3c23d
AM
14930 addend = 0;
14931 if (is_rela)
14932 addend += rp->r_addend;
c47320c3
AM
14933 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14934 partial_inplace. */
4dc3c23d 14935 if (!is_rela
dda8d76d 14936 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14937 && reloc_type == 1)
dda8d76d
NC
14938 || ((filedata->file_header.e_machine == EM_PJ
14939 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14940 && reloc_type == 1)
dda8d76d
NC
14941 || ((filedata->file_header.e_machine == EM_D30V
14942 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14943 && reloc_type == 12)
14944 || reloc_inplace)
39e07931
AS
14945 {
14946 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14947 addend += byte_get (rloc, reloc_size) & 0x3f;
14948 else
14949 addend += byte_get (rloc, reloc_size);
14950 }
cb8f3167 14951
dda8d76d
NC
14952 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14953 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14954 {
14955 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14956 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14957 addend -= 8;
91d6fa6a 14958 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14959 reloc_size);
14960 }
39e07931
AS
14961 else if (is_6bit_abs_reloc (filedata, reloc_type)
14962 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14963 {
14964 if (reloc_subtract)
14965 addend -= sym->st_value;
14966 else
14967 addend += sym->st_value;
14968 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14969 byte_put (rloc, addend, reloc_size);
14970 }
03336641
JW
14971 else if (reloc_subtract)
14972 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14973 else
91d6fa6a 14974 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14975 }
252b5132 14976
5b18a4bc 14977 free (symtab);
f84ce13b
NC
14978 /* Let the target specific reloc processing code know that
14979 we have finished with these relocs. */
dda8d76d 14980 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14981
14982 if (relocs_return)
14983 {
14984 * (Elf_Internal_Rela **) relocs_return = relocs;
14985 * num_relocs_return = num_relocs;
14986 }
14987 else
14988 free (relocs);
14989
5b18a4bc
NC
14990 break;
14991 }
32ec8896 14992
015dc7e1 14993 return true;
5b18a4bc 14994}
103f02d3 14995
cf13d699 14996#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14997static bool
dda8d76d 14998disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14999{
dda8d76d 15000 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 15001
74e1a04b 15002 /* FIXME: XXX -- to be done --- XXX */
cf13d699 15003
015dc7e1 15004 return true;
cf13d699
NC
15005}
15006#endif
15007
15008/* Reads in the contents of SECTION from FILE, returning a pointer
15009 to a malloc'ed buffer or NULL if something went wrong. */
15010
15011static char *
dda8d76d 15012get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15013{
dda8d76d 15014 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
15015
15016 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
15017 {
c6b78c96 15018 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 15019 printable_section_name (filedata, section));
cf13d699
NC
15020 return NULL;
15021 }
15022
dda8d76d 15023 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 15024 _("section contents"));
cf13d699
NC
15025}
15026
0e602686
NC
15027/* Uncompresses a section that was compressed using zlib, in place. */
15028
015dc7e1 15029static bool
dda8d76d
NC
15030uncompress_section_contents (unsigned char ** buffer,
15031 dwarf_size_type uncompressed_size,
15032 dwarf_size_type * size)
0e602686
NC
15033{
15034 dwarf_size_type compressed_size = *size;
15035 unsigned char * compressed_buffer = *buffer;
15036 unsigned char * uncompressed_buffer;
15037 z_stream strm;
15038 int rc;
15039
15040 /* It is possible the section consists of several compressed
15041 buffers concatenated together, so we uncompress in a loop. */
15042 /* PR 18313: The state field in the z_stream structure is supposed
15043 to be invisible to the user (ie us), but some compilers will
15044 still complain about it being used without initialisation. So
15045 we first zero the entire z_stream structure and then set the fields
15046 that we need. */
15047 memset (& strm, 0, sizeof strm);
15048 strm.avail_in = compressed_size;
15049 strm.next_in = (Bytef *) compressed_buffer;
15050 strm.avail_out = uncompressed_size;
15051 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
15052
15053 rc = inflateInit (& strm);
15054 while (strm.avail_in > 0)
15055 {
15056 if (rc != Z_OK)
3624a6c1 15057 break;
0e602686
NC
15058 strm.next_out = ((Bytef *) uncompressed_buffer
15059 + (uncompressed_size - strm.avail_out));
15060 rc = inflate (&strm, Z_FINISH);
15061 if (rc != Z_STREAM_END)
3624a6c1 15062 break;
0e602686
NC
15063 rc = inflateReset (& strm);
15064 }
ad92f33d
AM
15065 if (inflateEnd (& strm) != Z_OK
15066 || rc != Z_OK
0e602686
NC
15067 || strm.avail_out != 0)
15068 goto fail;
15069
15070 *buffer = uncompressed_buffer;
15071 *size = uncompressed_size;
015dc7e1 15072 return true;
0e602686
NC
15073
15074 fail:
15075 free (uncompressed_buffer);
15076 /* Indicate decompression failure. */
15077 *buffer = NULL;
015dc7e1 15078 return false;
0e602686 15079}
dd24e3da 15080
015dc7e1 15081static bool
dda8d76d 15082dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 15083{
015dc7e1
AM
15084 Elf_Internal_Shdr *relsec;
15085 bfd_size_type num_bytes;
15086 unsigned char *data;
15087 unsigned char *end;
15088 unsigned char *real_start;
15089 unsigned char *start;
15090 bool some_strings_shown;
cf13d699 15091
dda8d76d 15092 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15093 if (start == NULL)
c6b78c96 15094 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15095 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 15096
0e602686 15097 num_bytes = section->sh_size;
cf13d699 15098
835f2fae
NC
15099 if (filedata->is_separate)
15100 printf (_("\nString dump of section '%s' in linked file %s:\n"),
15101 printable_section_name (filedata, section),
15102 filedata->file_name);
15103 else
15104 printf (_("\nString dump of section '%s':\n"),
15105 printable_section_name (filedata, section));
cf13d699 15106
0e602686
NC
15107 if (decompress_dumps)
15108 {
15109 dwarf_size_type new_size = num_bytes;
15110 dwarf_size_type uncompressed_size = 0;
15111
15112 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15113 {
15114 Elf_Internal_Chdr chdr;
15115 unsigned int compression_header_size
ebdf1ebf
NC
15116 = get_compression_header (& chdr, (unsigned char *) start,
15117 num_bytes);
5844b465
NC
15118 if (compression_header_size == 0)
15119 /* An error message will have already been generated
15120 by get_compression_header. */
15121 goto error_out;
0e602686 15122
813dabb9 15123 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15124 {
813dabb9 15125 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15126 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15127 goto error_out;
813dabb9 15128 }
813dabb9
L
15129 uncompressed_size = chdr.ch_size;
15130 start += compression_header_size;
15131 new_size -= compression_header_size;
0e602686
NC
15132 }
15133 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15134 {
15135 /* Read the zlib header. In this case, it should be "ZLIB"
15136 followed by the uncompressed section size, 8 bytes in
15137 big-endian order. */
15138 uncompressed_size = start[4]; uncompressed_size <<= 8;
15139 uncompressed_size += start[5]; uncompressed_size <<= 8;
15140 uncompressed_size += start[6]; uncompressed_size <<= 8;
15141 uncompressed_size += start[7]; uncompressed_size <<= 8;
15142 uncompressed_size += start[8]; uncompressed_size <<= 8;
15143 uncompressed_size += start[9]; uncompressed_size <<= 8;
15144 uncompressed_size += start[10]; uncompressed_size <<= 8;
15145 uncompressed_size += start[11];
15146 start += 12;
15147 new_size -= 12;
15148 }
15149
1835f746
NC
15150 if (uncompressed_size)
15151 {
15152 if (uncompress_section_contents (& start,
15153 uncompressed_size, & new_size))
15154 num_bytes = new_size;
15155 else
15156 {
15157 error (_("Unable to decompress section %s\n"),
dda8d76d 15158 printable_section_name (filedata, section));
f761cb13 15159 goto error_out;
1835f746
NC
15160 }
15161 }
bc303e5d
NC
15162 else
15163 start = real_start;
0e602686 15164 }
fd8008d8 15165
cf13d699
NC
15166 /* If the section being dumped has relocations against it the user might
15167 be expecting these relocations to have been applied. Check for this
15168 case and issue a warning message in order to avoid confusion.
15169 FIXME: Maybe we ought to have an option that dumps a section with
15170 relocs applied ? */
dda8d76d
NC
15171 for (relsec = filedata->section_headers;
15172 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15173 ++relsec)
15174 {
15175 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15176 || relsec->sh_info >= filedata->file_header.e_shnum
15177 || filedata->section_headers + relsec->sh_info != section
cf13d699 15178 || relsec->sh_size == 0
dda8d76d 15179 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15180 continue;
15181
15182 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15183 break;
15184 }
15185
cf13d699
NC
15186 data = start;
15187 end = start + num_bytes;
015dc7e1 15188 some_strings_shown = false;
cf13d699 15189
ba3265d0
NC
15190#ifdef HAVE_MBSTATE_T
15191 mbstate_t state;
15192 /* Initialise the multibyte conversion state. */
15193 memset (& state, 0, sizeof (state));
15194#endif
15195
015dc7e1 15196 bool continuing = false;
ba3265d0 15197
cf13d699
NC
15198 while (data < end)
15199 {
15200 while (!ISPRINT (* data))
15201 if (++ data >= end)
15202 break;
15203
15204 if (data < end)
15205 {
071436c6
NC
15206 size_t maxlen = end - data;
15207
ba3265d0
NC
15208 if (continuing)
15209 {
15210 printf (" ");
015dc7e1 15211 continuing = false;
ba3265d0
NC
15212 }
15213 else
15214 {
d1ce973e 15215 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
15216 }
15217
4082ef84
NC
15218 if (maxlen > 0)
15219 {
f3da8a96 15220 char c = 0;
ba3265d0
NC
15221
15222 while (maxlen)
15223 {
15224 c = *data++;
15225
15226 if (c == 0)
15227 break;
15228
15229 /* PR 25543: Treat new-lines as string-ending characters. */
15230 if (c == '\n')
15231 {
15232 printf ("\\n\n");
15233 if (*data != 0)
015dc7e1 15234 continuing = true;
ba3265d0
NC
15235 break;
15236 }
15237
15238 /* Do not print control characters directly as they can affect terminal
15239 settings. Such characters usually appear in the names generated
15240 by the assembler for local labels. */
15241 if (ISCNTRL (c))
15242 {
15243 printf ("^%c", c + 0x40);
15244 }
15245 else if (ISPRINT (c))
15246 {
15247 putchar (c);
15248 }
15249 else
15250 {
15251 size_t n;
15252#ifdef HAVE_MBSTATE_T
15253 wchar_t w;
15254#endif
15255 /* Let printf do the hard work of displaying multibyte characters. */
15256 printf ("%.1s", data - 1);
15257#ifdef HAVE_MBSTATE_T
15258 /* Try to find out how many bytes made up the character that was
15259 just printed. Advance the symbol pointer past the bytes that
15260 were displayed. */
15261 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
15262#else
15263 n = 1;
15264#endif
15265 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
15266 data += (n - 1);
15267 }
15268 }
15269
15270 if (c != '\n')
15271 putchar ('\n');
4082ef84
NC
15272 }
15273 else
15274 {
15275 printf (_("<corrupt>\n"));
15276 data = end;
15277 }
015dc7e1 15278 some_strings_shown = true;
cf13d699
NC
15279 }
15280 }
15281
15282 if (! some_strings_shown)
15283 printf (_(" No strings found in this section."));
15284
0e602686 15285 free (real_start);
cf13d699
NC
15286
15287 putchar ('\n');
015dc7e1 15288 return true;
f761cb13
AM
15289
15290error_out:
15291 free (real_start);
015dc7e1 15292 return false;
cf13d699
NC
15293}
15294
015dc7e1
AM
15295static bool
15296dump_section_as_bytes (Elf_Internal_Shdr *section,
15297 Filedata *filedata,
15298 bool relocate)
cf13d699
NC
15299{
15300 Elf_Internal_Shdr * relsec;
0e602686
NC
15301 bfd_size_type bytes;
15302 bfd_size_type section_size;
15303 bfd_vma addr;
15304 unsigned char * data;
15305 unsigned char * real_start;
15306 unsigned char * start;
15307
dda8d76d 15308 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 15309 if (start == NULL)
c6b78c96 15310 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 15311 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 15312
0e602686 15313 section_size = section->sh_size;
cf13d699 15314
835f2fae
NC
15315 if (filedata->is_separate)
15316 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
15317 printable_section_name (filedata, section),
15318 filedata->file_name);
15319 else
15320 printf (_("\nHex dump of section '%s':\n"),
15321 printable_section_name (filedata, section));
cf13d699 15322
0e602686
NC
15323 if (decompress_dumps)
15324 {
15325 dwarf_size_type new_size = section_size;
15326 dwarf_size_type uncompressed_size = 0;
15327
15328 if ((section->sh_flags & SHF_COMPRESSED) != 0)
15329 {
15330 Elf_Internal_Chdr chdr;
15331 unsigned int compression_header_size
ebdf1ebf 15332 = get_compression_header (& chdr, start, section_size);
0e602686 15333
5844b465
NC
15334 if (compression_header_size == 0)
15335 /* An error message will have already been generated
15336 by get_compression_header. */
15337 goto error_out;
15338
813dabb9 15339 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 15340 {
813dabb9 15341 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 15342 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 15343 goto error_out;
0e602686 15344 }
813dabb9
L
15345 uncompressed_size = chdr.ch_size;
15346 start += compression_header_size;
15347 new_size -= compression_header_size;
0e602686
NC
15348 }
15349 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
15350 {
15351 /* Read the zlib header. In this case, it should be "ZLIB"
15352 followed by the uncompressed section size, 8 bytes in
15353 big-endian order. */
15354 uncompressed_size = start[4]; uncompressed_size <<= 8;
15355 uncompressed_size += start[5]; uncompressed_size <<= 8;
15356 uncompressed_size += start[6]; uncompressed_size <<= 8;
15357 uncompressed_size += start[7]; uncompressed_size <<= 8;
15358 uncompressed_size += start[8]; uncompressed_size <<= 8;
15359 uncompressed_size += start[9]; uncompressed_size <<= 8;
15360 uncompressed_size += start[10]; uncompressed_size <<= 8;
15361 uncompressed_size += start[11];
15362 start += 12;
15363 new_size -= 12;
15364 }
15365
f055032e
NC
15366 if (uncompressed_size)
15367 {
15368 if (uncompress_section_contents (& start, uncompressed_size,
15369 & new_size))
bc303e5d
NC
15370 {
15371 section_size = new_size;
15372 }
f055032e
NC
15373 else
15374 {
15375 error (_("Unable to decompress section %s\n"),
dda8d76d 15376 printable_section_name (filedata, section));
bc303e5d 15377 /* FIXME: Print the section anyway ? */
f761cb13 15378 goto error_out;
f055032e
NC
15379 }
15380 }
bc303e5d
NC
15381 else
15382 start = real_start;
0e602686 15383 }
14ae95f2 15384
cf13d699
NC
15385 if (relocate)
15386 {
dda8d76d 15387 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 15388 goto error_out;
cf13d699
NC
15389 }
15390 else
15391 {
15392 /* If the section being dumped has relocations against it the user might
15393 be expecting these relocations to have been applied. Check for this
15394 case and issue a warning message in order to avoid confusion.
15395 FIXME: Maybe we ought to have an option that dumps a section with
15396 relocs applied ? */
dda8d76d
NC
15397 for (relsec = filedata->section_headers;
15398 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15399 ++relsec)
15400 {
15401 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15402 || relsec->sh_info >= filedata->file_header.e_shnum
15403 || filedata->section_headers + relsec->sh_info != section
cf13d699 15404 || relsec->sh_size == 0
dda8d76d 15405 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15406 continue;
15407
15408 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15409 break;
15410 }
15411 }
15412
15413 addr = section->sh_addr;
0e602686 15414 bytes = section_size;
cf13d699
NC
15415 data = start;
15416
15417 while (bytes)
15418 {
15419 int j;
15420 int k;
15421 int lbytes;
15422
15423 lbytes = (bytes > 16 ? 16 : bytes);
15424
15425 printf (" 0x%8.8lx ", (unsigned long) addr);
15426
15427 for (j = 0; j < 16; j++)
15428 {
15429 if (j < lbytes)
15430 printf ("%2.2x", data[j]);
15431 else
15432 printf (" ");
15433
15434 if ((j & 3) == 3)
15435 printf (" ");
15436 }
15437
15438 for (j = 0; j < lbytes; j++)
15439 {
15440 k = data[j];
15441 if (k >= ' ' && k < 0x7f)
15442 printf ("%c", k);
15443 else
15444 printf (".");
15445 }
15446
15447 putchar ('\n');
15448
15449 data += lbytes;
15450 addr += lbytes;
15451 bytes -= lbytes;
15452 }
15453
0e602686 15454 free (real_start);
cf13d699
NC
15455
15456 putchar ('\n');
015dc7e1 15457 return true;
f761cb13
AM
15458
15459 error_out:
15460 free (real_start);
015dc7e1 15461 return false;
cf13d699
NC
15462}
15463
094e34f2 15464#ifdef ENABLE_LIBCTF
7d9813f1
NA
15465static ctf_sect_t *
15466shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15467{
84714f86 15468 buf->cts_name = section_name_print (filedata, shdr);
7d9813f1
NA
15469 buf->cts_size = shdr->sh_size;
15470 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15471
15472 return buf;
15473}
15474
15475/* Formatting callback function passed to ctf_dump. Returns either the pointer
15476 it is passed, or a pointer to newly-allocated storage, in which case
15477 dump_ctf() will free it when it no longer needs it. */
15478
2f6ecaed
NA
15479static char *
15480dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15481 char *s, void *arg)
7d9813f1 15482{
3e50a591 15483 const char *blanks = arg;
7d9813f1
NA
15484 char *new_s;
15485
3e50a591 15486 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15487 return s;
15488 return new_s;
15489}
15490
926c9e76
NA
15491/* Dump CTF errors/warnings. */
15492static void
139633c3 15493dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15494{
15495 ctf_next_t *it = NULL;
15496 char *errtext;
15497 int is_warning;
15498 int err;
15499
15500 /* Dump accumulated errors and warnings. */
15501 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15502 {
5e9b84f7 15503 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15504 errtext);
15505 free (errtext);
15506 }
15507 if (err != ECTF_NEXT_END)
15508 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15509}
15510
2f6ecaed
NA
15511/* Dump one CTF archive member. */
15512
80b56fad
NA
15513static void
15514dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, ctf_dict_t *parent,
15515 size_t member)
2f6ecaed 15516{
2f6ecaed
NA
15517 const char *things[] = {"Header", "Labels", "Data objects",
15518 "Function objects", "Variables", "Types", "Strings",
15519 ""};
15520 const char **thing;
15521 size_t i;
15522
80b56fad
NA
15523 /* Don't print out the name of the default-named archive member if it appears
15524 first in the list. The name .ctf appears everywhere, even for things that
15525 aren't really archives, so printing it out is liable to be confusing; also,
15526 the common case by far is for only one archive member to exist, and hiding
15527 it in that case seems worthwhile. */
2f6ecaed 15528
80b56fad
NA
15529 if (strcmp (name, ".ctf") != 0 || member != 0)
15530 printf (_("\nCTF archive member: %s:\n"), name);
2f6ecaed 15531
80b56fad
NA
15532 if (ctf_parent_name (ctf) != NULL)
15533 ctf_import (ctf, parent);
2f6ecaed
NA
15534
15535 for (i = 0, thing = things; *thing[0]; thing++, i++)
15536 {
15537 ctf_dump_state_t *s = NULL;
15538 char *item;
15539
15540 printf ("\n %s:\n", *thing);
15541 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15542 (void *) " ")) != NULL)
15543 {
15544 printf ("%s\n", item);
15545 free (item);
15546 }
15547
15548 if (ctf_errno (ctf))
15549 {
15550 error (_("Iteration failed: %s, %s\n"), *thing,
15551 ctf_errmsg (ctf_errno (ctf)));
80b56fad 15552 break;
2f6ecaed
NA
15553 }
15554 }
8b37e7b6 15555
926c9e76 15556 dump_ctf_errs (ctf);
2f6ecaed
NA
15557}
15558
015dc7e1 15559static bool
7d9813f1
NA
15560dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15561{
7d9813f1
NA
15562 Elf_Internal_Shdr * symtab_sec = NULL;
15563 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15564 void * data = NULL;
15565 void * symdata = NULL;
15566 void * strdata = NULL;
80b56fad 15567 ctf_sect_t ctfsect, symsect, strsect;
d344b407
NA
15568 ctf_sect_t * symsectp = NULL;
15569 ctf_sect_t * strsectp = NULL;
2f6ecaed 15570 ctf_archive_t * ctfa = NULL;
139633c3 15571 ctf_dict_t * parent = NULL;
80b56fad 15572 ctf_dict_t * fp;
7d9813f1 15573
80b56fad
NA
15574 ctf_next_t *i = NULL;
15575 const char *name;
15576 size_t member = 0;
7d9813f1 15577 int err;
015dc7e1 15578 bool ret = false;
7d9813f1
NA
15579
15580 shdr_to_ctf_sect (&ctfsect, section, filedata);
15581 data = get_section_contents (section, filedata);
15582 ctfsect.cts_data = data;
15583
616febde 15584 if (!dump_ctf_symtab_name)
3d16b64e 15585 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15586
15587 if (!dump_ctf_strtab_name)
3d16b64e 15588 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15589
15590 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15591 {
15592 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15593 {
15594 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15595 goto fail;
15596 }
15597 if ((symdata = (void *) get_data (NULL, filedata,
15598 symtab_sec->sh_offset, 1,
15599 symtab_sec->sh_size,
15600 _("symbols"))) == NULL)
15601 goto fail;
15602 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15603 symsect.cts_data = symdata;
15604 }
835f2fae 15605
df16e041 15606 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15607 {
15608 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15609 {
15610 error (_("No string table section named %s\n"),
15611 dump_ctf_strtab_name);
15612 goto fail;
15613 }
15614 if ((strdata = (void *) get_data (NULL, filedata,
15615 strtab_sec->sh_offset, 1,
15616 strtab_sec->sh_size,
15617 _("strings"))) == NULL)
15618 goto fail;
15619 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15620 strsect.cts_data = strdata;
15621 }
835f2fae 15622
2f6ecaed
NA
15623 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15624 libctf papers over the difference, so we can pretend it is always an
80b56fad 15625 archive. */
7d9813f1 15626
2f6ecaed 15627 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15628 {
926c9e76 15629 dump_ctf_errs (NULL);
7d9813f1
NA
15630 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15631 goto fail;
15632 }
15633
96c61be5
NA
15634 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15635 != ELFDATA2MSB);
15636
80b56fad
NA
15637 /* Preload the parent dict, since it will need to be imported into every
15638 child in turn. */
15639 if ((parent = ctf_dict_open (ctfa, dump_ctf_parent_name, &err)) == NULL)
2f6ecaed 15640 {
926c9e76 15641 dump_ctf_errs (NULL);
2f6ecaed
NA
15642 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15643 goto fail;
7d9813f1
NA
15644 }
15645
015dc7e1 15646 ret = true;
7d9813f1 15647
835f2fae
NC
15648 if (filedata->is_separate)
15649 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15650 printable_section_name (filedata, section),
15651 filedata->file_name);
15652 else
15653 printf (_("\nDump of CTF section '%s':\n"),
15654 printable_section_name (filedata, section));
7d9813f1 15655
80b56fad
NA
15656 while ((fp = ctf_archive_next (ctfa, &i, &name, 0, &err)) != NULL)
15657 dump_ctf_archive_member (fp, name, parent, member++);
15658 if (err != ECTF_NEXT_END)
15659 {
15660 dump_ctf_errs (NULL);
15661 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
15662 ret = false;
15663 }
7d9813f1
NA
15664
15665 fail:
139633c3 15666 ctf_dict_close (parent);
2f6ecaed 15667 ctf_close (ctfa);
7d9813f1
NA
15668 free (data);
15669 free (symdata);
15670 free (strdata);
15671 return ret;
15672}
094e34f2 15673#endif
7d9813f1 15674
015dc7e1 15675static bool
dda8d76d
NC
15676load_specific_debug_section (enum dwarf_section_display_enum debug,
15677 const Elf_Internal_Shdr * sec,
15678 void * data)
1007acb3 15679{
2cf0635d 15680 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15681 char buf [64];
dda8d76d 15682 Filedata * filedata = (Filedata *) data;
9abca702 15683
19e6b90e 15684 if (section->start != NULL)
dda8d76d
NC
15685 {
15686 /* If it is already loaded, do nothing. */
15687 if (streq (section->filename, filedata->file_name))
015dc7e1 15688 return true;
dda8d76d
NC
15689 free (section->start);
15690 }
1007acb3 15691
19e6b90e
L
15692 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15693 section->address = sec->sh_addr;
dda8d76d
NC
15694 section->filename = filedata->file_name;
15695 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15696 sec->sh_offset, 1,
15697 sec->sh_size, buf);
59245841
NC
15698 if (section->start == NULL)
15699 section->size = 0;
15700 else
15701 {
77115a4a
L
15702 unsigned char *start = section->start;
15703 dwarf_size_type size = sec->sh_size;
dab394de 15704 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15705
15706 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15707 {
15708 Elf_Internal_Chdr chdr;
d8024a91
NC
15709 unsigned int compression_header_size;
15710
f53be977
L
15711 if (size < (is_32bit_elf
15712 ? sizeof (Elf32_External_Chdr)
15713 : sizeof (Elf64_External_Chdr)))
d8024a91 15714 {
55be8fd0 15715 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15716 section->name);
015dc7e1 15717 return false;
d8024a91
NC
15718 }
15719
ebdf1ebf 15720 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15721 if (compression_header_size == 0)
15722 /* An error message will have already been generated
15723 by get_compression_header. */
015dc7e1 15724 return false;
d8024a91 15725
813dabb9
L
15726 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15727 {
15728 warn (_("section '%s' has unsupported compress type: %d\n"),
15729 section->name, chdr.ch_type);
015dc7e1 15730 return false;
813dabb9 15731 }
dab394de 15732 uncompressed_size = chdr.ch_size;
77115a4a
L
15733 start += compression_header_size;
15734 size -= compression_header_size;
15735 }
dab394de
L
15736 else if (size > 12 && streq ((char *) start, "ZLIB"))
15737 {
15738 /* Read the zlib header. In this case, it should be "ZLIB"
15739 followed by the uncompressed section size, 8 bytes in
15740 big-endian order. */
15741 uncompressed_size = start[4]; uncompressed_size <<= 8;
15742 uncompressed_size += start[5]; uncompressed_size <<= 8;
15743 uncompressed_size += start[6]; uncompressed_size <<= 8;
15744 uncompressed_size += start[7]; uncompressed_size <<= 8;
15745 uncompressed_size += start[8]; uncompressed_size <<= 8;
15746 uncompressed_size += start[9]; uncompressed_size <<= 8;
15747 uncompressed_size += start[10]; uncompressed_size <<= 8;
15748 uncompressed_size += start[11];
15749 start += 12;
15750 size -= 12;
15751 }
15752
1835f746 15753 if (uncompressed_size)
77115a4a 15754 {
1835f746
NC
15755 if (uncompress_section_contents (&start, uncompressed_size,
15756 &size))
15757 {
15758 /* Free the compressed buffer, update the section buffer
15759 and the section size if uncompress is successful. */
15760 free (section->start);
15761 section->start = start;
15762 }
15763 else
15764 {
15765 error (_("Unable to decompress section %s\n"),
dda8d76d 15766 printable_section_name (filedata, sec));
015dc7e1 15767 return false;
1835f746 15768 }
77115a4a 15769 }
bc303e5d 15770
77115a4a 15771 section->size = size;
59245841 15772 }
4a114e3e 15773
1b315056 15774 if (section->start == NULL)
015dc7e1 15775 return false;
1b315056 15776
19e6b90e 15777 if (debug_displays [debug].relocate)
32ec8896 15778 {
dda8d76d 15779 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15780 & section->reloc_info, & section->num_relocs))
015dc7e1 15781 return false;
32ec8896 15782 }
d1c4b12b
NC
15783 else
15784 {
15785 section->reloc_info = NULL;
15786 section->num_relocs = 0;
15787 }
1007acb3 15788
015dc7e1 15789 return true;
1007acb3
L
15790}
15791
301a9420
AM
15792#if HAVE_LIBDEBUGINFOD
15793/* Return a hex string representation of the build-id. */
15794unsigned char *
15795get_build_id (void * data)
15796{
ca0e11aa 15797 Filedata * filedata = (Filedata *) data;
301a9420
AM
15798 Elf_Internal_Shdr * shdr;
15799 unsigned long i;
15800
55be8fd0
NC
15801 /* Iterate through notes to find note.gnu.build-id.
15802 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15803 for (i = 0, shdr = filedata->section_headers;
15804 i < filedata->file_header.e_shnum && shdr != NULL;
15805 i++, shdr++)
15806 {
15807 if (shdr->sh_type != SHT_NOTE)
15808 continue;
15809
15810 char * next;
15811 char * end;
15812 size_t data_remaining;
15813 size_t min_notesz;
15814 Elf_External_Note * enote;
15815 Elf_Internal_Note inote;
15816
15817 bfd_vma offset = shdr->sh_offset;
15818 bfd_vma align = shdr->sh_addralign;
15819 bfd_vma length = shdr->sh_size;
15820
15821 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15822 if (enote == NULL)
15823 continue;
15824
15825 if (align < 4)
15826 align = 4;
15827 else if (align != 4 && align != 8)
f761cb13
AM
15828 {
15829 free (enote);
15830 continue;
15831 }
301a9420
AM
15832
15833 end = (char *) enote + length;
15834 data_remaining = end - (char *) enote;
15835
15836 if (!is_ia64_vms (filedata))
15837 {
15838 min_notesz = offsetof (Elf_External_Note, name);
15839 if (data_remaining < min_notesz)
15840 {
55be8fd0
NC
15841 warn (_("\
15842malformed note encountered in section %s whilst scanning for build-id note\n"),
15843 printable_section_name (filedata, shdr));
f761cb13 15844 free (enote);
55be8fd0 15845 continue;
301a9420
AM
15846 }
15847 data_remaining -= min_notesz;
15848
15849 inote.type = BYTE_GET (enote->type);
15850 inote.namesz = BYTE_GET (enote->namesz);
15851 inote.namedata = enote->name;
15852 inote.descsz = BYTE_GET (enote->descsz);
15853 inote.descdata = ((char *) enote
15854 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15855 inote.descpos = offset + (inote.descdata - (char *) enote);
15856 next = ((char *) enote
15857 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15858 }
15859 else
15860 {
15861 Elf64_External_VMS_Note *vms_enote;
15862
15863 /* PR binutils/15191
15864 Make sure that there is enough data to read. */
15865 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15866 if (data_remaining < min_notesz)
15867 {
55be8fd0
NC
15868 warn (_("\
15869malformed note encountered in section %s whilst scanning for build-id note\n"),
15870 printable_section_name (filedata, shdr));
f761cb13 15871 free (enote);
55be8fd0 15872 continue;
301a9420
AM
15873 }
15874 data_remaining -= min_notesz;
15875
15876 vms_enote = (Elf64_External_VMS_Note *) enote;
15877 inote.type = BYTE_GET (vms_enote->type);
15878 inote.namesz = BYTE_GET (vms_enote->namesz);
15879 inote.namedata = vms_enote->name;
15880 inote.descsz = BYTE_GET (vms_enote->descsz);
15881 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15882 inote.descpos = offset + (inote.descdata - (char *) enote);
15883 next = inote.descdata + align_power (inote.descsz, 3);
15884 }
15885
15886 /* Skip malformed notes. */
15887 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15888 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15889 || (size_t) (next - inote.descdata) < inote.descsz
15890 || ((size_t) (next - inote.descdata)
15891 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15892 {
55be8fd0
NC
15893 warn (_("\
15894malformed note encountered in section %s whilst scanning for build-id note\n"),
15895 printable_section_name (filedata, shdr));
f761cb13 15896 free (enote);
301a9420
AM
15897 continue;
15898 }
15899
15900 /* Check if this is the build-id note. If so then convert the build-id
15901 bytes to a hex string. */
15902 if (inote.namesz > 0
24d127aa 15903 && startswith (inote.namedata, "GNU")
301a9420
AM
15904 && inote.type == NT_GNU_BUILD_ID)
15905 {
15906 unsigned long j;
15907 char * build_id;
15908
15909 build_id = malloc (inote.descsz * 2 + 1);
15910 if (build_id == NULL)
f761cb13
AM
15911 {
15912 free (enote);
15913 return NULL;
15914 }
301a9420
AM
15915
15916 for (j = 0; j < inote.descsz; ++j)
15917 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15918 build_id[inote.descsz * 2] = '\0';
f761cb13 15919 free (enote);
301a9420 15920
55be8fd0 15921 return (unsigned char *) build_id;
301a9420 15922 }
f761cb13 15923 free (enote);
301a9420
AM
15924 }
15925
15926 return NULL;
15927}
15928#endif /* HAVE_LIBDEBUGINFOD */
15929
657d0d47
CC
15930/* If this is not NULL, load_debug_section will only look for sections
15931 within the list of sections given here. */
32ec8896 15932static unsigned int * section_subset = NULL;
657d0d47 15933
015dc7e1 15934bool
dda8d76d 15935load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15936{
2cf0635d
NC
15937 struct dwarf_section * section = &debug_displays [debug].section;
15938 Elf_Internal_Shdr * sec;
dda8d76d
NC
15939 Filedata * filedata = (Filedata *) data;
15940
e1dbfc17
L
15941 if (!dump_any_debugging)
15942 return false;
15943
f425ec66
NC
15944 /* Without section headers we cannot find any sections. */
15945 if (filedata->section_headers == NULL)
015dc7e1 15946 return false;
f425ec66 15947
9c1ce108
AM
15948 if (filedata->string_table == NULL
15949 && filedata->file_header.e_shstrndx != SHN_UNDEF
15950 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15951 {
15952 Elf_Internal_Shdr * strs;
15953
15954 /* Read in the string table, so that we have section names to scan. */
15955 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15956
4dff97b2 15957 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15958 {
9c1ce108
AM
15959 filedata->string_table
15960 = (char *) get_data (NULL, filedata, strs->sh_offset,
15961 1, strs->sh_size, _("string table"));
dda8d76d 15962
9c1ce108
AM
15963 filedata->string_table_length
15964 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15965 }
15966 }
d966045b
DJ
15967
15968 /* Locate the debug section. */
dda8d76d 15969 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15970 if (sec != NULL)
15971 section->name = section->uncompressed_name;
15972 else
15973 {
dda8d76d 15974 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15975 if (sec != NULL)
15976 section->name = section->compressed_name;
15977 }
15978 if (sec == NULL)
015dc7e1 15979 return false;
d966045b 15980
657d0d47
CC
15981 /* If we're loading from a subset of sections, and we've loaded
15982 a section matching this name before, it's likely that it's a
15983 different one. */
15984 if (section_subset != NULL)
15985 free_debug_section (debug);
15986
dda8d76d 15987 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15988}
15989
19e6b90e
L
15990void
15991free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15992{
2cf0635d 15993 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15994
19e6b90e
L
15995 if (section->start == NULL)
15996 return;
1007acb3 15997
19e6b90e
L
15998 free ((char *) section->start);
15999 section->start = NULL;
16000 section->address = 0;
16001 section->size = 0;
a788aedd 16002
9db70fc3
AM
16003 free (section->reloc_info);
16004 section->reloc_info = NULL;
16005 section->num_relocs = 0;
1007acb3
L
16006}
16007
015dc7e1 16008static bool
dda8d76d 16009display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 16010{
84714f86
AM
16011 const char *name = (section_name_valid (filedata, section)
16012 ? section_name (filedata, section) : "");
16013 const char *print_name = printable_section_name (filedata, section);
19e6b90e 16014 bfd_size_type length;
015dc7e1 16015 bool result = true;
3f5e193b 16016 int i;
1007acb3 16017
19e6b90e
L
16018 length = section->sh_size;
16019 if (length == 0)
1007acb3 16020 {
74e1a04b 16021 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 16022 return true;
1007acb3 16023 }
5dff79d8
NC
16024 if (section->sh_type == SHT_NOBITS)
16025 {
16026 /* There is no point in dumping the contents of a debugging section
16027 which has the NOBITS type - the bits in the file will be random.
16028 This can happen when a file containing a .eh_frame section is
16029 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
16030 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
16031 print_name);
015dc7e1 16032 return false;
5dff79d8 16033 }
1007acb3 16034
24d127aa 16035 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 16036 name = ".debug_info";
1007acb3 16037
19e6b90e
L
16038 /* See if we know how to display the contents of this section. */
16039 for (i = 0; i < max; i++)
d85bf2ba
NC
16040 {
16041 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
16042 struct dwarf_section_display * display = debug_displays + i;
16043 struct dwarf_section * sec = & display->section;
d966045b 16044
d85bf2ba 16045 if (streq (sec->uncompressed_name, name)
24d127aa 16046 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16047 || streq (sec->compressed_name, name))
16048 {
015dc7e1 16049 bool secondary = (section != find_section (filedata, name));
1007acb3 16050
d85bf2ba
NC
16051 if (secondary)
16052 free_debug_section (id);
dda8d76d 16053
24d127aa 16054 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
16055 sec->name = name;
16056 else if (streq (sec->uncompressed_name, name))
16057 sec->name = sec->uncompressed_name;
16058 else
16059 sec->name = sec->compressed_name;
657d0d47 16060
d85bf2ba
NC
16061 if (load_specific_debug_section (id, section, filedata))
16062 {
16063 /* If this debug section is part of a CU/TU set in a .dwp file,
16064 restrict load_debug_section to the sections in that set. */
16065 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 16066
d85bf2ba 16067 result &= display->display (sec, filedata);
657d0d47 16068
d85bf2ba 16069 section_subset = NULL;
1007acb3 16070
44266f36 16071 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
16072 free_debug_section (id);
16073 }
16074 break;
16075 }
16076 }
1007acb3 16077
19e6b90e 16078 if (i == max)
1007acb3 16079 {
74e1a04b 16080 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 16081 result = false;
1007acb3
L
16082 }
16083
19e6b90e 16084 return result;
5b18a4bc 16085}
103f02d3 16086
aef1f6d0
DJ
16087/* Set DUMP_SECTS for all sections where dumps were requested
16088 based on section name. */
16089
16090static void
dda8d76d 16091initialise_dumps_byname (Filedata * filedata)
aef1f6d0 16092{
2cf0635d 16093 struct dump_list_entry * cur;
aef1f6d0
DJ
16094
16095 for (cur = dump_sects_byname; cur; cur = cur->next)
16096 {
16097 unsigned int i;
015dc7e1 16098 bool any = false;
aef1f6d0 16099
dda8d76d 16100 for (i = 0; i < filedata->file_header.e_shnum; i++)
84714f86
AM
16101 if (section_name_valid (filedata, filedata->section_headers + i)
16102 && streq (section_name (filedata, filedata->section_headers + i),
16103 cur->name))
aef1f6d0 16104 {
6431e409 16105 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 16106 any = true;
aef1f6d0
DJ
16107 }
16108
835f2fae
NC
16109 if (!any && !filedata->is_separate)
16110 warn (_("Section '%s' was not dumped because it does not exist\n"),
16111 cur->name);
aef1f6d0
DJ
16112 }
16113}
16114
015dc7e1 16115static bool
dda8d76d 16116process_section_contents (Filedata * filedata)
5b18a4bc 16117{
2cf0635d 16118 Elf_Internal_Shdr * section;
19e6b90e 16119 unsigned int i;
015dc7e1 16120 bool res = true;
103f02d3 16121
19e6b90e 16122 if (! do_dump)
015dc7e1 16123 return true;
103f02d3 16124
dda8d76d 16125 initialise_dumps_byname (filedata);
aef1f6d0 16126
dda8d76d 16127 for (i = 0, section = filedata->section_headers;
6431e409 16128 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
16129 i++, section++)
16130 {
6431e409 16131 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 16132
d6bfbc39
NC
16133 if (filedata->is_separate && ! process_links)
16134 dump &= DEBUG_DUMP;
047c3dbf 16135
19e6b90e 16136#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
16137 if (dump & DISASS_DUMP)
16138 {
16139 if (! disassemble_section (section, filedata))
015dc7e1 16140 res = false;
dda8d76d 16141 }
19e6b90e 16142#endif
dda8d76d 16143 if (dump & HEX_DUMP)
32ec8896 16144 {
015dc7e1
AM
16145 if (! dump_section_as_bytes (section, filedata, false))
16146 res = false;
32ec8896 16147 }
103f02d3 16148
dda8d76d 16149 if (dump & RELOC_DUMP)
32ec8896 16150 {
015dc7e1
AM
16151 if (! dump_section_as_bytes (section, filedata, true))
16152 res = false;
32ec8896 16153 }
09c11c86 16154
dda8d76d 16155 if (dump & STRING_DUMP)
32ec8896 16156 {
dda8d76d 16157 if (! dump_section_as_strings (section, filedata))
015dc7e1 16158 res = false;
32ec8896 16159 }
cf13d699 16160
dda8d76d 16161 if (dump & DEBUG_DUMP)
32ec8896 16162 {
dda8d76d 16163 if (! display_debug_section (i, section, filedata))
015dc7e1 16164 res = false;
32ec8896 16165 }
7d9813f1 16166
094e34f2 16167#ifdef ENABLE_LIBCTF
7d9813f1
NA
16168 if (dump & CTF_DUMP)
16169 {
16170 if (! dump_section_as_ctf (section, filedata))
015dc7e1 16171 res = false;
7d9813f1 16172 }
094e34f2 16173#endif
5b18a4bc 16174 }
103f02d3 16175
835f2fae 16176 if (! filedata->is_separate)
0ee3043f 16177 {
835f2fae
NC
16178 /* Check to see if the user requested a
16179 dump of a section that does not exist. */
16180 for (; i < filedata->dump.num_dump_sects; i++)
16181 if (filedata->dump.dump_sects[i])
16182 {
ca0e11aa 16183 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 16184 res = false;
835f2fae 16185 }
0ee3043f 16186 }
32ec8896
NC
16187
16188 return res;
5b18a4bc 16189}
103f02d3 16190
5b18a4bc 16191static void
19e6b90e 16192process_mips_fpe_exception (int mask)
5b18a4bc 16193{
19e6b90e
L
16194 if (mask)
16195 {
015dc7e1 16196 bool first = true;
32ec8896 16197
19e6b90e 16198 if (mask & OEX_FPU_INEX)
015dc7e1 16199 fputs ("INEX", stdout), first = false;
19e6b90e 16200 if (mask & OEX_FPU_UFLO)
015dc7e1 16201 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 16202 if (mask & OEX_FPU_OFLO)
015dc7e1 16203 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 16204 if (mask & OEX_FPU_DIV0)
015dc7e1 16205 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
16206 if (mask & OEX_FPU_INVAL)
16207 printf ("%sINVAL", first ? "" : "|");
16208 }
5b18a4bc 16209 else
19e6b90e 16210 fputs ("0", stdout);
5b18a4bc 16211}
103f02d3 16212
f6f0e17b
NC
16213/* Display's the value of TAG at location P. If TAG is
16214 greater than 0 it is assumed to be an unknown tag, and
16215 a message is printed to this effect. Otherwise it is
16216 assumed that a message has already been printed.
16217
16218 If the bottom bit of TAG is set it assumed to have a
16219 string value, otherwise it is assumed to have an integer
16220 value.
16221
16222 Returns an updated P pointing to the first unread byte
16223 beyond the end of TAG's value.
16224
16225 Reads at or beyond END will not be made. */
16226
16227static unsigned char *
60abdbed 16228display_tag_value (signed int tag,
f6f0e17b
NC
16229 unsigned char * p,
16230 const unsigned char * const end)
16231{
16232 unsigned long val;
16233
16234 if (tag > 0)
16235 printf (" Tag_unknown_%d: ", tag);
16236
16237 if (p >= end)
16238 {
4082ef84 16239 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
16240 }
16241 else if (tag & 1)
16242 {
071436c6
NC
16243 /* PR 17531 file: 027-19978-0.004. */
16244 size_t maxlen = (end - p) - 1;
16245
16246 putchar ('"');
4082ef84
NC
16247 if (maxlen > 0)
16248 {
16249 print_symbol ((int) maxlen, (const char *) p);
16250 p += strnlen ((char *) p, maxlen) + 1;
16251 }
16252 else
16253 {
16254 printf (_("<corrupt string tag>"));
16255 p = (unsigned char *) end;
16256 }
071436c6 16257 printf ("\"\n");
f6f0e17b
NC
16258 }
16259 else
16260 {
cd30bcef 16261 READ_ULEB (val, p, end);
f6f0e17b
NC
16262 printf ("%ld (0x%lx)\n", val, val);
16263 }
16264
4082ef84 16265 assert (p <= end);
f6f0e17b
NC
16266 return p;
16267}
16268
53a346d8
CZ
16269/* ARC ABI attributes section. */
16270
16271static unsigned char *
16272display_arc_attribute (unsigned char * p,
16273 const unsigned char * const end)
16274{
16275 unsigned int tag;
53a346d8
CZ
16276 unsigned int val;
16277
cd30bcef 16278 READ_ULEB (tag, p, end);
53a346d8
CZ
16279
16280 switch (tag)
16281 {
16282 case Tag_ARC_PCS_config:
cd30bcef 16283 READ_ULEB (val, p, end);
53a346d8
CZ
16284 printf (" Tag_ARC_PCS_config: ");
16285 switch (val)
16286 {
16287 case 0:
16288 printf (_("Absent/Non standard\n"));
16289 break;
16290 case 1:
16291 printf (_("Bare metal/mwdt\n"));
16292 break;
16293 case 2:
16294 printf (_("Bare metal/newlib\n"));
16295 break;
16296 case 3:
16297 printf (_("Linux/uclibc\n"));
16298 break;
16299 case 4:
16300 printf (_("Linux/glibc\n"));
16301 break;
16302 default:
16303 printf (_("Unknown\n"));
16304 break;
16305 }
16306 break;
16307
16308 case Tag_ARC_CPU_base:
cd30bcef 16309 READ_ULEB (val, p, end);
53a346d8
CZ
16310 printf (" Tag_ARC_CPU_base: ");
16311 switch (val)
16312 {
16313 default:
16314 case TAG_CPU_NONE:
16315 printf (_("Absent\n"));
16316 break;
16317 case TAG_CPU_ARC6xx:
16318 printf ("ARC6xx\n");
16319 break;
16320 case TAG_CPU_ARC7xx:
16321 printf ("ARC7xx\n");
16322 break;
16323 case TAG_CPU_ARCEM:
16324 printf ("ARCEM\n");
16325 break;
16326 case TAG_CPU_ARCHS:
16327 printf ("ARCHS\n");
16328 break;
16329 }
16330 break;
16331
16332 case Tag_ARC_CPU_variation:
cd30bcef 16333 READ_ULEB (val, p, end);
53a346d8
CZ
16334 printf (" Tag_ARC_CPU_variation: ");
16335 switch (val)
16336 {
16337 default:
16338 if (val > 0 && val < 16)
53a346d8 16339 printf ("Core%d\n", val);
d8cbc93b
JL
16340 else
16341 printf ("Unknown\n");
16342 break;
16343
53a346d8
CZ
16344 case 0:
16345 printf (_("Absent\n"));
16346 break;
16347 }
16348 break;
16349
16350 case Tag_ARC_CPU_name:
16351 printf (" Tag_ARC_CPU_name: ");
16352 p = display_tag_value (-1, p, end);
16353 break;
16354
16355 case Tag_ARC_ABI_rf16:
cd30bcef 16356 READ_ULEB (val, p, end);
53a346d8
CZ
16357 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
16358 break;
16359
16360 case Tag_ARC_ABI_osver:
cd30bcef 16361 READ_ULEB (val, p, end);
53a346d8
CZ
16362 printf (" Tag_ARC_ABI_osver: v%d\n", val);
16363 break;
16364
16365 case Tag_ARC_ABI_pic:
16366 case Tag_ARC_ABI_sda:
cd30bcef 16367 READ_ULEB (val, p, end);
53a346d8
CZ
16368 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16369 : " Tag_ARC_ABI_pic: ");
16370 switch (val)
16371 {
16372 case 0:
16373 printf (_("Absent\n"));
16374 break;
16375 case 1:
16376 printf ("MWDT\n");
16377 break;
16378 case 2:
16379 printf ("GNU\n");
16380 break;
16381 default:
16382 printf (_("Unknown\n"));
16383 break;
16384 }
16385 break;
16386
16387 case Tag_ARC_ABI_tls:
cd30bcef 16388 READ_ULEB (val, p, end);
53a346d8
CZ
16389 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16390 break;
16391
16392 case Tag_ARC_ABI_enumsize:
cd30bcef 16393 READ_ULEB (val, p, end);
53a346d8
CZ
16394 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16395 _("smallest"));
16396 break;
16397
16398 case Tag_ARC_ABI_exceptions:
cd30bcef 16399 READ_ULEB (val, p, end);
53a346d8
CZ
16400 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16401 : _("default"));
16402 break;
16403
16404 case Tag_ARC_ABI_double_size:
cd30bcef 16405 READ_ULEB (val, p, end);
53a346d8
CZ
16406 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16407 break;
16408
16409 case Tag_ARC_ISA_config:
16410 printf (" Tag_ARC_ISA_config: ");
16411 p = display_tag_value (-1, p, end);
16412 break;
16413
16414 case Tag_ARC_ISA_apex:
16415 printf (" Tag_ARC_ISA_apex: ");
16416 p = display_tag_value (-1, p, end);
16417 break;
16418
16419 case Tag_ARC_ISA_mpy_option:
cd30bcef 16420 READ_ULEB (val, p, end);
53a346d8
CZ
16421 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16422 break;
16423
db1e1b45 16424 case Tag_ARC_ATR_version:
cd30bcef 16425 READ_ULEB (val, p, end);
db1e1b45 16426 printf (" Tag_ARC_ATR_version: %d\n", val);
16427 break;
16428
53a346d8
CZ
16429 default:
16430 return display_tag_value (tag & 1, p, end);
16431 }
16432
16433 return p;
16434}
16435
11c1ff18
PB
16436/* ARM EABI attributes section. */
16437typedef struct
16438{
70e99720 16439 unsigned int tag;
2cf0635d 16440 const char * name;
11c1ff18 16441 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16442 unsigned int type;
288f0ba2 16443 const char *const *table;
11c1ff18
PB
16444} arm_attr_public_tag;
16445
288f0ba2 16446static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16447 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16448 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
3197e593
PW
16449 "v8-M.mainline", "v8.1-A", "v8.2-A", "v8.3-A",
16450 "v8.1-M.mainline", "v9"};
288f0ba2
AM
16451static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16452static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16453 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16454static const char *const arm_attr_tag_FP_arch[] =
bca38921 16455 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16456 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16457static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16458static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16459 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16460 "NEON for ARMv8.1"};
288f0ba2 16461static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16462 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16463 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16464static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16465 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16466static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16467 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16468static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16469 {"Absolute", "PC-relative", "None"};
288f0ba2 16470static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16471 {"None", "direct", "GOT-indirect"};
288f0ba2 16472static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16473 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16474static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16475static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16476 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16477static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16478static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16479static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16480 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16481static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16482 {"Unused", "small", "int", "forced to int"};
288f0ba2 16483static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16484 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16485static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16486 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16487static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16488 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16489static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16490 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16491 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16492static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16493 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16494 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16495static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16496static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16497 {"Not Allowed", "Allowed"};
288f0ba2 16498static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16499 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16500static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16501 {"Follow architecture", "Allowed"};
288f0ba2 16502static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16503 {"Not Allowed", "Allowed"};
288f0ba2 16504static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16505 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16506 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16507static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16508static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16509 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16510 "TrustZone and Virtualization Extensions"};
288f0ba2 16511static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16512 {"Not Allowed", "Allowed"};
11c1ff18 16513
288f0ba2 16514static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16515 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16516
99db83d0
AC
16517static const char * arm_attr_tag_PAC_extension[] =
16518 {"No PAC/AUT instructions",
16519 "PAC/AUT instructions permitted in the NOP space",
16520 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16521
4b535030
AC
16522static const char * arm_attr_tag_BTI_extension[] =
16523 {"BTI instructions not permitted",
16524 "BTI instructions permitted in the NOP space",
16525 "BTI instructions permitted in the NOP and in the non-NOP space"};
16526
b81ee92f
AC
16527static const char * arm_attr_tag_BTI_use[] =
16528 {"Compiled without branch target enforcement",
16529 "Compiled with branch target enforcement"};
16530
c9fed665
AC
16531static const char * arm_attr_tag_PACRET_use[] =
16532 {"Compiled without return address signing and authentication",
16533 "Compiled with return address signing and authentication"};
16534
11c1ff18
PB
16535#define LOOKUP(id, name) \
16536 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16537static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16538{
16539 {4, "CPU_raw_name", 1, NULL},
16540 {5, "CPU_name", 1, NULL},
16541 LOOKUP(6, CPU_arch),
16542 {7, "CPU_arch_profile", 0, NULL},
16543 LOOKUP(8, ARM_ISA_use),
16544 LOOKUP(9, THUMB_ISA_use),
75375b3e 16545 LOOKUP(10, FP_arch),
11c1ff18 16546 LOOKUP(11, WMMX_arch),
f5f53991
AS
16547 LOOKUP(12, Advanced_SIMD_arch),
16548 LOOKUP(13, PCS_config),
11c1ff18
PB
16549 LOOKUP(14, ABI_PCS_R9_use),
16550 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16551 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16552 LOOKUP(17, ABI_PCS_GOT_use),
16553 LOOKUP(18, ABI_PCS_wchar_t),
16554 LOOKUP(19, ABI_FP_rounding),
16555 LOOKUP(20, ABI_FP_denormal),
16556 LOOKUP(21, ABI_FP_exceptions),
16557 LOOKUP(22, ABI_FP_user_exceptions),
16558 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16559 {24, "ABI_align_needed", 0, NULL},
16560 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16561 LOOKUP(26, ABI_enum_size),
16562 LOOKUP(27, ABI_HardFP_use),
16563 LOOKUP(28, ABI_VFP_args),
16564 LOOKUP(29, ABI_WMMX_args),
16565 LOOKUP(30, ABI_optimization_goals),
16566 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16567 {32, "compatibility", 0, NULL},
f5f53991 16568 LOOKUP(34, CPU_unaligned_access),
75375b3e 16569 LOOKUP(36, FP_HP_extension),
8e79c3df 16570 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16571 LOOKUP(42, MPextension_use),
16572 LOOKUP(44, DIV_use),
15afaa63 16573 LOOKUP(46, DSP_extension),
a7ad558c 16574 LOOKUP(48, MVE_arch),
99db83d0 16575 LOOKUP(50, PAC_extension),
4b535030 16576 LOOKUP(52, BTI_extension),
b81ee92f 16577 LOOKUP(74, BTI_use),
c9fed665 16578 LOOKUP(76, PACRET_use),
f5f53991
AS
16579 {64, "nodefaults", 0, NULL},
16580 {65, "also_compatible_with", 0, NULL},
16581 LOOKUP(66, T2EE_use),
16582 {67, "conformance", 1, NULL},
16583 LOOKUP(68, Virtualization_use),
cd21e546 16584 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16585};
16586#undef LOOKUP
16587
11c1ff18 16588static unsigned char *
f6f0e17b
NC
16589display_arm_attribute (unsigned char * p,
16590 const unsigned char * const end)
11c1ff18 16591{
70e99720 16592 unsigned int tag;
70e99720 16593 unsigned int val;
2cf0635d 16594 arm_attr_public_tag * attr;
11c1ff18 16595 unsigned i;
70e99720 16596 unsigned int type;
11c1ff18 16597
cd30bcef 16598 READ_ULEB (tag, p, end);
11c1ff18 16599 attr = NULL;
2cf0635d 16600 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16601 {
16602 if (arm_attr_public_tags[i].tag == tag)
16603 {
16604 attr = &arm_attr_public_tags[i];
16605 break;
16606 }
16607 }
16608
16609 if (attr)
16610 {
16611 printf (" Tag_%s: ", attr->name);
16612 switch (attr->type)
16613 {
16614 case 0:
16615 switch (tag)
16616 {
16617 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16618 READ_ULEB (val, p, end);
11c1ff18
PB
16619 switch (val)
16620 {
2b692964
NC
16621 case 0: printf (_("None\n")); break;
16622 case 'A': printf (_("Application\n")); break;
16623 case 'R': printf (_("Realtime\n")); break;
16624 case 'M': printf (_("Microcontroller\n")); break;
16625 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16626 default: printf ("??? (%d)\n", val); break;
16627 }
16628 break;
16629
75375b3e 16630 case 24: /* Tag_align_needed. */
cd30bcef 16631 READ_ULEB (val, p, end);
75375b3e
MGD
16632 switch (val)
16633 {
2b692964
NC
16634 case 0: printf (_("None\n")); break;
16635 case 1: printf (_("8-byte\n")); break;
16636 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16637 case 3: printf ("??? 3\n"); break;
16638 default:
16639 if (val <= 12)
dd24e3da 16640 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16641 1 << val);
16642 else
16643 printf ("??? (%d)\n", val);
16644 break;
16645 }
16646 break;
16647
16648 case 25: /* Tag_align_preserved. */
cd30bcef 16649 READ_ULEB (val, p, end);
75375b3e
MGD
16650 switch (val)
16651 {
2b692964
NC
16652 case 0: printf (_("None\n")); break;
16653 case 1: printf (_("8-byte, except leaf SP\n")); break;
16654 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16655 case 3: printf ("??? 3\n"); break;
16656 default:
16657 if (val <= 12)
dd24e3da 16658 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16659 1 << val);
16660 else
16661 printf ("??? (%d)\n", val);
16662 break;
16663 }
16664 break;
16665
11c1ff18 16666 case 32: /* Tag_compatibility. */
071436c6 16667 {
cd30bcef 16668 READ_ULEB (val, p, end);
071436c6 16669 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16670 if (p < end - 1)
16671 {
16672 size_t maxlen = (end - p) - 1;
16673
16674 print_symbol ((int) maxlen, (const char *) p);
16675 p += strnlen ((char *) p, maxlen) + 1;
16676 }
16677 else
16678 {
16679 printf (_("<corrupt>"));
16680 p = (unsigned char *) end;
16681 }
071436c6 16682 putchar ('\n');
071436c6 16683 }
11c1ff18
PB
16684 break;
16685
f5f53991 16686 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16687 /* PR 17531: file: 001-505008-0.01. */
16688 if (p < end)
16689 p++;
2b692964 16690 printf (_("True\n"));
f5f53991
AS
16691 break;
16692
16693 case 65: /* Tag_also_compatible_with. */
cd30bcef 16694 READ_ULEB (val, p, end);
f5f53991
AS
16695 if (val == 6 /* Tag_CPU_arch. */)
16696 {
cd30bcef 16697 READ_ULEB (val, p, end);
071436c6 16698 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16699 printf ("??? (%d)\n", val);
16700 else
16701 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16702 }
16703 else
16704 printf ("???\n");
071436c6
NC
16705 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16706 ;
f5f53991
AS
16707 break;
16708
11c1ff18 16709 default:
bee0ee85
NC
16710 printf (_("<unknown: %d>\n"), tag);
16711 break;
11c1ff18
PB
16712 }
16713 return p;
16714
16715 case 1:
f6f0e17b 16716 return display_tag_value (-1, p, end);
11c1ff18 16717 case 2:
f6f0e17b 16718 return display_tag_value (0, p, end);
11c1ff18
PB
16719
16720 default:
16721 assert (attr->type & 0x80);
cd30bcef 16722 READ_ULEB (val, p, end);
11c1ff18
PB
16723 type = attr->type & 0x7f;
16724 if (val >= type)
16725 printf ("??? (%d)\n", val);
16726 else
16727 printf ("%s\n", attr->table[val]);
16728 return p;
16729 }
16730 }
11c1ff18 16731
f6f0e17b 16732 return display_tag_value (tag, p, end);
11c1ff18
PB
16733}
16734
104d59d1 16735static unsigned char *
60bca95a 16736display_gnu_attribute (unsigned char * p,
60abdbed 16737 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16738 const unsigned char * const end)
104d59d1 16739{
cd30bcef 16740 unsigned int tag;
60abdbed 16741 unsigned int val;
104d59d1 16742
cd30bcef 16743 READ_ULEB (tag, p, end);
104d59d1
JM
16744
16745 /* Tag_compatibility is the only generic GNU attribute defined at
16746 present. */
16747 if (tag == 32)
16748 {
cd30bcef 16749 READ_ULEB (val, p, end);
071436c6
NC
16750
16751 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16752 if (p == end)
16753 {
071436c6 16754 printf (_("<corrupt>\n"));
f6f0e17b
NC
16755 warn (_("corrupt vendor attribute\n"));
16756 }
16757 else
16758 {
4082ef84
NC
16759 if (p < end - 1)
16760 {
16761 size_t maxlen = (end - p) - 1;
071436c6 16762
4082ef84
NC
16763 print_symbol ((int) maxlen, (const char *) p);
16764 p += strnlen ((char *) p, maxlen) + 1;
16765 }
16766 else
16767 {
16768 printf (_("<corrupt>"));
16769 p = (unsigned char *) end;
16770 }
071436c6 16771 putchar ('\n');
f6f0e17b 16772 }
104d59d1
JM
16773 return p;
16774 }
16775
16776 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16777 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16778
f6f0e17b 16779 return display_tag_value (tag, p, end);
104d59d1
JM
16780}
16781
85f7484a
PB
16782static unsigned char *
16783display_m68k_gnu_attribute (unsigned char * p,
16784 unsigned int tag,
16785 const unsigned char * const end)
16786{
16787 unsigned int val;
16788
16789 if (tag == Tag_GNU_M68K_ABI_FP)
16790 {
16791 printf (" Tag_GNU_M68K_ABI_FP: ");
16792 if (p == end)
16793 {
16794 printf (_("<corrupt>\n"));
16795 return p;
16796 }
16797 READ_ULEB (val, p, end);
16798
16799 if (val > 3)
16800 printf ("(%#x), ", val);
16801
16802 switch (val & 3)
16803 {
16804 case 0:
16805 printf (_("unspecified hard/soft float\n"));
16806 break;
16807 case 1:
16808 printf (_("hard float\n"));
16809 break;
16810 case 2:
16811 printf (_("soft float\n"));
16812 break;
16813 }
16814 return p;
16815 }
16816
16817 return display_tag_value (tag & 1, p, end);
16818}
16819
34c8bcba 16820static unsigned char *
f6f0e17b 16821display_power_gnu_attribute (unsigned char * p,
60abdbed 16822 unsigned int tag,
f6f0e17b 16823 const unsigned char * const end)
34c8bcba 16824{
005d79fd 16825 unsigned int val;
34c8bcba
JM
16826
16827 if (tag == Tag_GNU_Power_ABI_FP)
16828 {
34c8bcba 16829 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16830 if (p == end)
005d79fd
AM
16831 {
16832 printf (_("<corrupt>\n"));
16833 return p;
16834 }
cd30bcef 16835 READ_ULEB (val, p, end);
60bca95a 16836
005d79fd
AM
16837 if (val > 15)
16838 printf ("(%#x), ", val);
16839
16840 switch (val & 3)
34c8bcba
JM
16841 {
16842 case 0:
005d79fd 16843 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16844 break;
16845 case 1:
005d79fd 16846 printf (_("hard float, "));
34c8bcba
JM
16847 break;
16848 case 2:
005d79fd 16849 printf (_("soft float, "));
34c8bcba 16850 break;
3c7b9897 16851 case 3:
005d79fd 16852 printf (_("single-precision hard float, "));
3c7b9897 16853 break;
005d79fd
AM
16854 }
16855
16856 switch (val & 0xC)
16857 {
16858 case 0:
16859 printf (_("unspecified long double\n"));
16860 break;
16861 case 4:
16862 printf (_("128-bit IBM long double\n"));
16863 break;
16864 case 8:
16865 printf (_("64-bit long double\n"));
16866 break;
16867 case 12:
16868 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16869 break;
16870 }
16871 return p;
005d79fd 16872 }
34c8bcba 16873
c6e65352
DJ
16874 if (tag == Tag_GNU_Power_ABI_Vector)
16875 {
c6e65352 16876 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16877 if (p == end)
005d79fd
AM
16878 {
16879 printf (_("<corrupt>\n"));
16880 return p;
16881 }
cd30bcef 16882 READ_ULEB (val, p, end);
005d79fd
AM
16883
16884 if (val > 3)
16885 printf ("(%#x), ", val);
16886
16887 switch (val & 3)
c6e65352
DJ
16888 {
16889 case 0:
005d79fd 16890 printf (_("unspecified\n"));
c6e65352
DJ
16891 break;
16892 case 1:
005d79fd 16893 printf (_("generic\n"));
c6e65352
DJ
16894 break;
16895 case 2:
16896 printf ("AltiVec\n");
16897 break;
16898 case 3:
16899 printf ("SPE\n");
16900 break;
c6e65352
DJ
16901 }
16902 return p;
005d79fd 16903 }
c6e65352 16904
f82e0623
NF
16905 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16906 {
005d79fd 16907 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16908 if (p == end)
f6f0e17b 16909 {
005d79fd 16910 printf (_("<corrupt>\n"));
f6f0e17b
NC
16911 return p;
16912 }
cd30bcef 16913 READ_ULEB (val, p, end);
0b4362b0 16914
005d79fd
AM
16915 if (val > 2)
16916 printf ("(%#x), ", val);
16917
16918 switch (val & 3)
16919 {
16920 case 0:
16921 printf (_("unspecified\n"));
16922 break;
16923 case 1:
16924 printf ("r3/r4\n");
16925 break;
16926 case 2:
16927 printf (_("memory\n"));
16928 break;
16929 case 3:
16930 printf ("???\n");
16931 break;
16932 }
f82e0623
NF
16933 return p;
16934 }
16935
f6f0e17b 16936 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16937}
16938
643f7afb
AK
16939static unsigned char *
16940display_s390_gnu_attribute (unsigned char * p,
60abdbed 16941 unsigned int tag,
643f7afb
AK
16942 const unsigned char * const end)
16943{
cd30bcef 16944 unsigned int val;
643f7afb
AK
16945
16946 if (tag == Tag_GNU_S390_ABI_Vector)
16947 {
643f7afb 16948 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16949 READ_ULEB (val, p, end);
643f7afb
AK
16950
16951 switch (val)
16952 {
16953 case 0:
16954 printf (_("any\n"));
16955 break;
16956 case 1:
16957 printf (_("software\n"));
16958 break;
16959 case 2:
16960 printf (_("hardware\n"));
16961 break;
16962 default:
16963 printf ("??? (%d)\n", val);
16964 break;
16965 }
16966 return p;
16967 }
16968
16969 return display_tag_value (tag & 1, p, end);
16970}
16971
9e8c70f9 16972static void
60abdbed 16973display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16974{
16975 if (mask)
16976 {
015dc7e1 16977 bool first = true;
071436c6 16978
9e8c70f9 16979 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16980 fputs ("mul32", stdout), first = false;
9e8c70f9 16981 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16982 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16983 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16984 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16985 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16986 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16987 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16988 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16989 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16990 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16991 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16992 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16993 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16994 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16995 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16996 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16997 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16998 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16999 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 17000 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 17001 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 17002 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 17003 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 17004 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 17005 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 17006 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 17007 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 17008 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 17009 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 17010 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
17011 }
17012 else
071436c6
NC
17013 fputc ('0', stdout);
17014 fputc ('\n', stdout);
9e8c70f9
DM
17015}
17016
3d68f91c 17017static void
60abdbed 17018display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
17019{
17020 if (mask)
17021 {
015dc7e1 17022 bool first = true;
071436c6 17023
3d68f91c 17024 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 17025 fputs ("fjathplus", stdout), first = false;
3d68f91c 17026 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 17027 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 17028 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 17029 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 17030 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 17031 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 17032 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 17033 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 17034 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 17035 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 17036 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 17037 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 17038 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 17039 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 17040 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 17041 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 17042 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 17043 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 17044 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 17045 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
17046 }
17047 else
071436c6
NC
17048 fputc ('0', stdout);
17049 fputc ('\n', stdout);
3d68f91c
JM
17050}
17051
9e8c70f9 17052static unsigned char *
f6f0e17b 17053display_sparc_gnu_attribute (unsigned char * p,
60abdbed 17054 unsigned int tag,
f6f0e17b 17055 const unsigned char * const end)
9e8c70f9 17056{
cd30bcef 17057 unsigned int val;
3d68f91c 17058
9e8c70f9
DM
17059 if (tag == Tag_GNU_Sparc_HWCAPS)
17060 {
cd30bcef 17061 READ_ULEB (val, p, end);
9e8c70f9 17062 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
17063 display_sparc_hwcaps (val);
17064 return p;
3d68f91c
JM
17065 }
17066 if (tag == Tag_GNU_Sparc_HWCAPS2)
17067 {
cd30bcef 17068 READ_ULEB (val, p, end);
3d68f91c
JM
17069 printf (" Tag_GNU_Sparc_HWCAPS2: ");
17070 display_sparc_hwcaps2 (val);
17071 return p;
17072 }
9e8c70f9 17073
f6f0e17b 17074 return display_tag_value (tag, p, end);
9e8c70f9
DM
17075}
17076
351cdf24 17077static void
32ec8896 17078print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
17079{
17080 switch (val)
17081 {
17082 case Val_GNU_MIPS_ABI_FP_ANY:
17083 printf (_("Hard or soft float\n"));
17084 break;
17085 case Val_GNU_MIPS_ABI_FP_DOUBLE:
17086 printf (_("Hard float (double precision)\n"));
17087 break;
17088 case Val_GNU_MIPS_ABI_FP_SINGLE:
17089 printf (_("Hard float (single precision)\n"));
17090 break;
17091 case Val_GNU_MIPS_ABI_FP_SOFT:
17092 printf (_("Soft float\n"));
17093 break;
17094 case Val_GNU_MIPS_ABI_FP_OLD_64:
17095 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
17096 break;
17097 case Val_GNU_MIPS_ABI_FP_XX:
17098 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
17099 break;
17100 case Val_GNU_MIPS_ABI_FP_64:
17101 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
17102 break;
17103 case Val_GNU_MIPS_ABI_FP_64A:
17104 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
17105 break;
3350cc01
CM
17106 case Val_GNU_MIPS_ABI_FP_NAN2008:
17107 printf (_("NaN 2008 compatibility\n"));
17108 break;
351cdf24
MF
17109 default:
17110 printf ("??? (%d)\n", val);
17111 break;
17112 }
17113}
17114
2cf19d5c 17115static unsigned char *
f6f0e17b 17116display_mips_gnu_attribute (unsigned char * p,
60abdbed 17117 unsigned int tag,
f6f0e17b 17118 const unsigned char * const end)
2cf19d5c 17119{
2cf19d5c
JM
17120 if (tag == Tag_GNU_MIPS_ABI_FP)
17121 {
32ec8896 17122 unsigned int val;
f6f0e17b 17123
2cf19d5c 17124 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 17125 READ_ULEB (val, p, end);
351cdf24 17126 print_mips_fp_abi_value (val);
2cf19d5c
JM
17127 return p;
17128 }
17129
a9f58168
CF
17130 if (tag == Tag_GNU_MIPS_ABI_MSA)
17131 {
32ec8896 17132 unsigned int val;
a9f58168 17133
a9f58168 17134 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 17135 READ_ULEB (val, p, end);
a9f58168
CF
17136
17137 switch (val)
17138 {
17139 case Val_GNU_MIPS_ABI_MSA_ANY:
17140 printf (_("Any MSA or not\n"));
17141 break;
17142 case Val_GNU_MIPS_ABI_MSA_128:
17143 printf (_("128-bit MSA\n"));
17144 break;
17145 default:
17146 printf ("??? (%d)\n", val);
17147 break;
17148 }
17149 return p;
17150 }
17151
f6f0e17b 17152 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
17153}
17154
59e6276b 17155static unsigned char *
f6f0e17b
NC
17156display_tic6x_attribute (unsigned char * p,
17157 const unsigned char * const end)
59e6276b 17158{
60abdbed 17159 unsigned int tag;
cd30bcef 17160 unsigned int val;
59e6276b 17161
cd30bcef 17162 READ_ULEB (tag, p, end);
59e6276b
JM
17163
17164 switch (tag)
17165 {
75fa6dc1 17166 case Tag_ISA:
75fa6dc1 17167 printf (" Tag_ISA: ");
cd30bcef 17168 READ_ULEB (val, p, end);
59e6276b
JM
17169
17170 switch (val)
17171 {
75fa6dc1 17172 case C6XABI_Tag_ISA_none:
59e6276b
JM
17173 printf (_("None\n"));
17174 break;
75fa6dc1 17175 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
17176 printf ("C62x\n");
17177 break;
75fa6dc1 17178 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
17179 printf ("C67x\n");
17180 break;
75fa6dc1 17181 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
17182 printf ("C67x+\n");
17183 break;
75fa6dc1 17184 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
17185 printf ("C64x\n");
17186 break;
75fa6dc1 17187 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
17188 printf ("C64x+\n");
17189 break;
75fa6dc1 17190 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
17191 printf ("C674x\n");
17192 break;
17193 default:
17194 printf ("??? (%d)\n", val);
17195 break;
17196 }
17197 return p;
17198
87779176 17199 case Tag_ABI_wchar_t:
87779176 17200 printf (" Tag_ABI_wchar_t: ");
cd30bcef 17201 READ_ULEB (val, p, end);
87779176
JM
17202 switch (val)
17203 {
17204 case 0:
17205 printf (_("Not used\n"));
17206 break;
17207 case 1:
17208 printf (_("2 bytes\n"));
17209 break;
17210 case 2:
17211 printf (_("4 bytes\n"));
17212 break;
17213 default:
17214 printf ("??? (%d)\n", val);
17215 break;
17216 }
17217 return p;
17218
17219 case Tag_ABI_stack_align_needed:
87779176 17220 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 17221 READ_ULEB (val, p, end);
87779176
JM
17222 switch (val)
17223 {
17224 case 0:
17225 printf (_("8-byte\n"));
17226 break;
17227 case 1:
17228 printf (_("16-byte\n"));
17229 break;
17230 default:
17231 printf ("??? (%d)\n", val);
17232 break;
17233 }
17234 return p;
17235
17236 case Tag_ABI_stack_align_preserved:
cd30bcef 17237 READ_ULEB (val, p, end);
87779176
JM
17238 printf (" Tag_ABI_stack_align_preserved: ");
17239 switch (val)
17240 {
17241 case 0:
17242 printf (_("8-byte\n"));
17243 break;
17244 case 1:
17245 printf (_("16-byte\n"));
17246 break;
17247 default:
17248 printf ("??? (%d)\n", val);
17249 break;
17250 }
17251 return p;
17252
b5593623 17253 case Tag_ABI_DSBT:
cd30bcef 17254 READ_ULEB (val, p, end);
b5593623
JM
17255 printf (" Tag_ABI_DSBT: ");
17256 switch (val)
17257 {
17258 case 0:
17259 printf (_("DSBT addressing not used\n"));
17260 break;
17261 case 1:
17262 printf (_("DSBT addressing used\n"));
17263 break;
17264 default:
17265 printf ("??? (%d)\n", val);
17266 break;
17267 }
17268 return p;
17269
87779176 17270 case Tag_ABI_PID:
cd30bcef 17271 READ_ULEB (val, p, end);
87779176
JM
17272 printf (" Tag_ABI_PID: ");
17273 switch (val)
17274 {
17275 case 0:
17276 printf (_("Data addressing position-dependent\n"));
17277 break;
17278 case 1:
17279 printf (_("Data addressing position-independent, GOT near DP\n"));
17280 break;
17281 case 2:
17282 printf (_("Data addressing position-independent, GOT far from DP\n"));
17283 break;
17284 default:
17285 printf ("??? (%d)\n", val);
17286 break;
17287 }
17288 return p;
17289
17290 case Tag_ABI_PIC:
cd30bcef 17291 READ_ULEB (val, p, end);
87779176
JM
17292 printf (" Tag_ABI_PIC: ");
17293 switch (val)
17294 {
17295 case 0:
17296 printf (_("Code addressing position-dependent\n"));
17297 break;
17298 case 1:
17299 printf (_("Code addressing position-independent\n"));
17300 break;
17301 default:
17302 printf ("??? (%d)\n", val);
17303 break;
17304 }
17305 return p;
17306
17307 case Tag_ABI_array_object_alignment:
cd30bcef 17308 READ_ULEB (val, p, end);
87779176
JM
17309 printf (" Tag_ABI_array_object_alignment: ");
17310 switch (val)
17311 {
17312 case 0:
17313 printf (_("8-byte\n"));
17314 break;
17315 case 1:
17316 printf (_("4-byte\n"));
17317 break;
17318 case 2:
17319 printf (_("16-byte\n"));
17320 break;
17321 default:
17322 printf ("??? (%d)\n", val);
17323 break;
17324 }
17325 return p;
17326
17327 case Tag_ABI_array_object_align_expected:
cd30bcef 17328 READ_ULEB (val, p, end);
87779176
JM
17329 printf (" Tag_ABI_array_object_align_expected: ");
17330 switch (val)
17331 {
17332 case 0:
17333 printf (_("8-byte\n"));
17334 break;
17335 case 1:
17336 printf (_("4-byte\n"));
17337 break;
17338 case 2:
17339 printf (_("16-byte\n"));
17340 break;
17341 default:
17342 printf ("??? (%d)\n", val);
17343 break;
17344 }
17345 return p;
17346
3cbd1c06 17347 case Tag_ABI_compatibility:
071436c6 17348 {
cd30bcef 17349 READ_ULEB (val, p, end);
071436c6 17350 printf (" Tag_ABI_compatibility: ");
071436c6 17351 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
17352 if (p < end - 1)
17353 {
17354 size_t maxlen = (end - p) - 1;
17355
17356 print_symbol ((int) maxlen, (const char *) p);
17357 p += strnlen ((char *) p, maxlen) + 1;
17358 }
17359 else
17360 {
17361 printf (_("<corrupt>"));
17362 p = (unsigned char *) end;
17363 }
071436c6 17364 putchar ('\n');
071436c6
NC
17365 return p;
17366 }
87779176
JM
17367
17368 case Tag_ABI_conformance:
071436c6 17369 {
4082ef84
NC
17370 printf (" Tag_ABI_conformance: \"");
17371 if (p < end - 1)
17372 {
17373 size_t maxlen = (end - p) - 1;
071436c6 17374
4082ef84
NC
17375 print_symbol ((int) maxlen, (const char *) p);
17376 p += strnlen ((char *) p, maxlen) + 1;
17377 }
17378 else
17379 {
17380 printf (_("<corrupt>"));
17381 p = (unsigned char *) end;
17382 }
071436c6 17383 printf ("\"\n");
071436c6
NC
17384 return p;
17385 }
59e6276b
JM
17386 }
17387
f6f0e17b
NC
17388 return display_tag_value (tag, p, end);
17389}
59e6276b 17390
f6f0e17b 17391static void
60abdbed 17392display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17393{
17394 unsigned long addr = 0;
17395 size_t bytes = end - p;
17396
feceaa59 17397 assert (end >= p);
f6f0e17b 17398 while (bytes)
87779176 17399 {
f6f0e17b
NC
17400 int j;
17401 int k;
17402 int lbytes = (bytes > 16 ? 16 : bytes);
17403
17404 printf (" 0x%8.8lx ", addr);
17405
17406 for (j = 0; j < 16; j++)
17407 {
17408 if (j < lbytes)
17409 printf ("%2.2x", p[j]);
17410 else
17411 printf (" ");
17412
17413 if ((j & 3) == 3)
17414 printf (" ");
17415 }
17416
17417 for (j = 0; j < lbytes; j++)
17418 {
17419 k = p[j];
17420 if (k >= ' ' && k < 0x7f)
17421 printf ("%c", k);
17422 else
17423 printf (".");
17424 }
17425
17426 putchar ('\n');
17427
17428 p += lbytes;
17429 bytes -= lbytes;
17430 addr += lbytes;
87779176 17431 }
59e6276b 17432
f6f0e17b 17433 putchar ('\n');
59e6276b
JM
17434}
17435
13761a11 17436static unsigned char *
b0191216 17437display_msp430_attribute (unsigned char * p,
13761a11
NC
17438 const unsigned char * const end)
17439{
60abdbed
NC
17440 unsigned int val;
17441 unsigned int tag;
13761a11 17442
cd30bcef 17443 READ_ULEB (tag, p, end);
0b4362b0 17444
13761a11
NC
17445 switch (tag)
17446 {
17447 case OFBA_MSPABI_Tag_ISA:
13761a11 17448 printf (" Tag_ISA: ");
cd30bcef 17449 READ_ULEB (val, p, end);
13761a11
NC
17450 switch (val)
17451 {
17452 case 0: printf (_("None\n")); break;
17453 case 1: printf (_("MSP430\n")); break;
17454 case 2: printf (_("MSP430X\n")); break;
17455 default: printf ("??? (%d)\n", val); break;
17456 }
17457 break;
17458
17459 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17460 printf (" Tag_Code_Model: ");
cd30bcef 17461 READ_ULEB (val, p, end);
13761a11
NC
17462 switch (val)
17463 {
17464 case 0: printf (_("None\n")); break;
17465 case 1: printf (_("Small\n")); break;
17466 case 2: printf (_("Large\n")); break;
17467 default: printf ("??? (%d)\n", val); break;
17468 }
17469 break;
17470
17471 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17472 printf (" Tag_Data_Model: ");
cd30bcef 17473 READ_ULEB (val, p, end);
13761a11
NC
17474 switch (val)
17475 {
17476 case 0: printf (_("None\n")); break;
17477 case 1: printf (_("Small\n")); break;
17478 case 2: printf (_("Large\n")); break;
17479 case 3: printf (_("Restricted Large\n")); break;
17480 default: printf ("??? (%d)\n", val); break;
17481 }
17482 break;
17483
17484 default:
17485 printf (_(" <unknown tag %d>: "), tag);
17486
17487 if (tag & 1)
17488 {
071436c6 17489 putchar ('"');
4082ef84
NC
17490 if (p < end - 1)
17491 {
17492 size_t maxlen = (end - p) - 1;
17493
17494 print_symbol ((int) maxlen, (const char *) p);
17495 p += strnlen ((char *) p, maxlen) + 1;
17496 }
17497 else
17498 {
17499 printf (_("<corrupt>"));
17500 p = (unsigned char *) end;
17501 }
071436c6 17502 printf ("\"\n");
13761a11
NC
17503 }
17504 else
17505 {
cd30bcef 17506 READ_ULEB (val, p, end);
13761a11
NC
17507 printf ("%d (0x%x)\n", val, val);
17508 }
17509 break;
17510 }
17511
4082ef84 17512 assert (p <= end);
13761a11
NC
17513 return p;
17514}
17515
c0ea7c52
JL
17516static unsigned char *
17517display_msp430_gnu_attribute (unsigned char * p,
17518 unsigned int tag,
17519 const unsigned char * const end)
17520{
17521 if (tag == Tag_GNU_MSP430_Data_Region)
17522 {
cd30bcef 17523 unsigned int val;
c0ea7c52 17524
c0ea7c52 17525 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17526 READ_ULEB (val, p, end);
c0ea7c52
JL
17527
17528 switch (val)
17529 {
17530 case Val_GNU_MSP430_Data_Region_Any:
17531 printf (_("Any Region\n"));
17532 break;
17533 case Val_GNU_MSP430_Data_Region_Lower:
17534 printf (_("Lower Region Only\n"));
17535 break;
17536 default:
cd30bcef 17537 printf ("??? (%u)\n", val);
c0ea7c52
JL
17538 }
17539 return p;
17540 }
17541 return display_tag_value (tag & 1, p, end);
17542}
17543
2dc8dd17
JW
17544struct riscv_attr_tag_t {
17545 const char *name;
cd30bcef 17546 unsigned int tag;
2dc8dd17
JW
17547};
17548
17549static struct riscv_attr_tag_t riscv_attr_tag[] =
17550{
17551#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17552 T(arch),
17553 T(priv_spec),
17554 T(priv_spec_minor),
17555 T(priv_spec_revision),
17556 T(unaligned_access),
17557 T(stack_align),
17558#undef T
17559};
17560
17561static unsigned char *
17562display_riscv_attribute (unsigned char *p,
17563 const unsigned char * const end)
17564{
cd30bcef
AM
17565 unsigned int val;
17566 unsigned int tag;
2dc8dd17
JW
17567 struct riscv_attr_tag_t *attr = NULL;
17568 unsigned i;
17569
cd30bcef 17570 READ_ULEB (tag, p, end);
2dc8dd17
JW
17571
17572 /* Find the name of attribute. */
17573 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17574 {
17575 if (riscv_attr_tag[i].tag == tag)
17576 {
17577 attr = &riscv_attr_tag[i];
17578 break;
17579 }
17580 }
17581
17582 if (attr)
17583 printf (" %s: ", attr->name);
17584 else
17585 return display_tag_value (tag, p, end);
17586
17587 switch (tag)
17588 {
17589 case Tag_RISCV_priv_spec:
17590 case Tag_RISCV_priv_spec_minor:
17591 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17592 READ_ULEB (val, p, end);
17593 printf (_("%u\n"), val);
2dc8dd17
JW
17594 break;
17595 case Tag_RISCV_unaligned_access:
cd30bcef 17596 READ_ULEB (val, p, end);
2dc8dd17
JW
17597 switch (val)
17598 {
17599 case 0:
17600 printf (_("No unaligned access\n"));
17601 break;
17602 case 1:
17603 printf (_("Unaligned access\n"));
17604 break;
17605 }
17606 break;
17607 case Tag_RISCV_stack_align:
cd30bcef
AM
17608 READ_ULEB (val, p, end);
17609 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17610 break;
17611 case Tag_RISCV_arch:
17612 p = display_tag_value (-1, p, end);
17613 break;
17614 default:
17615 return display_tag_value (tag, p, end);
17616 }
17617
17618 return p;
17619}
17620
0861f561
CQ
17621static unsigned char *
17622display_csky_attribute (unsigned char * p,
17623 const unsigned char * const end)
17624{
17625 unsigned int tag;
17626 unsigned int val;
17627 READ_ULEB (tag, p, end);
17628
17629 if (tag >= Tag_CSKY_MAX)
17630 {
17631 return display_tag_value (-1, p, end);
17632 }
17633
17634 switch (tag)
17635 {
17636 case Tag_CSKY_ARCH_NAME:
17637 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17638 return display_tag_value (-1, p, end);
17639 case Tag_CSKY_CPU_NAME:
17640 printf (" Tag_CSKY_CPU_NAME:\t\t");
17641 return display_tag_value (-1, p, end);
17642
17643 case Tag_CSKY_ISA_FLAGS:
17644 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17645 return display_tag_value (0, p, end);
17646 case Tag_CSKY_ISA_EXT_FLAGS:
17647 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17648 return display_tag_value (0, p, end);
17649
17650 case Tag_CSKY_DSP_VERSION:
17651 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17652 READ_ULEB (val, p, end);
17653 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17654 printf ("DSP Extension\n");
17655 else if (val == VAL_CSKY_DSP_VERSION_2)
17656 printf ("DSP 2.0\n");
17657 break;
17658
17659 case Tag_CSKY_VDSP_VERSION:
17660 printf (" Tag_CSKY_VDSP_VERSION:\t");
17661 READ_ULEB (val, p, end);
17662 printf ("VDSP Version %d\n", val);
17663 break;
17664
17665 case Tag_CSKY_FPU_VERSION:
17666 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17667 READ_ULEB (val, p, end);
17668 if (val == VAL_CSKY_FPU_VERSION_1)
17669 printf ("ABIV1 FPU Version 1\n");
17670 else if (val == VAL_CSKY_FPU_VERSION_2)
17671 printf ("FPU Version 2\n");
17672 break;
17673
17674 case Tag_CSKY_FPU_ABI:
17675 printf (" Tag_CSKY_FPU_ABI:\t\t");
17676 READ_ULEB (val, p, end);
17677 if (val == VAL_CSKY_FPU_ABI_HARD)
17678 printf ("Hard\n");
17679 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17680 printf ("SoftFP\n");
17681 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17682 printf ("Soft\n");
17683 break;
17684 case Tag_CSKY_FPU_ROUNDING:
17685 READ_ULEB (val, p, end);
f253158f
NC
17686 if (val == 1)
17687 {
17688 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17689 printf ("Needed\n");
17690 }
0861f561
CQ
17691 break;
17692 case Tag_CSKY_FPU_DENORMAL:
17693 READ_ULEB (val, p, end);
f253158f
NC
17694 if (val == 1)
17695 {
17696 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17697 printf ("Needed\n");
17698 }
0861f561
CQ
17699 break;
17700 case Tag_CSKY_FPU_Exception:
17701 READ_ULEB (val, p, end);
f253158f
NC
17702 if (val == 1)
17703 {
17704 printf (" Tag_CSKY_FPU_Exception:\t");
17705 printf ("Needed\n");
17706 }
0861f561
CQ
17707 break;
17708 case Tag_CSKY_FPU_NUMBER_MODULE:
17709 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17710 return display_tag_value (-1, p, end);
17711 case Tag_CSKY_FPU_HARDFP:
17712 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17713 READ_ULEB (val, p, end);
17714 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17715 printf (" Half");
17716 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17717 printf (" Single");
17718 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17719 printf (" Double");
17720 printf ("\n");
17721 break;
17722 default:
17723 return display_tag_value (tag, p, end);
17724 }
17725 return p;
17726}
17727
015dc7e1 17728static bool
dda8d76d 17729process_attributes (Filedata * filedata,
60bca95a 17730 const char * public_name,
104d59d1 17731 unsigned int proc_type,
f6f0e17b 17732 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17733 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17734{
2cf0635d 17735 Elf_Internal_Shdr * sect;
11c1ff18 17736 unsigned i;
015dc7e1 17737 bool res = true;
11c1ff18
PB
17738
17739 /* Find the section header so that we get the size. */
dda8d76d
NC
17740 for (i = 0, sect = filedata->section_headers;
17741 i < filedata->file_header.e_shnum;
11c1ff18
PB
17742 i++, sect++)
17743 {
071436c6
NC
17744 unsigned char * contents;
17745 unsigned char * p;
17746
104d59d1 17747 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17748 continue;
17749
dda8d76d 17750 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17751 sect->sh_size, _("attributes"));
60bca95a 17752 if (contents == NULL)
32ec8896 17753 {
015dc7e1 17754 res = false;
32ec8896
NC
17755 continue;
17756 }
60bca95a 17757
11c1ff18 17758 p = contents;
60abdbed
NC
17759 /* The first character is the version of the attributes.
17760 Currently only version 1, (aka 'A') is recognised here. */
17761 if (*p != 'A')
32ec8896
NC
17762 {
17763 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17764 res = false;
32ec8896 17765 }
60abdbed 17766 else
11c1ff18 17767 {
071436c6
NC
17768 bfd_vma section_len;
17769
17770 section_len = sect->sh_size - 1;
11c1ff18 17771 p++;
60bca95a 17772
071436c6 17773 while (section_len > 0)
11c1ff18 17774 {
071436c6 17775 bfd_vma attr_len;
e9847026 17776 unsigned int namelen;
015dc7e1
AM
17777 bool public_section;
17778 bool gnu_section;
11c1ff18 17779
071436c6 17780 if (section_len <= 4)
e0a31db1
NC
17781 {
17782 error (_("Tag section ends prematurely\n"));
015dc7e1 17783 res = false;
e0a31db1
NC
17784 break;
17785 }
071436c6 17786 attr_len = byte_get (p, 4);
11c1ff18 17787 p += 4;
60bca95a 17788
071436c6 17789 if (attr_len > section_len)
11c1ff18 17790 {
071436c6
NC
17791 error (_("Bad attribute length (%u > %u)\n"),
17792 (unsigned) attr_len, (unsigned) section_len);
17793 attr_len = section_len;
015dc7e1 17794 res = false;
11c1ff18 17795 }
74e1a04b 17796 /* PR 17531: file: 001-101425-0.004 */
071436c6 17797 else if (attr_len < 5)
74e1a04b 17798 {
071436c6 17799 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17800 res = false;
74e1a04b
NC
17801 break;
17802 }
e9847026 17803
071436c6
NC
17804 section_len -= attr_len;
17805 attr_len -= 4;
17806
17807 namelen = strnlen ((char *) p, attr_len) + 1;
17808 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17809 {
17810 error (_("Corrupt attribute section name\n"));
015dc7e1 17811 res = false;
e9847026
NC
17812 break;
17813 }
17814
071436c6
NC
17815 printf (_("Attribute Section: "));
17816 print_symbol (INT_MAX, (const char *) p);
17817 putchar ('\n');
60bca95a
NC
17818
17819 if (public_name && streq ((char *) p, public_name))
015dc7e1 17820 public_section = true;
11c1ff18 17821 else
015dc7e1 17822 public_section = false;
60bca95a
NC
17823
17824 if (streq ((char *) p, "gnu"))
015dc7e1 17825 gnu_section = true;
104d59d1 17826 else
015dc7e1 17827 gnu_section = false;
60bca95a 17828
11c1ff18 17829 p += namelen;
071436c6 17830 attr_len -= namelen;
e0a31db1 17831
071436c6 17832 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17833 {
e0a31db1 17834 int tag;
cd30bcef 17835 unsigned int val;
11c1ff18 17836 bfd_vma size;
071436c6 17837 unsigned char * end;
60bca95a 17838
e0a31db1 17839 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17840 if (attr_len < 6)
e0a31db1
NC
17841 {
17842 error (_("Unused bytes at end of section\n"));
015dc7e1 17843 res = false;
e0a31db1
NC
17844 section_len = 0;
17845 break;
17846 }
17847
17848 tag = *(p++);
11c1ff18 17849 size = byte_get (p, 4);
071436c6 17850 if (size > attr_len)
11c1ff18 17851 {
e9847026 17852 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17853 (unsigned) size, (unsigned) attr_len);
015dc7e1 17854 res = false;
071436c6 17855 size = attr_len;
11c1ff18 17856 }
e0a31db1
NC
17857 /* PR binutils/17531: Safe handling of corrupt files. */
17858 if (size < 6)
17859 {
17860 error (_("Bad subsection length (%u < 6)\n"),
17861 (unsigned) size);
015dc7e1 17862 res = false;
e0a31db1
NC
17863 section_len = 0;
17864 break;
17865 }
60bca95a 17866
071436c6 17867 attr_len -= size;
11c1ff18 17868 end = p + size - 1;
071436c6 17869 assert (end <= contents + sect->sh_size);
11c1ff18 17870 p += 4;
60bca95a 17871
11c1ff18
PB
17872 switch (tag)
17873 {
17874 case 1:
2b692964 17875 printf (_("File Attributes\n"));
11c1ff18
PB
17876 break;
17877 case 2:
2b692964 17878 printf (_("Section Attributes:"));
11c1ff18
PB
17879 goto do_numlist;
17880 case 3:
2b692964 17881 printf (_("Symbol Attributes:"));
1a0670f3 17882 /* Fall through. */
11c1ff18
PB
17883 do_numlist:
17884 for (;;)
17885 {
cd30bcef 17886 READ_ULEB (val, p, end);
11c1ff18
PB
17887 if (val == 0)
17888 break;
17889 printf (" %d", val);
17890 }
17891 printf ("\n");
17892 break;
17893 default:
2b692964 17894 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17895 public_section = false;
11c1ff18
PB
17896 break;
17897 }
60bca95a 17898
071436c6 17899 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17900 {
17901 while (p < end)
f6f0e17b 17902 p = display_pub_attribute (p, end);
60abdbed 17903 assert (p == end);
104d59d1 17904 }
071436c6 17905 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17906 {
17907 while (p < end)
17908 p = display_gnu_attribute (p,
f6f0e17b
NC
17909 display_proc_gnu_attribute,
17910 end);
60abdbed 17911 assert (p == end);
11c1ff18 17912 }
071436c6 17913 else if (p < end)
11c1ff18 17914 {
071436c6 17915 printf (_(" Unknown attribute:\n"));
f6f0e17b 17916 display_raw_attribute (p, end);
11c1ff18
PB
17917 p = end;
17918 }
071436c6
NC
17919 else
17920 attr_len = 0;
11c1ff18
PB
17921 }
17922 }
17923 }
d70c5fc7 17924
60bca95a 17925 free (contents);
11c1ff18 17926 }
32ec8896
NC
17927
17928 return res;
11c1ff18
PB
17929}
17930
ccb4c951
RS
17931/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17932 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17933 and return the VMA of the next entry, or -1 if there was a problem.
17934 Does not read from DATA_END or beyond. */
ccb4c951
RS
17935
17936static bfd_vma
82b1b41b
NC
17937print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17938 unsigned char * data_end)
ccb4c951
RS
17939{
17940 printf (" ");
17941 print_vma (addr, LONG_HEX);
17942 printf (" ");
17943 if (addr < pltgot + 0xfff0)
17944 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17945 else
17946 printf ("%10s", "");
17947 printf (" ");
17948 if (data == NULL)
2b692964 17949 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17950 else
17951 {
17952 bfd_vma entry;
82b1b41b 17953 unsigned char * from = data + addr - pltgot;
ccb4c951 17954
82b1b41b
NC
17955 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17956 {
17957 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17958 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17959 return (bfd_vma) -1;
17960 }
17961 else
17962 {
17963 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17964 print_vma (entry, LONG_HEX);
17965 }
ccb4c951
RS
17966 }
17967 return addr + (is_32bit_elf ? 4 : 8);
17968}
17969
861fb55a
DJ
17970/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17971 PLTGOT. Print the Address and Initial fields of an entry at VMA
17972 ADDR and return the VMA of the next entry. */
17973
17974static bfd_vma
2cf0635d 17975print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17976{
17977 printf (" ");
17978 print_vma (addr, LONG_HEX);
17979 printf (" ");
17980 if (data == NULL)
2b692964 17981 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17982 else
17983 {
17984 bfd_vma entry;
17985
17986 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17987 print_vma (entry, LONG_HEX);
17988 }
17989 return addr + (is_32bit_elf ? 4 : 8);
17990}
17991
351cdf24
MF
17992static void
17993print_mips_ases (unsigned int mask)
17994{
17995 if (mask & AFL_ASE_DSP)
17996 fputs ("\n\tDSP ASE", stdout);
17997 if (mask & AFL_ASE_DSPR2)
17998 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17999 if (mask & AFL_ASE_DSPR3)
18000 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
18001 if (mask & AFL_ASE_EVA)
18002 fputs ("\n\tEnhanced VA Scheme", stdout);
18003 if (mask & AFL_ASE_MCU)
18004 fputs ("\n\tMCU (MicroController) ASE", stdout);
18005 if (mask & AFL_ASE_MDMX)
18006 fputs ("\n\tMDMX ASE", stdout);
18007 if (mask & AFL_ASE_MIPS3D)
18008 fputs ("\n\tMIPS-3D ASE", stdout);
18009 if (mask & AFL_ASE_MT)
18010 fputs ("\n\tMT ASE", stdout);
18011 if (mask & AFL_ASE_SMARTMIPS)
18012 fputs ("\n\tSmartMIPS ASE", stdout);
18013 if (mask & AFL_ASE_VIRT)
18014 fputs ("\n\tVZ ASE", stdout);
18015 if (mask & AFL_ASE_MSA)
18016 fputs ("\n\tMSA ASE", stdout);
18017 if (mask & AFL_ASE_MIPS16)
18018 fputs ("\n\tMIPS16 ASE", stdout);
18019 if (mask & AFL_ASE_MICROMIPS)
18020 fputs ("\n\tMICROMIPS ASE", stdout);
18021 if (mask & AFL_ASE_XPA)
18022 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
18023 if (mask & AFL_ASE_MIPS16E2)
18024 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
18025 if (mask & AFL_ASE_CRC)
18026 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
18027 if (mask & AFL_ASE_GINV)
18028 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
18029 if (mask & AFL_ASE_LOONGSON_MMI)
18030 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
18031 if (mask & AFL_ASE_LOONGSON_CAM)
18032 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
18033 if (mask & AFL_ASE_LOONGSON_EXT)
18034 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
18035 if (mask & AFL_ASE_LOONGSON_EXT2)
18036 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
18037 if (mask == 0)
18038 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
18039 else if ((mask & ~AFL_ASE_MASK) != 0)
18040 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
18041}
18042
18043static void
18044print_mips_isa_ext (unsigned int isa_ext)
18045{
18046 switch (isa_ext)
18047 {
18048 case 0:
18049 fputs (_("None"), stdout);
18050 break;
18051 case AFL_EXT_XLR:
18052 fputs ("RMI XLR", stdout);
18053 break;
2c629856
N
18054 case AFL_EXT_OCTEON3:
18055 fputs ("Cavium Networks Octeon3", stdout);
18056 break;
351cdf24
MF
18057 case AFL_EXT_OCTEON2:
18058 fputs ("Cavium Networks Octeon2", stdout);
18059 break;
18060 case AFL_EXT_OCTEONP:
18061 fputs ("Cavium Networks OcteonP", stdout);
18062 break;
351cdf24
MF
18063 case AFL_EXT_OCTEON:
18064 fputs ("Cavium Networks Octeon", stdout);
18065 break;
18066 case AFL_EXT_5900:
18067 fputs ("Toshiba R5900", stdout);
18068 break;
18069 case AFL_EXT_4650:
18070 fputs ("MIPS R4650", stdout);
18071 break;
18072 case AFL_EXT_4010:
18073 fputs ("LSI R4010", stdout);
18074 break;
18075 case AFL_EXT_4100:
18076 fputs ("NEC VR4100", stdout);
18077 break;
18078 case AFL_EXT_3900:
18079 fputs ("Toshiba R3900", stdout);
18080 break;
18081 case AFL_EXT_10000:
18082 fputs ("MIPS R10000", stdout);
18083 break;
18084 case AFL_EXT_SB1:
18085 fputs ("Broadcom SB-1", stdout);
18086 break;
18087 case AFL_EXT_4111:
18088 fputs ("NEC VR4111/VR4181", stdout);
18089 break;
18090 case AFL_EXT_4120:
18091 fputs ("NEC VR4120", stdout);
18092 break;
18093 case AFL_EXT_5400:
18094 fputs ("NEC VR5400", stdout);
18095 break;
18096 case AFL_EXT_5500:
18097 fputs ("NEC VR5500", stdout);
18098 break;
18099 case AFL_EXT_LOONGSON_2E:
18100 fputs ("ST Microelectronics Loongson 2E", stdout);
18101 break;
18102 case AFL_EXT_LOONGSON_2F:
18103 fputs ("ST Microelectronics Loongson 2F", stdout);
18104 break;
38bf472a
MR
18105 case AFL_EXT_INTERAPTIV_MR2:
18106 fputs ("Imagination interAptiv MR2", stdout);
18107 break;
351cdf24 18108 default:
00ac7aa0 18109 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
18110 }
18111}
18112
32ec8896 18113static signed int
351cdf24
MF
18114get_mips_reg_size (int reg_size)
18115{
18116 return (reg_size == AFL_REG_NONE) ? 0
18117 : (reg_size == AFL_REG_32) ? 32
18118 : (reg_size == AFL_REG_64) ? 64
18119 : (reg_size == AFL_REG_128) ? 128
18120 : -1;
18121}
18122
015dc7e1 18123static bool
dda8d76d 18124process_mips_specific (Filedata * filedata)
5b18a4bc 18125{
2cf0635d 18126 Elf_Internal_Dyn * entry;
351cdf24 18127 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
18128 size_t liblist_offset = 0;
18129 size_t liblistno = 0;
18130 size_t conflictsno = 0;
18131 size_t options_offset = 0;
18132 size_t conflicts_offset = 0;
861fb55a
DJ
18133 size_t pltrelsz = 0;
18134 size_t pltrel = 0;
ccb4c951 18135 bfd_vma pltgot = 0;
861fb55a
DJ
18136 bfd_vma mips_pltgot = 0;
18137 bfd_vma jmprel = 0;
ccb4c951
RS
18138 bfd_vma local_gotno = 0;
18139 bfd_vma gotsym = 0;
18140 bfd_vma symtabno = 0;
015dc7e1 18141 bool res = true;
103f02d3 18142
dda8d76d 18143 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 18144 display_mips_gnu_attribute))
015dc7e1 18145 res = false;
2cf19d5c 18146
dda8d76d 18147 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
18148
18149 if (sect != NULL)
18150 {
18151 Elf_External_ABIFlags_v0 *abiflags_ext;
18152 Elf_Internal_ABIFlags_v0 abiflags_in;
18153
18154 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
18155 {
18156 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 18157 res = false;
32ec8896 18158 }
351cdf24
MF
18159 else
18160 {
dda8d76d 18161 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
18162 sect->sh_size, _("MIPS ABI Flags section"));
18163 if (abiflags_ext)
18164 {
18165 abiflags_in.version = BYTE_GET (abiflags_ext->version);
18166 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
18167 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
18168 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
18169 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
18170 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
18171 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
18172 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
18173 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
18174 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
18175 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
18176
18177 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
18178 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
18179 if (abiflags_in.isa_rev > 1)
18180 printf ("r%d", abiflags_in.isa_rev);
18181 printf ("\nGPR size: %d",
18182 get_mips_reg_size (abiflags_in.gpr_size));
18183 printf ("\nCPR1 size: %d",
18184 get_mips_reg_size (abiflags_in.cpr1_size));
18185 printf ("\nCPR2 size: %d",
18186 get_mips_reg_size (abiflags_in.cpr2_size));
18187 fputs ("\nFP ABI: ", stdout);
18188 print_mips_fp_abi_value (abiflags_in.fp_abi);
18189 fputs ("ISA Extension: ", stdout);
18190 print_mips_isa_ext (abiflags_in.isa_ext);
18191 fputs ("\nASEs:", stdout);
18192 print_mips_ases (abiflags_in.ases);
18193 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
18194 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
18195 fputc ('\n', stdout);
18196 free (abiflags_ext);
18197 }
18198 }
18199 }
18200
19e6b90e 18201 /* We have a lot of special sections. Thanks SGI! */
978c4450 18202 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
18203 {
18204 /* No dynamic information available. See if there is static GOT. */
dda8d76d 18205 sect = find_section (filedata, ".got");
bbdd9a68
MR
18206 if (sect != NULL)
18207 {
18208 unsigned char *data_end;
18209 unsigned char *data;
18210 bfd_vma ent, end;
18211 int addr_size;
18212
18213 pltgot = sect->sh_addr;
18214
18215 ent = pltgot;
18216 addr_size = (is_32bit_elf ? 4 : 8);
18217 end = pltgot + sect->sh_size;
18218
dda8d76d 18219 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
18220 end - pltgot, 1,
18221 _("Global Offset Table data"));
18222 /* PR 12855: Null data is handled gracefully throughout. */
18223 data_end = data + (end - pltgot);
18224
18225 printf (_("\nStatic GOT:\n"));
18226 printf (_(" Canonical gp value: "));
18227 print_vma (ent + 0x7ff0, LONG_HEX);
18228 printf ("\n\n");
18229
18230 /* In a dynamic binary GOT[0] is reserved for the dynamic
18231 loader to store the lazy resolver pointer, however in
18232 a static binary it may well have been omitted and GOT
18233 reduced to a table of addresses.
18234 PR 21344: Check for the entry being fully available
18235 before fetching it. */
18236 if (data
18237 && data + ent - pltgot + addr_size <= data_end
18238 && byte_get (data + ent - pltgot, addr_size) == 0)
18239 {
18240 printf (_(" Reserved entries:\n"));
18241 printf (_(" %*s %10s %*s\n"),
18242 addr_size * 2, _("Address"), _("Access"),
18243 addr_size * 2, _("Value"));
18244 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18245 printf ("\n");
18246 if (ent == (bfd_vma) -1)
18247 goto sgot_print_fail;
18248
18249 /* Check for the MSB of GOT[1] being set, identifying a
18250 GNU object. This entry will be used by some runtime
18251 loaders, to store the module pointer. Otherwise this
18252 is an ordinary local entry.
18253 PR 21344: Check for the entry being fully available
18254 before fetching it. */
18255 if (data
18256 && data + ent - pltgot + addr_size <= data_end
18257 && (byte_get (data + ent - pltgot, addr_size)
18258 >> (addr_size * 8 - 1)) != 0)
18259 {
18260 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18261 printf ("\n");
18262 if (ent == (bfd_vma) -1)
18263 goto sgot_print_fail;
18264 }
18265 printf ("\n");
18266 }
18267
f17e9d8a 18268 if (data != NULL && ent < end)
bbdd9a68
MR
18269 {
18270 printf (_(" Local entries:\n"));
18271 printf (" %*s %10s %*s\n",
18272 addr_size * 2, _("Address"), _("Access"),
18273 addr_size * 2, _("Value"));
18274 while (ent < end)
18275 {
18276 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18277 printf ("\n");
18278 if (ent == (bfd_vma) -1)
18279 goto sgot_print_fail;
18280 }
18281 printf ("\n");
18282 }
18283
18284 sgot_print_fail:
9db70fc3 18285 free (data);
bbdd9a68
MR
18286 }
18287 return res;
18288 }
252b5132 18289
978c4450 18290 for (entry = filedata->dynamic_section;
071436c6 18291 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
18292 (entry < filedata->dynamic_section + filedata->dynamic_nent
18293 && entry->d_tag != DT_NULL);
071436c6 18294 ++entry)
252b5132
RH
18295 switch (entry->d_tag)
18296 {
18297 case DT_MIPS_LIBLIST:
d93f0186 18298 liblist_offset
dda8d76d 18299 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18300 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
18301 break;
18302 case DT_MIPS_LIBLISTNO:
18303 liblistno = entry->d_un.d_val;
18304 break;
18305 case DT_MIPS_OPTIONS:
dda8d76d 18306 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
18307 break;
18308 case DT_MIPS_CONFLICT:
d93f0186 18309 conflicts_offset
dda8d76d 18310 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 18311 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
18312 break;
18313 case DT_MIPS_CONFLICTNO:
18314 conflictsno = entry->d_un.d_val;
18315 break;
ccb4c951 18316 case DT_PLTGOT:
861fb55a
DJ
18317 pltgot = entry->d_un.d_ptr;
18318 break;
ccb4c951
RS
18319 case DT_MIPS_LOCAL_GOTNO:
18320 local_gotno = entry->d_un.d_val;
18321 break;
18322 case DT_MIPS_GOTSYM:
18323 gotsym = entry->d_un.d_val;
18324 break;
18325 case DT_MIPS_SYMTABNO:
18326 symtabno = entry->d_un.d_val;
18327 break;
861fb55a
DJ
18328 case DT_MIPS_PLTGOT:
18329 mips_pltgot = entry->d_un.d_ptr;
18330 break;
18331 case DT_PLTREL:
18332 pltrel = entry->d_un.d_val;
18333 break;
18334 case DT_PLTRELSZ:
18335 pltrelsz = entry->d_un.d_val;
18336 break;
18337 case DT_JMPREL:
18338 jmprel = entry->d_un.d_ptr;
18339 break;
252b5132
RH
18340 default:
18341 break;
18342 }
18343
18344 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
18345 {
2cf0635d 18346 Elf32_External_Lib * elib;
252b5132
RH
18347 size_t cnt;
18348
dda8d76d 18349 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
18350 sizeof (Elf32_External_Lib),
18351 liblistno,
18352 _("liblist section data"));
a6e9f9df 18353 if (elib)
252b5132 18354 {
d3a49aa8
AM
18355 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
18356 "\nSection '.liblist' contains %lu entries:\n",
18357 (unsigned long) liblistno),
a6e9f9df 18358 (unsigned long) liblistno);
2b692964 18359 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
18360 stdout);
18361
18362 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 18363 {
a6e9f9df 18364 Elf32_Lib liblist;
91d6fa6a 18365 time_t atime;
d5b07ef4 18366 char timebuf[128];
2cf0635d 18367 struct tm * tmp;
a6e9f9df
AM
18368
18369 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18370 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
18371 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18372 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18373 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18374
91d6fa6a 18375 tmp = gmtime (&atime);
e9e44622
JJ
18376 snprintf (timebuf, sizeof (timebuf),
18377 "%04u-%02u-%02uT%02u:%02u:%02u",
18378 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18379 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18380
31104126 18381 printf ("%3lu: ", (unsigned long) cnt);
84714f86
AM
18382 if (valid_dynamic_name (filedata, liblist.l_name))
18383 print_symbol (20, get_dynamic_name (filedata, liblist.l_name));
d79b3d50 18384 else
2b692964 18385 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18386 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18387 liblist.l_version);
a6e9f9df
AM
18388
18389 if (liblist.l_flags == 0)
2b692964 18390 puts (_(" NONE"));
a6e9f9df
AM
18391 else
18392 {
18393 static const struct
252b5132 18394 {
2cf0635d 18395 const char * name;
a6e9f9df 18396 int bit;
252b5132 18397 }
a6e9f9df
AM
18398 l_flags_vals[] =
18399 {
18400 { " EXACT_MATCH", LL_EXACT_MATCH },
18401 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18402 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18403 { " EXPORTS", LL_EXPORTS },
18404 { " DELAY_LOAD", LL_DELAY_LOAD },
18405 { " DELTA", LL_DELTA }
18406 };
18407 int flags = liblist.l_flags;
18408 size_t fcnt;
18409
60bca95a 18410 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18411 if ((flags & l_flags_vals[fcnt].bit) != 0)
18412 {
18413 fputs (l_flags_vals[fcnt].name, stdout);
18414 flags ^= l_flags_vals[fcnt].bit;
18415 }
18416 if (flags != 0)
18417 printf (" %#x", (unsigned int) flags);
252b5132 18418
a6e9f9df
AM
18419 puts ("");
18420 }
252b5132 18421 }
252b5132 18422
a6e9f9df
AM
18423 free (elib);
18424 }
32ec8896 18425 else
015dc7e1 18426 res = false;
252b5132
RH
18427 }
18428
18429 if (options_offset != 0)
18430 {
2cf0635d 18431 Elf_External_Options * eopt;
252b5132
RH
18432 size_t offset;
18433 int cnt;
18434
18435 /* Find the section header so that we get the size. */
dda8d76d 18436 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18437 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18438 if (sect == NULL)
18439 {
18440 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18441 return false;
071436c6 18442 }
7fc0c668
NC
18443 /* PR 24243 */
18444 if (sect->sh_size < sizeof (* eopt))
18445 {
18446 error (_("The MIPS options section is too small.\n"));
015dc7e1 18447 return false;
7fc0c668 18448 }
252b5132 18449
dda8d76d 18450 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18451 sect->sh_size, _("options"));
a6e9f9df 18452 if (eopt)
252b5132 18453 {
fd17d1e6 18454 Elf_Internal_Options option;
76da6bbe 18455
a6e9f9df 18456 offset = cnt = 0;
82b1b41b 18457 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18458 {
2cf0635d 18459 Elf_External_Options * eoption;
fd17d1e6 18460 unsigned int optsize;
252b5132 18461
a6e9f9df 18462 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18463
fd17d1e6 18464 optsize = BYTE_GET (eoption->size);
76da6bbe 18465
82b1b41b 18466 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18467 if (optsize < sizeof (* eopt)
18468 || optsize > sect->sh_size - offset)
82b1b41b 18469 {
645f43a8 18470 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18471 optsize);
645f43a8 18472 free (eopt);
015dc7e1 18473 return false;
82b1b41b 18474 }
fd17d1e6 18475 offset += optsize;
a6e9f9df
AM
18476 ++cnt;
18477 }
252b5132 18478
d3a49aa8
AM
18479 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18480 "\nSection '%s' contains %d entries:\n",
18481 cnt),
dda8d76d 18482 printable_section_name (filedata, sect), cnt);
76da6bbe 18483
82b1b41b 18484 offset = 0;
a6e9f9df 18485 while (cnt-- > 0)
252b5132 18486 {
a6e9f9df 18487 size_t len;
fd17d1e6
AM
18488 Elf_External_Options * eoption;
18489
18490 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18491
18492 option.kind = BYTE_GET (eoption->kind);
18493 option.size = BYTE_GET (eoption->size);
18494 option.section = BYTE_GET (eoption->section);
18495 option.info = BYTE_GET (eoption->info);
a6e9f9df 18496
fd17d1e6 18497 switch (option.kind)
252b5132 18498 {
a6e9f9df
AM
18499 case ODK_NULL:
18500 /* This shouldn't happen. */
d0c4e780 18501 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18502 option.section, option.info);
a6e9f9df 18503 break;
2e6be59c 18504
a6e9f9df
AM
18505 case ODK_REGINFO:
18506 printf (" REGINFO ");
dda8d76d 18507 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18508 {
2cf0635d 18509 Elf32_External_RegInfo * ereg;
b34976b6 18510 Elf32_RegInfo reginfo;
a6e9f9df 18511
2e6be59c 18512 /* 32bit form. */
fd17d1e6
AM
18513 if (option.size < (sizeof (Elf_External_Options)
18514 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18515 {
18516 printf (_("<corrupt>\n"));
18517 error (_("Truncated MIPS REGINFO option\n"));
18518 cnt = 0;
18519 break;
18520 }
18521
fd17d1e6 18522 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18523
a6e9f9df
AM
18524 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18525 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18526 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18527 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18528 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18529 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18530
d0c4e780
AM
18531 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18532 reginfo.ri_gprmask, reginfo.ri_gp_value);
18533 printf (" "
18534 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18535 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18536 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18537 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18538 }
18539 else
18540 {
18541 /* 64 bit form. */
2cf0635d 18542 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18543 Elf64_Internal_RegInfo reginfo;
18544
fd17d1e6
AM
18545 if (option.size < (sizeof (Elf_External_Options)
18546 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18547 {
18548 printf (_("<corrupt>\n"));
18549 error (_("Truncated MIPS REGINFO option\n"));
18550 cnt = 0;
18551 break;
18552 }
18553
fd17d1e6 18554 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18555 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18556 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18557 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18558 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18559 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18560 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18561
d0c4e780
AM
18562 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18563 reginfo.ri_gprmask, reginfo.ri_gp_value);
18564 printf (" "
18565 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18566 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18567 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18568 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18569 }
fd17d1e6 18570 offset += option.size;
a6e9f9df 18571 continue;
2e6be59c 18572
a6e9f9df
AM
18573 case ODK_EXCEPTIONS:
18574 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18575 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18576 fputs (") fpe_max(", stdout);
fd17d1e6 18577 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18578 fputs (")", stdout);
18579
fd17d1e6 18580 if (option.info & OEX_PAGE0)
a6e9f9df 18581 fputs (" PAGE0", stdout);
fd17d1e6 18582 if (option.info & OEX_SMM)
a6e9f9df 18583 fputs (" SMM", stdout);
fd17d1e6 18584 if (option.info & OEX_FPDBUG)
a6e9f9df 18585 fputs (" FPDBUG", stdout);
fd17d1e6 18586 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18587 fputs (" DISMISS", stdout);
18588 break;
2e6be59c 18589
a6e9f9df
AM
18590 case ODK_PAD:
18591 fputs (" PAD ", stdout);
fd17d1e6 18592 if (option.info & OPAD_PREFIX)
a6e9f9df 18593 fputs (" PREFIX", stdout);
fd17d1e6 18594 if (option.info & OPAD_POSTFIX)
a6e9f9df 18595 fputs (" POSTFIX", stdout);
fd17d1e6 18596 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18597 fputs (" SYMBOL", stdout);
18598 break;
2e6be59c 18599
a6e9f9df
AM
18600 case ODK_HWPATCH:
18601 fputs (" HWPATCH ", stdout);
fd17d1e6 18602 if (option.info & OHW_R4KEOP)
a6e9f9df 18603 fputs (" R4KEOP", stdout);
fd17d1e6 18604 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18605 fputs (" R8KPFETCH", stdout);
fd17d1e6 18606 if (option.info & OHW_R5KEOP)
a6e9f9df 18607 fputs (" R5KEOP", stdout);
fd17d1e6 18608 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18609 fputs (" R5KCVTL", stdout);
18610 break;
2e6be59c 18611
a6e9f9df
AM
18612 case ODK_FILL:
18613 fputs (" FILL ", stdout);
18614 /* XXX Print content of info word? */
18615 break;
2e6be59c 18616
a6e9f9df
AM
18617 case ODK_TAGS:
18618 fputs (" TAGS ", stdout);
18619 /* XXX Print content of info word? */
18620 break;
2e6be59c 18621
a6e9f9df
AM
18622 case ODK_HWAND:
18623 fputs (" HWAND ", stdout);
fd17d1e6 18624 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18625 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18626 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18627 fputs (" R4KEOP_CLEAN", stdout);
18628 break;
2e6be59c 18629
a6e9f9df
AM
18630 case ODK_HWOR:
18631 fputs (" HWOR ", stdout);
fd17d1e6 18632 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18633 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18634 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18635 fputs (" R4KEOP_CLEAN", stdout);
18636 break;
2e6be59c 18637
a6e9f9df 18638 case ODK_GP_GROUP:
d0c4e780 18639 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18640 option.info & OGP_GROUP,
18641 (option.info & OGP_SELF) >> 16);
a6e9f9df 18642 break;
2e6be59c 18643
a6e9f9df 18644 case ODK_IDENT:
d0c4e780 18645 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18646 option.info & OGP_GROUP,
18647 (option.info & OGP_SELF) >> 16);
a6e9f9df 18648 break;
2e6be59c 18649
a6e9f9df
AM
18650 default:
18651 /* This shouldn't happen. */
d0c4e780 18652 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18653 option.kind, option.section, option.info);
a6e9f9df 18654 break;
252b5132 18655 }
a6e9f9df 18656
2cf0635d 18657 len = sizeof (* eopt);
fd17d1e6 18658 while (len < option.size)
82b1b41b 18659 {
fd17d1e6 18660 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18661
82b1b41b
NC
18662 if (ISPRINT (datum))
18663 printf ("%c", datum);
18664 else
18665 printf ("\\%03o", datum);
18666 len ++;
18667 }
a6e9f9df 18668 fputs ("\n", stdout);
82b1b41b 18669
fd17d1e6 18670 offset += option.size;
252b5132 18671 }
a6e9f9df 18672 free (eopt);
252b5132 18673 }
32ec8896 18674 else
015dc7e1 18675 res = false;
252b5132
RH
18676 }
18677
18678 if (conflicts_offset != 0 && conflictsno != 0)
18679 {
2cf0635d 18680 Elf32_Conflict * iconf;
252b5132
RH
18681 size_t cnt;
18682
978c4450 18683 if (filedata->dynamic_symbols == NULL)
252b5132 18684 {
591a748a 18685 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18686 return false;
252b5132
RH
18687 }
18688
7296a62a
NC
18689 /* PR 21345 - print a slightly more helpful error message
18690 if we are sure that the cmalloc will fail. */
645f43a8 18691 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18692 {
18693 error (_("Overlarge number of conflicts detected: %lx\n"),
18694 (long) conflictsno);
015dc7e1 18695 return false;
7296a62a
NC
18696 }
18697
3f5e193b 18698 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18699 if (iconf == NULL)
18700 {
8b73c356 18701 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18702 return false;
252b5132
RH
18703 }
18704
9ea033b2 18705 if (is_32bit_elf)
252b5132 18706 {
2cf0635d 18707 Elf32_External_Conflict * econf32;
a6e9f9df 18708
3f5e193b 18709 econf32 = (Elf32_External_Conflict *)
95099889
AM
18710 get_data (NULL, filedata, conflicts_offset,
18711 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18712 if (!econf32)
5a814d6d
AM
18713 {
18714 free (iconf);
015dc7e1 18715 return false;
5a814d6d 18716 }
252b5132
RH
18717
18718 for (cnt = 0; cnt < conflictsno; ++cnt)
18719 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18720
18721 free (econf32);
252b5132
RH
18722 }
18723 else
18724 {
2cf0635d 18725 Elf64_External_Conflict * econf64;
a6e9f9df 18726
3f5e193b 18727 econf64 = (Elf64_External_Conflict *)
95099889
AM
18728 get_data (NULL, filedata, conflicts_offset,
18729 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18730 if (!econf64)
5a814d6d
AM
18731 {
18732 free (iconf);
015dc7e1 18733 return false;
5a814d6d 18734 }
252b5132
RH
18735
18736 for (cnt = 0; cnt < conflictsno; ++cnt)
18737 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18738
18739 free (econf64);
252b5132
RH
18740 }
18741
d3a49aa8
AM
18742 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18743 "\nSection '.conflict' contains %lu entries:\n",
18744 (unsigned long) conflictsno),
c7e7ca54 18745 (unsigned long) conflictsno);
252b5132
RH
18746 puts (_(" Num: Index Value Name"));
18747
18748 for (cnt = 0; cnt < conflictsno; ++cnt)
18749 {
b34976b6 18750 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18751
978c4450 18752 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18753 printf (_("<corrupt symbol index>"));
d79b3d50 18754 else
e0a31db1
NC
18755 {
18756 Elf_Internal_Sym * psym;
18757
978c4450 18758 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18759 print_vma (psym->st_value, FULL_HEX);
18760 putchar (' ');
84714f86
AM
18761 if (valid_dynamic_name (filedata, psym->st_name))
18762 print_symbol (25, get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18763 else
18764 printf (_("<corrupt: %14ld>"), psym->st_name);
18765 }
31104126 18766 putchar ('\n');
252b5132
RH
18767 }
18768
252b5132
RH
18769 free (iconf);
18770 }
18771
ccb4c951
RS
18772 if (pltgot != 0 && local_gotno != 0)
18773 {
91d6fa6a 18774 bfd_vma ent, local_end, global_end;
bbeee7ea 18775 size_t i, offset;
2cf0635d 18776 unsigned char * data;
82b1b41b 18777 unsigned char * data_end;
bbeee7ea 18778 int addr_size;
ccb4c951 18779
91d6fa6a 18780 ent = pltgot;
ccb4c951
RS
18781 addr_size = (is_32bit_elf ? 4 : 8);
18782 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18783
74e1a04b
NC
18784 /* PR binutils/17533 file: 012-111227-0.004 */
18785 if (symtabno < gotsym)
18786 {
18787 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18788 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18789 return false;
74e1a04b 18790 }
82b1b41b 18791
74e1a04b 18792 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18793 /* PR 17531: file: 54c91a34. */
18794 if (global_end < local_end)
18795 {
18796 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18797 return false;
82b1b41b 18798 }
948f632f 18799
dda8d76d
NC
18800 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18801 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18802 global_end - pltgot, 1,
18803 _("Global Offset Table data"));
919383ac 18804 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18805 data_end = data + (global_end - pltgot);
59245841 18806
ccb4c951
RS
18807 printf (_("\nPrimary GOT:\n"));
18808 printf (_(" Canonical gp value: "));
18809 print_vma (pltgot + 0x7ff0, LONG_HEX);
18810 printf ("\n\n");
18811
18812 printf (_(" Reserved entries:\n"));
18813 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18814 addr_size * 2, _("Address"), _("Access"),
18815 addr_size * 2, _("Initial"));
82b1b41b 18816 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18817 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18818 if (ent == (bfd_vma) -1)
18819 goto got_print_fail;
75ec1fdb 18820
c4ab9505
MR
18821 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18822 This entry will be used by some runtime loaders, to store the
18823 module pointer. Otherwise this is an ordinary local entry.
18824 PR 21344: Check for the entry being fully available before
18825 fetching it. */
18826 if (data
18827 && data + ent - pltgot + addr_size <= data_end
18828 && (byte_get (data + ent - pltgot, addr_size)
18829 >> (addr_size * 8 - 1)) != 0)
18830 {
18831 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18832 printf (_(" Module pointer (GNU extension)\n"));
18833 if (ent == (bfd_vma) -1)
18834 goto got_print_fail;
ccb4c951
RS
18835 }
18836 printf ("\n");
18837
f17e9d8a 18838 if (data != NULL && ent < local_end)
ccb4c951
RS
18839 {
18840 printf (_(" Local entries:\n"));
cc5914eb 18841 printf (" %*s %10s %*s\n",
2b692964
NC
18842 addr_size * 2, _("Address"), _("Access"),
18843 addr_size * 2, _("Initial"));
91d6fa6a 18844 while (ent < local_end)
ccb4c951 18845 {
82b1b41b 18846 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18847 printf ("\n");
82b1b41b
NC
18848 if (ent == (bfd_vma) -1)
18849 goto got_print_fail;
ccb4c951
RS
18850 }
18851 printf ("\n");
18852 }
18853
f17e9d8a 18854 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18855 {
18856 int sym_width;
18857
18858 printf (_(" Global entries:\n"));
cc5914eb 18859 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18860 addr_size * 2, _("Address"),
18861 _("Access"),
2b692964 18862 addr_size * 2, _("Initial"),
9cf03b7e
NC
18863 addr_size * 2, _("Sym.Val."),
18864 _("Type"),
18865 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18866 _("Ndx"), _("Name"));
0b4362b0 18867
ccb4c951 18868 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18869
ccb4c951
RS
18870 for (i = gotsym; i < symtabno; i++)
18871 {
82b1b41b 18872 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18873 printf (" ");
e0a31db1 18874
978c4450 18875 if (filedata->dynamic_symbols == NULL)
e0a31db1 18876 printf (_("<no dynamic symbols>"));
978c4450 18877 else if (i < filedata->num_dynamic_syms)
e0a31db1 18878 {
978c4450 18879 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18880
18881 print_vma (psym->st_value, LONG_HEX);
18882 printf (" %-7s %3s ",
dda8d76d
NC
18883 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18884 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18885
84714f86 18886 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18887 print_symbol (sym_width,
84714f86 18888 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18889 else
18890 printf (_("<corrupt: %14ld>"), psym->st_name);
18891 }
ccb4c951 18892 else
7fc5ac57
JBG
18893 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18894 (unsigned long) i);
e0a31db1 18895
ccb4c951 18896 printf ("\n");
82b1b41b
NC
18897 if (ent == (bfd_vma) -1)
18898 break;
ccb4c951
RS
18899 }
18900 printf ("\n");
18901 }
18902
82b1b41b 18903 got_print_fail:
9db70fc3 18904 free (data);
ccb4c951
RS
18905 }
18906
861fb55a
DJ
18907 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18908 {
91d6fa6a 18909 bfd_vma ent, end;
861fb55a
DJ
18910 size_t offset, rel_offset;
18911 unsigned long count, i;
2cf0635d 18912 unsigned char * data;
861fb55a 18913 int addr_size, sym_width;
2cf0635d 18914 Elf_Internal_Rela * rels;
861fb55a 18915
dda8d76d 18916 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18917 if (pltrel == DT_RELA)
18918 {
dda8d76d 18919 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18920 return false;
861fb55a
DJ
18921 }
18922 else
18923 {
dda8d76d 18924 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18925 return false;
861fb55a
DJ
18926 }
18927
91d6fa6a 18928 ent = mips_pltgot;
861fb55a
DJ
18929 addr_size = (is_32bit_elf ? 4 : 8);
18930 end = mips_pltgot + (2 + count) * addr_size;
18931
dda8d76d
NC
18932 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18933 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18934 1, _("Procedure Linkage Table data"));
59245841 18935 if (data == NULL)
288f0ba2
AM
18936 {
18937 free (rels);
015dc7e1 18938 return false;
288f0ba2 18939 }
59245841 18940
9cf03b7e 18941 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18942 printf (_(" Reserved entries:\n"));
18943 printf (_(" %*s %*s Purpose\n"),
2b692964 18944 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18945 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18946 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18947 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18948 printf (_(" Module pointer\n"));
861fb55a
DJ
18949 printf ("\n");
18950
18951 printf (_(" Entries:\n"));
cc5914eb 18952 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18953 addr_size * 2, _("Address"),
18954 addr_size * 2, _("Initial"),
18955 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18956 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18957 for (i = 0; i < count; i++)
18958 {
df97ab2a 18959 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18960
91d6fa6a 18961 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18962 printf (" ");
e0a31db1 18963
978c4450 18964 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18965 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18966 else
e0a31db1 18967 {
978c4450 18968 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18969
18970 print_vma (psym->st_value, LONG_HEX);
18971 printf (" %-7s %3s ",
dda8d76d
NC
18972 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18973 get_symbol_index_type (filedata, psym->st_shndx));
84714f86 18974 if (valid_dynamic_name (filedata, psym->st_name))
978c4450 18975 print_symbol (sym_width,
84714f86 18976 get_dynamic_name (filedata, psym->st_name));
e0a31db1
NC
18977 else
18978 printf (_("<corrupt: %14ld>"), psym->st_name);
18979 }
861fb55a
DJ
18980 printf ("\n");
18981 }
18982 printf ("\n");
18983
9db70fc3 18984 free (data);
861fb55a
DJ
18985 free (rels);
18986 }
18987
32ec8896 18988 return res;
252b5132
RH
18989}
18990
015dc7e1 18991static bool
dda8d76d 18992process_nds32_specific (Filedata * filedata)
35c08157
KLC
18993{
18994 Elf_Internal_Shdr *sect = NULL;
18995
dda8d76d 18996 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18997 if (sect != NULL && sect->sh_size >= 4)
35c08157 18998 {
9c7b8e9b
AM
18999 unsigned char *buf;
19000 unsigned int flag;
35c08157
KLC
19001
19002 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
19003 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
19004 _("NDS32 elf flags section"));
35c08157 19005
9c7b8e9b 19006 if (buf == NULL)
015dc7e1 19007 return false;
32ec8896 19008
9c7b8e9b
AM
19009 flag = byte_get (buf, 4);
19010 free (buf);
19011 switch (flag & 0x3)
35c08157
KLC
19012 {
19013 case 0:
19014 printf ("(VEC_SIZE):\tNo entry.\n");
19015 break;
19016 case 1:
19017 printf ("(VEC_SIZE):\t4 bytes\n");
19018 break;
19019 case 2:
19020 printf ("(VEC_SIZE):\t16 bytes\n");
19021 break;
19022 case 3:
19023 printf ("(VEC_SIZE):\treserved\n");
19024 break;
19025 }
19026 }
19027
015dc7e1 19028 return true;
35c08157
KLC
19029}
19030
015dc7e1 19031static bool
dda8d76d 19032process_gnu_liblist (Filedata * filedata)
047b2264 19033{
2cf0635d
NC
19034 Elf_Internal_Shdr * section;
19035 Elf_Internal_Shdr * string_sec;
19036 Elf32_External_Lib * elib;
19037 char * strtab;
c256ffe7 19038 size_t strtab_size;
047b2264 19039 size_t cnt;
d3a49aa8 19040 unsigned long num_liblist;
047b2264 19041 unsigned i;
015dc7e1 19042 bool res = true;
047b2264
JJ
19043
19044 if (! do_arch)
015dc7e1 19045 return true;
047b2264 19046
dda8d76d
NC
19047 for (i = 0, section = filedata->section_headers;
19048 i < filedata->file_header.e_shnum;
b34976b6 19049 i++, section++)
047b2264
JJ
19050 {
19051 switch (section->sh_type)
19052 {
19053 case SHT_GNU_LIBLIST:
dda8d76d 19054 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
19055 break;
19056
3f5e193b 19057 elib = (Elf32_External_Lib *)
dda8d76d 19058 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 19059 _("liblist section data"));
047b2264
JJ
19060
19061 if (elib == NULL)
32ec8896 19062 {
015dc7e1 19063 res = false;
32ec8896
NC
19064 break;
19065 }
047b2264 19066
dda8d76d
NC
19067 string_sec = filedata->section_headers + section->sh_link;
19068 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
19069 string_sec->sh_size,
19070 _("liblist string table"));
047b2264
JJ
19071 if (strtab == NULL
19072 || section->sh_entsize != sizeof (Elf32_External_Lib))
19073 {
19074 free (elib);
2842702f 19075 free (strtab);
015dc7e1 19076 res = false;
047b2264
JJ
19077 break;
19078 }
59245841 19079 strtab_size = string_sec->sh_size;
047b2264 19080
d3a49aa8
AM
19081 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
19082 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
19083 "\nLibrary list section '%s' contains %lu entries:\n",
19084 num_liblist),
dda8d76d 19085 printable_section_name (filedata, section),
d3a49aa8 19086 num_liblist);
047b2264 19087
2b692964 19088 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
19089
19090 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
19091 ++cnt)
19092 {
19093 Elf32_Lib liblist;
91d6fa6a 19094 time_t atime;
d5b07ef4 19095 char timebuf[128];
2cf0635d 19096 struct tm * tmp;
047b2264
JJ
19097
19098 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 19099 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
19100 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
19101 liblist.l_version = BYTE_GET (elib[cnt].l_version);
19102 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
19103
91d6fa6a 19104 tmp = gmtime (&atime);
e9e44622
JJ
19105 snprintf (timebuf, sizeof (timebuf),
19106 "%04u-%02u-%02uT%02u:%02u:%02u",
19107 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
19108 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
19109
19110 printf ("%3lu: ", (unsigned long) cnt);
19111 if (do_wide)
c256ffe7 19112 printf ("%-20s", liblist.l_name < strtab_size
2b692964 19113 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 19114 else
c256ffe7 19115 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 19116 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
19117 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
19118 liblist.l_version, liblist.l_flags);
19119 }
19120
19121 free (elib);
2842702f 19122 free (strtab);
047b2264
JJ
19123 }
19124 }
19125
32ec8896 19126 return res;
047b2264
JJ
19127}
19128
9437c45b 19129static const char *
dda8d76d 19130get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
19131{
19132 static char buff[64];
103f02d3 19133
dda8d76d 19134 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
19135 switch (e_type)
19136 {
57346661 19137 case NT_AUXV:
1ec5cd37 19138 return _("NT_AUXV (auxiliary vector)");
57346661 19139 case NT_PRSTATUS:
1ec5cd37 19140 return _("NT_PRSTATUS (prstatus structure)");
57346661 19141 case NT_FPREGSET:
1ec5cd37 19142 return _("NT_FPREGSET (floating point registers)");
57346661 19143 case NT_PRPSINFO:
1ec5cd37 19144 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 19145 case NT_TASKSTRUCT:
1ec5cd37 19146 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
19147 case NT_GDB_TDESC:
19148 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 19149 case NT_PRXFPREG:
1ec5cd37 19150 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
19151 case NT_PPC_VMX:
19152 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
19153 case NT_PPC_VSX:
19154 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
19155 case NT_PPC_TAR:
19156 return _("NT_PPC_TAR (ppc TAR register)");
19157 case NT_PPC_PPR:
19158 return _("NT_PPC_PPR (ppc PPR register)");
19159 case NT_PPC_DSCR:
19160 return _("NT_PPC_DSCR (ppc DSCR register)");
19161 case NT_PPC_EBB:
19162 return _("NT_PPC_EBB (ppc EBB registers)");
19163 case NT_PPC_PMU:
19164 return _("NT_PPC_PMU (ppc PMU registers)");
19165 case NT_PPC_TM_CGPR:
19166 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
19167 case NT_PPC_TM_CFPR:
19168 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
19169 case NT_PPC_TM_CVMX:
19170 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
19171 case NT_PPC_TM_CVSX:
3fd21718 19172 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
19173 case NT_PPC_TM_SPR:
19174 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
19175 case NT_PPC_TM_CTAR:
19176 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
19177 case NT_PPC_TM_CPPR:
19178 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
19179 case NT_PPC_TM_CDSCR:
19180 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
19181 case NT_386_TLS:
19182 return _("NT_386_TLS (x86 TLS information)");
19183 case NT_386_IOPERM:
19184 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
19185 case NT_X86_XSTATE:
19186 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
19187 case NT_X86_CET:
19188 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
19189 case NT_S390_HIGH_GPRS:
19190 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
19191 case NT_S390_TIMER:
19192 return _("NT_S390_TIMER (s390 timer register)");
19193 case NT_S390_TODCMP:
19194 return _("NT_S390_TODCMP (s390 TOD comparator register)");
19195 case NT_S390_TODPREG:
19196 return _("NT_S390_TODPREG (s390 TOD programmable register)");
19197 case NT_S390_CTRS:
19198 return _("NT_S390_CTRS (s390 control registers)");
19199 case NT_S390_PREFIX:
19200 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
19201 case NT_S390_LAST_BREAK:
19202 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
19203 case NT_S390_SYSTEM_CALL:
19204 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
19205 case NT_S390_TDB:
19206 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
19207 case NT_S390_VXRS_LOW:
19208 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
19209 case NT_S390_VXRS_HIGH:
19210 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
19211 case NT_S390_GS_CB:
19212 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
19213 case NT_S390_GS_BC:
19214 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
19215 case NT_ARM_VFP:
19216 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
19217 case NT_ARM_TLS:
19218 return _("NT_ARM_TLS (AArch TLS registers)");
19219 case NT_ARM_HW_BREAK:
19220 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
19221 case NT_ARM_HW_WATCH:
19222 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
19223 case NT_ARM_SVE:
19224 return _("NT_ARM_SVE (AArch SVE registers)");
19225 case NT_ARM_PAC_MASK:
19226 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
19227 case NT_ARM_PACA_KEYS:
19228 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
19229 case NT_ARM_PACG_KEYS:
19230 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
19231 case NT_ARM_TAGGED_ADDR_CTRL:
19232 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
19233 case NT_ARM_PAC_ENABLED_KEYS:
19234 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
19235 case NT_ARC_V2:
19236 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
19237 case NT_RISCV_CSR:
19238 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 19239 case NT_PSTATUS:
1ec5cd37 19240 return _("NT_PSTATUS (pstatus structure)");
57346661 19241 case NT_FPREGS:
1ec5cd37 19242 return _("NT_FPREGS (floating point registers)");
57346661 19243 case NT_PSINFO:
1ec5cd37 19244 return _("NT_PSINFO (psinfo structure)");
57346661 19245 case NT_LWPSTATUS:
1ec5cd37 19246 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 19247 case NT_LWPSINFO:
1ec5cd37 19248 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 19249 case NT_WIN32PSTATUS:
1ec5cd37 19250 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
19251 case NT_SIGINFO:
19252 return _("NT_SIGINFO (siginfo_t data)");
19253 case NT_FILE:
19254 return _("NT_FILE (mapped files)");
1ec5cd37
NC
19255 default:
19256 break;
19257 }
19258 else
19259 switch (e_type)
19260 {
19261 case NT_VERSION:
19262 return _("NT_VERSION (version)");
19263 case NT_ARCH:
19264 return _("NT_ARCH (architecture)");
9ef920e9 19265 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 19266 return _("OPEN");
9ef920e9 19267 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 19268 return _("func");
c8795e1f
NC
19269 case NT_GO_BUILDID:
19270 return _("GO BUILDID");
3ac925fc
LB
19271 case FDO_PACKAGING_METADATA:
19272 return _("FDO_PACKAGING_METADATA");
1ec5cd37
NC
19273 default:
19274 break;
19275 }
19276
e9e44622 19277 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 19278 return buff;
779fe533
NC
19279}
19280
015dc7e1 19281static bool
9ece1fa9
TT
19282print_core_note (Elf_Internal_Note *pnote)
19283{
19284 unsigned int addr_size = is_32bit_elf ? 4 : 8;
19285 bfd_vma count, page_size;
19286 unsigned char *descdata, *filenames, *descend;
19287
19288 if (pnote->type != NT_FILE)
04ac15ab
AS
19289 {
19290 if (do_wide)
19291 printf ("\n");
015dc7e1 19292 return true;
04ac15ab 19293 }
9ece1fa9
TT
19294
19295#ifndef BFD64
19296 if (!is_32bit_elf)
19297 {
19298 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
19299 /* Still "successful". */
015dc7e1 19300 return true;
9ece1fa9
TT
19301 }
19302#endif
19303
19304 if (pnote->descsz < 2 * addr_size)
19305 {
32ec8896 19306 error (_(" Malformed note - too short for header\n"));
015dc7e1 19307 return false;
9ece1fa9
TT
19308 }
19309
19310 descdata = (unsigned char *) pnote->descdata;
19311 descend = descdata + pnote->descsz;
19312
19313 if (descdata[pnote->descsz - 1] != '\0')
19314 {
32ec8896 19315 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 19316 return false;
9ece1fa9
TT
19317 }
19318
19319 count = byte_get (descdata, addr_size);
19320 descdata += addr_size;
19321
19322 page_size = byte_get (descdata, addr_size);
19323 descdata += addr_size;
19324
5396a86e
AM
19325 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
19326 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 19327 {
32ec8896 19328 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 19329 return false;
9ece1fa9
TT
19330 }
19331
19332 printf (_(" Page size: "));
19333 print_vma (page_size, DEC);
19334 printf ("\n");
19335
19336 printf (_(" %*s%*s%*s\n"),
19337 (int) (2 + 2 * addr_size), _("Start"),
19338 (int) (4 + 2 * addr_size), _("End"),
19339 (int) (4 + 2 * addr_size), _("Page Offset"));
19340 filenames = descdata + count * 3 * addr_size;
595712bb 19341 while (count-- > 0)
9ece1fa9
TT
19342 {
19343 bfd_vma start, end, file_ofs;
19344
19345 if (filenames == descend)
19346 {
32ec8896 19347 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 19348 return false;
9ece1fa9
TT
19349 }
19350
19351 start = byte_get (descdata, addr_size);
19352 descdata += addr_size;
19353 end = byte_get (descdata, addr_size);
19354 descdata += addr_size;
19355 file_ofs = byte_get (descdata, addr_size);
19356 descdata += addr_size;
19357
19358 printf (" ");
19359 print_vma (start, FULL_HEX);
19360 printf (" ");
19361 print_vma (end, FULL_HEX);
19362 printf (" ");
19363 print_vma (file_ofs, FULL_HEX);
19364 printf ("\n %s\n", filenames);
19365
19366 filenames += 1 + strlen ((char *) filenames);
19367 }
19368
015dc7e1 19369 return true;
9ece1fa9
TT
19370}
19371
1118d252
RM
19372static const char *
19373get_gnu_elf_note_type (unsigned e_type)
19374{
1449284b 19375 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19376 switch (e_type)
19377 {
19378 case NT_GNU_ABI_TAG:
19379 return _("NT_GNU_ABI_TAG (ABI version tag)");
19380 case NT_GNU_HWCAP:
19381 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19382 case NT_GNU_BUILD_ID:
19383 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19384 case NT_GNU_GOLD_VERSION:
19385 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19386 case NT_GNU_PROPERTY_TYPE_0:
19387 return _("NT_GNU_PROPERTY_TYPE_0");
19388 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19389 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19390 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19391 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19392 default:
1449284b
NC
19393 {
19394 static char buff[64];
1118d252 19395
1449284b
NC
19396 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19397 return buff;
19398 }
19399 }
1118d252
RM
19400}
19401
a9eafb08
L
19402static void
19403decode_x86_compat_isa (unsigned int bitmask)
19404{
19405 while (bitmask)
19406 {
19407 unsigned int bit = bitmask & (- bitmask);
19408
19409 bitmask &= ~ bit;
19410 switch (bit)
19411 {
19412 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19413 printf ("i486");
19414 break;
19415 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19416 printf ("586");
19417 break;
19418 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19419 printf ("686");
19420 break;
19421 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19422 printf ("SSE");
19423 break;
19424 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19425 printf ("SSE2");
19426 break;
19427 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19428 printf ("SSE3");
19429 break;
19430 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19431 printf ("SSSE3");
19432 break;
19433 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19434 printf ("SSE4_1");
19435 break;
19436 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19437 printf ("SSE4_2");
19438 break;
19439 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19440 printf ("AVX");
19441 break;
19442 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19443 printf ("AVX2");
19444 break;
19445 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19446 printf ("AVX512F");
19447 break;
19448 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19449 printf ("AVX512CD");
19450 break;
19451 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19452 printf ("AVX512ER");
19453 break;
19454 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19455 printf ("AVX512PF");
19456 break;
19457 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19458 printf ("AVX512VL");
19459 break;
19460 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19461 printf ("AVX512DQ");
19462 break;
19463 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19464 printf ("AVX512BW");
19465 break;
65b3d26e
L
19466 default:
19467 printf (_("<unknown: %x>"), bit);
19468 break;
a9eafb08
L
19469 }
19470 if (bitmask)
19471 printf (", ");
19472 }
19473}
19474
9ef920e9 19475static void
32930e4e 19476decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19477{
0a59decb 19478 if (!bitmask)
90c745dc
L
19479 {
19480 printf (_("<None>"));
19481 return;
19482 }
90c745dc 19483
9ef920e9
NC
19484 while (bitmask)
19485 {
1fc87489 19486 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19487
19488 bitmask &= ~ bit;
19489 switch (bit)
19490 {
32930e4e 19491 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19492 printf ("CMOV");
19493 break;
32930e4e 19494 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19495 printf ("SSE");
19496 break;
32930e4e 19497 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19498 printf ("SSE2");
19499 break;
32930e4e 19500 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19501 printf ("SSE3");
19502 break;
32930e4e 19503 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19504 printf ("SSSE3");
19505 break;
32930e4e 19506 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19507 printf ("SSE4_1");
19508 break;
32930e4e 19509 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19510 printf ("SSE4_2");
19511 break;
32930e4e 19512 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19513 printf ("AVX");
19514 break;
32930e4e 19515 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19516 printf ("AVX2");
19517 break;
32930e4e 19518 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19519 printf ("FMA");
19520 break;
32930e4e 19521 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19522 printf ("AVX512F");
19523 break;
32930e4e 19524 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19525 printf ("AVX512CD");
19526 break;
32930e4e 19527 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19528 printf ("AVX512ER");
19529 break;
32930e4e 19530 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19531 printf ("AVX512PF");
19532 break;
32930e4e 19533 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19534 printf ("AVX512VL");
19535 break;
32930e4e 19536 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19537 printf ("AVX512DQ");
19538 break;
32930e4e 19539 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19540 printf ("AVX512BW");
19541 break;
32930e4e 19542 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19543 printf ("AVX512_4FMAPS");
19544 break;
32930e4e 19545 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19546 printf ("AVX512_4VNNIW");
19547 break;
32930e4e 19548 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19549 printf ("AVX512_BITALG");
19550 break;
32930e4e 19551 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19552 printf ("AVX512_IFMA");
19553 break;
32930e4e 19554 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19555 printf ("AVX512_VBMI");
19556 break;
32930e4e 19557 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19558 printf ("AVX512_VBMI2");
19559 break;
32930e4e 19560 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19561 printf ("AVX512_VNNI");
19562 break;
32930e4e 19563 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19564 printf ("AVX512_BF16");
19565 break;
65b3d26e
L
19566 default:
19567 printf (_("<unknown: %x>"), bit);
19568 break;
9ef920e9
NC
19569 }
19570 if (bitmask)
19571 printf (", ");
19572 }
19573}
19574
32930e4e
L
19575static void
19576decode_x86_isa (unsigned int bitmask)
19577{
32930e4e
L
19578 while (bitmask)
19579 {
19580 unsigned int bit = bitmask & (- bitmask);
19581
19582 bitmask &= ~ bit;
19583 switch (bit)
19584 {
b0ab0693
L
19585 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19586 printf ("x86-64-baseline");
19587 break;
32930e4e
L
19588 case GNU_PROPERTY_X86_ISA_1_V2:
19589 printf ("x86-64-v2");
19590 break;
19591 case GNU_PROPERTY_X86_ISA_1_V3:
19592 printf ("x86-64-v3");
19593 break;
19594 case GNU_PROPERTY_X86_ISA_1_V4:
19595 printf ("x86-64-v4");
19596 break;
19597 default:
19598 printf (_("<unknown: %x>"), bit);
19599 break;
19600 }
19601 if (bitmask)
19602 printf (", ");
19603 }
19604}
19605
ee2fdd6f 19606static void
a9eafb08 19607decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19608{
0a59decb 19609 if (!bitmask)
90c745dc
L
19610 {
19611 printf (_("<None>"));
19612 return;
19613 }
90c745dc 19614
ee2fdd6f
L
19615 while (bitmask)
19616 {
19617 unsigned int bit = bitmask & (- bitmask);
19618
19619 bitmask &= ~ bit;
19620 switch (bit)
19621 {
19622 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19623 printf ("IBT");
ee2fdd6f 19624 break;
48580982 19625 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19626 printf ("SHSTK");
48580982 19627 break;
279d901e
L
19628 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19629 printf ("LAM_U48");
19630 break;
19631 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19632 printf ("LAM_U57");
19633 break;
ee2fdd6f
L
19634 default:
19635 printf (_("<unknown: %x>"), bit);
19636 break;
19637 }
19638 if (bitmask)
19639 printf (", ");
19640 }
19641}
19642
a9eafb08
L
19643static void
19644decode_x86_feature_2 (unsigned int bitmask)
19645{
0a59decb 19646 if (!bitmask)
90c745dc
L
19647 {
19648 printf (_("<None>"));
19649 return;
19650 }
90c745dc 19651
a9eafb08
L
19652 while (bitmask)
19653 {
19654 unsigned int bit = bitmask & (- bitmask);
19655
19656 bitmask &= ~ bit;
19657 switch (bit)
19658 {
19659 case GNU_PROPERTY_X86_FEATURE_2_X86:
19660 printf ("x86");
19661 break;
19662 case GNU_PROPERTY_X86_FEATURE_2_X87:
19663 printf ("x87");
19664 break;
19665 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19666 printf ("MMX");
19667 break;
19668 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19669 printf ("XMM");
19670 break;
19671 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19672 printf ("YMM");
19673 break;
19674 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19675 printf ("ZMM");
19676 break;
a308b89d
L
19677 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19678 printf ("TMM");
19679 break;
32930e4e
L
19680 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19681 printf ("MASK");
19682 break;
a9eafb08
L
19683 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19684 printf ("FXSR");
19685 break;
19686 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19687 printf ("XSAVE");
19688 break;
19689 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19690 printf ("XSAVEOPT");
19691 break;
19692 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19693 printf ("XSAVEC");
19694 break;
65b3d26e
L
19695 default:
19696 printf (_("<unknown: %x>"), bit);
19697 break;
a9eafb08
L
19698 }
19699 if (bitmask)
19700 printf (", ");
19701 }
19702}
19703
cd702818
SD
19704static void
19705decode_aarch64_feature_1_and (unsigned int bitmask)
19706{
19707 while (bitmask)
19708 {
19709 unsigned int bit = bitmask & (- bitmask);
19710
19711 bitmask &= ~ bit;
19712 switch (bit)
19713 {
19714 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19715 printf ("BTI");
19716 break;
19717
19718 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19719 printf ("PAC");
19720 break;
19721
19722 default:
19723 printf (_("<unknown: %x>"), bit);
19724 break;
19725 }
19726 if (bitmask)
19727 printf (", ");
19728 }
19729}
19730
6320fd00
L
19731static void
19732decode_1_needed (unsigned int bitmask)
19733{
19734 while (bitmask)
19735 {
19736 unsigned int bit = bitmask & (- bitmask);
19737
19738 bitmask &= ~ bit;
19739 switch (bit)
19740 {
19741 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19742 printf ("indirect external access");
19743 break;
19744 default:
19745 printf (_("<unknown: %x>"), bit);
19746 break;
19747 }
19748 if (bitmask)
19749 printf (", ");
19750 }
19751}
19752
9ef920e9 19753static void
dda8d76d 19754print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19755{
19756 unsigned char * ptr = (unsigned char *) pnote->descdata;
19757 unsigned char * ptr_end = ptr + pnote->descsz;
19758 unsigned int size = is_32bit_elf ? 4 : 8;
19759
19760 printf (_(" Properties: "));
19761
1fc87489 19762 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19763 {
19764 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19765 return;
19766 }
19767
6ab2c4ed 19768 while (ptr < ptr_end)
9ef920e9 19769 {
1fc87489 19770 unsigned int j;
6ab2c4ed
MC
19771 unsigned int type;
19772 unsigned int datasz;
19773
19774 if ((size_t) (ptr_end - ptr) < 8)
19775 {
19776 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19777 break;
19778 }
19779
19780 type = byte_get (ptr, 4);
19781 datasz = byte_get (ptr + 4, 4);
9ef920e9 19782
1fc87489 19783 ptr += 8;
9ef920e9 19784
6ab2c4ed 19785 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19786 {
1fc87489
L
19787 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19788 type, datasz);
9ef920e9 19789 break;
1fc87489 19790 }
9ef920e9 19791
1fc87489
L
19792 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19793 {
dda8d76d
NC
19794 if (filedata->file_header.e_machine == EM_X86_64
19795 || filedata->file_header.e_machine == EM_IAMCU
19796 || filedata->file_header.e_machine == EM_386)
1fc87489 19797 {
aa7bca9b
L
19798 unsigned int bitmask;
19799
19800 if (datasz == 4)
0a59decb 19801 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19802 else
19803 bitmask = 0;
19804
1fc87489
L
19805 switch (type)
19806 {
19807 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19808 if (datasz != 4)
aa7bca9b
L
19809 printf (_("x86 ISA used: <corrupt length: %#x> "),
19810 datasz);
1fc87489 19811 else
aa7bca9b
L
19812 {
19813 printf ("x86 ISA used: ");
19814 decode_x86_isa (bitmask);
19815 }
1fc87489 19816 goto next;
9ef920e9 19817
1fc87489 19818 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19819 if (datasz != 4)
aa7bca9b
L
19820 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19821 datasz);
1fc87489 19822 else
aa7bca9b
L
19823 {
19824 printf ("x86 ISA needed: ");
19825 decode_x86_isa (bitmask);
19826 }
1fc87489 19827 goto next;
9ef920e9 19828
ee2fdd6f 19829 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19830 if (datasz != 4)
aa7bca9b
L
19831 printf (_("x86 feature: <corrupt length: %#x> "),
19832 datasz);
ee2fdd6f 19833 else
aa7bca9b
L
19834 {
19835 printf ("x86 feature: ");
a9eafb08
L
19836 decode_x86_feature_1 (bitmask);
19837 }
19838 goto next;
19839
19840 case GNU_PROPERTY_X86_FEATURE_2_USED:
19841 if (datasz != 4)
19842 printf (_("x86 feature used: <corrupt length: %#x> "),
19843 datasz);
19844 else
19845 {
19846 printf ("x86 feature used: ");
19847 decode_x86_feature_2 (bitmask);
19848 }
19849 goto next;
19850
19851 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19852 if (datasz != 4)
19853 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19854 else
19855 {
19856 printf ("x86 feature needed: ");
19857 decode_x86_feature_2 (bitmask);
19858 }
19859 goto next;
19860
19861 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19862 if (datasz != 4)
19863 printf (_("x86 ISA used: <corrupt length: %#x> "),
19864 datasz);
19865 else
19866 {
19867 printf ("x86 ISA used: ");
19868 decode_x86_compat_isa (bitmask);
19869 }
19870 goto next;
19871
19872 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19873 if (datasz != 4)
19874 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19875 datasz);
19876 else
19877 {
19878 printf ("x86 ISA needed: ");
19879 decode_x86_compat_isa (bitmask);
aa7bca9b 19880 }
ee2fdd6f
L
19881 goto next;
19882
32930e4e
L
19883 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19884 if (datasz != 4)
19885 printf (_("x86 ISA used: <corrupt length: %#x> "),
19886 datasz);
19887 else
19888 {
19889 printf ("x86 ISA used: ");
19890 decode_x86_compat_2_isa (bitmask);
19891 }
19892 goto next;
19893
19894 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19895 if (datasz != 4)
19896 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19897 datasz);
19898 else
19899 {
19900 printf ("x86 ISA needed: ");
19901 decode_x86_compat_2_isa (bitmask);
19902 }
19903 goto next;
19904
1fc87489
L
19905 default:
19906 break;
19907 }
19908 }
cd702818
SD
19909 else if (filedata->file_header.e_machine == EM_AARCH64)
19910 {
19911 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19912 {
19913 printf ("AArch64 feature: ");
19914 if (datasz != 4)
19915 printf (_("<corrupt length: %#x> "), datasz);
19916 else
19917 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19918 goto next;
19919 }
19920 }
1fc87489
L
19921 }
19922 else
19923 {
19924 switch (type)
9ef920e9 19925 {
1fc87489
L
19926 case GNU_PROPERTY_STACK_SIZE:
19927 printf (_("stack size: "));
19928 if (datasz != size)
19929 printf (_("<corrupt length: %#x> "), datasz);
19930 else
19931 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19932 goto next;
19933
19934 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19935 printf ("no copy on protected ");
19936 if (datasz)
19937 printf (_("<corrupt length: %#x> "), datasz);
19938 goto next;
19939
19940 default:
5a767724
L
19941 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19942 && type <= GNU_PROPERTY_UINT32_AND_HI)
19943 || (type >= GNU_PROPERTY_UINT32_OR_LO
19944 && type <= GNU_PROPERTY_UINT32_OR_HI))
19945 {
6320fd00
L
19946 switch (type)
19947 {
19948 case GNU_PROPERTY_1_NEEDED:
19949 if (datasz != 4)
19950 printf (_("1_needed: <corrupt length: %#x> "),
19951 datasz);
19952 else
19953 {
19954 unsigned int bitmask = byte_get (ptr, 4);
19955 printf ("1_needed: ");
19956 decode_1_needed (bitmask);
19957 }
19958 goto next;
19959
19960 default:
19961 break;
19962 }
5a767724
L
19963 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19964 printf (_("UINT32_AND (%#x): "), type);
19965 else
19966 printf (_("UINT32_OR (%#x): "), type);
19967 if (datasz != 4)
19968 printf (_("<corrupt length: %#x> "), datasz);
19969 else
19970 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19971 goto next;
19972 }
9ef920e9
NC
19973 break;
19974 }
9ef920e9
NC
19975 }
19976
1fc87489
L
19977 if (type < GNU_PROPERTY_LOPROC)
19978 printf (_("<unknown type %#x data: "), type);
19979 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19980 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19981 else
19982 printf (_("<application-specific type %#x data: "), type);
19983 for (j = 0; j < datasz; ++j)
19984 printf ("%02x ", ptr[j] & 0xff);
19985 printf (">");
19986
dc1e8a47 19987 next:
9ef920e9 19988 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19989 if (ptr == ptr_end)
19990 break;
1fc87489 19991
6ab2c4ed
MC
19992 if (do_wide)
19993 printf (", ");
19994 else
19995 printf ("\n\t");
9ef920e9
NC
19996 }
19997
19998 printf ("\n");
19999}
20000
015dc7e1 20001static bool
dda8d76d 20002print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 20003{
1449284b 20004 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
20005 switch (pnote->type)
20006 {
20007 case NT_GNU_BUILD_ID:
20008 {
20009 unsigned long i;
20010
20011 printf (_(" Build ID: "));
20012 for (i = 0; i < pnote->descsz; ++i)
20013 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 20014 printf ("\n");
664f90a3
TT
20015 }
20016 break;
20017
20018 case NT_GNU_ABI_TAG:
20019 {
20020 unsigned long os, major, minor, subminor;
20021 const char *osname;
20022
3102e897
NC
20023 /* PR 17531: file: 030-599401-0.004. */
20024 if (pnote->descsz < 16)
20025 {
20026 printf (_(" <corrupt GNU_ABI_TAG>\n"));
20027 break;
20028 }
20029
664f90a3
TT
20030 os = byte_get ((unsigned char *) pnote->descdata, 4);
20031 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20032 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
20033 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
20034
20035 switch (os)
20036 {
20037 case GNU_ABI_TAG_LINUX:
20038 osname = "Linux";
20039 break;
20040 case GNU_ABI_TAG_HURD:
20041 osname = "Hurd";
20042 break;
20043 case GNU_ABI_TAG_SOLARIS:
20044 osname = "Solaris";
20045 break;
20046 case GNU_ABI_TAG_FREEBSD:
20047 osname = "FreeBSD";
20048 break;
20049 case GNU_ABI_TAG_NETBSD:
20050 osname = "NetBSD";
20051 break;
14ae95f2
RM
20052 case GNU_ABI_TAG_SYLLABLE:
20053 osname = "Syllable";
20054 break;
20055 case GNU_ABI_TAG_NACL:
20056 osname = "NaCl";
20057 break;
664f90a3
TT
20058 default:
20059 osname = "Unknown";
20060 break;
20061 }
20062
20063 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
20064 major, minor, subminor);
20065 }
20066 break;
926c5385
CC
20067
20068 case NT_GNU_GOLD_VERSION:
20069 {
20070 unsigned long i;
20071
20072 printf (_(" Version: "));
20073 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
20074 printf ("%c", pnote->descdata[i]);
20075 printf ("\n");
20076 }
20077 break;
1449284b
NC
20078
20079 case NT_GNU_HWCAP:
20080 {
20081 unsigned long num_entries, mask;
20082
20083 /* Hardware capabilities information. Word 0 is the number of entries.
20084 Word 1 is a bitmask of enabled entries. The rest of the descriptor
20085 is a series of entries, where each entry is a single byte followed
20086 by a nul terminated string. The byte gives the bit number to test
20087 if enabled in the bitmask. */
20088 printf (_(" Hardware Capabilities: "));
20089 if (pnote->descsz < 8)
20090 {
32ec8896 20091 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 20092 return false;
1449284b
NC
20093 }
20094 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
20095 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
20096 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
20097 /* FIXME: Add code to display the entries... */
20098 }
20099 break;
20100
9ef920e9 20101 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 20102 print_gnu_property_note (filedata, pnote);
9ef920e9 20103 break;
9abca702 20104
1449284b
NC
20105 default:
20106 /* Handle unrecognised types. An error message should have already been
20107 created by get_gnu_elf_note_type(), so all that we need to do is to
20108 display the data. */
20109 {
20110 unsigned long i;
20111
20112 printf (_(" Description data: "));
20113 for (i = 0; i < pnote->descsz; ++i)
20114 printf ("%02x ", pnote->descdata[i] & 0xff);
20115 printf ("\n");
20116 }
20117 break;
664f90a3
TT
20118 }
20119
015dc7e1 20120 return true;
664f90a3
TT
20121}
20122
685080f2
NC
20123static const char *
20124get_v850_elf_note_type (enum v850_notes n_type)
20125{
20126 static char buff[64];
20127
20128 switch (n_type)
20129 {
20130 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
20131 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
20132 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
20133 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
20134 case V850_NOTE_CACHE_INFO: return _("Use of cache");
20135 case V850_NOTE_MMU_INFO: return _("Use of MMU");
20136 default:
20137 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
20138 return buff;
20139 }
20140}
20141
015dc7e1 20142static bool
685080f2
NC
20143print_v850_note (Elf_Internal_Note * pnote)
20144{
20145 unsigned int val;
20146
20147 if (pnote->descsz != 4)
015dc7e1 20148 return false;
32ec8896 20149
685080f2
NC
20150 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
20151
20152 if (val == 0)
20153 {
20154 printf (_("not set\n"));
015dc7e1 20155 return true;
685080f2
NC
20156 }
20157
20158 switch (pnote->type)
20159 {
20160 case V850_NOTE_ALIGNMENT:
20161 switch (val)
20162 {
015dc7e1
AM
20163 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
20164 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
20165 }
20166 break;
14ae95f2 20167
685080f2
NC
20168 case V850_NOTE_DATA_SIZE:
20169 switch (val)
20170 {
015dc7e1
AM
20171 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
20172 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
20173 }
20174 break;
14ae95f2 20175
685080f2
NC
20176 case V850_NOTE_FPU_INFO:
20177 switch (val)
20178 {
015dc7e1
AM
20179 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
20180 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
20181 }
20182 break;
14ae95f2 20183
685080f2
NC
20184 case V850_NOTE_MMU_INFO:
20185 case V850_NOTE_CACHE_INFO:
20186 case V850_NOTE_SIMD_INFO:
20187 if (val == EF_RH850_SIMD)
20188 {
20189 printf (_("yes\n"));
015dc7e1 20190 return true;
685080f2
NC
20191 }
20192 break;
20193
20194 default:
20195 /* An 'unknown note type' message will already have been displayed. */
20196 break;
20197 }
20198
20199 printf (_("unknown value: %x\n"), val);
015dc7e1 20200 return false;
685080f2
NC
20201}
20202
015dc7e1 20203static bool
c6056a74
SF
20204process_netbsd_elf_note (Elf_Internal_Note * pnote)
20205{
20206 unsigned int version;
20207
20208 switch (pnote->type)
20209 {
20210 case NT_NETBSD_IDENT:
b966f55f
AM
20211 if (pnote->descsz < 1)
20212 break;
c6056a74
SF
20213 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20214 if ((version / 10000) % 100)
b966f55f 20215 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
20216 version, version / 100000000, (version / 1000000) % 100,
20217 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 20218 'A' + (version / 10000) % 26);
c6056a74
SF
20219 else
20220 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 20221 version, version / 100000000, (version / 1000000) % 100,
15f205b1 20222 (version / 100) % 100);
015dc7e1 20223 return true;
c6056a74
SF
20224
20225 case NT_NETBSD_MARCH:
9abca702 20226 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 20227 pnote->descdata);
015dc7e1 20228 return true;
c6056a74 20229
9abca702 20230 case NT_NETBSD_PAX:
b966f55f
AM
20231 if (pnote->descsz < 1)
20232 break;
9abca702
CZ
20233 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
20234 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
20235 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
20236 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
20237 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
20238 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
20239 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
20240 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 20241 return true;
c6056a74 20242 }
b966f55f
AM
20243
20244 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
20245 pnote->descsz, pnote->type);
015dc7e1 20246 return false;
c6056a74
SF
20247}
20248
f4ddf30f 20249static const char *
dda8d76d 20250get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 20251{
f4ddf30f
JB
20252 switch (e_type)
20253 {
20254 case NT_FREEBSD_THRMISC:
20255 return _("NT_THRMISC (thrmisc structure)");
20256 case NT_FREEBSD_PROCSTAT_PROC:
20257 return _("NT_PROCSTAT_PROC (proc data)");
20258 case NT_FREEBSD_PROCSTAT_FILES:
20259 return _("NT_PROCSTAT_FILES (files data)");
20260 case NT_FREEBSD_PROCSTAT_VMMAP:
20261 return _("NT_PROCSTAT_VMMAP (vmmap data)");
20262 case NT_FREEBSD_PROCSTAT_GROUPS:
20263 return _("NT_PROCSTAT_GROUPS (groups data)");
20264 case NT_FREEBSD_PROCSTAT_UMASK:
20265 return _("NT_PROCSTAT_UMASK (umask data)");
20266 case NT_FREEBSD_PROCSTAT_RLIMIT:
20267 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
20268 case NT_FREEBSD_PROCSTAT_OSREL:
20269 return _("NT_PROCSTAT_OSREL (osreldate data)");
20270 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
20271 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
20272 case NT_FREEBSD_PROCSTAT_AUXV:
20273 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
20274 case NT_FREEBSD_PTLWPINFO:
20275 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 20276 }
dda8d76d 20277 return get_note_type (filedata, e_type);
f4ddf30f
JB
20278}
20279
9437c45b 20280static const char *
dda8d76d 20281get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
20282{
20283 static char buff[64];
20284
540e6170
CZ
20285 switch (e_type)
20286 {
20287 case NT_NETBSDCORE_PROCINFO:
20288 /* NetBSD core "procinfo" structure. */
20289 return _("NetBSD procinfo structure");
9437c45b 20290
540e6170
CZ
20291 case NT_NETBSDCORE_AUXV:
20292 return _("NetBSD ELF auxiliary vector data");
9437c45b 20293
06d949ec
KR
20294 case NT_NETBSDCORE_LWPSTATUS:
20295 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 20296
540e6170 20297 default:
06d949ec 20298 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
20299 defined for NetBSD core files. If the note type is less
20300 than the start of the machine-dependent note types, we don't
20301 understand it. */
20302
20303 if (e_type < NT_NETBSDCORE_FIRSTMACH)
20304 {
20305 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20306 return buff;
20307 }
20308 break;
9437c45b
JT
20309 }
20310
dda8d76d 20311 switch (filedata->file_header.e_machine)
9437c45b
JT
20312 {
20313 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
20314 and PT_GETFPREGS == mach+2. */
20315
20316 case EM_OLD_ALPHA:
20317 case EM_ALPHA:
20318 case EM_SPARC:
20319 case EM_SPARC32PLUS:
20320 case EM_SPARCV9:
20321 switch (e_type)
20322 {
2b692964 20323 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 20324 return _("PT_GETREGS (reg structure)");
2b692964 20325 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 20326 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20327 default:
20328 break;
20329 }
20330 break;
20331
c0d38b0e
CZ
20332 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
20333 There's also old PT___GETREGS40 == mach + 1 for old reg
20334 structure which lacks GBR. */
20335 case EM_SH:
20336 switch (e_type)
20337 {
20338 case NT_NETBSDCORE_FIRSTMACH + 1:
20339 return _("PT___GETREGS40 (old reg structure)");
20340 case NT_NETBSDCORE_FIRSTMACH + 3:
20341 return _("PT_GETREGS (reg structure)");
20342 case NT_NETBSDCORE_FIRSTMACH + 5:
20343 return _("PT_GETFPREGS (fpreg structure)");
20344 default:
20345 break;
20346 }
20347 break;
20348
9437c45b
JT
20349 /* On all other arch's, PT_GETREGS == mach+1 and
20350 PT_GETFPREGS == mach+3. */
20351 default:
20352 switch (e_type)
20353 {
2b692964 20354 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 20355 return _("PT_GETREGS (reg structure)");
2b692964 20356 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 20357 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
20358 default:
20359 break;
20360 }
20361 }
20362
9cf03b7e 20363 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 20364 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
20365 return buff;
20366}
20367
98ca73af
FC
20368static const char *
20369get_openbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
20370{
20371 switch (e_type)
20372 {
20373 case NT_OPENBSD_PROCINFO:
20374 return _("OpenBSD procinfo structure");
20375 case NT_OPENBSD_AUXV:
20376 return _("OpenBSD ELF auxiliary vector data");
20377 case NT_OPENBSD_REGS:
20378 return _("OpenBSD regular registers");
20379 case NT_OPENBSD_FPREGS:
20380 return _("OpenBSD floating point registers");
20381 case NT_OPENBSD_WCOOKIE:
20382 return _("OpenBSD window cookie");
20383 }
20384
20385 return get_note_type (filedata, e_type);
20386}
20387
70616151
TT
20388static const char *
20389get_stapsdt_note_type (unsigned e_type)
20390{
20391 static char buff[64];
20392
20393 switch (e_type)
20394 {
20395 case NT_STAPSDT:
20396 return _("NT_STAPSDT (SystemTap probe descriptors)");
20397
20398 default:
20399 break;
20400 }
20401
20402 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20403 return buff;
20404}
20405
015dc7e1 20406static bool
c6a9fc58
TT
20407print_stapsdt_note (Elf_Internal_Note *pnote)
20408{
3ca60c57
NC
20409 size_t len, maxlen;
20410 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20411 char *data = pnote->descdata;
20412 char *data_end = pnote->descdata + pnote->descsz;
20413 bfd_vma pc, base_addr, semaphore;
20414 char *provider, *probe, *arg_fmt;
20415
3ca60c57
NC
20416 if (pnote->descsz < (addr_size * 3))
20417 goto stapdt_note_too_small;
20418
c6a9fc58
TT
20419 pc = byte_get ((unsigned char *) data, addr_size);
20420 data += addr_size;
3ca60c57 20421
c6a9fc58
TT
20422 base_addr = byte_get ((unsigned char *) data, addr_size);
20423 data += addr_size;
3ca60c57 20424
c6a9fc58
TT
20425 semaphore = byte_get ((unsigned char *) data, addr_size);
20426 data += addr_size;
20427
3ca60c57
NC
20428 if (data >= data_end)
20429 goto stapdt_note_too_small;
20430 maxlen = data_end - data;
20431 len = strnlen (data, maxlen);
20432 if (len < maxlen)
20433 {
20434 provider = data;
20435 data += len + 1;
20436 }
20437 else
20438 goto stapdt_note_too_small;
20439
20440 if (data >= data_end)
20441 goto stapdt_note_too_small;
20442 maxlen = data_end - data;
20443 len = strnlen (data, maxlen);
20444 if (len < maxlen)
20445 {
20446 probe = data;
20447 data += len + 1;
20448 }
20449 else
20450 goto stapdt_note_too_small;
9abca702 20451
3ca60c57
NC
20452 if (data >= data_end)
20453 goto stapdt_note_too_small;
20454 maxlen = data_end - data;
20455 len = strnlen (data, maxlen);
20456 if (len < maxlen)
20457 {
20458 arg_fmt = data;
20459 data += len + 1;
20460 }
20461 else
20462 goto stapdt_note_too_small;
c6a9fc58
TT
20463
20464 printf (_(" Provider: %s\n"), provider);
20465 printf (_(" Name: %s\n"), probe);
20466 printf (_(" Location: "));
20467 print_vma (pc, FULL_HEX);
20468 printf (_(", Base: "));
20469 print_vma (base_addr, FULL_HEX);
20470 printf (_(", Semaphore: "));
20471 print_vma (semaphore, FULL_HEX);
9cf03b7e 20472 printf ("\n");
c6a9fc58
TT
20473 printf (_(" Arguments: %s\n"), arg_fmt);
20474
20475 return data == data_end;
3ca60c57
NC
20476
20477 stapdt_note_too_small:
20478 printf (_(" <corrupt - note is too small>\n"));
20479 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20480 return false;
c6a9fc58
TT
20481}
20482
e5382207
LB
20483static bool
20484print_fdo_note (Elf_Internal_Note * pnote)
20485{
20486 if (pnote->descsz > 0 && pnote->type == FDO_PACKAGING_METADATA)
20487 {
20488 printf (_(" Packaging Metadata: %.*s\n"), (int) pnote->descsz, pnote->descdata);
20489 return true;
20490 }
20491 return false;
20492}
20493
00e98fc7
TG
20494static const char *
20495get_ia64_vms_note_type (unsigned e_type)
20496{
20497 static char buff[64];
20498
20499 switch (e_type)
20500 {
20501 case NT_VMS_MHD:
20502 return _("NT_VMS_MHD (module header)");
20503 case NT_VMS_LNM:
20504 return _("NT_VMS_LNM (language name)");
20505 case NT_VMS_SRC:
20506 return _("NT_VMS_SRC (source files)");
20507 case NT_VMS_TITLE:
9cf03b7e 20508 return "NT_VMS_TITLE";
00e98fc7
TG
20509 case NT_VMS_EIDC:
20510 return _("NT_VMS_EIDC (consistency check)");
20511 case NT_VMS_FPMODE:
20512 return _("NT_VMS_FPMODE (FP mode)");
20513 case NT_VMS_LINKTIME:
9cf03b7e 20514 return "NT_VMS_LINKTIME";
00e98fc7
TG
20515 case NT_VMS_IMGNAM:
20516 return _("NT_VMS_IMGNAM (image name)");
20517 case NT_VMS_IMGID:
20518 return _("NT_VMS_IMGID (image id)");
20519 case NT_VMS_LINKID:
20520 return _("NT_VMS_LINKID (link id)");
20521 case NT_VMS_IMGBID:
20522 return _("NT_VMS_IMGBID (build id)");
20523 case NT_VMS_GSTNAM:
20524 return _("NT_VMS_GSTNAM (sym table name)");
20525 case NT_VMS_ORIG_DYN:
9cf03b7e 20526 return "NT_VMS_ORIG_DYN";
00e98fc7 20527 case NT_VMS_PATCHTIME:
9cf03b7e 20528 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20529 default:
20530 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20531 return buff;
20532 }
20533}
20534
015dc7e1 20535static bool
00e98fc7
TG
20536print_ia64_vms_note (Elf_Internal_Note * pnote)
20537{
8d18bf79
NC
20538 int maxlen = pnote->descsz;
20539
20540 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20541 goto desc_size_fail;
20542
00e98fc7
TG
20543 switch (pnote->type)
20544 {
20545 case NT_VMS_MHD:
8d18bf79
NC
20546 if (maxlen <= 36)
20547 goto desc_size_fail;
20548
20549 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20550
20551 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20552 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20553 if (l + 34 < maxlen)
20554 {
20555 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20556 if (l + 35 < maxlen)
20557 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20558 else
20559 printf (_(" Module version : <missing>\n"));
20560 }
00e98fc7 20561 else
8d18bf79
NC
20562 {
20563 printf (_(" Module name : <missing>\n"));
20564 printf (_(" Module version : <missing>\n"));
20565 }
00e98fc7 20566 break;
8d18bf79 20567
00e98fc7 20568 case NT_VMS_LNM:
8d18bf79 20569 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20570 break;
8d18bf79 20571
00e98fc7
TG
20572#ifdef BFD64
20573 case NT_VMS_FPMODE:
9cf03b7e 20574 printf (_(" Floating Point mode: "));
8d18bf79
NC
20575 if (maxlen < 8)
20576 goto desc_size_fail;
20577 /* FIXME: Generate an error if descsz > 8 ? */
20578
4a5cb34f 20579 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20580 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20581 break;
8d18bf79 20582
00e98fc7
TG
20583 case NT_VMS_LINKTIME:
20584 printf (_(" Link time: "));
8d18bf79
NC
20585 if (maxlen < 8)
20586 goto desc_size_fail;
20587 /* FIXME: Generate an error if descsz > 8 ? */
20588
00e98fc7 20589 print_vms_time
8d18bf79 20590 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20591 printf ("\n");
20592 break;
8d18bf79 20593
00e98fc7
TG
20594 case NT_VMS_PATCHTIME:
20595 printf (_(" Patch time: "));
8d18bf79
NC
20596 if (maxlen < 8)
20597 goto desc_size_fail;
20598 /* FIXME: Generate an error if descsz > 8 ? */
20599
00e98fc7 20600 print_vms_time
8d18bf79 20601 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20602 printf ("\n");
20603 break;
8d18bf79 20604
00e98fc7 20605 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20606 if (maxlen < 34)
20607 goto desc_size_fail;
20608
00e98fc7
TG
20609 printf (_(" Major id: %u, minor id: %u\n"),
20610 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20611 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20612 printf (_(" Last modified : "));
00e98fc7
TG
20613 print_vms_time
20614 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20615 printf (_("\n Link flags : "));
4a5cb34f 20616 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20617 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20618 printf (_(" Header flags: 0x%08x\n"),
948f632f 20619 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20620 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20621 break;
20622#endif
8d18bf79 20623
00e98fc7 20624 case NT_VMS_IMGNAM:
8d18bf79 20625 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20626 break;
8d18bf79 20627
00e98fc7 20628 case NT_VMS_GSTNAM:
8d18bf79 20629 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20630 break;
8d18bf79 20631
00e98fc7 20632 case NT_VMS_IMGID:
8d18bf79 20633 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20634 break;
8d18bf79 20635
00e98fc7 20636 case NT_VMS_LINKID:
8d18bf79 20637 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20638 break;
8d18bf79 20639
00e98fc7 20640 default:
015dc7e1 20641 return false;
00e98fc7 20642 }
8d18bf79 20643
015dc7e1 20644 return true;
8d18bf79
NC
20645
20646 desc_size_fail:
20647 printf (_(" <corrupt - data size is too small>\n"));
20648 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20649 return false;
00e98fc7
TG
20650}
20651
fd486f32
AM
20652struct build_attr_cache {
20653 Filedata *filedata;
20654 char *strtab;
20655 unsigned long strtablen;
20656 Elf_Internal_Sym *symtab;
20657 unsigned long nsyms;
20658} ba_cache;
20659
6f156d7a
NC
20660/* Find the symbol associated with a build attribute that is attached
20661 to address OFFSET. If PNAME is non-NULL then store the name of
20662 the symbol (if found) in the provided pointer, Returns NULL if a
20663 symbol could not be found. */
c799a79d 20664
6f156d7a 20665static Elf_Internal_Sym *
015dc7e1
AM
20666get_symbol_for_build_attribute (Filedata *filedata,
20667 unsigned long offset,
20668 bool is_open_attr,
20669 const char **pname)
9ef920e9 20670{
fd486f32
AM
20671 Elf_Internal_Sym *saved_sym = NULL;
20672 Elf_Internal_Sym *sym;
9ef920e9 20673
dda8d76d 20674 if (filedata->section_headers != NULL
fd486f32 20675 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20676 {
c799a79d 20677 Elf_Internal_Shdr * symsec;
9ef920e9 20678
fd486f32
AM
20679 free (ba_cache.strtab);
20680 ba_cache.strtab = NULL;
20681 free (ba_cache.symtab);
20682 ba_cache.symtab = NULL;
20683
c799a79d 20684 /* Load the symbol and string sections. */
dda8d76d
NC
20685 for (symsec = filedata->section_headers;
20686 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20687 symsec ++)
9ef920e9 20688 {
28d13567
AM
20689 if (symsec->sh_type == SHT_SYMTAB
20690 && get_symtab (filedata, symsec,
20691 &ba_cache.symtab, &ba_cache.nsyms,
20692 &ba_cache.strtab, &ba_cache.strtablen))
20693 break;
9ef920e9 20694 }
fd486f32 20695 ba_cache.filedata = filedata;
9ef920e9
NC
20696 }
20697
fd486f32 20698 if (ba_cache.symtab == NULL)
6f156d7a 20699 return NULL;
9ef920e9 20700
c799a79d 20701 /* Find a symbol whose value matches offset. */
fd486f32 20702 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20703 if (sym->st_value == offset)
20704 {
fd486f32 20705 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20706 /* Huh ? This should not happen. */
20707 continue;
9ef920e9 20708
fd486f32 20709 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20710 continue;
9ef920e9 20711
9b9b1092 20712 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20713 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20714 if (ba_cache.strtab[sym->st_name] == '$'
20715 && ba_cache.strtab[sym->st_name + 1] != 0
20716 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20717 continue;
20718
c799a79d
NC
20719 if (is_open_attr)
20720 {
20721 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20722 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20723 FUNC symbols entirely. */
20724 switch (ELF_ST_TYPE (sym->st_info))
20725 {
c799a79d 20726 case STT_OBJECT:
6f156d7a 20727 case STT_FILE:
c799a79d 20728 saved_sym = sym;
6f156d7a
NC
20729 if (sym->st_size)
20730 {
20731 /* If the symbol has a size associated
20732 with it then we can stop searching. */
fd486f32 20733 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20734 }
c799a79d 20735 continue;
9ef920e9 20736
c799a79d
NC
20737 case STT_FUNC:
20738 /* Ignore function symbols. */
20739 continue;
20740
20741 default:
20742 break;
20743 }
20744
20745 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20746 {
c799a79d
NC
20747 case STB_GLOBAL:
20748 if (saved_sym == NULL
20749 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20750 saved_sym = sym;
20751 break;
c871dade 20752
c799a79d
NC
20753 case STB_LOCAL:
20754 if (saved_sym == NULL)
20755 saved_sym = sym;
20756 break;
20757
20758 default:
9ef920e9
NC
20759 break;
20760 }
20761 }
c799a79d
NC
20762 else
20763 {
20764 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20765 continue;
20766
20767 saved_sym = sym;
20768 break;
20769 }
20770 }
20771
6f156d7a 20772 if (saved_sym && pname)
fd486f32 20773 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20774
20775 return saved_sym;
c799a79d
NC
20776}
20777
d20e98ab
NC
20778/* Returns true iff addr1 and addr2 are in the same section. */
20779
015dc7e1 20780static bool
d20e98ab
NC
20781same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20782{
20783 Elf_Internal_Shdr * a1;
20784 Elf_Internal_Shdr * a2;
20785
20786 a1 = find_section_by_address (filedata, addr1);
20787 a2 = find_section_by_address (filedata, addr2);
9abca702 20788
d20e98ab
NC
20789 return a1 == a2 && a1 != NULL;
20790}
20791
015dc7e1 20792static bool
dda8d76d
NC
20793print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20794 Filedata * filedata)
c799a79d 20795{
015dc7e1
AM
20796 static unsigned long global_offset = 0;
20797 static unsigned long global_end = 0;
20798 static unsigned long func_offset = 0;
20799 static unsigned long func_end = 0;
c871dade 20800
015dc7e1
AM
20801 Elf_Internal_Sym *sym;
20802 const char *name;
20803 unsigned long start;
20804 unsigned long end;
20805 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20806
20807 switch (pnote->descsz)
c799a79d 20808 {
6f156d7a
NC
20809 case 0:
20810 /* A zero-length description means that the range of
20811 the previous note of the same type should be used. */
c799a79d 20812 if (is_open_attr)
c871dade 20813 {
6f156d7a
NC
20814 if (global_end > global_offset)
20815 printf (_(" Applies to region from %#lx to %#lx\n"),
20816 global_offset, global_end);
20817 else
20818 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20819 }
20820 else
20821 {
6f156d7a
NC
20822 if (func_end > func_offset)
20823 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20824 else
20825 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20826 }
015dc7e1 20827 return true;
9ef920e9 20828
6f156d7a
NC
20829 case 4:
20830 start = byte_get ((unsigned char *) pnote->descdata, 4);
20831 end = 0;
20832 break;
20833
20834 case 8:
c74147bb
NC
20835 start = byte_get ((unsigned char *) pnote->descdata, 4);
20836 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20837 break;
20838
20839 case 16:
20840 start = byte_get ((unsigned char *) pnote->descdata, 8);
20841 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20842 break;
9abca702 20843
6f156d7a 20844 default:
c799a79d
NC
20845 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20846 printf (_(" <invalid descsz>"));
015dc7e1 20847 return false;
c799a79d
NC
20848 }
20849
6f156d7a
NC
20850 name = NULL;
20851 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20852 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20853 in order to avoid them being confused with the start address of the
20854 first function in the file... */
20855 if (sym == NULL && is_open_attr)
20856 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20857 & name);
6f156d7a
NC
20858
20859 if (end == 0 && sym != NULL && sym->st_size > 0)
20860 end = start + sym->st_size;
c799a79d
NC
20861
20862 if (is_open_attr)
20863 {
d20e98ab
NC
20864 /* FIXME: Need to properly allow for section alignment.
20865 16 is just the alignment used on x86_64. */
20866 if (global_end > 0
20867 && start > BFD_ALIGN (global_end, 16)
20868 /* Build notes are not guaranteed to be organised in order of
20869 increasing address, but we should find the all of the notes
20870 for one section in the same place. */
20871 && same_section (filedata, start, global_end))
6f156d7a
NC
20872 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20873 global_end + 1, start - 1);
20874
20875 printf (_(" Applies to region from %#lx"), start);
20876 global_offset = start;
20877
20878 if (end)
20879 {
20880 printf (_(" to %#lx"), end);
20881 global_end = end;
20882 }
c799a79d
NC
20883 }
20884 else
20885 {
6f156d7a
NC
20886 printf (_(" Applies to region from %#lx"), start);
20887 func_offset = start;
20888
20889 if (end)
20890 {
20891 printf (_(" to %#lx"), end);
20892 func_end = end;
20893 }
c799a79d
NC
20894 }
20895
6f156d7a
NC
20896 if (sym && name)
20897 printf (_(" (%s)"), name);
20898
20899 printf ("\n");
015dc7e1 20900 return true;
9ef920e9
NC
20901}
20902
015dc7e1 20903static bool
9ef920e9
NC
20904print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20905{
1d15e434
NC
20906 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20907 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20908 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20909 char name_type;
20910 char name_attribute;
1d15e434 20911 const char * expected_types;
9ef920e9
NC
20912 const char * name = pnote->namedata;
20913 const char * text;
88305e1b 20914 signed int left;
9ef920e9
NC
20915
20916 if (name == NULL || pnote->namesz < 2)
20917 {
20918 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20919 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20920 return false;
9ef920e9
NC
20921 }
20922
6f156d7a
NC
20923 if (do_wide)
20924 left = 28;
20925 else
20926 left = 20;
88305e1b
NC
20927
20928 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20929 if (name[0] == 'G' && name[1] == 'A')
20930 {
6f156d7a
NC
20931 if (pnote->namesz < 4)
20932 {
20933 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20934 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20935 return false;
6f156d7a
NC
20936 }
20937
88305e1b
NC
20938 printf ("GA");
20939 name += 2;
20940 left -= 2;
20941 }
20942
9ef920e9
NC
20943 switch ((name_type = * name))
20944 {
20945 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20946 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20947 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20948 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20949 printf ("%c", * name);
88305e1b 20950 left --;
9ef920e9
NC
20951 break;
20952 default:
20953 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20954 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20955 return false;
9ef920e9
NC
20956 }
20957
9ef920e9
NC
20958 ++ name;
20959 text = NULL;
20960
20961 switch ((name_attribute = * name))
20962 {
20963 case GNU_BUILD_ATTRIBUTE_VERSION:
20964 text = _("<version>");
1d15e434 20965 expected_types = string_expected;
9ef920e9
NC
20966 ++ name;
20967 break;
20968 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20969 text = _("<stack prot>");
75d7d298 20970 expected_types = "!+*";
9ef920e9
NC
20971 ++ name;
20972 break;
20973 case GNU_BUILD_ATTRIBUTE_RELRO:
20974 text = _("<relro>");
1d15e434 20975 expected_types = bool_expected;
9ef920e9
NC
20976 ++ name;
20977 break;
20978 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20979 text = _("<stack size>");
1d15e434 20980 expected_types = number_expected;
9ef920e9
NC
20981 ++ name;
20982 break;
20983 case GNU_BUILD_ATTRIBUTE_TOOL:
20984 text = _("<tool>");
1d15e434 20985 expected_types = string_expected;
9ef920e9
NC
20986 ++ name;
20987 break;
20988 case GNU_BUILD_ATTRIBUTE_ABI:
20989 text = _("<ABI>");
20990 expected_types = "$*";
20991 ++ name;
20992 break;
20993 case GNU_BUILD_ATTRIBUTE_PIC:
20994 text = _("<PIC>");
1d15e434 20995 expected_types = number_expected;
9ef920e9
NC
20996 ++ name;
20997 break;
a8be5506
NC
20998 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20999 text = _("<short enum>");
1d15e434 21000 expected_types = bool_expected;
a8be5506
NC
21001 ++ name;
21002 break;
9ef920e9
NC
21003 default:
21004 if (ISPRINT (* name))
21005 {
21006 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
21007
21008 if (len > left && ! do_wide)
21009 len = left;
75d7d298 21010 printf ("%.*s:", len, name);
9ef920e9 21011 left -= len;
0dd6ae21 21012 name += len;
9ef920e9
NC
21013 }
21014 else
21015 {
3e6b6445 21016 static char tmpbuf [128];
88305e1b 21017
3e6b6445
NC
21018 error (_("unrecognised byte in name field: %d\n"), * name);
21019 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
21020 text = tmpbuf;
21021 name ++;
9ef920e9
NC
21022 }
21023 expected_types = "*$!+";
21024 break;
21025 }
21026
21027 if (text)
88305e1b 21028 left -= printf ("%s", text);
9ef920e9
NC
21029
21030 if (strchr (expected_types, name_type) == NULL)
75d7d298 21031 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
21032
21033 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
21034 {
21035 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
21036 (unsigned long) pnote->namesz,
21037 (long) (name - pnote->namedata));
015dc7e1 21038 return false;
9ef920e9
NC
21039 }
21040
21041 if (left < 1 && ! do_wide)
015dc7e1 21042 return true;
9ef920e9
NC
21043
21044 switch (name_type)
21045 {
21046 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
21047 {
b06b2c92 21048 unsigned int bytes;
ddef72cd
NC
21049 unsigned long long val = 0;
21050 unsigned int shift = 0;
21051 char * decoded = NULL;
21052
b06b2c92
NC
21053 bytes = pnote->namesz - (name - pnote->namedata);
21054 if (bytes > 0)
21055 /* The -1 is because the name field is always 0 terminated, and we
21056 want to be able to ensure that the shift in the while loop below
21057 will not overflow. */
21058 -- bytes;
21059
ddef72cd
NC
21060 if (bytes > sizeof (val))
21061 {
3e6b6445
NC
21062 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
21063 bytes);
21064 bytes = sizeof (val);
ddef72cd 21065 }
3e6b6445
NC
21066 /* We do not bother to warn if bytes == 0 as this can
21067 happen with some early versions of the gcc plugin. */
9ef920e9
NC
21068
21069 while (bytes --)
21070 {
54b8331d 21071 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
21072
21073 val |= byte << shift;
9ef920e9
NC
21074 shift += 8;
21075 }
21076
75d7d298 21077 switch (name_attribute)
9ef920e9 21078 {
75d7d298 21079 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
21080 switch (val)
21081 {
75d7d298
NC
21082 case 0: decoded = "static"; break;
21083 case 1: decoded = "pic"; break;
21084 case 2: decoded = "PIC"; break;
21085 case 3: decoded = "pie"; break;
21086 case 4: decoded = "PIE"; break;
21087 default: break;
9ef920e9 21088 }
75d7d298
NC
21089 break;
21090 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
21091 switch (val)
9ef920e9 21092 {
75d7d298
NC
21093 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
21094 case 0: decoded = "off"; break;
21095 case 1: decoded = "on"; break;
21096 case 2: decoded = "all"; break;
21097 case 3: decoded = "strong"; break;
21098 case 4: decoded = "explicit"; break;
21099 default: break;
9ef920e9 21100 }
75d7d298
NC
21101 break;
21102 default:
21103 break;
9ef920e9
NC
21104 }
21105
75d7d298 21106 if (decoded != NULL)
3e6b6445
NC
21107 {
21108 print_symbol (-left, decoded);
21109 left = 0;
21110 }
21111 else if (val == 0)
21112 {
21113 printf ("0x0");
21114 left -= 3;
21115 }
9ef920e9 21116 else
75d7d298
NC
21117 {
21118 if (do_wide)
ddef72cd 21119 left -= printf ("0x%llx", val);
75d7d298 21120 else
ddef72cd 21121 left -= printf ("0x%-.*llx", left, val);
75d7d298 21122 }
9ef920e9
NC
21123 }
21124 break;
21125 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
21126 left -= print_symbol (- left, name);
21127 break;
21128 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
21129 left -= print_symbol (- left, "true");
21130 break;
21131 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
21132 left -= print_symbol (- left, "false");
21133 break;
21134 }
21135
21136 if (do_wide && left > 0)
21137 printf ("%-*s", left, " ");
9abca702 21138
015dc7e1 21139 return true;
9ef920e9
NC
21140}
21141
6d118b09
NC
21142/* Note that by the ELF standard, the name field is already null byte
21143 terminated, and namesz includes the terminating null byte.
21144 I.E. the value of namesz for the name "FSF" is 4.
21145
e3c8793a 21146 If the value of namesz is zero, there is no name present. */
9ef920e9 21147
015dc7e1 21148static bool
9ef920e9 21149process_note (Elf_Internal_Note * pnote,
dda8d76d 21150 Filedata * filedata)
779fe533 21151{
2cf0635d
NC
21152 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
21153 const char * nt;
9437c45b
JT
21154
21155 if (pnote->namesz == 0)
1ec5cd37
NC
21156 /* If there is no note name, then use the default set of
21157 note type strings. */
dda8d76d 21158 nt = get_note_type (filedata, pnote->type);
1ec5cd37 21159
24d127aa 21160 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
21161 /* GNU-specific object file notes. */
21162 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 21163
24d127aa 21164 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 21165 /* FreeBSD-specific core file notes. */
dda8d76d 21166 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 21167
24d127aa 21168 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 21169 /* NetBSD-specific core file notes. */
dda8d76d 21170 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 21171
24d127aa 21172 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
21173 /* NetBSD-specific core file notes. */
21174 return process_netbsd_elf_note (pnote);
21175
24d127aa 21176 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
21177 /* NetBSD-specific core file notes. */
21178 return process_netbsd_elf_note (pnote);
21179
98ca73af
FC
21180 else if (startswith (pnote->namedata, "OpenBSD"))
21181 /* OpenBSD-specific core file notes. */
21182 nt = get_openbsd_elfcore_note_type (filedata, pnote->type);
21183
e9b095a5 21184 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
21185 {
21186 /* SPU-specific core file notes. */
21187 nt = pnote->namedata + 4;
21188 name = "SPU";
21189 }
21190
24d127aa 21191 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
21192 /* VMS/ia64-specific file notes. */
21193 nt = get_ia64_vms_note_type (pnote->type);
21194
24d127aa 21195 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
21196 nt = get_stapsdt_note_type (pnote->type);
21197
9437c45b 21198 else
1ec5cd37
NC
21199 /* Don't recognize this note name; just use the default set of
21200 note type strings. */
dda8d76d 21201 nt = get_note_type (filedata, pnote->type);
9437c45b 21202
1449284b 21203 printf (" ");
9ef920e9 21204
24d127aa 21205 if (((startswith (pnote->namedata, "GA")
483767a3
AM
21206 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21207 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21208 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21209 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
21210 print_gnu_build_attribute_name (pnote);
21211 else
21212 print_symbol (-20, name);
21213
21214 if (do_wide)
21215 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
21216 else
21217 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 21218
24d127aa 21219 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 21220 return print_ia64_vms_note (pnote);
24d127aa 21221 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 21222 return print_gnu_note (filedata, pnote);
24d127aa 21223 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 21224 return print_stapsdt_note (pnote);
24d127aa 21225 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 21226 return print_core_note (pnote);
e5382207
LB
21227 else if (startswith (pnote->namedata, "FDO"))
21228 return print_fdo_note (pnote);
24d127aa 21229 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
21230 && strchr ("*$!+", pnote->namedata[2]) != NULL)
21231 || strchr ("*$!+", pnote->namedata[0]) != NULL)
21232 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
21233 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 21234 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 21235
9ef920e9 21236 if (pnote->descsz)
1449284b
NC
21237 {
21238 unsigned long i;
21239
21240 printf (_(" description data: "));
21241 for (i = 0; i < pnote->descsz; i++)
178d8719 21242 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
21243 if (!do_wide)
21244 printf ("\n");
1449284b
NC
21245 }
21246
9ef920e9
NC
21247 if (do_wide)
21248 printf ("\n");
21249
015dc7e1 21250 return true;
1449284b 21251}
6d118b09 21252
015dc7e1 21253static bool
dda8d76d
NC
21254process_notes_at (Filedata * filedata,
21255 Elf_Internal_Shdr * section,
21256 bfd_vma offset,
82ed9683
L
21257 bfd_vma length,
21258 bfd_vma align)
779fe533 21259{
015dc7e1
AM
21260 Elf_External_Note *pnotes;
21261 Elf_External_Note *external;
21262 char *end;
21263 bool res = true;
103f02d3 21264
779fe533 21265 if (length <= 0)
015dc7e1 21266 return false;
103f02d3 21267
1449284b
NC
21268 if (section)
21269 {
dda8d76d 21270 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 21271 if (pnotes)
32ec8896 21272 {
dda8d76d 21273 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
21274 {
21275 free (pnotes);
015dc7e1 21276 return false;
f761cb13 21277 }
32ec8896 21278 }
1449284b
NC
21279 }
21280 else
82ed9683 21281 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 21282 _("notes"));
4dff97b2 21283
dd24e3da 21284 if (pnotes == NULL)
015dc7e1 21285 return false;
779fe533 21286
103f02d3 21287 external = pnotes;
103f02d3 21288
ca0e11aa
NC
21289 if (filedata->is_separate)
21290 printf (_("In linked file '%s': "), filedata->file_name);
21291 else
21292 printf ("\n");
1449284b 21293 if (section)
ca0e11aa 21294 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 21295 else
ca0e11aa 21296 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
21297 (unsigned long) offset, (unsigned long) length);
21298
82ed9683
L
21299 /* NB: Some note sections may have alignment value of 0 or 1. gABI
21300 specifies that notes should be aligned to 4 bytes in 32-bit
21301 objects and to 8 bytes in 64-bit objects. As a Linux extension,
21302 we also support 4 byte alignment in 64-bit objects. If section
21303 alignment is less than 4, we treate alignment as 4 bytes. */
21304 if (align < 4)
21305 align = 4;
21306 else if (align != 4 && align != 8)
21307 {
21308 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
21309 (long) align);
a788aedd 21310 free (pnotes);
015dc7e1 21311 return false;
82ed9683
L
21312 }
21313
dbe15e4e 21314 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 21315
c8071705
NC
21316 end = (char *) pnotes + length;
21317 while ((char *) external < end)
779fe533 21318 {
b34976b6 21319 Elf_Internal_Note inote;
15b42fb0 21320 size_t min_notesz;
4dff97b2 21321 char * next;
2cf0635d 21322 char * temp = NULL;
c8071705 21323 size_t data_remaining = end - (char *) external;
6d118b09 21324
dda8d76d 21325 if (!is_ia64_vms (filedata))
15b42fb0 21326 {
9dd3a467
NC
21327 /* PR binutils/15191
21328 Make sure that there is enough data to read. */
15b42fb0
AM
21329 min_notesz = offsetof (Elf_External_Note, name);
21330 if (data_remaining < min_notesz)
9dd3a467 21331 {
d3a49aa8
AM
21332 warn (ngettext ("Corrupt note: only %ld byte remains, "
21333 "not enough for a full note\n",
21334 "Corrupt note: only %ld bytes remain, "
21335 "not enough for a full note\n",
21336 data_remaining),
21337 (long) data_remaining);
9dd3a467
NC
21338 break;
21339 }
5396a86e
AM
21340 data_remaining -= min_notesz;
21341
15b42fb0
AM
21342 inote.type = BYTE_GET (external->type);
21343 inote.namesz = BYTE_GET (external->namesz);
21344 inote.namedata = external->name;
21345 inote.descsz = BYTE_GET (external->descsz);
276da9b3 21346 inote.descdata = ((char *) external
4dff97b2 21347 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 21348 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 21349 next = ((char *) external
4dff97b2 21350 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 21351 }
00e98fc7 21352 else
15b42fb0
AM
21353 {
21354 Elf64_External_VMS_Note *vms_external;
00e98fc7 21355
9dd3a467
NC
21356 /* PR binutils/15191
21357 Make sure that there is enough data to read. */
15b42fb0
AM
21358 min_notesz = offsetof (Elf64_External_VMS_Note, name);
21359 if (data_remaining < min_notesz)
9dd3a467 21360 {
d3a49aa8
AM
21361 warn (ngettext ("Corrupt note: only %ld byte remains, "
21362 "not enough for a full note\n",
21363 "Corrupt note: only %ld bytes remain, "
21364 "not enough for a full note\n",
21365 data_remaining),
21366 (long) data_remaining);
9dd3a467
NC
21367 break;
21368 }
5396a86e 21369 data_remaining -= min_notesz;
3e55a963 21370
15b42fb0
AM
21371 vms_external = (Elf64_External_VMS_Note *) external;
21372 inote.type = BYTE_GET (vms_external->type);
21373 inote.namesz = BYTE_GET (vms_external->namesz);
21374 inote.namedata = vms_external->name;
21375 inote.descsz = BYTE_GET (vms_external->descsz);
21376 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
21377 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21378 next = inote.descdata + align_power (inote.descsz, 3);
21379 }
21380
5396a86e
AM
21381 /* PR 17531: file: 3443835e. */
21382 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
21383 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
21384 || (size_t) (inote.descdata - inote.namedata) > data_remaining
21385 || (size_t) (next - inote.descdata) < inote.descsz
21386 || ((size_t) (next - inote.descdata)
21387 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 21388 {
15b42fb0 21389 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 21390 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
21391 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
21392 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
21393 break;
21394 }
21395
15b42fb0 21396 external = (Elf_External_Note *) next;
dd24e3da 21397
6d118b09
NC
21398 /* Verify that name is null terminated. It appears that at least
21399 one version of Linux (RedHat 6.0) generates corefiles that don't
21400 comply with the ELF spec by failing to include the null byte in
21401 namesz. */
18344509 21402 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 21403 {
5396a86e 21404 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 21405 {
5396a86e
AM
21406 temp = (char *) malloc (inote.namesz + 1);
21407 if (temp == NULL)
21408 {
21409 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 21410 res = false;
5396a86e
AM
21411 break;
21412 }
76da6bbe 21413
5396a86e
AM
21414 memcpy (temp, inote.namedata, inote.namesz);
21415 inote.namedata = temp;
21416 }
21417 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21418 }
21419
dda8d76d 21420 if (! process_note (& inote, filedata))
015dc7e1 21421 res = false;
103f02d3 21422
9db70fc3
AM
21423 free (temp);
21424 temp = NULL;
779fe533
NC
21425 }
21426
21427 free (pnotes);
103f02d3 21428
779fe533
NC
21429 return res;
21430}
21431
015dc7e1 21432static bool
dda8d76d 21433process_corefile_note_segments (Filedata * filedata)
779fe533 21434{
015dc7e1 21435 Elf_Internal_Phdr *segment;
b34976b6 21436 unsigned int i;
015dc7e1 21437 bool res = true;
103f02d3 21438
dda8d76d 21439 if (! get_program_headers (filedata))
015dc7e1 21440 return true;
103f02d3 21441
dda8d76d
NC
21442 for (i = 0, segment = filedata->program_headers;
21443 i < filedata->file_header.e_phnum;
b34976b6 21444 i++, segment++)
779fe533
NC
21445 {
21446 if (segment->p_type == PT_NOTE)
dda8d76d 21447 if (! process_notes_at (filedata, NULL,
32ec8896 21448 (bfd_vma) segment->p_offset,
82ed9683
L
21449 (bfd_vma) segment->p_filesz,
21450 (bfd_vma) segment->p_align))
015dc7e1 21451 res = false;
779fe533 21452 }
103f02d3 21453
779fe533
NC
21454 return res;
21455}
21456
015dc7e1 21457static bool
dda8d76d 21458process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21459{
21460 Elf_External_Note * pnotes;
21461 Elf_External_Note * external;
c8071705 21462 char * end;
015dc7e1 21463 bool res = true;
685080f2
NC
21464
21465 if (length <= 0)
015dc7e1 21466 return false;
685080f2 21467
dda8d76d 21468 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21469 _("v850 notes"));
21470 if (pnotes == NULL)
015dc7e1 21471 return false;
685080f2
NC
21472
21473 external = pnotes;
c8071705 21474 end = (char*) pnotes + length;
685080f2
NC
21475
21476 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21477 (unsigned long) offset, (unsigned long) length);
21478
c8071705 21479 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21480 {
21481 Elf_External_Note * next;
21482 Elf_Internal_Note inote;
21483
21484 inote.type = BYTE_GET (external->type);
21485 inote.namesz = BYTE_GET (external->namesz);
21486 inote.namedata = external->name;
21487 inote.descsz = BYTE_GET (external->descsz);
21488 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21489 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21490
c8071705
NC
21491 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21492 {
21493 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21494 inote.descdata = inote.namedata;
21495 inote.namesz = 0;
21496 }
21497
685080f2
NC
21498 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21499
c8071705 21500 if ( ((char *) next > end)
685080f2
NC
21501 || ((char *) next < (char *) pnotes))
21502 {
21503 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21504 (unsigned long) ((char *) external - (char *) pnotes));
21505 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21506 inote.type, inote.namesz, inote.descsz);
21507 break;
21508 }
21509
21510 external = next;
21511
21512 /* Prevent out-of-bounds indexing. */
c8071705 21513 if ( inote.namedata + inote.namesz > end
685080f2
NC
21514 || inote.namedata + inote.namesz < inote.namedata)
21515 {
21516 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21517 (unsigned long) ((char *) external - (char *) pnotes));
21518 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21519 inote.type, inote.namesz, inote.descsz);
21520 break;
21521 }
21522
21523 printf (" %s: ", get_v850_elf_note_type (inote.type));
21524
21525 if (! print_v850_note (& inote))
21526 {
015dc7e1 21527 res = false;
685080f2
NC
21528 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21529 inote.namesz, inote.descsz);
21530 }
21531 }
21532
21533 free (pnotes);
21534
21535 return res;
21536}
21537
015dc7e1 21538static bool
dda8d76d 21539process_note_sections (Filedata * filedata)
1ec5cd37 21540{
015dc7e1 21541 Elf_Internal_Shdr *section;
1ec5cd37 21542 unsigned long i;
32ec8896 21543 unsigned int n = 0;
015dc7e1 21544 bool res = true;
1ec5cd37 21545
dda8d76d
NC
21546 for (i = 0, section = filedata->section_headers;
21547 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21548 i++, section++)
685080f2
NC
21549 {
21550 if (section->sh_type == SHT_NOTE)
21551 {
dda8d76d 21552 if (! process_notes_at (filedata, section,
32ec8896 21553 (bfd_vma) section->sh_offset,
82ed9683
L
21554 (bfd_vma) section->sh_size,
21555 (bfd_vma) section->sh_addralign))
015dc7e1 21556 res = false;
685080f2
NC
21557 n++;
21558 }
21559
dda8d76d
NC
21560 if (( filedata->file_header.e_machine == EM_V800
21561 || filedata->file_header.e_machine == EM_V850
21562 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21563 && section->sh_type == SHT_RENESAS_INFO)
21564 {
dda8d76d 21565 if (! process_v850_notes (filedata,
32ec8896
NC
21566 (bfd_vma) section->sh_offset,
21567 (bfd_vma) section->sh_size))
015dc7e1 21568 res = false;
685080f2
NC
21569 n++;
21570 }
21571 }
df565f32
NC
21572
21573 if (n == 0)
21574 /* Try processing NOTE segments instead. */
dda8d76d 21575 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21576
21577 return res;
21578}
21579
015dc7e1 21580static bool
dda8d76d 21581process_notes (Filedata * filedata)
779fe533
NC
21582{
21583 /* If we have not been asked to display the notes then do nothing. */
21584 if (! do_notes)
015dc7e1 21585 return true;
103f02d3 21586
dda8d76d
NC
21587 if (filedata->file_header.e_type != ET_CORE)
21588 return process_note_sections (filedata);
103f02d3 21589
779fe533 21590 /* No program headers means no NOTE segment. */
dda8d76d
NC
21591 if (filedata->file_header.e_phnum > 0)
21592 return process_corefile_note_segments (filedata);
779fe533 21593
ca0e11aa
NC
21594 if (filedata->is_separate)
21595 printf (_("No notes found in linked file '%s'.\n"),
21596 filedata->file_name);
21597 else
21598 printf (_("No notes found file.\n"));
21599
015dc7e1 21600 return true;
779fe533
NC
21601}
21602
60abdbed
NC
21603static unsigned char *
21604display_public_gnu_attributes (unsigned char * start,
21605 const unsigned char * const end)
21606{
21607 printf (_(" Unknown GNU attribute: %s\n"), start);
21608
21609 start += strnlen ((char *) start, end - start);
21610 display_raw_attribute (start, end);
21611
21612 return (unsigned char *) end;
21613}
21614
21615static unsigned char *
21616display_generic_attribute (unsigned char * start,
21617 unsigned int tag,
21618 const unsigned char * const end)
21619{
21620 if (tag == 0)
21621 return (unsigned char *) end;
21622
21623 return display_tag_value (tag, start, end);
21624}
21625
015dc7e1 21626static bool
dda8d76d 21627process_arch_specific (Filedata * filedata)
252b5132 21628{
a952a375 21629 if (! do_arch)
015dc7e1 21630 return true;
a952a375 21631
dda8d76d 21632 switch (filedata->file_header.e_machine)
252b5132 21633 {
53a346d8
CZ
21634 case EM_ARC:
21635 case EM_ARC_COMPACT:
21636 case EM_ARC_COMPACT2:
dda8d76d 21637 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21638 display_arc_attribute,
21639 display_generic_attribute);
11c1ff18 21640 case EM_ARM:
dda8d76d 21641 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21642 display_arm_attribute,
21643 display_generic_attribute);
21644
252b5132 21645 case EM_MIPS:
4fe85591 21646 case EM_MIPS_RS3_LE:
dda8d76d 21647 return process_mips_specific (filedata);
60abdbed
NC
21648
21649 case EM_MSP430:
dda8d76d 21650 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21651 display_msp430_attribute,
c0ea7c52 21652 display_msp430_gnu_attribute);
60abdbed 21653
2dc8dd17
JW
21654 case EM_RISCV:
21655 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21656 display_riscv_attribute,
21657 display_generic_attribute);
21658
35c08157 21659 case EM_NDS32:
dda8d76d 21660 return process_nds32_specific (filedata);
60abdbed 21661
85f7484a
PB
21662 case EM_68K:
21663 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21664 display_m68k_gnu_attribute);
21665
34c8bcba 21666 case EM_PPC:
b82317dd 21667 case EM_PPC64:
dda8d76d 21668 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21669 display_power_gnu_attribute);
21670
643f7afb
AK
21671 case EM_S390:
21672 case EM_S390_OLD:
dda8d76d 21673 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21674 display_s390_gnu_attribute);
21675
9e8c70f9
DM
21676 case EM_SPARC:
21677 case EM_SPARC32PLUS:
21678 case EM_SPARCV9:
dda8d76d 21679 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21680 display_sparc_gnu_attribute);
21681
59e6276b 21682 case EM_TI_C6000:
dda8d76d 21683 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21684 display_tic6x_attribute,
21685 display_generic_attribute);
21686
0861f561
CQ
21687 case EM_CSKY:
21688 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21689 display_csky_attribute, NULL);
21690
252b5132 21691 default:
dda8d76d 21692 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21693 display_public_gnu_attributes,
21694 display_generic_attribute);
252b5132 21695 }
252b5132
RH
21696}
21697
015dc7e1 21698static bool
dda8d76d 21699get_file_header (Filedata * filedata)
252b5132 21700{
9ea033b2 21701 /* Read in the identity array. */
dda8d76d 21702 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21703 return false;
252b5132 21704
9ea033b2 21705 /* Determine how to read the rest of the header. */
dda8d76d 21706 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21707 {
1a0670f3
AM
21708 default:
21709 case ELFDATANONE:
adab8cdc
AO
21710 case ELFDATA2LSB:
21711 byte_get = byte_get_little_endian;
21712 byte_put = byte_put_little_endian;
21713 break;
21714 case ELFDATA2MSB:
21715 byte_get = byte_get_big_endian;
21716 byte_put = byte_put_big_endian;
21717 break;
9ea033b2
NC
21718 }
21719
21720 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21721 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21722
21723 /* Read in the rest of the header. */
21724 if (is_32bit_elf)
21725 {
21726 Elf32_External_Ehdr ehdr32;
252b5132 21727
dda8d76d 21728 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21729 return false;
103f02d3 21730
dda8d76d
NC
21731 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21732 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21733 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21734 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21735 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21736 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21737 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21738 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21739 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21740 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21741 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21742 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21743 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21744 }
252b5132 21745 else
9ea033b2
NC
21746 {
21747 Elf64_External_Ehdr ehdr64;
a952a375
NC
21748
21749 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21750 we will not be able to cope with the 64bit data found in
21751 64 ELF files. Detect this now and abort before we start
50c2245b 21752 overwriting things. */
a952a375
NC
21753 if (sizeof (bfd_vma) < 8)
21754 {
e3c8793a
NC
21755 error (_("This instance of readelf has been built without support for a\n\
2175664 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21757 return false;
a952a375 21758 }
103f02d3 21759
dda8d76d 21760 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21761 return false;
103f02d3 21762
dda8d76d
NC
21763 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21764 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21765 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21766 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21767 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21768 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21769 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21770 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21771 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21772 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21773 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21774 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21775 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21776 }
252b5132 21777
015dc7e1 21778 return true;
252b5132
RH
21779}
21780
13acb58d
AM
21781static void
21782free_filedata (Filedata *filedata)
21783{
21784 free (filedata->program_interpreter);
13acb58d 21785 free (filedata->program_headers);
13acb58d 21786 free (filedata->section_headers);
13acb58d 21787 free (filedata->string_table);
13acb58d 21788 free (filedata->dump.dump_sects);
13acb58d 21789 free (filedata->dynamic_strings);
13acb58d 21790 free (filedata->dynamic_symbols);
13acb58d 21791 free (filedata->dynamic_syminfo);
13acb58d 21792 free (filedata->dynamic_section);
13acb58d
AM
21793
21794 while (filedata->symtab_shndx_list != NULL)
21795 {
21796 elf_section_list *next = filedata->symtab_shndx_list->next;
21797 free (filedata->symtab_shndx_list);
21798 filedata->symtab_shndx_list = next;
21799 }
21800
21801 free (filedata->section_headers_groups);
13acb58d
AM
21802
21803 if (filedata->section_groups)
21804 {
21805 size_t i;
21806 struct group_list * g;
21807 struct group_list * next;
21808
21809 for (i = 0; i < filedata->group_count; i++)
21810 {
21811 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21812 {
21813 next = g->next;
21814 free (g);
21815 }
21816 }
21817
21818 free (filedata->section_groups);
13acb58d 21819 }
066f8fbe
AM
21820 memset (&filedata->section_headers, 0,
21821 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21822}
21823
dda8d76d
NC
21824static void
21825close_file (Filedata * filedata)
21826{
21827 if (filedata)
21828 {
21829 if (filedata->handle)
21830 fclose (filedata->handle);
21831 free (filedata);
21832 }
21833}
21834
21835void
21836close_debug_file (void * data)
21837{
13acb58d 21838 free_filedata ((Filedata *) data);
dda8d76d
NC
21839 close_file ((Filedata *) data);
21840}
21841
21842static Filedata *
015dc7e1 21843open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21844{
21845 struct stat statbuf;
21846 Filedata * filedata = NULL;
21847
21848 if (stat (pathname, & statbuf) < 0
21849 || ! S_ISREG (statbuf.st_mode))
21850 goto fail;
21851
21852 filedata = calloc (1, sizeof * filedata);
21853 if (filedata == NULL)
21854 goto fail;
21855
21856 filedata->handle = fopen (pathname, "rb");
21857 if (filedata->handle == NULL)
21858 goto fail;
21859
21860 filedata->file_size = (bfd_size_type) statbuf.st_size;
21861 filedata->file_name = pathname;
ca0e11aa 21862 filedata->is_separate = is_separate;
dda8d76d
NC
21863
21864 if (! get_file_header (filedata))
21865 goto fail;
21866
4de91c10
AM
21867 if (!get_section_headers (filedata, false))
21868 goto fail;
dda8d76d
NC
21869
21870 return filedata;
21871
21872 fail:
21873 if (filedata)
21874 {
21875 if (filedata->handle)
21876 fclose (filedata->handle);
21877 free (filedata);
21878 }
21879 return NULL;
21880}
21881
21882void *
21883open_debug_file (const char * pathname)
21884{
015dc7e1 21885 return open_file (pathname, true);
dda8d76d
NC
21886}
21887
835f2fae
NC
21888static void
21889initialise_dump_sects (Filedata * filedata)
21890{
21891 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21892 Note we do this even if cmdline_dump_sects is empty because we
21893 must make sure that the dump_sets array is zeroed out before each
21894 object file is processed. */
21895 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21896 memset (filedata->dump.dump_sects, 0,
21897 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21898
21899 if (cmdline.num_dump_sects > 0)
21900 {
21901 if (filedata->dump.num_dump_sects == 0)
21902 /* A sneaky way of allocating the dump_sects array. */
21903 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21904
21905 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21906 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21907 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21908 }
21909}
21910
fb52b2f4
NC
21911/* Process one ELF object file according to the command line options.
21912 This file may actually be stored in an archive. The file is
32ec8896
NC
21913 positioned at the start of the ELF object. Returns TRUE if no
21914 problems were encountered, FALSE otherwise. */
fb52b2f4 21915
015dc7e1 21916static bool
dda8d76d 21917process_object (Filedata * filedata)
252b5132 21918{
015dc7e1 21919 bool have_separate_files;
252b5132 21920 unsigned int i;
015dc7e1 21921 bool res;
252b5132 21922
dda8d76d 21923 if (! get_file_header (filedata))
252b5132 21924 {
dda8d76d 21925 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21926 return false;
252b5132
RH
21927 }
21928
21929 /* Initialise per file variables. */
978c4450
AM
21930 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21931 filedata->version_info[i] = 0;
252b5132 21932
978c4450
AM
21933 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21934 filedata->dynamic_info[i] = 0;
21935 filedata->dynamic_info_DT_GNU_HASH = 0;
21936 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21937
21938 /* Process the file. */
21939 if (show_name)
dda8d76d 21940 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21941
835f2fae 21942 initialise_dump_sects (filedata);
d70c5fc7 21943
4de91c10
AM
21944 /* There may be some extensions in the first section header. Don't
21945 bomb if we can't read it. */
21946 get_section_headers (filedata, true);
21947
dda8d76d 21948 if (! process_file_header (filedata))
4de91c10
AM
21949 {
21950 res = false;
21951 goto out;
21952 }
252b5132 21953
e331b18d
AM
21954 /* Throw away the single section header read above, so that we
21955 re-read the entire set. */
21956 free (filedata->section_headers);
21957 filedata->section_headers = NULL;
21958
dda8d76d 21959 if (! process_section_headers (filedata))
2f62977e 21960 {
32ec8896 21961 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21962 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21963
2f62977e 21964 if (! do_using_dynamic)
015dc7e1 21965 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21966 }
252b5132 21967
dda8d76d 21968 if (! process_section_groups (filedata))
32ec8896 21969 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21970 do_unwind = false;
d1f5c6e3 21971
93df3340
AM
21972 process_program_headers (filedata);
21973
21974 res = process_dynamic_section (filedata);
252b5132 21975
dda8d76d 21976 if (! process_relocs (filedata))
015dc7e1 21977 res = false;
252b5132 21978
dda8d76d 21979 if (! process_unwind (filedata))
015dc7e1 21980 res = false;
4d6ed7c8 21981
dda8d76d 21982 if (! process_symbol_table (filedata))
015dc7e1 21983 res = false;
252b5132 21984
0f03783c 21985 if (! process_lto_symbol_tables (filedata))
015dc7e1 21986 res = false;
b9e920ec 21987
dda8d76d 21988 if (! process_syminfo (filedata))
015dc7e1 21989 res = false;
252b5132 21990
dda8d76d 21991 if (! process_version_sections (filedata))
015dc7e1 21992 res = false;
252b5132 21993
82ed9683 21994 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21995 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21996 else
015dc7e1 21997 have_separate_files = false;
dda8d76d
NC
21998
21999 if (! process_section_contents (filedata))
015dc7e1 22000 res = false;
f5842774 22001
24841daa 22002 if (have_separate_files)
dda8d76d 22003 {
24841daa
NC
22004 separate_info * d;
22005
22006 for (d = first_separate_info; d != NULL; d = d->next)
22007 {
835f2fae
NC
22008 initialise_dump_sects (d->handle);
22009
ca0e11aa 22010 if (process_links && ! process_file_header (d->handle))
015dc7e1 22011 res = false;
ca0e11aa 22012 else if (! process_section_headers (d->handle))
015dc7e1 22013 res = false;
d6bfbc39 22014 else if (! process_section_contents (d->handle))
015dc7e1 22015 res = false;
ca0e11aa
NC
22016 else if (process_links)
22017 {
ca0e11aa 22018 if (! process_section_groups (d->handle))
015dc7e1 22019 res = false;
93df3340 22020 process_program_headers (d->handle);
ca0e11aa 22021 if (! process_dynamic_section (d->handle))
015dc7e1 22022 res = false;
ca0e11aa 22023 if (! process_relocs (d->handle))
015dc7e1 22024 res = false;
ca0e11aa 22025 if (! process_unwind (d->handle))
015dc7e1 22026 res = false;
ca0e11aa 22027 if (! process_symbol_table (d->handle))
015dc7e1 22028 res = false;
ca0e11aa 22029 if (! process_lto_symbol_tables (d->handle))
015dc7e1 22030 res = false;
ca0e11aa 22031 if (! process_syminfo (d->handle))
015dc7e1 22032 res = false;
ca0e11aa 22033 if (! process_version_sections (d->handle))
015dc7e1 22034 res = false;
ca0e11aa 22035 if (! process_notes (d->handle))
015dc7e1 22036 res = false;
ca0e11aa 22037 }
24841daa
NC
22038 }
22039
22040 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
22041 }
22042
22043 if (! process_notes (filedata))
015dc7e1 22044 res = false;
103f02d3 22045
dda8d76d 22046 if (! process_gnu_liblist (filedata))
015dc7e1 22047 res = false;
047b2264 22048
dda8d76d 22049 if (! process_arch_specific (filedata))
015dc7e1 22050 res = false;
252b5132 22051
4de91c10 22052 out:
13acb58d 22053 free_filedata (filedata);
e4b17d5c 22054
19e6b90e 22055 free_debug_memory ();
18bd398b 22056
32ec8896 22057 return res;
252b5132
RH
22058}
22059
2cf0635d 22060/* Process an ELF archive.
32ec8896
NC
22061 On entry the file is positioned just after the ARMAG string.
22062 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 22063
015dc7e1
AM
22064static bool
22065process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
22066{
22067 struct archive_info arch;
22068 struct archive_info nested_arch;
22069 size_t got;
015dc7e1 22070 bool ret = true;
2cf0635d 22071
015dc7e1 22072 show_name = true;
2cf0635d
NC
22073
22074 /* The ARCH structure is used to hold information about this archive. */
22075 arch.file_name = NULL;
22076 arch.file = NULL;
22077 arch.index_array = NULL;
22078 arch.sym_table = NULL;
22079 arch.longnames = NULL;
22080
22081 /* The NESTED_ARCH structure is used as a single-item cache of information
22082 about a nested archive (when members of a thin archive reside within
22083 another regular archive file). */
22084 nested_arch.file_name = NULL;
22085 nested_arch.file = NULL;
22086 nested_arch.index_array = NULL;
22087 nested_arch.sym_table = NULL;
22088 nested_arch.longnames = NULL;
22089
dda8d76d 22090 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
22091 filedata->file_size, is_thin_archive,
22092 do_archive_index) != 0)
2cf0635d 22093 {
015dc7e1 22094 ret = false;
2cf0635d 22095 goto out;
4145f1d5 22096 }
fb52b2f4 22097
4145f1d5
NC
22098 if (do_archive_index)
22099 {
2cf0635d 22100 if (arch.sym_table == NULL)
1cb7d8b1
AM
22101 error (_("%s: unable to dump the index as none was found\n"),
22102 filedata->file_name);
4145f1d5
NC
22103 else
22104 {
591f7597 22105 unsigned long i, l;
4145f1d5
NC
22106 unsigned long current_pos;
22107
1cb7d8b1
AM
22108 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
22109 "in the symbol table)\n"),
22110 filedata->file_name, (unsigned long) arch.index_num,
22111 arch.sym_size);
dda8d76d
NC
22112
22113 current_pos = ftell (filedata->handle);
4145f1d5 22114
2cf0635d 22115 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 22116 {
1cb7d8b1
AM
22117 if (i == 0
22118 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
22119 {
22120 char * member_name
22121 = get_archive_member_name_at (&arch, arch.index_array[i],
22122 &nested_arch);
2cf0635d 22123
1cb7d8b1
AM
22124 if (member_name != NULL)
22125 {
22126 char * qualified_name
22127 = make_qualified_name (&arch, &nested_arch,
22128 member_name);
2cf0635d 22129
1cb7d8b1
AM
22130 if (qualified_name != NULL)
22131 {
22132 printf (_("Contents of binary %s at offset "),
22133 qualified_name);
c2a7d3f5
NC
22134 (void) print_vma (arch.index_array[i], PREFIX_HEX);
22135 putchar ('\n');
1cb7d8b1
AM
22136 free (qualified_name);
22137 }
fd486f32 22138 free (member_name);
4145f1d5
NC
22139 }
22140 }
2cf0635d
NC
22141
22142 if (l >= arch.sym_size)
4145f1d5 22143 {
1cb7d8b1
AM
22144 error (_("%s: end of the symbol table reached "
22145 "before the end of the index\n"),
dda8d76d 22146 filedata->file_name);
015dc7e1 22147 ret = false;
cb8f3167 22148 break;
4145f1d5 22149 }
591f7597 22150 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
22151 printf ("\t%.*s\n",
22152 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 22153 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
22154 }
22155
67ce483b 22156 if (arch.uses_64bit_indices)
c2a7d3f5
NC
22157 l = (l + 7) & ~ 7;
22158 else
22159 l += l & 1;
22160
2cf0635d 22161 if (l < arch.sym_size)
32ec8896 22162 {
d3a49aa8
AM
22163 error (ngettext ("%s: %ld byte remains in the symbol table, "
22164 "but without corresponding entries in "
22165 "the index table\n",
22166 "%s: %ld bytes remain in the symbol table, "
22167 "but without corresponding entries in "
22168 "the index table\n",
22169 arch.sym_size - l),
dda8d76d 22170 filedata->file_name, arch.sym_size - l);
015dc7e1 22171 ret = false;
32ec8896 22172 }
4145f1d5 22173
dda8d76d 22174 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 22175 {
1cb7d8b1
AM
22176 error (_("%s: failed to seek back to start of object files "
22177 "in the archive\n"),
dda8d76d 22178 filedata->file_name);
015dc7e1 22179 ret = false;
2cf0635d 22180 goto out;
4145f1d5 22181 }
fb52b2f4 22182 }
4145f1d5
NC
22183
22184 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
22185 && !do_segments && !do_header && !do_dump && !do_version
22186 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 22187 && !do_section_groups && !do_dyn_syms)
2cf0635d 22188 {
015dc7e1 22189 ret = true; /* Archive index only. */
2cf0635d
NC
22190 goto out;
22191 }
fb52b2f4
NC
22192 }
22193
fb52b2f4
NC
22194 while (1)
22195 {
2cf0635d
NC
22196 char * name;
22197 size_t namelen;
22198 char * qualified_name;
22199
22200 /* Read the next archive header. */
dda8d76d 22201 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
22202 {
22203 error (_("%s: failed to seek to next archive header\n"),
22204 arch.file_name);
015dc7e1 22205 ret = false;
1cb7d8b1
AM
22206 break;
22207 }
dda8d76d 22208 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 22209 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
22210 {
22211 if (got == 0)
2cf0635d 22212 break;
28e817cc
NC
22213 /* PR 24049 - we cannot use filedata->file_name as this will
22214 have already been freed. */
22215 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 22216
015dc7e1 22217 ret = false;
1cb7d8b1
AM
22218 break;
22219 }
2cf0635d 22220 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
22221 {
22222 error (_("%s: did not find a valid archive header\n"),
22223 arch.file_name);
015dc7e1 22224 ret = false;
1cb7d8b1
AM
22225 break;
22226 }
2cf0635d
NC
22227
22228 arch.next_arhdr_offset += sizeof arch.arhdr;
22229
978c4450 22230 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
22231
22232 name = get_archive_member_name (&arch, &nested_arch);
22233 if (name == NULL)
fb52b2f4 22234 {
28e817cc 22235 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 22236 ret = false;
d989285c 22237 break;
fb52b2f4 22238 }
2cf0635d 22239 namelen = strlen (name);
fb52b2f4 22240
2cf0635d
NC
22241 qualified_name = make_qualified_name (&arch, &nested_arch, name);
22242 if (qualified_name == NULL)
fb52b2f4 22243 {
28e817cc 22244 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 22245 free (name);
015dc7e1 22246 ret = false;
d989285c 22247 break;
fb52b2f4
NC
22248 }
22249
2cf0635d 22250 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
22251 {
22252 /* This is a proxy for an external member of a thin archive. */
22253 Filedata * member_filedata;
22254 char * member_file_name = adjust_relative_path
dda8d76d 22255 (filedata->file_name, name, namelen);
32ec8896 22256
fd486f32 22257 free (name);
1cb7d8b1
AM
22258 if (member_file_name == NULL)
22259 {
fd486f32 22260 free (qualified_name);
015dc7e1 22261 ret = false;
1cb7d8b1
AM
22262 break;
22263 }
2cf0635d 22264
015dc7e1 22265 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
22266 if (member_filedata == NULL)
22267 {
22268 error (_("Input file '%s' is not readable.\n"), member_file_name);
22269 free (member_file_name);
fd486f32 22270 free (qualified_name);
015dc7e1 22271 ret = false;
1cb7d8b1
AM
22272 break;
22273 }
2cf0635d 22274
978c4450 22275 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 22276 member_filedata->file_name = qualified_name;
2cf0635d 22277
75a2da57
AH
22278 /* The call to process_object() expects the file to be at the beginning. */
22279 rewind (member_filedata->handle);
22280
1cb7d8b1 22281 if (! process_object (member_filedata))
015dc7e1 22282 ret = false;
2cf0635d 22283
1cb7d8b1
AM
22284 close_file (member_filedata);
22285 free (member_file_name);
1cb7d8b1 22286 }
2cf0635d 22287 else if (is_thin_archive)
1cb7d8b1
AM
22288 {
22289 Filedata thin_filedata;
eb02c04d 22290
1cb7d8b1 22291 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 22292
a043396b
NC
22293 /* PR 15140: Allow for corrupt thin archives. */
22294 if (nested_arch.file == NULL)
22295 {
22296 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 22297 qualified_name, name);
fd486f32
AM
22298 free (qualified_name);
22299 free (name);
015dc7e1 22300 ret = false;
a043396b
NC
22301 break;
22302 }
fd486f32 22303 free (name);
a043396b 22304
1cb7d8b1 22305 /* This is a proxy for a member of a nested archive. */
978c4450
AM
22306 filedata->archive_file_offset
22307 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 22308
1cb7d8b1
AM
22309 /* The nested archive file will have been opened and setup by
22310 get_archive_member_name. */
978c4450
AM
22311 if (fseek (nested_arch.file, filedata->archive_file_offset,
22312 SEEK_SET) != 0)
1cb7d8b1
AM
22313 {
22314 error (_("%s: failed to seek to archive member.\n"),
22315 nested_arch.file_name);
fd486f32 22316 free (qualified_name);
015dc7e1 22317 ret = false;
1cb7d8b1
AM
22318 break;
22319 }
2cf0635d 22320
dda8d76d
NC
22321 thin_filedata.handle = nested_arch.file;
22322 thin_filedata.file_name = qualified_name;
9abca702 22323
1cb7d8b1 22324 if (! process_object (& thin_filedata))
015dc7e1 22325 ret = false;
1cb7d8b1 22326 }
2cf0635d 22327 else
1cb7d8b1 22328 {
fd486f32 22329 free (name);
978c4450 22330 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 22331 filedata->file_name = qualified_name;
1cb7d8b1 22332 if (! process_object (filedata))
015dc7e1 22333 ret = false;
237877b8 22334 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 22335 /* Stop looping with "negative" archive_file_size. */
978c4450 22336 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 22337 arch.next_arhdr_offset = -1ul;
1cb7d8b1 22338 }
fb52b2f4 22339
2cf0635d 22340 free (qualified_name);
fb52b2f4
NC
22341 }
22342
4145f1d5 22343 out:
2cf0635d
NC
22344 if (nested_arch.file != NULL)
22345 fclose (nested_arch.file);
22346 release_archive (&nested_arch);
22347 release_archive (&arch);
fb52b2f4 22348
d989285c 22349 return ret;
fb52b2f4
NC
22350}
22351
015dc7e1 22352static bool
2cf0635d 22353process_file (char * file_name)
fb52b2f4 22354{
dda8d76d 22355 Filedata * filedata = NULL;
fb52b2f4
NC
22356 struct stat statbuf;
22357 char armag[SARMAG];
015dc7e1 22358 bool ret = true;
fb52b2f4
NC
22359
22360 if (stat (file_name, &statbuf) < 0)
22361 {
f24ddbdd
NC
22362 if (errno == ENOENT)
22363 error (_("'%s': No such file\n"), file_name);
22364 else
22365 error (_("Could not locate '%s'. System error message: %s\n"),
22366 file_name, strerror (errno));
015dc7e1 22367 return false;
f24ddbdd
NC
22368 }
22369
22370 if (! S_ISREG (statbuf.st_mode))
22371 {
22372 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 22373 return false;
fb52b2f4
NC
22374 }
22375
dda8d76d
NC
22376 filedata = calloc (1, sizeof * filedata);
22377 if (filedata == NULL)
22378 {
22379 error (_("Out of memory allocating file data structure\n"));
015dc7e1 22380 return false;
dda8d76d
NC
22381 }
22382
22383 filedata->file_name = file_name;
22384 filedata->handle = fopen (file_name, "rb");
22385 if (filedata->handle == NULL)
fb52b2f4 22386 {
f24ddbdd 22387 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 22388 free (filedata);
015dc7e1 22389 return false;
fb52b2f4
NC
22390 }
22391
dda8d76d 22392 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 22393 {
4145f1d5 22394 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
22395 fclose (filedata->handle);
22396 free (filedata);
015dc7e1 22397 return false;
fb52b2f4
NC
22398 }
22399
dda8d76d 22400 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 22401 filedata->is_separate = false;
f54498b4 22402
fb52b2f4 22403 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 22404 {
015dc7e1
AM
22405 if (! process_archive (filedata, false))
22406 ret = false;
32ec8896 22407 }
2cf0635d 22408 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 22409 {
015dc7e1
AM
22410 if ( ! process_archive (filedata, true))
22411 ret = false;
32ec8896 22412 }
fb52b2f4
NC
22413 else
22414 {
1b513401 22415 if (do_archive_index && !check_all)
4145f1d5
NC
22416 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22417 file_name);
22418
dda8d76d 22419 rewind (filedata->handle);
978c4450 22420 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22421
dda8d76d 22422 if (! process_object (filedata))
015dc7e1 22423 ret = false;
fb52b2f4
NC
22424 }
22425
dda8d76d 22426 fclose (filedata->handle);
8fb879cd
AM
22427 free (filedata->section_headers);
22428 free (filedata->program_headers);
22429 free (filedata->string_table);
6431e409 22430 free (filedata->dump.dump_sects);
dda8d76d 22431 free (filedata);
32ec8896 22432
fd486f32 22433 free (ba_cache.strtab);
1bd6175a 22434 ba_cache.strtab = NULL;
fd486f32 22435 free (ba_cache.symtab);
1bd6175a 22436 ba_cache.symtab = NULL;
fd486f32
AM
22437 ba_cache.filedata = NULL;
22438
fb52b2f4
NC
22439 return ret;
22440}
22441
252b5132
RH
22442#ifdef SUPPORT_DISASSEMBLY
22443/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22444 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22445 symbols. */
252b5132
RH
22446
22447void
2cf0635d 22448print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22449{
22450 fprintf (outfile,"0x%8.8x", addr);
22451}
22452
e3c8793a 22453/* Needed by the i386 disassembler. */
dda8d76d 22454
252b5132
RH
22455void
22456db_task_printsym (unsigned int addr)
22457{
22458 print_address (addr, stderr);
22459}
22460#endif
22461
22462int
2cf0635d 22463main (int argc, char ** argv)
252b5132 22464{
ff78d6d6
L
22465 int err;
22466
87b9f255 22467#ifdef HAVE_LC_MESSAGES
252b5132 22468 setlocale (LC_MESSAGES, "");
3882b010 22469#endif
3882b010 22470 setlocale (LC_CTYPE, "");
252b5132
RH
22471 bindtextdomain (PACKAGE, LOCALEDIR);
22472 textdomain (PACKAGE);
22473
869b9d07
MM
22474 expandargv (&argc, &argv);
22475
dda8d76d 22476 parse_args (& cmdline, argc, argv);
59f14fc0 22477
18bd398b 22478 if (optind < (argc - 1))
1b513401
NC
22479 /* When displaying information for more than one file,
22480 prefix the information with the file name. */
015dc7e1 22481 show_name = true;
5656ba2c
L
22482 else if (optind >= argc)
22483 {
1b513401 22484 /* Ensure that the warning is always displayed. */
015dc7e1 22485 do_checks = true;
1b513401 22486
5656ba2c
L
22487 warn (_("Nothing to do.\n"));
22488 usage (stderr);
22489 }
18bd398b 22490
015dc7e1 22491 err = false;
252b5132 22492 while (optind < argc)
32ec8896 22493 if (! process_file (argv[optind++]))
015dc7e1 22494 err = true;
252b5132 22495
9db70fc3 22496 free (cmdline.dump_sects);
252b5132 22497
7d9813f1
NA
22498 free (dump_ctf_symtab_name);
22499 free (dump_ctf_strtab_name);
22500 free (dump_ctf_parent_name);
22501
32ec8896 22502 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22503}