]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Revert: [AArch64] MTE corefile support
[thirdparty/binutils-gdb.git] / binutils / readelf.c
CommitLineData
252b5132 1/* readelf.c -- display contents of an ELF format file
250d07de 2 Copyright (C) 1998-2021 Free Software Foundation, Inc.
252b5132
RH
3
4 Originally developed by Eric Youngdale <eric@andante.jic.com>
12ab83a9 5 Modifications by Nick Clifton <nickc@redhat.com>
252b5132
RH
6
7 This file is part of GNU Binutils.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
32866df7 11 the Free Software Foundation; either version 3 of the License, or
252b5132
RH
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
b43b5d5f
NC
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
22 02110-1301, USA. */
252b5132 23\f
9eb20dd8 24/* The difference between readelf and objdump:
252b5132 25
74013231 26 Both programs are capable of displaying the contents of ELF format files,
9eb20dd8 27 so why does the binutils project have two file dumpers ?
0de14b54 28
9eb20dd8
NC
29 The reason is that objdump sees an ELF file through a BFD filter of the
30 world; if BFD has a bug where, say, it disagrees about a machine constant
31 in e_flags, then the odds are good that it will remain internally
32 consistent. The linker sees it the BFD way, objdump sees it the BFD way,
33 GAS sees it the BFD way. There was need for a tool to go find out what
34 the file actually says.
35
36 This is why the readelf program does not link against the BFD library - it
37 exists as an independent program to help verify the correct working of BFD.
38
39 There is also the case that readelf can provide more information about an
40 ELF file than is provided by objdump. In particular it can display DWARF
41 debugging information which (at the moment) objdump cannot. */
42\f
3db64b00 43#include "sysdep.h"
252b5132 44#include <assert.h>
252b5132 45#include <time.h>
1b315056 46#include <zlib.h>
7bfd842d 47#include <wchar.h>
252b5132 48
a952a375 49#if __GNUC__ >= 2
19936277 50/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 51 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 52 Only do this if we believe that the compiler can support a 64 bit
a952a375 53 data type. For now we only rely on GCC being able to do this. */
19936277 54#define BFD64
a952a375
NC
55#endif
56
3db64b00
AM
57#include "bfd.h"
58#include "bucomm.h"
3284fe0c 59#include "elfcomm.h"
19e6b90e 60#include "dwarf.h"
7d9813f1 61#include "ctf-api.h"
79bc120c 62#include "demangle.h"
252b5132
RH
63
64#include "elf/common.h"
65#include "elf/external.h"
66#include "elf/internal.h"
252b5132 67
4b78141a
NC
68
69/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
70 we can obtain the H8 reloc numbers. We need these for the
71 get_reloc_size() function. We include h8.h again after defining
72 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
73
74#include "elf/h8.h"
75#undef _ELF_H8_H
76
77/* Undo the effects of #including reloc-macros.h. */
78
79#undef START_RELOC_NUMBERS
80#undef RELOC_NUMBER
81#undef FAKE_RELOC
82#undef EMPTY_RELOC
83#undef END_RELOC_NUMBERS
84#undef _RELOC_MACROS_H
85
252b5132
RH
86/* The following headers use the elf/reloc-macros.h file to
87 automatically generate relocation recognition functions
88 such as elf_mips_reloc_type() */
89
90#define RELOC_MACROS_GEN_FUNC
91
a06ea964 92#include "elf/aarch64.h"
252b5132 93#include "elf/alpha.h"
3b16e843 94#include "elf/arc.h"
252b5132 95#include "elf/arm.h"
3b16e843 96#include "elf/avr.h"
1d65ded4 97#include "elf/bfin.h"
60bca95a 98#include "elf/cr16.h"
3b16e843 99#include "elf/cris.h"
1c0d3aa6 100#include "elf/crx.h"
b8891f8d 101#include "elf/csky.h"
252b5132
RH
102#include "elf/d10v.h"
103#include "elf/d30v.h"
d172d4ba 104#include "elf/dlx.h"
aca4efc7 105#include "elf/bpf.h"
cfb8c092 106#include "elf/epiphany.h"
252b5132 107#include "elf/fr30.h"
5c70f934 108#include "elf/frv.h"
3f8107ab 109#include "elf/ft32.h"
3b16e843
NC
110#include "elf/h8.h"
111#include "elf/hppa.h"
112#include "elf/i386.h"
f954747f
AM
113#include "elf/i370.h"
114#include "elf/i860.h"
115#include "elf/i960.h"
3b16e843 116#include "elf/ia64.h"
1e4cf259 117#include "elf/ip2k.h"
84e94c90 118#include "elf/lm32.h"
1c0d3aa6 119#include "elf/iq2000.h"
49f58d10 120#include "elf/m32c.h"
3b16e843
NC
121#include "elf/m32r.h"
122#include "elf/m68k.h"
75751cd9 123#include "elf/m68hc11.h"
7b4ae824 124#include "elf/s12z.h"
252b5132 125#include "elf/mcore.h"
15ab5209 126#include "elf/mep.h"
a3c62988 127#include "elf/metag.h"
7ba29e2a 128#include "elf/microblaze.h"
3b16e843 129#include "elf/mips.h"
3c3bdf30 130#include "elf/mmix.h"
3b16e843
NC
131#include "elf/mn10200.h"
132#include "elf/mn10300.h"
5506d11a 133#include "elf/moxie.h"
4970f871 134#include "elf/mt.h"
2469cfa2 135#include "elf/msp430.h"
35c08157 136#include "elf/nds32.h"
fe944acf 137#include "elf/nfp.h"
13761a11 138#include "elf/nios2.h"
73589c9d 139#include "elf/or1k.h"
7d466069 140#include "elf/pj.h"
3b16e843 141#include "elf/ppc.h"
c833c019 142#include "elf/ppc64.h"
2b100bb5 143#include "elf/pru.h"
03336641 144#include "elf/riscv.h"
99c513f6 145#include "elf/rl78.h"
c7927a3c 146#include "elf/rx.h"
a85d7ed0 147#include "elf/s390.h"
1c0d3aa6 148#include "elf/score.h"
3b16e843
NC
149#include "elf/sh.h"
150#include "elf/sparc.h"
e9f53129 151#include "elf/spu.h"
40b36596 152#include "elf/tic6x.h"
aa137e4d
NC
153#include "elf/tilegx.h"
154#include "elf/tilepro.h"
3b16e843 155#include "elf/v850.h"
179d3252 156#include "elf/vax.h"
619ed720 157#include "elf/visium.h"
f96bd6c2 158#include "elf/wasm32.h"
3b16e843 159#include "elf/x86-64.h"
c29aca4a 160#include "elf/xc16x.h"
f6c1a2d5 161#include "elf/xgate.h"
93fbbb04 162#include "elf/xstormy16.h"
88da6820 163#include "elf/xtensa.h"
6655dba2 164#include "elf/z80.h"
252b5132 165
252b5132 166#include "getopt.h"
566b0d53 167#include "libiberty.h"
09c11c86 168#include "safe-ctype.h"
2cf0635d 169#include "filenames.h"
252b5132 170
15b42fb0
AM
171#ifndef offsetof
172#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
173#endif
174
6a40cf0c
NC
175typedef struct elf_section_list
176{
dda8d76d
NC
177 Elf_Internal_Shdr * hdr;
178 struct elf_section_list * next;
6a40cf0c
NC
179} elf_section_list;
180
dda8d76d
NC
181/* Flag bits indicating particular types of dump. */
182#define HEX_DUMP (1 << 0) /* The -x command line switch. */
183#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
184#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
185#define STRING_DUMP (1 << 3) /* The -p command line switch. */
186#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 187#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
188
189typedef unsigned char dump_type;
190
191/* A linked list of the section names for which dumps were requested. */
192struct dump_list_entry
193{
194 char * name;
195 dump_type type;
196 struct dump_list_entry * next;
197};
198
6431e409
AM
199/* A dynamic array of flags indicating for which sections a dump
200 has been requested via command line switches. */
1b513401
NC
201struct dump_data
202{
6431e409
AM
203 dump_type * dump_sects;
204 unsigned int num_dump_sects;
205};
206
207static struct dump_data cmdline;
208
209static struct dump_list_entry * dump_sects_byname;
210
2cf0635d 211char * program_name = "readelf";
dda8d76d 212
015dc7e1
AM
213static bool show_name = false;
214static bool do_dynamic = false;
215static bool do_syms = false;
216static bool do_dyn_syms = false;
217static bool do_lto_syms = false;
218static bool do_reloc = false;
219static bool do_sections = false;
220static bool do_section_groups = false;
221static bool do_section_details = false;
222static bool do_segments = false;
223static bool do_unwind = false;
224static bool do_using_dynamic = false;
225static bool do_header = false;
226static bool do_dump = false;
227static bool do_version = false;
228static bool do_histogram = false;
229static bool do_debugging = false;
230static bool do_ctf = false;
231static bool do_arch = false;
232static bool do_notes = false;
233static bool do_archive_index = false;
234static bool check_all = false;
235static bool is_32bit_elf = false;
236static bool decompress_dumps = false;
237static bool do_not_show_symbol_truncation = false;
238static bool do_demangle = false; /* Pretty print C++ symbol names. */
239static bool process_links = false;
79bc120c 240static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
047c3dbf 241static int sym_base = 0;
252b5132 242
7d9813f1
NA
243static char *dump_ctf_parent_name;
244static char *dump_ctf_symtab_name;
245static char *dump_ctf_strtab_name;
246
e4b17d5c
L
247struct group_list
248{
dda8d76d
NC
249 struct group_list * next;
250 unsigned int section_index;
e4b17d5c
L
251};
252
253struct group
254{
dda8d76d
NC
255 struct group_list * root;
256 unsigned int group_index;
e4b17d5c
L
257};
258
978c4450
AM
259typedef struct filedata
260{
261 const char * file_name;
015dc7e1 262 bool is_separate;
978c4450
AM
263 FILE * handle;
264 bfd_size_type file_size;
265 Elf_Internal_Ehdr file_header;
066f8fbe
AM
266 unsigned long archive_file_offset;
267 unsigned long archive_file_size;
268 /* Everything below this point is cleared out by free_filedata. */
978c4450
AM
269 Elf_Internal_Shdr * section_headers;
270 Elf_Internal_Phdr * program_headers;
271 char * string_table;
272 unsigned long string_table_length;
978c4450
AM
273 unsigned long dynamic_addr;
274 bfd_size_type dynamic_size;
275 size_t dynamic_nent;
276 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 277 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
278 char * dynamic_strings;
279 unsigned long dynamic_strings_length;
8ac10c5b 280 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
281 unsigned long num_dynamic_syms;
282 Elf_Internal_Sym * dynamic_symbols;
283 bfd_vma version_info[16];
284 unsigned int dynamic_syminfo_nent;
285 Elf_Internal_Syminfo * dynamic_syminfo;
286 unsigned long dynamic_syminfo_offset;
287 bfd_size_type nbuckets;
288 bfd_size_type nchains;
289 bfd_vma * buckets;
290 bfd_vma * chains;
291 bfd_size_type ngnubuckets;
292 bfd_size_type ngnuchains;
293 bfd_vma * gnubuckets;
294 bfd_vma * gnuchains;
295 bfd_vma * mipsxlat;
296 bfd_vma gnusymidx;
13acb58d 297 char * program_interpreter;
978c4450
AM
298 bfd_vma dynamic_info[DT_ENCODING];
299 bfd_vma dynamic_info_DT_GNU_HASH;
300 bfd_vma dynamic_info_DT_MIPS_XHASH;
301 elf_section_list * symtab_shndx_list;
302 size_t group_count;
303 struct group * section_groups;
304 struct group ** section_headers_groups;
305 /* A dynamic array of flags indicating for which sections a dump of
306 some kind has been requested. It is reset on a per-object file
307 basis and then initialised from the cmdline_dump_sects array,
308 the results of interpreting the -w switch, and the
309 dump_sects_byname list. */
310 struct dump_data dump;
311} Filedata;
aef1f6d0 312
c256ffe7 313/* How to print a vma value. */
843dd992
NC
314typedef enum print_mode
315{
316 HEX,
047c3dbf 317 HEX_5,
843dd992
NC
318 DEC,
319 DEC_5,
320 UNSIGNED,
047c3dbf 321 UNSIGNED_5,
843dd992 322 PREFIX_HEX,
047c3dbf 323 PREFIX_HEX_5,
843dd992 324 FULL_HEX,
047c3dbf
NL
325 LONG_HEX,
326 OCTAL,
327 OCTAL_5
843dd992
NC
328}
329print_mode;
330
bb4d2ac2
L
331/* Versioned symbol info. */
332enum versioned_symbol_info
333{
334 symbol_undefined,
335 symbol_hidden,
336 symbol_public
337};
338
32ec8896 339static const char * get_symbol_version_string
015dc7e1 340 (Filedata *, bool, const char *, unsigned long, unsigned,
32ec8896 341 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 342
9c19a809
NC
343#define UNKNOWN -1
344
b9e920ec
AM
345#define SECTION_NAME(X) \
346 (filedata->string_table + (X)->sh_name)
347
348#define SECTION_NAME_VALID(X) \
349 ((X) != NULL \
350 && filedata->string_table != NULL \
351 && (X)->sh_name < filedata->string_table_length)
352
353#define SECTION_NAME_PRINT(X) \
354 ((X) == NULL ? _("<none>") \
355 : filedata->string_table == NULL ? _("<no-strings>") \
356 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
357 : filedata->string_table + (X)->sh_name)
252b5132 358
ee42cf8c 359#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 360
10ca4b04
L
361#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
362 (strtab != NULL && offset < strtab_size)
978c4450
AM
363#define VALID_DYNAMIC_NAME(filedata, offset) \
364 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
365 filedata->dynamic_strings_length, offset)
d79b3d50
NC
366/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
367 already been called and verified that the string exists. */
978c4450
AM
368#define GET_DYNAMIC_NAME(filedata, offset) \
369 (filedata->dynamic_strings + offset)
18bd398b 370
61865e30
NC
371#define REMOVE_ARCH_BITS(ADDR) \
372 do \
373 { \
dda8d76d 374 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
375 (ADDR) &= ~1; \
376 } \
377 while (0)
f16a9783
MS
378
379/* Get the correct GNU hash section name. */
978c4450
AM
380#define GNU_HASH_SECTION_NAME(filedata) \
381 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 382\f
66cfc0fd
AM
383/* Print a BFD_VMA to an internal buffer, for use in error messages.
384 BFD_FMA_FMT can't be used in translated strings. */
385
386static const char *
387bfd_vmatoa (char *fmtch, bfd_vma value)
388{
389 /* bfd_vmatoa is used more then once in a printf call for output.
390 Cycle through an array of buffers. */
391 static int buf_pos = 0;
392 static struct bfd_vmatoa_buf
393 {
394 char place[64];
395 } buf[4];
396 char *ret;
397 char fmt[32];
398
399 ret = buf[buf_pos++].place;
400 buf_pos %= ARRAY_SIZE (buf);
401
402 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
403 snprintf (ret, sizeof (buf[0].place), fmt, value);
404 return ret;
405}
406
dda8d76d
NC
407/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
408 OFFSET + the offset of the current archive member, if we are examining an
409 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
410 allocate a buffer using malloc and fill that. In either case return the
411 pointer to the start of the retrieved data or NULL if something went wrong.
412 If something does go wrong and REASON is not NULL then emit an error
413 message using REASON as part of the context. */
59245841 414
c256ffe7 415static void *
dda8d76d
NC
416get_data (void * var,
417 Filedata * filedata,
418 unsigned long offset,
419 bfd_size_type size,
420 bfd_size_type nmemb,
421 const char * reason)
a6e9f9df 422{
2cf0635d 423 void * mvar;
57028622 424 bfd_size_type amt = size * nmemb;
a6e9f9df 425
c256ffe7 426 if (size == 0 || nmemb == 0)
a6e9f9df
AM
427 return NULL;
428
57028622
NC
429 /* If the size_t type is smaller than the bfd_size_type, eg because
430 you are building a 32-bit tool on a 64-bit host, then make sure
431 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
432 if ((size_t) size != size
433 || (size_t) nmemb != nmemb
434 || (size_t) amt != amt)
57028622
NC
435 {
436 if (reason)
66cfc0fd
AM
437 error (_("Size truncation prevents reading %s"
438 " elements of size %s for %s\n"),
439 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
440 return NULL;
441 }
442
443 /* Check for size overflow. */
7c1c1904 444 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
445 {
446 if (reason)
66cfc0fd
AM
447 error (_("Size overflow prevents reading %s"
448 " elements of size %s for %s\n"),
449 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
450 return NULL;
451 }
452
c22b42ce 453 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 454 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
455 if (filedata->archive_file_offset > filedata->file_size
456 || offset > filedata->file_size - filedata->archive_file_offset
457 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 458 {
049b0c3a 459 if (reason)
66cfc0fd
AM
460 error (_("Reading %s bytes extends past end of file for %s\n"),
461 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
462 return NULL;
463 }
464
978c4450
AM
465 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
466 SEEK_SET))
071436c6
NC
467 {
468 if (reason)
c9c1d674 469 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 470 filedata->archive_file_offset + offset, reason);
071436c6
NC
471 return NULL;
472 }
473
a6e9f9df
AM
474 mvar = var;
475 if (mvar == NULL)
476 {
7c1c1904
AM
477 /* + 1 so that we can '\0' terminate invalid string table sections. */
478 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
479
480 if (mvar == NULL)
481 {
049b0c3a 482 if (reason)
66cfc0fd
AM
483 error (_("Out of memory allocating %s bytes for %s\n"),
484 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
485 return NULL;
486 }
c256ffe7 487
c9c1d674 488 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
489 }
490
dda8d76d 491 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 492 {
049b0c3a 493 if (reason)
66cfc0fd
AM
494 error (_("Unable to read in %s bytes of %s\n"),
495 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
496 if (mvar != var)
497 free (mvar);
498 return NULL;
499 }
500
501 return mvar;
502}
503
32ec8896
NC
504/* Print a VMA value in the MODE specified.
505 Returns the number of characters displayed. */
cb8f3167 506
32ec8896 507static unsigned int
14a91970 508print_vma (bfd_vma vma, print_mode mode)
66543521 509{
32ec8896 510 unsigned int nc = 0;
66543521 511
14a91970 512 switch (mode)
66543521 513 {
14a91970
AM
514 case FULL_HEX:
515 nc = printf ("0x");
1a0670f3 516 /* Fall through. */
14a91970 517 case LONG_HEX:
f7a99963 518#ifdef BFD64
14a91970 519 if (is_32bit_elf)
437c2fb7 520 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 521#endif
14a91970
AM
522 printf_vma (vma);
523 return nc + 16;
b19aac67 524
14a91970
AM
525 case DEC_5:
526 if (vma <= 99999)
527 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 528 /* Fall through. */
14a91970
AM
529 case PREFIX_HEX:
530 nc = printf ("0x");
1a0670f3 531 /* Fall through. */
14a91970
AM
532 case HEX:
533 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 534
047c3dbf
NL
535 case PREFIX_HEX_5:
536 nc = printf ("0x");
537 /* Fall through. */
538 case HEX_5:
539 return nc + printf ("%05" BFD_VMA_FMT "x", vma);
540
14a91970
AM
541 case DEC:
542 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 543
14a91970
AM
544 case UNSIGNED:
545 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896 546
047c3dbf
NL
547 case UNSIGNED_5:
548 return printf ("%5" BFD_VMA_FMT "u", vma);
549
550 case OCTAL:
551 return printf ("%" BFD_VMA_FMT "o", vma);
552
553 case OCTAL_5:
554 return printf ("%5" BFD_VMA_FMT "o", vma);
555
32ec8896
NC
556 default:
557 /* FIXME: Report unrecognised mode ? */
558 return 0;
f7a99963 559 }
f7a99963
NC
560}
561
047c3dbf 562
7bfd842d 563/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 564 multibye characters (assuming the host environment supports them).
31104126 565
7bfd842d
NC
566 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
567
0942c7ab
NC
568 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
569 abs(WIDTH) - 5 characters followed by "[...]".
570
7bfd842d
NC
571 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
572 padding as necessary.
171191ba
NC
573
574 Returns the number of emitted characters. */
575
576static unsigned int
0942c7ab 577print_symbol (signed int width, const char * symbol)
31104126 578{
015dc7e1
AM
579 bool extra_padding = false;
580 bool do_dots = false;
32ec8896 581 signed int num_printed = 0;
3bfcb652 582#ifdef HAVE_MBSTATE_T
7bfd842d 583 mbstate_t state;
3bfcb652 584#endif
32ec8896 585 unsigned int width_remaining;
79bc120c 586 const void * alloced_symbol = NULL;
961c521f 587
7bfd842d 588 if (width < 0)
961c521f 589 {
88305e1b 590 /* Keep the width positive. This helps the code below. */
961c521f 591 width = - width;
015dc7e1 592 extra_padding = true;
0b4362b0 593 }
56d8f8a9
NC
594 else if (width == 0)
595 return 0;
961c521f 596
7bfd842d
NC
597 if (do_wide)
598 /* Set the remaining width to a very large value.
599 This simplifies the code below. */
600 width_remaining = INT_MAX;
601 else
0942c7ab
NC
602 {
603 width_remaining = width;
604 if (! do_not_show_symbol_truncation
605 && (int) strlen (symbol) > width)
606 {
607 width_remaining -= 5;
608 if ((int) width_remaining < 0)
609 width_remaining = 0;
015dc7e1 610 do_dots = true;
0942c7ab
NC
611 }
612 }
cb8f3167 613
3bfcb652 614#ifdef HAVE_MBSTATE_T
7bfd842d
NC
615 /* Initialise the multibyte conversion state. */
616 memset (& state, 0, sizeof (state));
3bfcb652 617#endif
961c521f 618
79bc120c
NC
619 if (do_demangle && *symbol)
620 {
621 const char * res = cplus_demangle (symbol, demangle_flags);
622
623 if (res != NULL)
624 alloced_symbol = symbol = res;
625 }
626
7bfd842d
NC
627 while (width_remaining)
628 {
629 size_t n;
7bfd842d 630 const char c = *symbol++;
961c521f 631
7bfd842d 632 if (c == 0)
961c521f
NC
633 break;
634
7bfd842d
NC
635 /* Do not print control characters directly as they can affect terminal
636 settings. Such characters usually appear in the names generated
637 by the assembler for local labels. */
638 if (ISCNTRL (c))
961c521f 639 {
7bfd842d 640 if (width_remaining < 2)
961c521f
NC
641 break;
642
7bfd842d
NC
643 printf ("^%c", c + 0x40);
644 width_remaining -= 2;
171191ba 645 num_printed += 2;
961c521f 646 }
7bfd842d
NC
647 else if (ISPRINT (c))
648 {
649 putchar (c);
650 width_remaining --;
651 num_printed ++;
652 }
961c521f
NC
653 else
654 {
3bfcb652
NC
655#ifdef HAVE_MBSTATE_T
656 wchar_t w;
657#endif
7bfd842d
NC
658 /* Let printf do the hard work of displaying multibyte characters. */
659 printf ("%.1s", symbol - 1);
660 width_remaining --;
661 num_printed ++;
662
3bfcb652 663#ifdef HAVE_MBSTATE_T
7bfd842d
NC
664 /* Try to find out how many bytes made up the character that was
665 just printed. Advance the symbol pointer past the bytes that
666 were displayed. */
667 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
668#else
669 n = 1;
670#endif
7bfd842d
NC
671 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
672 symbol += (n - 1);
961c521f 673 }
961c521f 674 }
171191ba 675
0942c7ab
NC
676 if (do_dots)
677 num_printed += printf ("[...]");
678
7bfd842d 679 if (extra_padding && num_printed < width)
171191ba
NC
680 {
681 /* Fill in the remaining spaces. */
7bfd842d
NC
682 printf ("%-*s", width - num_printed, " ");
683 num_printed = width;
171191ba
NC
684 }
685
79bc120c 686 free ((void *) alloced_symbol);
171191ba 687 return num_printed;
31104126
NC
688}
689
1449284b 690/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
691 the given section's name. Like print_symbol, except that it does not try
692 to print multibyte characters, it just interprets them as hex values. */
693
694static const char *
dda8d76d 695printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b 696{
ca0e11aa 697#define MAX_PRINT_SEC_NAME_LEN 256
74e1a04b 698 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 699 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
700 char * buf = sec_name_buf;
701 char c;
702 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
703
704 while ((c = * name ++) != 0)
705 {
706 if (ISCNTRL (c))
707 {
708 if (remaining < 2)
709 break;
948f632f 710
74e1a04b
NC
711 * buf ++ = '^';
712 * buf ++ = c + 0x40;
713 remaining -= 2;
714 }
715 else if (ISPRINT (c))
716 {
717 * buf ++ = c;
718 remaining -= 1;
719 }
720 else
721 {
722 static char hex[17] = "0123456789ABCDEF";
723
724 if (remaining < 4)
725 break;
726 * buf ++ = '<';
727 * buf ++ = hex[(c & 0xf0) >> 4];
728 * buf ++ = hex[c & 0x0f];
729 * buf ++ = '>';
730 remaining -= 4;
731 }
732
733 if (remaining == 0)
734 break;
735 }
736
737 * buf = 0;
738 return sec_name_buf;
739}
740
741static const char *
dda8d76d 742printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 743{
dda8d76d 744 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
745 return _("<corrupt>");
746
dda8d76d 747 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
748}
749
89fac5e3
RS
750/* Return a pointer to section NAME, or NULL if no such section exists. */
751
752static Elf_Internal_Shdr *
dda8d76d 753find_section (Filedata * filedata, const char * name)
89fac5e3
RS
754{
755 unsigned int i;
756
68807c3c
NC
757 if (filedata->section_headers == NULL)
758 return NULL;
dda8d76d
NC
759
760 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
761 if (SECTION_NAME_VALID (filedata->section_headers + i)
762 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 763 return filedata->section_headers + i;
89fac5e3
RS
764
765 return NULL;
766}
767
0b6ae522
DJ
768/* Return a pointer to a section containing ADDR, or NULL if no such
769 section exists. */
770
771static Elf_Internal_Shdr *
dda8d76d 772find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
773{
774 unsigned int i;
775
68807c3c
NC
776 if (filedata->section_headers == NULL)
777 return NULL;
778
dda8d76d 779 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 780 {
dda8d76d
NC
781 Elf_Internal_Shdr *sec = filedata->section_headers + i;
782
0b6ae522
DJ
783 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
784 return sec;
785 }
786
787 return NULL;
788}
789
071436c6 790static Elf_Internal_Shdr *
dda8d76d 791find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
792{
793 unsigned int i;
794
68807c3c
NC
795 if (filedata->section_headers == NULL)
796 return NULL;
797
dda8d76d 798 for (i = 0; i < filedata->file_header.e_shnum; i++)
071436c6 799 {
dda8d76d
NC
800 Elf_Internal_Shdr *sec = filedata->section_headers + i;
801
071436c6
NC
802 if (sec->sh_type == type)
803 return sec;
804 }
805
806 return NULL;
807}
808
657d0d47
CC
809/* Return a pointer to section NAME, or NULL if no such section exists,
810 restricted to the list of sections given in SET. */
811
812static Elf_Internal_Shdr *
dda8d76d 813find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
814{
815 unsigned int i;
816
68807c3c
NC
817 if (filedata->section_headers == NULL)
818 return NULL;
819
657d0d47
CC
820 if (set != NULL)
821 {
822 while ((i = *set++) > 0)
b814a36d
NC
823 {
824 /* See PR 21156 for a reproducer. */
dda8d76d 825 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
826 continue; /* FIXME: Should we issue an error message ? */
827
b9e920ec
AM
828 if (SECTION_NAME_VALID (filedata->section_headers + i)
829 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 830 return filedata->section_headers + i;
b814a36d 831 }
657d0d47
CC
832 }
833
dda8d76d 834 return find_section (filedata, name);
657d0d47
CC
835}
836
32ec8896 837/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
838 This OS has so many departures from the ELF standard that we test it at
839 many places. */
840
015dc7e1 841static inline bool
dda8d76d 842is_ia64_vms (Filedata * filedata)
28f997cf 843{
dda8d76d
NC
844 return filedata->file_header.e_machine == EM_IA_64
845 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
846}
847
bcedfee6 848/* Guess the relocation size commonly used by the specific machines. */
252b5132 849
015dc7e1 850static bool
2dc4cec1 851guess_is_rela (unsigned int e_machine)
252b5132 852{
9c19a809 853 switch (e_machine)
252b5132
RH
854 {
855 /* Targets that use REL relocations. */
252b5132 856 case EM_386:
22abe556 857 case EM_IAMCU:
f954747f 858 case EM_960:
e9f53129 859 case EM_ARM:
2b0337b0 860 case EM_D10V:
252b5132 861 case EM_CYGNUS_D10V:
e9f53129 862 case EM_DLX:
252b5132 863 case EM_MIPS:
4fe85591 864 case EM_MIPS_RS3_LE:
e9f53129 865 case EM_CYGNUS_M32R:
1c0d3aa6 866 case EM_SCORE:
f6c1a2d5 867 case EM_XGATE:
fe944acf 868 case EM_NFP:
aca4efc7 869 case EM_BPF:
015dc7e1 870 return false;
103f02d3 871
252b5132
RH
872 /* Targets that use RELA relocations. */
873 case EM_68K:
f954747f 874 case EM_860:
a06ea964 875 case EM_AARCH64:
cfb8c092 876 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
877 case EM_ALPHA:
878 case EM_ALTERA_NIOS2:
886a2506
NC
879 case EM_ARC:
880 case EM_ARC_COMPACT:
881 case EM_ARC_COMPACT2:
e9f53129
AM
882 case EM_AVR:
883 case EM_AVR_OLD:
884 case EM_BLACKFIN:
60bca95a 885 case EM_CR16:
e9f53129
AM
886 case EM_CRIS:
887 case EM_CRX:
b8891f8d 888 case EM_CSKY:
2b0337b0 889 case EM_D30V:
252b5132 890 case EM_CYGNUS_D30V:
2b0337b0 891 case EM_FR30:
3f8107ab 892 case EM_FT32:
252b5132 893 case EM_CYGNUS_FR30:
5c70f934 894 case EM_CYGNUS_FRV:
e9f53129
AM
895 case EM_H8S:
896 case EM_H8_300:
897 case EM_H8_300H:
800eeca4 898 case EM_IA_64:
1e4cf259
NC
899 case EM_IP2K:
900 case EM_IP2K_OLD:
3b36097d 901 case EM_IQ2000:
84e94c90 902 case EM_LATTICEMICO32:
ff7eeb89 903 case EM_M32C_OLD:
49f58d10 904 case EM_M32C:
e9f53129
AM
905 case EM_M32R:
906 case EM_MCORE:
15ab5209 907 case EM_CYGNUS_MEP:
a3c62988 908 case EM_METAG:
e9f53129
AM
909 case EM_MMIX:
910 case EM_MN10200:
911 case EM_CYGNUS_MN10200:
912 case EM_MN10300:
913 case EM_CYGNUS_MN10300:
5506d11a 914 case EM_MOXIE:
e9f53129
AM
915 case EM_MSP430:
916 case EM_MSP430_OLD:
d031aafb 917 case EM_MT:
35c08157 918 case EM_NDS32:
64fd6348 919 case EM_NIOS32:
73589c9d 920 case EM_OR1K:
e9f53129
AM
921 case EM_PPC64:
922 case EM_PPC:
2b100bb5 923 case EM_TI_PRU:
e23eba97 924 case EM_RISCV:
99c513f6 925 case EM_RL78:
c7927a3c 926 case EM_RX:
e9f53129
AM
927 case EM_S390:
928 case EM_S390_OLD:
929 case EM_SH:
930 case EM_SPARC:
931 case EM_SPARC32PLUS:
932 case EM_SPARCV9:
933 case EM_SPU:
40b36596 934 case EM_TI_C6000:
aa137e4d
NC
935 case EM_TILEGX:
936 case EM_TILEPRO:
708e2187 937 case EM_V800:
e9f53129
AM
938 case EM_V850:
939 case EM_CYGNUS_V850:
940 case EM_VAX:
619ed720 941 case EM_VISIUM:
e9f53129 942 case EM_X86_64:
8a9036a4 943 case EM_L1OM:
7a9068fe 944 case EM_K1OM:
e9f53129
AM
945 case EM_XSTORMY16:
946 case EM_XTENSA:
947 case EM_XTENSA_OLD:
7ba29e2a
NC
948 case EM_MICROBLAZE:
949 case EM_MICROBLAZE_OLD:
f96bd6c2 950 case EM_WEBASSEMBLY:
015dc7e1 951 return true;
103f02d3 952
e9f53129
AM
953 case EM_68HC05:
954 case EM_68HC08:
955 case EM_68HC11:
956 case EM_68HC16:
957 case EM_FX66:
958 case EM_ME16:
d1133906 959 case EM_MMA:
d1133906
NC
960 case EM_NCPU:
961 case EM_NDR1:
e9f53129 962 case EM_PCP:
d1133906 963 case EM_ST100:
e9f53129 964 case EM_ST19:
d1133906 965 case EM_ST7:
e9f53129
AM
966 case EM_ST9PLUS:
967 case EM_STARCORE:
d1133906 968 case EM_SVX:
e9f53129 969 case EM_TINYJ:
9c19a809
NC
970 default:
971 warn (_("Don't know about relocations on this machine architecture\n"));
015dc7e1 972 return false;
9c19a809
NC
973 }
974}
252b5132 975
dda8d76d 976/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
977 Returns TRUE upon success, FALSE otherwise. If successful then a
978 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
979 and the number of relocs loaded is placed in *NRELASP. It is the caller's
980 responsibility to free the allocated buffer. */
981
015dc7e1 982static bool
dda8d76d
NC
983slurp_rela_relocs (Filedata * filedata,
984 unsigned long rel_offset,
985 unsigned long rel_size,
986 Elf_Internal_Rela ** relasp,
987 unsigned long * nrelasp)
9c19a809 988{
2cf0635d 989 Elf_Internal_Rela * relas;
8b73c356 990 size_t nrelas;
4d6ed7c8 991 unsigned int i;
252b5132 992
4d6ed7c8
NC
993 if (is_32bit_elf)
994 {
2cf0635d 995 Elf32_External_Rela * erelas;
103f02d3 996
dda8d76d 997 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 998 rel_size, _("32-bit relocation data"));
a6e9f9df 999 if (!erelas)
015dc7e1 1000 return false;
252b5132 1001
4d6ed7c8 1002 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 1003
3f5e193b
NC
1004 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1005 sizeof (Elf_Internal_Rela));
103f02d3 1006
4d6ed7c8
NC
1007 if (relas == NULL)
1008 {
c256ffe7 1009 free (erelas);
591a748a 1010 error (_("out of memory parsing relocs\n"));
015dc7e1 1011 return false;
4d6ed7c8 1012 }
103f02d3 1013
4d6ed7c8
NC
1014 for (i = 0; i < nrelas; i++)
1015 {
1016 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1017 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1018 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1019 }
103f02d3 1020
4d6ed7c8
NC
1021 free (erelas);
1022 }
1023 else
1024 {
2cf0635d 1025 Elf64_External_Rela * erelas;
103f02d3 1026
dda8d76d 1027 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1028 rel_size, _("64-bit relocation data"));
a6e9f9df 1029 if (!erelas)
015dc7e1 1030 return false;
4d6ed7c8
NC
1031
1032 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1033
3f5e193b
NC
1034 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1035 sizeof (Elf_Internal_Rela));
103f02d3 1036
4d6ed7c8
NC
1037 if (relas == NULL)
1038 {
c256ffe7 1039 free (erelas);
591a748a 1040 error (_("out of memory parsing relocs\n"));
015dc7e1 1041 return false;
9c19a809 1042 }
4d6ed7c8
NC
1043
1044 for (i = 0; i < nrelas; i++)
9c19a809 1045 {
66543521
AM
1046 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1047 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1048 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1049
1050 /* The #ifdef BFD64 below is to prevent a compile time
1051 warning. We know that if we do not have a 64 bit data
1052 type that we will never execute this code anyway. */
1053#ifdef BFD64
dda8d76d
NC
1054 if (filedata->file_header.e_machine == EM_MIPS
1055 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1056 {
1057 /* In little-endian objects, r_info isn't really a
1058 64-bit little-endian value: it has a 32-bit
1059 little-endian symbol index followed by four
1060 individual byte fields. Reorder INFO
1061 accordingly. */
91d6fa6a
NC
1062 bfd_vma inf = relas[i].r_info;
1063 inf = (((inf & 0xffffffff) << 32)
1064 | ((inf >> 56) & 0xff)
1065 | ((inf >> 40) & 0xff00)
1066 | ((inf >> 24) & 0xff0000)
1067 | ((inf >> 8) & 0xff000000));
1068 relas[i].r_info = inf;
861fb55a
DJ
1069 }
1070#endif /* BFD64 */
4d6ed7c8 1071 }
103f02d3 1072
4d6ed7c8
NC
1073 free (erelas);
1074 }
32ec8896 1075
4d6ed7c8
NC
1076 *relasp = relas;
1077 *nrelasp = nrelas;
015dc7e1 1078 return true;
4d6ed7c8 1079}
103f02d3 1080
dda8d76d 1081/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1082 Returns TRUE upon success, FALSE otherwise. If successful then a
1083 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1084 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1085 responsibility to free the allocated buffer. */
1086
015dc7e1 1087static bool
dda8d76d
NC
1088slurp_rel_relocs (Filedata * filedata,
1089 unsigned long rel_offset,
1090 unsigned long rel_size,
1091 Elf_Internal_Rela ** relsp,
1092 unsigned long * nrelsp)
4d6ed7c8 1093{
2cf0635d 1094 Elf_Internal_Rela * rels;
8b73c356 1095 size_t nrels;
4d6ed7c8 1096 unsigned int i;
103f02d3 1097
4d6ed7c8
NC
1098 if (is_32bit_elf)
1099 {
2cf0635d 1100 Elf32_External_Rel * erels;
103f02d3 1101
dda8d76d 1102 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1103 rel_size, _("32-bit relocation data"));
a6e9f9df 1104 if (!erels)
015dc7e1 1105 return false;
103f02d3 1106
4d6ed7c8 1107 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1108
3f5e193b 1109 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1110
4d6ed7c8
NC
1111 if (rels == NULL)
1112 {
c256ffe7 1113 free (erels);
591a748a 1114 error (_("out of memory parsing relocs\n"));
015dc7e1 1115 return false;
4d6ed7c8
NC
1116 }
1117
1118 for (i = 0; i < nrels; i++)
1119 {
1120 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1121 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1122 rels[i].r_addend = 0;
9ea033b2 1123 }
4d6ed7c8
NC
1124
1125 free (erels);
9c19a809
NC
1126 }
1127 else
1128 {
2cf0635d 1129 Elf64_External_Rel * erels;
9ea033b2 1130
dda8d76d 1131 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1132 rel_size, _("64-bit relocation data"));
a6e9f9df 1133 if (!erels)
015dc7e1 1134 return false;
103f02d3 1135
4d6ed7c8 1136 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1137
3f5e193b 1138 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1139
4d6ed7c8 1140 if (rels == NULL)
9c19a809 1141 {
c256ffe7 1142 free (erels);
591a748a 1143 error (_("out of memory parsing relocs\n"));
015dc7e1 1144 return false;
4d6ed7c8 1145 }
103f02d3 1146
4d6ed7c8
NC
1147 for (i = 0; i < nrels; i++)
1148 {
66543521
AM
1149 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1150 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1151 rels[i].r_addend = 0;
861fb55a
DJ
1152
1153 /* The #ifdef BFD64 below is to prevent a compile time
1154 warning. We know that if we do not have a 64 bit data
1155 type that we will never execute this code anyway. */
1156#ifdef BFD64
dda8d76d
NC
1157 if (filedata->file_header.e_machine == EM_MIPS
1158 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1159 {
1160 /* In little-endian objects, r_info isn't really a
1161 64-bit little-endian value: it has a 32-bit
1162 little-endian symbol index followed by four
1163 individual byte fields. Reorder INFO
1164 accordingly. */
91d6fa6a
NC
1165 bfd_vma inf = rels[i].r_info;
1166 inf = (((inf & 0xffffffff) << 32)
1167 | ((inf >> 56) & 0xff)
1168 | ((inf >> 40) & 0xff00)
1169 | ((inf >> 24) & 0xff0000)
1170 | ((inf >> 8) & 0xff000000));
1171 rels[i].r_info = inf;
861fb55a
DJ
1172 }
1173#endif /* BFD64 */
4d6ed7c8 1174 }
103f02d3 1175
4d6ed7c8
NC
1176 free (erels);
1177 }
32ec8896 1178
4d6ed7c8
NC
1179 *relsp = rels;
1180 *nrelsp = nrels;
015dc7e1 1181 return true;
4d6ed7c8 1182}
103f02d3 1183
aca88567
NC
1184/* Returns the reloc type extracted from the reloc info field. */
1185
1186static unsigned int
dda8d76d 1187get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1188{
1189 if (is_32bit_elf)
1190 return ELF32_R_TYPE (reloc_info);
1191
dda8d76d 1192 switch (filedata->file_header.e_machine)
aca88567
NC
1193 {
1194 case EM_MIPS:
1195 /* Note: We assume that reloc_info has already been adjusted for us. */
1196 return ELF64_MIPS_R_TYPE (reloc_info);
1197
1198 case EM_SPARCV9:
1199 return ELF64_R_TYPE_ID (reloc_info);
1200
1201 default:
1202 return ELF64_R_TYPE (reloc_info);
1203 }
1204}
1205
1206/* Return the symbol index extracted from the reloc info field. */
1207
1208static bfd_vma
1209get_reloc_symindex (bfd_vma reloc_info)
1210{
1211 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1212}
1213
015dc7e1 1214static inline bool
dda8d76d 1215uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1216{
1217 return
dda8d76d 1218 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1219 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1220 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1221 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1222 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1223}
1224
d3ba0551
AM
1225/* Display the contents of the relocation data found at the specified
1226 offset. */
ee42cf8c 1227
015dc7e1 1228static bool
dda8d76d
NC
1229dump_relocations (Filedata * filedata,
1230 unsigned long rel_offset,
1231 unsigned long rel_size,
1232 Elf_Internal_Sym * symtab,
1233 unsigned long nsyms,
1234 char * strtab,
1235 unsigned long strtablen,
1236 int is_rela,
015dc7e1 1237 bool is_dynsym)
4d6ed7c8 1238{
32ec8896 1239 unsigned long i;
2cf0635d 1240 Elf_Internal_Rela * rels;
015dc7e1 1241 bool res = true;
103f02d3 1242
4d6ed7c8 1243 if (is_rela == UNKNOWN)
dda8d76d 1244 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1245
4d6ed7c8
NC
1246 if (is_rela)
1247 {
dda8d76d 1248 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1249 return false;
4d6ed7c8
NC
1250 }
1251 else
1252 {
dda8d76d 1253 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
015dc7e1 1254 return false;
252b5132
RH
1255 }
1256
410f7a12
L
1257 if (is_32bit_elf)
1258 {
1259 if (is_rela)
2c71103e
NC
1260 {
1261 if (do_wide)
1262 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1263 else
1264 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1265 }
410f7a12 1266 else
2c71103e
NC
1267 {
1268 if (do_wide)
1269 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1270 else
1271 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1272 }
410f7a12 1273 }
252b5132 1274 else
410f7a12
L
1275 {
1276 if (is_rela)
2c71103e
NC
1277 {
1278 if (do_wide)
8beeaeb7 1279 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1280 else
1281 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1282 }
410f7a12 1283 else
2c71103e
NC
1284 {
1285 if (do_wide)
8beeaeb7 1286 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1287 else
1288 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1289 }
410f7a12 1290 }
252b5132
RH
1291
1292 for (i = 0; i < rel_size; i++)
1293 {
2cf0635d 1294 const char * rtype;
b34976b6 1295 bfd_vma offset;
91d6fa6a 1296 bfd_vma inf;
b34976b6
AM
1297 bfd_vma symtab_index;
1298 bfd_vma type;
103f02d3 1299
b34976b6 1300 offset = rels[i].r_offset;
91d6fa6a 1301 inf = rels[i].r_info;
103f02d3 1302
dda8d76d 1303 type = get_reloc_type (filedata, inf);
91d6fa6a 1304 symtab_index = get_reloc_symindex (inf);
252b5132 1305
410f7a12
L
1306 if (is_32bit_elf)
1307 {
39dbeff8
AM
1308 printf ("%8.8lx %8.8lx ",
1309 (unsigned long) offset & 0xffffffff,
91d6fa6a 1310 (unsigned long) inf & 0xffffffff);
410f7a12
L
1311 }
1312 else
1313 {
39dbeff8 1314 printf (do_wide
d1ce973e
AM
1315 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1316 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1317 offset, inf);
410f7a12 1318 }
103f02d3 1319
dda8d76d 1320 switch (filedata->file_header.e_machine)
252b5132
RH
1321 {
1322 default:
1323 rtype = NULL;
1324 break;
1325
a06ea964
NC
1326 case EM_AARCH64:
1327 rtype = elf_aarch64_reloc_type (type);
1328 break;
1329
2b0337b0 1330 case EM_M32R:
252b5132 1331 case EM_CYGNUS_M32R:
9ea033b2 1332 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1333 break;
1334
1335 case EM_386:
22abe556 1336 case EM_IAMCU:
9ea033b2 1337 rtype = elf_i386_reloc_type (type);
252b5132
RH
1338 break;
1339
ba2685cc
AM
1340 case EM_68HC11:
1341 case EM_68HC12:
1342 rtype = elf_m68hc11_reloc_type (type);
1343 break;
75751cd9 1344
7b4ae824
JD
1345 case EM_S12Z:
1346 rtype = elf_s12z_reloc_type (type);
1347 break;
1348
252b5132 1349 case EM_68K:
9ea033b2 1350 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1351 break;
1352
f954747f
AM
1353 case EM_960:
1354 rtype = elf_i960_reloc_type (type);
1355 break;
1356
adde6300 1357 case EM_AVR:
2b0337b0 1358 case EM_AVR_OLD:
adde6300
AM
1359 rtype = elf_avr_reloc_type (type);
1360 break;
1361
9ea033b2
NC
1362 case EM_OLD_SPARCV9:
1363 case EM_SPARC32PLUS:
1364 case EM_SPARCV9:
252b5132 1365 case EM_SPARC:
9ea033b2 1366 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1367 break;
1368
e9f53129
AM
1369 case EM_SPU:
1370 rtype = elf_spu_reloc_type (type);
1371 break;
1372
708e2187
NC
1373 case EM_V800:
1374 rtype = v800_reloc_type (type);
1375 break;
2b0337b0 1376 case EM_V850:
252b5132 1377 case EM_CYGNUS_V850:
9ea033b2 1378 rtype = v850_reloc_type (type);
252b5132
RH
1379 break;
1380
2b0337b0 1381 case EM_D10V:
252b5132 1382 case EM_CYGNUS_D10V:
9ea033b2 1383 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1384 break;
1385
2b0337b0 1386 case EM_D30V:
252b5132 1387 case EM_CYGNUS_D30V:
9ea033b2 1388 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1389 break;
1390
d172d4ba
NC
1391 case EM_DLX:
1392 rtype = elf_dlx_reloc_type (type);
1393 break;
1394
252b5132 1395 case EM_SH:
9ea033b2 1396 rtype = elf_sh_reloc_type (type);
252b5132
RH
1397 break;
1398
2b0337b0 1399 case EM_MN10300:
252b5132 1400 case EM_CYGNUS_MN10300:
9ea033b2 1401 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1402 break;
1403
2b0337b0 1404 case EM_MN10200:
252b5132 1405 case EM_CYGNUS_MN10200:
9ea033b2 1406 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1407 break;
1408
2b0337b0 1409 case EM_FR30:
252b5132 1410 case EM_CYGNUS_FR30:
9ea033b2 1411 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1412 break;
1413
ba2685cc
AM
1414 case EM_CYGNUS_FRV:
1415 rtype = elf_frv_reloc_type (type);
1416 break;
5c70f934 1417
b8891f8d
AJ
1418 case EM_CSKY:
1419 rtype = elf_csky_reloc_type (type);
1420 break;
1421
3f8107ab
AM
1422 case EM_FT32:
1423 rtype = elf_ft32_reloc_type (type);
1424 break;
1425
252b5132 1426 case EM_MCORE:
9ea033b2 1427 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1428 break;
1429
3c3bdf30
NC
1430 case EM_MMIX:
1431 rtype = elf_mmix_reloc_type (type);
1432 break;
1433
5506d11a
AM
1434 case EM_MOXIE:
1435 rtype = elf_moxie_reloc_type (type);
1436 break;
1437
2469cfa2 1438 case EM_MSP430:
dda8d76d 1439 if (uses_msp430x_relocs (filedata))
13761a11
NC
1440 {
1441 rtype = elf_msp430x_reloc_type (type);
1442 break;
1443 }
1a0670f3 1444 /* Fall through. */
2469cfa2
NC
1445 case EM_MSP430_OLD:
1446 rtype = elf_msp430_reloc_type (type);
1447 break;
1448
35c08157
KLC
1449 case EM_NDS32:
1450 rtype = elf_nds32_reloc_type (type);
1451 break;
1452
252b5132 1453 case EM_PPC:
9ea033b2 1454 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1455 break;
1456
c833c019
AM
1457 case EM_PPC64:
1458 rtype = elf_ppc64_reloc_type (type);
1459 break;
1460
252b5132 1461 case EM_MIPS:
4fe85591 1462 case EM_MIPS_RS3_LE:
9ea033b2 1463 rtype = elf_mips_reloc_type (type);
252b5132
RH
1464 break;
1465
e23eba97
NC
1466 case EM_RISCV:
1467 rtype = elf_riscv_reloc_type (type);
1468 break;
1469
252b5132 1470 case EM_ALPHA:
9ea033b2 1471 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1472 break;
1473
1474 case EM_ARM:
9ea033b2 1475 rtype = elf_arm_reloc_type (type);
252b5132
RH
1476 break;
1477
584da044 1478 case EM_ARC:
886a2506
NC
1479 case EM_ARC_COMPACT:
1480 case EM_ARC_COMPACT2:
9ea033b2 1481 rtype = elf_arc_reloc_type (type);
252b5132
RH
1482 break;
1483
1484 case EM_PARISC:
69e617ca 1485 rtype = elf_hppa_reloc_type (type);
252b5132 1486 break;
7d466069 1487
b8720f9d
JL
1488 case EM_H8_300:
1489 case EM_H8_300H:
1490 case EM_H8S:
1491 rtype = elf_h8_reloc_type (type);
1492 break;
1493
73589c9d
CS
1494 case EM_OR1K:
1495 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1496 break;
1497
7d466069 1498 case EM_PJ:
2b0337b0 1499 case EM_PJ_OLD:
7d466069
ILT
1500 rtype = elf_pj_reloc_type (type);
1501 break;
800eeca4
JW
1502 case EM_IA_64:
1503 rtype = elf_ia64_reloc_type (type);
1504 break;
1b61cf92
HPN
1505
1506 case EM_CRIS:
1507 rtype = elf_cris_reloc_type (type);
1508 break;
535c37ff 1509
f954747f
AM
1510 case EM_860:
1511 rtype = elf_i860_reloc_type (type);
1512 break;
1513
bcedfee6 1514 case EM_X86_64:
8a9036a4 1515 case EM_L1OM:
7a9068fe 1516 case EM_K1OM:
bcedfee6
NC
1517 rtype = elf_x86_64_reloc_type (type);
1518 break;
a85d7ed0 1519
f954747f
AM
1520 case EM_S370:
1521 rtype = i370_reloc_type (type);
1522 break;
1523
53c7db4b
KH
1524 case EM_S390_OLD:
1525 case EM_S390:
1526 rtype = elf_s390_reloc_type (type);
1527 break;
93fbbb04 1528
1c0d3aa6
NC
1529 case EM_SCORE:
1530 rtype = elf_score_reloc_type (type);
1531 break;
1532
93fbbb04
GK
1533 case EM_XSTORMY16:
1534 rtype = elf_xstormy16_reloc_type (type);
1535 break;
179d3252 1536
1fe1f39c
NC
1537 case EM_CRX:
1538 rtype = elf_crx_reloc_type (type);
1539 break;
1540
179d3252
JT
1541 case EM_VAX:
1542 rtype = elf_vax_reloc_type (type);
1543 break;
1e4cf259 1544
619ed720
EB
1545 case EM_VISIUM:
1546 rtype = elf_visium_reloc_type (type);
1547 break;
1548
aca4efc7
JM
1549 case EM_BPF:
1550 rtype = elf_bpf_reloc_type (type);
1551 break;
1552
cfb8c092
NC
1553 case EM_ADAPTEVA_EPIPHANY:
1554 rtype = elf_epiphany_reloc_type (type);
1555 break;
1556
1e4cf259
NC
1557 case EM_IP2K:
1558 case EM_IP2K_OLD:
1559 rtype = elf_ip2k_reloc_type (type);
1560 break;
3b36097d
SC
1561
1562 case EM_IQ2000:
1563 rtype = elf_iq2000_reloc_type (type);
1564 break;
88da6820
NC
1565
1566 case EM_XTENSA_OLD:
1567 case EM_XTENSA:
1568 rtype = elf_xtensa_reloc_type (type);
1569 break;
a34e3ecb 1570
84e94c90
NC
1571 case EM_LATTICEMICO32:
1572 rtype = elf_lm32_reloc_type (type);
1573 break;
1574
ff7eeb89 1575 case EM_M32C_OLD:
49f58d10
JB
1576 case EM_M32C:
1577 rtype = elf_m32c_reloc_type (type);
1578 break;
1579
d031aafb
NS
1580 case EM_MT:
1581 rtype = elf_mt_reloc_type (type);
a34e3ecb 1582 break;
1d65ded4
CM
1583
1584 case EM_BLACKFIN:
1585 rtype = elf_bfin_reloc_type (type);
1586 break;
15ab5209
DB
1587
1588 case EM_CYGNUS_MEP:
1589 rtype = elf_mep_reloc_type (type);
1590 break;
60bca95a
NC
1591
1592 case EM_CR16:
1593 rtype = elf_cr16_reloc_type (type);
1594 break;
dd24e3da 1595
7ba29e2a
NC
1596 case EM_MICROBLAZE:
1597 case EM_MICROBLAZE_OLD:
1598 rtype = elf_microblaze_reloc_type (type);
1599 break;
c7927a3c 1600
99c513f6
DD
1601 case EM_RL78:
1602 rtype = elf_rl78_reloc_type (type);
1603 break;
1604
c7927a3c
NC
1605 case EM_RX:
1606 rtype = elf_rx_reloc_type (type);
1607 break;
c29aca4a 1608
a3c62988
NC
1609 case EM_METAG:
1610 rtype = elf_metag_reloc_type (type);
1611 break;
1612
c29aca4a
NC
1613 case EM_XC16X:
1614 case EM_C166:
1615 rtype = elf_xc16x_reloc_type (type);
1616 break;
40b36596
JM
1617
1618 case EM_TI_C6000:
1619 rtype = elf_tic6x_reloc_type (type);
1620 break;
aa137e4d
NC
1621
1622 case EM_TILEGX:
1623 rtype = elf_tilegx_reloc_type (type);
1624 break;
1625
1626 case EM_TILEPRO:
1627 rtype = elf_tilepro_reloc_type (type);
1628 break;
f6c1a2d5 1629
f96bd6c2
PC
1630 case EM_WEBASSEMBLY:
1631 rtype = elf_wasm32_reloc_type (type);
1632 break;
1633
f6c1a2d5
NC
1634 case EM_XGATE:
1635 rtype = elf_xgate_reloc_type (type);
1636 break;
36591ba1
SL
1637
1638 case EM_ALTERA_NIOS2:
1639 rtype = elf_nios2_reloc_type (type);
1640 break;
2b100bb5
DD
1641
1642 case EM_TI_PRU:
1643 rtype = elf_pru_reloc_type (type);
1644 break;
fe944acf
FT
1645
1646 case EM_NFP:
1647 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1648 rtype = elf_nfp3200_reloc_type (type);
1649 else
1650 rtype = elf_nfp_reloc_type (type);
1651 break;
6655dba2
SB
1652
1653 case EM_Z80:
1654 rtype = elf_z80_reloc_type (type);
1655 break;
252b5132
RH
1656 }
1657
1658 if (rtype == NULL)
39dbeff8 1659 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1660 else
5c144731 1661 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1662
dda8d76d 1663 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1664 && rtype != NULL
7ace3541
RH
1665 && streq (rtype, "R_ALPHA_LITUSE")
1666 && is_rela)
1667 {
1668 switch (rels[i].r_addend)
1669 {
1670 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1671 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1672 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1673 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1674 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1675 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1676 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1677 default: rtype = NULL;
1678 }
32ec8896 1679
7ace3541
RH
1680 if (rtype)
1681 printf (" (%s)", rtype);
1682 else
1683 {
1684 putchar (' ');
1685 printf (_("<unknown addend: %lx>"),
1686 (unsigned long) rels[i].r_addend);
015dc7e1 1687 res = false;
7ace3541
RH
1688 }
1689 }
1690 else if (symtab_index)
252b5132 1691 {
af3fc3bc 1692 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1693 {
27a45f42
AS
1694 error (_(" bad symbol index: %08lx in reloc\n"),
1695 (unsigned long) symtab_index);
015dc7e1 1696 res = false;
32ec8896 1697 }
af3fc3bc 1698 else
19936277 1699 {
2cf0635d 1700 Elf_Internal_Sym * psym;
bb4d2ac2
L
1701 const char * version_string;
1702 enum versioned_symbol_info sym_info;
1703 unsigned short vna_other;
19936277 1704
af3fc3bc 1705 psym = symtab + symtab_index;
103f02d3 1706
bb4d2ac2 1707 version_string
dda8d76d 1708 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1709 strtab, strtablen,
1710 symtab_index,
1711 psym,
1712 &sym_info,
1713 &vna_other);
1714
af3fc3bc 1715 printf (" ");
171191ba 1716
d8045f23
NC
1717 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1718 {
1719 const char * name;
1720 unsigned int len;
1721 unsigned int width = is_32bit_elf ? 8 : 14;
1722
1723 /* Relocations against GNU_IFUNC symbols do not use the value
1724 of the symbol as the address to relocate against. Instead
1725 they invoke the function named by the symbol and use its
1726 result as the address for relocation.
1727
1728 To indicate this to the user, do not display the value of
1729 the symbol in the "Symbols's Value" field. Instead show
1730 its name followed by () as a hint that the symbol is
1731 invoked. */
1732
1733 if (strtab == NULL
1734 || psym->st_name == 0
1735 || psym->st_name >= strtablen)
1736 name = "??";
1737 else
1738 name = strtab + psym->st_name;
1739
1740 len = print_symbol (width, name);
bb4d2ac2
L
1741 if (version_string)
1742 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1743 version_string);
d8045f23
NC
1744 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1745 }
1746 else
1747 {
1748 print_vma (psym->st_value, LONG_HEX);
171191ba 1749
d8045f23
NC
1750 printf (is_32bit_elf ? " " : " ");
1751 }
103f02d3 1752
af3fc3bc 1753 if (psym->st_name == 0)
f1ef08cb 1754 {
2cf0635d 1755 const char * sec_name = "<null>";
f1ef08cb
AM
1756 char name_buf[40];
1757
1758 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1759 {
dda8d76d 1760 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1761 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1762 + psym->st_shndx);
f1ef08cb
AM
1763 else if (psym->st_shndx == SHN_ABS)
1764 sec_name = "ABS";
1765 else if (psym->st_shndx == SHN_COMMON)
1766 sec_name = "COMMON";
dda8d76d 1767 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1768 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1769 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1770 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1771 sec_name = "SCOMMON";
dda8d76d 1772 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1773 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1774 sec_name = "SUNDEF";
dda8d76d
NC
1775 else if ((filedata->file_header.e_machine == EM_X86_64
1776 || filedata->file_header.e_machine == EM_L1OM
1777 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1778 && psym->st_shndx == SHN_X86_64_LCOMMON)
1779 sec_name = "LARGE_COMMON";
dda8d76d
NC
1780 else if (filedata->file_header.e_machine == EM_IA_64
1781 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1782 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1783 sec_name = "ANSI_COM";
dda8d76d 1784 else if (is_ia64_vms (filedata)
148b93f2
NC
1785 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1786 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1787 else
1788 {
1789 sprintf (name_buf, "<section 0x%x>",
1790 (unsigned int) psym->st_shndx);
1791 sec_name = name_buf;
1792 }
1793 }
1794 print_symbol (22, sec_name);
1795 }
af3fc3bc 1796 else if (strtab == NULL)
d79b3d50 1797 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1798 else if (psym->st_name >= strtablen)
32ec8896 1799 {
27a45f42
AS
1800 error (_("<corrupt string table index: %3ld>\n"),
1801 psym->st_name);
015dc7e1 1802 res = false;
32ec8896 1803 }
af3fc3bc 1804 else
bb4d2ac2
L
1805 {
1806 print_symbol (22, strtab + psym->st_name);
1807 if (version_string)
1808 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1809 version_string);
1810 }
103f02d3 1811
af3fc3bc 1812 if (is_rela)
171191ba 1813 {
7360e63f 1814 bfd_vma off = rels[i].r_addend;
171191ba 1815
7360e63f 1816 if ((bfd_signed_vma) off < 0)
598aaa76 1817 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1818 else
598aaa76 1819 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1820 }
19936277 1821 }
252b5132 1822 }
1b228002 1823 else if (is_rela)
f7a99963 1824 {
7360e63f 1825 bfd_vma off = rels[i].r_addend;
e04d7088
L
1826
1827 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1828 if ((bfd_signed_vma) off < 0)
e04d7088
L
1829 printf ("-%" BFD_VMA_FMT "x", - off);
1830 else
1831 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1832 }
252b5132 1833
dda8d76d 1834 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1835 && rtype != NULL
1836 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1837 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1838
252b5132 1839 putchar ('\n');
2c71103e 1840
aca88567 1841#ifdef BFD64
dda8d76d 1842 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1843 {
91d6fa6a
NC
1844 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1845 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1846 const char * rtype2 = elf_mips_reloc_type (type2);
1847 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1848
2c71103e
NC
1849 printf (" Type2: ");
1850
1851 if (rtype2 == NULL)
39dbeff8
AM
1852 printf (_("unrecognized: %-7lx"),
1853 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1854 else
1855 printf ("%-17.17s", rtype2);
1856
18bd398b 1857 printf ("\n Type3: ");
2c71103e
NC
1858
1859 if (rtype3 == NULL)
39dbeff8
AM
1860 printf (_("unrecognized: %-7lx"),
1861 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1862 else
1863 printf ("%-17.17s", rtype3);
1864
53c7db4b 1865 putchar ('\n');
2c71103e 1866 }
aca88567 1867#endif /* BFD64 */
252b5132
RH
1868 }
1869
c8286bd1 1870 free (rels);
32ec8896
NC
1871
1872 return res;
252b5132
RH
1873}
1874
37c18eed
SD
1875static const char *
1876get_aarch64_dynamic_type (unsigned long type)
1877{
1878 switch (type)
1879 {
1880 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1881 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1882 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1883 default:
1884 return NULL;
1885 }
1886}
1887
252b5132 1888static const char *
d3ba0551 1889get_mips_dynamic_type (unsigned long type)
252b5132
RH
1890{
1891 switch (type)
1892 {
1893 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1894 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1895 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1896 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1897 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1898 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1899 case DT_MIPS_MSYM: return "MIPS_MSYM";
1900 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1901 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1902 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1903 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1904 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1905 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1906 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1907 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1908 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1909 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1910 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1911 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1912 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1913 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1914 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1915 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1916 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1917 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1918 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1919 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1920 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1921 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1922 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1923 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1924 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1925 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1926 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1927 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1928 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1929 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1930 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1931 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1932 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1933 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1934 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1935 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1936 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1937 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1938 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1939 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1940 default:
1941 return NULL;
1942 }
1943}
1944
9a097730 1945static const char *
d3ba0551 1946get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1947{
1948 switch (type)
1949 {
1950 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1951 default:
1952 return NULL;
1953 }
103f02d3
UD
1954}
1955
7490d522
AM
1956static const char *
1957get_ppc_dynamic_type (unsigned long type)
1958{
1959 switch (type)
1960 {
a7f2871e 1961 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1962 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1963 default:
1964 return NULL;
1965 }
1966}
1967
f1cb7e17 1968static const char *
d3ba0551 1969get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1970{
1971 switch (type)
1972 {
a7f2871e
AM
1973 case DT_PPC64_GLINK: return "PPC64_GLINK";
1974 case DT_PPC64_OPD: return "PPC64_OPD";
1975 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1976 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1977 default:
1978 return NULL;
1979 }
1980}
1981
103f02d3 1982static const char *
d3ba0551 1983get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1984{
1985 switch (type)
1986 {
1987 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1988 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1989 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1990 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1991 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1992 case DT_HP_PREINIT: return "HP_PREINIT";
1993 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1994 case DT_HP_NEEDED: return "HP_NEEDED";
1995 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1996 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1997 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1998 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1999 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
2000 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
2001 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
2002 case DT_HP_FILTERED: return "HP_FILTERED";
2003 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
2004 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
2005 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
2006 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
2007 case DT_PLT: return "PLT";
2008 case DT_PLT_SIZE: return "PLT_SIZE";
2009 case DT_DLT: return "DLT";
2010 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
2011 default:
2012 return NULL;
2013 }
2014}
9a097730 2015
ecc51f48 2016static const char *
d3ba0551 2017get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
2018{
2019 switch (type)
2020 {
148b93f2
NC
2021 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2022 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2023 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2024 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2025 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2026 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2027 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2028 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2029 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2030 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2031 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2032 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2033 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2034 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2035 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2036 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2037 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2038 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2039 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2040 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2041 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2042 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2043 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2044 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2045 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2046 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2047 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2048 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2049 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2050 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2051 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2052 default:
2053 return NULL;
2054 }
2055}
2056
fd85a6a1
NC
2057static const char *
2058get_solaris_section_type (unsigned long type)
2059{
2060 switch (type)
2061 {
2062 case 0x6fffffee: return "SUNW_ancillary";
2063 case 0x6fffffef: return "SUNW_capchain";
2064 case 0x6ffffff0: return "SUNW_capinfo";
2065 case 0x6ffffff1: return "SUNW_symsort";
2066 case 0x6ffffff2: return "SUNW_tlssort";
2067 case 0x6ffffff3: return "SUNW_LDYNSYM";
2068 case 0x6ffffff4: return "SUNW_dof";
2069 case 0x6ffffff5: return "SUNW_cap";
2070 case 0x6ffffff6: return "SUNW_SIGNATURE";
2071 case 0x6ffffff7: return "SUNW_ANNOTATE";
2072 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2073 case 0x6ffffff9: return "SUNW_DEBUG";
2074 case 0x6ffffffa: return "SUNW_move";
2075 case 0x6ffffffb: return "SUNW_COMDAT";
2076 case 0x6ffffffc: return "SUNW_syminfo";
2077 case 0x6ffffffd: return "SUNW_verdef";
2078 case 0x6ffffffe: return "SUNW_verneed";
2079 case 0x6fffffff: return "SUNW_versym";
2080 case 0x70000000: return "SPARC_GOTDATA";
2081 default: return NULL;
2082 }
2083}
2084
fabcb361
RH
2085static const char *
2086get_alpha_dynamic_type (unsigned long type)
2087{
2088 switch (type)
2089 {
2090 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2091 default: return NULL;
fabcb361
RH
2092 }
2093}
2094
1c0d3aa6
NC
2095static const char *
2096get_score_dynamic_type (unsigned long type)
2097{
2098 switch (type)
2099 {
2100 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2101 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2102 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2103 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2104 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2105 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2106 default: return NULL;
1c0d3aa6
NC
2107 }
2108}
2109
40b36596
JM
2110static const char *
2111get_tic6x_dynamic_type (unsigned long type)
2112{
2113 switch (type)
2114 {
2115 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2116 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2117 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2118 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2119 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2120 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2121 default: return NULL;
40b36596
JM
2122 }
2123}
1c0d3aa6 2124
36591ba1
SL
2125static const char *
2126get_nios2_dynamic_type (unsigned long type)
2127{
2128 switch (type)
2129 {
2130 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2131 default: return NULL;
36591ba1
SL
2132 }
2133}
2134
fd85a6a1
NC
2135static const char *
2136get_solaris_dynamic_type (unsigned long type)
2137{
2138 switch (type)
2139 {
2140 case 0x6000000d: return "SUNW_AUXILIARY";
2141 case 0x6000000e: return "SUNW_RTLDINF";
2142 case 0x6000000f: return "SUNW_FILTER";
2143 case 0x60000010: return "SUNW_CAP";
2144 case 0x60000011: return "SUNW_SYMTAB";
2145 case 0x60000012: return "SUNW_SYMSZ";
2146 case 0x60000013: return "SUNW_SORTENT";
2147 case 0x60000014: return "SUNW_SYMSORT";
2148 case 0x60000015: return "SUNW_SYMSORTSZ";
2149 case 0x60000016: return "SUNW_TLSSORT";
2150 case 0x60000017: return "SUNW_TLSSORTSZ";
2151 case 0x60000018: return "SUNW_CAPINFO";
2152 case 0x60000019: return "SUNW_STRPAD";
2153 case 0x6000001a: return "SUNW_CAPCHAIN";
2154 case 0x6000001b: return "SUNW_LDMACH";
2155 case 0x6000001d: return "SUNW_CAPCHAINENT";
2156 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2157 case 0x60000021: return "SUNW_PARENT";
2158 case 0x60000023: return "SUNW_ASLR";
2159 case 0x60000025: return "SUNW_RELAX";
2160 case 0x60000029: return "SUNW_NXHEAP";
2161 case 0x6000002b: return "SUNW_NXSTACK";
2162
2163 case 0x70000001: return "SPARC_REGISTER";
2164 case 0x7ffffffd: return "AUXILIARY";
2165 case 0x7ffffffe: return "USED";
2166 case 0x7fffffff: return "FILTER";
2167
15f205b1 2168 default: return NULL;
fd85a6a1
NC
2169 }
2170}
2171
252b5132 2172static const char *
dda8d76d 2173get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2174{
e9e44622 2175 static char buff[64];
252b5132
RH
2176
2177 switch (type)
2178 {
2179 case DT_NULL: return "NULL";
2180 case DT_NEEDED: return "NEEDED";
2181 case DT_PLTRELSZ: return "PLTRELSZ";
2182 case DT_PLTGOT: return "PLTGOT";
2183 case DT_HASH: return "HASH";
2184 case DT_STRTAB: return "STRTAB";
2185 case DT_SYMTAB: return "SYMTAB";
2186 case DT_RELA: return "RELA";
2187 case DT_RELASZ: return "RELASZ";
2188 case DT_RELAENT: return "RELAENT";
2189 case DT_STRSZ: return "STRSZ";
2190 case DT_SYMENT: return "SYMENT";
2191 case DT_INIT: return "INIT";
2192 case DT_FINI: return "FINI";
2193 case DT_SONAME: return "SONAME";
2194 case DT_RPATH: return "RPATH";
2195 case DT_SYMBOLIC: return "SYMBOLIC";
2196 case DT_REL: return "REL";
2197 case DT_RELSZ: return "RELSZ";
2198 case DT_RELENT: return "RELENT";
2199 case DT_PLTREL: return "PLTREL";
2200 case DT_DEBUG: return "DEBUG";
2201 case DT_TEXTREL: return "TEXTREL";
2202 case DT_JMPREL: return "JMPREL";
2203 case DT_BIND_NOW: return "BIND_NOW";
2204 case DT_INIT_ARRAY: return "INIT_ARRAY";
2205 case DT_FINI_ARRAY: return "FINI_ARRAY";
2206 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2207 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2208 case DT_RUNPATH: return "RUNPATH";
2209 case DT_FLAGS: return "FLAGS";
2d0e6f43 2210
d1133906
NC
2211 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2212 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2213 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2214
05107a46 2215 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2216 case DT_PLTPADSZ: return "PLTPADSZ";
2217 case DT_MOVEENT: return "MOVEENT";
2218 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2219 case DT_FEATURE: return "FEATURE";
252b5132
RH
2220 case DT_POSFLAG_1: return "POSFLAG_1";
2221 case DT_SYMINSZ: return "SYMINSZ";
2222 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2223
252b5132 2224 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2225 case DT_CONFIG: return "CONFIG";
2226 case DT_DEPAUDIT: return "DEPAUDIT";
2227 case DT_AUDIT: return "AUDIT";
2228 case DT_PLTPAD: return "PLTPAD";
2229 case DT_MOVETAB: return "MOVETAB";
252b5132 2230 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2231
252b5132 2232 case DT_VERSYM: return "VERSYM";
103f02d3 2233
67a4f2b7
AO
2234 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2235 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2236 case DT_RELACOUNT: return "RELACOUNT";
2237 case DT_RELCOUNT: return "RELCOUNT";
2238 case DT_FLAGS_1: return "FLAGS_1";
2239 case DT_VERDEF: return "VERDEF";
2240 case DT_VERDEFNUM: return "VERDEFNUM";
2241 case DT_VERNEED: return "VERNEED";
2242 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2243
019148e4 2244 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2245 case DT_USED: return "USED";
2246 case DT_FILTER: return "FILTER";
103f02d3 2247
047b2264
JJ
2248 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2249 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2250 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2251 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2252 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2253 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2254 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2255
252b5132
RH
2256 default:
2257 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2258 {
2cf0635d 2259 const char * result;
103f02d3 2260
dda8d76d 2261 switch (filedata->file_header.e_machine)
252b5132 2262 {
37c18eed
SD
2263 case EM_AARCH64:
2264 result = get_aarch64_dynamic_type (type);
2265 break;
252b5132 2266 case EM_MIPS:
4fe85591 2267 case EM_MIPS_RS3_LE:
252b5132
RH
2268 result = get_mips_dynamic_type (type);
2269 break;
9a097730
RH
2270 case EM_SPARCV9:
2271 result = get_sparc64_dynamic_type (type);
2272 break;
7490d522
AM
2273 case EM_PPC:
2274 result = get_ppc_dynamic_type (type);
2275 break;
f1cb7e17
AM
2276 case EM_PPC64:
2277 result = get_ppc64_dynamic_type (type);
2278 break;
ecc51f48
NC
2279 case EM_IA_64:
2280 result = get_ia64_dynamic_type (type);
2281 break;
fabcb361
RH
2282 case EM_ALPHA:
2283 result = get_alpha_dynamic_type (type);
2284 break;
1c0d3aa6
NC
2285 case EM_SCORE:
2286 result = get_score_dynamic_type (type);
2287 break;
40b36596
JM
2288 case EM_TI_C6000:
2289 result = get_tic6x_dynamic_type (type);
2290 break;
36591ba1
SL
2291 case EM_ALTERA_NIOS2:
2292 result = get_nios2_dynamic_type (type);
2293 break;
252b5132 2294 default:
dda8d76d 2295 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2296 result = get_solaris_dynamic_type (type);
2297 else
2298 result = NULL;
252b5132
RH
2299 break;
2300 }
2301
2302 if (result != NULL)
2303 return result;
2304
e9e44622 2305 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2306 }
eec8f817 2307 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2308 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2309 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2310 {
2cf0635d 2311 const char * result;
103f02d3 2312
dda8d76d 2313 switch (filedata->file_header.e_machine)
103f02d3
UD
2314 {
2315 case EM_PARISC:
2316 result = get_parisc_dynamic_type (type);
2317 break;
148b93f2
NC
2318 case EM_IA_64:
2319 result = get_ia64_dynamic_type (type);
2320 break;
103f02d3 2321 default:
dda8d76d 2322 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2323 result = get_solaris_dynamic_type (type);
2324 else
2325 result = NULL;
103f02d3
UD
2326 break;
2327 }
2328
2329 if (result != NULL)
2330 return result;
2331
e9e44622
JJ
2332 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2333 type);
103f02d3 2334 }
252b5132 2335 else
e9e44622 2336 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2337
252b5132
RH
2338 return buff;
2339 }
2340}
2341
93df3340
AM
2342static bool get_program_headers (Filedata *);
2343static bool get_dynamic_section (Filedata *);
2344
2345static void
2346locate_dynamic_section (Filedata *filedata)
2347{
2348 unsigned long dynamic_addr = 0;
2349 bfd_size_type dynamic_size = 0;
2350
2351 if (filedata->file_header.e_phnum != 0
2352 && get_program_headers (filedata))
2353 {
2354 Elf_Internal_Phdr *segment;
2355 unsigned int i;
2356
2357 for (i = 0, segment = filedata->program_headers;
2358 i < filedata->file_header.e_phnum;
2359 i++, segment++)
2360 {
2361 if (segment->p_type == PT_DYNAMIC)
2362 {
2363 dynamic_addr = segment->p_offset;
2364 dynamic_size = segment->p_filesz;
2365
2366 if (filedata->section_headers != NULL)
2367 {
2368 Elf_Internal_Shdr *sec;
2369
2370 sec = find_section (filedata, ".dynamic");
2371 if (sec != NULL)
2372 {
2373 if (sec->sh_size == 0
2374 || sec->sh_type == SHT_NOBITS)
2375 {
2376 dynamic_addr = 0;
2377 dynamic_size = 0;
2378 }
2379 else
2380 {
2381 dynamic_addr = sec->sh_offset;
2382 dynamic_size = sec->sh_size;
2383 }
2384 }
2385 }
2386
2387 if (dynamic_addr > filedata->file_size
2388 || (dynamic_size > filedata->file_size - dynamic_addr))
2389 {
2390 dynamic_addr = 0;
2391 dynamic_size = 0;
2392 }
2393 break;
2394 }
2395 }
2396 }
2397 filedata->dynamic_addr = dynamic_addr;
2398 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
2399}
2400
2401static bool
2402is_pie (Filedata *filedata)
2403{
2404 Elf_Internal_Dyn *entry;
2405
2406 if (filedata->dynamic_size == 0)
2407 locate_dynamic_section (filedata);
2408 if (filedata->dynamic_size <= 1)
2409 return false;
2410
2411 if (!get_dynamic_section (filedata))
2412 return false;
2413
2414 for (entry = filedata->dynamic_section;
2415 entry < filedata->dynamic_section + filedata->dynamic_nent;
2416 entry++)
2417 {
2418 if (entry->d_tag == DT_FLAGS_1)
2419 {
2420 if ((entry->d_un.d_val & DF_1_PIE) != 0)
2421 return true;
2422 break;
2423 }
2424 }
2425 return false;
2426}
2427
252b5132 2428static char *
93df3340 2429get_file_type (Filedata *filedata)
252b5132 2430{
93df3340 2431 unsigned e_type = filedata->file_header.e_type;
89246a0e 2432 static char buff[64];
252b5132
RH
2433
2434 switch (e_type)
2435 {
32ec8896
NC
2436 case ET_NONE: return _("NONE (None)");
2437 case ET_REL: return _("REL (Relocatable file)");
2438 case ET_EXEC: return _("EXEC (Executable file)");
93df3340
AM
2439 case ET_DYN:
2440 if (is_pie (filedata))
2441 return _("DYN (Position-Independent Executable file)");
2442 else
2443 return _("DYN (Shared object file)");
32ec8896 2444 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2445
2446 default:
2447 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2448 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2449 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2450 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2451 else
e9e44622 2452 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2453 return buff;
2454 }
2455}
2456
2457static char *
d3ba0551 2458get_machine_name (unsigned e_machine)
252b5132 2459{
b34976b6 2460 static char buff[64]; /* XXX */
252b5132
RH
2461
2462 switch (e_machine)
2463 {
55e22ca8
NC
2464 /* Please keep this switch table sorted by increasing EM_ value. */
2465 /* 0 */
c45021f2
NC
2466 case EM_NONE: return _("None");
2467 case EM_M32: return "WE32100";
2468 case EM_SPARC: return "Sparc";
2469 case EM_386: return "Intel 80386";
2470 case EM_68K: return "MC68000";
2471 case EM_88K: return "MC88000";
22abe556 2472 case EM_IAMCU: return "Intel MCU";
fb70ec17 2473 case EM_860: return "Intel 80860";
c45021f2
NC
2474 case EM_MIPS: return "MIPS R3000";
2475 case EM_S370: return "IBM System/370";
55e22ca8 2476 /* 10 */
7036c0e1 2477 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2478 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2479 case EM_PARISC: return "HPPA";
55e22ca8 2480 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2481 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2482 case EM_960: return "Intel 80960";
c45021f2 2483 case EM_PPC: return "PowerPC";
55e22ca8 2484 /* 20 */
285d1771 2485 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2486 case EM_S390_OLD:
2487 case EM_S390: return "IBM S/390";
2488 case EM_SPU: return "SPU";
2489 /* 30 */
2490 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2491 case EM_FR20: return "Fujitsu FR20";
2492 case EM_RH32: return "TRW RH32";
b34976b6 2493 case EM_MCORE: return "MCORE";
55e22ca8 2494 /* 40 */
7036c0e1
AJ
2495 case EM_ARM: return "ARM";
2496 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2497 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2498 case EM_SPARCV9: return "Sparc v9";
2499 case EM_TRICORE: return "Siemens Tricore";
584da044 2500 case EM_ARC: return "ARC";
c2dcd04e
NC
2501 case EM_H8_300: return "Renesas H8/300";
2502 case EM_H8_300H: return "Renesas H8/300H";
2503 case EM_H8S: return "Renesas H8S";
2504 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2505 /* 50 */
30800947 2506 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2507 case EM_MIPS_X: return "Stanford MIPS-X";
2508 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2509 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2510 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2511 case EM_PCP: return "Siemens PCP";
2512 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2513 case EM_NDR1: return "Denso NDR1 microprocesspr";
2514 case EM_STARCORE: return "Motorola Star*Core processor";
2515 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2516 /* 60 */
7036c0e1
AJ
2517 case EM_ST100: return "STMicroelectronics ST100 processor";
2518 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2519 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2520 case EM_PDSP: return "Sony DSP processor";
2521 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2522 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2523 case EM_FX66: return "Siemens FX66 microcontroller";
2524 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2525 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2526 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2527 /* 70 */
7036c0e1
AJ
2528 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2529 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2530 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2531 case EM_SVX: return "Silicon Graphics SVx";
2532 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2533 case EM_VAX: return "Digital VAX";
1b61cf92 2534 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2535 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2536 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2537 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2538 /* 80 */
b34976b6 2539 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2540 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2541 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2542 case EM_AVR_OLD:
2543 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2544 case EM_CYGNUS_FR30:
2545 case EM_FR30: return "Fujitsu FR30";
2546 case EM_CYGNUS_D10V:
2547 case EM_D10V: return "d10v";
2548 case EM_CYGNUS_D30V:
2549 case EM_D30V: return "d30v";
2550 case EM_CYGNUS_V850:
2551 case EM_V850: return "Renesas V850";
2552 case EM_CYGNUS_M32R:
2553 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2554 case EM_CYGNUS_MN10300:
2555 case EM_MN10300: return "mn10300";
2556 /* 90 */
2557 case EM_CYGNUS_MN10200:
2558 case EM_MN10200: return "mn10200";
2559 case EM_PJ: return "picoJava";
73589c9d 2560 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2561 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2562 case EM_XTENSA_OLD:
2563 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2564 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2565 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2566 case EM_NS32K: return "National Semiconductor 32000 series";
2567 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2568 case EM_SNP1K: return "Trebia SNP 1000 processor";
2569 /* 100 */
9abca702 2570 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2571 case EM_IP2K_OLD:
2572 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2573 case EM_MAX: return "MAX Processor";
2574 case EM_CR: return "National Semiconductor CompactRISC";
2575 case EM_F2MC16: return "Fujitsu F2MC16";
2576 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2577 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2578 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2579 case EM_SEP: return "Sharp embedded microprocessor";
2580 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2581 /* 110 */
11636f9e
JM
2582 case EM_UNICORE: return "Unicore";
2583 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2584 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2585 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2586 case EM_CRX: return "National Semiconductor CRX microprocessor";
2587 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2588 case EM_C166:
d70c5fc7 2589 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2590 case EM_M16C: return "Renesas M16C series microprocessors";
2591 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2592 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2593 /* 120 */
2594 case EM_M32C: return "Renesas M32c";
2595 /* 130 */
11636f9e
JM
2596 case EM_TSK3000: return "Altium TSK3000 core";
2597 case EM_RS08: return "Freescale RS08 embedded processor";
2598 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2599 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2600 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2601 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2602 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2603 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2604 /* 140 */
11636f9e
JM
2605 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2606 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2607 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2608 case EM_TI_PRU: return "TI PRU I/O processor";
2609 /* 160 */
11636f9e
JM
2610 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2611 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2612 case EM_R32C: return "Renesas R32C series microprocessors";
2613 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2614 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2615 case EM_8051: return "Intel 8051 and variants";
2616 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2617 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2618 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2619 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2620 /* 170 */
11636f9e
JM
2621 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2622 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2623 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2624 case EM_RX: return "Renesas RX";
a3c62988 2625 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2626 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2627 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2628 case EM_CR16:
2629 case EM_MICROBLAZE:
2630 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2631 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2632 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2633 /* 180 */
2634 case EM_L1OM: return "Intel L1OM";
2635 case EM_K1OM: return "Intel K1OM";
2636 case EM_INTEL182: return "Intel (reserved)";
2637 case EM_AARCH64: return "AArch64";
2638 case EM_ARM184: return "ARM (reserved)";
2639 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2640 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2641 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2642 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2643 /* 190 */
11636f9e 2644 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2645 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2646 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2647 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2648 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2649 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2650 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2651 case EM_RL78: return "Renesas RL78";
6d913794 2652 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2653 case EM_78K0R: return "Renesas 78K0R";
2654 /* 200 */
6d913794 2655 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2656 case EM_BA1: return "Beyond BA1 CPU architecture";
2657 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2658 case EM_XCORE: return "XMOS xCORE processor family";
2659 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
7b9f9859 2660 case EM_INTELGT: return "Intel Graphics Technology";
55e22ca8 2661 /* 210 */
6d913794
NC
2662 case EM_KM32: return "KM211 KM32 32-bit processor";
2663 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2664 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2665 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2666 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2667 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2668 case EM_COGE: return "Cognitive Smart Memory Processor";
2669 case EM_COOL: return "Bluechip Systems CoolEngine";
2670 case EM_NORC: return "Nanoradio Optimized RISC";
2671 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2672 /* 220 */
15f205b1 2673 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2674 case EM_VISIUM: return "CDS VISIUMcore processor";
2675 case EM_FT32: return "FTDI Chip FT32";
2676 case EM_MOXIE: return "Moxie";
2677 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2678 /* 230 (all reserved) */
2679 /* 240 */
55e22ca8
NC
2680 case EM_RISCV: return "RISC-V";
2681 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2682 case EM_CEVA: return "CEVA Processor Architecture Family";
2683 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2684 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2685 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2686 case EM_IMG1: return "Imagination Technologies";
2687 /* 250 */
fe944acf 2688 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2689 case EM_VE: return "NEC Vector Engine";
2690 case EM_CSKY: return "C-SKY";
2691 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2692 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2693 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2694 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2695 case EM_65816: return "WDC 65816/65C816";
01a8c731 2696 case EM_LOONGARCH: return "LoongArch";
4cf2ad72 2697 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2698
2699 /* Large numbers... */
2700 case EM_MT: return "Morpho Techologies MT processor";
2701 case EM_ALPHA: return "Alpha";
2702 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2703 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2704 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2705 case EM_IQ2000: return "Vitesse IQ2000";
2706 case EM_M32C_OLD:
2707 case EM_NIOS32: return "Altera Nios";
2708 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2709 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2710 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2711 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2712
252b5132 2713 default:
35d9dd2f 2714 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2715 return buff;
2716 }
2717}
2718
a9522a21
AB
2719static void
2720decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2721{
2722 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2723 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2724 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2725 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2726 architectures.
2727
2728 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2729 but also sets a specific architecture type in the e_flags field.
2730
2731 However, when decoding the flags we don't worry if we see an
2732 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2733 ARCEM architecture type. */
2734
2735 switch (e_flags & EF_ARC_MACH_MSK)
2736 {
2737 /* We only expect these to occur for EM_ARC_COMPACT2. */
2738 case EF_ARC_CPU_ARCV2EM:
2739 strcat (buf, ", ARC EM");
2740 break;
2741 case EF_ARC_CPU_ARCV2HS:
2742 strcat (buf, ", ARC HS");
2743 break;
2744
2745 /* We only expect these to occur for EM_ARC_COMPACT. */
2746 case E_ARC_MACH_ARC600:
2747 strcat (buf, ", ARC600");
2748 break;
2749 case E_ARC_MACH_ARC601:
2750 strcat (buf, ", ARC601");
2751 break;
2752 case E_ARC_MACH_ARC700:
2753 strcat (buf, ", ARC700");
2754 break;
2755
2756 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2757 new ELF with new architecture being read by an old version of
2758 readelf, or (c) An ELF built with non-GNU compiler that does not
2759 set the architecture in the e_flags. */
2760 default:
2761 if (e_machine == EM_ARC_COMPACT)
2762 strcat (buf, ", Unknown ARCompact");
2763 else
2764 strcat (buf, ", Unknown ARC");
2765 break;
2766 }
2767
2768 switch (e_flags & EF_ARC_OSABI_MSK)
2769 {
2770 case E_ARC_OSABI_ORIG:
2771 strcat (buf, ", (ABI:legacy)");
2772 break;
2773 case E_ARC_OSABI_V2:
2774 strcat (buf, ", (ABI:v2)");
2775 break;
2776 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2777 case E_ARC_OSABI_V3:
2778 strcat (buf, ", v3 no-legacy-syscalls ABI");
2779 break;
53a346d8
CZ
2780 case E_ARC_OSABI_V4:
2781 strcat (buf, ", v4 ABI");
2782 break;
a9522a21
AB
2783 default:
2784 strcat (buf, ", unrecognised ARC OSABI flag");
2785 break;
2786 }
2787}
2788
f3485b74 2789static void
d3ba0551 2790decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2791{
2792 unsigned eabi;
015dc7e1 2793 bool unknown = false;
f3485b74
NC
2794
2795 eabi = EF_ARM_EABI_VERSION (e_flags);
2796 e_flags &= ~ EF_ARM_EABIMASK;
2797
2798 /* Handle "generic" ARM flags. */
2799 if (e_flags & EF_ARM_RELEXEC)
2800 {
2801 strcat (buf, ", relocatable executable");
2802 e_flags &= ~ EF_ARM_RELEXEC;
2803 }
76da6bbe 2804
18a20338
CL
2805 if (e_flags & EF_ARM_PIC)
2806 {
2807 strcat (buf, ", position independent");
2808 e_flags &= ~ EF_ARM_PIC;
2809 }
2810
f3485b74
NC
2811 /* Now handle EABI specific flags. */
2812 switch (eabi)
2813 {
2814 default:
2c71103e 2815 strcat (buf, ", <unrecognized EABI>");
f3485b74 2816 if (e_flags)
015dc7e1 2817 unknown = true;
f3485b74
NC
2818 break;
2819
2820 case EF_ARM_EABI_VER1:
a5bcd848 2821 strcat (buf, ", Version1 EABI");
f3485b74
NC
2822 while (e_flags)
2823 {
2824 unsigned flag;
76da6bbe 2825
f3485b74
NC
2826 /* Process flags one bit at a time. */
2827 flag = e_flags & - e_flags;
2828 e_flags &= ~ flag;
76da6bbe 2829
f3485b74
NC
2830 switch (flag)
2831 {
a5bcd848 2832 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2833 strcat (buf, ", sorted symbol tables");
2834 break;
76da6bbe 2835
f3485b74 2836 default:
015dc7e1 2837 unknown = true;
f3485b74
NC
2838 break;
2839 }
2840 }
2841 break;
76da6bbe 2842
a5bcd848
PB
2843 case EF_ARM_EABI_VER2:
2844 strcat (buf, ", Version2 EABI");
2845 while (e_flags)
2846 {
2847 unsigned flag;
2848
2849 /* Process flags one bit at a time. */
2850 flag = e_flags & - e_flags;
2851 e_flags &= ~ flag;
2852
2853 switch (flag)
2854 {
2855 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2856 strcat (buf, ", sorted symbol tables");
2857 break;
2858
2859 case EF_ARM_DYNSYMSUSESEGIDX:
2860 strcat (buf, ", dynamic symbols use segment index");
2861 break;
2862
2863 case EF_ARM_MAPSYMSFIRST:
2864 strcat (buf, ", mapping symbols precede others");
2865 break;
2866
2867 default:
015dc7e1 2868 unknown = true;
a5bcd848
PB
2869 break;
2870 }
2871 }
2872 break;
2873
d507cf36
PB
2874 case EF_ARM_EABI_VER3:
2875 strcat (buf, ", Version3 EABI");
8cb51566
PB
2876 break;
2877
2878 case EF_ARM_EABI_VER4:
2879 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2880 while (e_flags)
2881 {
2882 unsigned flag;
2883
2884 /* Process flags one bit at a time. */
2885 flag = e_flags & - e_flags;
2886 e_flags &= ~ flag;
2887
2888 switch (flag)
2889 {
2890 case EF_ARM_BE8:
2891 strcat (buf, ", BE8");
2892 break;
2893
2894 case EF_ARM_LE8:
2895 strcat (buf, ", LE8");
2896 break;
2897
2898 default:
015dc7e1 2899 unknown = true;
3bfcb652
NC
2900 break;
2901 }
3bfcb652
NC
2902 }
2903 break;
3a4a14e9
PB
2904
2905 case EF_ARM_EABI_VER5:
2906 strcat (buf, ", Version5 EABI");
d507cf36
PB
2907 while (e_flags)
2908 {
2909 unsigned flag;
2910
2911 /* Process flags one bit at a time. */
2912 flag = e_flags & - e_flags;
2913 e_flags &= ~ flag;
2914
2915 switch (flag)
2916 {
2917 case EF_ARM_BE8:
2918 strcat (buf, ", BE8");
2919 break;
2920
2921 case EF_ARM_LE8:
2922 strcat (buf, ", LE8");
2923 break;
2924
3bfcb652
NC
2925 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2926 strcat (buf, ", soft-float ABI");
2927 break;
2928
2929 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2930 strcat (buf, ", hard-float ABI");
2931 break;
2932
d507cf36 2933 default:
015dc7e1 2934 unknown = true;
d507cf36
PB
2935 break;
2936 }
2937 }
2938 break;
2939
f3485b74 2940 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2941 strcat (buf, ", GNU EABI");
f3485b74
NC
2942 while (e_flags)
2943 {
2944 unsigned flag;
76da6bbe 2945
f3485b74
NC
2946 /* Process flags one bit at a time. */
2947 flag = e_flags & - e_flags;
2948 e_flags &= ~ flag;
76da6bbe 2949
f3485b74
NC
2950 switch (flag)
2951 {
a5bcd848 2952 case EF_ARM_INTERWORK:
f3485b74
NC
2953 strcat (buf, ", interworking enabled");
2954 break;
76da6bbe 2955
a5bcd848 2956 case EF_ARM_APCS_26:
f3485b74
NC
2957 strcat (buf, ", uses APCS/26");
2958 break;
76da6bbe 2959
a5bcd848 2960 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2961 strcat (buf, ", uses APCS/float");
2962 break;
76da6bbe 2963
a5bcd848 2964 case EF_ARM_PIC:
f3485b74
NC
2965 strcat (buf, ", position independent");
2966 break;
76da6bbe 2967
a5bcd848 2968 case EF_ARM_ALIGN8:
f3485b74
NC
2969 strcat (buf, ", 8 bit structure alignment");
2970 break;
76da6bbe 2971
a5bcd848 2972 case EF_ARM_NEW_ABI:
f3485b74
NC
2973 strcat (buf, ", uses new ABI");
2974 break;
76da6bbe 2975
a5bcd848 2976 case EF_ARM_OLD_ABI:
f3485b74
NC
2977 strcat (buf, ", uses old ABI");
2978 break;
76da6bbe 2979
a5bcd848 2980 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2981 strcat (buf, ", software FP");
2982 break;
76da6bbe 2983
90e01f86
ILT
2984 case EF_ARM_VFP_FLOAT:
2985 strcat (buf, ", VFP");
2986 break;
2987
fde78edd
NC
2988 case EF_ARM_MAVERICK_FLOAT:
2989 strcat (buf, ", Maverick FP");
2990 break;
2991
f3485b74 2992 default:
015dc7e1 2993 unknown = true;
f3485b74
NC
2994 break;
2995 }
2996 }
2997 }
f3485b74
NC
2998
2999 if (unknown)
2b692964 3000 strcat (buf,_(", <unknown>"));
f3485b74
NC
3001}
3002
343433df
AB
3003static void
3004decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
3005{
3006 --size; /* Leave space for null terminator. */
3007
3008 switch (e_flags & EF_AVR_MACH)
3009 {
3010 case E_AVR_MACH_AVR1:
3011 strncat (buf, ", avr:1", size);
3012 break;
3013 case E_AVR_MACH_AVR2:
3014 strncat (buf, ", avr:2", size);
3015 break;
3016 case E_AVR_MACH_AVR25:
3017 strncat (buf, ", avr:25", size);
3018 break;
3019 case E_AVR_MACH_AVR3:
3020 strncat (buf, ", avr:3", size);
3021 break;
3022 case E_AVR_MACH_AVR31:
3023 strncat (buf, ", avr:31", size);
3024 break;
3025 case E_AVR_MACH_AVR35:
3026 strncat (buf, ", avr:35", size);
3027 break;
3028 case E_AVR_MACH_AVR4:
3029 strncat (buf, ", avr:4", size);
3030 break;
3031 case E_AVR_MACH_AVR5:
3032 strncat (buf, ", avr:5", size);
3033 break;
3034 case E_AVR_MACH_AVR51:
3035 strncat (buf, ", avr:51", size);
3036 break;
3037 case E_AVR_MACH_AVR6:
3038 strncat (buf, ", avr:6", size);
3039 break;
3040 case E_AVR_MACH_AVRTINY:
3041 strncat (buf, ", avr:100", size);
3042 break;
3043 case E_AVR_MACH_XMEGA1:
3044 strncat (buf, ", avr:101", size);
3045 break;
3046 case E_AVR_MACH_XMEGA2:
3047 strncat (buf, ", avr:102", size);
3048 break;
3049 case E_AVR_MACH_XMEGA3:
3050 strncat (buf, ", avr:103", size);
3051 break;
3052 case E_AVR_MACH_XMEGA4:
3053 strncat (buf, ", avr:104", size);
3054 break;
3055 case E_AVR_MACH_XMEGA5:
3056 strncat (buf, ", avr:105", size);
3057 break;
3058 case E_AVR_MACH_XMEGA6:
3059 strncat (buf, ", avr:106", size);
3060 break;
3061 case E_AVR_MACH_XMEGA7:
3062 strncat (buf, ", avr:107", size);
3063 break;
3064 default:
3065 strncat (buf, ", avr:<unknown>", size);
3066 break;
3067 }
3068
3069 size -= strlen (buf);
3070 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
3071 strncat (buf, ", link-relax", size);
3072}
3073
35c08157
KLC
3074static void
3075decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
3076{
3077 unsigned abi;
3078 unsigned arch;
3079 unsigned config;
3080 unsigned version;
015dc7e1 3081 bool has_fpu = false;
32ec8896 3082 unsigned int r = 0;
35c08157
KLC
3083
3084 static const char *ABI_STRINGS[] =
3085 {
3086 "ABI v0", /* use r5 as return register; only used in N1213HC */
3087 "ABI v1", /* use r0 as return register */
3088 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
3089 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
3090 "AABI",
3091 "ABI2 FP+"
35c08157
KLC
3092 };
3093 static const char *VER_STRINGS[] =
3094 {
3095 "Andes ELF V1.3 or older",
3096 "Andes ELF V1.3.1",
3097 "Andes ELF V1.4"
3098 };
3099 static const char *ARCH_STRINGS[] =
3100 {
3101 "",
3102 "Andes Star v1.0",
3103 "Andes Star v2.0",
3104 "Andes Star v3.0",
3105 "Andes Star v3.0m"
3106 };
3107
3108 abi = EF_NDS_ABI & e_flags;
3109 arch = EF_NDS_ARCH & e_flags;
3110 config = EF_NDS_INST & e_flags;
3111 version = EF_NDS32_ELF_VERSION & e_flags;
3112
3113 memset (buf, 0, size);
3114
3115 switch (abi)
3116 {
3117 case E_NDS_ABI_V0:
3118 case E_NDS_ABI_V1:
3119 case E_NDS_ABI_V2:
3120 case E_NDS_ABI_V2FP:
3121 case E_NDS_ABI_AABI:
40c7a7cb 3122 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3123 /* In case there are holes in the array. */
3124 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3125 break;
3126
3127 default:
3128 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3129 break;
3130 }
3131
3132 switch (version)
3133 {
3134 case E_NDS32_ELF_VER_1_2:
3135 case E_NDS32_ELF_VER_1_3:
3136 case E_NDS32_ELF_VER_1_4:
3137 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3138 break;
3139
3140 default:
3141 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3142 break;
3143 }
3144
3145 if (E_NDS_ABI_V0 == abi)
3146 {
3147 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3148 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3149 if (arch == E_NDS_ARCH_STAR_V1_0)
3150 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3151 return;
3152 }
3153
3154 switch (arch)
3155 {
3156 case E_NDS_ARCH_STAR_V1_0:
3157 case E_NDS_ARCH_STAR_V2_0:
3158 case E_NDS_ARCH_STAR_V3_0:
3159 case E_NDS_ARCH_STAR_V3_M:
3160 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3161 break;
3162
3163 default:
3164 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3165 /* ARCH version determines how the e_flags are interpreted.
3166 If it is unknown, we cannot proceed. */
3167 return;
3168 }
3169
3170 /* Newer ABI; Now handle architecture specific flags. */
3171 if (arch == E_NDS_ARCH_STAR_V1_0)
3172 {
3173 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3174 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3175
3176 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3177 r += snprintf (buf + r, size -r, ", MAC");
3178
3179 if (config & E_NDS32_HAS_DIV_INST)
3180 r += snprintf (buf + r, size -r, ", DIV");
3181
3182 if (config & E_NDS32_HAS_16BIT_INST)
3183 r += snprintf (buf + r, size -r, ", 16b");
3184 }
3185 else
3186 {
3187 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3188 {
3189 if (version <= E_NDS32_ELF_VER_1_3)
3190 r += snprintf (buf + r, size -r, ", [B8]");
3191 else
3192 r += snprintf (buf + r, size -r, ", EX9");
3193 }
3194
3195 if (config & E_NDS32_HAS_MAC_DX_INST)
3196 r += snprintf (buf + r, size -r, ", MAC_DX");
3197
3198 if (config & E_NDS32_HAS_DIV_DX_INST)
3199 r += snprintf (buf + r, size -r, ", DIV_DX");
3200
3201 if (config & E_NDS32_HAS_16BIT_INST)
3202 {
3203 if (version <= E_NDS32_ELF_VER_1_3)
3204 r += snprintf (buf + r, size -r, ", 16b");
3205 else
3206 r += snprintf (buf + r, size -r, ", IFC");
3207 }
3208 }
3209
3210 if (config & E_NDS32_HAS_EXT_INST)
3211 r += snprintf (buf + r, size -r, ", PERF1");
3212
3213 if (config & E_NDS32_HAS_EXT2_INST)
3214 r += snprintf (buf + r, size -r, ", PERF2");
3215
3216 if (config & E_NDS32_HAS_FPU_INST)
3217 {
015dc7e1 3218 has_fpu = true;
35c08157
KLC
3219 r += snprintf (buf + r, size -r, ", FPU_SP");
3220 }
3221
3222 if (config & E_NDS32_HAS_FPU_DP_INST)
3223 {
015dc7e1 3224 has_fpu = true;
35c08157
KLC
3225 r += snprintf (buf + r, size -r, ", FPU_DP");
3226 }
3227
3228 if (config & E_NDS32_HAS_FPU_MAC_INST)
3229 {
015dc7e1 3230 has_fpu = true;
35c08157
KLC
3231 r += snprintf (buf + r, size -r, ", FPU_MAC");
3232 }
3233
3234 if (has_fpu)
3235 {
3236 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3237 {
3238 case E_NDS32_FPU_REG_8SP_4DP:
3239 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3240 break;
3241 case E_NDS32_FPU_REG_16SP_8DP:
3242 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3243 break;
3244 case E_NDS32_FPU_REG_32SP_16DP:
3245 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3246 break;
3247 case E_NDS32_FPU_REG_32SP_32DP:
3248 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3249 break;
3250 }
3251 }
3252
3253 if (config & E_NDS32_HAS_AUDIO_INST)
3254 r += snprintf (buf + r, size -r, ", AUDIO");
3255
3256 if (config & E_NDS32_HAS_STRING_INST)
3257 r += snprintf (buf + r, size -r, ", STR");
3258
3259 if (config & E_NDS32_HAS_REDUCED_REGS)
3260 r += snprintf (buf + r, size -r, ", 16REG");
3261
3262 if (config & E_NDS32_HAS_VIDEO_INST)
3263 {
3264 if (version <= E_NDS32_ELF_VER_1_3)
3265 r += snprintf (buf + r, size -r, ", VIDEO");
3266 else
3267 r += snprintf (buf + r, size -r, ", SATURATION");
3268 }
3269
3270 if (config & E_NDS32_HAS_ENCRIPT_INST)
3271 r += snprintf (buf + r, size -r, ", ENCRP");
3272
3273 if (config & E_NDS32_HAS_L2C_INST)
3274 r += snprintf (buf + r, size -r, ", L2C");
3275}
3276
252b5132 3277static char *
dda8d76d 3278get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3279{
b34976b6 3280 static char buf[1024];
252b5132
RH
3281
3282 buf[0] = '\0';
76da6bbe 3283
252b5132
RH
3284 if (e_flags)
3285 {
3286 switch (e_machine)
3287 {
3288 default:
3289 break;
3290
886a2506 3291 case EM_ARC_COMPACT2:
886a2506 3292 case EM_ARC_COMPACT:
a9522a21
AB
3293 decode_ARC_machine_flags (e_flags, e_machine, buf);
3294 break;
886a2506 3295
f3485b74
NC
3296 case EM_ARM:
3297 decode_ARM_machine_flags (e_flags, buf);
3298 break;
76da6bbe 3299
343433df
AB
3300 case EM_AVR:
3301 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3302 break;
3303
781303ce
MF
3304 case EM_BLACKFIN:
3305 if (e_flags & EF_BFIN_PIC)
3306 strcat (buf, ", PIC");
3307
3308 if (e_flags & EF_BFIN_FDPIC)
3309 strcat (buf, ", FDPIC");
3310
3311 if (e_flags & EF_BFIN_CODE_IN_L1)
3312 strcat (buf, ", code in L1");
3313
3314 if (e_flags & EF_BFIN_DATA_IN_L1)
3315 strcat (buf, ", data in L1");
3316
3317 break;
3318
ec2dfb42
AO
3319 case EM_CYGNUS_FRV:
3320 switch (e_flags & EF_FRV_CPU_MASK)
3321 {
3322 case EF_FRV_CPU_GENERIC:
3323 break;
3324
3325 default:
3326 strcat (buf, ", fr???");
3327 break;
57346661 3328
ec2dfb42
AO
3329 case EF_FRV_CPU_FR300:
3330 strcat (buf, ", fr300");
3331 break;
3332
3333 case EF_FRV_CPU_FR400:
3334 strcat (buf, ", fr400");
3335 break;
3336 case EF_FRV_CPU_FR405:
3337 strcat (buf, ", fr405");
3338 break;
3339
3340 case EF_FRV_CPU_FR450:
3341 strcat (buf, ", fr450");
3342 break;
3343
3344 case EF_FRV_CPU_FR500:
3345 strcat (buf, ", fr500");
3346 break;
3347 case EF_FRV_CPU_FR550:
3348 strcat (buf, ", fr550");
3349 break;
3350
3351 case EF_FRV_CPU_SIMPLE:
3352 strcat (buf, ", simple");
3353 break;
3354 case EF_FRV_CPU_TOMCAT:
3355 strcat (buf, ", tomcat");
3356 break;
3357 }
1c877e87 3358 break;
ec2dfb42 3359
53c7db4b 3360 case EM_68K:
425c6cb0 3361 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3362 strcat (buf, ", m68000");
425c6cb0 3363 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3364 strcat (buf, ", cpu32");
3365 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3366 strcat (buf, ", fido_a");
425c6cb0 3367 else
266abb8f 3368 {
2cf0635d
NC
3369 char const * isa = _("unknown");
3370 char const * mac = _("unknown mac");
3371 char const * additional = NULL;
0112cd26 3372
c694fd50 3373 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3374 {
c694fd50 3375 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3376 isa = "A";
3377 additional = ", nodiv";
3378 break;
c694fd50 3379 case EF_M68K_CF_ISA_A:
266abb8f
NS
3380 isa = "A";
3381 break;
c694fd50 3382 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3383 isa = "A+";
3384 break;
c694fd50 3385 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3386 isa = "B";
3387 additional = ", nousp";
3388 break;
c694fd50 3389 case EF_M68K_CF_ISA_B:
266abb8f
NS
3390 isa = "B";
3391 break;
f608cd77
NS
3392 case EF_M68K_CF_ISA_C:
3393 isa = "C";
3394 break;
3395 case EF_M68K_CF_ISA_C_NODIV:
3396 isa = "C";
3397 additional = ", nodiv";
3398 break;
266abb8f
NS
3399 }
3400 strcat (buf, ", cf, isa ");
3401 strcat (buf, isa);
0b2e31dc
NS
3402 if (additional)
3403 strcat (buf, additional);
c694fd50 3404 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3405 strcat (buf, ", float");
c694fd50 3406 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3407 {
3408 case 0:
3409 mac = NULL;
3410 break;
c694fd50 3411 case EF_M68K_CF_MAC:
266abb8f
NS
3412 mac = "mac";
3413 break;
c694fd50 3414 case EF_M68K_CF_EMAC:
266abb8f
NS
3415 mac = "emac";
3416 break;
f608cd77
NS
3417 case EF_M68K_CF_EMAC_B:
3418 mac = "emac_b";
3419 break;
266abb8f
NS
3420 }
3421 if (mac)
3422 {
3423 strcat (buf, ", ");
3424 strcat (buf, mac);
3425 }
266abb8f 3426 }
53c7db4b 3427 break;
33c63f9d 3428
153a2776
NC
3429 case EM_CYGNUS_MEP:
3430 switch (e_flags & EF_MEP_CPU_MASK)
3431 {
3432 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3433 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3434 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3435 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3436 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3437 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3438 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3439 }
3440
3441 switch (e_flags & EF_MEP_COP_MASK)
3442 {
3443 case EF_MEP_COP_NONE: break;
3444 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3445 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3446 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3447 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3448 default: strcat (buf, _("<unknown MeP copro type>")); break;
3449 }
3450
3451 if (e_flags & EF_MEP_LIBRARY)
3452 strcat (buf, ", Built for Library");
3453
3454 if (e_flags & EF_MEP_INDEX_MASK)
3455 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3456 e_flags & EF_MEP_INDEX_MASK);
3457
3458 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3459 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3460 e_flags & ~ EF_MEP_ALL_FLAGS);
3461 break;
3462
252b5132
RH
3463 case EM_PPC:
3464 if (e_flags & EF_PPC_EMB)
3465 strcat (buf, ", emb");
3466
3467 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3468 strcat (buf, _(", relocatable"));
252b5132
RH
3469
3470 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3471 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3472 break;
3473
ee67d69a
AM
3474 case EM_PPC64:
3475 if (e_flags & EF_PPC64_ABI)
3476 {
3477 char abi[] = ", abiv0";
3478
3479 abi[6] += e_flags & EF_PPC64_ABI;
3480 strcat (buf, abi);
3481 }
3482 break;
3483
708e2187
NC
3484 case EM_V800:
3485 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3486 strcat (buf, ", RH850 ABI");
0b4362b0 3487
708e2187
NC
3488 if (e_flags & EF_V800_850E3)
3489 strcat (buf, ", V3 architecture");
3490
3491 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3492 strcat (buf, ", FPU not used");
3493
3494 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3495 strcat (buf, ", regmode: COMMON");
3496
3497 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3498 strcat (buf, ", r4 not used");
3499
3500 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3501 strcat (buf, ", r30 not used");
3502
3503 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3504 strcat (buf, ", r5 not used");
3505
3506 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3507 strcat (buf, ", r2 not used");
3508
3509 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3510 {
3511 switch (e_flags & - e_flags)
3512 {
3513 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3514 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3515 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3516 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3517 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3518 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3519 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3520 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3521 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3522 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3523 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3524 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3525 default: break;
3526 }
3527 }
3528 break;
3529
2b0337b0 3530 case EM_V850:
252b5132
RH
3531 case EM_CYGNUS_V850:
3532 switch (e_flags & EF_V850_ARCH)
3533 {
78c8d46c
NC
3534 case E_V850E3V5_ARCH:
3535 strcat (buf, ", v850e3v5");
3536 break;
1cd986c5
NC
3537 case E_V850E2V3_ARCH:
3538 strcat (buf, ", v850e2v3");
3539 break;
3540 case E_V850E2_ARCH:
3541 strcat (buf, ", v850e2");
3542 break;
3543 case E_V850E1_ARCH:
3544 strcat (buf, ", v850e1");
8ad30312 3545 break;
252b5132
RH
3546 case E_V850E_ARCH:
3547 strcat (buf, ", v850e");
3548 break;
252b5132
RH
3549 case E_V850_ARCH:
3550 strcat (buf, ", v850");
3551 break;
3552 default:
2b692964 3553 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3554 break;
3555 }
3556 break;
3557
2b0337b0 3558 case EM_M32R:
252b5132
RH
3559 case EM_CYGNUS_M32R:
3560 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3561 strcat (buf, ", m32r");
252b5132
RH
3562 break;
3563
3564 case EM_MIPS:
4fe85591 3565 case EM_MIPS_RS3_LE:
252b5132
RH
3566 if (e_flags & EF_MIPS_NOREORDER)
3567 strcat (buf, ", noreorder");
3568
3569 if (e_flags & EF_MIPS_PIC)
3570 strcat (buf, ", pic");
3571
3572 if (e_flags & EF_MIPS_CPIC)
3573 strcat (buf, ", cpic");
3574
d1bdd336
TS
3575 if (e_flags & EF_MIPS_UCODE)
3576 strcat (buf, ", ugen_reserved");
3577
252b5132
RH
3578 if (e_flags & EF_MIPS_ABI2)
3579 strcat (buf, ", abi2");
3580
43521d43
TS
3581 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3582 strcat (buf, ", odk first");
3583
a5d22d2a
TS
3584 if (e_flags & EF_MIPS_32BITMODE)
3585 strcat (buf, ", 32bitmode");
3586
ba92f887
MR
3587 if (e_flags & EF_MIPS_NAN2008)
3588 strcat (buf, ", nan2008");
3589
fef1b0b3
SE
3590 if (e_flags & EF_MIPS_FP64)
3591 strcat (buf, ", fp64");
3592
156c2f8b
NC
3593 switch ((e_flags & EF_MIPS_MACH))
3594 {
3595 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3596 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3597 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3598 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3599 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3600 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3601 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3602 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3603 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3604 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3605 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3606 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3607 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3608 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3609 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3610 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3611 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3612 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3613 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3614 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3615 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3616 case 0:
3617 /* We simply ignore the field in this case to avoid confusion:
3618 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3619 extension. */
3620 break;
2b692964 3621 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3622 }
43521d43
TS
3623
3624 switch ((e_flags & EF_MIPS_ABI))
3625 {
3626 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3627 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3628 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3629 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3630 case 0:
3631 /* We simply ignore the field in this case to avoid confusion:
3632 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3633 This means it is likely to be an o32 file, but not for
3634 sure. */
3635 break;
2b692964 3636 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3637 }
3638
3639 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3640 strcat (buf, ", mdmx");
3641
3642 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3643 strcat (buf, ", mips16");
3644
df58fc94
RS
3645 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3646 strcat (buf, ", micromips");
3647
43521d43
TS
3648 switch ((e_flags & EF_MIPS_ARCH))
3649 {
3650 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3651 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3652 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3653 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3654 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3655 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3656 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3657 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3658 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3659 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3660 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3661 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3662 }
252b5132 3663 break;
351b4b40 3664
35c08157
KLC
3665 case EM_NDS32:
3666 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3667 break;
3668
fe944acf
FT
3669 case EM_NFP:
3670 switch (EF_NFP_MACH (e_flags))
3671 {
3672 case E_NFP_MACH_3200:
3673 strcat (buf, ", NFP-32xx");
3674 break;
3675 case E_NFP_MACH_6000:
3676 strcat (buf, ", NFP-6xxx");
3677 break;
3678 }
3679 break;
3680
e23eba97
NC
3681 case EM_RISCV:
3682 if (e_flags & EF_RISCV_RVC)
3683 strcat (buf, ", RVC");
2922d21d 3684
7f999549
JW
3685 if (e_flags & EF_RISCV_RVE)
3686 strcat (buf, ", RVE");
3687
2922d21d
AW
3688 switch (e_flags & EF_RISCV_FLOAT_ABI)
3689 {
3690 case EF_RISCV_FLOAT_ABI_SOFT:
3691 strcat (buf, ", soft-float ABI");
3692 break;
3693
3694 case EF_RISCV_FLOAT_ABI_SINGLE:
3695 strcat (buf, ", single-float ABI");
3696 break;
3697
3698 case EF_RISCV_FLOAT_ABI_DOUBLE:
3699 strcat (buf, ", double-float ABI");
3700 break;
3701
3702 case EF_RISCV_FLOAT_ABI_QUAD:
3703 strcat (buf, ", quad-float ABI");
3704 break;
3705 }
e23eba97
NC
3706 break;
3707
ccde1100
AO
3708 case EM_SH:
3709 switch ((e_flags & EF_SH_MACH_MASK))
3710 {
3711 case EF_SH1: strcat (buf, ", sh1"); break;
3712 case EF_SH2: strcat (buf, ", sh2"); break;
3713 case EF_SH3: strcat (buf, ", sh3"); break;
3714 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3715 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3716 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3717 case EF_SH3E: strcat (buf, ", sh3e"); break;
3718 case EF_SH4: strcat (buf, ", sh4"); break;
3719 case EF_SH5: strcat (buf, ", sh5"); break;
3720 case EF_SH2E: strcat (buf, ", sh2e"); break;
3721 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3722 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3723 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3724 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3725 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3726 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3727 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3728 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3729 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3730 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3731 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3732 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3733 }
3734
cec6a5b8
MR
3735 if (e_flags & EF_SH_PIC)
3736 strcat (buf, ", pic");
3737
3738 if (e_flags & EF_SH_FDPIC)
3739 strcat (buf, ", fdpic");
ccde1100 3740 break;
948f632f 3741
73589c9d
CS
3742 case EM_OR1K:
3743 if (e_flags & EF_OR1K_NODELAY)
3744 strcat (buf, ", no delay");
3745 break;
57346661 3746
351b4b40
RH
3747 case EM_SPARCV9:
3748 if (e_flags & EF_SPARC_32PLUS)
3749 strcat (buf, ", v8+");
3750
3751 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3752 strcat (buf, ", ultrasparcI");
3753
3754 if (e_flags & EF_SPARC_SUN_US3)
3755 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3756
3757 if (e_flags & EF_SPARC_HAL_R1)
3758 strcat (buf, ", halr1");
3759
3760 if (e_flags & EF_SPARC_LEDATA)
3761 strcat (buf, ", ledata");
3762
3763 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3764 strcat (buf, ", tso");
3765
3766 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3767 strcat (buf, ", pso");
3768
3769 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3770 strcat (buf, ", rmo");
3771 break;
7d466069 3772
103f02d3
UD
3773 case EM_PARISC:
3774 switch (e_flags & EF_PARISC_ARCH)
3775 {
3776 case EFA_PARISC_1_0:
3777 strcpy (buf, ", PA-RISC 1.0");
3778 break;
3779 case EFA_PARISC_1_1:
3780 strcpy (buf, ", PA-RISC 1.1");
3781 break;
3782 case EFA_PARISC_2_0:
3783 strcpy (buf, ", PA-RISC 2.0");
3784 break;
3785 default:
3786 break;
3787 }
3788 if (e_flags & EF_PARISC_TRAPNIL)
3789 strcat (buf, ", trapnil");
3790 if (e_flags & EF_PARISC_EXT)
3791 strcat (buf, ", ext");
3792 if (e_flags & EF_PARISC_LSB)
3793 strcat (buf, ", lsb");
3794 if (e_flags & EF_PARISC_WIDE)
3795 strcat (buf, ", wide");
3796 if (e_flags & EF_PARISC_NO_KABP)
3797 strcat (buf, ", no kabp");
3798 if (e_flags & EF_PARISC_LAZYSWAP)
3799 strcat (buf, ", lazyswap");
30800947 3800 break;
76da6bbe 3801
7d466069 3802 case EM_PJ:
2b0337b0 3803 case EM_PJ_OLD:
7d466069
ILT
3804 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3805 strcat (buf, ", new calling convention");
3806
3807 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3808 strcat (buf, ", gnu calling convention");
3809 break;
4d6ed7c8
NC
3810
3811 case EM_IA_64:
3812 if ((e_flags & EF_IA_64_ABI64))
3813 strcat (buf, ", 64-bit");
3814 else
3815 strcat (buf, ", 32-bit");
3816 if ((e_flags & EF_IA_64_REDUCEDFP))
3817 strcat (buf, ", reduced fp model");
3818 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3819 strcat (buf, ", no function descriptors, constant gp");
3820 else if ((e_flags & EF_IA_64_CONS_GP))
3821 strcat (buf, ", constant gp");
3822 if ((e_flags & EF_IA_64_ABSOLUTE))
3823 strcat (buf, ", absolute");
dda8d76d 3824 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3825 {
3826 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3827 strcat (buf, ", vms_linkages");
3828 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3829 {
3830 case EF_IA_64_VMS_COMCOD_SUCCESS:
3831 break;
3832 case EF_IA_64_VMS_COMCOD_WARNING:
3833 strcat (buf, ", warning");
3834 break;
3835 case EF_IA_64_VMS_COMCOD_ERROR:
3836 strcat (buf, ", error");
3837 break;
3838 case EF_IA_64_VMS_COMCOD_ABORT:
3839 strcat (buf, ", abort");
3840 break;
3841 default:
bee0ee85
NC
3842 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3843 e_flags & EF_IA_64_VMS_COMCOD);
3844 strcat (buf, ", <unknown>");
28f997cf
TG
3845 }
3846 }
4d6ed7c8 3847 break;
179d3252
JT
3848
3849 case EM_VAX:
3850 if ((e_flags & EF_VAX_NONPIC))
3851 strcat (buf, ", non-PIC");
3852 if ((e_flags & EF_VAX_DFLOAT))
3853 strcat (buf, ", D-Float");
3854 if ((e_flags & EF_VAX_GFLOAT))
3855 strcat (buf, ", G-Float");
3856 break;
c7927a3c 3857
619ed720
EB
3858 case EM_VISIUM:
3859 if (e_flags & EF_VISIUM_ARCH_MCM)
3860 strcat (buf, ", mcm");
3861 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3862 strcat (buf, ", mcm24");
3863 if (e_flags & EF_VISIUM_ARCH_GR6)
3864 strcat (buf, ", gr6");
3865 break;
3866
4046d87a 3867 case EM_RL78:
1740ba0c
NC
3868 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3869 {
3870 case E_FLAG_RL78_ANY_CPU: break;
3871 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3872 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3873 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3874 }
856ea05c
KP
3875 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3876 strcat (buf, ", 64-bit doubles");
4046d87a 3877 break;
0b4362b0 3878
c7927a3c
NC
3879 case EM_RX:
3880 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3881 strcat (buf, ", 64-bit doubles");
3882 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3883 strcat (buf, ", dsp");
d4cb0ea0 3884 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3885 strcat (buf, ", pid");
708e2187
NC
3886 if (e_flags & E_FLAG_RX_ABI)
3887 strcat (buf, ", RX ABI");
3525236c
NC
3888 if (e_flags & E_FLAG_RX_SINSNS_SET)
3889 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3890 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3891 if (e_flags & E_FLAG_RX_V2)
3892 strcat (buf, ", V2");
f87673e0
YS
3893 if (e_flags & E_FLAG_RX_V3)
3894 strcat (buf, ", V3");
d4cb0ea0 3895 break;
55786da2
AK
3896
3897 case EM_S390:
3898 if (e_flags & EF_S390_HIGH_GPRS)
3899 strcat (buf, ", highgprs");
d4cb0ea0 3900 break;
40b36596
JM
3901
3902 case EM_TI_C6000:
3903 if ((e_flags & EF_C6000_REL))
3904 strcat (buf, ", relocatable module");
d4cb0ea0 3905 break;
13761a11
NC
3906
3907 case EM_MSP430:
3908 strcat (buf, _(": architecture variant: "));
3909 switch (e_flags & EF_MSP430_MACH)
3910 {
3911 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3912 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3913 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3914 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3915 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3916 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3917 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3918 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3919 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3920 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3921 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3922 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3923 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3924 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3925 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3926 default:
3927 strcat (buf, _(": unknown")); break;
3928 }
3929
3930 if (e_flags & ~ EF_MSP430_MACH)
3931 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3932 break;
3933
3934 case EM_Z80:
3935 switch (e_flags & EF_Z80_MACH_MSK)
3936 {
3937 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3938 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3939 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3940 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3941 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3942 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3943 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3944 default:
3945 strcat (buf, _(", unknown")); break;
3946 }
3947 break;
252b5132
RH
3948 }
3949 }
3950
3951 return buf;
3952}
3953
252b5132 3954static const char *
dda8d76d 3955get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3956{
3957 static char buff[32];
3958
3959 switch (osabi)
3960 {
3961 case ELFOSABI_NONE: return "UNIX - System V";
3962 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3963 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3964 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3965 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3966 case ELFOSABI_AIX: return "UNIX - AIX";
3967 case ELFOSABI_IRIX: return "UNIX - IRIX";
3968 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3969 case ELFOSABI_TRU64: return "UNIX - TRU64";
3970 case ELFOSABI_MODESTO: return "Novell - Modesto";
3971 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3972 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3973 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3974 case ELFOSABI_AROS: return "AROS";
11636f9e 3975 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3976 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3977 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3978 default:
40b36596 3979 if (osabi >= 64)
dda8d76d 3980 switch (filedata->file_header.e_machine)
40b36596
JM
3981 {
3982 case EM_ARM:
3983 switch (osabi)
3984 {
3985 case ELFOSABI_ARM: return "ARM";
18a20338 3986 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3987 default:
3988 break;
3989 }
3990 break;
3991
3992 case EM_MSP430:
3993 case EM_MSP430_OLD:
619ed720 3994 case EM_VISIUM:
40b36596
JM
3995 switch (osabi)
3996 {
3997 case ELFOSABI_STANDALONE: return _("Standalone App");
3998 default:
3999 break;
4000 }
4001 break;
4002
4003 case EM_TI_C6000:
4004 switch (osabi)
4005 {
4006 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
4007 case ELFOSABI_C6000_LINUX: return "Linux C6000";
4008 default:
4009 break;
4010 }
4011 break;
4012
4013 default:
4014 break;
4015 }
e9e44622 4016 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
4017 return buff;
4018 }
4019}
4020
a06ea964
NC
4021static const char *
4022get_aarch64_segment_type (unsigned long type)
4023{
4024 switch (type)
4025 {
32ec8896
NC
4026 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
4027 default: return NULL;
a06ea964 4028 }
a06ea964
NC
4029}
4030
b294bdf8
MM
4031static const char *
4032get_arm_segment_type (unsigned long type)
4033{
4034 switch (type)
4035 {
32ec8896
NC
4036 case PT_ARM_EXIDX: return "EXIDX";
4037 default: return NULL;
b294bdf8 4038 }
b294bdf8
MM
4039}
4040
b4cbbe8f
AK
4041static const char *
4042get_s390_segment_type (unsigned long type)
4043{
4044 switch (type)
4045 {
4046 case PT_S390_PGSTE: return "S390_PGSTE";
4047 default: return NULL;
4048 }
4049}
4050
d3ba0551
AM
4051static const char *
4052get_mips_segment_type (unsigned long type)
252b5132
RH
4053{
4054 switch (type)
4055 {
32ec8896
NC
4056 case PT_MIPS_REGINFO: return "REGINFO";
4057 case PT_MIPS_RTPROC: return "RTPROC";
4058 case PT_MIPS_OPTIONS: return "OPTIONS";
4059 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
4060 default: return NULL;
252b5132 4061 }
252b5132
RH
4062}
4063
103f02d3 4064static const char *
d3ba0551 4065get_parisc_segment_type (unsigned long type)
103f02d3
UD
4066{
4067 switch (type)
4068 {
103f02d3
UD
4069 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
4070 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 4071 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 4072 default: return NULL;
103f02d3 4073 }
103f02d3
UD
4074}
4075
4d6ed7c8 4076static const char *
d3ba0551 4077get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
4078{
4079 switch (type)
4080 {
4081 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
4082 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 4083 default: return NULL;
4d6ed7c8 4084 }
4d6ed7c8
NC
4085}
4086
40b36596
JM
4087static const char *
4088get_tic6x_segment_type (unsigned long type)
4089{
4090 switch (type)
4091 {
32ec8896
NC
4092 case PT_C6000_PHATTR: return "C6000_PHATTR";
4093 default: return NULL;
40b36596 4094 }
40b36596
JM
4095}
4096
fbc95f1e
KC
4097static const char *
4098get_riscv_segment_type (unsigned long type)
4099{
4100 switch (type)
4101 {
4102 case PT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4103 default: return NULL;
4104 }
4105}
4106
df3a023b
AM
4107static const char *
4108get_hpux_segment_type (unsigned long type, unsigned e_machine)
4109{
4110 if (e_machine == EM_PARISC)
4111 switch (type)
4112 {
4113 case PT_HP_TLS: return "HP_TLS";
4114 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
4115 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
4116 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
4117 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
4118 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
4119 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
4120 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4121 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4122 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4123 case PT_HP_PARALLEL: return "HP_PARALLEL";
4124 case PT_HP_FASTBIND: return "HP_FASTBIND";
4125 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4126 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4127 case PT_HP_STACK: return "HP_STACK";
4128 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4129 default: return NULL;
4130 }
4131
4132 if (e_machine == EM_IA_64)
4133 switch (type)
4134 {
4135 case PT_HP_TLS: return "HP_TLS";
4136 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4137 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4138 case PT_IA_64_HP_STACK: return "HP_STACK";
4139 default: return NULL;
4140 }
4141
4142 return NULL;
4143}
4144
5522f910
NC
4145static const char *
4146get_solaris_segment_type (unsigned long type)
4147{
4148 switch (type)
4149 {
4150 case 0x6464e550: return "PT_SUNW_UNWIND";
4151 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4152 case 0x6ffffff7: return "PT_LOSUNW";
4153 case 0x6ffffffa: return "PT_SUNWBSS";
4154 case 0x6ffffffb: return "PT_SUNWSTACK";
4155 case 0x6ffffffc: return "PT_SUNWDTRACE";
4156 case 0x6ffffffd: return "PT_SUNWCAP";
4157 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4158 default: return NULL;
5522f910
NC
4159 }
4160}
4161
252b5132 4162static const char *
dda8d76d 4163get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4164{
b34976b6 4165 static char buff[32];
252b5132
RH
4166
4167 switch (p_type)
4168 {
b34976b6
AM
4169 case PT_NULL: return "NULL";
4170 case PT_LOAD: return "LOAD";
252b5132 4171 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4172 case PT_INTERP: return "INTERP";
4173 case PT_NOTE: return "NOTE";
4174 case PT_SHLIB: return "SHLIB";
4175 case PT_PHDR: return "PHDR";
13ae64f3 4176 case PT_TLS: return "TLS";
32ec8896 4177 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4178 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4179 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4180 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4181
3eba3ef3
NC
4182 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4183 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4184 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4185
252b5132 4186 default:
df3a023b 4187 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4188 {
2cf0635d 4189 const char * result;
103f02d3 4190
dda8d76d 4191 switch (filedata->file_header.e_machine)
252b5132 4192 {
a06ea964
NC
4193 case EM_AARCH64:
4194 result = get_aarch64_segment_type (p_type);
4195 break;
b294bdf8
MM
4196 case EM_ARM:
4197 result = get_arm_segment_type (p_type);
4198 break;
252b5132 4199 case EM_MIPS:
4fe85591 4200 case EM_MIPS_RS3_LE:
252b5132
RH
4201 result = get_mips_segment_type (p_type);
4202 break;
103f02d3
UD
4203 case EM_PARISC:
4204 result = get_parisc_segment_type (p_type);
4205 break;
4d6ed7c8
NC
4206 case EM_IA_64:
4207 result = get_ia64_segment_type (p_type);
4208 break;
40b36596
JM
4209 case EM_TI_C6000:
4210 result = get_tic6x_segment_type (p_type);
4211 break;
b4cbbe8f
AK
4212 case EM_S390:
4213 case EM_S390_OLD:
4214 result = get_s390_segment_type (p_type);
4215 break;
fbc95f1e
KC
4216 case EM_RISCV:
4217 result = get_riscv_segment_type (p_type);
4218 break;
252b5132
RH
4219 default:
4220 result = NULL;
4221 break;
4222 }
103f02d3 4223
252b5132
RH
4224 if (result != NULL)
4225 return result;
103f02d3 4226
1a9ccd70 4227 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4228 }
4229 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4230 {
df3a023b 4231 const char * result = NULL;
103f02d3 4232
df3a023b 4233 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4234 {
df3a023b
AM
4235 case ELFOSABI_GNU:
4236 case ELFOSABI_FREEBSD:
4237 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4238 {
4239 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4240 result = buff;
4241 }
103f02d3 4242 break;
df3a023b
AM
4243 case ELFOSABI_HPUX:
4244 result = get_hpux_segment_type (p_type,
4245 filedata->file_header.e_machine);
4246 break;
4247 case ELFOSABI_SOLARIS:
4248 result = get_solaris_segment_type (p_type);
00428cca 4249 break;
103f02d3 4250 default:
103f02d3
UD
4251 break;
4252 }
103f02d3
UD
4253 if (result != NULL)
4254 return result;
4255
1a9ccd70 4256 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4257 }
252b5132 4258 else
e9e44622 4259 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4260
4261 return buff;
4262 }
4263}
4264
53a346d8
CZ
4265static const char *
4266get_arc_section_type_name (unsigned int sh_type)
4267{
4268 switch (sh_type)
4269 {
4270 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4271 default:
4272 break;
4273 }
4274 return NULL;
4275}
4276
252b5132 4277static const char *
d3ba0551 4278get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4279{
4280 switch (sh_type)
4281 {
b34976b6
AM
4282 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4283 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4284 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4285 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4286 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4287 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4288 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4289 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4290 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4291 case SHT_MIPS_RELD: return "MIPS_RELD";
4292 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4293 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4294 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4295 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4296 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4297 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4298 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4299 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4300 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4301 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4302 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4303 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4304 case SHT_MIPS_LINE: return "MIPS_LINE";
4305 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4306 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4307 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4308 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4309 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4310 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4311 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4312 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4313 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4314 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4315 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4316 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4317 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4318 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4319 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4320 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4321 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4322 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4323 default:
4324 break;
4325 }
4326 return NULL;
4327}
4328
103f02d3 4329static const char *
d3ba0551 4330get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4331{
4332 switch (sh_type)
4333 {
4334 case SHT_PARISC_EXT: return "PARISC_EXT";
4335 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4336 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4337 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4338 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4339 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4340 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4341 default: return NULL;
103f02d3 4342 }
103f02d3
UD
4343}
4344
4d6ed7c8 4345static const char *
dda8d76d 4346get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4347{
18bd398b 4348 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4349 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4350 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4351
4d6ed7c8
NC
4352 switch (sh_type)
4353 {
148b93f2
NC
4354 case SHT_IA_64_EXT: return "IA_64_EXT";
4355 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4356 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4357 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4358 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4359 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4360 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4361 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4362 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4363 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4364 default:
4365 break;
4366 }
4367 return NULL;
4368}
4369
d2b2c203
DJ
4370static const char *
4371get_x86_64_section_type_name (unsigned int sh_type)
4372{
4373 switch (sh_type)
4374 {
4375 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4376 default: return NULL;
d2b2c203 4377 }
d2b2c203
DJ
4378}
4379
a06ea964
NC
4380static const char *
4381get_aarch64_section_type_name (unsigned int sh_type)
4382{
4383 switch (sh_type)
4384 {
32ec8896
NC
4385 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4386 default: return NULL;
a06ea964 4387 }
a06ea964
NC
4388}
4389
40a18ebd
NC
4390static const char *
4391get_arm_section_type_name (unsigned int sh_type)
4392{
4393 switch (sh_type)
4394 {
7f6fed87
NC
4395 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4396 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4397 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4398 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4399 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4400 default: return NULL;
40a18ebd 4401 }
40a18ebd
NC
4402}
4403
40b36596
JM
4404static const char *
4405get_tic6x_section_type_name (unsigned int sh_type)
4406{
4407 switch (sh_type)
4408 {
32ec8896
NC
4409 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4410 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4411 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4412 case SHT_TI_ICODE: return "TI_ICODE";
4413 case SHT_TI_XREF: return "TI_XREF";
4414 case SHT_TI_HANDLER: return "TI_HANDLER";
4415 case SHT_TI_INITINFO: return "TI_INITINFO";
4416 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4417 default: return NULL;
40b36596 4418 }
40b36596
JM
4419}
4420
13761a11 4421static const char *
b0191216 4422get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4423{
4424 switch (sh_type)
4425 {
32ec8896
NC
4426 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4427 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4428 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4429 default: return NULL;
13761a11
NC
4430 }
4431}
4432
fe944acf
FT
4433static const char *
4434get_nfp_section_type_name (unsigned int sh_type)
4435{
4436 switch (sh_type)
4437 {
4438 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4439 case SHT_NFP_INITREG: return "NFP_INITREG";
4440 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4441 default: return NULL;
4442 }
4443}
4444
685080f2
NC
4445static const char *
4446get_v850_section_type_name (unsigned int sh_type)
4447{
4448 switch (sh_type)
4449 {
32ec8896
NC
4450 case SHT_V850_SCOMMON: return "V850 Small Common";
4451 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4452 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4453 case SHT_RENESAS_IOP: return "RENESAS IOP";
4454 case SHT_RENESAS_INFO: return "RENESAS INFO";
4455 default: return NULL;
685080f2
NC
4456 }
4457}
4458
2dc8dd17
JW
4459static const char *
4460get_riscv_section_type_name (unsigned int sh_type)
4461{
4462 switch (sh_type)
4463 {
4464 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4465 default: return NULL;
4466 }
4467}
4468
0861f561
CQ
4469static const char *
4470get_csky_section_type_name (unsigned int sh_type)
4471{
4472 switch (sh_type)
4473 {
4474 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4475 default: return NULL;
4476 }
4477}
4478
252b5132 4479static const char *
dda8d76d 4480get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4481{
b34976b6 4482 static char buff[32];
9fb71ee4 4483 const char * result;
252b5132
RH
4484
4485 switch (sh_type)
4486 {
4487 case SHT_NULL: return "NULL";
4488 case SHT_PROGBITS: return "PROGBITS";
4489 case SHT_SYMTAB: return "SYMTAB";
4490 case SHT_STRTAB: return "STRTAB";
4491 case SHT_RELA: return "RELA";
4492 case SHT_HASH: return "HASH";
4493 case SHT_DYNAMIC: return "DYNAMIC";
4494 case SHT_NOTE: return "NOTE";
4495 case SHT_NOBITS: return "NOBITS";
4496 case SHT_REL: return "REL";
4497 case SHT_SHLIB: return "SHLIB";
4498 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4499 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4500 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4501 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4502 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4503 case SHT_GROUP: return "GROUP";
67ce483b 4504 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4505 case SHT_GNU_verdef: return "VERDEF";
4506 case SHT_GNU_verneed: return "VERNEED";
4507 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4508 case 0x6ffffff0: return "VERSYM";
4509 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4510 case 0x7ffffffd: return "AUXILIARY";
4511 case 0x7fffffff: return "FILTER";
047b2264 4512 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4513
4514 default:
4515 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4516 {
dda8d76d 4517 switch (filedata->file_header.e_machine)
252b5132 4518 {
53a346d8
CZ
4519 case EM_ARC:
4520 case EM_ARC_COMPACT:
4521 case EM_ARC_COMPACT2:
4522 result = get_arc_section_type_name (sh_type);
4523 break;
252b5132 4524 case EM_MIPS:
4fe85591 4525 case EM_MIPS_RS3_LE:
252b5132
RH
4526 result = get_mips_section_type_name (sh_type);
4527 break;
103f02d3
UD
4528 case EM_PARISC:
4529 result = get_parisc_section_type_name (sh_type);
4530 break;
4d6ed7c8 4531 case EM_IA_64:
dda8d76d 4532 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4533 break;
d2b2c203 4534 case EM_X86_64:
8a9036a4 4535 case EM_L1OM:
7a9068fe 4536 case EM_K1OM:
d2b2c203
DJ
4537 result = get_x86_64_section_type_name (sh_type);
4538 break;
a06ea964
NC
4539 case EM_AARCH64:
4540 result = get_aarch64_section_type_name (sh_type);
4541 break;
40a18ebd
NC
4542 case EM_ARM:
4543 result = get_arm_section_type_name (sh_type);
4544 break;
40b36596
JM
4545 case EM_TI_C6000:
4546 result = get_tic6x_section_type_name (sh_type);
4547 break;
13761a11 4548 case EM_MSP430:
b0191216 4549 result = get_msp430_section_type_name (sh_type);
13761a11 4550 break;
fe944acf
FT
4551 case EM_NFP:
4552 result = get_nfp_section_type_name (sh_type);
4553 break;
685080f2
NC
4554 case EM_V800:
4555 case EM_V850:
4556 case EM_CYGNUS_V850:
4557 result = get_v850_section_type_name (sh_type);
4558 break;
2dc8dd17
JW
4559 case EM_RISCV:
4560 result = get_riscv_section_type_name (sh_type);
4561 break;
0861f561
CQ
4562 case EM_CSKY:
4563 result = get_csky_section_type_name (sh_type);
4564 break;
252b5132
RH
4565 default:
4566 result = NULL;
4567 break;
4568 }
4569
4570 if (result != NULL)
4571 return result;
4572
9fb71ee4 4573 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4574 }
4575 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4576 {
dda8d76d 4577 switch (filedata->file_header.e_machine)
148b93f2
NC
4578 {
4579 case EM_IA_64:
dda8d76d 4580 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4581 break;
4582 default:
dda8d76d 4583 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4584 result = get_solaris_section_type (sh_type);
4585 else
1b4b80bf
NC
4586 {
4587 switch (sh_type)
4588 {
4589 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4590 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4591 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4592 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4593 default:
4594 result = NULL;
4595 break;
4596 }
4597 }
148b93f2
NC
4598 break;
4599 }
4600
4601 if (result != NULL)
4602 return result;
4603
9fb71ee4 4604 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4605 }
252b5132 4606 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4607 {
dda8d76d 4608 switch (filedata->file_header.e_machine)
685080f2
NC
4609 {
4610 case EM_V800:
4611 case EM_V850:
4612 case EM_CYGNUS_V850:
9fb71ee4 4613 result = get_v850_section_type_name (sh_type);
a9fb83be 4614 break;
685080f2 4615 default:
9fb71ee4 4616 result = NULL;
685080f2
NC
4617 break;
4618 }
4619
9fb71ee4
NC
4620 if (result != NULL)
4621 return result;
4622
4623 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4624 }
252b5132 4625 else
a7dbfd1c
NC
4626 /* This message is probably going to be displayed in a 15
4627 character wide field, so put the hex value first. */
4628 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4629
252b5132
RH
4630 return buff;
4631 }
4632}
4633
79bc120c
NC
4634enum long_option_values
4635{
4636 OPTION_DEBUG_DUMP = 512,
4637 OPTION_DYN_SYMS,
0f03783c 4638 OPTION_LTO_SYMS,
79bc120c
NC
4639 OPTION_DWARF_DEPTH,
4640 OPTION_DWARF_START,
4641 OPTION_DWARF_CHECK,
4642 OPTION_CTF_DUMP,
4643 OPTION_CTF_PARENT,
4644 OPTION_CTF_SYMBOLS,
4645 OPTION_CTF_STRINGS,
4646 OPTION_WITH_SYMBOL_VERSIONS,
4647 OPTION_RECURSE_LIMIT,
4648 OPTION_NO_RECURSE_LIMIT,
047c3dbf
NL
4649 OPTION_NO_DEMANGLING,
4650 OPTION_SYM_BASE
79bc120c 4651};
2979dc34 4652
85b1c36d 4653static struct option options[] =
252b5132 4654{
79bc120c
NC
4655 /* Note - This table is alpha-sorted on the 'val'
4656 field in order to make adding new options easier. */
4657 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4658 {"all", no_argument, 0, 'a'},
79bc120c
NC
4659 {"demangle", optional_argument, 0, 'C'},
4660 {"archive-index", no_argument, 0, 'c'},
4661 {"use-dynamic", no_argument, 0, 'D'},
4662 {"dynamic", no_argument, 0, 'd'},
b34976b6 4663 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4664 {"section-groups", no_argument, 0, 'g'},
4665 {"help", no_argument, 0, 'H'},
4666 {"file-header", no_argument, 0, 'h'},
b34976b6 4667 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4668 {"lint", no_argument, 0, 'L'},
4669 {"enable-checks", no_argument, 0, 'L'},
4670 {"program-headers", no_argument, 0, 'l'},
b34976b6 4671 {"segments", no_argument, 0, 'l'},
595cf52e 4672 {"full-section-name",no_argument, 0, 'N'},
79bc120c 4673 {"notes", no_argument, 0, 'n'},
ca0e11aa 4674 {"process-links", no_argument, 0, 'P'},
79bc120c
NC
4675 {"string-dump", required_argument, 0, 'p'},
4676 {"relocated-dump", required_argument, 0, 'R'},
4677 {"relocs", no_argument, 0, 'r'},
4678 {"section-headers", no_argument, 0, 'S'},
4679 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4680 {"symbols", no_argument, 0, 's'},
4681 {"syms", no_argument, 0, 's'},
79bc120c
NC
4682 {"silent-truncation",no_argument, 0, 'T'},
4683 {"section-details", no_argument, 0, 't'},
09c11c86 4684 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4685 {"version-info", no_argument, 0, 'V'},
4686 {"version", no_argument, 0, 'v'},
4687 {"wide", no_argument, 0, 'W'},
b34976b6 4688 {"hex-dump", required_argument, 0, 'x'},
0e602686 4689 {"decompress", no_argument, 0, 'z'},
252b5132 4690
79bc120c
NC
4691 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4692 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4693 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4694 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4695 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4696 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4697 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4698 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4699 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4700 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4701#ifdef ENABLE_LIBCTF
d344b407 4702 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4703 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4704 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4705 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4706#endif
047c3dbf 4707 {"sym-base", optional_argument, 0, OPTION_SYM_BASE},
7d9813f1 4708
b34976b6 4709 {0, no_argument, 0, 0}
252b5132
RH
4710};
4711
4712static void
2cf0635d 4713usage (FILE * stream)
252b5132 4714{
92f01d61
JM
4715 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4716 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
d6249f5f
AM
4717 fprintf (stream, _(" Options are:\n"));
4718 fprintf (stream, _("\
4719 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n"));
4720 fprintf (stream, _("\
4721 -h --file-header Display the ELF file header\n"));
4722 fprintf (stream, _("\
4723 -l --program-headers Display the program headers\n"));
4724 fprintf (stream, _("\
4725 --segments An alias for --program-headers\n"));
4726 fprintf (stream, _("\
4727 -S --section-headers Display the sections' header\n"));
4728 fprintf (stream, _("\
4729 --sections An alias for --section-headers\n"));
4730 fprintf (stream, _("\
4731 -g --section-groups Display the section groups\n"));
4732 fprintf (stream, _("\
4733 -t --section-details Display the section details\n"));
4734 fprintf (stream, _("\
4735 -e --headers Equivalent to: -h -l -S\n"));
4736 fprintf (stream, _("\
4737 -s --syms Display the symbol table\n"));
4738 fprintf (stream, _("\
4739 --symbols An alias for --syms\n"));
4740 fprintf (stream, _("\
4741 --dyn-syms Display the dynamic symbol table\n"));
4742 fprintf (stream, _("\
4743 --lto-syms Display LTO symbol tables\n"));
4744 fprintf (stream, _("\
047c3dbf
NL
4745 --sym-base=[0|8|10|16] \n\
4746 Force base for symbol sizes. The options are \n\
d6249f5f
AM
4747 mixed (the default), octal, decimal, hexadecimal.\n"));
4748 fprintf (stream, _("\
79bc120c
NC
4749 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4750 The STYLE, if specified, can be `auto' (the default),\n\
4751 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
d6249f5f
AM
4752 or `gnat'\n"));
4753 fprintf (stream, _("\
4754 --no-demangle Do not demangle low-level symbol names. (default)\n"));
4755 fprintf (stream, _("\
4756 --recurse-limit Enable a demangling recursion limit. (default)\n"));
4757 fprintf (stream, _("\
4758 --no-recurse-limit Disable a demangling recursion limit\n"));
4759 fprintf (stream, _("\
4760 -n --notes Display the core notes (if present)\n"));
4761 fprintf (stream, _("\
4762 -r --relocs Display the relocations (if present)\n"));
4763 fprintf (stream, _("\
4764 -u --unwind Display the unwind info (if present)\n"));
4765 fprintf (stream, _("\
4766 -d --dynamic Display the dynamic section (if present)\n"));
4767 fprintf (stream, _("\
4768 -V --version-info Display the version sections (if present)\n"));
4769 fprintf (stream, _("\
4770 -A --arch-specific Display architecture specific information (if any)\n"));
4771 fprintf (stream, _("\
4772 -c --archive-index Display the symbol/file index in an archive\n"));
4773 fprintf (stream, _("\
4774 -D --use-dynamic Use the dynamic section info when displaying symbols\n"));
4775 fprintf (stream, _("\
4776 -L --lint|--enable-checks\n\
4777 Display warning messages for possible problems\n"));
4778 fprintf (stream, _("\
09c11c86 4779 -x --hex-dump=<number|name>\n\
d6249f5f
AM
4780 Dump the contents of section <number|name> as bytes\n"));
4781 fprintf (stream, _("\
09c11c86 4782 -p --string-dump=<number|name>\n\
d6249f5f
AM
4783 Dump the contents of section <number|name> as strings\n"));
4784 fprintf (stream, _("\
cf13d699 4785 -R --relocated-dump=<number|name>\n\
d6249f5f
AM
4786 Dump the relocated contents of section <number|name>\n"));
4787 fprintf (stream, _("\
4788 -z --decompress Decompress section before dumping it\n"));
4789 fprintf (stream, _("\
4790 -w --debug-dump[a/=abbrev, A/=addr, r/=aranges, c/=cu_index, L/=decodedline,\n\
4791 f/=frames, F/=frames-interp, g/=gdb_index, i/=info, o/=loc,\n\
4792 m/=macro, p/=pubnames, t/=pubtypes, R/=Ranges, l/=rawline,\n\
4793 s/=str, O/=str-offsets, u/=trace_abbrev, T/=trace_aranges,\n\
4794 U/=trace_info]\n\
4795 Display the contents of DWARF debug sections\n"));
4796 fprintf (stream, _("\
4797 -wk --debug-dump=links Display the contents of sections that link to separate\n\
4798 debuginfo files\n"));
4799 fprintf (stream, _("\
4800 -P --process-links Display the contents of non-debug sections in separate\n\
4801 debuginfo files. (Implies -wK)\n"));
c46b7066
NC
4802#if DEFAULT_FOR_FOLLOW_LINKS
4803 fprintf (stream, _("\
d6249f5f
AM
4804 -wK --debug-dump=follow-links\n\
4805 Follow links to separate debug info files (default)\n"));
4806 fprintf (stream, _("\
4807 -wN --debug-dump=no-follow-links\n\
4808 Do not follow links to separate debug info files\n"));
c46b7066
NC
4809#else
4810 fprintf (stream, _("\
d6249f5f
AM
4811 -wK --debug-dump=follow-links\n\
4812 Follow links to separate debug info files\n"));
4813 fprintf (stream, _("\
4814 -wN --debug-dump=no-follow-links\n\
4815 Do not follow links to separate debug info files\n\
4816 (default)\n"));
c46b7066 4817#endif
fd2f0033 4818 fprintf (stream, _("\
d6249f5f
AM
4819 --dwarf-depth=N Do not display DIEs at depth N or greater\n"));
4820 fprintf (stream, _("\
4821 --dwarf-start=N Display DIEs starting at offset N\n"));
094e34f2 4822#ifdef ENABLE_LIBCTF
7d9813f1 4823 fprintf (stream, _("\
d6249f5f
AM
4824 --ctf=<number|name> Display CTF info from section <number|name>\n"));
4825 fprintf (stream, _("\
7d9813f1 4826 --ctf-parent=<number|name>\n\
d6249f5f
AM
4827 Use section <number|name> as the CTF parent\n"));
4828 fprintf (stream, _("\
7d9813f1 4829 --ctf-symbols=<number|name>\n\
d6249f5f
AM
4830 Use section <number|name> as the CTF external symtab\n"));
4831 fprintf (stream, _("\
7d9813f1 4832 --ctf-strings=<number|name>\n\
d6249f5f 4833 Use section <number|name> as the CTF external strtab\n"));
094e34f2 4834#endif
7d9813f1 4835
252b5132 4836#ifdef SUPPORT_DISASSEMBLY
92f01d61 4837 fprintf (stream, _("\
09c11c86
NC
4838 -i --instruction-dump=<number|name>\n\
4839 Disassemble the contents of section <number|name>\n"));
252b5132 4840#endif
92f01d61 4841 fprintf (stream, _("\
d6249f5f
AM
4842 -I --histogram Display histogram of bucket list lengths\n"));
4843 fprintf (stream, _("\
4844 -W --wide Allow output width to exceed 80 characters\n"));
4845 fprintf (stream, _("\
4846 -T --silent-truncation If a symbol name is truncated, do not add [...] suffix\n"));
4847 fprintf (stream, _("\
4848 @<file> Read options from <file>\n"));
4849 fprintf (stream, _("\
4850 -H --help Display this information\n"));
4851 fprintf (stream, _("\
8b53311e 4852 -v --version Display the version number of readelf\n"));
1118d252 4853
92f01d61
JM
4854 if (REPORT_BUGS_TO[0] && stream == stdout)
4855 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4856
92f01d61 4857 exit (stream == stdout ? 0 : 1);
252b5132
RH
4858}
4859
18bd398b
NC
4860/* Record the fact that the user wants the contents of section number
4861 SECTION to be displayed using the method(s) encoded as flags bits
4862 in TYPE. Note, TYPE can be zero if we are creating the array for
4863 the first time. */
4864
252b5132 4865static void
6431e409
AM
4866request_dump_bynumber (struct dump_data *dumpdata,
4867 unsigned int section, dump_type type)
252b5132 4868{
6431e409 4869 if (section >= dumpdata->num_dump_sects)
252b5132 4870 {
2cf0635d 4871 dump_type * new_dump_sects;
252b5132 4872
3f5e193b 4873 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4874 sizeof (* new_dump_sects));
252b5132
RH
4875
4876 if (new_dump_sects == NULL)
591a748a 4877 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4878 else
4879 {
6431e409 4880 if (dumpdata->dump_sects)
21b65bac
NC
4881 {
4882 /* Copy current flag settings. */
6431e409
AM
4883 memcpy (new_dump_sects, dumpdata->dump_sects,
4884 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4885
6431e409 4886 free (dumpdata->dump_sects);
21b65bac 4887 }
252b5132 4888
6431e409
AM
4889 dumpdata->dump_sects = new_dump_sects;
4890 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4891 }
4892 }
4893
6431e409
AM
4894 if (dumpdata->dump_sects)
4895 dumpdata->dump_sects[section] |= type;
252b5132
RH
4896}
4897
aef1f6d0
DJ
4898/* Request a dump by section name. */
4899
4900static void
2cf0635d 4901request_dump_byname (const char * section, dump_type type)
aef1f6d0 4902{
2cf0635d 4903 struct dump_list_entry * new_request;
aef1f6d0 4904
3f5e193b
NC
4905 new_request = (struct dump_list_entry *)
4906 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4907 if (!new_request)
591a748a 4908 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4909
4910 new_request->name = strdup (section);
4911 if (!new_request->name)
591a748a 4912 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4913
4914 new_request->type = type;
4915
4916 new_request->next = dump_sects_byname;
4917 dump_sects_byname = new_request;
4918}
4919
cf13d699 4920static inline void
6431e409 4921request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4922{
4923 int section;
4924 char * cp;
4925
015dc7e1 4926 do_dump = true;
cf13d699
NC
4927 section = strtoul (optarg, & cp, 0);
4928
4929 if (! *cp && section >= 0)
6431e409 4930 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4931 else
4932 request_dump_byname (optarg, type);
4933}
4934
252b5132 4935static void
6431e409 4936parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4937{
4938 int c;
4939
4940 if (argc < 2)
92f01d61 4941 usage (stderr);
252b5132
RH
4942
4943 while ((c = getopt_long
ca0e11aa 4944 (argc, argv, "ACDHILNPR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4945 {
252b5132
RH
4946 switch (c)
4947 {
4948 case 0:
4949 /* Long options. */
4950 break;
4951 case 'H':
92f01d61 4952 usage (stdout);
252b5132
RH
4953 break;
4954
4955 case 'a':
015dc7e1
AM
4956 do_syms = true;
4957 do_reloc = true;
4958 do_unwind = true;
4959 do_dynamic = true;
4960 do_header = true;
4961 do_sections = true;
4962 do_section_groups = true;
4963 do_segments = true;
4964 do_version = true;
4965 do_histogram = true;
4966 do_arch = true;
4967 do_notes = true;
252b5132 4968 break;
79bc120c 4969
f5842774 4970 case 'g':
015dc7e1 4971 do_section_groups = true;
f5842774 4972 break;
5477e8a0 4973 case 't':
595cf52e 4974 case 'N':
015dc7e1
AM
4975 do_sections = true;
4976 do_section_details = true;
595cf52e 4977 break;
252b5132 4978 case 'e':
015dc7e1
AM
4979 do_header = true;
4980 do_sections = true;
4981 do_segments = true;
252b5132 4982 break;
a952a375 4983 case 'A':
015dc7e1 4984 do_arch = true;
a952a375 4985 break;
252b5132 4986 case 'D':
015dc7e1 4987 do_using_dynamic = true;
252b5132
RH
4988 break;
4989 case 'r':
015dc7e1 4990 do_reloc = true;
252b5132 4991 break;
4d6ed7c8 4992 case 'u':
015dc7e1 4993 do_unwind = true;
4d6ed7c8 4994 break;
252b5132 4995 case 'h':
015dc7e1 4996 do_header = true;
252b5132
RH
4997 break;
4998 case 'l':
015dc7e1 4999 do_segments = true;
252b5132
RH
5000 break;
5001 case 's':
015dc7e1 5002 do_syms = true;
252b5132
RH
5003 break;
5004 case 'S':
015dc7e1 5005 do_sections = true;
252b5132
RH
5006 break;
5007 case 'd':
015dc7e1 5008 do_dynamic = true;
252b5132 5009 break;
a952a375 5010 case 'I':
015dc7e1 5011 do_histogram = true;
a952a375 5012 break;
779fe533 5013 case 'n':
015dc7e1 5014 do_notes = true;
779fe533 5015 break;
4145f1d5 5016 case 'c':
015dc7e1 5017 do_archive_index = true;
4145f1d5 5018 break;
1b513401 5019 case 'L':
015dc7e1 5020 do_checks = true;
1b513401 5021 break;
ca0e11aa 5022 case 'P':
015dc7e1
AM
5023 process_links = true;
5024 do_follow_links = true;
ca0e11aa 5025 break;
252b5132 5026 case 'x':
6431e409 5027 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 5028 break;
09c11c86 5029 case 'p':
6431e409 5030 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
5031 break;
5032 case 'R':
6431e409 5033 request_dump (dumpdata, RELOC_DUMP);
09c11c86 5034 break;
0e602686 5035 case 'z':
015dc7e1 5036 decompress_dumps = true;
0e602686 5037 break;
252b5132 5038 case 'w':
015dc7e1 5039 do_dump = true;
0f03783c 5040 if (optarg == NULL)
613ff48b 5041 {
015dc7e1 5042 do_debugging = true;
613ff48b
CC
5043 dwarf_select_sections_all ();
5044 }
252b5132
RH
5045 else
5046 {
015dc7e1 5047 do_debugging = false;
4cb93e3b 5048 dwarf_select_sections_by_letters (optarg);
252b5132
RH
5049 }
5050 break;
2979dc34 5051 case OPTION_DEBUG_DUMP:
015dc7e1 5052 do_dump = true;
0f03783c 5053 if (optarg == NULL)
d6249f5f
AM
5054 {
5055 do_debugging = true;
5056 dwarf_select_sections_all ();
5057 }
2979dc34
JJ
5058 else
5059 {
015dc7e1 5060 do_debugging = false;
4cb93e3b 5061 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
5062 }
5063 break;
fd2f0033
TT
5064 case OPTION_DWARF_DEPTH:
5065 {
5066 char *cp;
5067
5068 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
5069 }
5070 break;
5071 case OPTION_DWARF_START:
5072 {
5073 char *cp;
5074
5075 dwarf_start_die = strtoul (optarg, & cp, 0);
5076 }
5077 break;
4723351a 5078 case OPTION_DWARF_CHECK:
015dc7e1 5079 dwarf_check = true;
4723351a 5080 break;
7d9813f1 5081 case OPTION_CTF_DUMP:
015dc7e1 5082 do_ctf = true;
6431e409 5083 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
5084 break;
5085 case OPTION_CTF_SYMBOLS:
df16e041 5086 free (dump_ctf_symtab_name);
7d9813f1
NA
5087 dump_ctf_symtab_name = strdup (optarg);
5088 break;
5089 case OPTION_CTF_STRINGS:
df16e041 5090 free (dump_ctf_strtab_name);
7d9813f1
NA
5091 dump_ctf_strtab_name = strdup (optarg);
5092 break;
5093 case OPTION_CTF_PARENT:
df16e041 5094 free (dump_ctf_parent_name);
7d9813f1
NA
5095 dump_ctf_parent_name = strdup (optarg);
5096 break;
2c610e4b 5097 case OPTION_DYN_SYMS:
015dc7e1 5098 do_dyn_syms = true;
2c610e4b 5099 break;
0f03783c 5100 case OPTION_LTO_SYMS:
015dc7e1 5101 do_lto_syms = true;
0f03783c 5102 break;
252b5132
RH
5103#ifdef SUPPORT_DISASSEMBLY
5104 case 'i':
6431e409 5105 request_dump (dumpdata, DISASS_DUMP);
cf13d699 5106 break;
252b5132
RH
5107#endif
5108 case 'v':
5109 print_version (program_name);
5110 break;
5111 case 'V':
015dc7e1 5112 do_version = true;
252b5132 5113 break;
d974e256 5114 case 'W':
015dc7e1 5115 do_wide = true;
d974e256 5116 break;
0942c7ab 5117 case 'T':
015dc7e1 5118 do_not_show_symbol_truncation = true;
0942c7ab 5119 break;
79bc120c 5120 case 'C':
015dc7e1 5121 do_demangle = true;
79bc120c
NC
5122 if (optarg != NULL)
5123 {
5124 enum demangling_styles style;
5125
5126 style = cplus_demangle_name_to_style (optarg);
5127 if (style == unknown_demangling)
5128 error (_("unknown demangling style `%s'"), optarg);
5129
5130 cplus_demangle_set_style (style);
5131 }
5132 break;
5133 case OPTION_NO_DEMANGLING:
015dc7e1 5134 do_demangle = false;
79bc120c
NC
5135 break;
5136 case OPTION_RECURSE_LIMIT:
5137 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
5138 break;
5139 case OPTION_NO_RECURSE_LIMIT:
5140 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
5141 break;
5142 case OPTION_WITH_SYMBOL_VERSIONS:
5143 /* Ignored for backward compatibility. */
5144 break;
b9e920ec 5145
047c3dbf
NL
5146 case OPTION_SYM_BASE:
5147 sym_base = 0;
5148 if (optarg != NULL)
5149 {
5150 sym_base = strtoul (optarg, NULL, 0);
5151 switch (sym_base)
5152 {
5153 case 0:
5154 case 8:
5155 case 10:
5156 case 16:
5157 break;
5158
5159 default:
5160 sym_base = 0;
5161 break;
5162 }
5163 }
5164 break;
5165
252b5132 5166 default:
252b5132
RH
5167 /* xgettext:c-format */
5168 error (_("Invalid option '-%c'\n"), c);
1a0670f3 5169 /* Fall through. */
252b5132 5170 case '?':
92f01d61 5171 usage (stderr);
252b5132
RH
5172 }
5173 }
5174
4d6ed7c8 5175 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 5176 && !do_segments && !do_header && !do_dump && !do_version
f5842774 5177 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 5178 && !do_section_groups && !do_archive_index
0f03783c 5179 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
5180 {
5181 if (do_checks)
5182 {
015dc7e1
AM
5183 check_all = true;
5184 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = true;
5185 do_segments = do_header = do_dump = do_version = true;
5186 do_histogram = do_debugging = do_arch = do_notes = true;
5187 do_section_groups = do_archive_index = do_dyn_syms = true;
5188 do_lto_syms = true;
1b513401
NC
5189 }
5190 else
5191 usage (stderr);
5192 }
252b5132
RH
5193}
5194
5195static const char *
d3ba0551 5196get_elf_class (unsigned int elf_class)
252b5132 5197{
b34976b6 5198 static char buff[32];
103f02d3 5199
252b5132
RH
5200 switch (elf_class)
5201 {
5202 case ELFCLASSNONE: return _("none");
e3c8793a
NC
5203 case ELFCLASS32: return "ELF32";
5204 case ELFCLASS64: return "ELF64";
ab5e7794 5205 default:
e9e44622 5206 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 5207 return buff;
252b5132
RH
5208 }
5209}
5210
5211static const char *
d3ba0551 5212get_data_encoding (unsigned int encoding)
252b5132 5213{
b34976b6 5214 static char buff[32];
103f02d3 5215
252b5132
RH
5216 switch (encoding)
5217 {
5218 case ELFDATANONE: return _("none");
33c63f9d
CM
5219 case ELFDATA2LSB: return _("2's complement, little endian");
5220 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5221 default:
e9e44622 5222 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5223 return buff;
252b5132
RH
5224 }
5225}
5226
dda8d76d 5227/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5228
015dc7e1 5229static bool
dda8d76d 5230process_file_header (Filedata * filedata)
252b5132 5231{
dda8d76d
NC
5232 Elf_Internal_Ehdr * header = & filedata->file_header;
5233
5234 if ( header->e_ident[EI_MAG0] != ELFMAG0
5235 || header->e_ident[EI_MAG1] != ELFMAG1
5236 || header->e_ident[EI_MAG2] != ELFMAG2
5237 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5238 {
5239 error
5240 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
015dc7e1 5241 return false;
252b5132
RH
5242 }
5243
ca0e11aa
NC
5244 if (! filedata->is_separate)
5245 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5246
252b5132
RH
5247 if (do_header)
5248 {
32ec8896 5249 unsigned i;
252b5132 5250
ca0e11aa
NC
5251 if (filedata->is_separate)
5252 printf (_("ELF Header in linked file '%s':\n"), filedata->file_name);
5253 else
5254 printf (_("ELF Header:\n"));
252b5132 5255 printf (_(" Magic: "));
b34976b6 5256 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5257 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5258 printf ("\n");
5259 printf (_(" Class: %s\n"),
dda8d76d 5260 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5261 printf (_(" Data: %s\n"),
dda8d76d 5262 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5263 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5264 header->e_ident[EI_VERSION],
5265 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5266 ? _(" (current)")
dda8d76d 5267 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5268 ? _(" <unknown>")
789be9f7 5269 : "")));
252b5132 5270 printf (_(" OS/ABI: %s\n"),
dda8d76d 5271 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5272 printf (_(" ABI Version: %d\n"),
dda8d76d 5273 header->e_ident[EI_ABIVERSION]);
252b5132 5274 printf (_(" Type: %s\n"),
93df3340 5275 get_file_type (filedata));
252b5132 5276 printf (_(" Machine: %s\n"),
dda8d76d 5277 get_machine_name (header->e_machine));
252b5132 5278 printf (_(" Version: 0x%lx\n"),
e8a64888 5279 header->e_version);
76da6bbe 5280
f7a99963 5281 printf (_(" Entry point address: "));
e8a64888 5282 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5283 printf (_("\n Start of program headers: "));
e8a64888 5284 print_vma (header->e_phoff, DEC);
f7a99963 5285 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5286 print_vma (header->e_shoff, DEC);
f7a99963 5287 printf (_(" (bytes into file)\n"));
76da6bbe 5288
252b5132 5289 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5290 header->e_flags,
dda8d76d 5291 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5292 printf (_(" Size of this header: %u (bytes)\n"),
5293 header->e_ehsize);
5294 printf (_(" Size of program headers: %u (bytes)\n"),
5295 header->e_phentsize);
5296 printf (_(" Number of program headers: %u"),
5297 header->e_phnum);
dda8d76d
NC
5298 if (filedata->section_headers != NULL
5299 && header->e_phnum == PN_XNUM
5300 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5301 {
5302 header->e_phnum = filedata->section_headers[0].sh_info;
5303 printf (" (%u)", header->e_phnum);
5304 }
2046a35d 5305 putc ('\n', stdout);
e8a64888
AM
5306 printf (_(" Size of section headers: %u (bytes)\n"),
5307 header->e_shentsize);
5308 printf (_(" Number of section headers: %u"),
5309 header->e_shnum);
dda8d76d 5310 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5311 {
5312 header->e_shnum = filedata->section_headers[0].sh_size;
5313 printf (" (%u)", header->e_shnum);
5314 }
560f3c1c 5315 putc ('\n', stdout);
e8a64888
AM
5316 printf (_(" Section header string table index: %u"),
5317 header->e_shstrndx);
dda8d76d
NC
5318 if (filedata->section_headers != NULL
5319 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5320 {
5321 header->e_shstrndx = filedata->section_headers[0].sh_link;
5322 printf (" (%u)", header->e_shstrndx);
5323 }
5324 if (header->e_shstrndx != SHN_UNDEF
5325 && header->e_shstrndx >= header->e_shnum)
5326 {
5327 header->e_shstrndx = SHN_UNDEF;
5328 printf (_(" <corrupt: out of range>"));
5329 }
560f3c1c
AM
5330 putc ('\n', stdout);
5331 }
5332
dda8d76d 5333 if (filedata->section_headers != NULL)
560f3c1c 5334 {
dda8d76d
NC
5335 if (header->e_phnum == PN_XNUM
5336 && filedata->section_headers[0].sh_info != 0)
5337 header->e_phnum = filedata->section_headers[0].sh_info;
5338 if (header->e_shnum == SHN_UNDEF)
5339 header->e_shnum = filedata->section_headers[0].sh_size;
5340 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5341 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5342 if (header->e_shstrndx >= header->e_shnum)
dda8d76d 5343 header->e_shstrndx = SHN_UNDEF;
252b5132 5344 }
103f02d3 5345
015dc7e1 5346 return true;
9ea033b2
NC
5347}
5348
dda8d76d
NC
5349/* Read in the program headers from FILEDATA and store them in PHEADERS.
5350 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5351
015dc7e1 5352static bool
dda8d76d 5353get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5354{
2cf0635d
NC
5355 Elf32_External_Phdr * phdrs;
5356 Elf32_External_Phdr * external;
5357 Elf_Internal_Phdr * internal;
b34976b6 5358 unsigned int i;
dda8d76d
NC
5359 unsigned int size = filedata->file_header.e_phentsize;
5360 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5361
5362 /* PR binutils/17531: Cope with unexpected section header sizes. */
5363 if (size == 0 || num == 0)
015dc7e1 5364 return false;
e0a31db1
NC
5365 if (size < sizeof * phdrs)
5366 {
5367 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5368 return false;
e0a31db1
NC
5369 }
5370 if (size > sizeof * phdrs)
5371 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5372
dda8d76d 5373 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5374 size, num, _("program headers"));
5375 if (phdrs == NULL)
015dc7e1 5376 return false;
9ea033b2 5377
91d6fa6a 5378 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5379 i < filedata->file_header.e_phnum;
b34976b6 5380 i++, internal++, external++)
252b5132 5381 {
9ea033b2
NC
5382 internal->p_type = BYTE_GET (external->p_type);
5383 internal->p_offset = BYTE_GET (external->p_offset);
5384 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5385 internal->p_paddr = BYTE_GET (external->p_paddr);
5386 internal->p_filesz = BYTE_GET (external->p_filesz);
5387 internal->p_memsz = BYTE_GET (external->p_memsz);
5388 internal->p_flags = BYTE_GET (external->p_flags);
5389 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5390 }
5391
9ea033b2 5392 free (phdrs);
015dc7e1 5393 return true;
252b5132
RH
5394}
5395
dda8d76d
NC
5396/* Read in the program headers from FILEDATA and store them in PHEADERS.
5397 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5398
015dc7e1 5399static bool
dda8d76d 5400get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5401{
2cf0635d
NC
5402 Elf64_External_Phdr * phdrs;
5403 Elf64_External_Phdr * external;
5404 Elf_Internal_Phdr * internal;
b34976b6 5405 unsigned int i;
dda8d76d
NC
5406 unsigned int size = filedata->file_header.e_phentsize;
5407 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5408
5409 /* PR binutils/17531: Cope with unexpected section header sizes. */
5410 if (size == 0 || num == 0)
015dc7e1 5411 return false;
e0a31db1
NC
5412 if (size < sizeof * phdrs)
5413 {
5414 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
015dc7e1 5415 return false;
e0a31db1
NC
5416 }
5417 if (size > sizeof * phdrs)
5418 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5419
dda8d76d 5420 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5421 size, num, _("program headers"));
a6e9f9df 5422 if (!phdrs)
015dc7e1 5423 return false;
9ea033b2 5424
91d6fa6a 5425 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5426 i < filedata->file_header.e_phnum;
b34976b6 5427 i++, internal++, external++)
9ea033b2
NC
5428 {
5429 internal->p_type = BYTE_GET (external->p_type);
5430 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5431 internal->p_offset = BYTE_GET (external->p_offset);
5432 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5433 internal->p_paddr = BYTE_GET (external->p_paddr);
5434 internal->p_filesz = BYTE_GET (external->p_filesz);
5435 internal->p_memsz = BYTE_GET (external->p_memsz);
5436 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5437 }
5438
5439 free (phdrs);
015dc7e1 5440 return true;
9ea033b2 5441}
252b5132 5442
32ec8896 5443/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5444
015dc7e1 5445static bool
dda8d76d 5446get_program_headers (Filedata * filedata)
d93f0186 5447{
2cf0635d 5448 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5449
5450 /* Check cache of prior read. */
dda8d76d 5451 if (filedata->program_headers != NULL)
015dc7e1 5452 return true;
d93f0186 5453
82156ab7
NC
5454 /* Be kind to memory checkers by looking for
5455 e_phnum values which we know must be invalid. */
dda8d76d 5456 if (filedata->file_header.e_phnum
82156ab7 5457 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5458 >= filedata->file_size)
82156ab7
NC
5459 {
5460 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5461 filedata->file_header.e_phnum);
015dc7e1 5462 return false;
82156ab7 5463 }
d93f0186 5464
dda8d76d 5465 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5466 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5467 if (phdrs == NULL)
5468 {
8b73c356 5469 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5470 filedata->file_header.e_phnum);
015dc7e1 5471 return false;
d93f0186
NC
5472 }
5473
5474 if (is_32bit_elf
dda8d76d
NC
5475 ? get_32bit_program_headers (filedata, phdrs)
5476 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5477 {
dda8d76d 5478 filedata->program_headers = phdrs;
015dc7e1 5479 return true;
d93f0186
NC
5480 }
5481
5482 free (phdrs);
015dc7e1 5483 return false;
d93f0186
NC
5484}
5485
93df3340 5486/* Print program header info and locate dynamic section. */
2f62977e 5487
93df3340 5488static void
dda8d76d 5489process_program_headers (Filedata * filedata)
252b5132 5490{
2cf0635d 5491 Elf_Internal_Phdr * segment;
b34976b6 5492 unsigned int i;
1a9ccd70 5493 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5494
dda8d76d 5495 if (filedata->file_header.e_phnum == 0)
252b5132 5496 {
82f2dbf7 5497 /* PR binutils/12467. */
dda8d76d 5498 if (filedata->file_header.e_phoff != 0)
93df3340
AM
5499 warn (_("possibly corrupt ELF header - it has a non-zero program"
5500 " header offset, but no program headers\n"));
82f2dbf7 5501 else if (do_segments)
ca0e11aa
NC
5502 {
5503 if (filedata->is_separate)
5504 printf (_("\nThere are no program headers in linked file '%s'.\n"),
5505 filedata->file_name);
5506 else
5507 printf (_("\nThere are no program headers in this file.\n"));
5508 }
93df3340 5509 goto no_headers;
252b5132
RH
5510 }
5511
5512 if (do_segments && !do_header)
5513 {
ca0e11aa
NC
5514 if (filedata->is_separate)
5515 printf ("\nIn linked file '%s' the ELF file type is %s\n",
93df3340 5516 filedata->file_name, get_file_type (filedata));
ca0e11aa 5517 else
93df3340 5518 printf (_("\nElf file type is %s\n"), get_file_type (filedata));
dda8d76d 5519 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5520 printf (ngettext ("There is %d program header, starting at offset %s\n",
5521 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5522 filedata->file_header.e_phnum),
5523 filedata->file_header.e_phnum,
5524 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5525 }
5526
dda8d76d 5527 if (! get_program_headers (filedata))
93df3340 5528 goto no_headers;
103f02d3 5529
252b5132
RH
5530 if (do_segments)
5531 {
dda8d76d 5532 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5533 printf (_("\nProgram Headers:\n"));
5534 else
5535 printf (_("\nProgram Headers:\n"));
76da6bbe 5536
f7a99963
NC
5537 if (is_32bit_elf)
5538 printf
5539 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5540 else if (do_wide)
5541 printf
5542 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5543 else
5544 {
5545 printf
5546 (_(" Type Offset VirtAddr PhysAddr\n"));
5547 printf
5548 (_(" FileSiz MemSiz Flags Align\n"));
5549 }
252b5132
RH
5550 }
5551
93df3340
AM
5552 unsigned long dynamic_addr = 0;
5553 bfd_size_type dynamic_size = 0;
dda8d76d
NC
5554 for (i = 0, segment = filedata->program_headers;
5555 i < filedata->file_header.e_phnum;
b34976b6 5556 i++, segment++)
252b5132
RH
5557 {
5558 if (do_segments)
5559 {
dda8d76d 5560 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5561
5562 if (is_32bit_elf)
5563 {
5564 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5565 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5566 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5567 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5568 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5569 printf ("%c%c%c ",
5570 (segment->p_flags & PF_R ? 'R' : ' '),
5571 (segment->p_flags & PF_W ? 'W' : ' '),
5572 (segment->p_flags & PF_X ? 'E' : ' '));
5573 printf ("%#lx", (unsigned long) segment->p_align);
5574 }
d974e256
JJ
5575 else if (do_wide)
5576 {
5577 if ((unsigned long) segment->p_offset == segment->p_offset)
5578 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5579 else
5580 {
5581 print_vma (segment->p_offset, FULL_HEX);
5582 putchar (' ');
5583 }
5584
5585 print_vma (segment->p_vaddr, FULL_HEX);
5586 putchar (' ');
5587 print_vma (segment->p_paddr, FULL_HEX);
5588 putchar (' ');
5589
5590 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5591 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5592 else
5593 {
5594 print_vma (segment->p_filesz, FULL_HEX);
5595 putchar (' ');
5596 }
5597
5598 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5599 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5600 else
5601 {
f48e6c45 5602 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5603 }
5604
5605 printf (" %c%c%c ",
5606 (segment->p_flags & PF_R ? 'R' : ' '),
5607 (segment->p_flags & PF_W ? 'W' : ' '),
5608 (segment->p_flags & PF_X ? 'E' : ' '));
5609
5610 if ((unsigned long) segment->p_align == segment->p_align)
5611 printf ("%#lx", (unsigned long) segment->p_align);
5612 else
5613 {
5614 print_vma (segment->p_align, PREFIX_HEX);
5615 }
5616 }
f7a99963
NC
5617 else
5618 {
5619 print_vma (segment->p_offset, FULL_HEX);
5620 putchar (' ');
5621 print_vma (segment->p_vaddr, FULL_HEX);
5622 putchar (' ');
5623 print_vma (segment->p_paddr, FULL_HEX);
5624 printf ("\n ");
5625 print_vma (segment->p_filesz, FULL_HEX);
5626 putchar (' ');
5627 print_vma (segment->p_memsz, FULL_HEX);
5628 printf (" %c%c%c ",
5629 (segment->p_flags & PF_R ? 'R' : ' '),
5630 (segment->p_flags & PF_W ? 'W' : ' '),
5631 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5632 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5633 }
252b5132 5634
1a9ccd70
NC
5635 putc ('\n', stdout);
5636 }
f54498b4 5637
252b5132
RH
5638 switch (segment->p_type)
5639 {
1a9ccd70 5640 case PT_LOAD:
502d895c
NC
5641#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5642 required by the ELF standard, several programs, including the Linux
5643 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5644 if (previous_load
5645 && previous_load->p_vaddr > segment->p_vaddr)
5646 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5647#endif
1a9ccd70
NC
5648 if (segment->p_memsz < segment->p_filesz)
5649 error (_("the segment's file size is larger than its memory size\n"));
5650 previous_load = segment;
5651 break;
5652
5653 case PT_PHDR:
5654 /* PR 20815 - Verify that the program header is loaded into memory. */
5655 if (i > 0 && previous_load != NULL)
5656 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5657 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5658 {
5659 unsigned int j;
5660
dda8d76d 5661 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5662 {
5663 Elf_Internal_Phdr *load = filedata->program_headers + j;
5664 if (load->p_type == PT_LOAD
5665 && load->p_offset <= segment->p_offset
5666 && (load->p_offset + load->p_filesz
5667 >= segment->p_offset + segment->p_filesz)
5668 && load->p_vaddr <= segment->p_vaddr
5669 && (load->p_vaddr + load->p_filesz
5670 >= segment->p_vaddr + segment->p_filesz))
5671 break;
5672 }
dda8d76d 5673 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5674 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5675 }
5676 break;
5677
252b5132 5678 case PT_DYNAMIC:
93df3340 5679 if (dynamic_addr)
252b5132
RH
5680 error (_("more than one dynamic segment\n"));
5681
20737c13
AM
5682 /* By default, assume that the .dynamic section is the first
5683 section in the DYNAMIC segment. */
93df3340
AM
5684 dynamic_addr = segment->p_offset;
5685 dynamic_size = segment->p_filesz;
20737c13 5686
b2d38a17
NC
5687 /* Try to locate the .dynamic section. If there is
5688 a section header table, we can easily locate it. */
dda8d76d 5689 if (filedata->section_headers != NULL)
b2d38a17 5690 {
2cf0635d 5691 Elf_Internal_Shdr * sec;
b2d38a17 5692
dda8d76d 5693 sec = find_section (filedata, ".dynamic");
89fac5e3 5694 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5695 {
93df3340
AM
5696 /* A corresponding .dynamic section is expected, but on
5697 IA-64/OpenVMS it is OK for it to be missing. */
5698 if (!is_ia64_vms (filedata))
5699 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5700 break;
5701 }
5702
42bb2e33 5703 if (sec->sh_type == SHT_NOBITS)
20737c13 5704 {
93df3340
AM
5705 dynamic_addr = 0;
5706 dynamic_size = 0;
20737c13
AM
5707 break;
5708 }
42bb2e33 5709
93df3340
AM
5710 dynamic_addr = sec->sh_offset;
5711 dynamic_size = sec->sh_size;
b2d38a17 5712
8ac10c5b
L
5713 /* The PT_DYNAMIC segment, which is used by the run-time
5714 loader, should exactly match the .dynamic section. */
5715 if (do_checks
93df3340
AM
5716 && (dynamic_addr != segment->p_offset
5717 || dynamic_size != segment->p_filesz))
8ac10c5b
L
5718 warn (_("\
5719the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5720 }
39e224f6
MW
5721
5722 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5723 segment. Check this after matching against the section headers
5724 so we don't warn on debuginfo file (which have NOBITS .dynamic
5725 sections). */
93df3340
AM
5726 if (dynamic_addr > filedata->file_size
5727 || (dynamic_size > filedata->file_size - dynamic_addr))
39e224f6
MW
5728 {
5729 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
93df3340
AM
5730 dynamic_addr = 0;
5731 dynamic_size = 0;
39e224f6 5732 }
252b5132
RH
5733 break;
5734
5735 case PT_INTERP:
13acb58d
AM
5736 if (segment->p_offset >= filedata->file_size
5737 || segment->p_filesz > filedata->file_size - segment->p_offset
5738 || segment->p_filesz - 1 >= (size_t) -2
5739 || fseek (filedata->handle,
5740 filedata->archive_file_offset + (long) segment->p_offset,
5741 SEEK_SET))
252b5132
RH
5742 error (_("Unable to find program interpreter name\n"));
5743 else
5744 {
13acb58d
AM
5745 size_t len = segment->p_filesz;
5746 free (filedata->program_interpreter);
5747 filedata->program_interpreter = xmalloc (len + 1);
5748 len = fread (filedata->program_interpreter, 1, len,
5749 filedata->handle);
5750 filedata->program_interpreter[len] = 0;
252b5132
RH
5751
5752 if (do_segments)
f54498b4 5753 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5754 filedata->program_interpreter);
252b5132
RH
5755 }
5756 break;
5757 }
252b5132
RH
5758 }
5759
dda8d76d
NC
5760 if (do_segments
5761 && filedata->section_headers != NULL
5762 && filedata->string_table != NULL)
252b5132
RH
5763 {
5764 printf (_("\n Section to Segment mapping:\n"));
5765 printf (_(" Segment Sections...\n"));
5766
dda8d76d 5767 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5768 {
9ad5cbcf 5769 unsigned int j;
2cf0635d 5770 Elf_Internal_Shdr * section;
252b5132 5771
dda8d76d
NC
5772 segment = filedata->program_headers + i;
5773 section = filedata->section_headers + 1;
252b5132
RH
5774
5775 printf (" %2.2d ", i);
5776
dda8d76d 5777 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5778 {
f4638467
AM
5779 if (!ELF_TBSS_SPECIAL (section, segment)
5780 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5781 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5782 }
5783
5784 putc ('\n',stdout);
5785 }
5786 }
5787
93df3340
AM
5788 filedata->dynamic_addr = dynamic_addr;
5789 filedata->dynamic_size = dynamic_size ? dynamic_size : 1;
5790 return;
5791
5792 no_headers:
5793 filedata->dynamic_addr = 0;
5794 filedata->dynamic_size = 1;
252b5132
RH
5795}
5796
5797
d93f0186
NC
5798/* Find the file offset corresponding to VMA by using the program headers. */
5799
5800static long
dda8d76d 5801offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5802{
2cf0635d 5803 Elf_Internal_Phdr * seg;
d93f0186 5804
dda8d76d 5805 if (! get_program_headers (filedata))
d93f0186
NC
5806 {
5807 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5808 return (long) vma;
5809 }
5810
dda8d76d
NC
5811 for (seg = filedata->program_headers;
5812 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5813 ++seg)
5814 {
5815 if (seg->p_type != PT_LOAD)
5816 continue;
5817
5818 if (vma >= (seg->p_vaddr & -seg->p_align)
5819 && vma + size <= seg->p_vaddr + seg->p_filesz)
5820 return vma - seg->p_vaddr + seg->p_offset;
5821 }
5822
5823 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5824 (unsigned long) vma);
d93f0186
NC
5825 return (long) vma;
5826}
5827
5828
dda8d76d
NC
5829/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5830 If PROBE is true, this is just a probe and we do not generate any error
5831 messages if the load fails. */
049b0c3a 5832
015dc7e1
AM
5833static bool
5834get_32bit_section_headers (Filedata * filedata, bool probe)
252b5132 5835{
2cf0635d
NC
5836 Elf32_External_Shdr * shdrs;
5837 Elf_Internal_Shdr * internal;
dda8d76d
NC
5838 unsigned int i;
5839 unsigned int size = filedata->file_header.e_shentsize;
5840 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5841
5842 /* PR binutils/17531: Cope with unexpected section header sizes. */
5843 if (size == 0 || num == 0)
015dc7e1 5844 return false;
049b0c3a
NC
5845 if (size < sizeof * shdrs)
5846 {
5847 if (! probe)
5848 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5849 return false;
049b0c3a
NC
5850 }
5851 if (!probe && size > sizeof * shdrs)
5852 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5853
dda8d76d 5854 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5855 size, num,
5856 probe ? NULL : _("section headers"));
5857 if (shdrs == NULL)
015dc7e1 5858 return false;
252b5132 5859
dda8d76d
NC
5860 filedata->section_headers = (Elf_Internal_Shdr *)
5861 cmalloc (num, sizeof (Elf_Internal_Shdr));
5862 if (filedata->section_headers == NULL)
252b5132 5863 {
049b0c3a 5864 if (!probe)
8b73c356 5865 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5866 free (shdrs);
015dc7e1 5867 return false;
252b5132
RH
5868 }
5869
dda8d76d 5870 for (i = 0, internal = filedata->section_headers;
560f3c1c 5871 i < num;
b34976b6 5872 i++, internal++)
252b5132
RH
5873 {
5874 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5875 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5876 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5877 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5878 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5879 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5880 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5881 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5882 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5883 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5884 if (!probe && internal->sh_link > num)
5885 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5886 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5887 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5888 }
5889
5890 free (shdrs);
015dc7e1 5891 return true;
252b5132
RH
5892}
5893
dda8d76d
NC
5894/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5895
015dc7e1
AM
5896static bool
5897get_64bit_section_headers (Filedata * filedata, bool probe)
9ea033b2 5898{
dda8d76d
NC
5899 Elf64_External_Shdr * shdrs;
5900 Elf_Internal_Shdr * internal;
5901 unsigned int i;
5902 unsigned int size = filedata->file_header.e_shentsize;
5903 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5904
5905 /* PR binutils/17531: Cope with unexpected section header sizes. */
5906 if (size == 0 || num == 0)
015dc7e1 5907 return false;
dda8d76d 5908
049b0c3a
NC
5909 if (size < sizeof * shdrs)
5910 {
5911 if (! probe)
5912 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
015dc7e1 5913 return false;
049b0c3a 5914 }
dda8d76d 5915
049b0c3a
NC
5916 if (! probe && size > sizeof * shdrs)
5917 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5918
dda8d76d
NC
5919 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5920 filedata->file_header.e_shoff,
049b0c3a
NC
5921 size, num,
5922 probe ? NULL : _("section headers"));
5923 if (shdrs == NULL)
015dc7e1 5924 return false;
9ea033b2 5925
dda8d76d
NC
5926 filedata->section_headers = (Elf_Internal_Shdr *)
5927 cmalloc (num, sizeof (Elf_Internal_Shdr));
5928 if (filedata->section_headers == NULL)
9ea033b2 5929 {
049b0c3a 5930 if (! probe)
8b73c356 5931 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5932 free (shdrs);
015dc7e1 5933 return false;
9ea033b2
NC
5934 }
5935
dda8d76d 5936 for (i = 0, internal = filedata->section_headers;
560f3c1c 5937 i < num;
b34976b6 5938 i++, internal++)
9ea033b2
NC
5939 {
5940 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5941 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5942 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5943 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5944 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5945 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5946 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5947 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5948 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5949 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5950 if (!probe && internal->sh_link > num)
5951 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5952 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5953 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5954 }
5955
5956 free (shdrs);
015dc7e1 5957 return true;
9ea033b2
NC
5958}
5959
4de91c10
AM
5960static bool
5961get_section_headers (Filedata *filedata, bool probe)
5962{
5963 if (filedata->section_headers != NULL)
5964 return true;
5965
4de91c10
AM
5966 if (is_32bit_elf)
5967 return get_32bit_section_headers (filedata, probe);
5968 else
5969 return get_64bit_section_headers (filedata, probe);
5970}
5971
252b5132 5972static Elf_Internal_Sym *
dda8d76d
NC
5973get_32bit_elf_symbols (Filedata * filedata,
5974 Elf_Internal_Shdr * section,
5975 unsigned long * num_syms_return)
252b5132 5976{
ba5cdace 5977 unsigned long number = 0;
dd24e3da 5978 Elf32_External_Sym * esyms = NULL;
ba5cdace 5979 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5980 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5981 Elf_Internal_Sym * psym;
b34976b6 5982 unsigned int j;
e3d39609 5983 elf_section_list * entry;
252b5132 5984
c9c1d674
EG
5985 if (section->sh_size == 0)
5986 {
5987 if (num_syms_return != NULL)
5988 * num_syms_return = 0;
5989 return NULL;
5990 }
5991
dd24e3da 5992 /* Run some sanity checks first. */
c9c1d674 5993 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5994 {
c9c1d674 5995 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5996 printable_section_name (filedata, section),
5997 (unsigned long) section->sh_entsize);
ba5cdace 5998 goto exit_point;
dd24e3da
NC
5999 }
6000
dda8d76d 6001 if (section->sh_size > filedata->file_size)
f54498b4
NC
6002 {
6003 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
6004 printable_section_name (filedata, section),
6005 (unsigned long) section->sh_size);
f54498b4
NC
6006 goto exit_point;
6007 }
6008
dd24e3da
NC
6009 number = section->sh_size / section->sh_entsize;
6010
6011 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
6012 {
c9c1d674 6013 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6014 (unsigned long) section->sh_size,
dda8d76d 6015 printable_section_name (filedata, section),
8066deb1 6016 (unsigned long) section->sh_entsize);
ba5cdace 6017 goto exit_point;
dd24e3da
NC
6018 }
6019
dda8d76d 6020 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6021 section->sh_size, _("symbols"));
dd24e3da 6022 if (esyms == NULL)
ba5cdace 6023 goto exit_point;
252b5132 6024
e3d39609 6025 shndx = NULL;
978c4450 6026 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6027 {
6028 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6029 continue;
6030
6031 if (shndx != NULL)
6032 {
6033 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6034 free (shndx);
6035 }
6036
6037 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6038 entry->hdr->sh_offset,
6039 1, entry->hdr->sh_size,
6040 _("symbol table section indices"));
6041 if (shndx == NULL)
6042 goto exit_point;
6043
6044 /* PR17531: file: heap-buffer-overflow */
6045 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6046 {
6047 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6048 printable_section_name (filedata, entry->hdr),
6049 (unsigned long) entry->hdr->sh_size,
6050 (unsigned long) section->sh_size);
6051 goto exit_point;
c9c1d674 6052 }
e3d39609 6053 }
9ad5cbcf 6054
3f5e193b 6055 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
6056
6057 if (isyms == NULL)
6058 {
8b73c356
NC
6059 error (_("Out of memory reading %lu symbols\n"),
6060 (unsigned long) number);
dd24e3da 6061 goto exit_point;
252b5132
RH
6062 }
6063
dd24e3da 6064 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
6065 {
6066 psym->st_name = BYTE_GET (esyms[j].st_name);
6067 psym->st_value = BYTE_GET (esyms[j].st_value);
6068 psym->st_size = BYTE_GET (esyms[j].st_size);
6069 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 6070 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6071 psym->st_shndx
6072 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6073 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6074 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
6075 psym->st_info = BYTE_GET (esyms[j].st_info);
6076 psym->st_other = BYTE_GET (esyms[j].st_other);
6077 }
6078
dd24e3da 6079 exit_point:
e3d39609
NC
6080 free (shndx);
6081 free (esyms);
252b5132 6082
ba5cdace
NC
6083 if (num_syms_return != NULL)
6084 * num_syms_return = isyms == NULL ? 0 : number;
6085
252b5132
RH
6086 return isyms;
6087}
6088
9ea033b2 6089static Elf_Internal_Sym *
dda8d76d
NC
6090get_64bit_elf_symbols (Filedata * filedata,
6091 Elf_Internal_Shdr * section,
6092 unsigned long * num_syms_return)
9ea033b2 6093{
ba5cdace
NC
6094 unsigned long number = 0;
6095 Elf64_External_Sym * esyms = NULL;
6096 Elf_External_Sym_Shndx * shndx = NULL;
6097 Elf_Internal_Sym * isyms = NULL;
2cf0635d 6098 Elf_Internal_Sym * psym;
b34976b6 6099 unsigned int j;
e3d39609 6100 elf_section_list * entry;
9ea033b2 6101
c9c1d674
EG
6102 if (section->sh_size == 0)
6103 {
6104 if (num_syms_return != NULL)
6105 * num_syms_return = 0;
6106 return NULL;
6107 }
6108
dd24e3da 6109 /* Run some sanity checks first. */
c9c1d674 6110 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 6111 {
c9c1d674 6112 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 6113 printable_section_name (filedata, section),
8066deb1 6114 (unsigned long) section->sh_entsize);
ba5cdace 6115 goto exit_point;
dd24e3da
NC
6116 }
6117
dda8d76d 6118 if (section->sh_size > filedata->file_size)
f54498b4
NC
6119 {
6120 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 6121 printable_section_name (filedata, section),
8066deb1 6122 (unsigned long) section->sh_size);
f54498b4
NC
6123 goto exit_point;
6124 }
6125
dd24e3da
NC
6126 number = section->sh_size / section->sh_entsize;
6127
6128 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
6129 {
c9c1d674 6130 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 6131 (unsigned long) section->sh_size,
dda8d76d 6132 printable_section_name (filedata, section),
8066deb1 6133 (unsigned long) section->sh_entsize);
ba5cdace 6134 goto exit_point;
dd24e3da
NC
6135 }
6136
dda8d76d 6137 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 6138 section->sh_size, _("symbols"));
a6e9f9df 6139 if (!esyms)
ba5cdace 6140 goto exit_point;
9ea033b2 6141
e3d39609 6142 shndx = NULL;
978c4450 6143 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
6144 {
6145 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
6146 continue;
6147
6148 if (shndx != NULL)
6149 {
6150 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
6151 free (shndx);
c9c1d674 6152 }
e3d39609
NC
6153
6154 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
6155 entry->hdr->sh_offset,
6156 1, entry->hdr->sh_size,
6157 _("symbol table section indices"));
6158 if (shndx == NULL)
6159 goto exit_point;
6160
6161 /* PR17531: file: heap-buffer-overflow */
6162 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
6163 {
6164 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
6165 printable_section_name (filedata, entry->hdr),
6166 (unsigned long) entry->hdr->sh_size,
6167 (unsigned long) section->sh_size);
6168 goto exit_point;
6169 }
6170 }
9ad5cbcf 6171
3f5e193b 6172 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
6173
6174 if (isyms == NULL)
6175 {
8b73c356
NC
6176 error (_("Out of memory reading %lu symbols\n"),
6177 (unsigned long) number);
ba5cdace 6178 goto exit_point;
9ea033b2
NC
6179 }
6180
ba5cdace 6181 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
6182 {
6183 psym->st_name = BYTE_GET (esyms[j].st_name);
6184 psym->st_info = BYTE_GET (esyms[j].st_info);
6185 psym->st_other = BYTE_GET (esyms[j].st_other);
6186 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 6187
4fbb74a6 6188 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
6189 psym->st_shndx
6190 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
6191 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
6192 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 6193
66543521
AM
6194 psym->st_value = BYTE_GET (esyms[j].st_value);
6195 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
6196 }
6197
ba5cdace 6198 exit_point:
e3d39609
NC
6199 free (shndx);
6200 free (esyms);
ba5cdace
NC
6201
6202 if (num_syms_return != NULL)
6203 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
6204
6205 return isyms;
6206}
6207
4de91c10
AM
6208static Elf_Internal_Sym *
6209get_elf_symbols (Filedata *filedata,
6210 Elf_Internal_Shdr *section,
6211 unsigned long *num_syms_return)
6212{
6213 if (is_32bit_elf)
6214 return get_32bit_elf_symbols (filedata, section, num_syms_return);
6215 else
6216 return get_64bit_elf_symbols (filedata, section, num_syms_return);
6217}
6218
d1133906 6219static const char *
dda8d76d 6220get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 6221{
5477e8a0 6222 static char buff[1024];
2cf0635d 6223 char * p = buff;
32ec8896
NC
6224 unsigned int field_size = is_32bit_elf ? 8 : 16;
6225 signed int sindex;
6226 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
6227 bfd_vma os_flags = 0;
6228 bfd_vma proc_flags = 0;
6229 bfd_vma unknown_flags = 0;
148b93f2 6230 static const struct
5477e8a0 6231 {
2cf0635d 6232 const char * str;
32ec8896 6233 unsigned int len;
5477e8a0
L
6234 }
6235 flags [] =
6236 {
cfcac11d
NC
6237 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
6238 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
6239 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
6240 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
6241 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
6242 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
6243 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
6244 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
6245 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
6246 /* 9 */ { STRING_COMMA_LEN ("TLS") },
6247 /* IA-64 specific. */
6248 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
6249 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
6250 /* IA-64 OpenVMS specific. */
6251 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
6252 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
6253 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
6254 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6255 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6256 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6257 /* Generic. */
cfcac11d 6258 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6259 /* SPARC specific. */
77115a4a 6260 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6261 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6262 /* ARM specific. */
6263 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6264 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6265 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6266 /* GNU specific. */
6267 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6268 /* VLE specific. */
6269 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6270 /* GNU specific. */
6271 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6272 };
6273
6274 if (do_section_details)
6275 {
8d5ff12c
L
6276 sprintf (buff, "[%*.*lx]: ",
6277 field_size, field_size, (unsigned long) sh_flags);
6278 p += field_size + 4;
5477e8a0 6279 }
76da6bbe 6280
d1133906
NC
6281 while (sh_flags)
6282 {
6283 bfd_vma flag;
6284
6285 flag = sh_flags & - sh_flags;
6286 sh_flags &= ~ flag;
76da6bbe 6287
5477e8a0 6288 if (do_section_details)
d1133906 6289 {
5477e8a0
L
6290 switch (flag)
6291 {
91d6fa6a
NC
6292 case SHF_WRITE: sindex = 0; break;
6293 case SHF_ALLOC: sindex = 1; break;
6294 case SHF_EXECINSTR: sindex = 2; break;
6295 case SHF_MERGE: sindex = 3; break;
6296 case SHF_STRINGS: sindex = 4; break;
6297 case SHF_INFO_LINK: sindex = 5; break;
6298 case SHF_LINK_ORDER: sindex = 6; break;
6299 case SHF_OS_NONCONFORMING: sindex = 7; break;
6300 case SHF_GROUP: sindex = 8; break;
6301 case SHF_TLS: sindex = 9; break;
18ae9cc1 6302 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6303 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6304
5477e8a0 6305 default:
91d6fa6a 6306 sindex = -1;
dda8d76d 6307 switch (filedata->file_header.e_machine)
148b93f2 6308 {
cfcac11d 6309 case EM_IA_64:
148b93f2 6310 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6311 sindex = 10;
148b93f2 6312 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6313 sindex = 11;
148b93f2 6314#ifdef BFD64
dda8d76d 6315 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6316 switch (flag)
6317 {
91d6fa6a
NC
6318 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6319 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6320 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6321 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6322 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6323 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6324 default: break;
6325 }
6326#endif
cfcac11d
NC
6327 break;
6328
caa83f8b 6329 case EM_386:
22abe556 6330 case EM_IAMCU:
caa83f8b 6331 case EM_X86_64:
7f502d6c 6332 case EM_L1OM:
7a9068fe 6333 case EM_K1OM:
cfcac11d
NC
6334 case EM_OLD_SPARCV9:
6335 case EM_SPARC32PLUS:
6336 case EM_SPARCV9:
6337 case EM_SPARC:
18ae9cc1 6338 if (flag == SHF_ORDERED)
91d6fa6a 6339 sindex = 19;
cfcac11d 6340 break;
ac4c9b04
MG
6341
6342 case EM_ARM:
6343 switch (flag)
6344 {
6345 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6346 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6347 case SHF_COMDEF: sindex = 23; break;
6348 default: break;
6349 }
6350 break;
83eef883
AFB
6351 case EM_PPC:
6352 if (flag == SHF_PPC_VLE)
6353 sindex = 25;
6354 break;
99fabbc9
JL
6355 default:
6356 break;
6357 }
ac4c9b04 6358
99fabbc9
JL
6359 switch (filedata->file_header.e_ident[EI_OSABI])
6360 {
6361 case ELFOSABI_GNU:
6362 case ELFOSABI_FREEBSD:
6363 if (flag == SHF_GNU_RETAIN)
6364 sindex = 26;
6365 /* Fall through */
6366 case ELFOSABI_NONE:
6367 if (flag == SHF_GNU_MBIND)
6368 /* We should not recognize SHF_GNU_MBIND for
6369 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6370 not set the EI_OSABI header byte. */
6371 sindex = 24;
6372 break;
cfcac11d
NC
6373 default:
6374 break;
148b93f2 6375 }
99fabbc9 6376 break;
5477e8a0
L
6377 }
6378
91d6fa6a 6379 if (sindex != -1)
5477e8a0 6380 {
8d5ff12c
L
6381 if (p != buff + field_size + 4)
6382 {
6383 if (size < (10 + 2))
bee0ee85
NC
6384 {
6385 warn (_("Internal error: not enough buffer room for section flag info"));
6386 return _("<unknown>");
6387 }
8d5ff12c
L
6388 size -= 2;
6389 *p++ = ',';
6390 *p++ = ' ';
6391 }
6392
91d6fa6a
NC
6393 size -= flags [sindex].len;
6394 p = stpcpy (p, flags [sindex].str);
5477e8a0 6395 }
3b22753a 6396 else if (flag & SHF_MASKOS)
8d5ff12c 6397 os_flags |= flag;
d1133906 6398 else if (flag & SHF_MASKPROC)
8d5ff12c 6399 proc_flags |= flag;
d1133906 6400 else
8d5ff12c 6401 unknown_flags |= flag;
5477e8a0
L
6402 }
6403 else
6404 {
6405 switch (flag)
6406 {
6407 case SHF_WRITE: *p = 'W'; break;
6408 case SHF_ALLOC: *p = 'A'; break;
6409 case SHF_EXECINSTR: *p = 'X'; break;
6410 case SHF_MERGE: *p = 'M'; break;
6411 case SHF_STRINGS: *p = 'S'; break;
6412 case SHF_INFO_LINK: *p = 'I'; break;
6413 case SHF_LINK_ORDER: *p = 'L'; break;
6414 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6415 case SHF_GROUP: *p = 'G'; break;
6416 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6417 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6418 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6419
6420 default:
dda8d76d
NC
6421 if ((filedata->file_header.e_machine == EM_X86_64
6422 || filedata->file_header.e_machine == EM_L1OM
6423 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6424 && flag == SHF_X86_64_LARGE)
6425 *p = 'l';
dda8d76d 6426 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6427 && flag == SHF_ARM_PURECODE)
99fabbc9 6428 *p = 'y';
dda8d76d 6429 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6430 && flag == SHF_PPC_VLE)
99fabbc9 6431 *p = 'v';
5477e8a0
L
6432 else if (flag & SHF_MASKOS)
6433 {
99fabbc9
JL
6434 switch (filedata->file_header.e_ident[EI_OSABI])
6435 {
6436 case ELFOSABI_GNU:
6437 case ELFOSABI_FREEBSD:
6438 if (flag == SHF_GNU_RETAIN)
6439 {
6440 *p = 'R';
6441 break;
6442 }
6443 /* Fall through */
6444 case ELFOSABI_NONE:
6445 if (flag == SHF_GNU_MBIND)
6446 {
6447 /* We should not recognize SHF_GNU_MBIND for
6448 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6449 not set the EI_OSABI header byte. */
6450 *p = 'D';
6451 break;
6452 }
6453 /* Fall through */
6454 default:
6455 *p = 'o';
6456 sh_flags &= ~SHF_MASKOS;
6457 break;
6458 }
5477e8a0
L
6459 }
6460 else if (flag & SHF_MASKPROC)
6461 {
6462 *p = 'p';
6463 sh_flags &= ~ SHF_MASKPROC;
6464 }
6465 else
6466 *p = 'x';
6467 break;
6468 }
6469 p++;
d1133906
NC
6470 }
6471 }
76da6bbe 6472
8d5ff12c
L
6473 if (do_section_details)
6474 {
6475 if (os_flags)
6476 {
6477 size -= 5 + field_size;
6478 if (p != buff + field_size + 4)
6479 {
6480 if (size < (2 + 1))
bee0ee85
NC
6481 {
6482 warn (_("Internal error: not enough buffer room for section flag info"));
6483 return _("<unknown>");
6484 }
8d5ff12c
L
6485 size -= 2;
6486 *p++ = ',';
6487 *p++ = ' ';
6488 }
6489 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6490 (unsigned long) os_flags);
6491 p += 5 + field_size;
6492 }
6493 if (proc_flags)
6494 {
6495 size -= 7 + field_size;
6496 if (p != buff + field_size + 4)
6497 {
6498 if (size < (2 + 1))
bee0ee85
NC
6499 {
6500 warn (_("Internal error: not enough buffer room for section flag info"));
6501 return _("<unknown>");
6502 }
8d5ff12c
L
6503 size -= 2;
6504 *p++ = ',';
6505 *p++ = ' ';
6506 }
6507 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6508 (unsigned long) proc_flags);
6509 p += 7 + field_size;
6510 }
6511 if (unknown_flags)
6512 {
6513 size -= 10 + field_size;
6514 if (p != buff + field_size + 4)
6515 {
6516 if (size < (2 + 1))
bee0ee85
NC
6517 {
6518 warn (_("Internal error: not enough buffer room for section flag info"));
6519 return _("<unknown>");
6520 }
8d5ff12c
L
6521 size -= 2;
6522 *p++ = ',';
6523 *p++ = ' ';
6524 }
2b692964 6525 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6526 (unsigned long) unknown_flags);
6527 p += 10 + field_size;
6528 }
6529 }
6530
e9e44622 6531 *p = '\0';
d1133906
NC
6532 return buff;
6533}
6534
5844b465 6535static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6536get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6537{
6538 if (is_32bit_elf)
6539 {
6540 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6541
ebdf1ebf
NC
6542 if (size < sizeof (* echdr))
6543 {
6544 error (_("Compressed section is too small even for a compression header\n"));
6545 return 0;
6546 }
6547
77115a4a
L
6548 chdr->ch_type = BYTE_GET (echdr->ch_type);
6549 chdr->ch_size = BYTE_GET (echdr->ch_size);
6550 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6551 return sizeof (*echdr);
6552 }
6553 else
6554 {
6555 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6556
ebdf1ebf
NC
6557 if (size < sizeof (* echdr))
6558 {
6559 error (_("Compressed section is too small even for a compression header\n"));
6560 return 0;
6561 }
6562
77115a4a
L
6563 chdr->ch_type = BYTE_GET (echdr->ch_type);
6564 chdr->ch_size = BYTE_GET (echdr->ch_size);
6565 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6566 return sizeof (*echdr);
6567 }
6568}
6569
015dc7e1 6570static bool
dda8d76d 6571process_section_headers (Filedata * filedata)
252b5132 6572{
2cf0635d 6573 Elf_Internal_Shdr * section;
b34976b6 6574 unsigned int i;
252b5132 6575
dda8d76d 6576 if (filedata->file_header.e_shnum == 0)
252b5132 6577 {
82f2dbf7 6578 /* PR binutils/12467. */
dda8d76d 6579 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6580 {
6581 warn (_("possibly corrupt ELF file header - it has a non-zero"
6582 " section header offset, but no section headers\n"));
015dc7e1 6583 return false;
32ec8896 6584 }
82f2dbf7 6585 else if (do_sections)
252b5132
RH
6586 printf (_("\nThere are no sections in this file.\n"));
6587
015dc7e1 6588 return true;
252b5132
RH
6589 }
6590
6591 if (do_sections && !do_header)
ca0e11aa
NC
6592 {
6593 if (filedata->is_separate && process_links)
6594 printf (_("In linked file '%s': "), filedata->file_name);
6595 if (! filedata->is_separate || process_links)
6596 printf (ngettext ("There is %d section header, "
6597 "starting at offset 0x%lx:\n",
6598 "There are %d section headers, "
6599 "starting at offset 0x%lx:\n",
6600 filedata->file_header.e_shnum),
6601 filedata->file_header.e_shnum,
6602 (unsigned long) filedata->file_header.e_shoff);
6603 }
252b5132 6604
4de91c10
AM
6605 if (!get_section_headers (filedata, false))
6606 return false;
252b5132
RH
6607
6608 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6609 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6610 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6611 {
dda8d76d 6612 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6613
c256ffe7
JJ
6614 if (section->sh_size != 0)
6615 {
dda8d76d
NC
6616 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6617 1, section->sh_size,
6618 _("string table"));
0de14b54 6619
dda8d76d 6620 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6621 }
252b5132
RH
6622 }
6623
6624 /* Scan the sections for the dynamic symbol table
e3c8793a 6625 and dynamic string table and debug sections. */
89fac5e3 6626 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6627 switch (filedata->file_header.e_machine)
89fac5e3
RS
6628 {
6629 case EM_MIPS:
6630 case EM_MIPS_RS3_LE:
6631 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6632 FDE addresses. However, the ABI also has a semi-official ILP32
6633 variant for which the normal FDE address size rules apply.
6634
6635 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6636 section, where XX is the size of longs in bits. Unfortunately,
6637 earlier compilers provided no way of distinguishing ILP32 objects
6638 from LP64 objects, so if there's any doubt, we should assume that
6639 the official LP64 form is being used. */
dda8d76d
NC
6640 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6641 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6642 eh_addr_size = 8;
6643 break;
0f56a26a
DD
6644
6645 case EM_H8_300:
6646 case EM_H8_300H:
dda8d76d 6647 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6648 {
6649 case E_H8_MACH_H8300:
6650 case E_H8_MACH_H8300HN:
6651 case E_H8_MACH_H8300SN:
6652 case E_H8_MACH_H8300SXN:
6653 eh_addr_size = 2;
6654 break;
6655 case E_H8_MACH_H8300H:
6656 case E_H8_MACH_H8300S:
6657 case E_H8_MACH_H8300SX:
6658 eh_addr_size = 4;
6659 break;
6660 }
f4236fe4
DD
6661 break;
6662
ff7eeb89 6663 case EM_M32C_OLD:
f4236fe4 6664 case EM_M32C:
dda8d76d 6665 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6666 {
6667 case EF_M32C_CPU_M16C:
6668 eh_addr_size = 2;
6669 break;
6670 }
6671 break;
89fac5e3
RS
6672 }
6673
76ca31c0
NC
6674#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6675 do \
6676 { \
6677 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6678 if (section->sh_entsize != expected_entsize) \
9dd3a467 6679 { \
76ca31c0
NC
6680 char buf[40]; \
6681 sprintf_vma (buf, section->sh_entsize); \
6682 /* Note: coded this way so that there is a single string for \
6683 translation. */ \
6684 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6685 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6686 (unsigned) expected_entsize); \
9dd3a467 6687 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6688 } \
6689 } \
08d8fa11 6690 while (0)
9dd3a467
NC
6691
6692#define CHECK_ENTSIZE(section, i, type) \
1b513401 6693 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6694 sizeof (Elf64_External_##type))
6695
dda8d76d
NC
6696 for (i = 0, section = filedata->section_headers;
6697 i < filedata->file_header.e_shnum;
b34976b6 6698 i++, section++)
252b5132 6699 {
b9e920ec 6700 char * name = SECTION_NAME_PRINT (section);
252b5132 6701
1b513401
NC
6702 /* Run some sanity checks on the headers and
6703 possibly fill in some file data as well. */
6704 switch (section->sh_type)
252b5132 6705 {
1b513401 6706 case SHT_DYNSYM:
978c4450 6707 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6708 {
6709 error (_("File contains multiple dynamic symbol tables\n"));
6710 continue;
6711 }
6712
08d8fa11 6713 CHECK_ENTSIZE (section, i, Sym);
978c4450 6714 filedata->dynamic_symbols
4de91c10 6715 = get_elf_symbols (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6716 filedata->dynamic_symtab_section = section;
1b513401
NC
6717 break;
6718
6719 case SHT_STRTAB:
6720 if (streq (name, ".dynstr"))
252b5132 6721 {
1b513401
NC
6722 if (filedata->dynamic_strings != NULL)
6723 {
6724 error (_("File contains multiple dynamic string tables\n"));
6725 continue;
6726 }
6727
6728 filedata->dynamic_strings
6729 = (char *) get_data (NULL, filedata, section->sh_offset,
6730 1, section->sh_size, _("dynamic strings"));
6731 filedata->dynamic_strings_length
6732 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6733 filedata->dynamic_strtab_section = section;
252b5132 6734 }
1b513401
NC
6735 break;
6736
6737 case SHT_SYMTAB_SHNDX:
6738 {
6739 elf_section_list * entry = xmalloc (sizeof * entry);
6740
6741 entry->hdr = section;
6742 entry->next = filedata->symtab_shndx_list;
6743 filedata->symtab_shndx_list = entry;
6744 }
6745 break;
6746
6747 case SHT_SYMTAB:
6748 CHECK_ENTSIZE (section, i, Sym);
6749 break;
6750
6751 case SHT_GROUP:
6752 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6753 break;
252b5132 6754
1b513401
NC
6755 case SHT_REL:
6756 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6757 if (do_checks && section->sh_size == 0)
1b513401
NC
6758 warn (_("Section '%s': zero-sized relocation section\n"), name);
6759 break;
6760
6761 case SHT_RELA:
6762 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6763 if (do_checks && section->sh_size == 0)
1b513401
NC
6764 warn (_("Section '%s': zero-sized relocation section\n"), name);
6765 break;
6766
6767 case SHT_NOTE:
6768 case SHT_PROGBITS:
546cb2d8
NC
6769 /* Having a zero sized section is not illegal according to the
6770 ELF standard, but it might be an indication that something
6771 is wrong. So issue a warning if we are running in lint mode. */
6772 if (do_checks && section->sh_size == 0)
1b513401
NC
6773 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6774 break;
6775
6776 default:
6777 break;
6778 }
6779
6780 if ((do_debugging || do_debug_info || do_debug_abbrevs
6781 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6782 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e38332c2
NC
6783 || do_debug_str || do_debug_str_offsets || do_debug_loc
6784 || do_debug_ranges
1b513401 6785 || do_debug_addr || do_debug_cu_index || do_debug_links)
24d127aa
ML
6786 && (startswith (name, ".debug_")
6787 || startswith (name, ".zdebug_")))
252b5132 6788 {
1b315056
CS
6789 if (name[1] == 'z')
6790 name += sizeof (".zdebug_") - 1;
6791 else
6792 name += sizeof (".debug_") - 1;
252b5132
RH
6793
6794 if (do_debugging
24d127aa
ML
6795 || (do_debug_info && startswith (name, "info"))
6796 || (do_debug_info && startswith (name, "types"))
6797 || (do_debug_abbrevs && startswith (name, "abbrev"))
b40bf0a2 6798 || (do_debug_lines && strcmp (name, "line") == 0)
24d127aa
ML
6799 || (do_debug_lines && startswith (name, "line."))
6800 || (do_debug_pubnames && startswith (name, "pubnames"))
6801 || (do_debug_pubtypes && startswith (name, "pubtypes"))
6802 || (do_debug_pubnames && startswith (name, "gnu_pubnames"))
6803 || (do_debug_pubtypes && startswith (name, "gnu_pubtypes"))
6804 || (do_debug_aranges && startswith (name, "aranges"))
6805 || (do_debug_ranges && startswith (name, "ranges"))
6806 || (do_debug_ranges && startswith (name, "rnglists"))
6807 || (do_debug_frames && startswith (name, "frame"))
6808 || (do_debug_macinfo && startswith (name, "macinfo"))
6809 || (do_debug_macinfo && startswith (name, "macro"))
6810 || (do_debug_str && startswith (name, "str"))
6811 || (do_debug_links && startswith (name, "sup"))
6812 || (do_debug_str_offsets && startswith (name, "str_offsets"))
6813 || (do_debug_loc && startswith (name, "loc"))
6814 || (do_debug_loc && startswith (name, "loclists"))
6815 || (do_debug_addr && startswith (name, "addr"))
6816 || (do_debug_cu_index && startswith (name, "cu_index"))
6817 || (do_debug_cu_index && startswith (name, "tu_index"))
252b5132 6818 )
6431e409 6819 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6820 }
a262ae96 6821 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6822 else if ((do_debugging || do_debug_info)
24d127aa 6823 && startswith (name, ".gnu.linkonce.wi."))
6431e409 6824 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6825 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6826 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6827 else if (do_gdb_index && (streq (name, ".gdb_index")
6828 || streq (name, ".debug_names")))
6431e409 6829 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6830 /* Trace sections for Itanium VMS. */
6831 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6832 || do_trace_aranges)
24d127aa 6833 && startswith (name, ".trace_"))
6f875884
TG
6834 {
6835 name += sizeof (".trace_") - 1;
6836
6837 if (do_debugging
6838 || (do_trace_info && streq (name, "info"))
6839 || (do_trace_abbrevs && streq (name, "abbrev"))
6840 || (do_trace_aranges && streq (name, "aranges"))
6841 )
6431e409 6842 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6843 }
dda8d76d 6844 else if ((do_debugging || do_debug_links)
24d127aa
ML
6845 && (startswith (name, ".gnu_debuglink")
6846 || startswith (name, ".gnu_debugaltlink")))
6431e409 6847 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6848 }
6849
6850 if (! do_sections)
015dc7e1 6851 return true;
252b5132 6852
ca0e11aa 6853 if (filedata->is_separate && ! process_links)
015dc7e1 6854 return true;
ca0e11aa
NC
6855
6856 if (filedata->is_separate)
6857 printf (_("\nSection Headers in linked file '%s':\n"), filedata->file_name);
6858 else if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6859 printf (_("\nSection Headers:\n"));
6860 else
6861 printf (_("\nSection Header:\n"));
76da6bbe 6862
f7a99963 6863 if (is_32bit_elf)
595cf52e 6864 {
5477e8a0 6865 if (do_section_details)
595cf52e
L
6866 {
6867 printf (_(" [Nr] Name\n"));
5477e8a0 6868 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6869 }
6870 else
6871 printf
6872 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6873 }
d974e256 6874 else if (do_wide)
595cf52e 6875 {
5477e8a0 6876 if (do_section_details)
595cf52e
L
6877 {
6878 printf (_(" [Nr] Name\n"));
5477e8a0 6879 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6880 }
6881 else
6882 printf
6883 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6884 }
f7a99963
NC
6885 else
6886 {
5477e8a0 6887 if (do_section_details)
595cf52e
L
6888 {
6889 printf (_(" [Nr] Name\n"));
5477e8a0
L
6890 printf (_(" Type Address Offset Link\n"));
6891 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6892 }
6893 else
6894 {
6895 printf (_(" [Nr] Name Type Address Offset\n"));
6896 printf (_(" Size EntSize Flags Link Info Align\n"));
6897 }
f7a99963 6898 }
252b5132 6899
5477e8a0
L
6900 if (do_section_details)
6901 printf (_(" Flags\n"));
6902
dda8d76d
NC
6903 for (i = 0, section = filedata->section_headers;
6904 i < filedata->file_header.e_shnum;
b34976b6 6905 i++, section++)
252b5132 6906 {
dd905818
NC
6907 /* Run some sanity checks on the section header. */
6908
6909 /* Check the sh_link field. */
6910 switch (section->sh_type)
6911 {
285e3f99
AM
6912 case SHT_REL:
6913 case SHT_RELA:
6914 if (section->sh_link == 0
6915 && (filedata->file_header.e_type == ET_EXEC
6916 || filedata->file_header.e_type == ET_DYN))
6917 /* A dynamic relocation section where all entries use a
6918 zero symbol index need not specify a symtab section. */
6919 break;
6920 /* Fall through. */
dd905818
NC
6921 case SHT_SYMTAB_SHNDX:
6922 case SHT_GROUP:
6923 case SHT_HASH:
6924 case SHT_GNU_HASH:
6925 case SHT_GNU_versym:
285e3f99 6926 if (section->sh_link == 0
dda8d76d
NC
6927 || section->sh_link >= filedata->file_header.e_shnum
6928 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6929 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6930 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6931 i, section->sh_link);
6932 break;
6933
6934 case SHT_DYNAMIC:
6935 case SHT_SYMTAB:
6936 case SHT_DYNSYM:
6937 case SHT_GNU_verneed:
6938 case SHT_GNU_verdef:
6939 case SHT_GNU_LIBLIST:
285e3f99 6940 if (section->sh_link == 0
dda8d76d
NC
6941 || section->sh_link >= filedata->file_header.e_shnum
6942 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6943 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6944 i, section->sh_link);
6945 break;
6946
6947 case SHT_INIT_ARRAY:
6948 case SHT_FINI_ARRAY:
6949 case SHT_PREINIT_ARRAY:
6950 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6951 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6952 i, section->sh_link);
6953 break;
6954
6955 default:
6956 /* FIXME: Add support for target specific section types. */
6957#if 0 /* Currently we do not check other section types as there are too
6958 many special cases. Stab sections for example have a type
6959 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6960 section. */
6961 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6962 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6963 i, section->sh_link);
6964#endif
6965 break;
6966 }
6967
6968 /* Check the sh_info field. */
6969 switch (section->sh_type)
6970 {
6971 case SHT_REL:
6972 case SHT_RELA:
285e3f99
AM
6973 if (section->sh_info == 0
6974 && (filedata->file_header.e_type == ET_EXEC
6975 || filedata->file_header.e_type == ET_DYN))
6976 /* Dynamic relocations apply to segments, so they do not
6977 need to specify the section they relocate. */
6978 break;
6979 if (section->sh_info == 0
dda8d76d
NC
6980 || section->sh_info >= filedata->file_header.e_shnum
6981 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6982 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6983 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6984 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6985 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6986 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6987 /* FIXME: Are other section types valid ? */
dda8d76d 6988 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6989 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6990 i, section->sh_info);
dd905818
NC
6991 break;
6992
6993 case SHT_DYNAMIC:
6994 case SHT_HASH:
6995 case SHT_SYMTAB_SHNDX:
6996 case SHT_INIT_ARRAY:
6997 case SHT_FINI_ARRAY:
6998 case SHT_PREINIT_ARRAY:
6999 if (section->sh_info != 0)
7000 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7001 i, section->sh_info);
7002 break;
7003
7004 case SHT_GROUP:
7005 case SHT_SYMTAB:
7006 case SHT_DYNSYM:
7007 /* A symbol index - we assume that it is valid. */
7008 break;
7009
7010 default:
7011 /* FIXME: Add support for target specific section types. */
7012 if (section->sh_type == SHT_NOBITS)
7013 /* NOBITS section headers with non-zero sh_info fields can be
7014 created when a binary is stripped of everything but its debug
1a9ccd70
NC
7015 information. The stripped sections have their headers
7016 preserved but their types set to SHT_NOBITS. So do not check
7017 this type of section. */
dd905818
NC
7018 ;
7019 else if (section->sh_flags & SHF_INFO_LINK)
7020 {
dda8d76d 7021 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
7022 warn (_("[%2u]: Expected link to another section in info field"), i);
7023 }
a91e1603
L
7024 else if (section->sh_type < SHT_LOOS
7025 && (section->sh_flags & SHF_GNU_MBIND) == 0
7026 && section->sh_info != 0)
dd905818
NC
7027 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
7028 i, section->sh_info);
7029 break;
7030 }
7031
3e6b6445 7032 /* Check the sh_size field. */
dda8d76d 7033 if (section->sh_size > filedata->file_size
3e6b6445
NC
7034 && section->sh_type != SHT_NOBITS
7035 && section->sh_type != SHT_NULL
7036 && section->sh_type < SHT_LOOS)
7037 warn (_("Size of section %u is larger than the entire file!\n"), i);
7038
7bfd842d 7039 printf (" [%2u] ", i);
5477e8a0 7040 if (do_section_details)
dda8d76d 7041 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 7042 else
b9e920ec 7043 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 7044
ea52a088 7045 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 7046 get_section_type_name (filedata, section->sh_type));
0b4362b0 7047
f7a99963
NC
7048 if (is_32bit_elf)
7049 {
cfcac11d
NC
7050 const char * link_too_big = NULL;
7051
f7a99963 7052 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 7053
f7a99963
NC
7054 printf ( " %6.6lx %6.6lx %2.2lx",
7055 (unsigned long) section->sh_offset,
7056 (unsigned long) section->sh_size,
7057 (unsigned long) section->sh_entsize);
d1133906 7058
5477e8a0
L
7059 if (do_section_details)
7060 fputs (" ", stdout);
7061 else
dda8d76d 7062 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7063
dda8d76d 7064 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
7065 {
7066 link_too_big = "";
7067 /* The sh_link value is out of range. Normally this indicates
caa83f8b 7068 an error but it can have special values in Solaris binaries. */
dda8d76d 7069 switch (filedata->file_header.e_machine)
cfcac11d 7070 {
caa83f8b 7071 case EM_386:
22abe556 7072 case EM_IAMCU:
caa83f8b 7073 case EM_X86_64:
7f502d6c 7074 case EM_L1OM:
7a9068fe 7075 case EM_K1OM:
cfcac11d
NC
7076 case EM_OLD_SPARCV9:
7077 case EM_SPARC32PLUS:
7078 case EM_SPARCV9:
7079 case EM_SPARC:
7080 if (section->sh_link == (SHN_BEFORE & 0xffff))
7081 link_too_big = "BEFORE";
7082 else if (section->sh_link == (SHN_AFTER & 0xffff))
7083 link_too_big = "AFTER";
7084 break;
7085 default:
7086 break;
7087 }
7088 }
7089
7090 if (do_section_details)
7091 {
7092 if (link_too_big != NULL && * link_too_big)
7093 printf ("<%s> ", link_too_big);
7094 else
7095 printf ("%2u ", section->sh_link);
7096 printf ("%3u %2lu\n", section->sh_info,
7097 (unsigned long) section->sh_addralign);
7098 }
7099 else
7100 printf ("%2u %3u %2lu\n",
7101 section->sh_link,
7102 section->sh_info,
7103 (unsigned long) section->sh_addralign);
7104
7105 if (link_too_big && ! * link_too_big)
7106 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
7107 i, section->sh_link);
f7a99963 7108 }
d974e256
JJ
7109 else if (do_wide)
7110 {
7111 print_vma (section->sh_addr, LONG_HEX);
7112
7113 if ((long) section->sh_offset == section->sh_offset)
7114 printf (" %6.6lx", (unsigned long) section->sh_offset);
7115 else
7116 {
7117 putchar (' ');
7118 print_vma (section->sh_offset, LONG_HEX);
7119 }
7120
7121 if ((unsigned long) section->sh_size == section->sh_size)
7122 printf (" %6.6lx", (unsigned long) section->sh_size);
7123 else
7124 {
7125 putchar (' ');
7126 print_vma (section->sh_size, LONG_HEX);
7127 }
7128
7129 if ((unsigned long) section->sh_entsize == section->sh_entsize)
7130 printf (" %2.2lx", (unsigned long) section->sh_entsize);
7131 else
7132 {
7133 putchar (' ');
7134 print_vma (section->sh_entsize, LONG_HEX);
7135 }
7136
5477e8a0
L
7137 if (do_section_details)
7138 fputs (" ", stdout);
7139 else
dda8d76d 7140 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 7141
72de5009 7142 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
7143
7144 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 7145 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
7146 else
7147 {
7148 print_vma (section->sh_addralign, DEC);
7149 putchar ('\n');
7150 }
7151 }
5477e8a0 7152 else if (do_section_details)
595cf52e 7153 {
55cc53e9 7154 putchar (' ');
595cf52e
L
7155 print_vma (section->sh_addr, LONG_HEX);
7156 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 7157 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
7158 else
7159 {
7160 printf (" ");
7161 print_vma (section->sh_offset, LONG_HEX);
7162 }
72de5009 7163 printf (" %u\n ", section->sh_link);
595cf52e 7164 print_vma (section->sh_size, LONG_HEX);
5477e8a0 7165 putchar (' ');
595cf52e
L
7166 print_vma (section->sh_entsize, LONG_HEX);
7167
72de5009
AM
7168 printf (" %-16u %lu\n",
7169 section->sh_info,
595cf52e
L
7170 (unsigned long) section->sh_addralign);
7171 }
f7a99963
NC
7172 else
7173 {
7174 putchar (' ');
7175 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
7176 if ((long) section->sh_offset == section->sh_offset)
7177 printf (" %8.8lx", (unsigned long) section->sh_offset);
7178 else
7179 {
7180 printf (" ");
7181 print_vma (section->sh_offset, LONG_HEX);
7182 }
f7a99963
NC
7183 printf ("\n ");
7184 print_vma (section->sh_size, LONG_HEX);
7185 printf (" ");
7186 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 7187
dda8d76d 7188 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 7189
72de5009
AM
7190 printf (" %2u %3u %lu\n",
7191 section->sh_link,
7192 section->sh_info,
f7a99963
NC
7193 (unsigned long) section->sh_addralign);
7194 }
5477e8a0
L
7195
7196 if (do_section_details)
77115a4a 7197 {
dda8d76d 7198 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
7199 if ((section->sh_flags & SHF_COMPRESSED) != 0)
7200 {
7201 /* Minimum section size is 12 bytes for 32-bit compression
7202 header + 12 bytes for compressed data header. */
7203 unsigned char buf[24];
d8024a91 7204
77115a4a 7205 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 7206 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
7207 sizeof (buf), _("compression header")))
7208 {
7209 Elf_Internal_Chdr chdr;
d8024a91 7210
5844b465
NC
7211 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
7212 printf (_(" [<corrupt>]\n"));
77115a4a 7213 else
5844b465
NC
7214 {
7215 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
7216 printf (" ZLIB, ");
7217 else
7218 printf (_(" [<unknown>: 0x%x], "),
7219 chdr.ch_type);
7220 print_vma (chdr.ch_size, LONG_HEX);
7221 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
7222 }
77115a4a
L
7223 }
7224 }
7225 }
252b5132
RH
7226 }
7227
5477e8a0 7228 if (!do_section_details)
3dbcc61d 7229 {
9fb71ee4
NC
7230 /* The ordering of the letters shown here matches the ordering of the
7231 corresponding SHF_xxx values, and hence the order in which these
7232 letters will be displayed to the user. */
7233 printf (_("Key to Flags:\n\
7234 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
7235 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 7236 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
7237 switch (filedata->file_header.e_ident[EI_OSABI])
7238 {
7239 case ELFOSABI_GNU:
7240 case ELFOSABI_FREEBSD:
7241 printf (_("R (retain), "));
7242 /* Fall through */
7243 case ELFOSABI_NONE:
7244 printf (_("D (mbind), "));
7245 break;
7246 default:
7247 break;
7248 }
dda8d76d
NC
7249 if (filedata->file_header.e_machine == EM_X86_64
7250 || filedata->file_header.e_machine == EM_L1OM
7251 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7252 printf (_("l (large), "));
dda8d76d 7253 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7254 printf (_("y (purecode), "));
dda8d76d 7255 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7256 printf (_("v (VLE), "));
9fb71ee4 7257 printf ("p (processor specific)\n");
0b4362b0 7258 }
d1133906 7259
015dc7e1 7260 return true;
252b5132
RH
7261}
7262
015dc7e1 7263static bool
28d13567
AM
7264get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7265 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7266 char **strtab, unsigned long *strtablen)
7267{
7268 *strtab = NULL;
7269 *strtablen = 0;
4de91c10 7270 *symtab = get_elf_symbols (filedata, symsec, nsyms);
28d13567
AM
7271
7272 if (*symtab == NULL)
015dc7e1 7273 return false;
28d13567
AM
7274
7275 if (symsec->sh_link != 0)
7276 {
7277 Elf_Internal_Shdr *strsec;
7278
7279 if (symsec->sh_link >= filedata->file_header.e_shnum)
7280 {
7281 error (_("Bad sh_link in symbol table section\n"));
7282 free (*symtab);
7283 *symtab = NULL;
7284 *nsyms = 0;
015dc7e1 7285 return false;
28d13567
AM
7286 }
7287
7288 strsec = filedata->section_headers + symsec->sh_link;
7289
7290 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7291 1, strsec->sh_size, _("string table"));
7292 if (*strtab == NULL)
7293 {
7294 free (*symtab);
7295 *symtab = NULL;
7296 *nsyms = 0;
015dc7e1 7297 return false;
28d13567
AM
7298 }
7299 *strtablen = strsec->sh_size;
7300 }
015dc7e1 7301 return true;
28d13567
AM
7302}
7303
f5842774
L
7304static const char *
7305get_group_flags (unsigned int flags)
7306{
1449284b 7307 static char buff[128];
220453ec 7308
6d913794
NC
7309 if (flags == 0)
7310 return "";
7311 else if (flags == GRP_COMDAT)
7312 return "COMDAT ";
f5842774 7313
89246a0e
AM
7314 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7315 flags,
7316 flags & GRP_MASKOS ? _("<OS specific>") : "",
7317 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7318 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7319 ? _("<unknown>") : ""));
6d913794 7320
f5842774
L
7321 return buff;
7322}
7323
015dc7e1 7324static bool
dda8d76d 7325process_section_groups (Filedata * filedata)
f5842774 7326{
2cf0635d 7327 Elf_Internal_Shdr * section;
f5842774 7328 unsigned int i;
2cf0635d
NC
7329 struct group * group;
7330 Elf_Internal_Shdr * symtab_sec;
7331 Elf_Internal_Shdr * strtab_sec;
7332 Elf_Internal_Sym * symtab;
ba5cdace 7333 unsigned long num_syms;
2cf0635d 7334 char * strtab;
c256ffe7 7335 size_t strtab_size;
d1f5c6e3
L
7336
7337 /* Don't process section groups unless needed. */
7338 if (!do_unwind && !do_section_groups)
015dc7e1 7339 return true;
f5842774 7340
dda8d76d 7341 if (filedata->file_header.e_shnum == 0)
f5842774
L
7342 {
7343 if (do_section_groups)
ca0e11aa
NC
7344 {
7345 if (filedata->is_separate)
7346 printf (_("\nThere are no sections group in linked file '%s'.\n"),
7347 filedata->file_name);
7348 else
7349 printf (_("\nThere are no section groups in this file.\n"));
7350 }
015dc7e1 7351 return true;
f5842774
L
7352 }
7353
dda8d76d 7354 if (filedata->section_headers == NULL)
f5842774
L
7355 {
7356 error (_("Section headers are not available!\n"));
fa1908fd 7357 /* PR 13622: This can happen with a corrupt ELF header. */
015dc7e1 7358 return false;
f5842774
L
7359 }
7360
978c4450
AM
7361 filedata->section_headers_groups
7362 = (struct group **) calloc (filedata->file_header.e_shnum,
7363 sizeof (struct group *));
e4b17d5c 7364
978c4450 7365 if (filedata->section_headers_groups == NULL)
e4b17d5c 7366 {
8b73c356 7367 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7368 filedata->file_header.e_shnum);
015dc7e1 7369 return false;
e4b17d5c
L
7370 }
7371
f5842774 7372 /* Scan the sections for the group section. */
978c4450 7373 filedata->group_count = 0;
dda8d76d
NC
7374 for (i = 0, section = filedata->section_headers;
7375 i < filedata->file_header.e_shnum;
f5842774 7376 i++, section++)
e4b17d5c 7377 if (section->sh_type == SHT_GROUP)
978c4450 7378 filedata->group_count++;
e4b17d5c 7379
978c4450 7380 if (filedata->group_count == 0)
d1f5c6e3
L
7381 {
7382 if (do_section_groups)
ca0e11aa
NC
7383 {
7384 if (filedata->is_separate)
7385 printf (_("\nThere are no section groups in linked file '%s'.\n"),
7386 filedata->file_name);
7387 else
7388 printf (_("\nThere are no section groups in this file.\n"));
7389 }
d1f5c6e3 7390
015dc7e1 7391 return true;
d1f5c6e3
L
7392 }
7393
978c4450
AM
7394 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7395 sizeof (struct group));
e4b17d5c 7396
978c4450 7397 if (filedata->section_groups == NULL)
e4b17d5c 7398 {
8b73c356 7399 error (_("Out of memory reading %lu groups\n"),
978c4450 7400 (unsigned long) filedata->group_count);
015dc7e1 7401 return false;
e4b17d5c
L
7402 }
7403
d1f5c6e3
L
7404 symtab_sec = NULL;
7405 strtab_sec = NULL;
7406 symtab = NULL;
ba5cdace 7407 num_syms = 0;
d1f5c6e3 7408 strtab = NULL;
c256ffe7 7409 strtab_size = 0;
ca0e11aa
NC
7410
7411 if (filedata->is_separate)
7412 printf (_("Section groups in linked file '%s'\n"), filedata->file_name);
047c3dbf 7413
978c4450 7414 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7415 i < filedata->file_header.e_shnum;
e4b17d5c 7416 i++, section++)
f5842774
L
7417 {
7418 if (section->sh_type == SHT_GROUP)
7419 {
dda8d76d 7420 const char * name = printable_section_name (filedata, section);
74e1a04b 7421 const char * group_name;
2cf0635d
NC
7422 unsigned char * start;
7423 unsigned char * indices;
f5842774 7424 unsigned int entry, j, size;
2cf0635d
NC
7425 Elf_Internal_Shdr * sec;
7426 Elf_Internal_Sym * sym;
f5842774
L
7427
7428 /* Get the symbol table. */
dda8d76d
NC
7429 if (section->sh_link >= filedata->file_header.e_shnum
7430 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7431 != SHT_SYMTAB))
f5842774
L
7432 {
7433 error (_("Bad sh_link in group section `%s'\n"), name);
7434 continue;
7435 }
d1f5c6e3
L
7436
7437 if (symtab_sec != sec)
7438 {
7439 symtab_sec = sec;
9db70fc3 7440 free (symtab);
4de91c10 7441 symtab = get_elf_symbols (filedata, symtab_sec, & num_syms);
d1f5c6e3 7442 }
f5842774 7443
dd24e3da
NC
7444 if (symtab == NULL)
7445 {
7446 error (_("Corrupt header in group section `%s'\n"), name);
7447 continue;
7448 }
7449
ba5cdace
NC
7450 if (section->sh_info >= num_syms)
7451 {
7452 error (_("Bad sh_info in group section `%s'\n"), name);
7453 continue;
7454 }
7455
f5842774
L
7456 sym = symtab + section->sh_info;
7457
7458 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7459 {
4fbb74a6 7460 if (sym->st_shndx == 0
dda8d76d 7461 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7462 {
7463 error (_("Bad sh_info in group section `%s'\n"), name);
7464 continue;
7465 }
ba2685cc 7466
b9e920ec
AM
7467 group_name = SECTION_NAME_PRINT (filedata->section_headers
7468 + sym->st_shndx);
c256ffe7 7469 strtab_sec = NULL;
9db70fc3 7470 free (strtab);
f5842774 7471 strtab = NULL;
c256ffe7 7472 strtab_size = 0;
f5842774
L
7473 }
7474 else
7475 {
7476 /* Get the string table. */
dda8d76d 7477 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7478 {
7479 strtab_sec = NULL;
9db70fc3 7480 free (strtab);
c256ffe7
JJ
7481 strtab = NULL;
7482 strtab_size = 0;
7483 }
7484 else if (strtab_sec
dda8d76d 7485 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7486 {
7487 strtab_sec = sec;
9db70fc3 7488 free (strtab);
071436c6 7489
dda8d76d 7490 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7491 1, strtab_sec->sh_size,
7492 _("string table"));
c256ffe7 7493 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7494 }
c256ffe7 7495 group_name = sym->st_name < strtab_size
2b692964 7496 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7497 }
7498
c9c1d674
EG
7499 /* PR 17531: file: loop. */
7500 if (section->sh_entsize > section->sh_size)
7501 {
7502 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7503 printable_section_name (filedata, section),
8066deb1
AM
7504 (unsigned long) section->sh_entsize,
7505 (unsigned long) section->sh_size);
61dd8e19 7506 continue;
c9c1d674
EG
7507 }
7508
dda8d76d 7509 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7510 1, section->sh_size,
7511 _("section data"));
59245841
NC
7512 if (start == NULL)
7513 continue;
f5842774
L
7514
7515 indices = start;
7516 size = (section->sh_size / section->sh_entsize) - 1;
7517 entry = byte_get (indices, 4);
7518 indices += 4;
e4b17d5c
L
7519
7520 if (do_section_groups)
7521 {
2b692964 7522 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7523 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7524
e4b17d5c
L
7525 printf (_(" [Index] Name\n"));
7526 }
7527
7528 group->group_index = i;
7529
f5842774
L
7530 for (j = 0; j < size; j++)
7531 {
2cf0635d 7532 struct group_list * g;
e4b17d5c 7533
f5842774
L
7534 entry = byte_get (indices, 4);
7535 indices += 4;
7536
dda8d76d 7537 if (entry >= filedata->file_header.e_shnum)
391cb864 7538 {
57028622
NC
7539 static unsigned num_group_errors = 0;
7540
7541 if (num_group_errors ++ < 10)
7542 {
7543 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7544 entry, i, filedata->file_header.e_shnum - 1);
57028622 7545 if (num_group_errors == 10)
67ce483b 7546 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7547 }
391cb864
L
7548 continue;
7549 }
391cb864 7550
978c4450 7551 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7552 {
d1f5c6e3
L
7553 if (entry)
7554 {
57028622
NC
7555 static unsigned num_errs = 0;
7556
7557 if (num_errs ++ < 10)
7558 {
7559 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7560 entry, i,
978c4450 7561 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7562 if (num_errs == 10)
7563 warn (_("Further error messages about already contained group sections suppressed\n"));
7564 }
d1f5c6e3
L
7565 continue;
7566 }
7567 else
7568 {
7569 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7570 section group. We just warn it the first time
d1f5c6e3 7571 and ignore it afterwards. */
015dc7e1 7572 static bool warned = false;
d1f5c6e3
L
7573 if (!warned)
7574 {
7575 error (_("section 0 in group section [%5u]\n"),
978c4450 7576 filedata->section_headers_groups [entry]->group_index);
015dc7e1 7577 warned = true;
d1f5c6e3
L
7578 }
7579 }
e4b17d5c
L
7580 }
7581
978c4450 7582 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7583
7584 if (do_section_groups)
7585 {
dda8d76d
NC
7586 sec = filedata->section_headers + entry;
7587 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7588 }
7589
3f5e193b 7590 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7591 g->section_index = entry;
7592 g->next = group->root;
7593 group->root = g;
f5842774
L
7594 }
7595
9db70fc3 7596 free (start);
e4b17d5c
L
7597
7598 group++;
f5842774
L
7599 }
7600 }
7601
9db70fc3
AM
7602 free (symtab);
7603 free (strtab);
015dc7e1 7604 return true;
f5842774
L
7605}
7606
28f997cf
TG
7607/* Data used to display dynamic fixups. */
7608
7609struct ia64_vms_dynfixup
7610{
7611 bfd_vma needed_ident; /* Library ident number. */
7612 bfd_vma needed; /* Index in the dstrtab of the library name. */
7613 bfd_vma fixup_needed; /* Index of the library. */
7614 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7615 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7616};
7617
7618/* Data used to display dynamic relocations. */
7619
7620struct ia64_vms_dynimgrela
7621{
7622 bfd_vma img_rela_cnt; /* Number of relocations. */
7623 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7624};
7625
7626/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7627 library). */
7628
015dc7e1 7629static bool
dda8d76d
NC
7630dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7631 struct ia64_vms_dynfixup * fixup,
7632 const char * strtab,
7633 unsigned int strtab_sz)
28f997cf 7634{
32ec8896 7635 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7636 long i;
32ec8896 7637 const char * lib_name;
28f997cf 7638
978c4450
AM
7639 imfs = get_data (NULL, filedata,
7640 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7641 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7642 _("dynamic section image fixups"));
7643 if (!imfs)
015dc7e1 7644 return false;
28f997cf
TG
7645
7646 if (fixup->needed < strtab_sz)
7647 lib_name = strtab + fixup->needed;
7648 else
7649 {
32ec8896 7650 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7651 (unsigned long) fixup->needed);
28f997cf
TG
7652 lib_name = "???";
7653 }
736990c4 7654
28f997cf
TG
7655 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7656 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7657 printf
7658 (_("Seg Offset Type SymVec DataType\n"));
7659
7660 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7661 {
7662 unsigned int type;
7663 const char *rtype;
7664
7665 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7666 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7667 type = BYTE_GET (imfs [i].type);
7668 rtype = elf_ia64_reloc_type (type);
7669 if (rtype == NULL)
7670 printf (" 0x%08x ", type);
7671 else
7672 printf (" %-32s ", rtype);
7673 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7674 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7675 }
7676
7677 free (imfs);
015dc7e1 7678 return true;
28f997cf
TG
7679}
7680
7681/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7682
015dc7e1 7683static bool
dda8d76d 7684dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7685{
7686 Elf64_External_VMS_IMAGE_RELA *imrs;
7687 long i;
7688
978c4450
AM
7689 imrs = get_data (NULL, filedata,
7690 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7691 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7692 _("dynamic section image relocations"));
28f997cf 7693 if (!imrs)
015dc7e1 7694 return false;
28f997cf
TG
7695
7696 printf (_("\nImage relocs\n"));
7697 printf
7698 (_("Seg Offset Type Addend Seg Sym Off\n"));
7699
7700 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7701 {
7702 unsigned int type;
7703 const char *rtype;
7704
7705 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7706 printf ("%08" BFD_VMA_FMT "x ",
7707 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7708 type = BYTE_GET (imrs [i].type);
7709 rtype = elf_ia64_reloc_type (type);
7710 if (rtype == NULL)
7711 printf ("0x%08x ", type);
7712 else
7713 printf ("%-31s ", rtype);
7714 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7715 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7716 printf ("%08" BFD_VMA_FMT "x\n",
7717 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7718 }
7719
7720 free (imrs);
015dc7e1 7721 return true;
28f997cf
TG
7722}
7723
7724/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7725
015dc7e1 7726static bool
dda8d76d 7727process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7728{
7729 struct ia64_vms_dynfixup fixup;
7730 struct ia64_vms_dynimgrela imgrela;
7731 Elf_Internal_Dyn *entry;
28f997cf
TG
7732 bfd_vma strtab_off = 0;
7733 bfd_vma strtab_sz = 0;
7734 char *strtab = NULL;
015dc7e1 7735 bool res = true;
28f997cf
TG
7736
7737 memset (&fixup, 0, sizeof (fixup));
7738 memset (&imgrela, 0, sizeof (imgrela));
7739
7740 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7741 for (entry = filedata->dynamic_section;
7742 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7743 entry++)
7744 {
7745 switch (entry->d_tag)
7746 {
7747 case DT_IA_64_VMS_STRTAB_OFFSET:
7748 strtab_off = entry->d_un.d_val;
7749 break;
7750 case DT_STRSZ:
7751 strtab_sz = entry->d_un.d_val;
7752 if (strtab == NULL)
978c4450
AM
7753 strtab = get_data (NULL, filedata,
7754 filedata->dynamic_addr + strtab_off,
28f997cf 7755 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7756 if (strtab == NULL)
7757 strtab_sz = 0;
28f997cf
TG
7758 break;
7759
7760 case DT_IA_64_VMS_NEEDED_IDENT:
7761 fixup.needed_ident = entry->d_un.d_val;
7762 break;
7763 case DT_NEEDED:
7764 fixup.needed = entry->d_un.d_val;
7765 break;
7766 case DT_IA_64_VMS_FIXUP_NEEDED:
7767 fixup.fixup_needed = entry->d_un.d_val;
7768 break;
7769 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7770 fixup.fixup_rela_cnt = entry->d_un.d_val;
7771 break;
7772 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7773 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7774 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
015dc7e1 7775 res = false;
28f997cf 7776 break;
28f997cf
TG
7777 case DT_IA_64_VMS_IMG_RELA_CNT:
7778 imgrela.img_rela_cnt = entry->d_un.d_val;
7779 break;
7780 case DT_IA_64_VMS_IMG_RELA_OFF:
7781 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7782 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
015dc7e1 7783 res = false;
28f997cf
TG
7784 break;
7785
7786 default:
7787 break;
7788 }
7789 }
7790
9db70fc3 7791 free (strtab);
28f997cf
TG
7792
7793 return res;
7794}
7795
85b1c36d 7796static struct
566b0d53 7797{
2cf0635d 7798 const char * name;
566b0d53
L
7799 int reloc;
7800 int size;
7801 int rela;
32ec8896
NC
7802}
7803 dynamic_relocations [] =
566b0d53 7804{
015dc7e1
AM
7805 { "REL", DT_REL, DT_RELSZ, false },
7806 { "RELA", DT_RELA, DT_RELASZ, true },
32ec8896 7807 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7808};
7809
252b5132 7810/* Process the reloc section. */
18bd398b 7811
015dc7e1 7812static bool
dda8d76d 7813process_relocs (Filedata * filedata)
252b5132 7814{
b34976b6
AM
7815 unsigned long rel_size;
7816 unsigned long rel_offset;
252b5132 7817
252b5132 7818 if (!do_reloc)
015dc7e1 7819 return true;
252b5132
RH
7820
7821 if (do_using_dynamic)
7822 {
32ec8896 7823 int is_rela;
2cf0635d 7824 const char * name;
015dc7e1 7825 bool has_dynamic_reloc;
566b0d53 7826 unsigned int i;
0de14b54 7827
015dc7e1 7828 has_dynamic_reloc = false;
252b5132 7829
566b0d53 7830 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7831 {
566b0d53
L
7832 is_rela = dynamic_relocations [i].rela;
7833 name = dynamic_relocations [i].name;
978c4450
AM
7834 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7835 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7836
32ec8896 7837 if (rel_size)
015dc7e1 7838 has_dynamic_reloc = true;
566b0d53
L
7839
7840 if (is_rela == UNKNOWN)
aa903cfb 7841 {
566b0d53 7842 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7843 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7844 {
7845 case DT_REL:
015dc7e1 7846 is_rela = false;
566b0d53
L
7847 break;
7848 case DT_RELA:
015dc7e1 7849 is_rela = true;
566b0d53
L
7850 break;
7851 }
aa903cfb 7852 }
252b5132 7853
566b0d53
L
7854 if (rel_size)
7855 {
ca0e11aa
NC
7856 if (filedata->is_separate)
7857 printf
7858 (_("\nIn linked file '%s' section '%s' at offset 0x%lx contains %ld bytes:\n"),
7859 filedata->file_name, name, rel_offset, rel_size);
7860 else
7861 printf
7862 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7863 name, rel_offset, rel_size);
252b5132 7864
dda8d76d
NC
7865 dump_relocations (filedata,
7866 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7867 rel_size,
978c4450
AM
7868 filedata->dynamic_symbols,
7869 filedata->num_dynamic_syms,
7870 filedata->dynamic_strings,
7871 filedata->dynamic_strings_length,
015dc7e1 7872 is_rela, true /* is_dynamic */);
566b0d53 7873 }
252b5132 7874 }
566b0d53 7875
dda8d76d
NC
7876 if (is_ia64_vms (filedata))
7877 if (process_ia64_vms_dynamic_relocs (filedata))
015dc7e1 7878 has_dynamic_reloc = true;
28f997cf 7879
566b0d53 7880 if (! has_dynamic_reloc)
ca0e11aa
NC
7881 {
7882 if (filedata->is_separate)
7883 printf (_("\nThere are no dynamic relocations in linked file '%s'.\n"),
7884 filedata->file_name);
7885 else
7886 printf (_("\nThere are no dynamic relocations in this file.\n"));
7887 }
252b5132
RH
7888 }
7889 else
7890 {
2cf0635d 7891 Elf_Internal_Shdr * section;
b34976b6 7892 unsigned long i;
015dc7e1 7893 bool found = false;
252b5132 7894
dda8d76d
NC
7895 for (i = 0, section = filedata->section_headers;
7896 i < filedata->file_header.e_shnum;
b34976b6 7897 i++, section++)
252b5132
RH
7898 {
7899 if ( section->sh_type != SHT_RELA
7900 && section->sh_type != SHT_REL)
7901 continue;
7902
7903 rel_offset = section->sh_offset;
7904 rel_size = section->sh_size;
7905
7906 if (rel_size)
7907 {
b34976b6 7908 int is_rela;
d3a49aa8 7909 unsigned long num_rela;
103f02d3 7910
ca0e11aa
NC
7911 if (filedata->is_separate)
7912 printf (_("\nIn linked file '%s' relocation section "),
7913 filedata->file_name);
7914 else
7915 printf (_("\nRelocation section "));
252b5132 7916
dda8d76d 7917 if (filedata->string_table == NULL)
19936277 7918 printf ("%d", section->sh_name);
252b5132 7919 else
dda8d76d 7920 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7921
d3a49aa8
AM
7922 num_rela = rel_size / section->sh_entsize;
7923 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7924 " at offset 0x%lx contains %lu entries:\n",
7925 num_rela),
7926 rel_offset, num_rela);
252b5132 7927
d79b3d50
NC
7928 is_rela = section->sh_type == SHT_RELA;
7929
4fbb74a6 7930 if (section->sh_link != 0
dda8d76d 7931 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7932 {
2cf0635d
NC
7933 Elf_Internal_Shdr * symsec;
7934 Elf_Internal_Sym * symtab;
d79b3d50 7935 unsigned long nsyms;
c256ffe7 7936 unsigned long strtablen = 0;
2cf0635d 7937 char * strtab = NULL;
57346661 7938
dda8d76d 7939 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7940 if (symsec->sh_type != SHT_SYMTAB
7941 && symsec->sh_type != SHT_DYNSYM)
7942 continue;
7943
28d13567
AM
7944 if (!get_symtab (filedata, symsec,
7945 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7946 continue;
252b5132 7947
dda8d76d 7948 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7949 symtab, nsyms, strtab, strtablen,
7950 is_rela,
7951 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7952 free (strtab);
d79b3d50
NC
7953 free (symtab);
7954 }
7955 else
dda8d76d 7956 dump_relocations (filedata, rel_offset, rel_size,
32ec8896 7957 NULL, 0, NULL, 0, is_rela,
015dc7e1 7958 false /* is_dynamic */);
252b5132 7959
015dc7e1 7960 found = true;
252b5132
RH
7961 }
7962 }
7963
7964 if (! found)
45ac8f4f
NC
7965 {
7966 /* Users sometimes forget the -D option, so try to be helpful. */
7967 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7968 {
978c4450 7969 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f 7970 {
ca0e11aa
NC
7971 if (filedata->is_separate)
7972 printf (_("\nThere are no static relocations in linked file '%s'."),
7973 filedata->file_name);
7974 else
7975 printf (_("\nThere are no static relocations in this file."));
45ac8f4f
NC
7976 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7977
7978 break;
7979 }
7980 }
7981 if (i == ARRAY_SIZE (dynamic_relocations))
ca0e11aa
NC
7982 {
7983 if (filedata->is_separate)
7984 printf (_("\nThere are no relocations in linked file '%s'.\n"),
7985 filedata->file_name);
7986 else
7987 printf (_("\nThere are no relocations in this file.\n"));
7988 }
45ac8f4f 7989 }
252b5132
RH
7990 }
7991
015dc7e1 7992 return true;
252b5132
RH
7993}
7994
4d6ed7c8
NC
7995/* An absolute address consists of a section and an offset. If the
7996 section is NULL, the offset itself is the address, otherwise, the
7997 address equals to LOAD_ADDRESS(section) + offset. */
7998
7999struct absaddr
948f632f
DA
8000{
8001 unsigned short section;
8002 bfd_vma offset;
8003};
4d6ed7c8 8004
948f632f
DA
8005/* Find the nearest symbol at or below ADDR. Returns the symbol
8006 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 8007
4d6ed7c8 8008static void
dda8d76d
NC
8009find_symbol_for_address (Filedata * filedata,
8010 Elf_Internal_Sym * symtab,
8011 unsigned long nsyms,
8012 const char * strtab,
8013 unsigned long strtab_size,
8014 struct absaddr addr,
8015 const char ** symname,
8016 bfd_vma * offset)
4d6ed7c8 8017{
d3ba0551 8018 bfd_vma dist = 0x100000;
2cf0635d 8019 Elf_Internal_Sym * sym;
948f632f
DA
8020 Elf_Internal_Sym * beg;
8021 Elf_Internal_Sym * end;
2cf0635d 8022 Elf_Internal_Sym * best = NULL;
4d6ed7c8 8023
0b6ae522 8024 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
8025 beg = symtab;
8026 end = symtab + nsyms;
0b6ae522 8027
948f632f 8028 while (beg < end)
4d6ed7c8 8029 {
948f632f
DA
8030 bfd_vma value;
8031
8032 sym = beg + (end - beg) / 2;
0b6ae522 8033
948f632f 8034 value = sym->st_value;
0b6ae522
DJ
8035 REMOVE_ARCH_BITS (value);
8036
948f632f 8037 if (sym->st_name != 0
4d6ed7c8 8038 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
8039 && addr.offset >= value
8040 && addr.offset - value < dist)
4d6ed7c8
NC
8041 {
8042 best = sym;
0b6ae522 8043 dist = addr.offset - value;
4d6ed7c8
NC
8044 if (!dist)
8045 break;
8046 }
948f632f
DA
8047
8048 if (addr.offset < value)
8049 end = sym;
8050 else
8051 beg = sym + 1;
4d6ed7c8 8052 }
1b31d05e 8053
4d6ed7c8
NC
8054 if (best)
8055 {
57346661 8056 *symname = (best->st_name >= strtab_size
2b692964 8057 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
8058 *offset = dist;
8059 return;
8060 }
1b31d05e 8061
4d6ed7c8
NC
8062 *symname = NULL;
8063 *offset = addr.offset;
8064}
8065
32ec8896 8066static /* signed */ int
948f632f
DA
8067symcmp (const void *p, const void *q)
8068{
8069 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
8070 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
8071
8072 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
8073}
8074
8075/* Process the unwind section. */
8076
8077#include "unwind-ia64.h"
8078
8079struct ia64_unw_table_entry
8080{
8081 struct absaddr start;
8082 struct absaddr end;
8083 struct absaddr info;
8084};
8085
8086struct ia64_unw_aux_info
8087{
32ec8896
NC
8088 struct ia64_unw_table_entry * table; /* Unwind table. */
8089 unsigned long table_len; /* Length of unwind table. */
8090 unsigned char * info; /* Unwind info. */
8091 unsigned long info_size; /* Size of unwind info. */
8092 bfd_vma info_addr; /* Starting address of unwind info. */
8093 bfd_vma seg_base; /* Starting address of segment. */
8094 Elf_Internal_Sym * symtab; /* The symbol table. */
8095 unsigned long nsyms; /* Number of symbols. */
8096 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8097 unsigned long nfuns; /* Number of entries in funtab. */
8098 char * strtab; /* The string table. */
8099 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
8100};
8101
015dc7e1 8102static bool
dda8d76d 8103dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 8104{
2cf0635d 8105 struct ia64_unw_table_entry * tp;
948f632f 8106 unsigned long j, nfuns;
4d6ed7c8 8107 int in_body;
015dc7e1 8108 bool res = true;
7036c0e1 8109
948f632f
DA
8110 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8111 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8112 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8113 aux->funtab[nfuns++] = aux->symtab[j];
8114 aux->nfuns = nfuns;
8115 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
8116
4d6ed7c8
NC
8117 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8118 {
8119 bfd_vma stamp;
8120 bfd_vma offset;
2cf0635d
NC
8121 const unsigned char * dp;
8122 const unsigned char * head;
53774b7e 8123 const unsigned char * end;
2cf0635d 8124 const char * procname;
4d6ed7c8 8125
dda8d76d 8126 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 8127 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
8128
8129 fputs ("\n<", stdout);
8130
8131 if (procname)
8132 {
8133 fputs (procname, stdout);
8134
8135 if (offset)
8136 printf ("+%lx", (unsigned long) offset);
8137 }
8138
8139 fputs (">: [", stdout);
8140 print_vma (tp->start.offset, PREFIX_HEX);
8141 fputc ('-', stdout);
8142 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 8143 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
8144 (unsigned long) (tp->info.offset - aux->seg_base));
8145
53774b7e
NC
8146 /* PR 17531: file: 86232b32. */
8147 if (aux->info == NULL)
8148 continue;
8149
97c0a079
AM
8150 offset = tp->info.offset;
8151 if (tp->info.section)
8152 {
8153 if (tp->info.section >= filedata->file_header.e_shnum)
8154 {
8155 warn (_("Invalid section %u in table entry %ld\n"),
8156 tp->info.section, (long) (tp - aux->table));
015dc7e1 8157 res = false;
97c0a079
AM
8158 continue;
8159 }
8160 offset += filedata->section_headers[tp->info.section].sh_addr;
8161 }
8162 offset -= aux->info_addr;
53774b7e 8163 /* PR 17531: file: 0997b4d1. */
90679903
AM
8164 if (offset >= aux->info_size
8165 || aux->info_size - offset < 8)
53774b7e
NC
8166 {
8167 warn (_("Invalid offset %lx in table entry %ld\n"),
8168 (long) tp->info.offset, (long) (tp - aux->table));
015dc7e1 8169 res = false;
53774b7e
NC
8170 continue;
8171 }
8172
97c0a079 8173 head = aux->info + offset;
a4a00738 8174 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 8175
86f55779 8176 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
8177 (unsigned) UNW_VER (stamp),
8178 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
8179 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
8180 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 8181 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
8182
8183 if (UNW_VER (stamp) != 1)
8184 {
2b692964 8185 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
8186 continue;
8187 }
8188
8189 in_body = 0;
53774b7e
NC
8190 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
8191 /* PR 17531: file: 16ceda89. */
8192 if (end > aux->info + aux->info_size)
8193 end = aux->info + aux->info_size;
8194 for (dp = head + 8; dp < end;)
b4477bc8 8195 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 8196 }
948f632f
DA
8197
8198 free (aux->funtab);
32ec8896
NC
8199
8200 return res;
4d6ed7c8
NC
8201}
8202
015dc7e1 8203static bool
dda8d76d
NC
8204slurp_ia64_unwind_table (Filedata * filedata,
8205 struct ia64_unw_aux_info * aux,
8206 Elf_Internal_Shdr * sec)
4d6ed7c8 8207{
89fac5e3 8208 unsigned long size, nrelas, i;
2cf0635d
NC
8209 Elf_Internal_Phdr * seg;
8210 struct ia64_unw_table_entry * tep;
8211 Elf_Internal_Shdr * relsec;
8212 Elf_Internal_Rela * rela;
8213 Elf_Internal_Rela * rp;
8214 unsigned char * table;
8215 unsigned char * tp;
8216 Elf_Internal_Sym * sym;
8217 const char * relname;
4d6ed7c8 8218
53774b7e
NC
8219 aux->table_len = 0;
8220
4d6ed7c8
NC
8221 /* First, find the starting address of the segment that includes
8222 this section: */
8223
dda8d76d 8224 if (filedata->file_header.e_phnum)
4d6ed7c8 8225 {
dda8d76d 8226 if (! get_program_headers (filedata))
015dc7e1 8227 return false;
4d6ed7c8 8228
dda8d76d
NC
8229 for (seg = filedata->program_headers;
8230 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 8231 ++seg)
4d6ed7c8
NC
8232 {
8233 if (seg->p_type != PT_LOAD)
8234 continue;
8235
8236 if (sec->sh_addr >= seg->p_vaddr
8237 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8238 {
8239 aux->seg_base = seg->p_vaddr;
8240 break;
8241 }
8242 }
4d6ed7c8
NC
8243 }
8244
8245 /* Second, build the unwind table from the contents of the unwind section: */
8246 size = sec->sh_size;
dda8d76d 8247 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8248 _("unwind table"));
a6e9f9df 8249 if (!table)
015dc7e1 8250 return false;
4d6ed7c8 8251
53774b7e 8252 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 8253 aux->table = (struct ia64_unw_table_entry *)
53774b7e 8254 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 8255 tep = aux->table;
53774b7e
NC
8256
8257 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
8258 {
8259 tep->start.section = SHN_UNDEF;
8260 tep->end.section = SHN_UNDEF;
8261 tep->info.section = SHN_UNDEF;
c6a0c689
AM
8262 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8263 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
8264 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
8265 tep->start.offset += aux->seg_base;
8266 tep->end.offset += aux->seg_base;
8267 tep->info.offset += aux->seg_base;
8268 }
8269 free (table);
8270
41e92641 8271 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
8272 for (relsec = filedata->section_headers;
8273 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
8274 ++relsec)
8275 {
8276 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8277 || relsec->sh_info >= filedata->file_header.e_shnum
8278 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
8279 continue;
8280
dda8d76d 8281 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8282 & rela, & nrelas))
53774b7e
NC
8283 {
8284 free (aux->table);
8285 aux->table = NULL;
8286 aux->table_len = 0;
015dc7e1 8287 return false;
53774b7e 8288 }
4d6ed7c8
NC
8289
8290 for (rp = rela; rp < rela + nrelas; ++rp)
8291 {
4770fb94 8292 unsigned int sym_ndx;
726bd37d
AM
8293 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8294 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8295
82b1b41b
NC
8296 /* PR 17531: file: 9fa67536. */
8297 if (relname == NULL)
8298 {
726bd37d 8299 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8300 continue;
8301 }
948f632f 8302
24d127aa 8303 if (! startswith (relname, "R_IA64_SEGREL"))
4d6ed7c8 8304 {
82b1b41b 8305 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8306 continue;
8307 }
8308
89fac5e3 8309 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8310
53774b7e
NC
8311 /* PR 17531: file: 5bc8d9bf. */
8312 if (i >= aux->table_len)
8313 {
8314 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8315 continue;
8316 }
8317
4770fb94
AM
8318 sym_ndx = get_reloc_symindex (rp->r_info);
8319 if (sym_ndx >= aux->nsyms)
8320 {
8321 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8322 sym_ndx);
8323 continue;
8324 }
8325 sym = aux->symtab + sym_ndx;
8326
53774b7e 8327 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8328 {
8329 case 0:
8330 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8331 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8332 break;
8333 case 1:
8334 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8335 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8336 break;
8337 case 2:
8338 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8339 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8340 break;
8341 default:
8342 break;
8343 }
8344 }
8345
8346 free (rela);
8347 }
8348
015dc7e1 8349 return true;
4d6ed7c8
NC
8350}
8351
015dc7e1 8352static bool
dda8d76d 8353ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8354{
2cf0635d
NC
8355 Elf_Internal_Shdr * sec;
8356 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8357 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8358 struct ia64_unw_aux_info aux;
015dc7e1 8359 bool res = true;
f1467e33 8360
4d6ed7c8
NC
8361 memset (& aux, 0, sizeof (aux));
8362
dda8d76d 8363 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8364 {
28d13567 8365 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8366 {
28d13567 8367 if (aux.symtab)
4082ef84 8368 {
28d13567
AM
8369 error (_("Multiple symbol tables encountered\n"));
8370 free (aux.symtab);
8371 aux.symtab = NULL;
4082ef84 8372 free (aux.strtab);
28d13567 8373 aux.strtab = NULL;
4082ef84 8374 }
28d13567
AM
8375 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8376 &aux.strtab, &aux.strtab_size))
015dc7e1 8377 return false;
4d6ed7c8
NC
8378 }
8379 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8380 unwcount++;
8381 }
8382
8383 if (!unwcount)
8384 printf (_("\nThere are no unwind sections in this file.\n"));
8385
8386 while (unwcount-- > 0)
8387 {
2cf0635d 8388 char * suffix;
579f31ac
JJ
8389 size_t len, len2;
8390
dda8d76d
NC
8391 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8392 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8393 if (sec->sh_type == SHT_IA_64_UNWIND)
8394 {
8395 unwsec = sec;
8396 break;
8397 }
4082ef84
NC
8398 /* We have already counted the number of SHT_IA64_UNWIND
8399 sections so the loop above should never fail. */
8400 assert (unwsec != NULL);
579f31ac
JJ
8401
8402 unwstart = i + 1;
8403 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8404
e4b17d5c
L
8405 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8406 {
8407 /* We need to find which section group it is in. */
4082ef84 8408 struct group_list * g;
e4b17d5c 8409
978c4450
AM
8410 if (filedata->section_headers_groups == NULL
8411 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8412 i = filedata->file_header.e_shnum;
4082ef84 8413 else
e4b17d5c 8414 {
978c4450 8415 g = filedata->section_headers_groups[i]->root;
18bd398b 8416
4082ef84
NC
8417 for (; g != NULL; g = g->next)
8418 {
dda8d76d 8419 sec = filedata->section_headers + g->section_index;
e4b17d5c 8420
b9e920ec
AM
8421 if (SECTION_NAME_VALID (sec)
8422 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8423 break;
8424 }
8425
8426 if (g == NULL)
dda8d76d 8427 i = filedata->file_header.e_shnum;
4082ef84 8428 }
e4b17d5c 8429 }
b9e920ec 8430 else if (SECTION_NAME_VALID (unwsec)
e9b095a5
ML
8431 && startswith (SECTION_NAME (unwsec),
8432 ELF_STRING_ia64_unwind_once))
579f31ac 8433 {
18bd398b 8434 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8435 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8436 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8437 for (i = 0, sec = filedata->section_headers;
8438 i < filedata->file_header.e_shnum;
579f31ac 8439 ++i, ++sec)
b9e920ec 8440 if (SECTION_NAME_VALID (sec)
e9b095a5
ML
8441 && startswith (SECTION_NAME (sec),
8442 ELF_STRING_ia64_unwind_info_once)
18bd398b 8443 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8444 break;
8445 }
8446 else
8447 {
8448 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8449 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8450 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8451 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8452 suffix = "";
b9e920ec 8453 if (SECTION_NAME_VALID (unwsec)
e9b095a5 8454 && startswith (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind))
579f31ac 8455 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8456 for (i = 0, sec = filedata->section_headers;
8457 i < filedata->file_header.e_shnum;
579f31ac 8458 ++i, ++sec)
b9e920ec 8459 if (SECTION_NAME_VALID (sec)
e9b095a5 8460 && startswith (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info)
18bd398b 8461 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8462 break;
8463 }
8464
dda8d76d 8465 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8466 {
8467 printf (_("\nCould not find unwind info section for "));
8468
dda8d76d 8469 if (filedata->string_table == NULL)
579f31ac
JJ
8470 printf ("%d", unwsec->sh_name);
8471 else
dda8d76d 8472 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8473 }
8474 else
4d6ed7c8 8475 {
4d6ed7c8 8476 aux.info_addr = sec->sh_addr;
dda8d76d 8477 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8478 sec->sh_size,
8479 _("unwind info"));
59245841 8480 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8481
579f31ac 8482 printf (_("\nUnwind section "));
4d6ed7c8 8483
dda8d76d 8484 if (filedata->string_table == NULL)
579f31ac
JJ
8485 printf ("%d", unwsec->sh_name);
8486 else
dda8d76d 8487 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8488
579f31ac 8489 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8490 (unsigned long) unwsec->sh_offset,
89fac5e3 8491 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8492
dda8d76d 8493 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8494 && aux.table_len > 0)
dda8d76d 8495 dump_ia64_unwind (filedata, & aux);
579f31ac 8496
9db70fc3
AM
8497 free ((char *) aux.table);
8498 free ((char *) aux.info);
579f31ac
JJ
8499 aux.table = NULL;
8500 aux.info = NULL;
8501 }
4d6ed7c8 8502 }
4d6ed7c8 8503
9db70fc3
AM
8504 free (aux.symtab);
8505 free ((char *) aux.strtab);
32ec8896
NC
8506
8507 return res;
4d6ed7c8
NC
8508}
8509
3f5e193b 8510struct hppa_unw_table_entry
32ec8896
NC
8511{
8512 struct absaddr start;
8513 struct absaddr end;
8514 unsigned int Cannot_unwind:1; /* 0 */
8515 unsigned int Millicode:1; /* 1 */
8516 unsigned int Millicode_save_sr0:1; /* 2 */
8517 unsigned int Region_description:2; /* 3..4 */
8518 unsigned int reserved1:1; /* 5 */
8519 unsigned int Entry_SR:1; /* 6 */
8520 unsigned int Entry_FR:4; /* Number saved 7..10 */
8521 unsigned int Entry_GR:5; /* Number saved 11..15 */
8522 unsigned int Args_stored:1; /* 16 */
8523 unsigned int Variable_Frame:1; /* 17 */
8524 unsigned int Separate_Package_Body:1; /* 18 */
8525 unsigned int Frame_Extension_Millicode:1; /* 19 */
8526 unsigned int Stack_Overflow_Check:1; /* 20 */
8527 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8528 unsigned int Ada_Region:1; /* 22 */
8529 unsigned int cxx_info:1; /* 23 */
8530 unsigned int cxx_try_catch:1; /* 24 */
8531 unsigned int sched_entry_seq:1; /* 25 */
8532 unsigned int reserved2:1; /* 26 */
8533 unsigned int Save_SP:1; /* 27 */
8534 unsigned int Save_RP:1; /* 28 */
8535 unsigned int Save_MRP_in_frame:1; /* 29 */
8536 unsigned int extn_ptr_defined:1; /* 30 */
8537 unsigned int Cleanup_defined:1; /* 31 */
8538
8539 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8540 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8541 unsigned int Large_frame:1; /* 2 */
8542 unsigned int Pseudo_SP_Set:1; /* 3 */
8543 unsigned int reserved4:1; /* 4 */
8544 unsigned int Total_frame_size:27; /* 5..31 */
8545};
3f5e193b 8546
57346661 8547struct hppa_unw_aux_info
948f632f 8548{
32ec8896
NC
8549 struct hppa_unw_table_entry * table; /* Unwind table. */
8550 unsigned long table_len; /* Length of unwind table. */
8551 bfd_vma seg_base; /* Starting address of segment. */
8552 Elf_Internal_Sym * symtab; /* The symbol table. */
8553 unsigned long nsyms; /* Number of symbols. */
8554 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8555 unsigned long nfuns; /* Number of entries in funtab. */
8556 char * strtab; /* The string table. */
8557 unsigned long strtab_size; /* Size of string table. */
948f632f 8558};
57346661 8559
015dc7e1 8560static bool
dda8d76d 8561dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8562{
2cf0635d 8563 struct hppa_unw_table_entry * tp;
948f632f 8564 unsigned long j, nfuns;
015dc7e1 8565 bool res = true;
948f632f
DA
8566
8567 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8568 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8569 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8570 aux->funtab[nfuns++] = aux->symtab[j];
8571 aux->nfuns = nfuns;
8572 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8573
57346661
AM
8574 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8575 {
8576 bfd_vma offset;
2cf0635d 8577 const char * procname;
57346661 8578
dda8d76d 8579 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8580 aux->strtab_size, tp->start, &procname,
8581 &offset);
8582
8583 fputs ("\n<", stdout);
8584
8585 if (procname)
8586 {
8587 fputs (procname, stdout);
8588
8589 if (offset)
8590 printf ("+%lx", (unsigned long) offset);
8591 }
8592
8593 fputs (">: [", stdout);
8594 print_vma (tp->start.offset, PREFIX_HEX);
8595 fputc ('-', stdout);
8596 print_vma (tp->end.offset, PREFIX_HEX);
8597 printf ("]\n\t");
8598
18bd398b
NC
8599#define PF(_m) if (tp->_m) printf (#_m " ");
8600#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8601 PF(Cannot_unwind);
8602 PF(Millicode);
8603 PF(Millicode_save_sr0);
18bd398b 8604 /* PV(Region_description); */
57346661
AM
8605 PF(Entry_SR);
8606 PV(Entry_FR);
8607 PV(Entry_GR);
8608 PF(Args_stored);
8609 PF(Variable_Frame);
8610 PF(Separate_Package_Body);
8611 PF(Frame_Extension_Millicode);
8612 PF(Stack_Overflow_Check);
8613 PF(Two_Instruction_SP_Increment);
8614 PF(Ada_Region);
8615 PF(cxx_info);
8616 PF(cxx_try_catch);
8617 PF(sched_entry_seq);
8618 PF(Save_SP);
8619 PF(Save_RP);
8620 PF(Save_MRP_in_frame);
8621 PF(extn_ptr_defined);
8622 PF(Cleanup_defined);
8623 PF(MPE_XL_interrupt_marker);
8624 PF(HP_UX_interrupt_marker);
8625 PF(Large_frame);
8626 PF(Pseudo_SP_Set);
8627 PV(Total_frame_size);
8628#undef PF
8629#undef PV
8630 }
8631
18bd398b 8632 printf ("\n");
948f632f
DA
8633
8634 free (aux->funtab);
32ec8896
NC
8635
8636 return res;
57346661
AM
8637}
8638
015dc7e1 8639static bool
dda8d76d
NC
8640slurp_hppa_unwind_table (Filedata * filedata,
8641 struct hppa_unw_aux_info * aux,
8642 Elf_Internal_Shdr * sec)
57346661 8643{
1c0751b2 8644 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8645 Elf_Internal_Phdr * seg;
8646 struct hppa_unw_table_entry * tep;
8647 Elf_Internal_Shdr * relsec;
8648 Elf_Internal_Rela * rela;
8649 Elf_Internal_Rela * rp;
8650 unsigned char * table;
8651 unsigned char * tp;
8652 Elf_Internal_Sym * sym;
8653 const char * relname;
57346661 8654
57346661
AM
8655 /* First, find the starting address of the segment that includes
8656 this section. */
dda8d76d 8657 if (filedata->file_header.e_phnum)
57346661 8658 {
dda8d76d 8659 if (! get_program_headers (filedata))
015dc7e1 8660 return false;
57346661 8661
dda8d76d
NC
8662 for (seg = filedata->program_headers;
8663 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8664 ++seg)
8665 {
8666 if (seg->p_type != PT_LOAD)
8667 continue;
8668
8669 if (sec->sh_addr >= seg->p_vaddr
8670 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8671 {
8672 aux->seg_base = seg->p_vaddr;
8673 break;
8674 }
8675 }
8676 }
8677
8678 /* Second, build the unwind table from the contents of the unwind
8679 section. */
8680 size = sec->sh_size;
dda8d76d 8681 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8682 _("unwind table"));
57346661 8683 if (!table)
015dc7e1 8684 return false;
57346661 8685
1c0751b2
DA
8686 unw_ent_size = 16;
8687 nentries = size / unw_ent_size;
8688 size = unw_ent_size * nentries;
57346661 8689
e3fdc001 8690 aux->table_len = nentries;
3f5e193b
NC
8691 tep = aux->table = (struct hppa_unw_table_entry *)
8692 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8693
1c0751b2 8694 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8695 {
8696 unsigned int tmp1, tmp2;
8697
8698 tep->start.section = SHN_UNDEF;
8699 tep->end.section = SHN_UNDEF;
8700
1c0751b2
DA
8701 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8702 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8703 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8704 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8705
8706 tep->start.offset += aux->seg_base;
8707 tep->end.offset += aux->seg_base;
57346661
AM
8708
8709 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8710 tep->Millicode = (tmp1 >> 30) & 0x1;
8711 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8712 tep->Region_description = (tmp1 >> 27) & 0x3;
8713 tep->reserved1 = (tmp1 >> 26) & 0x1;
8714 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8715 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8716 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8717 tep->Args_stored = (tmp1 >> 15) & 0x1;
8718 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8719 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8720 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8721 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8722 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8723 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8724 tep->cxx_info = (tmp1 >> 8) & 0x1;
8725 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8726 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8727 tep->reserved2 = (tmp1 >> 5) & 0x1;
8728 tep->Save_SP = (tmp1 >> 4) & 0x1;
8729 tep->Save_RP = (tmp1 >> 3) & 0x1;
8730 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8731 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8732 tep->Cleanup_defined = tmp1 & 0x1;
8733
8734 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8735 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8736 tep->Large_frame = (tmp2 >> 29) & 0x1;
8737 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8738 tep->reserved4 = (tmp2 >> 27) & 0x1;
8739 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8740 }
8741 free (table);
8742
8743 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8744 for (relsec = filedata->section_headers;
8745 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8746 ++relsec)
8747 {
8748 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8749 || relsec->sh_info >= filedata->file_header.e_shnum
8750 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8751 continue;
8752
dda8d76d 8753 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8754 & rela, & nrelas))
015dc7e1 8755 return false;
57346661
AM
8756
8757 for (rp = rela; rp < rela + nrelas; ++rp)
8758 {
4770fb94 8759 unsigned int sym_ndx;
726bd37d
AM
8760 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8761 relname = elf_hppa_reloc_type (r_type);
57346661 8762
726bd37d
AM
8763 if (relname == NULL)
8764 {
8765 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8766 continue;
8767 }
8768
57346661 8769 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
24d127aa 8770 if (! startswith (relname, "R_PARISC_SEGREL"))
57346661 8771 {
726bd37d 8772 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8773 continue;
8774 }
8775
8776 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8777 if (i >= aux->table_len)
8778 {
8779 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8780 continue;
8781 }
57346661 8782
4770fb94
AM
8783 sym_ndx = get_reloc_symindex (rp->r_info);
8784 if (sym_ndx >= aux->nsyms)
8785 {
8786 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8787 sym_ndx);
8788 continue;
8789 }
8790 sym = aux->symtab + sym_ndx;
8791
43f6cd05 8792 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8793 {
8794 case 0:
8795 aux->table[i].start.section = sym->st_shndx;
1e456d54 8796 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8797 break;
8798 case 1:
8799 aux->table[i].end.section = sym->st_shndx;
1e456d54 8800 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8801 break;
8802 default:
8803 break;
8804 }
8805 }
8806
8807 free (rela);
8808 }
8809
015dc7e1 8810 return true;
57346661
AM
8811}
8812
015dc7e1 8813static bool
dda8d76d 8814hppa_process_unwind (Filedata * filedata)
57346661 8815{
57346661 8816 struct hppa_unw_aux_info aux;
2cf0635d 8817 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8818 Elf_Internal_Shdr * sec;
18bd398b 8819 unsigned long i;
015dc7e1 8820 bool res = true;
57346661 8821
dda8d76d 8822 if (filedata->string_table == NULL)
015dc7e1 8823 return false;
1b31d05e
NC
8824
8825 memset (& aux, 0, sizeof (aux));
57346661 8826
dda8d76d 8827 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8828 {
28d13567 8829 if (sec->sh_type == SHT_SYMTAB)
57346661 8830 {
28d13567 8831 if (aux.symtab)
4082ef84 8832 {
28d13567
AM
8833 error (_("Multiple symbol tables encountered\n"));
8834 free (aux.symtab);
8835 aux.symtab = NULL;
4082ef84 8836 free (aux.strtab);
28d13567 8837 aux.strtab = NULL;
4082ef84 8838 }
28d13567
AM
8839 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8840 &aux.strtab, &aux.strtab_size))
015dc7e1 8841 return false;
57346661 8842 }
b9e920ec
AM
8843 else if (SECTION_NAME_VALID (sec)
8844 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8845 unwsec = sec;
8846 }
8847
8848 if (!unwsec)
8849 printf (_("\nThere are no unwind sections in this file.\n"));
8850
dda8d76d 8851 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8852 {
b9e920ec
AM
8853 if (SECTION_NAME_VALID (sec)
8854 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8855 {
43f6cd05 8856 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8857
d3a49aa8
AM
8858 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8859 "contains %lu entry:\n",
8860 "\nUnwind section '%s' at offset 0x%lx "
8861 "contains %lu entries:\n",
8862 num_unwind),
dda8d76d 8863 printable_section_name (filedata, sec),
57346661 8864 (unsigned long) sec->sh_offset,
d3a49aa8 8865 num_unwind);
57346661 8866
dda8d76d 8867 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
015dc7e1 8868 res = false;
66b09c7e
S
8869
8870 if (res && aux.table_len > 0)
32ec8896 8871 {
dda8d76d 8872 if (! dump_hppa_unwind (filedata, &aux))
015dc7e1 8873 res = false;
32ec8896 8874 }
57346661 8875
9db70fc3 8876 free ((char *) aux.table);
57346661
AM
8877 aux.table = NULL;
8878 }
8879 }
8880
9db70fc3
AM
8881 free (aux.symtab);
8882 free ((char *) aux.strtab);
32ec8896
NC
8883
8884 return res;
57346661
AM
8885}
8886
0b6ae522
DJ
8887struct arm_section
8888{
a734115a
NC
8889 unsigned char * data; /* The unwind data. */
8890 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8891 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8892 unsigned long nrelas; /* The number of relocations. */
8893 unsigned int rel_type; /* REL or RELA ? */
8894 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8895};
8896
8897struct arm_unw_aux_info
8898{
dda8d76d 8899 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8900 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8901 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8902 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8903 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8904 char * strtab; /* The file's string table. */
8905 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8906};
8907
8908static const char *
dda8d76d
NC
8909arm_print_vma_and_name (Filedata * filedata,
8910 struct arm_unw_aux_info * aux,
8911 bfd_vma fn,
8912 struct absaddr addr)
0b6ae522
DJ
8913{
8914 const char *procname;
8915 bfd_vma sym_offset;
8916
8917 if (addr.section == SHN_UNDEF)
8918 addr.offset = fn;
8919
dda8d76d 8920 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8921 aux->strtab_size, addr, &procname,
8922 &sym_offset);
8923
8924 print_vma (fn, PREFIX_HEX);
8925
8926 if (procname)
8927 {
8928 fputs (" <", stdout);
8929 fputs (procname, stdout);
8930
8931 if (sym_offset)
8932 printf ("+0x%lx", (unsigned long) sym_offset);
8933 fputc ('>', stdout);
8934 }
8935
8936 return procname;
8937}
8938
8939static void
8940arm_free_section (struct arm_section *arm_sec)
8941{
9db70fc3
AM
8942 free (arm_sec->data);
8943 free (arm_sec->rela);
0b6ae522
DJ
8944}
8945
a734115a
NC
8946/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8947 cached section and install SEC instead.
8948 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8949 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8950 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8951 relocation's offset in ADDR.
1b31d05e
NC
8952 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8953 into the string table of the symbol associated with the reloc. If no
8954 reloc was applied store -1 there.
8955 5) Return TRUE upon success, FALSE otherwise. */
a734115a 8956
015dc7e1 8957static bool
dda8d76d
NC
8958get_unwind_section_word (Filedata * filedata,
8959 struct arm_unw_aux_info * aux,
1b31d05e
NC
8960 struct arm_section * arm_sec,
8961 Elf_Internal_Shdr * sec,
8962 bfd_vma word_offset,
8963 unsigned int * wordp,
8964 struct absaddr * addr,
8965 bfd_vma * sym_name)
0b6ae522
DJ
8966{
8967 Elf_Internal_Rela *rp;
8968 Elf_Internal_Sym *sym;
8969 const char * relname;
8970 unsigned int word;
015dc7e1 8971 bool wrapped;
0b6ae522 8972
e0a31db1 8973 if (sec == NULL || arm_sec == NULL)
015dc7e1 8974 return false;
e0a31db1 8975
0b6ae522
DJ
8976 addr->section = SHN_UNDEF;
8977 addr->offset = 0;
8978
1b31d05e
NC
8979 if (sym_name != NULL)
8980 *sym_name = (bfd_vma) -1;
8981
a734115a 8982 /* If necessary, update the section cache. */
0b6ae522
DJ
8983 if (sec != arm_sec->sec)
8984 {
8985 Elf_Internal_Shdr *relsec;
8986
8987 arm_free_section (arm_sec);
8988
8989 arm_sec->sec = sec;
dda8d76d 8990 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8991 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8992 arm_sec->rela = NULL;
8993 arm_sec->nrelas = 0;
8994
dda8d76d
NC
8995 for (relsec = filedata->section_headers;
8996 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8997 ++relsec)
8998 {
dda8d76d
NC
8999 if (relsec->sh_info >= filedata->file_header.e_shnum
9000 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
9001 /* PR 15745: Check the section type as well. */
9002 || (relsec->sh_type != SHT_REL
9003 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
9004 continue;
9005
a734115a 9006 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
9007 if (relsec->sh_type == SHT_REL)
9008 {
dda8d76d 9009 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9010 relsec->sh_size,
9011 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9012 return false;
0b6ae522 9013 }
1ae40aa4 9014 else /* relsec->sh_type == SHT_RELA */
0b6ae522 9015 {
dda8d76d 9016 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
9017 relsec->sh_size,
9018 & arm_sec->rela, & arm_sec->nrelas))
015dc7e1 9019 return false;
0b6ae522 9020 }
1ae40aa4 9021 break;
0b6ae522
DJ
9022 }
9023
9024 arm_sec->next_rela = arm_sec->rela;
9025 }
9026
a734115a 9027 /* If there is no unwind data we can do nothing. */
0b6ae522 9028 if (arm_sec->data == NULL)
015dc7e1 9029 return false;
0b6ae522 9030
e0a31db1 9031 /* If the offset is invalid then fail. */
f32ba729
NC
9032 if (/* PR 21343 *//* PR 18879 */
9033 sec->sh_size < 4
9034 || word_offset > (sec->sh_size - 4)
1a915552 9035 || ((bfd_signed_vma) word_offset) < 0)
015dc7e1 9036 return false;
e0a31db1 9037
a734115a 9038 /* Get the word at the required offset. */
0b6ae522
DJ
9039 word = byte_get (arm_sec->data + word_offset, 4);
9040
0eff7165
NC
9041 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
9042 if (arm_sec->rela == NULL)
9043 {
9044 * wordp = word;
015dc7e1 9045 return true;
0eff7165
NC
9046 }
9047
a734115a 9048 /* Look through the relocs to find the one that applies to the provided offset. */
015dc7e1 9049 wrapped = false;
0b6ae522
DJ
9050 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
9051 {
9052 bfd_vma prelval, offset;
9053
9054 if (rp->r_offset > word_offset && !wrapped)
9055 {
9056 rp = arm_sec->rela;
015dc7e1 9057 wrapped = true;
0b6ae522
DJ
9058 }
9059 if (rp->r_offset > word_offset)
9060 break;
9061
9062 if (rp->r_offset & 3)
9063 {
9064 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
9065 (unsigned long) rp->r_offset);
9066 continue;
9067 }
9068
9069 if (rp->r_offset < word_offset)
9070 continue;
9071
74e1a04b
NC
9072 /* PR 17531: file: 027-161405-0.004 */
9073 if (aux->symtab == NULL)
9074 continue;
9075
0b6ae522
DJ
9076 if (arm_sec->rel_type == SHT_REL)
9077 {
9078 offset = word & 0x7fffffff;
9079 if (offset & 0x40000000)
9080 offset |= ~ (bfd_vma) 0x7fffffff;
9081 }
a734115a 9082 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 9083 offset = rp->r_addend;
a734115a 9084 else
74e1a04b
NC
9085 {
9086 error (_("Unknown section relocation type %d encountered\n"),
9087 arm_sec->rel_type);
9088 break;
9089 }
0b6ae522 9090
071436c6
NC
9091 /* PR 17531 file: 027-1241568-0.004. */
9092 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
9093 {
9094 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
9095 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
9096 break;
9097 }
9098
9099 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
9100 offset += sym->st_value;
9101 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
9102
a734115a 9103 /* Check that we are processing the expected reloc type. */
dda8d76d 9104 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
9105 {
9106 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9107 if (relname == NULL)
9108 {
9109 warn (_("Skipping unknown ARM relocation type: %d\n"),
9110 (int) ELF32_R_TYPE (rp->r_info));
9111 continue;
9112 }
a734115a
NC
9113
9114 if (streq (relname, "R_ARM_NONE"))
9115 continue;
0b4362b0 9116
a734115a
NC
9117 if (! streq (relname, "R_ARM_PREL31"))
9118 {
071436c6 9119 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
9120 continue;
9121 }
9122 }
dda8d76d 9123 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
9124 {
9125 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
9126 if (relname == NULL)
9127 {
9128 warn (_("Skipping unknown C6000 relocation type: %d\n"),
9129 (int) ELF32_R_TYPE (rp->r_info));
9130 continue;
9131 }
0b4362b0 9132
a734115a
NC
9133 if (streq (relname, "R_C6000_NONE"))
9134 continue;
9135
9136 if (! streq (relname, "R_C6000_PREL31"))
9137 {
071436c6 9138 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
9139 continue;
9140 }
9141
9142 prelval >>= 1;
9143 }
9144 else
74e1a04b
NC
9145 {
9146 /* This function currently only supports ARM and TI unwinders. */
9147 warn (_("Only TI and ARM unwinders are currently supported\n"));
9148 break;
9149 }
fa197c1c 9150
0b6ae522
DJ
9151 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
9152 addr->section = sym->st_shndx;
9153 addr->offset = offset;
74e1a04b 9154
1b31d05e
NC
9155 if (sym_name)
9156 * sym_name = sym->st_name;
0b6ae522
DJ
9157 break;
9158 }
9159
9160 *wordp = word;
9161 arm_sec->next_rela = rp;
9162
015dc7e1 9163 return true;
0b6ae522
DJ
9164}
9165
a734115a
NC
9166static const char *tic6x_unwind_regnames[16] =
9167{
0b4362b0
RM
9168 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
9169 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
9170 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
9171};
fa197c1c 9172
0b6ae522 9173static void
fa197c1c 9174decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 9175{
fa197c1c
PB
9176 int i;
9177
9178 for (i = 12; mask; mask >>= 1, i--)
9179 {
9180 if (mask & 1)
9181 {
9182 fputs (tic6x_unwind_regnames[i], stdout);
9183 if (mask > 1)
9184 fputs (", ", stdout);
9185 }
9186 }
9187}
0b6ae522
DJ
9188
9189#define ADVANCE \
9190 if (remaining == 0 && more_words) \
9191 { \
9192 data_offset += 4; \
dda8d76d 9193 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 9194 data_offset, & word, & addr, NULL)) \
015dc7e1 9195 return false; \
0b6ae522
DJ
9196 remaining = 4; \
9197 more_words--; \
9198 } \
9199
9200#define GET_OP(OP) \
9201 ADVANCE; \
9202 if (remaining) \
9203 { \
9204 remaining--; \
9205 (OP) = word >> 24; \
9206 word <<= 8; \
9207 } \
9208 else \
9209 { \
2b692964 9210 printf (_("[Truncated opcode]\n")); \
015dc7e1 9211 return false; \
0b6ae522 9212 } \
cc5914eb 9213 printf ("0x%02x ", OP)
0b6ae522 9214
015dc7e1 9215static bool
dda8d76d
NC
9216decode_arm_unwind_bytecode (Filedata * filedata,
9217 struct arm_unw_aux_info * aux,
948f632f
DA
9218 unsigned int word,
9219 unsigned int remaining,
9220 unsigned int more_words,
9221 bfd_vma data_offset,
9222 Elf_Internal_Shdr * data_sec,
9223 struct arm_section * data_arm_sec)
fa197c1c
PB
9224{
9225 struct absaddr addr;
015dc7e1 9226 bool res = true;
0b6ae522
DJ
9227
9228 /* Decode the unwinding instructions. */
9229 while (1)
9230 {
9231 unsigned int op, op2;
9232
9233 ADVANCE;
9234 if (remaining == 0)
9235 break;
9236 remaining--;
9237 op = word >> 24;
9238 word <<= 8;
9239
cc5914eb 9240 printf (" 0x%02x ", op);
0b6ae522
DJ
9241
9242 if ((op & 0xc0) == 0x00)
9243 {
9244 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9245
cc5914eb 9246 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
9247 }
9248 else if ((op & 0xc0) == 0x40)
9249 {
9250 int offset = ((op & 0x3f) << 2) + 4;
61865e30 9251
cc5914eb 9252 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
9253 }
9254 else if ((op & 0xf0) == 0x80)
9255 {
9256 GET_OP (op2);
9257 if (op == 0x80 && op2 == 0)
9258 printf (_("Refuse to unwind"));
9259 else
9260 {
9261 unsigned int mask = ((op & 0x0f) << 8) | op2;
015dc7e1 9262 bool first = true;
0b6ae522 9263 int i;
2b692964 9264
0b6ae522
DJ
9265 printf ("pop {");
9266 for (i = 0; i < 12; i++)
9267 if (mask & (1 << i))
9268 {
9269 if (first)
015dc7e1 9270 first = false;
0b6ae522
DJ
9271 else
9272 printf (", ");
9273 printf ("r%d", 4 + i);
9274 }
9275 printf ("}");
9276 }
9277 }
9278 else if ((op & 0xf0) == 0x90)
9279 {
9280 if (op == 0x9d || op == 0x9f)
9281 printf (_(" [Reserved]"));
9282 else
cc5914eb 9283 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9284 }
9285 else if ((op & 0xf0) == 0xa0)
9286 {
9287 int end = 4 + (op & 0x07);
015dc7e1 9288 bool first = true;
0b6ae522 9289 int i;
61865e30 9290
0b6ae522
DJ
9291 printf (" pop {");
9292 for (i = 4; i <= end; i++)
9293 {
9294 if (first)
015dc7e1 9295 first = false;
0b6ae522
DJ
9296 else
9297 printf (", ");
9298 printf ("r%d", i);
9299 }
9300 if (op & 0x08)
9301 {
1b31d05e 9302 if (!first)
0b6ae522
DJ
9303 printf (", ");
9304 printf ("r14");
9305 }
9306 printf ("}");
9307 }
9308 else if (op == 0xb0)
9309 printf (_(" finish"));
9310 else if (op == 0xb1)
9311 {
9312 GET_OP (op2);
9313 if (op2 == 0 || (op2 & 0xf0) != 0)
9314 printf (_("[Spare]"));
9315 else
9316 {
9317 unsigned int mask = op2 & 0x0f;
015dc7e1 9318 bool first = true;
0b6ae522 9319 int i;
61865e30 9320
0b6ae522
DJ
9321 printf ("pop {");
9322 for (i = 0; i < 12; i++)
9323 if (mask & (1 << i))
9324 {
9325 if (first)
015dc7e1 9326 first = false;
0b6ae522
DJ
9327 else
9328 printf (", ");
9329 printf ("r%d", i);
9330 }
9331 printf ("}");
9332 }
9333 }
9334 else if (op == 0xb2)
9335 {
b115cf96 9336 unsigned char buf[9];
0b6ae522
DJ
9337 unsigned int i, len;
9338 unsigned long offset;
61865e30 9339
b115cf96 9340 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9341 {
9342 GET_OP (buf[i]);
9343 if ((buf[i] & 0x80) == 0)
9344 break;
9345 }
4082ef84 9346 if (i == sizeof (buf))
32ec8896 9347 {
27a45f42 9348 error (_("corrupt change to vsp\n"));
015dc7e1 9349 res = false;
32ec8896 9350 }
4082ef84
NC
9351 else
9352 {
015dc7e1 9353 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
4082ef84
NC
9354 assert (len == i + 1);
9355 offset = offset * 4 + 0x204;
9356 printf ("vsp = vsp + %ld", offset);
9357 }
0b6ae522 9358 }
61865e30 9359 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9360 {
61865e30
NC
9361 unsigned int first, last;
9362
9363 GET_OP (op2);
9364 first = op2 >> 4;
9365 last = op2 & 0x0f;
9366 if (op == 0xc8)
9367 first = first + 16;
9368 printf ("pop {D%d", first);
9369 if (last)
9370 printf ("-D%d", first + last);
9371 printf ("}");
9372 }
9373 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9374 {
9375 unsigned int count = op & 0x07;
9376
9377 printf ("pop {D8");
9378 if (count)
9379 printf ("-D%d", 8 + count);
9380 printf ("}");
9381 }
9382 else if (op >= 0xc0 && op <= 0xc5)
9383 {
9384 unsigned int count = op & 0x07;
9385
9386 printf (" pop {wR10");
9387 if (count)
9388 printf ("-wR%d", 10 + count);
9389 printf ("}");
9390 }
9391 else if (op == 0xc6)
9392 {
9393 unsigned int first, last;
9394
9395 GET_OP (op2);
9396 first = op2 >> 4;
9397 last = op2 & 0x0f;
9398 printf ("pop {wR%d", first);
9399 if (last)
9400 printf ("-wR%d", first + last);
9401 printf ("}");
9402 }
9403 else if (op == 0xc7)
9404 {
9405 GET_OP (op2);
9406 if (op2 == 0 || (op2 & 0xf0) != 0)
9407 printf (_("[Spare]"));
0b6ae522
DJ
9408 else
9409 {
61865e30 9410 unsigned int mask = op2 & 0x0f;
015dc7e1 9411 bool first = true;
61865e30
NC
9412 int i;
9413
9414 printf ("pop {");
9415 for (i = 0; i < 4; i++)
9416 if (mask & (1 << i))
9417 {
9418 if (first)
015dc7e1 9419 first = false;
61865e30
NC
9420 else
9421 printf (", ");
9422 printf ("wCGR%d", i);
9423 }
9424 printf ("}");
0b6ae522
DJ
9425 }
9426 }
61865e30 9427 else
32ec8896
NC
9428 {
9429 printf (_(" [unsupported opcode]"));
015dc7e1 9430 res = false;
32ec8896
NC
9431 }
9432
0b6ae522
DJ
9433 printf ("\n");
9434 }
32ec8896
NC
9435
9436 return res;
fa197c1c
PB
9437}
9438
015dc7e1 9439static bool
dda8d76d
NC
9440decode_tic6x_unwind_bytecode (Filedata * filedata,
9441 struct arm_unw_aux_info * aux,
948f632f
DA
9442 unsigned int word,
9443 unsigned int remaining,
9444 unsigned int more_words,
9445 bfd_vma data_offset,
9446 Elf_Internal_Shdr * data_sec,
9447 struct arm_section * data_arm_sec)
fa197c1c
PB
9448{
9449 struct absaddr addr;
9450
9451 /* Decode the unwinding instructions. */
9452 while (1)
9453 {
9454 unsigned int op, op2;
9455
9456 ADVANCE;
9457 if (remaining == 0)
9458 break;
9459 remaining--;
9460 op = word >> 24;
9461 word <<= 8;
9462
9cf03b7e 9463 printf (" 0x%02x ", op);
fa197c1c
PB
9464
9465 if ((op & 0xc0) == 0x00)
9466 {
9467 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9468 printf (" sp = sp + %d", offset);
fa197c1c
PB
9469 }
9470 else if ((op & 0xc0) == 0x80)
9471 {
9472 GET_OP (op2);
9473 if (op == 0x80 && op2 == 0)
9474 printf (_("Refuse to unwind"));
9475 else
9476 {
9477 unsigned int mask = ((op & 0x1f) << 8) | op2;
9478 if (op & 0x20)
9479 printf ("pop compact {");
9480 else
9481 printf ("pop {");
9482
9483 decode_tic6x_unwind_regmask (mask);
9484 printf("}");
9485 }
9486 }
9487 else if ((op & 0xf0) == 0xc0)
9488 {
9489 unsigned int reg;
9490 unsigned int nregs;
9491 unsigned int i;
9492 const char *name;
a734115a
NC
9493 struct
9494 {
32ec8896
NC
9495 unsigned int offset;
9496 unsigned int reg;
fa197c1c
PB
9497 } regpos[16];
9498
9499 /* Scan entire instruction first so that GET_OP output is not
9500 interleaved with disassembly. */
9501 nregs = 0;
9502 for (i = 0; nregs < (op & 0xf); i++)
9503 {
9504 GET_OP (op2);
9505 reg = op2 >> 4;
9506 if (reg != 0xf)
9507 {
9508 regpos[nregs].offset = i * 2;
9509 regpos[nregs].reg = reg;
9510 nregs++;
9511 }
9512
9513 reg = op2 & 0xf;
9514 if (reg != 0xf)
9515 {
9516 regpos[nregs].offset = i * 2 + 1;
9517 regpos[nregs].reg = reg;
9518 nregs++;
9519 }
9520 }
9521
9522 printf (_("pop frame {"));
18344509 9523 if (nregs == 0)
fa197c1c 9524 {
18344509
NC
9525 printf (_("*corrupt* - no registers specified"));
9526 }
9527 else
9528 {
9529 reg = nregs - 1;
9530 for (i = i * 2; i > 0; i--)
fa197c1c 9531 {
18344509
NC
9532 if (regpos[reg].offset == i - 1)
9533 {
9534 name = tic6x_unwind_regnames[regpos[reg].reg];
9535 if (reg > 0)
9536 reg--;
9537 }
9538 else
9539 name = _("[pad]");
fa197c1c 9540
18344509
NC
9541 fputs (name, stdout);
9542 if (i > 1)
9543 printf (", ");
9544 }
fa197c1c
PB
9545 }
9546
9547 printf ("}");
9548 }
9549 else if (op == 0xd0)
9550 printf (" MOV FP, SP");
9551 else if (op == 0xd1)
9552 printf (" __c6xabi_pop_rts");
9553 else if (op == 0xd2)
9554 {
9555 unsigned char buf[9];
9556 unsigned int i, len;
9557 unsigned long offset;
a734115a 9558
fa197c1c
PB
9559 for (i = 0; i < sizeof (buf); i++)
9560 {
9561 GET_OP (buf[i]);
9562 if ((buf[i] & 0x80) == 0)
9563 break;
9564 }
0eff7165
NC
9565 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9566 if (i == sizeof (buf))
9567 {
0eff7165 9568 warn (_("Corrupt stack pointer adjustment detected\n"));
015dc7e1 9569 return false;
0eff7165 9570 }
948f632f 9571
015dc7e1 9572 offset = read_leb128 (buf, buf + i + 1, false, &len, NULL);
fa197c1c
PB
9573 assert (len == i + 1);
9574 offset = offset * 8 + 0x408;
9575 printf (_("sp = sp + %ld"), offset);
9576 }
9577 else if ((op & 0xf0) == 0xe0)
9578 {
9579 if ((op & 0x0f) == 7)
9580 printf (" RETURN");
9581 else
9582 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9583 }
9584 else
9585 {
9586 printf (_(" [unsupported opcode]"));
9587 }
9588 putchar ('\n');
9589 }
32ec8896 9590
015dc7e1 9591 return true;
fa197c1c
PB
9592}
9593
9594static bfd_vma
dda8d76d 9595arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9596{
9597 bfd_vma offset;
9598
9599 offset = word & 0x7fffffff;
9600 if (offset & 0x40000000)
9601 offset |= ~ (bfd_vma) 0x7fffffff;
9602
dda8d76d 9603 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9604 offset <<= 1;
9605
9606 return offset + where;
9607}
9608
015dc7e1 9609static bool
dda8d76d
NC
9610decode_arm_unwind (Filedata * filedata,
9611 struct arm_unw_aux_info * aux,
1b31d05e
NC
9612 unsigned int word,
9613 unsigned int remaining,
9614 bfd_vma data_offset,
9615 Elf_Internal_Shdr * data_sec,
9616 struct arm_section * data_arm_sec)
fa197c1c
PB
9617{
9618 int per_index;
9619 unsigned int more_words = 0;
37e14bc3 9620 struct absaddr addr;
1b31d05e 9621 bfd_vma sym_name = (bfd_vma) -1;
015dc7e1 9622 bool res = true;
fa197c1c
PB
9623
9624 if (remaining == 0)
9625 {
1b31d05e
NC
9626 /* Fetch the first word.
9627 Note - when decoding an object file the address extracted
9628 here will always be 0. So we also pass in the sym_name
9629 parameter so that we can find the symbol associated with
9630 the personality routine. */
dda8d76d 9631 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9632 & word, & addr, & sym_name))
015dc7e1 9633 return false;
1b31d05e 9634
fa197c1c
PB
9635 remaining = 4;
9636 }
c93dbb25
CZ
9637 else
9638 {
9639 addr.section = SHN_UNDEF;
9640 addr.offset = 0;
9641 }
fa197c1c
PB
9642
9643 if ((word & 0x80000000) == 0)
9644 {
9645 /* Expand prel31 for personality routine. */
9646 bfd_vma fn;
9647 const char *procname;
9648
dda8d76d 9649 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9650 printf (_(" Personality routine: "));
1b31d05e
NC
9651 if (fn == 0
9652 && addr.section == SHN_UNDEF && addr.offset == 0
9653 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9654 {
9655 procname = aux->strtab + sym_name;
9656 print_vma (fn, PREFIX_HEX);
9657 if (procname)
9658 {
9659 fputs (" <", stdout);
9660 fputs (procname, stdout);
9661 fputc ('>', stdout);
9662 }
9663 }
9664 else
dda8d76d 9665 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9666 fputc ('\n', stdout);
9667
9668 /* The GCC personality routines use the standard compact
9669 encoding, starting with one byte giving the number of
9670 words. */
9671 if (procname != NULL
24d127aa
ML
9672 && (startswith (procname, "__gcc_personality_v0")
9673 || startswith (procname, "__gxx_personality_v0")
9674 || startswith (procname, "__gcj_personality_v0")
9675 || startswith (procname, "__gnu_objc_personality_v0")))
fa197c1c
PB
9676 {
9677 remaining = 0;
9678 more_words = 1;
9679 ADVANCE;
9680 if (!remaining)
9681 {
9682 printf (_(" [Truncated data]\n"));
015dc7e1 9683 return false;
fa197c1c
PB
9684 }
9685 more_words = word >> 24;
9686 word <<= 8;
9687 remaining--;
9688 per_index = -1;
9689 }
9690 else
015dc7e1 9691 return true;
fa197c1c
PB
9692 }
9693 else
9694 {
1b31d05e 9695 /* ARM EHABI Section 6.3:
0b4362b0 9696
1b31d05e 9697 An exception-handling table entry for the compact model looks like:
0b4362b0 9698
1b31d05e
NC
9699 31 30-28 27-24 23-0
9700 -- ----- ----- ----
9701 1 0 index Data for personalityRoutine[index] */
9702
dda8d76d 9703 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9704 && (word & 0x70000000))
32ec8896
NC
9705 {
9706 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
015dc7e1 9707 res = false;
32ec8896 9708 }
1b31d05e 9709
fa197c1c 9710 per_index = (word >> 24) & 0x7f;
1b31d05e 9711 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9712 if (per_index == 0)
9713 {
9714 more_words = 0;
9715 word <<= 8;
9716 remaining--;
9717 }
9718 else if (per_index < 3)
9719 {
9720 more_words = (word >> 16) & 0xff;
9721 word <<= 16;
9722 remaining -= 2;
9723 }
9724 }
9725
dda8d76d 9726 switch (filedata->file_header.e_machine)
fa197c1c
PB
9727 {
9728 case EM_ARM:
9729 if (per_index < 3)
9730 {
dda8d76d 9731 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9732 data_offset, data_sec, data_arm_sec))
015dc7e1 9733 res = false;
fa197c1c
PB
9734 }
9735 else
1b31d05e
NC
9736 {
9737 warn (_("Unknown ARM compact model index encountered\n"));
9738 printf (_(" [reserved]\n"));
015dc7e1 9739 res = false;
1b31d05e 9740 }
fa197c1c
PB
9741 break;
9742
9743 case EM_TI_C6000:
9744 if (per_index < 3)
9745 {
dda8d76d 9746 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896 9747 data_offset, data_sec, data_arm_sec))
015dc7e1 9748 res = false;
fa197c1c
PB
9749 }
9750 else if (per_index < 5)
9751 {
9752 if (((word >> 17) & 0x7f) == 0x7f)
9753 printf (_(" Restore stack from frame pointer\n"));
9754 else
9755 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9756 printf (_(" Registers restored: "));
9757 if (per_index == 4)
9758 printf (" (compact) ");
9759 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9760 putchar ('\n');
9761 printf (_(" Return register: %s\n"),
9762 tic6x_unwind_regnames[word & 0xf]);
9763 }
9764 else
1b31d05e 9765 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9766 break;
9767
9768 default:
74e1a04b 9769 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9770 filedata->file_header.e_machine);
015dc7e1 9771 res = false;
fa197c1c 9772 }
0b6ae522
DJ
9773
9774 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9775
9776 return res;
0b6ae522
DJ
9777}
9778
015dc7e1 9779static bool
dda8d76d
NC
9780dump_arm_unwind (Filedata * filedata,
9781 struct arm_unw_aux_info * aux,
9782 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9783{
9784 struct arm_section exidx_arm_sec, extab_arm_sec;
9785 unsigned int i, exidx_len;
948f632f 9786 unsigned long j, nfuns;
015dc7e1 9787 bool res = true;
0b6ae522
DJ
9788
9789 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9790 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9791 exidx_len = exidx_sec->sh_size / 8;
9792
948f632f
DA
9793 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9794 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9795 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9796 aux->funtab[nfuns++] = aux->symtab[j];
9797 aux->nfuns = nfuns;
9798 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9799
0b6ae522
DJ
9800 for (i = 0; i < exidx_len; i++)
9801 {
9802 unsigned int exidx_fn, exidx_entry;
9803 struct absaddr fn_addr, entry_addr;
9804 bfd_vma fn;
9805
9806 fputc ('\n', stdout);
9807
dda8d76d 9808 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9809 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9810 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9811 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9812 {
948f632f 9813 free (aux->funtab);
1b31d05e
NC
9814 arm_free_section (& exidx_arm_sec);
9815 arm_free_section (& extab_arm_sec);
015dc7e1 9816 return false;
0b6ae522
DJ
9817 }
9818
83c257ca
NC
9819 /* ARM EHABI, Section 5:
9820 An index table entry consists of 2 words.
9821 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9822 if (exidx_fn & 0x80000000)
32ec8896
NC
9823 {
9824 warn (_("corrupt index table entry: %x\n"), exidx_fn);
015dc7e1 9825 res = false;
32ec8896 9826 }
83c257ca 9827
dda8d76d 9828 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9829
dda8d76d 9830 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9831 fputs (": ", stdout);
9832
9833 if (exidx_entry == 1)
9834 {
9835 print_vma (exidx_entry, PREFIX_HEX);
9836 fputs (" [cantunwind]\n", stdout);
9837 }
9838 else if (exidx_entry & 0x80000000)
9839 {
9840 print_vma (exidx_entry, PREFIX_HEX);
9841 fputc ('\n', stdout);
dda8d76d 9842 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9843 }
9844 else
9845 {
8f73510c 9846 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9847 Elf_Internal_Shdr *table_sec;
9848
9849 fputs ("@", stdout);
dda8d76d 9850 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9851 print_vma (table, PREFIX_HEX);
9852 printf ("\n");
9853
9854 /* Locate the matching .ARM.extab. */
9855 if (entry_addr.section != SHN_UNDEF
dda8d76d 9856 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9857 {
dda8d76d 9858 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9859 table_offset = entry_addr.offset;
1a915552
NC
9860 /* PR 18879 */
9861 if (table_offset > table_sec->sh_size
9862 || ((bfd_signed_vma) table_offset) < 0)
9863 {
9864 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9865 (unsigned long) table_offset,
dda8d76d 9866 printable_section_name (filedata, table_sec));
015dc7e1 9867 res = false;
1a915552
NC
9868 continue;
9869 }
0b6ae522
DJ
9870 }
9871 else
9872 {
dda8d76d 9873 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9874 if (table_sec != NULL)
9875 table_offset = table - table_sec->sh_addr;
9876 }
32ec8896 9877
0b6ae522
DJ
9878 if (table_sec == NULL)
9879 {
9880 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9881 (unsigned long) table);
015dc7e1 9882 res = false;
0b6ae522
DJ
9883 continue;
9884 }
32ec8896 9885
dda8d76d 9886 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896 9887 &extab_arm_sec))
015dc7e1 9888 res = false;
0b6ae522
DJ
9889 }
9890 }
9891
9892 printf ("\n");
9893
948f632f 9894 free (aux->funtab);
0b6ae522
DJ
9895 arm_free_section (&exidx_arm_sec);
9896 arm_free_section (&extab_arm_sec);
32ec8896
NC
9897
9898 return res;
0b6ae522
DJ
9899}
9900
fa197c1c 9901/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9902
015dc7e1 9903static bool
dda8d76d 9904arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9905{
9906 struct arm_unw_aux_info aux;
9907 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9908 Elf_Internal_Shdr *sec;
9909 unsigned long i;
fa197c1c 9910 unsigned int sec_type;
015dc7e1 9911 bool res = true;
0b6ae522 9912
dda8d76d 9913 switch (filedata->file_header.e_machine)
fa197c1c
PB
9914 {
9915 case EM_ARM:
9916 sec_type = SHT_ARM_EXIDX;
9917 break;
9918
9919 case EM_TI_C6000:
9920 sec_type = SHT_C6000_UNWIND;
9921 break;
9922
0b4362b0 9923 default:
74e1a04b 9924 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9925 filedata->file_header.e_machine);
015dc7e1 9926 return false;
fa197c1c
PB
9927 }
9928
dda8d76d 9929 if (filedata->string_table == NULL)
015dc7e1 9930 return false;
1b31d05e
NC
9931
9932 memset (& aux, 0, sizeof (aux));
dda8d76d 9933 aux.filedata = filedata;
0b6ae522 9934
dda8d76d 9935 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9936 {
28d13567 9937 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9938 {
28d13567 9939 if (aux.symtab)
74e1a04b 9940 {
28d13567
AM
9941 error (_("Multiple symbol tables encountered\n"));
9942 free (aux.symtab);
9943 aux.symtab = NULL;
74e1a04b 9944 free (aux.strtab);
28d13567 9945 aux.strtab = NULL;
74e1a04b 9946 }
28d13567
AM
9947 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9948 &aux.strtab, &aux.strtab_size))
015dc7e1 9949 return false;
0b6ae522 9950 }
fa197c1c 9951 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9952 unwsec = sec;
9953 }
9954
1b31d05e 9955 if (unwsec == NULL)
0b6ae522 9956 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9957 else
dda8d76d 9958 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9959 {
9960 if (sec->sh_type == sec_type)
9961 {
d3a49aa8
AM
9962 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9963 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9964 "contains %lu entry:\n",
9965 "\nUnwind section '%s' at offset 0x%lx "
9966 "contains %lu entries:\n",
9967 num_unwind),
dda8d76d 9968 printable_section_name (filedata, sec),
1b31d05e 9969 (unsigned long) sec->sh_offset,
d3a49aa8 9970 num_unwind);
0b6ae522 9971
dda8d76d 9972 if (! dump_arm_unwind (filedata, &aux, sec))
015dc7e1 9973 res = false;
1b31d05e
NC
9974 }
9975 }
0b6ae522 9976
9db70fc3
AM
9977 free (aux.symtab);
9978 free ((char *) aux.strtab);
32ec8896
NC
9979
9980 return res;
0b6ae522
DJ
9981}
9982
3ecc00ec
NC
9983static bool
9984no_processor_specific_unwind (Filedata * filedata ATTRIBUTE_UNUSED)
9985{
9986 printf (_("No processor specific unwind information to decode\n"));
9987 return true;
9988}
9989
015dc7e1 9990static bool
dda8d76d 9991process_unwind (Filedata * filedata)
57346661 9992{
2cf0635d
NC
9993 struct unwind_handler
9994 {
32ec8896 9995 unsigned int machtype;
015dc7e1 9996 bool (* handler)(Filedata *);
2cf0635d
NC
9997 } handlers[] =
9998 {
0b6ae522 9999 { EM_ARM, arm_process_unwind },
57346661
AM
10000 { EM_IA_64, ia64_process_unwind },
10001 { EM_PARISC, hppa_process_unwind },
fa197c1c 10002 { EM_TI_C6000, arm_process_unwind },
3ecc00ec
NC
10003 { EM_386, no_processor_specific_unwind },
10004 { EM_X86_64, no_processor_specific_unwind },
32ec8896 10005 { 0, NULL }
57346661
AM
10006 };
10007 int i;
10008
10009 if (!do_unwind)
015dc7e1 10010 return true;
57346661
AM
10011
10012 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
10013 if (filedata->file_header.e_machine == handlers[i].machtype)
10014 return handlers[i].handler (filedata);
57346661 10015
1b31d05e 10016 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 10017 get_machine_name (filedata->file_header.e_machine));
015dc7e1 10018 return true;
57346661
AM
10019}
10020
37c18eed
SD
10021static void
10022dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
10023{
10024 switch (entry->d_tag)
10025 {
10026 case DT_AARCH64_BTI_PLT:
1dbade74 10027 case DT_AARCH64_PAC_PLT:
37c18eed
SD
10028 break;
10029 default:
10030 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10031 break;
10032 }
10033 putchar ('\n');
10034}
10035
252b5132 10036static void
978c4450 10037dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
10038{
10039 switch (entry->d_tag)
10040 {
10041 case DT_MIPS_FLAGS:
10042 if (entry->d_un.d_val == 0)
4b68bca3 10043 printf (_("NONE"));
252b5132
RH
10044 else
10045 {
10046 static const char * opts[] =
10047 {
10048 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
10049 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
10050 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
10051 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
10052 "RLD_ORDER_SAFE"
10053 };
10054 unsigned int cnt;
015dc7e1 10055 bool first = true;
2b692964 10056
60bca95a 10057 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
10058 if (entry->d_un.d_val & (1 << cnt))
10059 {
10060 printf ("%s%s", first ? "" : " ", opts[cnt]);
015dc7e1 10061 first = false;
252b5132 10062 }
252b5132
RH
10063 }
10064 break;
103f02d3 10065
252b5132 10066 case DT_MIPS_IVERSION:
978c4450
AM
10067 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10068 printf (_("Interface Version: %s"),
10069 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10070 else
76ca31c0
NC
10071 {
10072 char buf[40];
10073 sprintf_vma (buf, entry->d_un.d_ptr);
10074 /* Note: coded this way so that there is a single string for translation. */
10075 printf (_("<corrupt: %s>"), buf);
10076 }
252b5132 10077 break;
103f02d3 10078
252b5132
RH
10079 case DT_MIPS_TIME_STAMP:
10080 {
d5b07ef4 10081 char timebuf[128];
2cf0635d 10082 struct tm * tmp;
91d6fa6a 10083 time_t atime = entry->d_un.d_val;
82b1b41b 10084
91d6fa6a 10085 tmp = gmtime (&atime);
82b1b41b
NC
10086 /* PR 17531: file: 6accc532. */
10087 if (tmp == NULL)
10088 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
10089 else
10090 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
10091 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
10092 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 10093 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
10094 }
10095 break;
103f02d3 10096
252b5132
RH
10097 case DT_MIPS_RLD_VERSION:
10098 case DT_MIPS_LOCAL_GOTNO:
10099 case DT_MIPS_CONFLICTNO:
10100 case DT_MIPS_LIBLISTNO:
10101 case DT_MIPS_SYMTABNO:
10102 case DT_MIPS_UNREFEXTNO:
10103 case DT_MIPS_HIPAGENO:
10104 case DT_MIPS_DELTA_CLASS_NO:
10105 case DT_MIPS_DELTA_INSTANCE_NO:
10106 case DT_MIPS_DELTA_RELOC_NO:
10107 case DT_MIPS_DELTA_SYM_NO:
10108 case DT_MIPS_DELTA_CLASSSYM_NO:
10109 case DT_MIPS_COMPACT_SIZE:
c69075ac 10110 print_vma (entry->d_un.d_val, DEC);
252b5132 10111 break;
103f02d3 10112
f16a9783 10113 case DT_MIPS_XHASH:
978c4450
AM
10114 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10115 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
10116 /* Falls through. */
10117
103f02d3 10118 default:
4b68bca3 10119 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 10120 }
4b68bca3 10121 putchar ('\n');
103f02d3
UD
10122}
10123
103f02d3 10124static void
2cf0635d 10125dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
10126{
10127 switch (entry->d_tag)
10128 {
10129 case DT_HP_DLD_FLAGS:
10130 {
10131 static struct
10132 {
10133 long int bit;
2cf0635d 10134 const char * str;
5e220199
NC
10135 }
10136 flags[] =
10137 {
10138 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
10139 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
10140 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
10141 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
10142 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
10143 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
10144 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
10145 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
10146 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
10147 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
10148 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
10149 { DT_HP_GST, "HP_GST" },
10150 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
10151 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
10152 { DT_HP_NODELETE, "HP_NODELETE" },
10153 { DT_HP_GROUP, "HP_GROUP" },
10154 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 10155 };
015dc7e1 10156 bool first = true;
5e220199 10157 size_t cnt;
f7a99963 10158 bfd_vma val = entry->d_un.d_val;
103f02d3 10159
60bca95a 10160 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 10161 if (val & flags[cnt].bit)
30800947
NC
10162 {
10163 if (! first)
10164 putchar (' ');
10165 fputs (flags[cnt].str, stdout);
015dc7e1 10166 first = false;
30800947
NC
10167 val ^= flags[cnt].bit;
10168 }
76da6bbe 10169
103f02d3 10170 if (val != 0 || first)
f7a99963
NC
10171 {
10172 if (! first)
10173 putchar (' ');
10174 print_vma (val, HEX);
10175 }
103f02d3
UD
10176 }
10177 break;
76da6bbe 10178
252b5132 10179 default:
f7a99963
NC
10180 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10181 break;
252b5132 10182 }
35b1837e 10183 putchar ('\n');
252b5132
RH
10184}
10185
28f997cf
TG
10186#ifdef BFD64
10187
10188/* VMS vs Unix time offset and factor. */
10189
10190#define VMS_EPOCH_OFFSET 35067168000000000LL
10191#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
10192#ifndef INT64_MIN
10193#define INT64_MIN (-9223372036854775807LL - 1)
10194#endif
28f997cf
TG
10195
10196/* Display a VMS time in a human readable format. */
10197
10198static void
10199print_vms_time (bfd_int64_t vmstime)
10200{
dccc31de 10201 struct tm *tm = NULL;
28f997cf
TG
10202 time_t unxtime;
10203
dccc31de
AM
10204 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
10205 {
10206 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
10207 unxtime = vmstime;
10208 if (unxtime == vmstime)
10209 tm = gmtime (&unxtime);
10210 }
10211 if (tm != NULL)
10212 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
10213 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
10214 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
10215}
10216#endif /* BFD64 */
10217
ecc51f48 10218static void
2cf0635d 10219dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
10220{
10221 switch (entry->d_tag)
10222 {
0de14b54 10223 case DT_IA_64_PLT_RESERVE:
bdf4d63a 10224 /* First 3 slots reserved. */
ecc51f48
NC
10225 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10226 printf (" -- ");
10227 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
10228 break;
10229
28f997cf
TG
10230 case DT_IA_64_VMS_LINKTIME:
10231#ifdef BFD64
10232 print_vms_time (entry->d_un.d_val);
10233#endif
10234 break;
10235
10236 case DT_IA_64_VMS_LNKFLAGS:
10237 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10238 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
10239 printf (" CALL_DEBUG");
10240 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
10241 printf (" NOP0BUFS");
10242 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
10243 printf (" P0IMAGE");
10244 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
10245 printf (" MKTHREADS");
10246 if (entry->d_un.d_val & VMS_LF_UPCALLS)
10247 printf (" UPCALLS");
10248 if (entry->d_un.d_val & VMS_LF_IMGSTA)
10249 printf (" IMGSTA");
10250 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
10251 printf (" INITIALIZE");
10252 if (entry->d_un.d_val & VMS_LF_MAIN)
10253 printf (" MAIN");
10254 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
10255 printf (" EXE_INIT");
10256 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
10257 printf (" TBK_IN_IMG");
10258 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
10259 printf (" DBG_IN_IMG");
10260 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
10261 printf (" TBK_IN_DSF");
10262 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
10263 printf (" DBG_IN_DSF");
10264 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
10265 printf (" SIGNATURES");
10266 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
10267 printf (" REL_SEG_OFF");
10268 break;
10269
bdf4d63a
JJ
10270 default:
10271 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
10272 break;
ecc51f48 10273 }
bdf4d63a 10274 putchar ('\n');
ecc51f48
NC
10275}
10276
015dc7e1 10277static bool
dda8d76d 10278get_32bit_dynamic_section (Filedata * filedata)
252b5132 10279{
2cf0635d
NC
10280 Elf32_External_Dyn * edyn;
10281 Elf32_External_Dyn * ext;
10282 Elf_Internal_Dyn * entry;
103f02d3 10283
978c4450
AM
10284 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
10285 filedata->dynamic_addr, 1,
10286 filedata->dynamic_size,
10287 _("dynamic section"));
a6e9f9df 10288 if (!edyn)
015dc7e1 10289 return false;
103f02d3 10290
071436c6
NC
10291 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10292 might not have the luxury of section headers. Look for the DT_NULL
10293 terminator to determine the number of entries. */
978c4450
AM
10294 for (ext = edyn, filedata->dynamic_nent = 0;
10295 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10296 ext++)
10297 {
978c4450 10298 filedata->dynamic_nent++;
ba2685cc
AM
10299 if (BYTE_GET (ext->d_tag) == DT_NULL)
10300 break;
10301 }
252b5132 10302
978c4450
AM
10303 filedata->dynamic_section
10304 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10305 if (filedata->dynamic_section == NULL)
252b5132 10306 {
8b73c356 10307 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10308 (unsigned long) filedata->dynamic_nent);
9ea033b2 10309 free (edyn);
015dc7e1 10310 return false;
9ea033b2 10311 }
252b5132 10312
978c4450
AM
10313 for (ext = edyn, entry = filedata->dynamic_section;
10314 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10315 ext++, entry++)
9ea033b2 10316 {
fb514b26
AM
10317 entry->d_tag = BYTE_GET (ext->d_tag);
10318 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10319 }
10320
9ea033b2
NC
10321 free (edyn);
10322
015dc7e1 10323 return true;
9ea033b2
NC
10324}
10325
015dc7e1 10326static bool
dda8d76d 10327get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10328{
2cf0635d
NC
10329 Elf64_External_Dyn * edyn;
10330 Elf64_External_Dyn * ext;
10331 Elf_Internal_Dyn * entry;
103f02d3 10332
071436c6 10333 /* Read in the data. */
978c4450
AM
10334 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10335 filedata->dynamic_addr, 1,
10336 filedata->dynamic_size,
10337 _("dynamic section"));
a6e9f9df 10338 if (!edyn)
015dc7e1 10339 return false;
103f02d3 10340
071436c6
NC
10341 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10342 might not have the luxury of section headers. Look for the DT_NULL
10343 terminator to determine the number of entries. */
978c4450 10344 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10345 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10346 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10347 ext++)
10348 {
978c4450 10349 filedata->dynamic_nent++;
66543521 10350 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10351 break;
10352 }
252b5132 10353
978c4450
AM
10354 filedata->dynamic_section
10355 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10356 if (filedata->dynamic_section == NULL)
252b5132 10357 {
8b73c356 10358 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10359 (unsigned long) filedata->dynamic_nent);
252b5132 10360 free (edyn);
015dc7e1 10361 return false;
252b5132
RH
10362 }
10363
071436c6 10364 /* Convert from external to internal formats. */
978c4450
AM
10365 for (ext = edyn, entry = filedata->dynamic_section;
10366 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10367 ext++, entry++)
252b5132 10368 {
66543521
AM
10369 entry->d_tag = BYTE_GET (ext->d_tag);
10370 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10371 }
10372
10373 free (edyn);
10374
015dc7e1 10375 return true;
9ea033b2
NC
10376}
10377
4de91c10
AM
10378static bool
10379get_dynamic_section (Filedata *filedata)
10380{
10381 if (filedata->dynamic_section)
10382 return true;
10383
10384 if (is_32bit_elf)
10385 return get_32bit_dynamic_section (filedata);
10386 else
10387 return get_64bit_dynamic_section (filedata);
10388}
10389
e9e44622
JJ
10390static void
10391print_dynamic_flags (bfd_vma flags)
d1133906 10392{
015dc7e1 10393 bool first = true;
13ae64f3 10394
d1133906
NC
10395 while (flags)
10396 {
10397 bfd_vma flag;
10398
10399 flag = flags & - flags;
10400 flags &= ~ flag;
10401
e9e44622 10402 if (first)
015dc7e1 10403 first = false;
e9e44622
JJ
10404 else
10405 putc (' ', stdout);
13ae64f3 10406
d1133906
NC
10407 switch (flag)
10408 {
e9e44622
JJ
10409 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10410 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10411 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10412 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10413 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10414 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10415 }
10416 }
e9e44622 10417 puts ("");
d1133906
NC
10418}
10419
10ca4b04
L
10420static bfd_vma *
10421get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10422{
10423 unsigned char * e_data;
10424 bfd_vma * i_data;
10425
10426 /* If the size_t type is smaller than the bfd_size_type, eg because
10427 you are building a 32-bit tool on a 64-bit host, then make sure
10428 that when (number) is cast to (size_t) no information is lost. */
10429 if (sizeof (size_t) < sizeof (bfd_size_type)
10430 && (bfd_size_type) ((size_t) number) != number)
10431 {
10432 error (_("Size truncation prevents reading %s elements of size %u\n"),
10433 bfd_vmatoa ("u", number), ent_size);
10434 return NULL;
10435 }
10436
10437 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10438 attempting to allocate memory when the read is bound to fail. */
10439 if (ent_size * number > filedata->file_size)
10440 {
10441 error (_("Invalid number of dynamic entries: %s\n"),
10442 bfd_vmatoa ("u", number));
10443 return NULL;
10444 }
10445
10446 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10447 if (e_data == NULL)
10448 {
10449 error (_("Out of memory reading %s dynamic entries\n"),
10450 bfd_vmatoa ("u", number));
10451 return NULL;
10452 }
10453
10454 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10455 {
10456 error (_("Unable to read in %s bytes of dynamic data\n"),
10457 bfd_vmatoa ("u", number * ent_size));
10458 free (e_data);
10459 return NULL;
10460 }
10461
10462 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10463 if (i_data == NULL)
10464 {
10465 error (_("Out of memory allocating space for %s dynamic entries\n"),
10466 bfd_vmatoa ("u", number));
10467 free (e_data);
10468 return NULL;
10469 }
10470
10471 while (number--)
10472 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10473
10474 free (e_data);
10475
10476 return i_data;
10477}
10478
10479static unsigned long
10480get_num_dynamic_syms (Filedata * filedata)
10481{
10482 unsigned long num_of_syms = 0;
10483
10484 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10485 return num_of_syms;
10486
978c4450 10487 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10488 {
10489 unsigned char nb[8];
10490 unsigned char nc[8];
10491 unsigned int hash_ent_size = 4;
10492
10493 if ((filedata->file_header.e_machine == EM_ALPHA
10494 || filedata->file_header.e_machine == EM_S390
10495 || filedata->file_header.e_machine == EM_S390_OLD)
10496 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10497 hash_ent_size = 8;
10498
10499 if (fseek (filedata->handle,
978c4450
AM
10500 (filedata->archive_file_offset
10501 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10502 sizeof nb + sizeof nc)),
10503 SEEK_SET))
10504 {
10505 error (_("Unable to seek to start of dynamic information\n"));
10506 goto no_hash;
10507 }
10508
10509 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10510 {
10511 error (_("Failed to read in number of buckets\n"));
10512 goto no_hash;
10513 }
10514
10515 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10516 {
10517 error (_("Failed to read in number of chains\n"));
10518 goto no_hash;
10519 }
10520
978c4450
AM
10521 filedata->nbuckets = byte_get (nb, hash_ent_size);
10522 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10523
2482f306
AM
10524 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10525 {
10526 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10527 hash_ent_size);
10528 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10529 hash_ent_size);
001890e1 10530
2482f306
AM
10531 if (filedata->buckets != NULL && filedata->chains != NULL)
10532 num_of_syms = filedata->nchains;
10533 }
ceb9bf11 10534 no_hash:
10ca4b04
L
10535 if (num_of_syms == 0)
10536 {
9db70fc3
AM
10537 free (filedata->buckets);
10538 filedata->buckets = NULL;
10539 free (filedata->chains);
10540 filedata->chains = NULL;
978c4450 10541 filedata->nbuckets = 0;
10ca4b04
L
10542 }
10543 }
10544
978c4450 10545 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10546 {
10547 unsigned char nb[16];
10548 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10549 bfd_vma buckets_vma;
10550 unsigned long hn;
10ca4b04
L
10551
10552 if (fseek (filedata->handle,
978c4450
AM
10553 (filedata->archive_file_offset
10554 + offset_from_vma (filedata,
10555 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10556 sizeof nb)),
10557 SEEK_SET))
10558 {
10559 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10560 goto no_gnu_hash;
10561 }
10562
10563 if (fread (nb, 16, 1, filedata->handle) != 1)
10564 {
10565 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10566 goto no_gnu_hash;
10567 }
10568
978c4450
AM
10569 filedata->ngnubuckets = byte_get (nb, 4);
10570 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10571 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10572 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10573 if (is_32bit_elf)
10574 buckets_vma += bitmaskwords * 4;
10575 else
10576 buckets_vma += bitmaskwords * 8;
10577
10578 if (fseek (filedata->handle,
978c4450 10579 (filedata->archive_file_offset
10ca4b04
L
10580 + offset_from_vma (filedata, buckets_vma, 4)),
10581 SEEK_SET))
10582 {
10583 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10584 goto no_gnu_hash;
10585 }
10586
978c4450
AM
10587 filedata->gnubuckets
10588 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10589
978c4450 10590 if (filedata->gnubuckets == NULL)
90837ea7 10591 goto no_gnu_hash;
10ca4b04 10592
978c4450
AM
10593 for (i = 0; i < filedata->ngnubuckets; i++)
10594 if (filedata->gnubuckets[i] != 0)
10ca4b04 10595 {
978c4450 10596 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10597 goto no_gnu_hash;
10ca4b04 10598
978c4450
AM
10599 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10600 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10601 }
10602
10603 if (maxchain == 0xffffffff)
90837ea7 10604 goto no_gnu_hash;
10ca4b04 10605
978c4450 10606 maxchain -= filedata->gnusymidx;
10ca4b04
L
10607
10608 if (fseek (filedata->handle,
978c4450
AM
10609 (filedata->archive_file_offset
10610 + offset_from_vma (filedata,
10611 buckets_vma + 4 * (filedata->ngnubuckets
10612 + maxchain),
10613 4)),
10ca4b04
L
10614 SEEK_SET))
10615 {
10616 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10617 goto no_gnu_hash;
10618 }
10619
10620 do
10621 {
10622 if (fread (nb, 4, 1, filedata->handle) != 1)
10623 {
10624 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10625 goto no_gnu_hash;
10626 }
10627
10628 if (maxchain + 1 == 0)
90837ea7 10629 goto no_gnu_hash;
10ca4b04
L
10630
10631 ++maxchain;
10632 }
10633 while ((byte_get (nb, 4) & 1) == 0);
10634
10635 if (fseek (filedata->handle,
978c4450
AM
10636 (filedata->archive_file_offset
10637 + offset_from_vma (filedata, (buckets_vma
10638 + 4 * filedata->ngnubuckets),
10639 4)),
10ca4b04
L
10640 SEEK_SET))
10641 {
10642 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10643 goto no_gnu_hash;
10644 }
10645
978c4450
AM
10646 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10647 filedata->ngnuchains = maxchain;
10ca4b04 10648
978c4450 10649 if (filedata->gnuchains == NULL)
90837ea7 10650 goto no_gnu_hash;
10ca4b04 10651
978c4450 10652 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10653 {
10654 if (fseek (filedata->handle,
978c4450 10655 (filedata->archive_file_offset
10ca4b04 10656 + offset_from_vma (filedata, (buckets_vma
978c4450 10657 + 4 * (filedata->ngnubuckets
10ca4b04
L
10658 + maxchain)), 4)),
10659 SEEK_SET))
10660 {
10661 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10662 goto no_gnu_hash;
10663 }
10664
978c4450 10665 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10666 if (filedata->mipsxlat == NULL)
10667 goto no_gnu_hash;
10ca4b04
L
10668 }
10669
978c4450
AM
10670 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10671 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10672 {
978c4450
AM
10673 bfd_vma si = filedata->gnubuckets[hn];
10674 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10675
10676 do
10677 {
978c4450 10678 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10679 {
c31ab5a0
AM
10680 if (off < filedata->ngnuchains
10681 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10682 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10683 }
10684 else
10685 {
10686 if (si >= num_of_syms)
10687 num_of_syms = si + 1;
10688 }
10689 si++;
10690 }
978c4450
AM
10691 while (off < filedata->ngnuchains
10692 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10693 }
10694
90837ea7 10695 if (num_of_syms == 0)
10ca4b04 10696 {
90837ea7 10697 no_gnu_hash:
9db70fc3
AM
10698 free (filedata->mipsxlat);
10699 filedata->mipsxlat = NULL;
10700 free (filedata->gnuchains);
10701 filedata->gnuchains = NULL;
10702 free (filedata->gnubuckets);
10703 filedata->gnubuckets = NULL;
978c4450
AM
10704 filedata->ngnubuckets = 0;
10705 filedata->ngnuchains = 0;
10ca4b04
L
10706 }
10707 }
10708
10709 return num_of_syms;
10710}
10711
b2d38a17
NC
10712/* Parse and display the contents of the dynamic section. */
10713
015dc7e1 10714static bool
dda8d76d 10715process_dynamic_section (Filedata * filedata)
9ea033b2 10716{
2cf0635d 10717 Elf_Internal_Dyn * entry;
9ea033b2 10718
93df3340 10719 if (filedata->dynamic_size <= 1)
9ea033b2
NC
10720 {
10721 if (do_dynamic)
ca0e11aa
NC
10722 {
10723 if (filedata->is_separate)
10724 printf (_("\nThere is no dynamic section in linked file '%s'.\n"),
10725 filedata->file_name);
10726 else
10727 printf (_("\nThere is no dynamic section in this file.\n"));
10728 }
9ea033b2 10729
015dc7e1 10730 return true;
9ea033b2
NC
10731 }
10732
4de91c10
AM
10733 if (!get_dynamic_section (filedata))
10734 return false;
9ea033b2 10735
252b5132 10736 /* Find the appropriate symbol table. */
978c4450 10737 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10738 {
2482f306
AM
10739 unsigned long num_of_syms;
10740
978c4450
AM
10741 for (entry = filedata->dynamic_section;
10742 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10743 ++entry)
10ca4b04 10744 if (entry->d_tag == DT_SYMTAB)
978c4450 10745 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10746 else if (entry->d_tag == DT_SYMENT)
978c4450 10747 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10748 else if (entry->d_tag == DT_HASH)
978c4450 10749 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10750 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10751 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10752 else if ((filedata->file_header.e_machine == EM_MIPS
10753 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10754 && entry->d_tag == DT_MIPS_XHASH)
10755 {
978c4450
AM
10756 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10757 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10758 }
252b5132 10759
2482f306
AM
10760 num_of_syms = get_num_dynamic_syms (filedata);
10761
10762 if (num_of_syms != 0
10763 && filedata->dynamic_symbols == NULL
10764 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10765 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10766 {
10767 Elf_Internal_Phdr *seg;
2482f306 10768 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10769
2482f306
AM
10770 if (! get_program_headers (filedata))
10771 {
10772 error (_("Cannot interpret virtual addresses "
10773 "without program headers.\n"));
015dc7e1 10774 return false;
2482f306 10775 }
252b5132 10776
2482f306
AM
10777 for (seg = filedata->program_headers;
10778 seg < filedata->program_headers + filedata->file_header.e_phnum;
10779 ++seg)
10780 {
10781 if (seg->p_type != PT_LOAD)
10782 continue;
252b5132 10783
2482f306
AM
10784 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10785 {
10786 /* See PR 21379 for a reproducer. */
10787 error (_("Invalid PT_LOAD entry\n"));
015dc7e1 10788 return false;
2482f306 10789 }
252b5132 10790
2482f306
AM
10791 if (vma >= (seg->p_vaddr & -seg->p_align)
10792 && vma < seg->p_vaddr + seg->p_filesz)
10793 {
10794 /* Since we do not know how big the symbol table is,
10795 we default to reading in up to the end of PT_LOAD
10796 segment and processing that. This is overkill, I
10797 know, but it should work. */
10798 Elf_Internal_Shdr section;
10799 section.sh_offset = (vma - seg->p_vaddr
10800 + seg->p_offset);
10801 section.sh_size = (num_of_syms
10802 * filedata->dynamic_info[DT_SYMENT]);
10803 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10804
10805 if (do_checks
10806 && filedata->dynamic_symtab_section != NULL
10807 && ((filedata->dynamic_symtab_section->sh_offset
10808 != section.sh_offset)
10809 || (filedata->dynamic_symtab_section->sh_size
10810 != section.sh_size)
10811 || (filedata->dynamic_symtab_section->sh_entsize
10812 != section.sh_entsize)))
10813 warn (_("\
10814the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10815
2482f306
AM
10816 section.sh_name = filedata->string_table_length;
10817 filedata->dynamic_symbols
4de91c10 10818 = get_elf_symbols (filedata, &section,
2482f306
AM
10819 &filedata->num_dynamic_syms);
10820 if (filedata->dynamic_symbols == NULL
10821 || filedata->num_dynamic_syms != num_of_syms)
10822 {
10823 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
015dc7e1 10824 return false;
2482f306
AM
10825 }
10826 break;
10827 }
10828 }
10829 }
10830 }
252b5132
RH
10831
10832 /* Similarly find a string table. */
978c4450
AM
10833 if (filedata->dynamic_strings == NULL)
10834 for (entry = filedata->dynamic_section;
10835 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10836 ++entry)
10837 {
10838 if (entry->d_tag == DT_STRTAB)
978c4450 10839 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10840
10ca4b04 10841 if (entry->d_tag == DT_STRSZ)
978c4450 10842 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10843
978c4450
AM
10844 if (filedata->dynamic_info[DT_STRTAB]
10845 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10846 {
10847 unsigned long offset;
978c4450 10848 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10849
10850 offset = offset_from_vma (filedata,
978c4450 10851 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10852 str_tab_len);
8ac10c5b
L
10853 if (do_checks
10854 && filedata->dynamic_strtab_section
10855 && ((filedata->dynamic_strtab_section->sh_offset
10856 != (file_ptr) offset)
10857 || (filedata->dynamic_strtab_section->sh_size
10858 != str_tab_len)))
10859 warn (_("\
10860the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10861
978c4450
AM
10862 filedata->dynamic_strings
10863 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10864 _("dynamic string table"));
10865 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10866 {
10867 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10868 break;
10869 }
e3d39609 10870
978c4450 10871 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10872 break;
10873 }
10874 }
252b5132
RH
10875
10876 /* And find the syminfo section if available. */
978c4450 10877 if (filedata->dynamic_syminfo == NULL)
252b5132 10878 {
3e8bba36 10879 unsigned long syminsz = 0;
252b5132 10880
978c4450
AM
10881 for (entry = filedata->dynamic_section;
10882 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10883 ++entry)
252b5132
RH
10884 {
10885 if (entry->d_tag == DT_SYMINENT)
10886 {
10887 /* Note: these braces are necessary to avoid a syntax
10888 error from the SunOS4 C compiler. */
049b0c3a
NC
10889 /* PR binutils/17531: A corrupt file can trigger this test.
10890 So do not use an assert, instead generate an error message. */
10891 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10892 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10893 (int) entry->d_un.d_val);
252b5132
RH
10894 }
10895 else if (entry->d_tag == DT_SYMINSZ)
10896 syminsz = entry->d_un.d_val;
10897 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10898 filedata->dynamic_syminfo_offset
10899 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10900 }
10901
978c4450 10902 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10903 {
2cf0635d
NC
10904 Elf_External_Syminfo * extsyminfo;
10905 Elf_External_Syminfo * extsym;
10906 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10907
10908 /* There is a syminfo section. Read the data. */
3f5e193b 10909 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10910 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10911 1, syminsz, _("symbol information"));
a6e9f9df 10912 if (!extsyminfo)
015dc7e1 10913 return false;
252b5132 10914
978c4450 10915 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10916 {
10917 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10918 free (filedata->dynamic_syminfo);
e3d39609 10919 }
978c4450
AM
10920 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10921 if (filedata->dynamic_syminfo == NULL)
252b5132 10922 {
2482f306
AM
10923 error (_("Out of memory allocating %lu bytes "
10924 "for dynamic symbol info\n"),
8b73c356 10925 (unsigned long) syminsz);
015dc7e1 10926 return false;
252b5132
RH
10927 }
10928
2482f306
AM
10929 filedata->dynamic_syminfo_nent
10930 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10931 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10932 syminfo < (filedata->dynamic_syminfo
10933 + filedata->dynamic_syminfo_nent);
86dba8ee 10934 ++syminfo, ++extsym)
252b5132 10935 {
86dba8ee
AM
10936 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10937 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10938 }
10939
10940 free (extsyminfo);
10941 }
10942 }
10943
978c4450 10944 if (do_dynamic && filedata->dynamic_addr)
ca0e11aa 10945 {
f253158f
NC
10946 if (filedata->is_separate)
10947 printf (ngettext ("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entry:\n",
10948 "\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n",
10949 (unsigned long) filedata->dynamic_nent),
10950 filedata->file_name,
10951 filedata->dynamic_addr,
10952 (unsigned long) filedata->dynamic_nent);
ca0e11aa 10953 else
f253158f
NC
10954 printf (ngettext ("\nDynamic section at offset 0x%lx contains %lu entry:\n",
10955 "\nDynamic section at offset 0x%lx contains %lu entries:\n",
10956 (unsigned long) filedata->dynamic_nent),
ca0e11aa
NC
10957 filedata->dynamic_addr,
10958 (unsigned long) filedata->dynamic_nent);
ca0e11aa 10959 }
252b5132
RH
10960 if (do_dynamic)
10961 printf (_(" Tag Type Name/Value\n"));
10962
978c4450
AM
10963 for (entry = filedata->dynamic_section;
10964 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10965 entry++)
252b5132
RH
10966 {
10967 if (do_dynamic)
f7a99963 10968 {
2cf0635d 10969 const char * dtype;
e699b9ff 10970
f7a99963
NC
10971 putchar (' ');
10972 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10973 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10974 printf (" (%s)%*s", dtype,
32ec8896 10975 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10976 }
252b5132
RH
10977
10978 switch (entry->d_tag)
10979 {
d1133906
NC
10980 case DT_FLAGS:
10981 if (do_dynamic)
e9e44622 10982 print_dynamic_flags (entry->d_un.d_val);
d1133906 10983 break;
76da6bbe 10984
252b5132
RH
10985 case DT_AUXILIARY:
10986 case DT_FILTER:
019148e4
L
10987 case DT_CONFIG:
10988 case DT_DEPAUDIT:
10989 case DT_AUDIT:
252b5132
RH
10990 if (do_dynamic)
10991 {
019148e4 10992 switch (entry->d_tag)
b34976b6 10993 {
019148e4
L
10994 case DT_AUXILIARY:
10995 printf (_("Auxiliary library"));
10996 break;
10997
10998 case DT_FILTER:
10999 printf (_("Filter library"));
11000 break;
11001
b34976b6 11002 case DT_CONFIG:
019148e4
L
11003 printf (_("Configuration file"));
11004 break;
11005
11006 case DT_DEPAUDIT:
11007 printf (_("Dependency audit library"));
11008 break;
11009
11010 case DT_AUDIT:
11011 printf (_("Audit library"));
11012 break;
11013 }
252b5132 11014
978c4450
AM
11015 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11016 printf (": [%s]\n",
11017 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 11018 else
f7a99963
NC
11019 {
11020 printf (": ");
11021 print_vma (entry->d_un.d_val, PREFIX_HEX);
11022 putchar ('\n');
11023 }
252b5132
RH
11024 }
11025 break;
11026
dcefbbbd 11027 case DT_FEATURE:
252b5132
RH
11028 if (do_dynamic)
11029 {
11030 printf (_("Flags:"));
86f55779 11031
252b5132
RH
11032 if (entry->d_un.d_val == 0)
11033 printf (_(" None\n"));
11034 else
11035 {
11036 unsigned long int val = entry->d_un.d_val;
86f55779 11037
252b5132
RH
11038 if (val & DTF_1_PARINIT)
11039 {
11040 printf (" PARINIT");
11041 val ^= DTF_1_PARINIT;
11042 }
dcefbbbd
L
11043 if (val & DTF_1_CONFEXP)
11044 {
11045 printf (" CONFEXP");
11046 val ^= DTF_1_CONFEXP;
11047 }
252b5132
RH
11048 if (val != 0)
11049 printf (" %lx", val);
11050 puts ("");
11051 }
11052 }
11053 break;
11054
11055 case DT_POSFLAG_1:
11056 if (do_dynamic)
11057 {
11058 printf (_("Flags:"));
86f55779 11059
252b5132
RH
11060 if (entry->d_un.d_val == 0)
11061 printf (_(" None\n"));
11062 else
11063 {
11064 unsigned long int val = entry->d_un.d_val;
86f55779 11065
252b5132
RH
11066 if (val & DF_P1_LAZYLOAD)
11067 {
11068 printf (" LAZYLOAD");
11069 val ^= DF_P1_LAZYLOAD;
11070 }
11071 if (val & DF_P1_GROUPPERM)
11072 {
11073 printf (" GROUPPERM");
11074 val ^= DF_P1_GROUPPERM;
11075 }
11076 if (val != 0)
11077 printf (" %lx", val);
11078 puts ("");
11079 }
11080 }
11081 break;
11082
11083 case DT_FLAGS_1:
11084 if (do_dynamic)
11085 {
11086 printf (_("Flags:"));
11087 if (entry->d_un.d_val == 0)
11088 printf (_(" None\n"));
11089 else
11090 {
11091 unsigned long int val = entry->d_un.d_val;
86f55779 11092
252b5132
RH
11093 if (val & DF_1_NOW)
11094 {
11095 printf (" NOW");
11096 val ^= DF_1_NOW;
11097 }
11098 if (val & DF_1_GLOBAL)
11099 {
11100 printf (" GLOBAL");
11101 val ^= DF_1_GLOBAL;
11102 }
11103 if (val & DF_1_GROUP)
11104 {
11105 printf (" GROUP");
11106 val ^= DF_1_GROUP;
11107 }
11108 if (val & DF_1_NODELETE)
11109 {
11110 printf (" NODELETE");
11111 val ^= DF_1_NODELETE;
11112 }
11113 if (val & DF_1_LOADFLTR)
11114 {
11115 printf (" LOADFLTR");
11116 val ^= DF_1_LOADFLTR;
11117 }
11118 if (val & DF_1_INITFIRST)
11119 {
11120 printf (" INITFIRST");
11121 val ^= DF_1_INITFIRST;
11122 }
11123 if (val & DF_1_NOOPEN)
11124 {
11125 printf (" NOOPEN");
11126 val ^= DF_1_NOOPEN;
11127 }
11128 if (val & DF_1_ORIGIN)
11129 {
11130 printf (" ORIGIN");
11131 val ^= DF_1_ORIGIN;
11132 }
11133 if (val & DF_1_DIRECT)
11134 {
11135 printf (" DIRECT");
11136 val ^= DF_1_DIRECT;
11137 }
11138 if (val & DF_1_TRANS)
11139 {
11140 printf (" TRANS");
11141 val ^= DF_1_TRANS;
11142 }
11143 if (val & DF_1_INTERPOSE)
11144 {
11145 printf (" INTERPOSE");
11146 val ^= DF_1_INTERPOSE;
11147 }
f7db6139 11148 if (val & DF_1_NODEFLIB)
dcefbbbd 11149 {
f7db6139
L
11150 printf (" NODEFLIB");
11151 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11152 }
11153 if (val & DF_1_NODUMP)
11154 {
11155 printf (" NODUMP");
11156 val ^= DF_1_NODUMP;
11157 }
34b60028 11158 if (val & DF_1_CONFALT)
dcefbbbd 11159 {
34b60028
L
11160 printf (" CONFALT");
11161 val ^= DF_1_CONFALT;
11162 }
11163 if (val & DF_1_ENDFILTEE)
11164 {
11165 printf (" ENDFILTEE");
11166 val ^= DF_1_ENDFILTEE;
11167 }
11168 if (val & DF_1_DISPRELDNE)
11169 {
11170 printf (" DISPRELDNE");
11171 val ^= DF_1_DISPRELDNE;
11172 }
11173 if (val & DF_1_DISPRELPND)
11174 {
11175 printf (" DISPRELPND");
11176 val ^= DF_1_DISPRELPND;
11177 }
11178 if (val & DF_1_NODIRECT)
11179 {
11180 printf (" NODIRECT");
11181 val ^= DF_1_NODIRECT;
11182 }
11183 if (val & DF_1_IGNMULDEF)
11184 {
11185 printf (" IGNMULDEF");
11186 val ^= DF_1_IGNMULDEF;
11187 }
11188 if (val & DF_1_NOKSYMS)
11189 {
11190 printf (" NOKSYMS");
11191 val ^= DF_1_NOKSYMS;
11192 }
11193 if (val & DF_1_NOHDR)
11194 {
11195 printf (" NOHDR");
11196 val ^= DF_1_NOHDR;
11197 }
11198 if (val & DF_1_EDITED)
11199 {
11200 printf (" EDITED");
11201 val ^= DF_1_EDITED;
11202 }
11203 if (val & DF_1_NORELOC)
11204 {
11205 printf (" NORELOC");
11206 val ^= DF_1_NORELOC;
11207 }
11208 if (val & DF_1_SYMINTPOSE)
11209 {
11210 printf (" SYMINTPOSE");
11211 val ^= DF_1_SYMINTPOSE;
11212 }
11213 if (val & DF_1_GLOBAUDIT)
11214 {
11215 printf (" GLOBAUDIT");
11216 val ^= DF_1_GLOBAUDIT;
11217 }
11218 if (val & DF_1_SINGLETON)
11219 {
11220 printf (" SINGLETON");
11221 val ^= DF_1_SINGLETON;
dcefbbbd 11222 }
5c383f02
RO
11223 if (val & DF_1_STUB)
11224 {
11225 printf (" STUB");
11226 val ^= DF_1_STUB;
11227 }
11228 if (val & DF_1_PIE)
11229 {
11230 printf (" PIE");
11231 val ^= DF_1_PIE;
11232 }
b1202ffa
L
11233 if (val & DF_1_KMOD)
11234 {
11235 printf (" KMOD");
11236 val ^= DF_1_KMOD;
11237 }
11238 if (val & DF_1_WEAKFILTER)
11239 {
11240 printf (" WEAKFILTER");
11241 val ^= DF_1_WEAKFILTER;
11242 }
11243 if (val & DF_1_NOCOMMON)
11244 {
11245 printf (" NOCOMMON");
11246 val ^= DF_1_NOCOMMON;
11247 }
252b5132
RH
11248 if (val != 0)
11249 printf (" %lx", val);
11250 puts ("");
11251 }
11252 }
11253 break;
11254
11255 case DT_PLTREL:
978c4450 11256 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11257 if (do_dynamic)
dda8d76d 11258 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11259 break;
11260
11261 case DT_NULL :
11262 case DT_NEEDED :
11263 case DT_PLTGOT :
11264 case DT_HASH :
11265 case DT_STRTAB :
11266 case DT_SYMTAB :
11267 case DT_RELA :
11268 case DT_INIT :
11269 case DT_FINI :
11270 case DT_SONAME :
11271 case DT_RPATH :
11272 case DT_SYMBOLIC:
11273 case DT_REL :
11274 case DT_DEBUG :
11275 case DT_TEXTREL :
11276 case DT_JMPREL :
019148e4 11277 case DT_RUNPATH :
978c4450 11278 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11279
11280 if (do_dynamic)
11281 {
2cf0635d 11282 char * name;
252b5132 11283
978c4450
AM
11284 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11285 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11286 else
d79b3d50 11287 name = NULL;
252b5132
RH
11288
11289 if (name)
11290 {
11291 switch (entry->d_tag)
11292 {
11293 case DT_NEEDED:
11294 printf (_("Shared library: [%s]"), name);
11295
13acb58d
AM
11296 if (filedata->program_interpreter
11297 && streq (name, filedata->program_interpreter))
f7a99963 11298 printf (_(" program interpreter"));
252b5132
RH
11299 break;
11300
11301 case DT_SONAME:
f7a99963 11302 printf (_("Library soname: [%s]"), name);
252b5132
RH
11303 break;
11304
11305 case DT_RPATH:
f7a99963 11306 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11307 break;
11308
019148e4
L
11309 case DT_RUNPATH:
11310 printf (_("Library runpath: [%s]"), name);
11311 break;
11312
252b5132 11313 default:
f7a99963
NC
11314 print_vma (entry->d_un.d_val, PREFIX_HEX);
11315 break;
252b5132
RH
11316 }
11317 }
11318 else
f7a99963
NC
11319 print_vma (entry->d_un.d_val, PREFIX_HEX);
11320
11321 putchar ('\n');
252b5132
RH
11322 }
11323 break;
11324
11325 case DT_PLTRELSZ:
11326 case DT_RELASZ :
11327 case DT_STRSZ :
11328 case DT_RELSZ :
11329 case DT_RELAENT :
11330 case DT_SYMENT :
11331 case DT_RELENT :
978c4450 11332 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11333 /* Fall through. */
252b5132
RH
11334 case DT_PLTPADSZ:
11335 case DT_MOVEENT :
11336 case DT_MOVESZ :
11337 case DT_INIT_ARRAYSZ:
11338 case DT_FINI_ARRAYSZ:
047b2264
JJ
11339 case DT_GNU_CONFLICTSZ:
11340 case DT_GNU_LIBLISTSZ:
252b5132 11341 if (do_dynamic)
f7a99963
NC
11342 {
11343 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11344 printf (_(" (bytes)\n"));
f7a99963 11345 }
252b5132
RH
11346 break;
11347
11348 case DT_VERDEFNUM:
11349 case DT_VERNEEDNUM:
11350 case DT_RELACOUNT:
11351 case DT_RELCOUNT:
11352 if (do_dynamic)
f7a99963
NC
11353 {
11354 print_vma (entry->d_un.d_val, UNSIGNED);
11355 putchar ('\n');
11356 }
252b5132
RH
11357 break;
11358
11359 case DT_SYMINSZ:
11360 case DT_SYMINENT:
11361 case DT_SYMINFO:
11362 case DT_USED:
11363 case DT_INIT_ARRAY:
11364 case DT_FINI_ARRAY:
11365 if (do_dynamic)
11366 {
d79b3d50 11367 if (entry->d_tag == DT_USED
978c4450 11368 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11369 {
978c4450 11370 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11371
b34976b6 11372 if (*name)
252b5132
RH
11373 {
11374 printf (_("Not needed object: [%s]\n"), name);
11375 break;
11376 }
11377 }
103f02d3 11378
f7a99963
NC
11379 print_vma (entry->d_un.d_val, PREFIX_HEX);
11380 putchar ('\n');
252b5132
RH
11381 }
11382 break;
11383
11384 case DT_BIND_NOW:
11385 /* The value of this entry is ignored. */
35b1837e
AM
11386 if (do_dynamic)
11387 putchar ('\n');
252b5132 11388 break;
103f02d3 11389
047b2264
JJ
11390 case DT_GNU_PRELINKED:
11391 if (do_dynamic)
11392 {
2cf0635d 11393 struct tm * tmp;
91d6fa6a 11394 time_t atime = entry->d_un.d_val;
047b2264 11395
91d6fa6a 11396 tmp = gmtime (&atime);
071436c6
NC
11397 /* PR 17533 file: 041-1244816-0.004. */
11398 if (tmp == NULL)
5a2cbcf4
L
11399 printf (_("<corrupt time val: %lx"),
11400 (unsigned long) atime);
071436c6
NC
11401 else
11402 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11403 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11404 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11405
11406 }
11407 break;
11408
fdc90cb4 11409 case DT_GNU_HASH:
978c4450 11410 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11411 if (do_dynamic)
11412 {
11413 print_vma (entry->d_un.d_val, PREFIX_HEX);
11414 putchar ('\n');
11415 }
11416 break;
11417
a5da3dee
VDM
11418 case DT_GNU_FLAGS_1:
11419 if (do_dynamic)
11420 {
11421 printf (_("Flags:"));
11422 if (entry->d_un.d_val == 0)
11423 printf (_(" None\n"));
11424 else
11425 {
11426 unsigned long int val = entry->d_un.d_val;
11427
11428 if (val & DF_GNU_1_UNIQUE)
11429 {
11430 printf (" UNIQUE");
11431 val ^= DF_GNU_1_UNIQUE;
11432 }
11433 if (val != 0)
11434 printf (" %lx", val);
11435 puts ("");
11436 }
11437 }
11438 break;
11439
252b5132
RH
11440 default:
11441 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11442 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11443 = entry->d_un.d_val;
252b5132
RH
11444
11445 if (do_dynamic)
11446 {
dda8d76d 11447 switch (filedata->file_header.e_machine)
252b5132 11448 {
37c18eed
SD
11449 case EM_AARCH64:
11450 dynamic_section_aarch64_val (entry);
11451 break;
252b5132 11452 case EM_MIPS:
4fe85591 11453 case EM_MIPS_RS3_LE:
978c4450 11454 dynamic_section_mips_val (filedata, entry);
252b5132 11455 break;
103f02d3 11456 case EM_PARISC:
b2d38a17 11457 dynamic_section_parisc_val (entry);
103f02d3 11458 break;
ecc51f48 11459 case EM_IA_64:
b2d38a17 11460 dynamic_section_ia64_val (entry);
ecc51f48 11461 break;
252b5132 11462 default:
f7a99963
NC
11463 print_vma (entry->d_un.d_val, PREFIX_HEX);
11464 putchar ('\n');
252b5132
RH
11465 }
11466 }
11467 break;
11468 }
11469 }
11470
015dc7e1 11471 return true;
252b5132
RH
11472}
11473
11474static char *
d3ba0551 11475get_ver_flags (unsigned int flags)
252b5132 11476{
6d4f21f6 11477 static char buff[128];
252b5132
RH
11478
11479 buff[0] = 0;
11480
11481 if (flags == 0)
11482 return _("none");
11483
11484 if (flags & VER_FLG_BASE)
7bb1ad17 11485 strcat (buff, "BASE");
252b5132
RH
11486
11487 if (flags & VER_FLG_WEAK)
11488 {
11489 if (flags & VER_FLG_BASE)
7bb1ad17 11490 strcat (buff, " | ");
252b5132 11491
7bb1ad17 11492 strcat (buff, "WEAK");
252b5132
RH
11493 }
11494
44ec90b9
RO
11495 if (flags & VER_FLG_INFO)
11496 {
11497 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11498 strcat (buff, " | ");
44ec90b9 11499
7bb1ad17 11500 strcat (buff, "INFO");
44ec90b9
RO
11501 }
11502
11503 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11504 {
11505 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11506 strcat (buff, " | ");
11507
11508 strcat (buff, _("<unknown>"));
11509 }
252b5132
RH
11510
11511 return buff;
11512}
11513
11514/* Display the contents of the version sections. */
98fb390a 11515
015dc7e1 11516static bool
dda8d76d 11517process_version_sections (Filedata * filedata)
252b5132 11518{
2cf0635d 11519 Elf_Internal_Shdr * section;
b34976b6 11520 unsigned i;
015dc7e1 11521 bool found = false;
252b5132
RH
11522
11523 if (! do_version)
015dc7e1 11524 return true;
252b5132 11525
dda8d76d
NC
11526 for (i = 0, section = filedata->section_headers;
11527 i < filedata->file_header.e_shnum;
b34976b6 11528 i++, section++)
252b5132
RH
11529 {
11530 switch (section->sh_type)
11531 {
11532 case SHT_GNU_verdef:
11533 {
2cf0635d 11534 Elf_External_Verdef * edefs;
452bf675
AM
11535 unsigned long idx;
11536 unsigned long cnt;
2cf0635d 11537 char * endbuf;
252b5132 11538
015dc7e1 11539 found = true;
252b5132 11540
ca0e11aa
NC
11541 if (filedata->is_separate)
11542 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11543 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11544 section->sh_info),
11545 filedata->file_name,
11546 printable_section_name (filedata, section),
11547 section->sh_info);
11548 else
11549 printf (ngettext ("\nVersion definition section '%s' "
11550 "contains %u entry:\n",
11551 "\nVersion definition section '%s' "
11552 "contains %u entries:\n",
11553 section->sh_info),
11554 printable_section_name (filedata, section),
11555 section->sh_info);
047c3dbf 11556
ae9ac79e 11557 printf (_(" Addr: 0x"));
252b5132 11558 printf_vma (section->sh_addr);
233f82cf 11559 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11560 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11561 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11562
3f5e193b 11563 edefs = (Elf_External_Verdef *)
dda8d76d 11564 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11565 _("version definition section"));
a6e9f9df
AM
11566 if (!edefs)
11567 break;
59245841 11568 endbuf = (char *) edefs + section->sh_size;
252b5132 11569
1445030f 11570 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11571 {
2cf0635d
NC
11572 char * vstart;
11573 Elf_External_Verdef * edef;
b34976b6 11574 Elf_Internal_Verdef ent;
2cf0635d 11575 Elf_External_Verdaux * eaux;
b34976b6 11576 Elf_Internal_Verdaux aux;
452bf675 11577 unsigned long isum;
b34976b6 11578 int j;
103f02d3 11579
252b5132 11580 vstart = ((char *) edefs) + idx;
54806181
AM
11581 if (vstart + sizeof (*edef) > endbuf)
11582 break;
252b5132
RH
11583
11584 edef = (Elf_External_Verdef *) vstart;
11585
11586 ent.vd_version = BYTE_GET (edef->vd_version);
11587 ent.vd_flags = BYTE_GET (edef->vd_flags);
11588 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11589 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11590 ent.vd_hash = BYTE_GET (edef->vd_hash);
11591 ent.vd_aux = BYTE_GET (edef->vd_aux);
11592 ent.vd_next = BYTE_GET (edef->vd_next);
11593
452bf675 11594 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11595 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11596
11597 printf (_(" Index: %d Cnt: %d "),
11598 ent.vd_ndx, ent.vd_cnt);
11599
452bf675 11600 /* Check for overflow. */
1445030f 11601 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11602 break;
11603
252b5132
RH
11604 vstart += ent.vd_aux;
11605
1445030f
AM
11606 if (vstart + sizeof (*eaux) > endbuf)
11607 break;
252b5132
RH
11608 eaux = (Elf_External_Verdaux *) vstart;
11609
11610 aux.vda_name = BYTE_GET (eaux->vda_name);
11611 aux.vda_next = BYTE_GET (eaux->vda_next);
11612
978c4450
AM
11613 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11614 printf (_("Name: %s\n"),
11615 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11616 else
11617 printf (_("Name index: %ld\n"), aux.vda_name);
11618
11619 isum = idx + ent.vd_aux;
11620
b34976b6 11621 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11622 {
1445030f
AM
11623 if (aux.vda_next < sizeof (*eaux)
11624 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11625 {
11626 warn (_("Invalid vda_next field of %lx\n"),
11627 aux.vda_next);
11628 j = ent.vd_cnt;
11629 break;
11630 }
dd24e3da 11631 /* Check for overflow. */
7e26601c 11632 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11633 break;
11634
252b5132
RH
11635 isum += aux.vda_next;
11636 vstart += aux.vda_next;
11637
54806181
AM
11638 if (vstart + sizeof (*eaux) > endbuf)
11639 break;
1445030f 11640 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11641
11642 aux.vda_name = BYTE_GET (eaux->vda_name);
11643 aux.vda_next = BYTE_GET (eaux->vda_next);
11644
978c4450 11645 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11646 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11647 isum, j,
11648 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11649 else
452bf675 11650 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11651 isum, j, aux.vda_name);
11652 }
dd24e3da 11653
54806181
AM
11654 if (j < ent.vd_cnt)
11655 printf (_(" Version def aux past end of section\n"));
252b5132 11656
c9f02c3e
MR
11657 /* PR 17531:
11658 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11659 if (ent.vd_next < sizeof (*edef)
11660 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11661 {
11662 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11663 cnt = section->sh_info;
11664 break;
11665 }
452bf675 11666 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11667 break;
11668
252b5132
RH
11669 idx += ent.vd_next;
11670 }
dd24e3da 11671
54806181
AM
11672 if (cnt < section->sh_info)
11673 printf (_(" Version definition past end of section\n"));
252b5132
RH
11674
11675 free (edefs);
11676 }
11677 break;
103f02d3 11678
252b5132
RH
11679 case SHT_GNU_verneed:
11680 {
2cf0635d 11681 Elf_External_Verneed * eneed;
452bf675
AM
11682 unsigned long idx;
11683 unsigned long cnt;
2cf0635d 11684 char * endbuf;
252b5132 11685
015dc7e1 11686 found = true;
252b5132 11687
ca0e11aa
NC
11688 if (filedata->is_separate)
11689 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11690 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11691 section->sh_info),
11692 filedata->file_name,
11693 printable_section_name (filedata, section),
11694 section->sh_info);
11695 else
11696 printf (ngettext ("\nVersion needs section '%s' "
11697 "contains %u entry:\n",
11698 "\nVersion needs section '%s' "
11699 "contains %u entries:\n",
11700 section->sh_info),
11701 printable_section_name (filedata, section),
11702 section->sh_info);
047c3dbf 11703
252b5132
RH
11704 printf (_(" Addr: 0x"));
11705 printf_vma (section->sh_addr);
72de5009 11706 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11707 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11708 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11709
dda8d76d 11710 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11711 section->sh_offset, 1,
11712 section->sh_size,
9cf03b7e 11713 _("Version Needs section"));
a6e9f9df
AM
11714 if (!eneed)
11715 break;
59245841 11716 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11717
11718 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11719 {
2cf0635d 11720 Elf_External_Verneed * entry;
b34976b6 11721 Elf_Internal_Verneed ent;
452bf675 11722 unsigned long isum;
b34976b6 11723 int j;
2cf0635d 11724 char * vstart;
252b5132
RH
11725
11726 vstart = ((char *) eneed) + idx;
54806181
AM
11727 if (vstart + sizeof (*entry) > endbuf)
11728 break;
252b5132
RH
11729
11730 entry = (Elf_External_Verneed *) vstart;
11731
11732 ent.vn_version = BYTE_GET (entry->vn_version);
11733 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11734 ent.vn_file = BYTE_GET (entry->vn_file);
11735 ent.vn_aux = BYTE_GET (entry->vn_aux);
11736 ent.vn_next = BYTE_GET (entry->vn_next);
11737
452bf675 11738 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11739
978c4450
AM
11740 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11741 printf (_(" File: %s"),
11742 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11743 else
11744 printf (_(" File: %lx"), ent.vn_file);
11745
11746 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11747
dd24e3da 11748 /* Check for overflow. */
7e26601c 11749 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11750 break;
252b5132
RH
11751 vstart += ent.vn_aux;
11752
11753 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11754 {
2cf0635d 11755 Elf_External_Vernaux * eaux;
b34976b6 11756 Elf_Internal_Vernaux aux;
252b5132 11757
54806181
AM
11758 if (vstart + sizeof (*eaux) > endbuf)
11759 break;
252b5132
RH
11760 eaux = (Elf_External_Vernaux *) vstart;
11761
11762 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11763 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11764 aux.vna_other = BYTE_GET (eaux->vna_other);
11765 aux.vna_name = BYTE_GET (eaux->vna_name);
11766 aux.vna_next = BYTE_GET (eaux->vna_next);
11767
978c4450 11768 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11769 printf (_(" %#06lx: Name: %s"),
978c4450 11770 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11771 else
452bf675 11772 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11773 isum, aux.vna_name);
11774
11775 printf (_(" Flags: %s Version: %d\n"),
11776 get_ver_flags (aux.vna_flags), aux.vna_other);
11777
1445030f
AM
11778 if (aux.vna_next < sizeof (*eaux)
11779 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11780 {
11781 warn (_("Invalid vna_next field of %lx\n"),
11782 aux.vna_next);
11783 j = ent.vn_cnt;
11784 break;
11785 }
1445030f
AM
11786 /* Check for overflow. */
11787 if (aux.vna_next > (size_t) (endbuf - vstart))
11788 break;
252b5132
RH
11789 isum += aux.vna_next;
11790 vstart += aux.vna_next;
11791 }
9cf03b7e 11792
54806181 11793 if (j < ent.vn_cnt)
f9a6a8f0 11794 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11795
1445030f
AM
11796 if (ent.vn_next < sizeof (*entry)
11797 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11798 {
452bf675 11799 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11800 cnt = section->sh_info;
11801 break;
11802 }
1445030f
AM
11803 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11804 break;
252b5132
RH
11805 idx += ent.vn_next;
11806 }
9cf03b7e 11807
54806181 11808 if (cnt < section->sh_info)
9cf03b7e 11809 warn (_("Missing Version Needs information\n"));
103f02d3 11810
252b5132
RH
11811 free (eneed);
11812 }
11813 break;
11814
11815 case SHT_GNU_versym:
11816 {
2cf0635d 11817 Elf_Internal_Shdr * link_section;
8b73c356
NC
11818 size_t total;
11819 unsigned int cnt;
2cf0635d
NC
11820 unsigned char * edata;
11821 unsigned short * data;
11822 char * strtab;
11823 Elf_Internal_Sym * symbols;
11824 Elf_Internal_Shdr * string_sec;
ba5cdace 11825 unsigned long num_syms;
d3ba0551 11826 long off;
252b5132 11827
dda8d76d 11828 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11829 break;
11830
dda8d76d 11831 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11832 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11833
dda8d76d 11834 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11835 break;
11836
015dc7e1 11837 found = true;
252b5132 11838
4de91c10 11839 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
11840 if (symbols == NULL)
11841 break;
252b5132 11842
dda8d76d 11843 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11844
dda8d76d 11845 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11846 string_sec->sh_size,
11847 _("version string table"));
a6e9f9df 11848 if (!strtab)
0429c154
MS
11849 {
11850 free (symbols);
11851 break;
11852 }
252b5132 11853
ca0e11aa
NC
11854 if (filedata->is_separate)
11855 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11856 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11857 total),
11858 filedata->file_name,
11859 printable_section_name (filedata, section),
11860 (unsigned long) total);
11861 else
11862 printf (ngettext ("\nVersion symbols section '%s' "
11863 "contains %lu entry:\n",
11864 "\nVersion symbols section '%s' "
11865 "contains %lu entries:\n",
11866 total),
11867 printable_section_name (filedata, section),
11868 (unsigned long) total);
252b5132 11869
ae9ac79e 11870 printf (_(" Addr: 0x"));
252b5132 11871 printf_vma (section->sh_addr);
72de5009 11872 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11873 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11874 printable_section_name (filedata, link_section));
252b5132 11875
dda8d76d 11876 off = offset_from_vma (filedata,
978c4450 11877 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11878 total * sizeof (short));
95099889
AM
11879 edata = (unsigned char *) get_data (NULL, filedata, off,
11880 sizeof (short), total,
11881 _("version symbol data"));
a6e9f9df
AM
11882 if (!edata)
11883 {
11884 free (strtab);
0429c154 11885 free (symbols);
a6e9f9df
AM
11886 break;
11887 }
252b5132 11888
3f5e193b 11889 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11890
11891 for (cnt = total; cnt --;)
b34976b6
AM
11892 data[cnt] = byte_get (edata + cnt * sizeof (short),
11893 sizeof (short));
252b5132
RH
11894
11895 free (edata);
11896
11897 for (cnt = 0; cnt < total; cnt += 4)
11898 {
11899 int j, nn;
ab273396
AM
11900 char *name;
11901 char *invalid = _("*invalid*");
252b5132
RH
11902
11903 printf (" %03x:", cnt);
11904
11905 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11906 switch (data[cnt + j])
252b5132
RH
11907 {
11908 case 0:
11909 fputs (_(" 0 (*local*) "), stdout);
11910 break;
11911
11912 case 1:
11913 fputs (_(" 1 (*global*) "), stdout);
11914 break;
11915
11916 default:
c244d050
NC
11917 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11918 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11919
dd24e3da 11920 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11921 array, break to avoid an out-of-bounds read. */
11922 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11923 {
11924 warn (_("invalid index into symbol array\n"));
11925 break;
11926 }
11927
ab273396 11928 name = NULL;
978c4450 11929 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11930 {
b34976b6
AM
11931 Elf_Internal_Verneed ivn;
11932 unsigned long offset;
252b5132 11933
d93f0186 11934 offset = offset_from_vma
978c4450
AM
11935 (filedata,
11936 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11937 sizeof (Elf_External_Verneed));
252b5132 11938
b34976b6 11939 do
252b5132 11940 {
b34976b6
AM
11941 Elf_Internal_Vernaux ivna;
11942 Elf_External_Verneed evn;
11943 Elf_External_Vernaux evna;
11944 unsigned long a_off;
252b5132 11945
dda8d76d 11946 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11947 _("version need")) == NULL)
11948 break;
0b4362b0 11949
252b5132
RH
11950 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11951 ivn.vn_next = BYTE_GET (evn.vn_next);
11952
11953 a_off = offset + ivn.vn_aux;
11954
11955 do
11956 {
dda8d76d 11957 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11958 1, _("version need aux (2)")) == NULL)
11959 {
11960 ivna.vna_next = 0;
11961 ivna.vna_other = 0;
11962 }
11963 else
11964 {
11965 ivna.vna_next = BYTE_GET (evna.vna_next);
11966 ivna.vna_other = BYTE_GET (evna.vna_other);
11967 }
252b5132
RH
11968
11969 a_off += ivna.vna_next;
11970 }
b34976b6 11971 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11972 && ivna.vna_next != 0);
11973
b34976b6 11974 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11975 {
11976 ivna.vna_name = BYTE_GET (evna.vna_name);
11977
54806181 11978 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11979 name = invalid;
54806181
AM
11980 else
11981 name = strtab + ivna.vna_name;
252b5132
RH
11982 break;
11983 }
11984
11985 offset += ivn.vn_next;
11986 }
11987 while (ivn.vn_next);
11988 }
00d93f34 11989
ab273396 11990 if (data[cnt + j] != 0x8001
978c4450 11991 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11992 {
b34976b6
AM
11993 Elf_Internal_Verdef ivd;
11994 Elf_External_Verdef evd;
11995 unsigned long offset;
252b5132 11996
d93f0186 11997 offset = offset_from_vma
978c4450
AM
11998 (filedata,
11999 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12000 sizeof evd);
252b5132
RH
12001
12002 do
12003 {
dda8d76d 12004 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12005 _("version def")) == NULL)
12006 {
12007 ivd.vd_next = 0;
948f632f 12008 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12009 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12010 break;
59245841
NC
12011 }
12012 else
12013 {
12014 ivd.vd_next = BYTE_GET (evd.vd_next);
12015 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12016 }
252b5132
RH
12017
12018 offset += ivd.vd_next;
12019 }
c244d050 12020 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12021 && ivd.vd_next != 0);
12022
c244d050 12023 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12024 {
b34976b6
AM
12025 Elf_External_Verdaux evda;
12026 Elf_Internal_Verdaux ivda;
252b5132
RH
12027
12028 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12029
dda8d76d 12030 if (get_data (&evda, filedata,
59245841
NC
12031 offset - ivd.vd_next + ivd.vd_aux,
12032 sizeof (evda), 1,
12033 _("version def aux")) == NULL)
12034 break;
252b5132
RH
12035
12036 ivda.vda_name = BYTE_GET (evda.vda_name);
12037
54806181 12038 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12039 name = invalid;
12040 else if (name != NULL && name != invalid)
12041 name = _("*both*");
54806181
AM
12042 else
12043 name = strtab + ivda.vda_name;
252b5132
RH
12044 }
12045 }
ab273396
AM
12046 if (name != NULL)
12047 nn += printf ("(%s%-*s",
12048 name,
12049 12 - (int) strlen (name),
12050 ")");
252b5132
RH
12051
12052 if (nn < 18)
12053 printf ("%*c", 18 - nn, ' ');
12054 }
12055
12056 putchar ('\n');
12057 }
12058
12059 free (data);
12060 free (strtab);
12061 free (symbols);
12062 }
12063 break;
103f02d3 12064
252b5132
RH
12065 default:
12066 break;
12067 }
12068 }
12069
12070 if (! found)
ca0e11aa
NC
12071 {
12072 if (filedata->is_separate)
12073 printf (_("\nNo version information found in linked file '%s'.\n"),
12074 filedata->file_name);
12075 else
12076 printf (_("\nNo version information found in this file.\n"));
12077 }
252b5132 12078
015dc7e1 12079 return true;
252b5132
RH
12080}
12081
d1133906 12082static const char *
dda8d76d 12083get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12084{
89246a0e 12085 static char buff[64];
252b5132
RH
12086
12087 switch (binding)
12088 {
b34976b6
AM
12089 case STB_LOCAL: return "LOCAL";
12090 case STB_GLOBAL: return "GLOBAL";
12091 case STB_WEAK: return "WEAK";
252b5132
RH
12092 default:
12093 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12094 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12095 binding);
252b5132 12096 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12097 {
12098 if (binding == STB_GNU_UNIQUE
df3a023b 12099 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12100 return "UNIQUE";
12101 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12102 }
252b5132 12103 else
e9e44622 12104 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12105 return buff;
12106 }
12107}
12108
d1133906 12109static const char *
dda8d76d 12110get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12111{
89246a0e 12112 static char buff[64];
252b5132
RH
12113
12114 switch (type)
12115 {
b34976b6
AM
12116 case STT_NOTYPE: return "NOTYPE";
12117 case STT_OBJECT: return "OBJECT";
12118 case STT_FUNC: return "FUNC";
12119 case STT_SECTION: return "SECTION";
12120 case STT_FILE: return "FILE";
12121 case STT_COMMON: return "COMMON";
12122 case STT_TLS: return "TLS";
15ab5209
DB
12123 case STT_RELC: return "RELC";
12124 case STT_SRELC: return "SRELC";
252b5132
RH
12125 default:
12126 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12127 {
dda8d76d 12128 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12129 return "THUMB_FUNC";
103f02d3 12130
dda8d76d 12131 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12132 return "REGISTER";
12133
dda8d76d 12134 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12135 return "PARISC_MILLI";
12136
e9e44622 12137 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12138 }
252b5132 12139 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12140 {
dda8d76d 12141 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12142 {
12143 if (type == STT_HP_OPAQUE)
12144 return "HP_OPAQUE";
12145 if (type == STT_HP_STUB)
12146 return "HP_STUB";
12147 }
12148
d8045f23 12149 if (type == STT_GNU_IFUNC
dda8d76d 12150 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12151 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12152 return "IFUNC";
12153
e9e44622 12154 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12155 }
252b5132 12156 else
e9e44622 12157 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12158 return buff;
12159 }
12160}
12161
d1133906 12162static const char *
d3ba0551 12163get_symbol_visibility (unsigned int visibility)
d1133906
NC
12164{
12165 switch (visibility)
12166 {
b34976b6
AM
12167 case STV_DEFAULT: return "DEFAULT";
12168 case STV_INTERNAL: return "INTERNAL";
12169 case STV_HIDDEN: return "HIDDEN";
d1133906 12170 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12171 default:
27a45f42 12172 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12173 return _("<unknown>");
d1133906
NC
12174 }
12175}
12176
2057d69d
CZ
12177static const char *
12178get_alpha_symbol_other (unsigned int other)
9abca702 12179{
2057d69d
CZ
12180 switch (other)
12181 {
12182 case STO_ALPHA_NOPV: return "NOPV";
12183 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12184 default:
27a45f42 12185 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12186 return _("<unknown>");
9abca702 12187 }
2057d69d
CZ
12188}
12189
fd85a6a1
NC
12190static const char *
12191get_solaris_symbol_visibility (unsigned int visibility)
12192{
12193 switch (visibility)
12194 {
12195 case 4: return "EXPORTED";
12196 case 5: return "SINGLETON";
12197 case 6: return "ELIMINATE";
12198 default: return get_symbol_visibility (visibility);
12199 }
12200}
12201
2301ed1c
SN
12202static const char *
12203get_aarch64_symbol_other (unsigned int other)
12204{
12205 static char buf[32];
12206
12207 if (other & STO_AARCH64_VARIANT_PCS)
12208 {
12209 other &= ~STO_AARCH64_VARIANT_PCS;
12210 if (other == 0)
12211 return "VARIANT_PCS";
12212 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12213 return buf;
12214 }
12215 return NULL;
12216}
12217
5e2b0d47
NC
12218static const char *
12219get_mips_symbol_other (unsigned int other)
12220{
12221 switch (other)
12222 {
32ec8896
NC
12223 case STO_OPTIONAL: return "OPTIONAL";
12224 case STO_MIPS_PLT: return "MIPS PLT";
12225 case STO_MIPS_PIC: return "MIPS PIC";
12226 case STO_MICROMIPS: return "MICROMIPS";
12227 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12228 case STO_MIPS16: return "MIPS16";
12229 default: return NULL;
5e2b0d47
NC
12230 }
12231}
12232
28f997cf 12233static const char *
dda8d76d 12234get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12235{
dda8d76d 12236 if (is_ia64_vms (filedata))
28f997cf
TG
12237 {
12238 static char res[32];
12239
12240 res[0] = 0;
12241
12242 /* Function types is for images and .STB files only. */
dda8d76d 12243 switch (filedata->file_header.e_type)
28f997cf
TG
12244 {
12245 case ET_DYN:
12246 case ET_EXEC:
12247 switch (VMS_ST_FUNC_TYPE (other))
12248 {
12249 case VMS_SFT_CODE_ADDR:
12250 strcat (res, " CA");
12251 break;
12252 case VMS_SFT_SYMV_IDX:
12253 strcat (res, " VEC");
12254 break;
12255 case VMS_SFT_FD:
12256 strcat (res, " FD");
12257 break;
12258 case VMS_SFT_RESERVE:
12259 strcat (res, " RSV");
12260 break;
12261 default:
bee0ee85
NC
12262 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12263 VMS_ST_FUNC_TYPE (other));
12264 strcat (res, " <unknown>");
12265 break;
28f997cf
TG
12266 }
12267 break;
12268 default:
12269 break;
12270 }
12271 switch (VMS_ST_LINKAGE (other))
12272 {
12273 case VMS_STL_IGNORE:
12274 strcat (res, " IGN");
12275 break;
12276 case VMS_STL_RESERVE:
12277 strcat (res, " RSV");
12278 break;
12279 case VMS_STL_STD:
12280 strcat (res, " STD");
12281 break;
12282 case VMS_STL_LNK:
12283 strcat (res, " LNK");
12284 break;
12285 default:
bee0ee85
NC
12286 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12287 VMS_ST_LINKAGE (other));
12288 strcat (res, " <unknown>");
12289 break;
28f997cf
TG
12290 }
12291
12292 if (res[0] != 0)
12293 return res + 1;
12294 else
12295 return res;
12296 }
12297 return NULL;
12298}
12299
6911b7dc
AM
12300static const char *
12301get_ppc64_symbol_other (unsigned int other)
12302{
14732552
AM
12303 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12304 return NULL;
12305
12306 other >>= STO_PPC64_LOCAL_BIT;
12307 if (other <= 6)
6911b7dc 12308 {
89246a0e 12309 static char buf[64];
14732552
AM
12310 if (other >= 2)
12311 other = ppc64_decode_local_entry (other);
12312 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12313 return buf;
12314 }
12315 return NULL;
12316}
12317
5e2b0d47 12318static const char *
dda8d76d 12319get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12320{
12321 const char * result = NULL;
89246a0e 12322 static char buff [64];
5e2b0d47
NC
12323
12324 if (other == 0)
12325 return "";
12326
dda8d76d 12327 switch (filedata->file_header.e_machine)
5e2b0d47 12328 {
2057d69d
CZ
12329 case EM_ALPHA:
12330 result = get_alpha_symbol_other (other);
12331 break;
2301ed1c
SN
12332 case EM_AARCH64:
12333 result = get_aarch64_symbol_other (other);
12334 break;
5e2b0d47
NC
12335 case EM_MIPS:
12336 result = get_mips_symbol_other (other);
28f997cf
TG
12337 break;
12338 case EM_IA_64:
dda8d76d 12339 result = get_ia64_symbol_other (filedata, other);
28f997cf 12340 break;
6911b7dc
AM
12341 case EM_PPC64:
12342 result = get_ppc64_symbol_other (other);
12343 break;
5e2b0d47 12344 default:
fd85a6a1 12345 result = NULL;
5e2b0d47
NC
12346 break;
12347 }
12348
12349 if (result)
12350 return result;
12351
12352 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12353 return buff;
12354}
12355
d1133906 12356static const char *
dda8d76d 12357get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12358{
b34976b6 12359 static char buff[32];
5cf1065c 12360
252b5132
RH
12361 switch (type)
12362 {
b34976b6
AM
12363 case SHN_UNDEF: return "UND";
12364 case SHN_ABS: return "ABS";
12365 case SHN_COMMON: return "COM";
252b5132 12366 default:
9ce701e2 12367 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12368 && filedata->file_header.e_machine == EM_IA_64
12369 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12370 return "ANSI_COM";
12371 else if ((filedata->file_header.e_machine == EM_X86_64
12372 || filedata->file_header.e_machine == EM_L1OM
12373 || filedata->file_header.e_machine == EM_K1OM)
12374 && type == SHN_X86_64_LCOMMON)
12375 return "LARGE_COM";
12376 else if ((type == SHN_MIPS_SCOMMON
12377 && filedata->file_header.e_machine == EM_MIPS)
12378 || (type == SHN_TIC6X_SCOMMON
12379 && filedata->file_header.e_machine == EM_TI_C6000))
12380 return "SCOM";
12381 else if (type == SHN_MIPS_SUNDEFINED
12382 && filedata->file_header.e_machine == EM_MIPS)
12383 return "SUND";
12384 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12385 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12386 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12387 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12388 else if (type >= SHN_LORESERVE)
12389 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12390 else if (filedata->file_header.e_shnum != 0
12391 && type >= filedata->file_header.e_shnum)
12392 sprintf (buff, _("bad section index[%3d]"), type);
12393 else
12394 sprintf (buff, "%3d", type);
12395 break;
fd85a6a1
NC
12396 }
12397
10ca4b04 12398 return buff;
6bd1a22c
L
12399}
12400
bb4d2ac2 12401static const char *
dda8d76d 12402get_symbol_version_string (Filedata * filedata,
015dc7e1 12403 bool is_dynsym,
1449284b
NC
12404 const char * strtab,
12405 unsigned long int strtab_size,
12406 unsigned int si,
12407 Elf_Internal_Sym * psym,
12408 enum versioned_symbol_info * sym_info,
12409 unsigned short * vna_other)
bb4d2ac2 12410{
ab273396
AM
12411 unsigned char data[2];
12412 unsigned short vers_data;
12413 unsigned long offset;
7a815dd5 12414 unsigned short max_vd_ndx;
bb4d2ac2 12415
ab273396 12416 if (!is_dynsym
978c4450 12417 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12418 return NULL;
bb4d2ac2 12419
978c4450
AM
12420 offset = offset_from_vma (filedata,
12421 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12422 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12423
dda8d76d 12424 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12425 sizeof (data), 1, _("version data")) == NULL)
12426 return NULL;
12427
12428 vers_data = byte_get (data, 2);
bb4d2ac2 12429
1f6f5dba 12430 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12431 return NULL;
bb4d2ac2 12432
0b8b7609 12433 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12434 max_vd_ndx = 0;
12435
ab273396
AM
12436 /* Usually we'd only see verdef for defined symbols, and verneed for
12437 undefined symbols. However, symbols defined by the linker in
12438 .dynbss for variables copied from a shared library in order to
12439 avoid text relocations are defined yet have verneed. We could
12440 use a heuristic to detect the special case, for example, check
12441 for verneed first on symbols defined in SHT_NOBITS sections, but
12442 it is simpler and more reliable to just look for both verdef and
12443 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12444
ab273396
AM
12445 if (psym->st_shndx != SHN_UNDEF
12446 && vers_data != 0x8001
978c4450 12447 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12448 {
12449 Elf_Internal_Verdef ivd;
12450 Elf_Internal_Verdaux ivda;
12451 Elf_External_Verdaux evda;
12452 unsigned long off;
bb4d2ac2 12453
dda8d76d 12454 off = offset_from_vma (filedata,
978c4450 12455 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12456 sizeof (Elf_External_Verdef));
12457
12458 do
bb4d2ac2 12459 {
ab273396
AM
12460 Elf_External_Verdef evd;
12461
dda8d76d 12462 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12463 _("version def")) == NULL)
12464 {
12465 ivd.vd_ndx = 0;
12466 ivd.vd_aux = 0;
12467 ivd.vd_next = 0;
1f6f5dba 12468 ivd.vd_flags = 0;
ab273396
AM
12469 }
12470 else
bb4d2ac2 12471 {
ab273396
AM
12472 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12473 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12474 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12475 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12476 }
bb4d2ac2 12477
7a815dd5
L
12478 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12479 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12480
ab273396
AM
12481 off += ivd.vd_next;
12482 }
12483 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12484
ab273396
AM
12485 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12486 {
9abca702 12487 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12488 return NULL;
12489
ab273396
AM
12490 off -= ivd.vd_next;
12491 off += ivd.vd_aux;
bb4d2ac2 12492
dda8d76d 12493 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12494 _("version def aux")) != NULL)
12495 {
12496 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12497
ab273396 12498 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12499 return (ivda.vda_name < strtab_size
12500 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12501 }
12502 }
12503 }
bb4d2ac2 12504
978c4450 12505 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12506 {
12507 Elf_External_Verneed evn;
12508 Elf_Internal_Verneed ivn;
12509 Elf_Internal_Vernaux ivna;
bb4d2ac2 12510
dda8d76d 12511 offset = offset_from_vma (filedata,
978c4450 12512 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12513 sizeof evn);
12514 do
12515 {
12516 unsigned long vna_off;
bb4d2ac2 12517
dda8d76d 12518 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12519 _("version need")) == NULL)
12520 {
12521 ivna.vna_next = 0;
12522 ivna.vna_other = 0;
12523 ivna.vna_name = 0;
12524 break;
12525 }
bb4d2ac2 12526
ab273396
AM
12527 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12528 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12529
ab273396 12530 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12531
ab273396
AM
12532 do
12533 {
12534 Elf_External_Vernaux evna;
bb4d2ac2 12535
dda8d76d 12536 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12537 _("version need aux (3)")) == NULL)
bb4d2ac2 12538 {
ab273396
AM
12539 ivna.vna_next = 0;
12540 ivna.vna_other = 0;
12541 ivna.vna_name = 0;
bb4d2ac2 12542 }
bb4d2ac2 12543 else
bb4d2ac2 12544 {
ab273396
AM
12545 ivna.vna_other = BYTE_GET (evna.vna_other);
12546 ivna.vna_next = BYTE_GET (evna.vna_next);
12547 ivna.vna_name = BYTE_GET (evna.vna_name);
12548 }
bb4d2ac2 12549
ab273396
AM
12550 vna_off += ivna.vna_next;
12551 }
12552 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12553
ab273396
AM
12554 if (ivna.vna_other == vers_data)
12555 break;
bb4d2ac2 12556
ab273396
AM
12557 offset += ivn.vn_next;
12558 }
12559 while (ivn.vn_next != 0);
bb4d2ac2 12560
ab273396
AM
12561 if (ivna.vna_other == vers_data)
12562 {
12563 *sym_info = symbol_undefined;
12564 *vna_other = ivna.vna_other;
12565 return (ivna.vna_name < strtab_size
12566 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12567 }
7a815dd5
L
12568 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12569 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12570 return _("<corrupt>");
bb4d2ac2 12571 }
ab273396 12572 return NULL;
bb4d2ac2
L
12573}
12574
047c3dbf
NL
12575/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12576
12577static unsigned int
12578print_dynamic_symbol_size (bfd_vma vma, int base)
12579{
12580 switch (base)
12581 {
12582 case 8:
12583 return print_vma (vma, OCTAL_5);
12584
12585 case 10:
12586 return print_vma (vma, UNSIGNED_5);
12587
12588 case 16:
12589 return print_vma (vma, PREFIX_HEX_5);
12590
12591 case 0:
12592 default:
12593 return print_vma (vma, DEC_5);
12594 }
12595}
12596
10ca4b04
L
12597static void
12598print_dynamic_symbol (Filedata *filedata, unsigned long si,
12599 Elf_Internal_Sym *symtab,
12600 Elf_Internal_Shdr *section,
12601 char *strtab, size_t strtab_size)
252b5132 12602{
10ca4b04
L
12603 const char *version_string;
12604 enum versioned_symbol_info sym_info;
12605 unsigned short vna_other;
23356397
NC
12606 bool is_valid;
12607 const char * sstr;
10ca4b04 12608 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12609
10ca4b04
L
12610 printf ("%6ld: ", si);
12611 print_vma (psym->st_value, LONG_HEX);
12612 putchar (' ');
047c3dbf 12613 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12614 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12615 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12616 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12617 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12618 else
252b5132 12619 {
10ca4b04 12620 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12621
10ca4b04
L
12622 printf (" %-7s", get_symbol_visibility (vis));
12623 /* Check to see if any other bits in the st_other field are set.
12624 Note - displaying this information disrupts the layout of the
12625 table being generated, but for the moment this case is very rare. */
12626 if (psym->st_other ^ vis)
12627 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12628 }
10ca4b04 12629 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12630
23356397
NC
12631 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12632 && psym->st_shndx < filedata->file_header.e_shnum
12633 && psym->st_name == 0)
12634 {
12635 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12636 sstr = is_valid ?
12637 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12638 : _("<corrupt>");
12639 }
12640 else
12641 {
12642 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12643 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12644 }
10ca4b04
L
12645
12646 version_string
12647 = get_symbol_version_string (filedata,
12648 (section == NULL
12649 || section->sh_type == SHT_DYNSYM),
12650 strtab, strtab_size, si,
12651 psym, &sym_info, &vna_other);
b9e920ec 12652
0942c7ab
NC
12653 int len_avail = 21;
12654 if (! do_wide && version_string != NULL)
12655 {
ddb43bab 12656 char buffer[16];
0942c7ab 12657
ddb43bab 12658 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12659
12660 if (sym_info == symbol_undefined)
12661 len_avail -= sprintf (buffer," (%d)", vna_other);
12662 else if (sym_info != symbol_hidden)
12663 len_avail -= 1;
12664 }
12665
12666 print_symbol (len_avail, sstr);
b9e920ec 12667
10ca4b04
L
12668 if (version_string)
12669 {
12670 if (sym_info == symbol_undefined)
12671 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12672 else
10ca4b04
L
12673 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12674 version_string);
12675 }
6bd1a22c 12676
10ca4b04 12677 putchar ('\n');
6bd1a22c 12678
10ca4b04
L
12679 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12680 && section != NULL
12681 && si >= section->sh_info
12682 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12683 && filedata->file_header.e_machine != EM_MIPS
12684 /* Solaris binaries have been found to violate this requirement as
12685 well. Not sure if this is a bug or an ABI requirement. */
12686 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12687 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12688 si, printable_section_name (filedata, section), section->sh_info);
12689}
f16a9783 12690
0f03783c
NC
12691static const char *
12692get_lto_kind (unsigned int kind)
12693{
12694 switch (kind)
12695 {
12696 case 0: return "DEF";
12697 case 1: return "WEAKDEF";
12698 case 2: return "UNDEF";
12699 case 3: return "WEAKUNDEF";
12700 case 4: return "COMMON";
12701 default:
12702 break;
12703 }
12704
12705 static char buffer[30];
12706 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12707 sprintf (buffer, "<unknown: %u>", kind);
12708 return buffer;
12709}
12710
12711static const char *
12712get_lto_visibility (unsigned int visibility)
12713{
12714 switch (visibility)
12715 {
12716 case 0: return "DEFAULT";
12717 case 1: return "PROTECTED";
12718 case 2: return "INTERNAL";
12719 case 3: return "HIDDEN";
12720 default:
12721 break;
12722 }
12723
12724 static char buffer[30];
12725 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12726 sprintf (buffer, "<unknown: %u>", visibility);
12727 return buffer;
12728}
12729
12730static const char *
12731get_lto_sym_type (unsigned int sym_type)
12732{
12733 switch (sym_type)
12734 {
12735 case 0: return "UNKNOWN";
12736 case 1: return "FUNCTION";
12737 case 2: return "VARIABLE";
12738 default:
12739 break;
12740 }
12741
12742 static char buffer[30];
12743 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12744 sprintf (buffer, "<unknown: %u>", sym_type);
12745 return buffer;
12746}
12747
12748/* Display an LTO format symbol table.
12749 FIXME: The format of LTO symbol tables is not formalized.
12750 So this code could need changing in the future. */
12751
015dc7e1 12752static bool
0f03783c
NC
12753display_lto_symtab (Filedata * filedata,
12754 Elf_Internal_Shdr * section)
12755{
12756 if (section->sh_size == 0)
12757 {
ca0e11aa
NC
12758 if (filedata->is_separate)
12759 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12760 printable_section_name (filedata, section),
12761 filedata->file_name);
12762 else
12763 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12764 printable_section_name (filedata, section));
047c3dbf 12765
015dc7e1 12766 return true;
0f03783c
NC
12767 }
12768
12769 if (section->sh_size > filedata->file_size)
12770 {
12771 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12772 printable_section_name (filedata, section),
12773 (unsigned long) section->sh_size);
015dc7e1 12774 return false;
0f03783c
NC
12775 }
12776
12777 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12778 section->sh_size, 1, _("LTO symbols"));
12779 if (alloced_data == NULL)
015dc7e1 12780 return false;
0f03783c
NC
12781
12782 /* Look for extended data for the symbol table. */
12783 Elf_Internal_Shdr * ext;
12784 void * ext_data_orig = NULL;
12785 char * ext_data = NULL;
12786 char * ext_data_end = NULL;
12787 char * ext_name = NULL;
12788
12789 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12790 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12791 && ext_name != NULL /* Paranoia. */
12792 && (ext = find_section (filedata, ext_name)) != NULL)
12793 {
12794 if (ext->sh_size < 3)
12795 error (_("LTO Symbol extension table '%s' is empty!\n"),
12796 printable_section_name (filedata, ext));
12797 else
12798 {
12799 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12800 ext->sh_size, 1,
12801 _("LTO ext symbol data"));
12802 if (ext_data != NULL)
12803 {
12804 ext_data_end = ext_data + ext->sh_size;
12805 if (* ext_data++ != 1)
12806 error (_("Unexpected version number in symbol extension table\n"));
12807 }
12808 }
12809 }
b9e920ec 12810
0f03783c
NC
12811 const unsigned char * data = (const unsigned char *) alloced_data;
12812 const unsigned char * end = data + section->sh_size;
12813
ca0e11aa
NC
12814 if (filedata->is_separate)
12815 printf (_("\nIn linked file '%s': "), filedata->file_name);
12816 else
12817 printf ("\n");
12818
0f03783c
NC
12819 if (ext_data_orig != NULL)
12820 {
12821 if (do_wide)
ca0e11aa 12822 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12823 printable_section_name (filedata, section),
12824 printable_section_name (filedata, ext));
12825 else
12826 {
ca0e11aa 12827 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12828 printable_section_name (filedata, section));
12829 printf (_(" and extension table '%s' contain:\n"),
12830 printable_section_name (filedata, ext));
12831 }
12832 }
12833 else
ca0e11aa 12834 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12835 printable_section_name (filedata, section));
b9e920ec 12836
0f03783c 12837 /* FIXME: Add a wide version. */
b9e920ec 12838 if (ext_data_orig != NULL)
0f03783c
NC
12839 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12840 else
12841 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12842
12843 /* FIXME: We do not handle style prefixes. */
12844
12845 while (data < end)
12846 {
12847 const unsigned char * sym_name = data;
12848 data += strnlen ((const char *) sym_name, end - data) + 1;
12849 if (data >= end)
12850 goto fail;
12851
12852 const unsigned char * comdat_key = data;
12853 data += strnlen ((const char *) comdat_key, end - data) + 1;
12854 if (data >= end)
12855 goto fail;
12856
12857 if (data + 2 + 8 + 4 > end)
12858 goto fail;
12859
12860 unsigned int kind = *data++;
12861 unsigned int visibility = *data++;
12862
12863 elf_vma size = byte_get (data, 8);
12864 data += 8;
12865
12866 elf_vma slot = byte_get (data, 4);
12867 data += 4;
12868
12869 if (ext_data != NULL)
12870 {
12871 if (ext_data < (ext_data_end - 1))
12872 {
12873 unsigned int sym_type = * ext_data ++;
12874 unsigned int sec_kind = * ext_data ++;
12875
12876 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12877 * comdat_key == 0 ? "-" : (char *) comdat_key,
12878 get_lto_kind (kind),
12879 get_lto_visibility (visibility),
12880 (long) size,
12881 (long) slot,
12882 get_lto_sym_type (sym_type),
12883 (long) sec_kind);
12884 print_symbol (6, (const char *) sym_name);
12885 }
12886 else
12887 {
12888 error (_("Ran out of LTO symbol extension data\n"));
12889 ext_data = NULL;
12890 /* FIXME: return FAIL result ? */
12891 }
12892 }
12893 else
12894 {
12895 printf (" %10s %10s %11s %08lx %08lx _",
12896 * comdat_key == 0 ? "-" : (char *) comdat_key,
12897 get_lto_kind (kind),
12898 get_lto_visibility (visibility),
12899 (long) size,
12900 (long) slot);
12901 print_symbol (21, (const char *) sym_name);
12902 }
12903 putchar ('\n');
12904 }
12905
12906 if (ext_data != NULL && ext_data < ext_data_end)
12907 {
12908 error (_("Data remains in the LTO symbol extension table\n"));
12909 goto fail;
12910 }
12911
12912 free (alloced_data);
12913 free (ext_data_orig);
12914 free (ext_name);
015dc7e1 12915 return true;
b9e920ec 12916
0f03783c
NC
12917 fail:
12918 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12919 free (alloced_data);
12920 free (ext_data_orig);
12921 free (ext_name);
015dc7e1 12922 return false;
0f03783c
NC
12923}
12924
12925/* Display LTO symbol tables. */
12926
015dc7e1 12927static bool
0f03783c
NC
12928process_lto_symbol_tables (Filedata * filedata)
12929{
12930 Elf_Internal_Shdr * section;
12931 unsigned int i;
015dc7e1 12932 bool res = true;
0f03783c
NC
12933
12934 if (!do_lto_syms)
015dc7e1 12935 return true;
0f03783c
NC
12936
12937 if (filedata->section_headers == NULL)
015dc7e1 12938 return true;
0f03783c
NC
12939
12940 for (i = 0, section = filedata->section_headers;
12941 i < filedata->file_header.e_shnum;
12942 i++, section++)
b9e920ec 12943 if (SECTION_NAME_VALID (section)
08dedd66 12944 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12945 res &= display_lto_symtab (filedata, section);
12946
b9e920ec 12947 return res;
0f03783c
NC
12948}
12949
10ca4b04 12950/* Dump the symbol table. */
0f03783c 12951
015dc7e1 12952static bool
10ca4b04
L
12953process_symbol_table (Filedata * filedata)
12954{
12955 Elf_Internal_Shdr * section;
f16a9783 12956
10ca4b04 12957 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12958 return true;
6bd1a22c 12959
978c4450 12960 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12961 && do_syms
12962 && do_using_dynamic
978c4450
AM
12963 && filedata->dynamic_strings != NULL
12964 && filedata->dynamic_symbols != NULL)
6bd1a22c 12965 {
10ca4b04 12966 unsigned long si;
6bd1a22c 12967
ca0e11aa
NC
12968 if (filedata->is_separate)
12969 {
12970 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12971 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12972 filedata->num_dynamic_syms),
12973 filedata->file_name,
12974 filedata->num_dynamic_syms);
12975 }
12976 else
12977 {
12978 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12979 "\nSymbol table for image contains %lu entries:\n",
12980 filedata->num_dynamic_syms),
12981 filedata->num_dynamic_syms);
12982 }
10ca4b04
L
12983 if (is_32bit_elf)
12984 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12985 else
12986 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12987
978c4450
AM
12988 for (si = 0; si < filedata->num_dynamic_syms; si++)
12989 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12990 filedata->dynamic_strings,
12991 filedata->dynamic_strings_length);
252b5132 12992 }
8b73c356 12993 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12994 && filedata->section_headers != NULL)
252b5132 12995 {
b34976b6 12996 unsigned int i;
252b5132 12997
dda8d76d
NC
12998 for (i = 0, section = filedata->section_headers;
12999 i < filedata->file_header.e_shnum;
252b5132
RH
13000 i++, section++)
13001 {
2cf0635d 13002 char * strtab = NULL;
c256ffe7 13003 unsigned long int strtab_size = 0;
2cf0635d 13004 Elf_Internal_Sym * symtab;
ef3df110 13005 unsigned long si, num_syms;
252b5132 13006
2c610e4b
L
13007 if ((section->sh_type != SHT_SYMTAB
13008 && section->sh_type != SHT_DYNSYM)
13009 || (!do_syms
13010 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13011 continue;
13012
dd24e3da
NC
13013 if (section->sh_entsize == 0)
13014 {
13015 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13016 printable_section_name (filedata, section));
dd24e3da
NC
13017 continue;
13018 }
13019
d3a49aa8 13020 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13021
13022 if (filedata->is_separate)
13023 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13024 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13025 num_syms),
13026 filedata->file_name,
13027 printable_section_name (filedata, section),
13028 num_syms);
13029 else
13030 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13031 "\nSymbol table '%s' contains %lu entries:\n",
13032 num_syms),
13033 printable_section_name (filedata, section),
13034 num_syms);
dd24e3da 13035
f7a99963 13036 if (is_32bit_elf)
ca47b30c 13037 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13038 else
ca47b30c 13039 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13040
4de91c10 13041 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13042 if (symtab == NULL)
13043 continue;
13044
dda8d76d 13045 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13046 {
dda8d76d
NC
13047 strtab = filedata->string_table;
13048 strtab_size = filedata->string_table_length;
c256ffe7 13049 }
dda8d76d 13050 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13051 {
2cf0635d 13052 Elf_Internal_Shdr * string_sec;
252b5132 13053
dda8d76d 13054 string_sec = filedata->section_headers + section->sh_link;
252b5132 13055
dda8d76d 13056 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13057 1, string_sec->sh_size,
13058 _("string table"));
c256ffe7 13059 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13060 }
13061
10ca4b04
L
13062 for (si = 0; si < num_syms; si++)
13063 print_dynamic_symbol (filedata, si, symtab, section,
13064 strtab, strtab_size);
252b5132
RH
13065
13066 free (symtab);
dda8d76d 13067 if (strtab != filedata->string_table)
252b5132
RH
13068 free (strtab);
13069 }
13070 }
13071 else if (do_syms)
13072 printf
13073 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13074
978c4450 13075 if (do_histogram && filedata->buckets != NULL)
252b5132 13076 {
2cf0635d
NC
13077 unsigned long * lengths;
13078 unsigned long * counts;
66543521
AM
13079 unsigned long hn;
13080 bfd_vma si;
13081 unsigned long maxlength = 0;
13082 unsigned long nzero_counts = 0;
13083 unsigned long nsyms = 0;
6bd6a03d 13084 char *visited;
252b5132 13085
d3a49aa8
AM
13086 printf (ngettext ("\nHistogram for bucket list length "
13087 "(total of %lu bucket):\n",
13088 "\nHistogram for bucket list length "
13089 "(total of %lu buckets):\n",
978c4450
AM
13090 (unsigned long) filedata->nbuckets),
13091 (unsigned long) filedata->nbuckets);
252b5132 13092
978c4450
AM
13093 lengths = (unsigned long *) calloc (filedata->nbuckets,
13094 sizeof (*lengths));
252b5132
RH
13095 if (lengths == NULL)
13096 {
8b73c356 13097 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13098 goto err_out;
252b5132 13099 }
978c4450
AM
13100 visited = xcmalloc (filedata->nchains, 1);
13101 memset (visited, 0, filedata->nchains);
8b73c356
NC
13102
13103 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13104 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13105 {
978c4450 13106 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13107 {
b34976b6 13108 ++nsyms;
252b5132 13109 if (maxlength < ++lengths[hn])
b34976b6 13110 ++maxlength;
978c4450 13111 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13112 {
13113 error (_("histogram chain is corrupt\n"));
13114 break;
13115 }
13116 visited[si] = 1;
252b5132
RH
13117 }
13118 }
6bd6a03d 13119 free (visited);
252b5132 13120
3f5e193b 13121 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13122 if (counts == NULL)
13123 {
b2e951ec 13124 free (lengths);
8b73c356 13125 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13126 goto err_out;
252b5132
RH
13127 }
13128
978c4450 13129 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13130 ++counts[lengths[hn]];
252b5132 13131
978c4450 13132 if (filedata->nbuckets > 0)
252b5132 13133 {
66543521
AM
13134 unsigned long i;
13135 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13136 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13137 for (i = 1; i <= maxlength; ++i)
103f02d3 13138 {
66543521
AM
13139 nzero_counts += counts[i] * i;
13140 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13141 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13142 (nzero_counts * 100.0) / nsyms);
13143 }
252b5132
RH
13144 }
13145
13146 free (counts);
13147 free (lengths);
13148 }
13149
978c4450
AM
13150 free (filedata->buckets);
13151 filedata->buckets = NULL;
13152 filedata->nbuckets = 0;
13153 free (filedata->chains);
13154 filedata->chains = NULL;
252b5132 13155
978c4450 13156 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13157 {
2cf0635d
NC
13158 unsigned long * lengths;
13159 unsigned long * counts;
fdc90cb4
JJ
13160 unsigned long hn;
13161 unsigned long maxlength = 0;
13162 unsigned long nzero_counts = 0;
13163 unsigned long nsyms = 0;
fdc90cb4 13164
f16a9783 13165 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13166 "(total of %lu bucket):\n",
f16a9783 13167 "\nHistogram for `%s' bucket list length "
d3a49aa8 13168 "(total of %lu buckets):\n",
978c4450
AM
13169 (unsigned long) filedata->ngnubuckets),
13170 GNU_HASH_SECTION_NAME (filedata),
13171 (unsigned long) filedata->ngnubuckets);
8b73c356 13172
978c4450
AM
13173 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13174 sizeof (*lengths));
fdc90cb4
JJ
13175 if (lengths == NULL)
13176 {
8b73c356 13177 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13178 goto err_out;
fdc90cb4
JJ
13179 }
13180
fdc90cb4
JJ
13181 printf (_(" Length Number %% of total Coverage\n"));
13182
978c4450
AM
13183 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13184 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13185 {
13186 bfd_vma off, length = 1;
13187
978c4450 13188 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13189 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13190 off < filedata->ngnuchains
13191 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13192 ++off)
fdc90cb4
JJ
13193 ++length;
13194 lengths[hn] = length;
13195 if (length > maxlength)
13196 maxlength = length;
13197 nsyms += length;
13198 }
13199
3f5e193b 13200 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13201 if (counts == NULL)
13202 {
b2e951ec 13203 free (lengths);
8b73c356 13204 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13205 goto err_out;
fdc90cb4
JJ
13206 }
13207
978c4450 13208 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13209 ++counts[lengths[hn]];
13210
978c4450 13211 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13212 {
13213 unsigned long j;
13214 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13215 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13216 for (j = 1; j <= maxlength; ++j)
13217 {
13218 nzero_counts += counts[j] * j;
13219 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13220 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13221 (nzero_counts * 100.0) / nsyms);
13222 }
13223 }
13224
13225 free (counts);
13226 free (lengths);
fdc90cb4 13227 }
978c4450
AM
13228 free (filedata->gnubuckets);
13229 filedata->gnubuckets = NULL;
13230 filedata->ngnubuckets = 0;
13231 free (filedata->gnuchains);
13232 filedata->gnuchains = NULL;
13233 filedata->ngnuchains = 0;
13234 free (filedata->mipsxlat);
13235 filedata->mipsxlat = NULL;
015dc7e1 13236 return true;
fd486f32
AM
13237
13238 err_out:
978c4450
AM
13239 free (filedata->gnubuckets);
13240 filedata->gnubuckets = NULL;
13241 filedata->ngnubuckets = 0;
13242 free (filedata->gnuchains);
13243 filedata->gnuchains = NULL;
13244 filedata->ngnuchains = 0;
13245 free (filedata->mipsxlat);
13246 filedata->mipsxlat = NULL;
13247 free (filedata->buckets);
13248 filedata->buckets = NULL;
13249 filedata->nbuckets = 0;
13250 free (filedata->chains);
13251 filedata->chains = NULL;
015dc7e1 13252 return false;
252b5132
RH
13253}
13254
015dc7e1 13255static bool
ca0e11aa 13256process_syminfo (Filedata * filedata)
252b5132 13257{
b4c96d0d 13258 unsigned int i;
252b5132 13259
978c4450 13260 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13261 || !do_dynamic)
13262 /* No syminfo, this is ok. */
015dc7e1 13263 return true;
252b5132
RH
13264
13265 /* There better should be a dynamic symbol section. */
978c4450 13266 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13267 return false;
252b5132 13268
ca0e11aa
NC
13269 if (filedata->is_separate)
13270 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13271 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13272 filedata->dynamic_syminfo_nent),
13273 filedata->file_name,
13274 filedata->dynamic_syminfo_offset,
13275 filedata->dynamic_syminfo_nent);
13276 else
d3a49aa8
AM
13277 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13278 "contains %d entry:\n",
13279 "\nDynamic info segment at offset 0x%lx "
13280 "contains %d entries:\n",
978c4450 13281 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13282 filedata->dynamic_syminfo_offset,
13283 filedata->dynamic_syminfo_nent);
252b5132
RH
13284
13285 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13286 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13287 {
978c4450 13288 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13289
31104126 13290 printf ("%4d: ", i);
978c4450 13291 if (i >= filedata->num_dynamic_syms)
4082ef84 13292 printf (_("<corrupt index>"));
978c4450
AM
13293 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13294 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13295 filedata->dynamic_symbols[i].st_name));
d79b3d50 13296 else
978c4450 13297 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13298 putchar (' ');
252b5132 13299
978c4450 13300 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13301 {
13302 case SYMINFO_BT_SELF:
13303 fputs ("SELF ", stdout);
13304 break;
13305 case SYMINFO_BT_PARENT:
13306 fputs ("PARENT ", stdout);
13307 break;
13308 default:
978c4450
AM
13309 if (filedata->dynamic_syminfo[i].si_boundto > 0
13310 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13311 && VALID_DYNAMIC_NAME (filedata,
13312 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13313 {
978c4450
AM
13314 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13315 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13316 putchar (' ' );
13317 }
252b5132 13318 else
978c4450 13319 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13320 break;
13321 }
13322
13323 if (flags & SYMINFO_FLG_DIRECT)
13324 printf (" DIRECT");
13325 if (flags & SYMINFO_FLG_PASSTHRU)
13326 printf (" PASSTHRU");
13327 if (flags & SYMINFO_FLG_COPY)
13328 printf (" COPY");
13329 if (flags & SYMINFO_FLG_LAZYLOAD)
13330 printf (" LAZYLOAD");
13331
13332 puts ("");
13333 }
13334
015dc7e1 13335 return true;
252b5132
RH
13336}
13337
75802ccb
CE
13338/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13339 is contained by the region START .. END. The types of ADDR, START
13340 and END should all be the same. Note both ADDR + NELEM and END
13341 point to just beyond the end of the regions that are being tested. */
13342#define IN_RANGE(START,END,ADDR,NELEM) \
13343 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13344
cf13d699
NC
13345/* Check to see if the given reloc needs to be handled in a target specific
13346 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13347 FALSE.
13348
13349 If called with reloc == NULL, then this is a signal that reloc processing
13350 for the current section has finished, and any saved state should be
13351 discarded. */
09c11c86 13352
015dc7e1 13353static bool
dda8d76d
NC
13354target_specific_reloc_handling (Filedata * filedata,
13355 Elf_Internal_Rela * reloc,
13356 unsigned char * start,
13357 unsigned char * end,
13358 Elf_Internal_Sym * symtab,
13359 unsigned long num_syms)
252b5132 13360{
f84ce13b
NC
13361 unsigned int reloc_type = 0;
13362 unsigned long sym_index = 0;
13363
13364 if (reloc)
13365 {
dda8d76d 13366 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13367 sym_index = get_reloc_symindex (reloc->r_info);
13368 }
252b5132 13369
dda8d76d 13370 switch (filedata->file_header.e_machine)
252b5132 13371 {
13761a11
NC
13372 case EM_MSP430:
13373 case EM_MSP430_OLD:
13374 {
13375 static Elf_Internal_Sym * saved_sym = NULL;
13376
f84ce13b
NC
13377 if (reloc == NULL)
13378 {
13379 saved_sym = NULL;
015dc7e1 13380 return true;
f84ce13b
NC
13381 }
13382
13761a11
NC
13383 switch (reloc_type)
13384 {
13385 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13386 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13387 if (uses_msp430x_relocs (filedata))
13761a11 13388 break;
1a0670f3 13389 /* Fall through. */
13761a11 13390 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13391 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13392 /* PR 21139. */
13393 if (sym_index >= num_syms)
13394 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13395 sym_index);
13396 else
13397 saved_sym = symtab + sym_index;
015dc7e1 13398 return true;
13761a11
NC
13399
13400 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13401 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13402 goto handle_sym_diff;
0b4362b0 13403
13761a11
NC
13404 case 5: /* R_MSP430_16_BYTE */
13405 case 9: /* R_MSP430_8 */
7d81bc93 13406 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13407 if (uses_msp430x_relocs (filedata))
13761a11
NC
13408 break;
13409 goto handle_sym_diff;
13410
13411 case 2: /* R_MSP430_ABS16 */
13412 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13413 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13414 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13415 break;
13416 goto handle_sym_diff;
0b4362b0 13417
13761a11
NC
13418 handle_sym_diff:
13419 if (saved_sym != NULL)
13420 {
13421 bfd_vma value;
5a805384 13422 unsigned int reloc_size = 0;
7d81bc93
JL
13423 int leb_ret = 0;
13424 switch (reloc_type)
13425 {
13426 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13427 reloc_size = 4;
13428 break;
13429 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13430 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13431 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13432 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13433 &reloc_size, &leb_ret);
7d81bc93
JL
13434 break;
13435 default:
13436 reloc_size = 2;
13437 break;
13438 }
13761a11 13439
5a805384 13440 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13441 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13442 "ULEB128 value\n"),
13443 (long) reloc->r_offset);
13444 else if (sym_index >= num_syms)
f84ce13b
NC
13445 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13446 sym_index);
03f7786e 13447 else
f84ce13b
NC
13448 {
13449 value = reloc->r_addend + (symtab[sym_index].st_value
13450 - saved_sym->st_value);
13451
b32e566b 13452 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13453 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13454 else
13455 /* PR 21137 */
13456 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13457 (long) reloc->r_offset);
f84ce13b 13458 }
13761a11
NC
13459
13460 saved_sym = NULL;
015dc7e1 13461 return true;
13761a11
NC
13462 }
13463 break;
13464
13465 default:
13466 if (saved_sym != NULL)
071436c6 13467 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13468 break;
13469 }
13470 break;
13471 }
13472
cf13d699
NC
13473 case EM_MN10300:
13474 case EM_CYGNUS_MN10300:
13475 {
13476 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13477
f84ce13b
NC
13478 if (reloc == NULL)
13479 {
13480 saved_sym = NULL;
015dc7e1 13481 return true;
f84ce13b
NC
13482 }
13483
cf13d699
NC
13484 switch (reloc_type)
13485 {
13486 case 34: /* R_MN10300_ALIGN */
015dc7e1 13487 return true;
cf13d699 13488 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13489 if (sym_index >= num_syms)
13490 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13491 sym_index);
13492 else
13493 saved_sym = symtab + sym_index;
015dc7e1 13494 return true;
f84ce13b 13495
cf13d699
NC
13496 case 1: /* R_MN10300_32 */
13497 case 2: /* R_MN10300_16 */
13498 if (saved_sym != NULL)
13499 {
03f7786e 13500 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13501 bfd_vma value;
252b5132 13502
f84ce13b
NC
13503 if (sym_index >= num_syms)
13504 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13505 sym_index);
03f7786e 13506 else
f84ce13b
NC
13507 {
13508 value = reloc->r_addend + (symtab[sym_index].st_value
13509 - saved_sym->st_value);
13510
b32e566b 13511 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13512 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13513 else
13514 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13515 (long) reloc->r_offset);
f84ce13b 13516 }
252b5132 13517
cf13d699 13518 saved_sym = NULL;
015dc7e1 13519 return true;
cf13d699
NC
13520 }
13521 break;
13522 default:
13523 if (saved_sym != NULL)
071436c6 13524 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13525 break;
13526 }
13527 break;
13528 }
6ff71e76
NC
13529
13530 case EM_RL78:
13531 {
13532 static bfd_vma saved_sym1 = 0;
13533 static bfd_vma saved_sym2 = 0;
13534 static bfd_vma value;
13535
f84ce13b
NC
13536 if (reloc == NULL)
13537 {
13538 saved_sym1 = saved_sym2 = 0;
015dc7e1 13539 return true;
f84ce13b
NC
13540 }
13541
6ff71e76
NC
13542 switch (reloc_type)
13543 {
13544 case 0x80: /* R_RL78_SYM. */
13545 saved_sym1 = saved_sym2;
f84ce13b
NC
13546 if (sym_index >= num_syms)
13547 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13548 sym_index);
13549 else
13550 {
13551 saved_sym2 = symtab[sym_index].st_value;
13552 saved_sym2 += reloc->r_addend;
13553 }
015dc7e1 13554 return true;
6ff71e76
NC
13555
13556 case 0x83: /* R_RL78_OPsub. */
13557 value = saved_sym1 - saved_sym2;
13558 saved_sym2 = saved_sym1 = 0;
015dc7e1 13559 return true;
6ff71e76
NC
13560 break;
13561
13562 case 0x41: /* R_RL78_ABS32. */
b32e566b 13563 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13564 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13565 else
13566 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13567 (long) reloc->r_offset);
6ff71e76 13568 value = 0;
015dc7e1 13569 return true;
6ff71e76
NC
13570
13571 case 0x43: /* R_RL78_ABS16. */
b32e566b 13572 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13573 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13574 else
13575 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13576 (long) reloc->r_offset);
6ff71e76 13577 value = 0;
015dc7e1 13578 return true;
6ff71e76
NC
13579
13580 default:
13581 break;
13582 }
13583 break;
13584 }
252b5132
RH
13585 }
13586
015dc7e1 13587 return false;
252b5132
RH
13588}
13589
aca88567
NC
13590/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13591 DWARF debug sections. This is a target specific test. Note - we do not
13592 go through the whole including-target-headers-multiple-times route, (as
13593 we have already done with <elf/h8.h>) because this would become very
13594 messy and even then this function would have to contain target specific
13595 information (the names of the relocs instead of their numeric values).
13596 FIXME: This is not the correct way to solve this problem. The proper way
13597 is to have target specific reloc sizing and typing functions created by
13598 the reloc-macros.h header, in the same way that it already creates the
13599 reloc naming functions. */
13600
015dc7e1 13601static bool
dda8d76d 13602is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13603{
d347c9df 13604 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13605 switch (filedata->file_header.e_machine)
aca88567 13606 {
41e92641 13607 case EM_386:
22abe556 13608 case EM_IAMCU:
41e92641 13609 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13610 case EM_68K:
13611 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13612 case EM_860:
13613 return reloc_type == 1; /* R_860_32. */
13614 case EM_960:
13615 return reloc_type == 2; /* R_960_32. */
a06ea964 13616 case EM_AARCH64:
9282b95a
JW
13617 return (reloc_type == 258
13618 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13619 case EM_BPF:
13620 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13621 case EM_ADAPTEVA_EPIPHANY:
13622 return reloc_type == 3;
aca88567 13623 case EM_ALPHA:
137b6b5f 13624 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13625 case EM_ARC:
13626 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13627 case EM_ARC_COMPACT:
13628 case EM_ARC_COMPACT2:
13629 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13630 case EM_ARM:
13631 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13632 case EM_AVR_OLD:
aca88567
NC
13633 case EM_AVR:
13634 return reloc_type == 1;
13635 case EM_BLACKFIN:
13636 return reloc_type == 0x12; /* R_byte4_data. */
13637 case EM_CRIS:
13638 return reloc_type == 3; /* R_CRIS_32. */
13639 case EM_CR16:
13640 return reloc_type == 3; /* R_CR16_NUM32. */
13641 case EM_CRX:
13642 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13643 case EM_CSKY:
13644 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13645 case EM_CYGNUS_FRV:
13646 return reloc_type == 1;
41e92641
NC
13647 case EM_CYGNUS_D10V:
13648 case EM_D10V:
13649 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13650 case EM_CYGNUS_D30V:
13651 case EM_D30V:
13652 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13653 case EM_DLX:
13654 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13655 case EM_CYGNUS_FR30:
13656 case EM_FR30:
13657 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13658 case EM_FT32:
13659 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13660 case EM_H8S:
13661 case EM_H8_300:
13662 case EM_H8_300H:
13663 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13664 case EM_IA_64:
262cdac7
AM
13665 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13666 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13667 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13668 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13669 case EM_IP2K_OLD:
13670 case EM_IP2K:
13671 return reloc_type == 2; /* R_IP2K_32. */
13672 case EM_IQ2000:
13673 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13674 case EM_LATTICEMICO32:
13675 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13676 case EM_M32C_OLD:
aca88567
NC
13677 case EM_M32C:
13678 return reloc_type == 3; /* R_M32C_32. */
13679 case EM_M32R:
13680 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13681 case EM_68HC11:
13682 case EM_68HC12:
13683 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13684 case EM_S12Z:
2849d19f
JD
13685 return reloc_type == 7 || /* R_S12Z_EXT32 */
13686 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13687 case EM_MCORE:
13688 return reloc_type == 1; /* R_MCORE_ADDR32. */
13689 case EM_CYGNUS_MEP:
13690 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13691 case EM_METAG:
13692 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13693 case EM_MICROBLAZE:
13694 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13695 case EM_MIPS:
13696 return reloc_type == 2; /* R_MIPS_32. */
13697 case EM_MMIX:
13698 return reloc_type == 4; /* R_MMIX_32. */
13699 case EM_CYGNUS_MN10200:
13700 case EM_MN10200:
13701 return reloc_type == 1; /* R_MN10200_32. */
13702 case EM_CYGNUS_MN10300:
13703 case EM_MN10300:
13704 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13705 case EM_MOXIE:
13706 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13707 case EM_MSP430_OLD:
13708 case EM_MSP430:
13761a11 13709 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13710 case EM_MT:
13711 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13712 case EM_NDS32:
13713 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13714 case EM_ALTERA_NIOS2:
36591ba1 13715 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13716 case EM_NIOS32:
13717 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13718 case EM_OR1K:
13719 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13720 case EM_PARISC:
9abca702 13721 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13722 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13723 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13724 case EM_PJ:
13725 case EM_PJ_OLD:
13726 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13727 case EM_PPC64:
13728 return reloc_type == 1; /* R_PPC64_ADDR32. */
13729 case EM_PPC:
13730 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13731 case EM_TI_PRU:
13732 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13733 case EM_RISCV:
13734 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13735 case EM_RL78:
13736 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13737 case EM_RX:
13738 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13739 case EM_S370:
13740 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13741 case EM_S390_OLD:
13742 case EM_S390:
13743 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13744 case EM_SCORE:
13745 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13746 case EM_SH:
13747 return reloc_type == 1; /* R_SH_DIR32. */
13748 case EM_SPARC32PLUS:
13749 case EM_SPARCV9:
13750 case EM_SPARC:
13751 return reloc_type == 3 /* R_SPARC_32. */
13752 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13753 case EM_SPU:
13754 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13755 case EM_TI_C6000:
13756 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13757 case EM_TILEGX:
13758 return reloc_type == 2; /* R_TILEGX_32. */
13759 case EM_TILEPRO:
13760 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13761 case EM_CYGNUS_V850:
13762 case EM_V850:
13763 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13764 case EM_V800:
13765 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13766 case EM_VAX:
13767 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13768 case EM_VISIUM:
13769 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13770 case EM_WEBASSEMBLY:
13771 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13772 case EM_X86_64:
8a9036a4 13773 case EM_L1OM:
7a9068fe 13774 case EM_K1OM:
aca88567 13775 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13776 case EM_XC16X:
13777 case EM_C166:
13778 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13779 case EM_XGATE:
13780 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13781 case EM_XSTORMY16:
13782 return reloc_type == 1; /* R_XSTROMY16_32. */
13783 case EM_XTENSA_OLD:
13784 case EM_XTENSA:
13785 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13786 case EM_Z80:
13787 return reloc_type == 6; /* R_Z80_32. */
aca88567 13788 default:
bee0ee85
NC
13789 {
13790 static unsigned int prev_warn = 0;
13791
13792 /* Avoid repeating the same warning multiple times. */
dda8d76d 13793 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13794 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13795 filedata->file_header.e_machine);
13796 prev_warn = filedata->file_header.e_machine;
015dc7e1 13797 return false;
bee0ee85 13798 }
aca88567
NC
13799 }
13800}
13801
13802/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13803 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13804
015dc7e1 13805static bool
dda8d76d 13806is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13807{
dda8d76d 13808 switch (filedata->file_header.e_machine)
d347c9df 13809 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13810 {
41e92641 13811 case EM_386:
22abe556 13812 case EM_IAMCU:
3e0873ac 13813 return reloc_type == 2; /* R_386_PC32. */
aca88567 13814 case EM_68K:
3e0873ac 13815 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13816 case EM_AARCH64:
13817 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13818 case EM_ADAPTEVA_EPIPHANY:
13819 return reloc_type == 6;
aca88567
NC
13820 case EM_ALPHA:
13821 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13822 case EM_ARC_COMPACT:
13823 case EM_ARC_COMPACT2:
13824 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13825 case EM_ARM:
3e0873ac 13826 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13827 case EM_AVR_OLD:
13828 case EM_AVR:
13829 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13830 case EM_MICROBLAZE:
13831 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13832 case EM_OR1K:
13833 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13834 case EM_PARISC:
85acf597 13835 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13836 case EM_PPC:
13837 return reloc_type == 26; /* R_PPC_REL32. */
13838 case EM_PPC64:
3e0873ac 13839 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13840 case EM_RISCV:
13841 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13842 case EM_S390_OLD:
13843 case EM_S390:
3e0873ac 13844 return reloc_type == 5; /* R_390_PC32. */
aca88567 13845 case EM_SH:
3e0873ac 13846 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13847 case EM_SPARC32PLUS:
13848 case EM_SPARCV9:
13849 case EM_SPARC:
3e0873ac 13850 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13851 case EM_SPU:
13852 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13853 case EM_TILEGX:
13854 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13855 case EM_TILEPRO:
13856 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13857 case EM_VISIUM:
13858 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13859 case EM_X86_64:
8a9036a4 13860 case EM_L1OM:
7a9068fe 13861 case EM_K1OM:
3e0873ac 13862 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13863 case EM_VAX:
13864 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13865 case EM_XTENSA_OLD:
13866 case EM_XTENSA:
13867 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13868 default:
13869 /* Do not abort or issue an error message here. Not all targets use
13870 pc-relative 32-bit relocs in their DWARF debug information and we
13871 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13872 more helpful warning message will be generated by apply_relocations
13873 anyway, so just return. */
015dc7e1 13874 return false;
aca88567
NC
13875 }
13876}
13877
13878/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13879 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13880
015dc7e1 13881static bool
dda8d76d 13882is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13883{
dda8d76d 13884 switch (filedata->file_header.e_machine)
aca88567 13885 {
a06ea964
NC
13886 case EM_AARCH64:
13887 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13888 case EM_ALPHA:
13889 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13890 case EM_IA_64:
262cdac7
AM
13891 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13892 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13893 case EM_PARISC:
13894 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13895 case EM_PPC64:
13896 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13897 case EM_RISCV:
13898 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13899 case EM_SPARC32PLUS:
13900 case EM_SPARCV9:
13901 case EM_SPARC:
714da62f
NC
13902 return reloc_type == 32 /* R_SPARC_64. */
13903 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13904 case EM_X86_64:
8a9036a4 13905 case EM_L1OM:
7a9068fe 13906 case EM_K1OM:
aca88567 13907 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13908 case EM_S390_OLD:
13909 case EM_S390:
aa137e4d
NC
13910 return reloc_type == 22; /* R_S390_64. */
13911 case EM_TILEGX:
13912 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13913 case EM_MIPS:
aa137e4d 13914 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13915 default:
015dc7e1 13916 return false;
aca88567
NC
13917 }
13918}
13919
85acf597
RH
13920/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13921 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13922
015dc7e1 13923static bool
dda8d76d 13924is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13925{
dda8d76d 13926 switch (filedata->file_header.e_machine)
85acf597 13927 {
a06ea964
NC
13928 case EM_AARCH64:
13929 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13930 case EM_ALPHA:
aa137e4d 13931 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13932 case EM_IA_64:
262cdac7
AM
13933 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13934 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13935 case EM_PARISC:
aa137e4d 13936 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13937 case EM_PPC64:
aa137e4d 13938 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13939 case EM_SPARC32PLUS:
13940 case EM_SPARCV9:
13941 case EM_SPARC:
aa137e4d 13942 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13943 case EM_X86_64:
8a9036a4 13944 case EM_L1OM:
7a9068fe 13945 case EM_K1OM:
aa137e4d 13946 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13947 case EM_S390_OLD:
13948 case EM_S390:
aa137e4d
NC
13949 return reloc_type == 23; /* R_S390_PC64. */
13950 case EM_TILEGX:
13951 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13952 default:
015dc7e1 13953 return false;
85acf597
RH
13954 }
13955}
13956
4dc3c23d
AM
13957/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13958 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13959
015dc7e1 13960static bool
dda8d76d 13961is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13962{
dda8d76d 13963 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13964 {
13965 case EM_CYGNUS_MN10200:
13966 case EM_MN10200:
13967 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13968 case EM_FT32:
13969 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13970 case EM_Z80:
13971 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13972 default:
015dc7e1 13973 return false;
4dc3c23d
AM
13974 }
13975}
13976
aca88567
NC
13977/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13978 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13979
015dc7e1 13980static bool
dda8d76d 13981is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13982{
d347c9df 13983 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13984 switch (filedata->file_header.e_machine)
4b78141a 13985 {
886a2506
NC
13986 case EM_ARC:
13987 case EM_ARC_COMPACT:
13988 case EM_ARC_COMPACT2:
13989 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13990 case EM_ADAPTEVA_EPIPHANY:
13991 return reloc_type == 5;
aca88567
NC
13992 case EM_AVR_OLD:
13993 case EM_AVR:
13994 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13995 case EM_CYGNUS_D10V:
13996 case EM_D10V:
13997 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13998 case EM_FT32:
13999 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14000 case EM_H8S:
14001 case EM_H8_300:
14002 case EM_H8_300H:
aca88567
NC
14003 return reloc_type == R_H8_DIR16;
14004 case EM_IP2K_OLD:
14005 case EM_IP2K:
14006 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14007 case EM_M32C_OLD:
f4236fe4
DD
14008 case EM_M32C:
14009 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14010 case EM_CYGNUS_MN10200:
14011 case EM_MN10200:
14012 return reloc_type == 2; /* R_MN10200_16. */
14013 case EM_CYGNUS_MN10300:
14014 case EM_MN10300:
14015 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14016 case EM_MSP430:
dda8d76d 14017 if (uses_msp430x_relocs (filedata))
13761a11 14018 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14019 /* Fall through. */
78c8d46c 14020 case EM_MSP430_OLD:
aca88567 14021 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14022 case EM_NDS32:
14023 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14024 case EM_ALTERA_NIOS2:
36591ba1 14025 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14026 case EM_NIOS32:
14027 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14028 case EM_OR1K:
14029 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14030 case EM_RISCV:
14031 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14032 case EM_TI_PRU:
14033 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14034 case EM_TI_C6000:
14035 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14036 case EM_VISIUM:
14037 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14038 case EM_XC16X:
14039 case EM_C166:
14040 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14041 case EM_XGATE:
14042 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14043 case EM_Z80:
14044 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14045 default:
015dc7e1 14046 return false;
4b78141a
NC
14047 }
14048}
14049
39e07931
AS
14050/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14051 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14052
015dc7e1 14053static bool
39e07931
AS
14054is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14055{
14056 switch (filedata->file_header.e_machine)
14057 {
14058 case EM_RISCV:
14059 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14060 case EM_Z80:
14061 return reloc_type == 1; /* R_Z80_8. */
39e07931 14062 default:
015dc7e1 14063 return false;
39e07931
AS
14064 }
14065}
14066
14067/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14068 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14069
015dc7e1 14070static bool
39e07931
AS
14071is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14072{
14073 switch (filedata->file_header.e_machine)
14074 {
14075 case EM_RISCV:
14076 return reloc_type == 53; /* R_RISCV_SET6. */
14077 default:
015dc7e1 14078 return false;
39e07931
AS
14079 }
14080}
14081
03336641
JW
14082/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14083 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14084
015dc7e1 14085static bool
03336641
JW
14086is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14087{
14088 /* Please keep this table alpha-sorted for ease of visual lookup. */
14089 switch (filedata->file_header.e_machine)
14090 {
14091 case EM_RISCV:
14092 return reloc_type == 35; /* R_RISCV_ADD32. */
14093 default:
015dc7e1 14094 return false;
03336641
JW
14095 }
14096}
14097
14098/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14099 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14100
015dc7e1 14101static bool
03336641
JW
14102is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14103{
14104 /* Please keep this table alpha-sorted for ease of visual lookup. */
14105 switch (filedata->file_header.e_machine)
14106 {
14107 case EM_RISCV:
14108 return reloc_type == 39; /* R_RISCV_SUB32. */
14109 default:
015dc7e1 14110 return false;
03336641
JW
14111 }
14112}
14113
14114/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14115 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14116
015dc7e1 14117static bool
03336641
JW
14118is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14119{
14120 /* Please keep this table alpha-sorted for ease of visual lookup. */
14121 switch (filedata->file_header.e_machine)
14122 {
14123 case EM_RISCV:
14124 return reloc_type == 36; /* R_RISCV_ADD64. */
14125 default:
015dc7e1 14126 return false;
03336641
JW
14127 }
14128}
14129
14130/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14131 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14132
015dc7e1 14133static bool
03336641
JW
14134is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14135{
14136 /* Please keep this table alpha-sorted for ease of visual lookup. */
14137 switch (filedata->file_header.e_machine)
14138 {
14139 case EM_RISCV:
14140 return reloc_type == 40; /* R_RISCV_SUB64. */
14141 default:
015dc7e1 14142 return false;
03336641
JW
14143 }
14144}
14145
14146/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14147 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14148
015dc7e1 14149static bool
03336641
JW
14150is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14151{
14152 /* Please keep this table alpha-sorted for ease of visual lookup. */
14153 switch (filedata->file_header.e_machine)
14154 {
14155 case EM_RISCV:
14156 return reloc_type == 34; /* R_RISCV_ADD16. */
14157 default:
015dc7e1 14158 return false;
03336641
JW
14159 }
14160}
14161
14162/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14163 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14164
015dc7e1 14165static bool
03336641
JW
14166is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14167{
14168 /* Please keep this table alpha-sorted for ease of visual lookup. */
14169 switch (filedata->file_header.e_machine)
14170 {
14171 case EM_RISCV:
14172 return reloc_type == 38; /* R_RISCV_SUB16. */
14173 default:
015dc7e1 14174 return false;
03336641
JW
14175 }
14176}
14177
14178/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14179 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14180
015dc7e1 14181static bool
03336641
JW
14182is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14183{
14184 /* Please keep this table alpha-sorted for ease of visual lookup. */
14185 switch (filedata->file_header.e_machine)
14186 {
14187 case EM_RISCV:
14188 return reloc_type == 33; /* R_RISCV_ADD8. */
14189 default:
015dc7e1 14190 return false;
03336641
JW
14191 }
14192}
14193
14194/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14195 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14196
015dc7e1 14197static bool
03336641
JW
14198is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14199{
14200 /* Please keep this table alpha-sorted for ease of visual lookup. */
14201 switch (filedata->file_header.e_machine)
14202 {
14203 case EM_RISCV:
14204 return reloc_type == 37; /* R_RISCV_SUB8. */
14205 default:
015dc7e1 14206 return false;
03336641
JW
14207 }
14208}
14209
39e07931
AS
14210/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14211 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14212
015dc7e1 14213static bool
39e07931
AS
14214is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14215{
14216 switch (filedata->file_header.e_machine)
14217 {
14218 case EM_RISCV:
14219 return reloc_type == 52; /* R_RISCV_SUB6. */
14220 default:
015dc7e1 14221 return false;
39e07931
AS
14222 }
14223}
14224
2a7b2e88
JK
14225/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14226 relocation entries (possibly formerly used for SHT_GROUP sections). */
14227
015dc7e1 14228static bool
dda8d76d 14229is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14230{
dda8d76d 14231 switch (filedata->file_header.e_machine)
2a7b2e88 14232 {
cb8f3167 14233 case EM_386: /* R_386_NONE. */
d347c9df 14234 case EM_68K: /* R_68K_NONE. */
cfb8c092 14235 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14236 case EM_ALPHA: /* R_ALPHA_NONE. */
14237 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14238 case EM_ARC: /* R_ARC_NONE. */
886a2506 14239 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14240 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14241 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14242 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14243 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14244 case EM_FT32: /* R_FT32_NONE. */
14245 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14246 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14247 case EM_L1OM: /* R_X86_64_NONE. */
14248 case EM_M32R: /* R_M32R_NONE. */
14249 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14250 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14251 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14252 case EM_NIOS32: /* R_NIOS_NONE. */
14253 case EM_OR1K: /* R_OR1K_NONE. */
14254 case EM_PARISC: /* R_PARISC_NONE. */
14255 case EM_PPC64: /* R_PPC64_NONE. */
14256 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14257 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14258 case EM_S390: /* R_390_NONE. */
14259 case EM_S390_OLD:
14260 case EM_SH: /* R_SH_NONE. */
14261 case EM_SPARC32PLUS:
14262 case EM_SPARC: /* R_SPARC_NONE. */
14263 case EM_SPARCV9:
aa137e4d
NC
14264 case EM_TILEGX: /* R_TILEGX_NONE. */
14265 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14266 case EM_TI_C6000:/* R_C6000_NONE. */
14267 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14268 case EM_XC16X:
6655dba2 14269 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14270 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14271 return reloc_type == 0;
d347c9df 14272
a06ea964
NC
14273 case EM_AARCH64:
14274 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14275 case EM_AVR_OLD:
14276 case EM_AVR:
14277 return (reloc_type == 0 /* R_AVR_NONE. */
14278 || reloc_type == 30 /* R_AVR_DIFF8. */
14279 || reloc_type == 31 /* R_AVR_DIFF16. */
14280 || reloc_type == 32 /* R_AVR_DIFF32. */);
14281 case EM_METAG:
14282 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14283 case EM_NDS32:
14284 return (reloc_type == 0 /* R_XTENSA_NONE. */
14285 || reloc_type == 204 /* R_NDS32_DIFF8. */
14286 || reloc_type == 205 /* R_NDS32_DIFF16. */
14287 || reloc_type == 206 /* R_NDS32_DIFF32. */
14288 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14289 case EM_TI_PRU:
14290 return (reloc_type == 0 /* R_PRU_NONE. */
14291 || reloc_type == 65 /* R_PRU_DIFF8. */
14292 || reloc_type == 66 /* R_PRU_DIFF16. */
14293 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14294 case EM_XTENSA_OLD:
14295 case EM_XTENSA:
4dc3c23d
AM
14296 return (reloc_type == 0 /* R_XTENSA_NONE. */
14297 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14298 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14299 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14300 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14301 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14302 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14303 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14304 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14305 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14306 }
015dc7e1 14307 return false;
2a7b2e88
JK
14308}
14309
d1c4b12b
NC
14310/* Returns TRUE if there is a relocation against
14311 section NAME at OFFSET bytes. */
14312
015dc7e1 14313bool
d1c4b12b
NC
14314reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14315{
14316 Elf_Internal_Rela * relocs;
14317 Elf_Internal_Rela * rp;
14318
14319 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14320 return false;
d1c4b12b
NC
14321
14322 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14323
14324 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14325 if (rp->r_offset == offset)
015dc7e1 14326 return true;
d1c4b12b 14327
015dc7e1 14328 return false;
d1c4b12b
NC
14329}
14330
cf13d699 14331/* Apply relocations to a section.
32ec8896
NC
14332 Returns TRUE upon success, FALSE otherwise.
14333 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14334 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14335 will be set to the number of relocs loaded.
14336
cf13d699 14337 Note: So far support has been added only for those relocations
32ec8896
NC
14338 which can be found in debug sections. FIXME: Add support for
14339 more relocations ? */
1b315056 14340
015dc7e1 14341static bool
dda8d76d 14342apply_relocations (Filedata * filedata,
d1c4b12b
NC
14343 const Elf_Internal_Shdr * section,
14344 unsigned char * start,
14345 bfd_size_type size,
1449284b 14346 void ** relocs_return,
d1c4b12b 14347 unsigned long * num_relocs_return)
1b315056 14348{
cf13d699 14349 Elf_Internal_Shdr * relsec;
0d2a7a93 14350 unsigned char * end = start + size;
cb8f3167 14351
d1c4b12b
NC
14352 if (relocs_return != NULL)
14353 {
14354 * (Elf_Internal_Rela **) relocs_return = NULL;
14355 * num_relocs_return = 0;
14356 }
14357
dda8d76d 14358 if (filedata->file_header.e_type != ET_REL)
32ec8896 14359 /* No relocs to apply. */
015dc7e1 14360 return true;
1b315056 14361
cf13d699 14362 /* Find the reloc section associated with the section. */
dda8d76d
NC
14363 for (relsec = filedata->section_headers;
14364 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14365 ++relsec)
252b5132 14366 {
015dc7e1 14367 bool is_rela;
41e92641 14368 unsigned long num_relocs;
2cf0635d
NC
14369 Elf_Internal_Rela * relocs;
14370 Elf_Internal_Rela * rp;
14371 Elf_Internal_Shdr * symsec;
14372 Elf_Internal_Sym * symtab;
ba5cdace 14373 unsigned long num_syms;
2cf0635d 14374 Elf_Internal_Sym * sym;
252b5132 14375
41e92641 14376 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14377 || relsec->sh_info >= filedata->file_header.e_shnum
14378 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14379 || relsec->sh_size == 0
dda8d76d 14380 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14381 continue;
428409d5 14382
a788aedd
AM
14383 symsec = filedata->section_headers + relsec->sh_link;
14384 if (symsec->sh_type != SHT_SYMTAB
14385 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14386 return false;
a788aedd 14387
41e92641
NC
14388 is_rela = relsec->sh_type == SHT_RELA;
14389
14390 if (is_rela)
14391 {
dda8d76d 14392 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14393 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14394 return false;
41e92641
NC
14395 }
14396 else
14397 {
dda8d76d 14398 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14399 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14400 return false;
41e92641
NC
14401 }
14402
14403 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14404 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14405 is_rela = false;
428409d5 14406
4de91c10 14407 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14408
41e92641 14409 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14410 {
015dc7e1
AM
14411 bfd_vma addend;
14412 unsigned int reloc_type;
14413 unsigned int reloc_size;
14414 bool reloc_inplace = false;
14415 bool reloc_subtract = false;
14416 unsigned char *rloc;
14417 unsigned long sym_index;
4b78141a 14418
dda8d76d 14419 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14420
dda8d76d 14421 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14422 continue;
dda8d76d 14423 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14424 continue;
dda8d76d
NC
14425 else if (is_32bit_abs_reloc (filedata, reloc_type)
14426 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14427 reloc_size = 4;
dda8d76d
NC
14428 else if (is_64bit_abs_reloc (filedata, reloc_type)
14429 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14430 reloc_size = 8;
dda8d76d 14431 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14432 reloc_size = 3;
dda8d76d 14433 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14434 reloc_size = 2;
39e07931
AS
14435 else if (is_8bit_abs_reloc (filedata, reloc_type)
14436 || is_6bit_abs_reloc (filedata, reloc_type))
14437 reloc_size = 1;
03336641
JW
14438 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14439 reloc_type))
14440 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14441 {
14442 reloc_size = 4;
015dc7e1 14443 reloc_inplace = true;
03336641
JW
14444 }
14445 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14446 reloc_type))
14447 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14448 {
14449 reloc_size = 8;
015dc7e1 14450 reloc_inplace = true;
03336641
JW
14451 }
14452 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14453 reloc_type))
14454 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14455 {
14456 reloc_size = 2;
015dc7e1 14457 reloc_inplace = true;
03336641
JW
14458 }
14459 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14460 reloc_type))
14461 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14462 {
14463 reloc_size = 1;
015dc7e1 14464 reloc_inplace = true;
03336641 14465 }
39e07931
AS
14466 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14467 reloc_type)))
14468 {
14469 reloc_size = 1;
015dc7e1 14470 reloc_inplace = true;
39e07931 14471 }
aca88567 14472 else
4b78141a 14473 {
bee0ee85 14474 static unsigned int prev_reloc = 0;
dda8d76d 14475
bee0ee85
NC
14476 if (reloc_type != prev_reloc)
14477 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14478 reloc_type, printable_section_name (filedata, section));
bee0ee85 14479 prev_reloc = reloc_type;
4b78141a
NC
14480 continue;
14481 }
103f02d3 14482
91d6fa6a 14483 rloc = start + rp->r_offset;
75802ccb 14484 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14485 {
14486 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14487 (unsigned long) rp->r_offset,
dda8d76d 14488 printable_section_name (filedata, section));
700dd8b7
L
14489 continue;
14490 }
103f02d3 14491
ba5cdace
NC
14492 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14493 if (sym_index >= num_syms)
14494 {
14495 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14496 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14497 continue;
14498 }
14499 sym = symtab + sym_index;
41e92641
NC
14500
14501 /* If the reloc has a symbol associated with it,
55f25fc3
L
14502 make sure that it is of an appropriate type.
14503
14504 Relocations against symbols without type can happen.
14505 Gcc -feliminate-dwarf2-dups may generate symbols
14506 without type for debug info.
14507
14508 Icc generates relocations against function symbols
14509 instead of local labels.
14510
14511 Relocations against object symbols can happen, eg when
14512 referencing a global array. For an example of this see
14513 the _clz.o binary in libgcc.a. */
aca88567 14514 if (sym != symtab
b8871f35 14515 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14516 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14517 {
d3a49aa8 14518 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14519 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14520 printable_section_name (filedata, relsec),
d3a49aa8 14521 (long int)(rp - relocs));
aca88567 14522 continue;
5b18a4bc 14523 }
252b5132 14524
4dc3c23d
AM
14525 addend = 0;
14526 if (is_rela)
14527 addend += rp->r_addend;
c47320c3
AM
14528 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14529 partial_inplace. */
4dc3c23d 14530 if (!is_rela
dda8d76d 14531 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14532 && reloc_type == 1)
dda8d76d
NC
14533 || ((filedata->file_header.e_machine == EM_PJ
14534 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14535 && reloc_type == 1)
dda8d76d
NC
14536 || ((filedata->file_header.e_machine == EM_D30V
14537 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14538 && reloc_type == 12)
14539 || reloc_inplace)
39e07931
AS
14540 {
14541 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14542 addend += byte_get (rloc, reloc_size) & 0x3f;
14543 else
14544 addend += byte_get (rloc, reloc_size);
14545 }
cb8f3167 14546
dda8d76d
NC
14547 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14548 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14549 {
14550 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14551 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14552 addend -= 8;
91d6fa6a 14553 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14554 reloc_size);
14555 }
39e07931
AS
14556 else if (is_6bit_abs_reloc (filedata, reloc_type)
14557 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14558 {
14559 if (reloc_subtract)
14560 addend -= sym->st_value;
14561 else
14562 addend += sym->st_value;
14563 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14564 byte_put (rloc, addend, reloc_size);
14565 }
03336641
JW
14566 else if (reloc_subtract)
14567 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14568 else
91d6fa6a 14569 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14570 }
252b5132 14571
5b18a4bc 14572 free (symtab);
f84ce13b
NC
14573 /* Let the target specific reloc processing code know that
14574 we have finished with these relocs. */
dda8d76d 14575 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14576
14577 if (relocs_return)
14578 {
14579 * (Elf_Internal_Rela **) relocs_return = relocs;
14580 * num_relocs_return = num_relocs;
14581 }
14582 else
14583 free (relocs);
14584
5b18a4bc
NC
14585 break;
14586 }
32ec8896 14587
015dc7e1 14588 return true;
5b18a4bc 14589}
103f02d3 14590
cf13d699 14591#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14592static bool
dda8d76d 14593disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14594{
dda8d76d 14595 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14596
74e1a04b 14597 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14598
015dc7e1 14599 return true;
cf13d699
NC
14600}
14601#endif
14602
14603/* Reads in the contents of SECTION from FILE, returning a pointer
14604 to a malloc'ed buffer or NULL if something went wrong. */
14605
14606static char *
dda8d76d 14607get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14608{
dda8d76d 14609 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14610
14611 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14612 {
c6b78c96 14613 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14614 printable_section_name (filedata, section));
cf13d699
NC
14615 return NULL;
14616 }
14617
dda8d76d 14618 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14619 _("section contents"));
cf13d699
NC
14620}
14621
0e602686
NC
14622/* Uncompresses a section that was compressed using zlib, in place. */
14623
015dc7e1 14624static bool
dda8d76d
NC
14625uncompress_section_contents (unsigned char ** buffer,
14626 dwarf_size_type uncompressed_size,
14627 dwarf_size_type * size)
0e602686
NC
14628{
14629 dwarf_size_type compressed_size = *size;
14630 unsigned char * compressed_buffer = *buffer;
14631 unsigned char * uncompressed_buffer;
14632 z_stream strm;
14633 int rc;
14634
14635 /* It is possible the section consists of several compressed
14636 buffers concatenated together, so we uncompress in a loop. */
14637 /* PR 18313: The state field in the z_stream structure is supposed
14638 to be invisible to the user (ie us), but some compilers will
14639 still complain about it being used without initialisation. So
14640 we first zero the entire z_stream structure and then set the fields
14641 that we need. */
14642 memset (& strm, 0, sizeof strm);
14643 strm.avail_in = compressed_size;
14644 strm.next_in = (Bytef *) compressed_buffer;
14645 strm.avail_out = uncompressed_size;
14646 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14647
14648 rc = inflateInit (& strm);
14649 while (strm.avail_in > 0)
14650 {
14651 if (rc != Z_OK)
3624a6c1 14652 break;
0e602686
NC
14653 strm.next_out = ((Bytef *) uncompressed_buffer
14654 + (uncompressed_size - strm.avail_out));
14655 rc = inflate (&strm, Z_FINISH);
14656 if (rc != Z_STREAM_END)
3624a6c1 14657 break;
0e602686
NC
14658 rc = inflateReset (& strm);
14659 }
ad92f33d
AM
14660 if (inflateEnd (& strm) != Z_OK
14661 || rc != Z_OK
0e602686
NC
14662 || strm.avail_out != 0)
14663 goto fail;
14664
14665 *buffer = uncompressed_buffer;
14666 *size = uncompressed_size;
015dc7e1 14667 return true;
0e602686
NC
14668
14669 fail:
14670 free (uncompressed_buffer);
14671 /* Indicate decompression failure. */
14672 *buffer = NULL;
015dc7e1 14673 return false;
0e602686 14674}
dd24e3da 14675
015dc7e1 14676static bool
dda8d76d 14677dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14678{
015dc7e1
AM
14679 Elf_Internal_Shdr *relsec;
14680 bfd_size_type num_bytes;
14681 unsigned char *data;
14682 unsigned char *end;
14683 unsigned char *real_start;
14684 unsigned char *start;
14685 bool some_strings_shown;
cf13d699 14686
dda8d76d 14687 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14688 if (start == NULL)
c6b78c96 14689 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14690 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14691
0e602686 14692 num_bytes = section->sh_size;
cf13d699 14693
835f2fae
NC
14694 if (filedata->is_separate)
14695 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14696 printable_section_name (filedata, section),
14697 filedata->file_name);
14698 else
14699 printf (_("\nString dump of section '%s':\n"),
14700 printable_section_name (filedata, section));
cf13d699 14701
0e602686
NC
14702 if (decompress_dumps)
14703 {
14704 dwarf_size_type new_size = num_bytes;
14705 dwarf_size_type uncompressed_size = 0;
14706
14707 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14708 {
14709 Elf_Internal_Chdr chdr;
14710 unsigned int compression_header_size
ebdf1ebf
NC
14711 = get_compression_header (& chdr, (unsigned char *) start,
14712 num_bytes);
5844b465
NC
14713 if (compression_header_size == 0)
14714 /* An error message will have already been generated
14715 by get_compression_header. */
14716 goto error_out;
0e602686 14717
813dabb9 14718 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14719 {
813dabb9 14720 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14721 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14722 goto error_out;
813dabb9 14723 }
813dabb9
L
14724 uncompressed_size = chdr.ch_size;
14725 start += compression_header_size;
14726 new_size -= compression_header_size;
0e602686
NC
14727 }
14728 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14729 {
14730 /* Read the zlib header. In this case, it should be "ZLIB"
14731 followed by the uncompressed section size, 8 bytes in
14732 big-endian order. */
14733 uncompressed_size = start[4]; uncompressed_size <<= 8;
14734 uncompressed_size += start[5]; uncompressed_size <<= 8;
14735 uncompressed_size += start[6]; uncompressed_size <<= 8;
14736 uncompressed_size += start[7]; uncompressed_size <<= 8;
14737 uncompressed_size += start[8]; uncompressed_size <<= 8;
14738 uncompressed_size += start[9]; uncompressed_size <<= 8;
14739 uncompressed_size += start[10]; uncompressed_size <<= 8;
14740 uncompressed_size += start[11];
14741 start += 12;
14742 new_size -= 12;
14743 }
14744
1835f746
NC
14745 if (uncompressed_size)
14746 {
14747 if (uncompress_section_contents (& start,
14748 uncompressed_size, & new_size))
14749 num_bytes = new_size;
14750 else
14751 {
14752 error (_("Unable to decompress section %s\n"),
dda8d76d 14753 printable_section_name (filedata, section));
f761cb13 14754 goto error_out;
1835f746
NC
14755 }
14756 }
bc303e5d
NC
14757 else
14758 start = real_start;
0e602686 14759 }
fd8008d8 14760
cf13d699
NC
14761 /* If the section being dumped has relocations against it the user might
14762 be expecting these relocations to have been applied. Check for this
14763 case and issue a warning message in order to avoid confusion.
14764 FIXME: Maybe we ought to have an option that dumps a section with
14765 relocs applied ? */
dda8d76d
NC
14766 for (relsec = filedata->section_headers;
14767 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14768 ++relsec)
14769 {
14770 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14771 || relsec->sh_info >= filedata->file_header.e_shnum
14772 || filedata->section_headers + relsec->sh_info != section
cf13d699 14773 || relsec->sh_size == 0
dda8d76d 14774 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14775 continue;
14776
14777 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14778 break;
14779 }
14780
cf13d699
NC
14781 data = start;
14782 end = start + num_bytes;
015dc7e1 14783 some_strings_shown = false;
cf13d699 14784
ba3265d0
NC
14785#ifdef HAVE_MBSTATE_T
14786 mbstate_t state;
14787 /* Initialise the multibyte conversion state. */
14788 memset (& state, 0, sizeof (state));
14789#endif
14790
015dc7e1 14791 bool continuing = false;
ba3265d0 14792
cf13d699
NC
14793 while (data < end)
14794 {
14795 while (!ISPRINT (* data))
14796 if (++ data >= end)
14797 break;
14798
14799 if (data < end)
14800 {
071436c6
NC
14801 size_t maxlen = end - data;
14802
ba3265d0
NC
14803 if (continuing)
14804 {
14805 printf (" ");
015dc7e1 14806 continuing = false;
ba3265d0
NC
14807 }
14808 else
14809 {
d1ce973e 14810 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14811 }
14812
4082ef84
NC
14813 if (maxlen > 0)
14814 {
f3da8a96 14815 char c = 0;
ba3265d0
NC
14816
14817 while (maxlen)
14818 {
14819 c = *data++;
14820
14821 if (c == 0)
14822 break;
14823
14824 /* PR 25543: Treat new-lines as string-ending characters. */
14825 if (c == '\n')
14826 {
14827 printf ("\\n\n");
14828 if (*data != 0)
015dc7e1 14829 continuing = true;
ba3265d0
NC
14830 break;
14831 }
14832
14833 /* Do not print control characters directly as they can affect terminal
14834 settings. Such characters usually appear in the names generated
14835 by the assembler for local labels. */
14836 if (ISCNTRL (c))
14837 {
14838 printf ("^%c", c + 0x40);
14839 }
14840 else if (ISPRINT (c))
14841 {
14842 putchar (c);
14843 }
14844 else
14845 {
14846 size_t n;
14847#ifdef HAVE_MBSTATE_T
14848 wchar_t w;
14849#endif
14850 /* Let printf do the hard work of displaying multibyte characters. */
14851 printf ("%.1s", data - 1);
14852#ifdef HAVE_MBSTATE_T
14853 /* Try to find out how many bytes made up the character that was
14854 just printed. Advance the symbol pointer past the bytes that
14855 were displayed. */
14856 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14857#else
14858 n = 1;
14859#endif
14860 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14861 data += (n - 1);
14862 }
14863 }
14864
14865 if (c != '\n')
14866 putchar ('\n');
4082ef84
NC
14867 }
14868 else
14869 {
14870 printf (_("<corrupt>\n"));
14871 data = end;
14872 }
015dc7e1 14873 some_strings_shown = true;
cf13d699
NC
14874 }
14875 }
14876
14877 if (! some_strings_shown)
14878 printf (_(" No strings found in this section."));
14879
0e602686 14880 free (real_start);
cf13d699
NC
14881
14882 putchar ('\n');
015dc7e1 14883 return true;
f761cb13
AM
14884
14885error_out:
14886 free (real_start);
015dc7e1 14887 return false;
cf13d699
NC
14888}
14889
015dc7e1
AM
14890static bool
14891dump_section_as_bytes (Elf_Internal_Shdr *section,
14892 Filedata *filedata,
14893 bool relocate)
cf13d699
NC
14894{
14895 Elf_Internal_Shdr * relsec;
0e602686
NC
14896 bfd_size_type bytes;
14897 bfd_size_type section_size;
14898 bfd_vma addr;
14899 unsigned char * data;
14900 unsigned char * real_start;
14901 unsigned char * start;
14902
dda8d76d 14903 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14904 if (start == NULL)
c6b78c96 14905 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14906 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14907
0e602686 14908 section_size = section->sh_size;
cf13d699 14909
835f2fae
NC
14910 if (filedata->is_separate)
14911 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14912 printable_section_name (filedata, section),
14913 filedata->file_name);
14914 else
14915 printf (_("\nHex dump of section '%s':\n"),
14916 printable_section_name (filedata, section));
cf13d699 14917
0e602686
NC
14918 if (decompress_dumps)
14919 {
14920 dwarf_size_type new_size = section_size;
14921 dwarf_size_type uncompressed_size = 0;
14922
14923 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14924 {
14925 Elf_Internal_Chdr chdr;
14926 unsigned int compression_header_size
ebdf1ebf 14927 = get_compression_header (& chdr, start, section_size);
0e602686 14928
5844b465
NC
14929 if (compression_header_size == 0)
14930 /* An error message will have already been generated
14931 by get_compression_header. */
14932 goto error_out;
14933
813dabb9 14934 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14935 {
813dabb9 14936 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14937 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14938 goto error_out;
0e602686 14939 }
813dabb9
L
14940 uncompressed_size = chdr.ch_size;
14941 start += compression_header_size;
14942 new_size -= compression_header_size;
0e602686
NC
14943 }
14944 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14945 {
14946 /* Read the zlib header. In this case, it should be "ZLIB"
14947 followed by the uncompressed section size, 8 bytes in
14948 big-endian order. */
14949 uncompressed_size = start[4]; uncompressed_size <<= 8;
14950 uncompressed_size += start[5]; uncompressed_size <<= 8;
14951 uncompressed_size += start[6]; uncompressed_size <<= 8;
14952 uncompressed_size += start[7]; uncompressed_size <<= 8;
14953 uncompressed_size += start[8]; uncompressed_size <<= 8;
14954 uncompressed_size += start[9]; uncompressed_size <<= 8;
14955 uncompressed_size += start[10]; uncompressed_size <<= 8;
14956 uncompressed_size += start[11];
14957 start += 12;
14958 new_size -= 12;
14959 }
14960
f055032e
NC
14961 if (uncompressed_size)
14962 {
14963 if (uncompress_section_contents (& start, uncompressed_size,
14964 & new_size))
bc303e5d
NC
14965 {
14966 section_size = new_size;
14967 }
f055032e
NC
14968 else
14969 {
14970 error (_("Unable to decompress section %s\n"),
dda8d76d 14971 printable_section_name (filedata, section));
bc303e5d 14972 /* FIXME: Print the section anyway ? */
f761cb13 14973 goto error_out;
f055032e
NC
14974 }
14975 }
bc303e5d
NC
14976 else
14977 start = real_start;
0e602686 14978 }
14ae95f2 14979
cf13d699
NC
14980 if (relocate)
14981 {
dda8d76d 14982 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14983 goto error_out;
cf13d699
NC
14984 }
14985 else
14986 {
14987 /* If the section being dumped has relocations against it the user might
14988 be expecting these relocations to have been applied. Check for this
14989 case and issue a warning message in order to avoid confusion.
14990 FIXME: Maybe we ought to have an option that dumps a section with
14991 relocs applied ? */
dda8d76d
NC
14992 for (relsec = filedata->section_headers;
14993 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14994 ++relsec)
14995 {
14996 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14997 || relsec->sh_info >= filedata->file_header.e_shnum
14998 || filedata->section_headers + relsec->sh_info != section
cf13d699 14999 || relsec->sh_size == 0
dda8d76d 15000 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15001 continue;
15002
15003 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15004 break;
15005 }
15006 }
15007
15008 addr = section->sh_addr;
0e602686 15009 bytes = section_size;
cf13d699
NC
15010 data = start;
15011
15012 while (bytes)
15013 {
15014 int j;
15015 int k;
15016 int lbytes;
15017
15018 lbytes = (bytes > 16 ? 16 : bytes);
15019
15020 printf (" 0x%8.8lx ", (unsigned long) addr);
15021
15022 for (j = 0; j < 16; j++)
15023 {
15024 if (j < lbytes)
15025 printf ("%2.2x", data[j]);
15026 else
15027 printf (" ");
15028
15029 if ((j & 3) == 3)
15030 printf (" ");
15031 }
15032
15033 for (j = 0; j < lbytes; j++)
15034 {
15035 k = data[j];
15036 if (k >= ' ' && k < 0x7f)
15037 printf ("%c", k);
15038 else
15039 printf (".");
15040 }
15041
15042 putchar ('\n');
15043
15044 data += lbytes;
15045 addr += lbytes;
15046 bytes -= lbytes;
15047 }
15048
0e602686 15049 free (real_start);
cf13d699
NC
15050
15051 putchar ('\n');
015dc7e1 15052 return true;
f761cb13
AM
15053
15054 error_out:
15055 free (real_start);
015dc7e1 15056 return false;
cf13d699
NC
15057}
15058
094e34f2 15059#ifdef ENABLE_LIBCTF
7d9813f1
NA
15060static ctf_sect_t *
15061shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15062{
b9e920ec 15063 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
15064 buf->cts_size = shdr->sh_size;
15065 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15066
15067 return buf;
15068}
15069
15070/* Formatting callback function passed to ctf_dump. Returns either the pointer
15071 it is passed, or a pointer to newly-allocated storage, in which case
15072 dump_ctf() will free it when it no longer needs it. */
15073
2f6ecaed
NA
15074static char *
15075dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15076 char *s, void *arg)
7d9813f1 15077{
3e50a591 15078 const char *blanks = arg;
7d9813f1
NA
15079 char *new_s;
15080
3e50a591 15081 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15082 return s;
15083 return new_s;
15084}
15085
926c9e76
NA
15086/* Dump CTF errors/warnings. */
15087static void
139633c3 15088dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15089{
15090 ctf_next_t *it = NULL;
15091 char *errtext;
15092 int is_warning;
15093 int err;
15094
15095 /* Dump accumulated errors and warnings. */
15096 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15097 {
5e9b84f7 15098 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15099 errtext);
15100 free (errtext);
15101 }
15102 if (err != ECTF_NEXT_END)
15103 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15104}
15105
2f6ecaed
NA
15106/* Dump one CTF archive member. */
15107
15108static int
139633c3 15109dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 15110{
139633c3 15111 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
15112 const char *things[] = {"Header", "Labels", "Data objects",
15113 "Function objects", "Variables", "Types", "Strings",
15114 ""};
15115 const char **thing;
15116 size_t i;
8b37e7b6 15117 int err = 0;
2f6ecaed
NA
15118
15119 /* Only print out the name of non-default-named archive members.
15120 The name .ctf appears everywhere, even for things that aren't
15121 really archives, so printing it out is liable to be confusing.
15122
15123 The parent, if there is one, is the default-owned archive member:
15124 avoid importing it into itself. (This does no harm, but looks
15125 confusing.) */
15126
15127 if (strcmp (name, ".ctf") != 0)
15128 {
15129 printf (_("\nCTF archive member: %s:\n"), name);
15130 ctf_import (ctf, parent);
15131 }
15132
15133 for (i = 0, thing = things; *thing[0]; thing++, i++)
15134 {
15135 ctf_dump_state_t *s = NULL;
15136 char *item;
15137
15138 printf ("\n %s:\n", *thing);
15139 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15140 (void *) " ")) != NULL)
15141 {
15142 printf ("%s\n", item);
15143 free (item);
15144 }
15145
15146 if (ctf_errno (ctf))
15147 {
15148 error (_("Iteration failed: %s, %s\n"), *thing,
15149 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15150 err = 1;
15151 goto out;
2f6ecaed
NA
15152 }
15153 }
8b37e7b6
NA
15154
15155 out:
926c9e76 15156 dump_ctf_errs (ctf);
8b37e7b6 15157 return err;
2f6ecaed
NA
15158}
15159
015dc7e1 15160static bool
7d9813f1
NA
15161dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15162{
15163 Elf_Internal_Shdr * parent_sec = NULL;
15164 Elf_Internal_Shdr * symtab_sec = NULL;
15165 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15166 void * data = NULL;
15167 void * symdata = NULL;
15168 void * strdata = NULL;
15169 void * parentdata = NULL;
15170 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15171 ctf_sect_t * symsectp = NULL;
15172 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15173 ctf_archive_t * ctfa = NULL;
15174 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15175 ctf_dict_t * parent = NULL;
7d9813f1 15176
7d9813f1 15177 int err;
015dc7e1 15178 bool ret = false;
7d9813f1
NA
15179
15180 shdr_to_ctf_sect (&ctfsect, section, filedata);
15181 data = get_section_contents (section, filedata);
15182 ctfsect.cts_data = data;
15183
616febde 15184 if (!dump_ctf_symtab_name)
3d16b64e 15185 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15186
15187 if (!dump_ctf_strtab_name)
3d16b64e 15188 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15189
15190 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15191 {
15192 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15193 {
15194 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15195 goto fail;
15196 }
15197 if ((symdata = (void *) get_data (NULL, filedata,
15198 symtab_sec->sh_offset, 1,
15199 symtab_sec->sh_size,
15200 _("symbols"))) == NULL)
15201 goto fail;
15202 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15203 symsect.cts_data = symdata;
15204 }
835f2fae 15205
df16e041 15206 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15207 {
15208 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15209 {
15210 error (_("No string table section named %s\n"),
15211 dump_ctf_strtab_name);
15212 goto fail;
15213 }
15214 if ((strdata = (void *) get_data (NULL, filedata,
15215 strtab_sec->sh_offset, 1,
15216 strtab_sec->sh_size,
15217 _("strings"))) == NULL)
15218 goto fail;
15219 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15220 strsect.cts_data = strdata;
15221 }
835f2fae 15222
7d9813f1
NA
15223 if (dump_ctf_parent_name)
15224 {
15225 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15226 {
15227 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15228 goto fail;
15229 }
15230 if ((parentdata = (void *) get_data (NULL, filedata,
15231 parent_sec->sh_offset, 1,
15232 parent_sec->sh_size,
15233 _("CTF parent"))) == NULL)
15234 goto fail;
15235 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15236 parentsect.cts_data = parentdata;
15237 }
15238
2f6ecaed
NA
15239 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15240 libctf papers over the difference, so we can pretend it is always an
15241 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15242
2f6ecaed 15243 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15244 {
926c9e76 15245 dump_ctf_errs (NULL);
7d9813f1
NA
15246 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15247 goto fail;
15248 }
15249
96c61be5
NA
15250 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15251 != ELFDATA2MSB);
15252
7d9813f1
NA
15253 if (parentdata)
15254 {
2f6ecaed
NA
15255 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15256 &err)) == NULL)
7d9813f1 15257 {
926c9e76 15258 dump_ctf_errs (NULL);
7d9813f1
NA
15259 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15260 goto fail;
15261 }
2f6ecaed
NA
15262 lookparent = parenta;
15263 }
15264 else
15265 lookparent = ctfa;
7d9813f1 15266
2f6ecaed
NA
15267 /* Assume that the applicable parent archive member is the default one.
15268 (This is what all known implementations are expected to do, if they
15269 put CTFs and their parents in archives together.) */
ae41200b 15270 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15271 {
926c9e76 15272 dump_ctf_errs (NULL);
2f6ecaed
NA
15273 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15274 goto fail;
7d9813f1
NA
15275 }
15276
015dc7e1 15277 ret = true;
7d9813f1 15278
835f2fae
NC
15279 if (filedata->is_separate)
15280 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15281 printable_section_name (filedata, section),
15282 filedata->file_name);
15283 else
15284 printf (_("\nDump of CTF section '%s':\n"),
15285 printable_section_name (filedata, section));
7d9813f1 15286
83d59285
NA
15287 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15288 {
15289 dump_ctf_errs (NULL);
15290 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15291 ret = false;
83d59285 15292 }
7d9813f1
NA
15293
15294 fail:
139633c3 15295 ctf_dict_close (parent);
2f6ecaed
NA
15296 ctf_close (ctfa);
15297 ctf_close (parenta);
7d9813f1
NA
15298 free (parentdata);
15299 free (data);
15300 free (symdata);
15301 free (strdata);
15302 return ret;
15303}
094e34f2 15304#endif
7d9813f1 15305
015dc7e1 15306static bool
dda8d76d
NC
15307load_specific_debug_section (enum dwarf_section_display_enum debug,
15308 const Elf_Internal_Shdr * sec,
15309 void * data)
1007acb3 15310{
2cf0635d 15311 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15312 char buf [64];
dda8d76d 15313 Filedata * filedata = (Filedata *) data;
9abca702 15314
19e6b90e 15315 if (section->start != NULL)
dda8d76d
NC
15316 {
15317 /* If it is already loaded, do nothing. */
15318 if (streq (section->filename, filedata->file_name))
015dc7e1 15319 return true;
dda8d76d
NC
15320 free (section->start);
15321 }
1007acb3 15322
19e6b90e
L
15323 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15324 section->address = sec->sh_addr;
dda8d76d
NC
15325 section->filename = filedata->file_name;
15326 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15327 sec->sh_offset, 1,
15328 sec->sh_size, buf);
59245841
NC
15329 if (section->start == NULL)
15330 section->size = 0;
15331 else
15332 {
77115a4a
L
15333 unsigned char *start = section->start;
15334 dwarf_size_type size = sec->sh_size;
dab394de 15335 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15336
15337 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15338 {
15339 Elf_Internal_Chdr chdr;
d8024a91
NC
15340 unsigned int compression_header_size;
15341
f53be977
L
15342 if (size < (is_32bit_elf
15343 ? sizeof (Elf32_External_Chdr)
15344 : sizeof (Elf64_External_Chdr)))
d8024a91 15345 {
55be8fd0 15346 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15347 section->name);
015dc7e1 15348 return false;
d8024a91
NC
15349 }
15350
ebdf1ebf 15351 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15352 if (compression_header_size == 0)
15353 /* An error message will have already been generated
15354 by get_compression_header. */
015dc7e1 15355 return false;
d8024a91 15356
813dabb9
L
15357 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15358 {
15359 warn (_("section '%s' has unsupported compress type: %d\n"),
15360 section->name, chdr.ch_type);
015dc7e1 15361 return false;
813dabb9 15362 }
dab394de 15363 uncompressed_size = chdr.ch_size;
77115a4a
L
15364 start += compression_header_size;
15365 size -= compression_header_size;
15366 }
dab394de
L
15367 else if (size > 12 && streq ((char *) start, "ZLIB"))
15368 {
15369 /* Read the zlib header. In this case, it should be "ZLIB"
15370 followed by the uncompressed section size, 8 bytes in
15371 big-endian order. */
15372 uncompressed_size = start[4]; uncompressed_size <<= 8;
15373 uncompressed_size += start[5]; uncompressed_size <<= 8;
15374 uncompressed_size += start[6]; uncompressed_size <<= 8;
15375 uncompressed_size += start[7]; uncompressed_size <<= 8;
15376 uncompressed_size += start[8]; uncompressed_size <<= 8;
15377 uncompressed_size += start[9]; uncompressed_size <<= 8;
15378 uncompressed_size += start[10]; uncompressed_size <<= 8;
15379 uncompressed_size += start[11];
15380 start += 12;
15381 size -= 12;
15382 }
15383
1835f746 15384 if (uncompressed_size)
77115a4a 15385 {
1835f746
NC
15386 if (uncompress_section_contents (&start, uncompressed_size,
15387 &size))
15388 {
15389 /* Free the compressed buffer, update the section buffer
15390 and the section size if uncompress is successful. */
15391 free (section->start);
15392 section->start = start;
15393 }
15394 else
15395 {
15396 error (_("Unable to decompress section %s\n"),
dda8d76d 15397 printable_section_name (filedata, sec));
015dc7e1 15398 return false;
1835f746 15399 }
77115a4a 15400 }
bc303e5d 15401
77115a4a 15402 section->size = size;
59245841 15403 }
4a114e3e 15404
1b315056 15405 if (section->start == NULL)
015dc7e1 15406 return false;
1b315056 15407
19e6b90e 15408 if (debug_displays [debug].relocate)
32ec8896 15409 {
dda8d76d 15410 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15411 & section->reloc_info, & section->num_relocs))
015dc7e1 15412 return false;
32ec8896 15413 }
d1c4b12b
NC
15414 else
15415 {
15416 section->reloc_info = NULL;
15417 section->num_relocs = 0;
15418 }
1007acb3 15419
015dc7e1 15420 return true;
1007acb3
L
15421}
15422
301a9420
AM
15423#if HAVE_LIBDEBUGINFOD
15424/* Return a hex string representation of the build-id. */
15425unsigned char *
15426get_build_id (void * data)
15427{
ca0e11aa 15428 Filedata * filedata = (Filedata *) data;
301a9420
AM
15429 Elf_Internal_Shdr * shdr;
15430 unsigned long i;
15431
55be8fd0
NC
15432 /* Iterate through notes to find note.gnu.build-id.
15433 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15434 for (i = 0, shdr = filedata->section_headers;
15435 i < filedata->file_header.e_shnum && shdr != NULL;
15436 i++, shdr++)
15437 {
15438 if (shdr->sh_type != SHT_NOTE)
15439 continue;
15440
15441 char * next;
15442 char * end;
15443 size_t data_remaining;
15444 size_t min_notesz;
15445 Elf_External_Note * enote;
15446 Elf_Internal_Note inote;
15447
15448 bfd_vma offset = shdr->sh_offset;
15449 bfd_vma align = shdr->sh_addralign;
15450 bfd_vma length = shdr->sh_size;
15451
15452 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15453 if (enote == NULL)
15454 continue;
15455
15456 if (align < 4)
15457 align = 4;
15458 else if (align != 4 && align != 8)
f761cb13
AM
15459 {
15460 free (enote);
15461 continue;
15462 }
301a9420
AM
15463
15464 end = (char *) enote + length;
15465 data_remaining = end - (char *) enote;
15466
15467 if (!is_ia64_vms (filedata))
15468 {
15469 min_notesz = offsetof (Elf_External_Note, name);
15470 if (data_remaining < min_notesz)
15471 {
55be8fd0
NC
15472 warn (_("\
15473malformed note encountered in section %s whilst scanning for build-id note\n"),
15474 printable_section_name (filedata, shdr));
f761cb13 15475 free (enote);
55be8fd0 15476 continue;
301a9420
AM
15477 }
15478 data_remaining -= min_notesz;
15479
15480 inote.type = BYTE_GET (enote->type);
15481 inote.namesz = BYTE_GET (enote->namesz);
15482 inote.namedata = enote->name;
15483 inote.descsz = BYTE_GET (enote->descsz);
15484 inote.descdata = ((char *) enote
15485 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15486 inote.descpos = offset + (inote.descdata - (char *) enote);
15487 next = ((char *) enote
15488 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15489 }
15490 else
15491 {
15492 Elf64_External_VMS_Note *vms_enote;
15493
15494 /* PR binutils/15191
15495 Make sure that there is enough data to read. */
15496 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15497 if (data_remaining < min_notesz)
15498 {
55be8fd0
NC
15499 warn (_("\
15500malformed note encountered in section %s whilst scanning for build-id note\n"),
15501 printable_section_name (filedata, shdr));
f761cb13 15502 free (enote);
55be8fd0 15503 continue;
301a9420
AM
15504 }
15505 data_remaining -= min_notesz;
15506
15507 vms_enote = (Elf64_External_VMS_Note *) enote;
15508 inote.type = BYTE_GET (vms_enote->type);
15509 inote.namesz = BYTE_GET (vms_enote->namesz);
15510 inote.namedata = vms_enote->name;
15511 inote.descsz = BYTE_GET (vms_enote->descsz);
15512 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15513 inote.descpos = offset + (inote.descdata - (char *) enote);
15514 next = inote.descdata + align_power (inote.descsz, 3);
15515 }
15516
15517 /* Skip malformed notes. */
15518 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15519 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15520 || (size_t) (next - inote.descdata) < inote.descsz
15521 || ((size_t) (next - inote.descdata)
15522 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15523 {
55be8fd0
NC
15524 warn (_("\
15525malformed note encountered in section %s whilst scanning for build-id note\n"),
15526 printable_section_name (filedata, shdr));
f761cb13 15527 free (enote);
301a9420
AM
15528 continue;
15529 }
15530
15531 /* Check if this is the build-id note. If so then convert the build-id
15532 bytes to a hex string. */
15533 if (inote.namesz > 0
24d127aa 15534 && startswith (inote.namedata, "GNU")
301a9420
AM
15535 && inote.type == NT_GNU_BUILD_ID)
15536 {
15537 unsigned long j;
15538 char * build_id;
15539
15540 build_id = malloc (inote.descsz * 2 + 1);
15541 if (build_id == NULL)
f761cb13
AM
15542 {
15543 free (enote);
15544 return NULL;
15545 }
301a9420
AM
15546
15547 for (j = 0; j < inote.descsz; ++j)
15548 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15549 build_id[inote.descsz * 2] = '\0';
f761cb13 15550 free (enote);
301a9420 15551
55be8fd0 15552 return (unsigned char *) build_id;
301a9420 15553 }
f761cb13 15554 free (enote);
301a9420
AM
15555 }
15556
15557 return NULL;
15558}
15559#endif /* HAVE_LIBDEBUGINFOD */
15560
657d0d47
CC
15561/* If this is not NULL, load_debug_section will only look for sections
15562 within the list of sections given here. */
32ec8896 15563static unsigned int * section_subset = NULL;
657d0d47 15564
015dc7e1 15565bool
dda8d76d 15566load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15567{
2cf0635d
NC
15568 struct dwarf_section * section = &debug_displays [debug].section;
15569 Elf_Internal_Shdr * sec;
dda8d76d
NC
15570 Filedata * filedata = (Filedata *) data;
15571
f425ec66
NC
15572 /* Without section headers we cannot find any sections. */
15573 if (filedata->section_headers == NULL)
015dc7e1 15574 return false;
f425ec66 15575
9c1ce108
AM
15576 if (filedata->string_table == NULL
15577 && filedata->file_header.e_shstrndx != SHN_UNDEF
15578 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15579 {
15580 Elf_Internal_Shdr * strs;
15581
15582 /* Read in the string table, so that we have section names to scan. */
15583 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15584
4dff97b2 15585 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15586 {
9c1ce108
AM
15587 filedata->string_table
15588 = (char *) get_data (NULL, filedata, strs->sh_offset,
15589 1, strs->sh_size, _("string table"));
dda8d76d 15590
9c1ce108
AM
15591 filedata->string_table_length
15592 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15593 }
15594 }
d966045b
DJ
15595
15596 /* Locate the debug section. */
dda8d76d 15597 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15598 if (sec != NULL)
15599 section->name = section->uncompressed_name;
15600 else
15601 {
dda8d76d 15602 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15603 if (sec != NULL)
15604 section->name = section->compressed_name;
15605 }
15606 if (sec == NULL)
015dc7e1 15607 return false;
d966045b 15608
657d0d47
CC
15609 /* If we're loading from a subset of sections, and we've loaded
15610 a section matching this name before, it's likely that it's a
15611 different one. */
15612 if (section_subset != NULL)
15613 free_debug_section (debug);
15614
dda8d76d 15615 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15616}
15617
19e6b90e
L
15618void
15619free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15620{
2cf0635d 15621 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15622
19e6b90e
L
15623 if (section->start == NULL)
15624 return;
1007acb3 15625
19e6b90e
L
15626 free ((char *) section->start);
15627 section->start = NULL;
15628 section->address = 0;
15629 section->size = 0;
a788aedd 15630
9db70fc3
AM
15631 free (section->reloc_info);
15632 section->reloc_info = NULL;
15633 section->num_relocs = 0;
1007acb3
L
15634}
15635
015dc7e1 15636static bool
dda8d76d 15637display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15638{
b9e920ec 15639 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15640 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15641 bfd_size_type length;
015dc7e1 15642 bool result = true;
3f5e193b 15643 int i;
1007acb3 15644
19e6b90e
L
15645 length = section->sh_size;
15646 if (length == 0)
1007acb3 15647 {
74e1a04b 15648 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15649 return true;
1007acb3 15650 }
5dff79d8
NC
15651 if (section->sh_type == SHT_NOBITS)
15652 {
15653 /* There is no point in dumping the contents of a debugging section
15654 which has the NOBITS type - the bits in the file will be random.
15655 This can happen when a file containing a .eh_frame section is
15656 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15657 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15658 print_name);
015dc7e1 15659 return false;
5dff79d8 15660 }
1007acb3 15661
24d127aa 15662 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15663 name = ".debug_info";
1007acb3 15664
19e6b90e
L
15665 /* See if we know how to display the contents of this section. */
15666 for (i = 0; i < max; i++)
d85bf2ba
NC
15667 {
15668 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15669 struct dwarf_section_display * display = debug_displays + i;
15670 struct dwarf_section * sec = & display->section;
d966045b 15671
d85bf2ba 15672 if (streq (sec->uncompressed_name, name)
24d127aa 15673 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15674 || streq (sec->compressed_name, name))
15675 {
015dc7e1 15676 bool secondary = (section != find_section (filedata, name));
1007acb3 15677
d85bf2ba
NC
15678 if (secondary)
15679 free_debug_section (id);
dda8d76d 15680
24d127aa 15681 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15682 sec->name = name;
15683 else if (streq (sec->uncompressed_name, name))
15684 sec->name = sec->uncompressed_name;
15685 else
15686 sec->name = sec->compressed_name;
657d0d47 15687
d85bf2ba
NC
15688 if (load_specific_debug_section (id, section, filedata))
15689 {
15690 /* If this debug section is part of a CU/TU set in a .dwp file,
15691 restrict load_debug_section to the sections in that set. */
15692 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15693
d85bf2ba 15694 result &= display->display (sec, filedata);
657d0d47 15695
d85bf2ba 15696 section_subset = NULL;
1007acb3 15697
44266f36 15698 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15699 free_debug_section (id);
15700 }
15701 break;
15702 }
15703 }
1007acb3 15704
19e6b90e 15705 if (i == max)
1007acb3 15706 {
74e1a04b 15707 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15708 result = false;
1007acb3
L
15709 }
15710
19e6b90e 15711 return result;
5b18a4bc 15712}
103f02d3 15713
aef1f6d0
DJ
15714/* Set DUMP_SECTS for all sections where dumps were requested
15715 based on section name. */
15716
15717static void
dda8d76d 15718initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15719{
2cf0635d 15720 struct dump_list_entry * cur;
aef1f6d0
DJ
15721
15722 for (cur = dump_sects_byname; cur; cur = cur->next)
15723 {
15724 unsigned int i;
015dc7e1 15725 bool any = false;
aef1f6d0 15726
dda8d76d 15727 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15728 if (SECTION_NAME_VALID (filedata->section_headers + i)
15729 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15730 {
6431e409 15731 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15732 any = true;
aef1f6d0
DJ
15733 }
15734
835f2fae
NC
15735 if (!any && !filedata->is_separate)
15736 warn (_("Section '%s' was not dumped because it does not exist\n"),
15737 cur->name);
aef1f6d0
DJ
15738 }
15739}
15740
015dc7e1 15741static bool
dda8d76d 15742process_section_contents (Filedata * filedata)
5b18a4bc 15743{
2cf0635d 15744 Elf_Internal_Shdr * section;
19e6b90e 15745 unsigned int i;
015dc7e1 15746 bool res = true;
103f02d3 15747
19e6b90e 15748 if (! do_dump)
015dc7e1 15749 return true;
103f02d3 15750
dda8d76d 15751 initialise_dumps_byname (filedata);
aef1f6d0 15752
dda8d76d 15753 for (i = 0, section = filedata->section_headers;
6431e409 15754 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15755 i++, section++)
15756 {
6431e409 15757 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15758
d6bfbc39
NC
15759 if (filedata->is_separate && ! process_links)
15760 dump &= DEBUG_DUMP;
047c3dbf 15761
19e6b90e 15762#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15763 if (dump & DISASS_DUMP)
15764 {
15765 if (! disassemble_section (section, filedata))
015dc7e1 15766 res = false;
dda8d76d 15767 }
19e6b90e 15768#endif
dda8d76d 15769 if (dump & HEX_DUMP)
32ec8896 15770 {
015dc7e1
AM
15771 if (! dump_section_as_bytes (section, filedata, false))
15772 res = false;
32ec8896 15773 }
103f02d3 15774
dda8d76d 15775 if (dump & RELOC_DUMP)
32ec8896 15776 {
015dc7e1
AM
15777 if (! dump_section_as_bytes (section, filedata, true))
15778 res = false;
32ec8896 15779 }
09c11c86 15780
dda8d76d 15781 if (dump & STRING_DUMP)
32ec8896 15782 {
dda8d76d 15783 if (! dump_section_as_strings (section, filedata))
015dc7e1 15784 res = false;
32ec8896 15785 }
cf13d699 15786
dda8d76d 15787 if (dump & DEBUG_DUMP)
32ec8896 15788 {
dda8d76d 15789 if (! display_debug_section (i, section, filedata))
015dc7e1 15790 res = false;
32ec8896 15791 }
7d9813f1 15792
094e34f2 15793#ifdef ENABLE_LIBCTF
7d9813f1
NA
15794 if (dump & CTF_DUMP)
15795 {
15796 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15797 res = false;
7d9813f1 15798 }
094e34f2 15799#endif
5b18a4bc 15800 }
103f02d3 15801
835f2fae 15802 if (! filedata->is_separate)
0ee3043f 15803 {
835f2fae
NC
15804 /* Check to see if the user requested a
15805 dump of a section that does not exist. */
15806 for (; i < filedata->dump.num_dump_sects; i++)
15807 if (filedata->dump.dump_sects[i])
15808 {
ca0e11aa 15809 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15810 res = false;
835f2fae 15811 }
0ee3043f 15812 }
32ec8896
NC
15813
15814 return res;
5b18a4bc 15815}
103f02d3 15816
5b18a4bc 15817static void
19e6b90e 15818process_mips_fpe_exception (int mask)
5b18a4bc 15819{
19e6b90e
L
15820 if (mask)
15821 {
015dc7e1 15822 bool first = true;
32ec8896 15823
19e6b90e 15824 if (mask & OEX_FPU_INEX)
015dc7e1 15825 fputs ("INEX", stdout), first = false;
19e6b90e 15826 if (mask & OEX_FPU_UFLO)
015dc7e1 15827 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15828 if (mask & OEX_FPU_OFLO)
015dc7e1 15829 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15830 if (mask & OEX_FPU_DIV0)
015dc7e1 15831 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15832 if (mask & OEX_FPU_INVAL)
15833 printf ("%sINVAL", first ? "" : "|");
15834 }
5b18a4bc 15835 else
19e6b90e 15836 fputs ("0", stdout);
5b18a4bc 15837}
103f02d3 15838
f6f0e17b
NC
15839/* Display's the value of TAG at location P. If TAG is
15840 greater than 0 it is assumed to be an unknown tag, and
15841 a message is printed to this effect. Otherwise it is
15842 assumed that a message has already been printed.
15843
15844 If the bottom bit of TAG is set it assumed to have a
15845 string value, otherwise it is assumed to have an integer
15846 value.
15847
15848 Returns an updated P pointing to the first unread byte
15849 beyond the end of TAG's value.
15850
15851 Reads at or beyond END will not be made. */
15852
15853static unsigned char *
60abdbed 15854display_tag_value (signed int tag,
f6f0e17b
NC
15855 unsigned char * p,
15856 const unsigned char * const end)
15857{
15858 unsigned long val;
15859
15860 if (tag > 0)
15861 printf (" Tag_unknown_%d: ", tag);
15862
15863 if (p >= end)
15864 {
4082ef84 15865 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15866 }
15867 else if (tag & 1)
15868 {
071436c6
NC
15869 /* PR 17531 file: 027-19978-0.004. */
15870 size_t maxlen = (end - p) - 1;
15871
15872 putchar ('"');
4082ef84
NC
15873 if (maxlen > 0)
15874 {
15875 print_symbol ((int) maxlen, (const char *) p);
15876 p += strnlen ((char *) p, maxlen) + 1;
15877 }
15878 else
15879 {
15880 printf (_("<corrupt string tag>"));
15881 p = (unsigned char *) end;
15882 }
071436c6 15883 printf ("\"\n");
f6f0e17b
NC
15884 }
15885 else
15886 {
cd30bcef 15887 READ_ULEB (val, p, end);
f6f0e17b
NC
15888 printf ("%ld (0x%lx)\n", val, val);
15889 }
15890
4082ef84 15891 assert (p <= end);
f6f0e17b
NC
15892 return p;
15893}
15894
53a346d8
CZ
15895/* ARC ABI attributes section. */
15896
15897static unsigned char *
15898display_arc_attribute (unsigned char * p,
15899 const unsigned char * const end)
15900{
15901 unsigned int tag;
53a346d8
CZ
15902 unsigned int val;
15903
cd30bcef 15904 READ_ULEB (tag, p, end);
53a346d8
CZ
15905
15906 switch (tag)
15907 {
15908 case Tag_ARC_PCS_config:
cd30bcef 15909 READ_ULEB (val, p, end);
53a346d8
CZ
15910 printf (" Tag_ARC_PCS_config: ");
15911 switch (val)
15912 {
15913 case 0:
15914 printf (_("Absent/Non standard\n"));
15915 break;
15916 case 1:
15917 printf (_("Bare metal/mwdt\n"));
15918 break;
15919 case 2:
15920 printf (_("Bare metal/newlib\n"));
15921 break;
15922 case 3:
15923 printf (_("Linux/uclibc\n"));
15924 break;
15925 case 4:
15926 printf (_("Linux/glibc\n"));
15927 break;
15928 default:
15929 printf (_("Unknown\n"));
15930 break;
15931 }
15932 break;
15933
15934 case Tag_ARC_CPU_base:
cd30bcef 15935 READ_ULEB (val, p, end);
53a346d8
CZ
15936 printf (" Tag_ARC_CPU_base: ");
15937 switch (val)
15938 {
15939 default:
15940 case TAG_CPU_NONE:
15941 printf (_("Absent\n"));
15942 break;
15943 case TAG_CPU_ARC6xx:
15944 printf ("ARC6xx\n");
15945 break;
15946 case TAG_CPU_ARC7xx:
15947 printf ("ARC7xx\n");
15948 break;
15949 case TAG_CPU_ARCEM:
15950 printf ("ARCEM\n");
15951 break;
15952 case TAG_CPU_ARCHS:
15953 printf ("ARCHS\n");
15954 break;
15955 }
15956 break;
15957
15958 case Tag_ARC_CPU_variation:
cd30bcef 15959 READ_ULEB (val, p, end);
53a346d8
CZ
15960 printf (" Tag_ARC_CPU_variation: ");
15961 switch (val)
15962 {
15963 default:
15964 if (val > 0 && val < 16)
53a346d8 15965 printf ("Core%d\n", val);
d8cbc93b
JL
15966 else
15967 printf ("Unknown\n");
15968 break;
15969
53a346d8
CZ
15970 case 0:
15971 printf (_("Absent\n"));
15972 break;
15973 }
15974 break;
15975
15976 case Tag_ARC_CPU_name:
15977 printf (" Tag_ARC_CPU_name: ");
15978 p = display_tag_value (-1, p, end);
15979 break;
15980
15981 case Tag_ARC_ABI_rf16:
cd30bcef 15982 READ_ULEB (val, p, end);
53a346d8
CZ
15983 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15984 break;
15985
15986 case Tag_ARC_ABI_osver:
cd30bcef 15987 READ_ULEB (val, p, end);
53a346d8
CZ
15988 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15989 break;
15990
15991 case Tag_ARC_ABI_pic:
15992 case Tag_ARC_ABI_sda:
cd30bcef 15993 READ_ULEB (val, p, end);
53a346d8
CZ
15994 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15995 : " Tag_ARC_ABI_pic: ");
15996 switch (val)
15997 {
15998 case 0:
15999 printf (_("Absent\n"));
16000 break;
16001 case 1:
16002 printf ("MWDT\n");
16003 break;
16004 case 2:
16005 printf ("GNU\n");
16006 break;
16007 default:
16008 printf (_("Unknown\n"));
16009 break;
16010 }
16011 break;
16012
16013 case Tag_ARC_ABI_tls:
cd30bcef 16014 READ_ULEB (val, p, end);
53a346d8
CZ
16015 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16016 break;
16017
16018 case Tag_ARC_ABI_enumsize:
cd30bcef 16019 READ_ULEB (val, p, end);
53a346d8
CZ
16020 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16021 _("smallest"));
16022 break;
16023
16024 case Tag_ARC_ABI_exceptions:
cd30bcef 16025 READ_ULEB (val, p, end);
53a346d8
CZ
16026 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16027 : _("default"));
16028 break;
16029
16030 case Tag_ARC_ABI_double_size:
cd30bcef 16031 READ_ULEB (val, p, end);
53a346d8
CZ
16032 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16033 break;
16034
16035 case Tag_ARC_ISA_config:
16036 printf (" Tag_ARC_ISA_config: ");
16037 p = display_tag_value (-1, p, end);
16038 break;
16039
16040 case Tag_ARC_ISA_apex:
16041 printf (" Tag_ARC_ISA_apex: ");
16042 p = display_tag_value (-1, p, end);
16043 break;
16044
16045 case Tag_ARC_ISA_mpy_option:
cd30bcef 16046 READ_ULEB (val, p, end);
53a346d8
CZ
16047 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16048 break;
16049
db1e1b45 16050 case Tag_ARC_ATR_version:
cd30bcef 16051 READ_ULEB (val, p, end);
db1e1b45 16052 printf (" Tag_ARC_ATR_version: %d\n", val);
16053 break;
16054
53a346d8
CZ
16055 default:
16056 return display_tag_value (tag & 1, p, end);
16057 }
16058
16059 return p;
16060}
16061
11c1ff18
PB
16062/* ARM EABI attributes section. */
16063typedef struct
16064{
70e99720 16065 unsigned int tag;
2cf0635d 16066 const char * name;
11c1ff18 16067 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16068 unsigned int type;
288f0ba2 16069 const char *const *table;
11c1ff18
PB
16070} arm_attr_public_tag;
16071
288f0ba2 16072static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16073 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16074 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 16075 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
16076static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16077static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16078 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16079static const char *const arm_attr_tag_FP_arch[] =
bca38921 16080 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16081 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16082static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16083static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16084 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16085 "NEON for ARMv8.1"};
288f0ba2 16086static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16087 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16088 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16089static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16090 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16091static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16092 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16093static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16094 {"Absolute", "PC-relative", "None"};
288f0ba2 16095static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16096 {"None", "direct", "GOT-indirect"};
288f0ba2 16097static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16098 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16099static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16100static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16101 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16102static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16103static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16104static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16105 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16106static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16107 {"Unused", "small", "int", "forced to int"};
288f0ba2 16108static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16109 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16110static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16111 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16112static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16113 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16114static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16115 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16116 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16117static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16118 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16119 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16120static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16121static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16122 {"Not Allowed", "Allowed"};
288f0ba2 16123static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16124 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16125static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16126 {"Follow architecture", "Allowed"};
288f0ba2 16127static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16128 {"Not Allowed", "Allowed"};
288f0ba2 16129static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16130 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16131 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16132static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16133static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16134 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16135 "TrustZone and Virtualization Extensions"};
288f0ba2 16136static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16137 {"Not Allowed", "Allowed"};
11c1ff18 16138
288f0ba2 16139static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16140 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16141
99db83d0
AC
16142static const char * arm_attr_tag_PAC_extension[] =
16143 {"No PAC/AUT instructions",
16144 "PAC/AUT instructions permitted in the NOP space",
16145 "PAC/AUT instructions permitted in the NOP and in the non-NOP space"};
16146
4b535030
AC
16147static const char * arm_attr_tag_BTI_extension[] =
16148 {"BTI instructions not permitted",
16149 "BTI instructions permitted in the NOP space",
16150 "BTI instructions permitted in the NOP and in the non-NOP space"};
16151
b81ee92f
AC
16152static const char * arm_attr_tag_BTI_use[] =
16153 {"Compiled without branch target enforcement",
16154 "Compiled with branch target enforcement"};
16155
c9fed665
AC
16156static const char * arm_attr_tag_PACRET_use[] =
16157 {"Compiled without return address signing and authentication",
16158 "Compiled with return address signing and authentication"};
16159
11c1ff18
PB
16160#define LOOKUP(id, name) \
16161 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16162static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16163{
16164 {4, "CPU_raw_name", 1, NULL},
16165 {5, "CPU_name", 1, NULL},
16166 LOOKUP(6, CPU_arch),
16167 {7, "CPU_arch_profile", 0, NULL},
16168 LOOKUP(8, ARM_ISA_use),
16169 LOOKUP(9, THUMB_ISA_use),
75375b3e 16170 LOOKUP(10, FP_arch),
11c1ff18 16171 LOOKUP(11, WMMX_arch),
f5f53991
AS
16172 LOOKUP(12, Advanced_SIMD_arch),
16173 LOOKUP(13, PCS_config),
11c1ff18
PB
16174 LOOKUP(14, ABI_PCS_R9_use),
16175 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16176 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16177 LOOKUP(17, ABI_PCS_GOT_use),
16178 LOOKUP(18, ABI_PCS_wchar_t),
16179 LOOKUP(19, ABI_FP_rounding),
16180 LOOKUP(20, ABI_FP_denormal),
16181 LOOKUP(21, ABI_FP_exceptions),
16182 LOOKUP(22, ABI_FP_user_exceptions),
16183 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16184 {24, "ABI_align_needed", 0, NULL},
16185 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16186 LOOKUP(26, ABI_enum_size),
16187 LOOKUP(27, ABI_HardFP_use),
16188 LOOKUP(28, ABI_VFP_args),
16189 LOOKUP(29, ABI_WMMX_args),
16190 LOOKUP(30, ABI_optimization_goals),
16191 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16192 {32, "compatibility", 0, NULL},
f5f53991 16193 LOOKUP(34, CPU_unaligned_access),
75375b3e 16194 LOOKUP(36, FP_HP_extension),
8e79c3df 16195 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16196 LOOKUP(42, MPextension_use),
16197 LOOKUP(44, DIV_use),
15afaa63 16198 LOOKUP(46, DSP_extension),
a7ad558c 16199 LOOKUP(48, MVE_arch),
99db83d0 16200 LOOKUP(50, PAC_extension),
4b535030 16201 LOOKUP(52, BTI_extension),
b81ee92f 16202 LOOKUP(74, BTI_use),
c9fed665 16203 LOOKUP(76, PACRET_use),
f5f53991
AS
16204 {64, "nodefaults", 0, NULL},
16205 {65, "also_compatible_with", 0, NULL},
16206 LOOKUP(66, T2EE_use),
16207 {67, "conformance", 1, NULL},
16208 LOOKUP(68, Virtualization_use),
cd21e546 16209 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16210};
16211#undef LOOKUP
16212
11c1ff18 16213static unsigned char *
f6f0e17b
NC
16214display_arm_attribute (unsigned char * p,
16215 const unsigned char * const end)
11c1ff18 16216{
70e99720 16217 unsigned int tag;
70e99720 16218 unsigned int val;
2cf0635d 16219 arm_attr_public_tag * attr;
11c1ff18 16220 unsigned i;
70e99720 16221 unsigned int type;
11c1ff18 16222
cd30bcef 16223 READ_ULEB (tag, p, end);
11c1ff18 16224 attr = NULL;
2cf0635d 16225 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16226 {
16227 if (arm_attr_public_tags[i].tag == tag)
16228 {
16229 attr = &arm_attr_public_tags[i];
16230 break;
16231 }
16232 }
16233
16234 if (attr)
16235 {
16236 printf (" Tag_%s: ", attr->name);
16237 switch (attr->type)
16238 {
16239 case 0:
16240 switch (tag)
16241 {
16242 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16243 READ_ULEB (val, p, end);
11c1ff18
PB
16244 switch (val)
16245 {
2b692964
NC
16246 case 0: printf (_("None\n")); break;
16247 case 'A': printf (_("Application\n")); break;
16248 case 'R': printf (_("Realtime\n")); break;
16249 case 'M': printf (_("Microcontroller\n")); break;
16250 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16251 default: printf ("??? (%d)\n", val); break;
16252 }
16253 break;
16254
75375b3e 16255 case 24: /* Tag_align_needed. */
cd30bcef 16256 READ_ULEB (val, p, end);
75375b3e
MGD
16257 switch (val)
16258 {
2b692964
NC
16259 case 0: printf (_("None\n")); break;
16260 case 1: printf (_("8-byte\n")); break;
16261 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16262 case 3: printf ("??? 3\n"); break;
16263 default:
16264 if (val <= 12)
dd24e3da 16265 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16266 1 << val);
16267 else
16268 printf ("??? (%d)\n", val);
16269 break;
16270 }
16271 break;
16272
16273 case 25: /* Tag_align_preserved. */
cd30bcef 16274 READ_ULEB (val, p, end);
75375b3e
MGD
16275 switch (val)
16276 {
2b692964
NC
16277 case 0: printf (_("None\n")); break;
16278 case 1: printf (_("8-byte, except leaf SP\n")); break;
16279 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16280 case 3: printf ("??? 3\n"); break;
16281 default:
16282 if (val <= 12)
dd24e3da 16283 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16284 1 << val);
16285 else
16286 printf ("??? (%d)\n", val);
16287 break;
16288 }
16289 break;
16290
11c1ff18 16291 case 32: /* Tag_compatibility. */
071436c6 16292 {
cd30bcef 16293 READ_ULEB (val, p, end);
071436c6 16294 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16295 if (p < end - 1)
16296 {
16297 size_t maxlen = (end - p) - 1;
16298
16299 print_symbol ((int) maxlen, (const char *) p);
16300 p += strnlen ((char *) p, maxlen) + 1;
16301 }
16302 else
16303 {
16304 printf (_("<corrupt>"));
16305 p = (unsigned char *) end;
16306 }
071436c6 16307 putchar ('\n');
071436c6 16308 }
11c1ff18
PB
16309 break;
16310
f5f53991 16311 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16312 /* PR 17531: file: 001-505008-0.01. */
16313 if (p < end)
16314 p++;
2b692964 16315 printf (_("True\n"));
f5f53991
AS
16316 break;
16317
16318 case 65: /* Tag_also_compatible_with. */
cd30bcef 16319 READ_ULEB (val, p, end);
f5f53991
AS
16320 if (val == 6 /* Tag_CPU_arch. */)
16321 {
cd30bcef 16322 READ_ULEB (val, p, end);
071436c6 16323 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16324 printf ("??? (%d)\n", val);
16325 else
16326 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16327 }
16328 else
16329 printf ("???\n");
071436c6
NC
16330 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16331 ;
f5f53991
AS
16332 break;
16333
11c1ff18 16334 default:
bee0ee85
NC
16335 printf (_("<unknown: %d>\n"), tag);
16336 break;
11c1ff18
PB
16337 }
16338 return p;
16339
16340 case 1:
f6f0e17b 16341 return display_tag_value (-1, p, end);
11c1ff18 16342 case 2:
f6f0e17b 16343 return display_tag_value (0, p, end);
11c1ff18
PB
16344
16345 default:
16346 assert (attr->type & 0x80);
cd30bcef 16347 READ_ULEB (val, p, end);
11c1ff18
PB
16348 type = attr->type & 0x7f;
16349 if (val >= type)
16350 printf ("??? (%d)\n", val);
16351 else
16352 printf ("%s\n", attr->table[val]);
16353 return p;
16354 }
16355 }
11c1ff18 16356
f6f0e17b 16357 return display_tag_value (tag, p, end);
11c1ff18
PB
16358}
16359
104d59d1 16360static unsigned char *
60bca95a 16361display_gnu_attribute (unsigned char * p,
60abdbed 16362 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16363 const unsigned char * const end)
104d59d1 16364{
cd30bcef 16365 unsigned int tag;
60abdbed 16366 unsigned int val;
104d59d1 16367
cd30bcef 16368 READ_ULEB (tag, p, end);
104d59d1
JM
16369
16370 /* Tag_compatibility is the only generic GNU attribute defined at
16371 present. */
16372 if (tag == 32)
16373 {
cd30bcef 16374 READ_ULEB (val, p, end);
071436c6
NC
16375
16376 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16377 if (p == end)
16378 {
071436c6 16379 printf (_("<corrupt>\n"));
f6f0e17b
NC
16380 warn (_("corrupt vendor attribute\n"));
16381 }
16382 else
16383 {
4082ef84
NC
16384 if (p < end - 1)
16385 {
16386 size_t maxlen = (end - p) - 1;
071436c6 16387
4082ef84
NC
16388 print_symbol ((int) maxlen, (const char *) p);
16389 p += strnlen ((char *) p, maxlen) + 1;
16390 }
16391 else
16392 {
16393 printf (_("<corrupt>"));
16394 p = (unsigned char *) end;
16395 }
071436c6 16396 putchar ('\n');
f6f0e17b 16397 }
104d59d1
JM
16398 return p;
16399 }
16400
16401 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16402 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16403
f6f0e17b 16404 return display_tag_value (tag, p, end);
104d59d1
JM
16405}
16406
85f7484a
PB
16407static unsigned char *
16408display_m68k_gnu_attribute (unsigned char * p,
16409 unsigned int tag,
16410 const unsigned char * const end)
16411{
16412 unsigned int val;
16413
16414 if (tag == Tag_GNU_M68K_ABI_FP)
16415 {
16416 printf (" Tag_GNU_M68K_ABI_FP: ");
16417 if (p == end)
16418 {
16419 printf (_("<corrupt>\n"));
16420 return p;
16421 }
16422 READ_ULEB (val, p, end);
16423
16424 if (val > 3)
16425 printf ("(%#x), ", val);
16426
16427 switch (val & 3)
16428 {
16429 case 0:
16430 printf (_("unspecified hard/soft float\n"));
16431 break;
16432 case 1:
16433 printf (_("hard float\n"));
16434 break;
16435 case 2:
16436 printf (_("soft float\n"));
16437 break;
16438 }
16439 return p;
16440 }
16441
16442 return display_tag_value (tag & 1, p, end);
16443}
16444
34c8bcba 16445static unsigned char *
f6f0e17b 16446display_power_gnu_attribute (unsigned char * p,
60abdbed 16447 unsigned int tag,
f6f0e17b 16448 const unsigned char * const end)
34c8bcba 16449{
005d79fd 16450 unsigned int val;
34c8bcba
JM
16451
16452 if (tag == Tag_GNU_Power_ABI_FP)
16453 {
34c8bcba 16454 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16455 if (p == end)
005d79fd
AM
16456 {
16457 printf (_("<corrupt>\n"));
16458 return p;
16459 }
cd30bcef 16460 READ_ULEB (val, p, end);
60bca95a 16461
005d79fd
AM
16462 if (val > 15)
16463 printf ("(%#x), ", val);
16464
16465 switch (val & 3)
34c8bcba
JM
16466 {
16467 case 0:
005d79fd 16468 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16469 break;
16470 case 1:
005d79fd 16471 printf (_("hard float, "));
34c8bcba
JM
16472 break;
16473 case 2:
005d79fd 16474 printf (_("soft float, "));
34c8bcba 16475 break;
3c7b9897 16476 case 3:
005d79fd 16477 printf (_("single-precision hard float, "));
3c7b9897 16478 break;
005d79fd
AM
16479 }
16480
16481 switch (val & 0xC)
16482 {
16483 case 0:
16484 printf (_("unspecified long double\n"));
16485 break;
16486 case 4:
16487 printf (_("128-bit IBM long double\n"));
16488 break;
16489 case 8:
16490 printf (_("64-bit long double\n"));
16491 break;
16492 case 12:
16493 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16494 break;
16495 }
16496 return p;
005d79fd 16497 }
34c8bcba 16498
c6e65352
DJ
16499 if (tag == Tag_GNU_Power_ABI_Vector)
16500 {
c6e65352 16501 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16502 if (p == end)
005d79fd
AM
16503 {
16504 printf (_("<corrupt>\n"));
16505 return p;
16506 }
cd30bcef 16507 READ_ULEB (val, p, end);
005d79fd
AM
16508
16509 if (val > 3)
16510 printf ("(%#x), ", val);
16511
16512 switch (val & 3)
c6e65352
DJ
16513 {
16514 case 0:
005d79fd 16515 printf (_("unspecified\n"));
c6e65352
DJ
16516 break;
16517 case 1:
005d79fd 16518 printf (_("generic\n"));
c6e65352
DJ
16519 break;
16520 case 2:
16521 printf ("AltiVec\n");
16522 break;
16523 case 3:
16524 printf ("SPE\n");
16525 break;
c6e65352
DJ
16526 }
16527 return p;
005d79fd 16528 }
c6e65352 16529
f82e0623
NF
16530 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16531 {
005d79fd 16532 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16533 if (p == end)
f6f0e17b 16534 {
005d79fd 16535 printf (_("<corrupt>\n"));
f6f0e17b
NC
16536 return p;
16537 }
cd30bcef 16538 READ_ULEB (val, p, end);
0b4362b0 16539
005d79fd
AM
16540 if (val > 2)
16541 printf ("(%#x), ", val);
16542
16543 switch (val & 3)
16544 {
16545 case 0:
16546 printf (_("unspecified\n"));
16547 break;
16548 case 1:
16549 printf ("r3/r4\n");
16550 break;
16551 case 2:
16552 printf (_("memory\n"));
16553 break;
16554 case 3:
16555 printf ("???\n");
16556 break;
16557 }
f82e0623
NF
16558 return p;
16559 }
16560
f6f0e17b 16561 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16562}
16563
643f7afb
AK
16564static unsigned char *
16565display_s390_gnu_attribute (unsigned char * p,
60abdbed 16566 unsigned int tag,
643f7afb
AK
16567 const unsigned char * const end)
16568{
cd30bcef 16569 unsigned int val;
643f7afb
AK
16570
16571 if (tag == Tag_GNU_S390_ABI_Vector)
16572 {
643f7afb 16573 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16574 READ_ULEB (val, p, end);
643f7afb
AK
16575
16576 switch (val)
16577 {
16578 case 0:
16579 printf (_("any\n"));
16580 break;
16581 case 1:
16582 printf (_("software\n"));
16583 break;
16584 case 2:
16585 printf (_("hardware\n"));
16586 break;
16587 default:
16588 printf ("??? (%d)\n", val);
16589 break;
16590 }
16591 return p;
16592 }
16593
16594 return display_tag_value (tag & 1, p, end);
16595}
16596
9e8c70f9 16597static void
60abdbed 16598display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16599{
16600 if (mask)
16601 {
015dc7e1 16602 bool first = true;
071436c6 16603
9e8c70f9 16604 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16605 fputs ("mul32", stdout), first = false;
9e8c70f9 16606 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16607 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16608 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16609 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16610 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16611 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16612 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16613 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16614 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16615 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16616 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16617 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16618 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16619 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16620 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16621 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16622 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16623 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16624 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16625 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16626 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16627 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16628 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16629 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16630 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16631 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16632 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16633 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16634 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16635 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16636 }
16637 else
071436c6
NC
16638 fputc ('0', stdout);
16639 fputc ('\n', stdout);
9e8c70f9
DM
16640}
16641
3d68f91c 16642static void
60abdbed 16643display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16644{
16645 if (mask)
16646 {
015dc7e1 16647 bool first = true;
071436c6 16648
3d68f91c 16649 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16650 fputs ("fjathplus", stdout), first = false;
3d68f91c 16651 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16652 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16653 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16654 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16655 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16656 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16657 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16658 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16659 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16660 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16661 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16662 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16663 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16664 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16665 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16666 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16667 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16668 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16669 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16670 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16671 }
16672 else
071436c6
NC
16673 fputc ('0', stdout);
16674 fputc ('\n', stdout);
3d68f91c
JM
16675}
16676
9e8c70f9 16677static unsigned char *
f6f0e17b 16678display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16679 unsigned int tag,
f6f0e17b 16680 const unsigned char * const end)
9e8c70f9 16681{
cd30bcef 16682 unsigned int val;
3d68f91c 16683
9e8c70f9
DM
16684 if (tag == Tag_GNU_Sparc_HWCAPS)
16685 {
cd30bcef 16686 READ_ULEB (val, p, end);
9e8c70f9 16687 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16688 display_sparc_hwcaps (val);
16689 return p;
3d68f91c
JM
16690 }
16691 if (tag == Tag_GNU_Sparc_HWCAPS2)
16692 {
cd30bcef 16693 READ_ULEB (val, p, end);
3d68f91c
JM
16694 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16695 display_sparc_hwcaps2 (val);
16696 return p;
16697 }
9e8c70f9 16698
f6f0e17b 16699 return display_tag_value (tag, p, end);
9e8c70f9
DM
16700}
16701
351cdf24 16702static void
32ec8896 16703print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16704{
16705 switch (val)
16706 {
16707 case Val_GNU_MIPS_ABI_FP_ANY:
16708 printf (_("Hard or soft float\n"));
16709 break;
16710 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16711 printf (_("Hard float (double precision)\n"));
16712 break;
16713 case Val_GNU_MIPS_ABI_FP_SINGLE:
16714 printf (_("Hard float (single precision)\n"));
16715 break;
16716 case Val_GNU_MIPS_ABI_FP_SOFT:
16717 printf (_("Soft float\n"));
16718 break;
16719 case Val_GNU_MIPS_ABI_FP_OLD_64:
16720 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16721 break;
16722 case Val_GNU_MIPS_ABI_FP_XX:
16723 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16724 break;
16725 case Val_GNU_MIPS_ABI_FP_64:
16726 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16727 break;
16728 case Val_GNU_MIPS_ABI_FP_64A:
16729 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16730 break;
3350cc01
CM
16731 case Val_GNU_MIPS_ABI_FP_NAN2008:
16732 printf (_("NaN 2008 compatibility\n"));
16733 break;
351cdf24
MF
16734 default:
16735 printf ("??? (%d)\n", val);
16736 break;
16737 }
16738}
16739
2cf19d5c 16740static unsigned char *
f6f0e17b 16741display_mips_gnu_attribute (unsigned char * p,
60abdbed 16742 unsigned int tag,
f6f0e17b 16743 const unsigned char * const end)
2cf19d5c 16744{
2cf19d5c
JM
16745 if (tag == Tag_GNU_MIPS_ABI_FP)
16746 {
32ec8896 16747 unsigned int val;
f6f0e17b 16748
2cf19d5c 16749 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16750 READ_ULEB (val, p, end);
351cdf24 16751 print_mips_fp_abi_value (val);
2cf19d5c
JM
16752 return p;
16753 }
16754
a9f58168
CF
16755 if (tag == Tag_GNU_MIPS_ABI_MSA)
16756 {
32ec8896 16757 unsigned int val;
a9f58168 16758
a9f58168 16759 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16760 READ_ULEB (val, p, end);
a9f58168
CF
16761
16762 switch (val)
16763 {
16764 case Val_GNU_MIPS_ABI_MSA_ANY:
16765 printf (_("Any MSA or not\n"));
16766 break;
16767 case Val_GNU_MIPS_ABI_MSA_128:
16768 printf (_("128-bit MSA\n"));
16769 break;
16770 default:
16771 printf ("??? (%d)\n", val);
16772 break;
16773 }
16774 return p;
16775 }
16776
f6f0e17b 16777 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16778}
16779
59e6276b 16780static unsigned char *
f6f0e17b
NC
16781display_tic6x_attribute (unsigned char * p,
16782 const unsigned char * const end)
59e6276b 16783{
60abdbed 16784 unsigned int tag;
cd30bcef 16785 unsigned int val;
59e6276b 16786
cd30bcef 16787 READ_ULEB (tag, p, end);
59e6276b
JM
16788
16789 switch (tag)
16790 {
75fa6dc1 16791 case Tag_ISA:
75fa6dc1 16792 printf (" Tag_ISA: ");
cd30bcef 16793 READ_ULEB (val, p, end);
59e6276b
JM
16794
16795 switch (val)
16796 {
75fa6dc1 16797 case C6XABI_Tag_ISA_none:
59e6276b
JM
16798 printf (_("None\n"));
16799 break;
75fa6dc1 16800 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16801 printf ("C62x\n");
16802 break;
75fa6dc1 16803 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16804 printf ("C67x\n");
16805 break;
75fa6dc1 16806 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16807 printf ("C67x+\n");
16808 break;
75fa6dc1 16809 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16810 printf ("C64x\n");
16811 break;
75fa6dc1 16812 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16813 printf ("C64x+\n");
16814 break;
75fa6dc1 16815 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16816 printf ("C674x\n");
16817 break;
16818 default:
16819 printf ("??? (%d)\n", val);
16820 break;
16821 }
16822 return p;
16823
87779176 16824 case Tag_ABI_wchar_t:
87779176 16825 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16826 READ_ULEB (val, p, end);
87779176
JM
16827 switch (val)
16828 {
16829 case 0:
16830 printf (_("Not used\n"));
16831 break;
16832 case 1:
16833 printf (_("2 bytes\n"));
16834 break;
16835 case 2:
16836 printf (_("4 bytes\n"));
16837 break;
16838 default:
16839 printf ("??? (%d)\n", val);
16840 break;
16841 }
16842 return p;
16843
16844 case Tag_ABI_stack_align_needed:
87779176 16845 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16846 READ_ULEB (val, p, end);
87779176
JM
16847 switch (val)
16848 {
16849 case 0:
16850 printf (_("8-byte\n"));
16851 break;
16852 case 1:
16853 printf (_("16-byte\n"));
16854 break;
16855 default:
16856 printf ("??? (%d)\n", val);
16857 break;
16858 }
16859 return p;
16860
16861 case Tag_ABI_stack_align_preserved:
cd30bcef 16862 READ_ULEB (val, p, end);
87779176
JM
16863 printf (" Tag_ABI_stack_align_preserved: ");
16864 switch (val)
16865 {
16866 case 0:
16867 printf (_("8-byte\n"));
16868 break;
16869 case 1:
16870 printf (_("16-byte\n"));
16871 break;
16872 default:
16873 printf ("??? (%d)\n", val);
16874 break;
16875 }
16876 return p;
16877
b5593623 16878 case Tag_ABI_DSBT:
cd30bcef 16879 READ_ULEB (val, p, end);
b5593623
JM
16880 printf (" Tag_ABI_DSBT: ");
16881 switch (val)
16882 {
16883 case 0:
16884 printf (_("DSBT addressing not used\n"));
16885 break;
16886 case 1:
16887 printf (_("DSBT addressing used\n"));
16888 break;
16889 default:
16890 printf ("??? (%d)\n", val);
16891 break;
16892 }
16893 return p;
16894
87779176 16895 case Tag_ABI_PID:
cd30bcef 16896 READ_ULEB (val, p, end);
87779176
JM
16897 printf (" Tag_ABI_PID: ");
16898 switch (val)
16899 {
16900 case 0:
16901 printf (_("Data addressing position-dependent\n"));
16902 break;
16903 case 1:
16904 printf (_("Data addressing position-independent, GOT near DP\n"));
16905 break;
16906 case 2:
16907 printf (_("Data addressing position-independent, GOT far from DP\n"));
16908 break;
16909 default:
16910 printf ("??? (%d)\n", val);
16911 break;
16912 }
16913 return p;
16914
16915 case Tag_ABI_PIC:
cd30bcef 16916 READ_ULEB (val, p, end);
87779176
JM
16917 printf (" Tag_ABI_PIC: ");
16918 switch (val)
16919 {
16920 case 0:
16921 printf (_("Code addressing position-dependent\n"));
16922 break;
16923 case 1:
16924 printf (_("Code addressing position-independent\n"));
16925 break;
16926 default:
16927 printf ("??? (%d)\n", val);
16928 break;
16929 }
16930 return p;
16931
16932 case Tag_ABI_array_object_alignment:
cd30bcef 16933 READ_ULEB (val, p, end);
87779176
JM
16934 printf (" Tag_ABI_array_object_alignment: ");
16935 switch (val)
16936 {
16937 case 0:
16938 printf (_("8-byte\n"));
16939 break;
16940 case 1:
16941 printf (_("4-byte\n"));
16942 break;
16943 case 2:
16944 printf (_("16-byte\n"));
16945 break;
16946 default:
16947 printf ("??? (%d)\n", val);
16948 break;
16949 }
16950 return p;
16951
16952 case Tag_ABI_array_object_align_expected:
cd30bcef 16953 READ_ULEB (val, p, end);
87779176
JM
16954 printf (" Tag_ABI_array_object_align_expected: ");
16955 switch (val)
16956 {
16957 case 0:
16958 printf (_("8-byte\n"));
16959 break;
16960 case 1:
16961 printf (_("4-byte\n"));
16962 break;
16963 case 2:
16964 printf (_("16-byte\n"));
16965 break;
16966 default:
16967 printf ("??? (%d)\n", val);
16968 break;
16969 }
16970 return p;
16971
3cbd1c06 16972 case Tag_ABI_compatibility:
071436c6 16973 {
cd30bcef 16974 READ_ULEB (val, p, end);
071436c6 16975 printf (" Tag_ABI_compatibility: ");
071436c6 16976 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16977 if (p < end - 1)
16978 {
16979 size_t maxlen = (end - p) - 1;
16980
16981 print_symbol ((int) maxlen, (const char *) p);
16982 p += strnlen ((char *) p, maxlen) + 1;
16983 }
16984 else
16985 {
16986 printf (_("<corrupt>"));
16987 p = (unsigned char *) end;
16988 }
071436c6 16989 putchar ('\n');
071436c6
NC
16990 return p;
16991 }
87779176
JM
16992
16993 case Tag_ABI_conformance:
071436c6 16994 {
4082ef84
NC
16995 printf (" Tag_ABI_conformance: \"");
16996 if (p < end - 1)
16997 {
16998 size_t maxlen = (end - p) - 1;
071436c6 16999
4082ef84
NC
17000 print_symbol ((int) maxlen, (const char *) p);
17001 p += strnlen ((char *) p, maxlen) + 1;
17002 }
17003 else
17004 {
17005 printf (_("<corrupt>"));
17006 p = (unsigned char *) end;
17007 }
071436c6 17008 printf ("\"\n");
071436c6
NC
17009 return p;
17010 }
59e6276b
JM
17011 }
17012
f6f0e17b
NC
17013 return display_tag_value (tag, p, end);
17014}
59e6276b 17015
f6f0e17b 17016static void
60abdbed 17017display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17018{
17019 unsigned long addr = 0;
17020 size_t bytes = end - p;
17021
feceaa59 17022 assert (end >= p);
f6f0e17b 17023 while (bytes)
87779176 17024 {
f6f0e17b
NC
17025 int j;
17026 int k;
17027 int lbytes = (bytes > 16 ? 16 : bytes);
17028
17029 printf (" 0x%8.8lx ", addr);
17030
17031 for (j = 0; j < 16; j++)
17032 {
17033 if (j < lbytes)
17034 printf ("%2.2x", p[j]);
17035 else
17036 printf (" ");
17037
17038 if ((j & 3) == 3)
17039 printf (" ");
17040 }
17041
17042 for (j = 0; j < lbytes; j++)
17043 {
17044 k = p[j];
17045 if (k >= ' ' && k < 0x7f)
17046 printf ("%c", k);
17047 else
17048 printf (".");
17049 }
17050
17051 putchar ('\n');
17052
17053 p += lbytes;
17054 bytes -= lbytes;
17055 addr += lbytes;
87779176 17056 }
59e6276b 17057
f6f0e17b 17058 putchar ('\n');
59e6276b
JM
17059}
17060
13761a11 17061static unsigned char *
b0191216 17062display_msp430_attribute (unsigned char * p,
13761a11
NC
17063 const unsigned char * const end)
17064{
60abdbed
NC
17065 unsigned int val;
17066 unsigned int tag;
13761a11 17067
cd30bcef 17068 READ_ULEB (tag, p, end);
0b4362b0 17069
13761a11
NC
17070 switch (tag)
17071 {
17072 case OFBA_MSPABI_Tag_ISA:
13761a11 17073 printf (" Tag_ISA: ");
cd30bcef 17074 READ_ULEB (val, p, end);
13761a11
NC
17075 switch (val)
17076 {
17077 case 0: printf (_("None\n")); break;
17078 case 1: printf (_("MSP430\n")); break;
17079 case 2: printf (_("MSP430X\n")); break;
17080 default: printf ("??? (%d)\n", val); break;
17081 }
17082 break;
17083
17084 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17085 printf (" Tag_Code_Model: ");
cd30bcef 17086 READ_ULEB (val, p, end);
13761a11
NC
17087 switch (val)
17088 {
17089 case 0: printf (_("None\n")); break;
17090 case 1: printf (_("Small\n")); break;
17091 case 2: printf (_("Large\n")); break;
17092 default: printf ("??? (%d)\n", val); break;
17093 }
17094 break;
17095
17096 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17097 printf (" Tag_Data_Model: ");
cd30bcef 17098 READ_ULEB (val, p, end);
13761a11
NC
17099 switch (val)
17100 {
17101 case 0: printf (_("None\n")); break;
17102 case 1: printf (_("Small\n")); break;
17103 case 2: printf (_("Large\n")); break;
17104 case 3: printf (_("Restricted Large\n")); break;
17105 default: printf ("??? (%d)\n", val); break;
17106 }
17107 break;
17108
17109 default:
17110 printf (_(" <unknown tag %d>: "), tag);
17111
17112 if (tag & 1)
17113 {
071436c6 17114 putchar ('"');
4082ef84
NC
17115 if (p < end - 1)
17116 {
17117 size_t maxlen = (end - p) - 1;
17118
17119 print_symbol ((int) maxlen, (const char *) p);
17120 p += strnlen ((char *) p, maxlen) + 1;
17121 }
17122 else
17123 {
17124 printf (_("<corrupt>"));
17125 p = (unsigned char *) end;
17126 }
071436c6 17127 printf ("\"\n");
13761a11
NC
17128 }
17129 else
17130 {
cd30bcef 17131 READ_ULEB (val, p, end);
13761a11
NC
17132 printf ("%d (0x%x)\n", val, val);
17133 }
17134 break;
17135 }
17136
4082ef84 17137 assert (p <= end);
13761a11
NC
17138 return p;
17139}
17140
c0ea7c52
JL
17141static unsigned char *
17142display_msp430_gnu_attribute (unsigned char * p,
17143 unsigned int tag,
17144 const unsigned char * const end)
17145{
17146 if (tag == Tag_GNU_MSP430_Data_Region)
17147 {
cd30bcef 17148 unsigned int val;
c0ea7c52 17149
c0ea7c52 17150 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17151 READ_ULEB (val, p, end);
c0ea7c52
JL
17152
17153 switch (val)
17154 {
17155 case Val_GNU_MSP430_Data_Region_Any:
17156 printf (_("Any Region\n"));
17157 break;
17158 case Val_GNU_MSP430_Data_Region_Lower:
17159 printf (_("Lower Region Only\n"));
17160 break;
17161 default:
cd30bcef 17162 printf ("??? (%u)\n", val);
c0ea7c52
JL
17163 }
17164 return p;
17165 }
17166 return display_tag_value (tag & 1, p, end);
17167}
17168
2dc8dd17
JW
17169struct riscv_attr_tag_t {
17170 const char *name;
cd30bcef 17171 unsigned int tag;
2dc8dd17
JW
17172};
17173
17174static struct riscv_attr_tag_t riscv_attr_tag[] =
17175{
17176#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17177 T(arch),
17178 T(priv_spec),
17179 T(priv_spec_minor),
17180 T(priv_spec_revision),
17181 T(unaligned_access),
17182 T(stack_align),
17183#undef T
17184};
17185
17186static unsigned char *
17187display_riscv_attribute (unsigned char *p,
17188 const unsigned char * const end)
17189{
cd30bcef
AM
17190 unsigned int val;
17191 unsigned int tag;
2dc8dd17
JW
17192 struct riscv_attr_tag_t *attr = NULL;
17193 unsigned i;
17194
cd30bcef 17195 READ_ULEB (tag, p, end);
2dc8dd17
JW
17196
17197 /* Find the name of attribute. */
17198 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17199 {
17200 if (riscv_attr_tag[i].tag == tag)
17201 {
17202 attr = &riscv_attr_tag[i];
17203 break;
17204 }
17205 }
17206
17207 if (attr)
17208 printf (" %s: ", attr->name);
17209 else
17210 return display_tag_value (tag, p, end);
17211
17212 switch (tag)
17213 {
17214 case Tag_RISCV_priv_spec:
17215 case Tag_RISCV_priv_spec_minor:
17216 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17217 READ_ULEB (val, p, end);
17218 printf (_("%u\n"), val);
2dc8dd17
JW
17219 break;
17220 case Tag_RISCV_unaligned_access:
cd30bcef 17221 READ_ULEB (val, p, end);
2dc8dd17
JW
17222 switch (val)
17223 {
17224 case 0:
17225 printf (_("No unaligned access\n"));
17226 break;
17227 case 1:
17228 printf (_("Unaligned access\n"));
17229 break;
17230 }
17231 break;
17232 case Tag_RISCV_stack_align:
cd30bcef
AM
17233 READ_ULEB (val, p, end);
17234 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17235 break;
17236 case Tag_RISCV_arch:
17237 p = display_tag_value (-1, p, end);
17238 break;
17239 default:
17240 return display_tag_value (tag, p, end);
17241 }
17242
17243 return p;
17244}
17245
0861f561
CQ
17246static unsigned char *
17247display_csky_attribute (unsigned char * p,
17248 const unsigned char * const end)
17249{
17250 unsigned int tag;
17251 unsigned int val;
17252 READ_ULEB (tag, p, end);
17253
17254 if (tag >= Tag_CSKY_MAX)
17255 {
17256 return display_tag_value (-1, p, end);
17257 }
17258
17259 switch (tag)
17260 {
17261 case Tag_CSKY_ARCH_NAME:
17262 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17263 return display_tag_value (-1, p, end);
17264 case Tag_CSKY_CPU_NAME:
17265 printf (" Tag_CSKY_CPU_NAME:\t\t");
17266 return display_tag_value (-1, p, end);
17267
17268 case Tag_CSKY_ISA_FLAGS:
17269 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17270 return display_tag_value (0, p, end);
17271 case Tag_CSKY_ISA_EXT_FLAGS:
17272 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17273 return display_tag_value (0, p, end);
17274
17275 case Tag_CSKY_DSP_VERSION:
17276 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17277 READ_ULEB (val, p, end);
17278 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17279 printf ("DSP Extension\n");
17280 else if (val == VAL_CSKY_DSP_VERSION_2)
17281 printf ("DSP 2.0\n");
17282 break;
17283
17284 case Tag_CSKY_VDSP_VERSION:
17285 printf (" Tag_CSKY_VDSP_VERSION:\t");
17286 READ_ULEB (val, p, end);
17287 printf ("VDSP Version %d\n", val);
17288 break;
17289
17290 case Tag_CSKY_FPU_VERSION:
17291 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17292 READ_ULEB (val, p, end);
17293 if (val == VAL_CSKY_FPU_VERSION_1)
17294 printf ("ABIV1 FPU Version 1\n");
17295 else if (val == VAL_CSKY_FPU_VERSION_2)
17296 printf ("FPU Version 2\n");
17297 break;
17298
17299 case Tag_CSKY_FPU_ABI:
17300 printf (" Tag_CSKY_FPU_ABI:\t\t");
17301 READ_ULEB (val, p, end);
17302 if (val == VAL_CSKY_FPU_ABI_HARD)
17303 printf ("Hard\n");
17304 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17305 printf ("SoftFP\n");
17306 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17307 printf ("Soft\n");
17308 break;
17309 case Tag_CSKY_FPU_ROUNDING:
17310 READ_ULEB (val, p, end);
f253158f
NC
17311 if (val == 1)
17312 {
17313 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17314 printf ("Needed\n");
17315 }
0861f561
CQ
17316 break;
17317 case Tag_CSKY_FPU_DENORMAL:
17318 READ_ULEB (val, p, end);
f253158f
NC
17319 if (val == 1)
17320 {
17321 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17322 printf ("Needed\n");
17323 }
0861f561
CQ
17324 break;
17325 case Tag_CSKY_FPU_Exception:
17326 READ_ULEB (val, p, end);
f253158f
NC
17327 if (val == 1)
17328 {
17329 printf (" Tag_CSKY_FPU_Exception:\t");
17330 printf ("Needed\n");
17331 }
0861f561
CQ
17332 break;
17333 case Tag_CSKY_FPU_NUMBER_MODULE:
17334 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17335 return display_tag_value (-1, p, end);
17336 case Tag_CSKY_FPU_HARDFP:
17337 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17338 READ_ULEB (val, p, end);
17339 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17340 printf (" Half");
17341 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17342 printf (" Single");
17343 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17344 printf (" Double");
17345 printf ("\n");
17346 break;
17347 default:
17348 return display_tag_value (tag, p, end);
17349 }
17350 return p;
17351}
17352
015dc7e1 17353static bool
dda8d76d 17354process_attributes (Filedata * filedata,
60bca95a 17355 const char * public_name,
104d59d1 17356 unsigned int proc_type,
f6f0e17b 17357 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17358 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17359{
2cf0635d 17360 Elf_Internal_Shdr * sect;
11c1ff18 17361 unsigned i;
015dc7e1 17362 bool res = true;
11c1ff18
PB
17363
17364 /* Find the section header so that we get the size. */
dda8d76d
NC
17365 for (i = 0, sect = filedata->section_headers;
17366 i < filedata->file_header.e_shnum;
11c1ff18
PB
17367 i++, sect++)
17368 {
071436c6
NC
17369 unsigned char * contents;
17370 unsigned char * p;
17371
104d59d1 17372 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17373 continue;
17374
dda8d76d 17375 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17376 sect->sh_size, _("attributes"));
60bca95a 17377 if (contents == NULL)
32ec8896 17378 {
015dc7e1 17379 res = false;
32ec8896
NC
17380 continue;
17381 }
60bca95a 17382
11c1ff18 17383 p = contents;
60abdbed
NC
17384 /* The first character is the version of the attributes.
17385 Currently only version 1, (aka 'A') is recognised here. */
17386 if (*p != 'A')
32ec8896
NC
17387 {
17388 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17389 res = false;
32ec8896 17390 }
60abdbed 17391 else
11c1ff18 17392 {
071436c6
NC
17393 bfd_vma section_len;
17394
17395 section_len = sect->sh_size - 1;
11c1ff18 17396 p++;
60bca95a 17397
071436c6 17398 while (section_len > 0)
11c1ff18 17399 {
071436c6 17400 bfd_vma attr_len;
e9847026 17401 unsigned int namelen;
015dc7e1
AM
17402 bool public_section;
17403 bool gnu_section;
11c1ff18 17404
071436c6 17405 if (section_len <= 4)
e0a31db1
NC
17406 {
17407 error (_("Tag section ends prematurely\n"));
015dc7e1 17408 res = false;
e0a31db1
NC
17409 break;
17410 }
071436c6 17411 attr_len = byte_get (p, 4);
11c1ff18 17412 p += 4;
60bca95a 17413
071436c6 17414 if (attr_len > section_len)
11c1ff18 17415 {
071436c6
NC
17416 error (_("Bad attribute length (%u > %u)\n"),
17417 (unsigned) attr_len, (unsigned) section_len);
17418 attr_len = section_len;
015dc7e1 17419 res = false;
11c1ff18 17420 }
74e1a04b 17421 /* PR 17531: file: 001-101425-0.004 */
071436c6 17422 else if (attr_len < 5)
74e1a04b 17423 {
071436c6 17424 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17425 res = false;
74e1a04b
NC
17426 break;
17427 }
e9847026 17428
071436c6
NC
17429 section_len -= attr_len;
17430 attr_len -= 4;
17431
17432 namelen = strnlen ((char *) p, attr_len) + 1;
17433 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17434 {
17435 error (_("Corrupt attribute section name\n"));
015dc7e1 17436 res = false;
e9847026
NC
17437 break;
17438 }
17439
071436c6
NC
17440 printf (_("Attribute Section: "));
17441 print_symbol (INT_MAX, (const char *) p);
17442 putchar ('\n');
60bca95a
NC
17443
17444 if (public_name && streq ((char *) p, public_name))
015dc7e1 17445 public_section = true;
11c1ff18 17446 else
015dc7e1 17447 public_section = false;
60bca95a
NC
17448
17449 if (streq ((char *) p, "gnu"))
015dc7e1 17450 gnu_section = true;
104d59d1 17451 else
015dc7e1 17452 gnu_section = false;
60bca95a 17453
11c1ff18 17454 p += namelen;
071436c6 17455 attr_len -= namelen;
e0a31db1 17456
071436c6 17457 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17458 {
e0a31db1 17459 int tag;
cd30bcef 17460 unsigned int val;
11c1ff18 17461 bfd_vma size;
071436c6 17462 unsigned char * end;
60bca95a 17463
e0a31db1 17464 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17465 if (attr_len < 6)
e0a31db1
NC
17466 {
17467 error (_("Unused bytes at end of section\n"));
015dc7e1 17468 res = false;
e0a31db1
NC
17469 section_len = 0;
17470 break;
17471 }
17472
17473 tag = *(p++);
11c1ff18 17474 size = byte_get (p, 4);
071436c6 17475 if (size > attr_len)
11c1ff18 17476 {
e9847026 17477 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17478 (unsigned) size, (unsigned) attr_len);
015dc7e1 17479 res = false;
071436c6 17480 size = attr_len;
11c1ff18 17481 }
e0a31db1
NC
17482 /* PR binutils/17531: Safe handling of corrupt files. */
17483 if (size < 6)
17484 {
17485 error (_("Bad subsection length (%u < 6)\n"),
17486 (unsigned) size);
015dc7e1 17487 res = false;
e0a31db1
NC
17488 section_len = 0;
17489 break;
17490 }
60bca95a 17491
071436c6 17492 attr_len -= size;
11c1ff18 17493 end = p + size - 1;
071436c6 17494 assert (end <= contents + sect->sh_size);
11c1ff18 17495 p += 4;
60bca95a 17496
11c1ff18
PB
17497 switch (tag)
17498 {
17499 case 1:
2b692964 17500 printf (_("File Attributes\n"));
11c1ff18
PB
17501 break;
17502 case 2:
2b692964 17503 printf (_("Section Attributes:"));
11c1ff18
PB
17504 goto do_numlist;
17505 case 3:
2b692964 17506 printf (_("Symbol Attributes:"));
1a0670f3 17507 /* Fall through. */
11c1ff18
PB
17508 do_numlist:
17509 for (;;)
17510 {
cd30bcef 17511 READ_ULEB (val, p, end);
11c1ff18
PB
17512 if (val == 0)
17513 break;
17514 printf (" %d", val);
17515 }
17516 printf ("\n");
17517 break;
17518 default:
2b692964 17519 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17520 public_section = false;
11c1ff18
PB
17521 break;
17522 }
60bca95a 17523
071436c6 17524 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17525 {
17526 while (p < end)
f6f0e17b 17527 p = display_pub_attribute (p, end);
60abdbed 17528 assert (p == end);
104d59d1 17529 }
071436c6 17530 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17531 {
17532 while (p < end)
17533 p = display_gnu_attribute (p,
f6f0e17b
NC
17534 display_proc_gnu_attribute,
17535 end);
60abdbed 17536 assert (p == end);
11c1ff18 17537 }
071436c6 17538 else if (p < end)
11c1ff18 17539 {
071436c6 17540 printf (_(" Unknown attribute:\n"));
f6f0e17b 17541 display_raw_attribute (p, end);
11c1ff18
PB
17542 p = end;
17543 }
071436c6
NC
17544 else
17545 attr_len = 0;
11c1ff18
PB
17546 }
17547 }
17548 }
d70c5fc7 17549
60bca95a 17550 free (contents);
11c1ff18 17551 }
32ec8896
NC
17552
17553 return res;
11c1ff18
PB
17554}
17555
ccb4c951
RS
17556/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17557 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17558 and return the VMA of the next entry, or -1 if there was a problem.
17559 Does not read from DATA_END or beyond. */
ccb4c951
RS
17560
17561static bfd_vma
82b1b41b
NC
17562print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17563 unsigned char * data_end)
ccb4c951
RS
17564{
17565 printf (" ");
17566 print_vma (addr, LONG_HEX);
17567 printf (" ");
17568 if (addr < pltgot + 0xfff0)
17569 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17570 else
17571 printf ("%10s", "");
17572 printf (" ");
17573 if (data == NULL)
2b692964 17574 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17575 else
17576 {
17577 bfd_vma entry;
82b1b41b 17578 unsigned char * from = data + addr - pltgot;
ccb4c951 17579
82b1b41b
NC
17580 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17581 {
17582 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17583 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17584 return (bfd_vma) -1;
17585 }
17586 else
17587 {
17588 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17589 print_vma (entry, LONG_HEX);
17590 }
ccb4c951
RS
17591 }
17592 return addr + (is_32bit_elf ? 4 : 8);
17593}
17594
861fb55a
DJ
17595/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17596 PLTGOT. Print the Address and Initial fields of an entry at VMA
17597 ADDR and return the VMA of the next entry. */
17598
17599static bfd_vma
2cf0635d 17600print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17601{
17602 printf (" ");
17603 print_vma (addr, LONG_HEX);
17604 printf (" ");
17605 if (data == NULL)
2b692964 17606 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17607 else
17608 {
17609 bfd_vma entry;
17610
17611 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17612 print_vma (entry, LONG_HEX);
17613 }
17614 return addr + (is_32bit_elf ? 4 : 8);
17615}
17616
351cdf24
MF
17617static void
17618print_mips_ases (unsigned int mask)
17619{
17620 if (mask & AFL_ASE_DSP)
17621 fputs ("\n\tDSP ASE", stdout);
17622 if (mask & AFL_ASE_DSPR2)
17623 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17624 if (mask & AFL_ASE_DSPR3)
17625 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17626 if (mask & AFL_ASE_EVA)
17627 fputs ("\n\tEnhanced VA Scheme", stdout);
17628 if (mask & AFL_ASE_MCU)
17629 fputs ("\n\tMCU (MicroController) ASE", stdout);
17630 if (mask & AFL_ASE_MDMX)
17631 fputs ("\n\tMDMX ASE", stdout);
17632 if (mask & AFL_ASE_MIPS3D)
17633 fputs ("\n\tMIPS-3D ASE", stdout);
17634 if (mask & AFL_ASE_MT)
17635 fputs ("\n\tMT ASE", stdout);
17636 if (mask & AFL_ASE_SMARTMIPS)
17637 fputs ("\n\tSmartMIPS ASE", stdout);
17638 if (mask & AFL_ASE_VIRT)
17639 fputs ("\n\tVZ ASE", stdout);
17640 if (mask & AFL_ASE_MSA)
17641 fputs ("\n\tMSA ASE", stdout);
17642 if (mask & AFL_ASE_MIPS16)
17643 fputs ("\n\tMIPS16 ASE", stdout);
17644 if (mask & AFL_ASE_MICROMIPS)
17645 fputs ("\n\tMICROMIPS ASE", stdout);
17646 if (mask & AFL_ASE_XPA)
17647 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17648 if (mask & AFL_ASE_MIPS16E2)
17649 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17650 if (mask & AFL_ASE_CRC)
17651 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17652 if (mask & AFL_ASE_GINV)
17653 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17654 if (mask & AFL_ASE_LOONGSON_MMI)
17655 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17656 if (mask & AFL_ASE_LOONGSON_CAM)
17657 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17658 if (mask & AFL_ASE_LOONGSON_EXT)
17659 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17660 if (mask & AFL_ASE_LOONGSON_EXT2)
17661 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17662 if (mask == 0)
17663 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17664 else if ((mask & ~AFL_ASE_MASK) != 0)
17665 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17666}
17667
17668static void
17669print_mips_isa_ext (unsigned int isa_ext)
17670{
17671 switch (isa_ext)
17672 {
17673 case 0:
17674 fputs (_("None"), stdout);
17675 break;
17676 case AFL_EXT_XLR:
17677 fputs ("RMI XLR", stdout);
17678 break;
2c629856
N
17679 case AFL_EXT_OCTEON3:
17680 fputs ("Cavium Networks Octeon3", stdout);
17681 break;
351cdf24
MF
17682 case AFL_EXT_OCTEON2:
17683 fputs ("Cavium Networks Octeon2", stdout);
17684 break;
17685 case AFL_EXT_OCTEONP:
17686 fputs ("Cavium Networks OcteonP", stdout);
17687 break;
351cdf24
MF
17688 case AFL_EXT_OCTEON:
17689 fputs ("Cavium Networks Octeon", stdout);
17690 break;
17691 case AFL_EXT_5900:
17692 fputs ("Toshiba R5900", stdout);
17693 break;
17694 case AFL_EXT_4650:
17695 fputs ("MIPS R4650", stdout);
17696 break;
17697 case AFL_EXT_4010:
17698 fputs ("LSI R4010", stdout);
17699 break;
17700 case AFL_EXT_4100:
17701 fputs ("NEC VR4100", stdout);
17702 break;
17703 case AFL_EXT_3900:
17704 fputs ("Toshiba R3900", stdout);
17705 break;
17706 case AFL_EXT_10000:
17707 fputs ("MIPS R10000", stdout);
17708 break;
17709 case AFL_EXT_SB1:
17710 fputs ("Broadcom SB-1", stdout);
17711 break;
17712 case AFL_EXT_4111:
17713 fputs ("NEC VR4111/VR4181", stdout);
17714 break;
17715 case AFL_EXT_4120:
17716 fputs ("NEC VR4120", stdout);
17717 break;
17718 case AFL_EXT_5400:
17719 fputs ("NEC VR5400", stdout);
17720 break;
17721 case AFL_EXT_5500:
17722 fputs ("NEC VR5500", stdout);
17723 break;
17724 case AFL_EXT_LOONGSON_2E:
17725 fputs ("ST Microelectronics Loongson 2E", stdout);
17726 break;
17727 case AFL_EXT_LOONGSON_2F:
17728 fputs ("ST Microelectronics Loongson 2F", stdout);
17729 break;
38bf472a
MR
17730 case AFL_EXT_INTERAPTIV_MR2:
17731 fputs ("Imagination interAptiv MR2", stdout);
17732 break;
351cdf24 17733 default:
00ac7aa0 17734 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17735 }
17736}
17737
32ec8896 17738static signed int
351cdf24
MF
17739get_mips_reg_size (int reg_size)
17740{
17741 return (reg_size == AFL_REG_NONE) ? 0
17742 : (reg_size == AFL_REG_32) ? 32
17743 : (reg_size == AFL_REG_64) ? 64
17744 : (reg_size == AFL_REG_128) ? 128
17745 : -1;
17746}
17747
015dc7e1 17748static bool
dda8d76d 17749process_mips_specific (Filedata * filedata)
5b18a4bc 17750{
2cf0635d 17751 Elf_Internal_Dyn * entry;
351cdf24 17752 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17753 size_t liblist_offset = 0;
17754 size_t liblistno = 0;
17755 size_t conflictsno = 0;
17756 size_t options_offset = 0;
17757 size_t conflicts_offset = 0;
861fb55a
DJ
17758 size_t pltrelsz = 0;
17759 size_t pltrel = 0;
ccb4c951 17760 bfd_vma pltgot = 0;
861fb55a
DJ
17761 bfd_vma mips_pltgot = 0;
17762 bfd_vma jmprel = 0;
ccb4c951
RS
17763 bfd_vma local_gotno = 0;
17764 bfd_vma gotsym = 0;
17765 bfd_vma symtabno = 0;
015dc7e1 17766 bool res = true;
103f02d3 17767
dda8d76d 17768 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17769 display_mips_gnu_attribute))
015dc7e1 17770 res = false;
2cf19d5c 17771
dda8d76d 17772 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17773
17774 if (sect != NULL)
17775 {
17776 Elf_External_ABIFlags_v0 *abiflags_ext;
17777 Elf_Internal_ABIFlags_v0 abiflags_in;
17778
17779 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17780 {
17781 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17782 res = false;
32ec8896 17783 }
351cdf24
MF
17784 else
17785 {
dda8d76d 17786 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17787 sect->sh_size, _("MIPS ABI Flags section"));
17788 if (abiflags_ext)
17789 {
17790 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17791 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17792 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17793 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17794 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17795 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17796 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17797 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17798 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17799 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17800 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17801
17802 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17803 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17804 if (abiflags_in.isa_rev > 1)
17805 printf ("r%d", abiflags_in.isa_rev);
17806 printf ("\nGPR size: %d",
17807 get_mips_reg_size (abiflags_in.gpr_size));
17808 printf ("\nCPR1 size: %d",
17809 get_mips_reg_size (abiflags_in.cpr1_size));
17810 printf ("\nCPR2 size: %d",
17811 get_mips_reg_size (abiflags_in.cpr2_size));
17812 fputs ("\nFP ABI: ", stdout);
17813 print_mips_fp_abi_value (abiflags_in.fp_abi);
17814 fputs ("ISA Extension: ", stdout);
17815 print_mips_isa_ext (abiflags_in.isa_ext);
17816 fputs ("\nASEs:", stdout);
17817 print_mips_ases (abiflags_in.ases);
17818 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17819 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17820 fputc ('\n', stdout);
17821 free (abiflags_ext);
17822 }
17823 }
17824 }
17825
19e6b90e 17826 /* We have a lot of special sections. Thanks SGI! */
978c4450 17827 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17828 {
17829 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17830 sect = find_section (filedata, ".got");
bbdd9a68
MR
17831 if (sect != NULL)
17832 {
17833 unsigned char *data_end;
17834 unsigned char *data;
17835 bfd_vma ent, end;
17836 int addr_size;
17837
17838 pltgot = sect->sh_addr;
17839
17840 ent = pltgot;
17841 addr_size = (is_32bit_elf ? 4 : 8);
17842 end = pltgot + sect->sh_size;
17843
dda8d76d 17844 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17845 end - pltgot, 1,
17846 _("Global Offset Table data"));
17847 /* PR 12855: Null data is handled gracefully throughout. */
17848 data_end = data + (end - pltgot);
17849
17850 printf (_("\nStatic GOT:\n"));
17851 printf (_(" Canonical gp value: "));
17852 print_vma (ent + 0x7ff0, LONG_HEX);
17853 printf ("\n\n");
17854
17855 /* In a dynamic binary GOT[0] is reserved for the dynamic
17856 loader to store the lazy resolver pointer, however in
17857 a static binary it may well have been omitted and GOT
17858 reduced to a table of addresses.
17859 PR 21344: Check for the entry being fully available
17860 before fetching it. */
17861 if (data
17862 && data + ent - pltgot + addr_size <= data_end
17863 && byte_get (data + ent - pltgot, addr_size) == 0)
17864 {
17865 printf (_(" Reserved entries:\n"));
17866 printf (_(" %*s %10s %*s\n"),
17867 addr_size * 2, _("Address"), _("Access"),
17868 addr_size * 2, _("Value"));
17869 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17870 printf ("\n");
17871 if (ent == (bfd_vma) -1)
17872 goto sgot_print_fail;
17873
17874 /* Check for the MSB of GOT[1] being set, identifying a
17875 GNU object. This entry will be used by some runtime
17876 loaders, to store the module pointer. Otherwise this
17877 is an ordinary local entry.
17878 PR 21344: Check for the entry being fully available
17879 before fetching it. */
17880 if (data
17881 && data + ent - pltgot + addr_size <= data_end
17882 && (byte_get (data + ent - pltgot, addr_size)
17883 >> (addr_size * 8 - 1)) != 0)
17884 {
17885 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17886 printf ("\n");
17887 if (ent == (bfd_vma) -1)
17888 goto sgot_print_fail;
17889 }
17890 printf ("\n");
17891 }
17892
f17e9d8a 17893 if (data != NULL && ent < end)
bbdd9a68
MR
17894 {
17895 printf (_(" Local entries:\n"));
17896 printf (" %*s %10s %*s\n",
17897 addr_size * 2, _("Address"), _("Access"),
17898 addr_size * 2, _("Value"));
17899 while (ent < end)
17900 {
17901 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17902 printf ("\n");
17903 if (ent == (bfd_vma) -1)
17904 goto sgot_print_fail;
17905 }
17906 printf ("\n");
17907 }
17908
17909 sgot_print_fail:
9db70fc3 17910 free (data);
bbdd9a68
MR
17911 }
17912 return res;
17913 }
252b5132 17914
978c4450 17915 for (entry = filedata->dynamic_section;
071436c6 17916 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17917 (entry < filedata->dynamic_section + filedata->dynamic_nent
17918 && entry->d_tag != DT_NULL);
071436c6 17919 ++entry)
252b5132
RH
17920 switch (entry->d_tag)
17921 {
17922 case DT_MIPS_LIBLIST:
d93f0186 17923 liblist_offset
dda8d76d 17924 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17925 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17926 break;
17927 case DT_MIPS_LIBLISTNO:
17928 liblistno = entry->d_un.d_val;
17929 break;
17930 case DT_MIPS_OPTIONS:
dda8d76d 17931 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17932 break;
17933 case DT_MIPS_CONFLICT:
d93f0186 17934 conflicts_offset
dda8d76d 17935 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17936 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17937 break;
17938 case DT_MIPS_CONFLICTNO:
17939 conflictsno = entry->d_un.d_val;
17940 break;
ccb4c951 17941 case DT_PLTGOT:
861fb55a
DJ
17942 pltgot = entry->d_un.d_ptr;
17943 break;
ccb4c951
RS
17944 case DT_MIPS_LOCAL_GOTNO:
17945 local_gotno = entry->d_un.d_val;
17946 break;
17947 case DT_MIPS_GOTSYM:
17948 gotsym = entry->d_un.d_val;
17949 break;
17950 case DT_MIPS_SYMTABNO:
17951 symtabno = entry->d_un.d_val;
17952 break;
861fb55a
DJ
17953 case DT_MIPS_PLTGOT:
17954 mips_pltgot = entry->d_un.d_ptr;
17955 break;
17956 case DT_PLTREL:
17957 pltrel = entry->d_un.d_val;
17958 break;
17959 case DT_PLTRELSZ:
17960 pltrelsz = entry->d_un.d_val;
17961 break;
17962 case DT_JMPREL:
17963 jmprel = entry->d_un.d_ptr;
17964 break;
252b5132
RH
17965 default:
17966 break;
17967 }
17968
17969 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17970 {
2cf0635d 17971 Elf32_External_Lib * elib;
252b5132
RH
17972 size_t cnt;
17973
dda8d76d 17974 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17975 sizeof (Elf32_External_Lib),
17976 liblistno,
17977 _("liblist section data"));
a6e9f9df 17978 if (elib)
252b5132 17979 {
d3a49aa8
AM
17980 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17981 "\nSection '.liblist' contains %lu entries:\n",
17982 (unsigned long) liblistno),
a6e9f9df 17983 (unsigned long) liblistno);
2b692964 17984 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17985 stdout);
17986
17987 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17988 {
a6e9f9df 17989 Elf32_Lib liblist;
91d6fa6a 17990 time_t atime;
d5b07ef4 17991 char timebuf[128];
2cf0635d 17992 struct tm * tmp;
a6e9f9df
AM
17993
17994 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17995 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17996 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17997 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17998 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17999
91d6fa6a 18000 tmp = gmtime (&atime);
e9e44622
JJ
18001 snprintf (timebuf, sizeof (timebuf),
18002 "%04u-%02u-%02uT%02u:%02u:%02u",
18003 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18004 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 18005
31104126 18006 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
18007 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
18008 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 18009 else
2b692964 18010 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
18011 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
18012 liblist.l_version);
a6e9f9df
AM
18013
18014 if (liblist.l_flags == 0)
2b692964 18015 puts (_(" NONE"));
a6e9f9df
AM
18016 else
18017 {
18018 static const struct
252b5132 18019 {
2cf0635d 18020 const char * name;
a6e9f9df 18021 int bit;
252b5132 18022 }
a6e9f9df
AM
18023 l_flags_vals[] =
18024 {
18025 { " EXACT_MATCH", LL_EXACT_MATCH },
18026 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18027 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18028 { " EXPORTS", LL_EXPORTS },
18029 { " DELAY_LOAD", LL_DELAY_LOAD },
18030 { " DELTA", LL_DELTA }
18031 };
18032 int flags = liblist.l_flags;
18033 size_t fcnt;
18034
60bca95a 18035 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18036 if ((flags & l_flags_vals[fcnt].bit) != 0)
18037 {
18038 fputs (l_flags_vals[fcnt].name, stdout);
18039 flags ^= l_flags_vals[fcnt].bit;
18040 }
18041 if (flags != 0)
18042 printf (" %#x", (unsigned int) flags);
252b5132 18043
a6e9f9df
AM
18044 puts ("");
18045 }
252b5132 18046 }
252b5132 18047
a6e9f9df
AM
18048 free (elib);
18049 }
32ec8896 18050 else
015dc7e1 18051 res = false;
252b5132
RH
18052 }
18053
18054 if (options_offset != 0)
18055 {
2cf0635d 18056 Elf_External_Options * eopt;
252b5132
RH
18057 size_t offset;
18058 int cnt;
dda8d76d 18059 sect = filedata->section_headers;
252b5132
RH
18060
18061 /* Find the section header so that we get the size. */
dda8d76d 18062 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18063 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18064 if (sect == NULL)
18065 {
18066 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18067 return false;
071436c6 18068 }
7fc0c668
NC
18069 /* PR 24243 */
18070 if (sect->sh_size < sizeof (* eopt))
18071 {
18072 error (_("The MIPS options section is too small.\n"));
015dc7e1 18073 return false;
7fc0c668 18074 }
252b5132 18075
dda8d76d 18076 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18077 sect->sh_size, _("options"));
a6e9f9df 18078 if (eopt)
252b5132 18079 {
fd17d1e6 18080 Elf_Internal_Options option;
76da6bbe 18081
a6e9f9df 18082 offset = cnt = 0;
82b1b41b 18083 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18084 {
2cf0635d 18085 Elf_External_Options * eoption;
fd17d1e6 18086 unsigned int optsize;
252b5132 18087
a6e9f9df 18088 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18089
fd17d1e6 18090 optsize = BYTE_GET (eoption->size);
76da6bbe 18091
82b1b41b 18092 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18093 if (optsize < sizeof (* eopt)
18094 || optsize > sect->sh_size - offset)
82b1b41b 18095 {
645f43a8 18096 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18097 optsize);
645f43a8 18098 free (eopt);
015dc7e1 18099 return false;
82b1b41b 18100 }
fd17d1e6 18101 offset += optsize;
a6e9f9df
AM
18102 ++cnt;
18103 }
252b5132 18104
d3a49aa8
AM
18105 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18106 "\nSection '%s' contains %d entries:\n",
18107 cnt),
dda8d76d 18108 printable_section_name (filedata, sect), cnt);
76da6bbe 18109
82b1b41b 18110 offset = 0;
a6e9f9df 18111 while (cnt-- > 0)
252b5132 18112 {
a6e9f9df 18113 size_t len;
fd17d1e6
AM
18114 Elf_External_Options * eoption;
18115
18116 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18117
18118 option.kind = BYTE_GET (eoption->kind);
18119 option.size = BYTE_GET (eoption->size);
18120 option.section = BYTE_GET (eoption->section);
18121 option.info = BYTE_GET (eoption->info);
a6e9f9df 18122
fd17d1e6 18123 switch (option.kind)
252b5132 18124 {
a6e9f9df
AM
18125 case ODK_NULL:
18126 /* This shouldn't happen. */
d0c4e780 18127 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18128 option.section, option.info);
a6e9f9df 18129 break;
2e6be59c 18130
a6e9f9df
AM
18131 case ODK_REGINFO:
18132 printf (" REGINFO ");
dda8d76d 18133 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18134 {
2cf0635d 18135 Elf32_External_RegInfo * ereg;
b34976b6 18136 Elf32_RegInfo reginfo;
a6e9f9df 18137
2e6be59c 18138 /* 32bit form. */
fd17d1e6
AM
18139 if (option.size < (sizeof (Elf_External_Options)
18140 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18141 {
18142 printf (_("<corrupt>\n"));
18143 error (_("Truncated MIPS REGINFO option\n"));
18144 cnt = 0;
18145 break;
18146 }
18147
fd17d1e6 18148 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18149
a6e9f9df
AM
18150 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18151 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18152 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18153 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18154 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18155 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18156
d0c4e780
AM
18157 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18158 reginfo.ri_gprmask, reginfo.ri_gp_value);
18159 printf (" "
18160 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18161 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18162 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18163 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18164 }
18165 else
18166 {
18167 /* 64 bit form. */
2cf0635d 18168 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18169 Elf64_Internal_RegInfo reginfo;
18170
fd17d1e6
AM
18171 if (option.size < (sizeof (Elf_External_Options)
18172 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18173 {
18174 printf (_("<corrupt>\n"));
18175 error (_("Truncated MIPS REGINFO option\n"));
18176 cnt = 0;
18177 break;
18178 }
18179
fd17d1e6 18180 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18181 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18182 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18183 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18184 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18185 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18186 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18187
d0c4e780
AM
18188 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18189 reginfo.ri_gprmask, reginfo.ri_gp_value);
18190 printf (" "
18191 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18192 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18193 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18194 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18195 }
fd17d1e6 18196 offset += option.size;
a6e9f9df 18197 continue;
2e6be59c 18198
a6e9f9df
AM
18199 case ODK_EXCEPTIONS:
18200 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18201 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18202 fputs (") fpe_max(", stdout);
fd17d1e6 18203 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18204 fputs (")", stdout);
18205
fd17d1e6 18206 if (option.info & OEX_PAGE0)
a6e9f9df 18207 fputs (" PAGE0", stdout);
fd17d1e6 18208 if (option.info & OEX_SMM)
a6e9f9df 18209 fputs (" SMM", stdout);
fd17d1e6 18210 if (option.info & OEX_FPDBUG)
a6e9f9df 18211 fputs (" FPDBUG", stdout);
fd17d1e6 18212 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18213 fputs (" DISMISS", stdout);
18214 break;
2e6be59c 18215
a6e9f9df
AM
18216 case ODK_PAD:
18217 fputs (" PAD ", stdout);
fd17d1e6 18218 if (option.info & OPAD_PREFIX)
a6e9f9df 18219 fputs (" PREFIX", stdout);
fd17d1e6 18220 if (option.info & OPAD_POSTFIX)
a6e9f9df 18221 fputs (" POSTFIX", stdout);
fd17d1e6 18222 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18223 fputs (" SYMBOL", stdout);
18224 break;
2e6be59c 18225
a6e9f9df
AM
18226 case ODK_HWPATCH:
18227 fputs (" HWPATCH ", stdout);
fd17d1e6 18228 if (option.info & OHW_R4KEOP)
a6e9f9df 18229 fputs (" R4KEOP", stdout);
fd17d1e6 18230 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18231 fputs (" R8KPFETCH", stdout);
fd17d1e6 18232 if (option.info & OHW_R5KEOP)
a6e9f9df 18233 fputs (" R5KEOP", stdout);
fd17d1e6 18234 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18235 fputs (" R5KCVTL", stdout);
18236 break;
2e6be59c 18237
a6e9f9df
AM
18238 case ODK_FILL:
18239 fputs (" FILL ", stdout);
18240 /* XXX Print content of info word? */
18241 break;
2e6be59c 18242
a6e9f9df
AM
18243 case ODK_TAGS:
18244 fputs (" TAGS ", stdout);
18245 /* XXX Print content of info word? */
18246 break;
2e6be59c 18247
a6e9f9df
AM
18248 case ODK_HWAND:
18249 fputs (" HWAND ", stdout);
fd17d1e6 18250 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18251 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18252 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18253 fputs (" R4KEOP_CLEAN", stdout);
18254 break;
2e6be59c 18255
a6e9f9df
AM
18256 case ODK_HWOR:
18257 fputs (" HWOR ", stdout);
fd17d1e6 18258 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18259 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18260 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18261 fputs (" R4KEOP_CLEAN", stdout);
18262 break;
2e6be59c 18263
a6e9f9df 18264 case ODK_GP_GROUP:
d0c4e780 18265 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18266 option.info & OGP_GROUP,
18267 (option.info & OGP_SELF) >> 16);
a6e9f9df 18268 break;
2e6be59c 18269
a6e9f9df 18270 case ODK_IDENT:
d0c4e780 18271 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18272 option.info & OGP_GROUP,
18273 (option.info & OGP_SELF) >> 16);
a6e9f9df 18274 break;
2e6be59c 18275
a6e9f9df
AM
18276 default:
18277 /* This shouldn't happen. */
d0c4e780 18278 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18279 option.kind, option.section, option.info);
a6e9f9df 18280 break;
252b5132 18281 }
a6e9f9df 18282
2cf0635d 18283 len = sizeof (* eopt);
fd17d1e6 18284 while (len < option.size)
82b1b41b 18285 {
fd17d1e6 18286 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18287
82b1b41b
NC
18288 if (ISPRINT (datum))
18289 printf ("%c", datum);
18290 else
18291 printf ("\\%03o", datum);
18292 len ++;
18293 }
a6e9f9df 18294 fputs ("\n", stdout);
82b1b41b 18295
fd17d1e6 18296 offset += option.size;
252b5132 18297 }
a6e9f9df 18298 free (eopt);
252b5132 18299 }
32ec8896 18300 else
015dc7e1 18301 res = false;
252b5132
RH
18302 }
18303
18304 if (conflicts_offset != 0 && conflictsno != 0)
18305 {
2cf0635d 18306 Elf32_Conflict * iconf;
252b5132
RH
18307 size_t cnt;
18308
978c4450 18309 if (filedata->dynamic_symbols == NULL)
252b5132 18310 {
591a748a 18311 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18312 return false;
252b5132
RH
18313 }
18314
7296a62a
NC
18315 /* PR 21345 - print a slightly more helpful error message
18316 if we are sure that the cmalloc will fail. */
645f43a8 18317 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18318 {
18319 error (_("Overlarge number of conflicts detected: %lx\n"),
18320 (long) conflictsno);
015dc7e1 18321 return false;
7296a62a
NC
18322 }
18323
3f5e193b 18324 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18325 if (iconf == NULL)
18326 {
8b73c356 18327 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18328 return false;
252b5132
RH
18329 }
18330
9ea033b2 18331 if (is_32bit_elf)
252b5132 18332 {
2cf0635d 18333 Elf32_External_Conflict * econf32;
a6e9f9df 18334
3f5e193b 18335 econf32 = (Elf32_External_Conflict *)
95099889
AM
18336 get_data (NULL, filedata, conflicts_offset,
18337 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18338 if (!econf32)
5a814d6d
AM
18339 {
18340 free (iconf);
015dc7e1 18341 return false;
5a814d6d 18342 }
252b5132
RH
18343
18344 for (cnt = 0; cnt < conflictsno; ++cnt)
18345 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18346
18347 free (econf32);
252b5132
RH
18348 }
18349 else
18350 {
2cf0635d 18351 Elf64_External_Conflict * econf64;
a6e9f9df 18352
3f5e193b 18353 econf64 = (Elf64_External_Conflict *)
95099889
AM
18354 get_data (NULL, filedata, conflicts_offset,
18355 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18356 if (!econf64)
5a814d6d
AM
18357 {
18358 free (iconf);
015dc7e1 18359 return false;
5a814d6d 18360 }
252b5132
RH
18361
18362 for (cnt = 0; cnt < conflictsno; ++cnt)
18363 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18364
18365 free (econf64);
252b5132
RH
18366 }
18367
d3a49aa8
AM
18368 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18369 "\nSection '.conflict' contains %lu entries:\n",
18370 (unsigned long) conflictsno),
c7e7ca54 18371 (unsigned long) conflictsno);
252b5132
RH
18372 puts (_(" Num: Index Value Name"));
18373
18374 for (cnt = 0; cnt < conflictsno; ++cnt)
18375 {
b34976b6 18376 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18377
978c4450 18378 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18379 printf (_("<corrupt symbol index>"));
d79b3d50 18380 else
e0a31db1
NC
18381 {
18382 Elf_Internal_Sym * psym;
18383
978c4450 18384 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18385 print_vma (psym->st_value, FULL_HEX);
18386 putchar (' ');
978c4450
AM
18387 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18388 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18389 else
18390 printf (_("<corrupt: %14ld>"), psym->st_name);
18391 }
31104126 18392 putchar ('\n');
252b5132
RH
18393 }
18394
252b5132
RH
18395 free (iconf);
18396 }
18397
ccb4c951
RS
18398 if (pltgot != 0 && local_gotno != 0)
18399 {
91d6fa6a 18400 bfd_vma ent, local_end, global_end;
bbeee7ea 18401 size_t i, offset;
2cf0635d 18402 unsigned char * data;
82b1b41b 18403 unsigned char * data_end;
bbeee7ea 18404 int addr_size;
ccb4c951 18405
91d6fa6a 18406 ent = pltgot;
ccb4c951
RS
18407 addr_size = (is_32bit_elf ? 4 : 8);
18408 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18409
74e1a04b
NC
18410 /* PR binutils/17533 file: 012-111227-0.004 */
18411 if (symtabno < gotsym)
18412 {
18413 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18414 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18415 return false;
74e1a04b 18416 }
82b1b41b 18417
74e1a04b 18418 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18419 /* PR 17531: file: 54c91a34. */
18420 if (global_end < local_end)
18421 {
18422 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18423 return false;
82b1b41b 18424 }
948f632f 18425
dda8d76d
NC
18426 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18427 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18428 global_end - pltgot, 1,
18429 _("Global Offset Table data"));
919383ac 18430 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18431 data_end = data + (global_end - pltgot);
59245841 18432
ccb4c951
RS
18433 printf (_("\nPrimary GOT:\n"));
18434 printf (_(" Canonical gp value: "));
18435 print_vma (pltgot + 0x7ff0, LONG_HEX);
18436 printf ("\n\n");
18437
18438 printf (_(" Reserved entries:\n"));
18439 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18440 addr_size * 2, _("Address"), _("Access"),
18441 addr_size * 2, _("Initial"));
82b1b41b 18442 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18443 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18444 if (ent == (bfd_vma) -1)
18445 goto got_print_fail;
75ec1fdb 18446
c4ab9505
MR
18447 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18448 This entry will be used by some runtime loaders, to store the
18449 module pointer. Otherwise this is an ordinary local entry.
18450 PR 21344: Check for the entry being fully available before
18451 fetching it. */
18452 if (data
18453 && data + ent - pltgot + addr_size <= data_end
18454 && (byte_get (data + ent - pltgot, addr_size)
18455 >> (addr_size * 8 - 1)) != 0)
18456 {
18457 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18458 printf (_(" Module pointer (GNU extension)\n"));
18459 if (ent == (bfd_vma) -1)
18460 goto got_print_fail;
ccb4c951
RS
18461 }
18462 printf ("\n");
18463
f17e9d8a 18464 if (data != NULL && ent < local_end)
ccb4c951
RS
18465 {
18466 printf (_(" Local entries:\n"));
cc5914eb 18467 printf (" %*s %10s %*s\n",
2b692964
NC
18468 addr_size * 2, _("Address"), _("Access"),
18469 addr_size * 2, _("Initial"));
91d6fa6a 18470 while (ent < local_end)
ccb4c951 18471 {
82b1b41b 18472 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18473 printf ("\n");
82b1b41b
NC
18474 if (ent == (bfd_vma) -1)
18475 goto got_print_fail;
ccb4c951
RS
18476 }
18477 printf ("\n");
18478 }
18479
f17e9d8a 18480 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18481 {
18482 int sym_width;
18483
18484 printf (_(" Global entries:\n"));
cc5914eb 18485 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18486 addr_size * 2, _("Address"),
18487 _("Access"),
2b692964 18488 addr_size * 2, _("Initial"),
9cf03b7e
NC
18489 addr_size * 2, _("Sym.Val."),
18490 _("Type"),
18491 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18492 _("Ndx"), _("Name"));
0b4362b0 18493
ccb4c951 18494 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18495
ccb4c951
RS
18496 for (i = gotsym; i < symtabno; i++)
18497 {
82b1b41b 18498 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18499 printf (" ");
e0a31db1 18500
978c4450 18501 if (filedata->dynamic_symbols == NULL)
e0a31db1 18502 printf (_("<no dynamic symbols>"));
978c4450 18503 else if (i < filedata->num_dynamic_syms)
e0a31db1 18504 {
978c4450 18505 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18506
18507 print_vma (psym->st_value, LONG_HEX);
18508 printf (" %-7s %3s ",
dda8d76d
NC
18509 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18510 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18511
978c4450
AM
18512 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18513 print_symbol (sym_width,
18514 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18515 else
18516 printf (_("<corrupt: %14ld>"), psym->st_name);
18517 }
ccb4c951 18518 else
7fc5ac57
JBG
18519 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18520 (unsigned long) i);
e0a31db1 18521
ccb4c951 18522 printf ("\n");
82b1b41b
NC
18523 if (ent == (bfd_vma) -1)
18524 break;
ccb4c951
RS
18525 }
18526 printf ("\n");
18527 }
18528
82b1b41b 18529 got_print_fail:
9db70fc3 18530 free (data);
ccb4c951
RS
18531 }
18532
861fb55a
DJ
18533 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18534 {
91d6fa6a 18535 bfd_vma ent, end;
861fb55a
DJ
18536 size_t offset, rel_offset;
18537 unsigned long count, i;
2cf0635d 18538 unsigned char * data;
861fb55a 18539 int addr_size, sym_width;
2cf0635d 18540 Elf_Internal_Rela * rels;
861fb55a 18541
dda8d76d 18542 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18543 if (pltrel == DT_RELA)
18544 {
dda8d76d 18545 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18546 return false;
861fb55a
DJ
18547 }
18548 else
18549 {
dda8d76d 18550 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18551 return false;
861fb55a
DJ
18552 }
18553
91d6fa6a 18554 ent = mips_pltgot;
861fb55a
DJ
18555 addr_size = (is_32bit_elf ? 4 : 8);
18556 end = mips_pltgot + (2 + count) * addr_size;
18557
dda8d76d
NC
18558 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18559 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18560 1, _("Procedure Linkage Table data"));
59245841 18561 if (data == NULL)
288f0ba2
AM
18562 {
18563 free (rels);
015dc7e1 18564 return false;
288f0ba2 18565 }
59245841 18566
9cf03b7e 18567 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18568 printf (_(" Reserved entries:\n"));
18569 printf (_(" %*s %*s Purpose\n"),
2b692964 18570 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18571 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18572 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18573 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18574 printf (_(" Module pointer\n"));
861fb55a
DJ
18575 printf ("\n");
18576
18577 printf (_(" Entries:\n"));
cc5914eb 18578 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18579 addr_size * 2, _("Address"),
18580 addr_size * 2, _("Initial"),
18581 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18582 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18583 for (i = 0; i < count; i++)
18584 {
df97ab2a 18585 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18586
91d6fa6a 18587 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18588 printf (" ");
e0a31db1 18589
978c4450 18590 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18591 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18592 else
e0a31db1 18593 {
978c4450 18594 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18595
18596 print_vma (psym->st_value, LONG_HEX);
18597 printf (" %-7s %3s ",
dda8d76d
NC
18598 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18599 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18600 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18601 print_symbol (sym_width,
18602 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18603 else
18604 printf (_("<corrupt: %14ld>"), psym->st_name);
18605 }
861fb55a
DJ
18606 printf ("\n");
18607 }
18608 printf ("\n");
18609
9db70fc3 18610 free (data);
861fb55a
DJ
18611 free (rels);
18612 }
18613
32ec8896 18614 return res;
252b5132
RH
18615}
18616
015dc7e1 18617static bool
dda8d76d 18618process_nds32_specific (Filedata * filedata)
35c08157
KLC
18619{
18620 Elf_Internal_Shdr *sect = NULL;
18621
dda8d76d 18622 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18623 if (sect != NULL && sect->sh_size >= 4)
35c08157 18624 {
9c7b8e9b
AM
18625 unsigned char *buf;
18626 unsigned int flag;
35c08157
KLC
18627
18628 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18629 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18630 _("NDS32 elf flags section"));
35c08157 18631
9c7b8e9b 18632 if (buf == NULL)
015dc7e1 18633 return false;
32ec8896 18634
9c7b8e9b
AM
18635 flag = byte_get (buf, 4);
18636 free (buf);
18637 switch (flag & 0x3)
35c08157
KLC
18638 {
18639 case 0:
18640 printf ("(VEC_SIZE):\tNo entry.\n");
18641 break;
18642 case 1:
18643 printf ("(VEC_SIZE):\t4 bytes\n");
18644 break;
18645 case 2:
18646 printf ("(VEC_SIZE):\t16 bytes\n");
18647 break;
18648 case 3:
18649 printf ("(VEC_SIZE):\treserved\n");
18650 break;
18651 }
18652 }
18653
015dc7e1 18654 return true;
35c08157
KLC
18655}
18656
015dc7e1 18657static bool
dda8d76d 18658process_gnu_liblist (Filedata * filedata)
047b2264 18659{
2cf0635d
NC
18660 Elf_Internal_Shdr * section;
18661 Elf_Internal_Shdr * string_sec;
18662 Elf32_External_Lib * elib;
18663 char * strtab;
c256ffe7 18664 size_t strtab_size;
047b2264 18665 size_t cnt;
d3a49aa8 18666 unsigned long num_liblist;
047b2264 18667 unsigned i;
015dc7e1 18668 bool res = true;
047b2264
JJ
18669
18670 if (! do_arch)
015dc7e1 18671 return true;
047b2264 18672
dda8d76d
NC
18673 for (i = 0, section = filedata->section_headers;
18674 i < filedata->file_header.e_shnum;
b34976b6 18675 i++, section++)
047b2264
JJ
18676 {
18677 switch (section->sh_type)
18678 {
18679 case SHT_GNU_LIBLIST:
dda8d76d 18680 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18681 break;
18682
3f5e193b 18683 elib = (Elf32_External_Lib *)
dda8d76d 18684 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18685 _("liblist section data"));
047b2264
JJ
18686
18687 if (elib == NULL)
32ec8896 18688 {
015dc7e1 18689 res = false;
32ec8896
NC
18690 break;
18691 }
047b2264 18692
dda8d76d
NC
18693 string_sec = filedata->section_headers + section->sh_link;
18694 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18695 string_sec->sh_size,
18696 _("liblist string table"));
047b2264
JJ
18697 if (strtab == NULL
18698 || section->sh_entsize != sizeof (Elf32_External_Lib))
18699 {
18700 free (elib);
2842702f 18701 free (strtab);
015dc7e1 18702 res = false;
047b2264
JJ
18703 break;
18704 }
59245841 18705 strtab_size = string_sec->sh_size;
047b2264 18706
d3a49aa8
AM
18707 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18708 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18709 "\nLibrary list section '%s' contains %lu entries:\n",
18710 num_liblist),
dda8d76d 18711 printable_section_name (filedata, section),
d3a49aa8 18712 num_liblist);
047b2264 18713
2b692964 18714 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18715
18716 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18717 ++cnt)
18718 {
18719 Elf32_Lib liblist;
91d6fa6a 18720 time_t atime;
d5b07ef4 18721 char timebuf[128];
2cf0635d 18722 struct tm * tmp;
047b2264
JJ
18723
18724 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18725 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18726 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18727 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18728 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18729
91d6fa6a 18730 tmp = gmtime (&atime);
e9e44622
JJ
18731 snprintf (timebuf, sizeof (timebuf),
18732 "%04u-%02u-%02uT%02u:%02u:%02u",
18733 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18734 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18735
18736 printf ("%3lu: ", (unsigned long) cnt);
18737 if (do_wide)
c256ffe7 18738 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18739 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18740 else
c256ffe7 18741 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18742 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18743 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18744 liblist.l_version, liblist.l_flags);
18745 }
18746
18747 free (elib);
2842702f 18748 free (strtab);
047b2264
JJ
18749 }
18750 }
18751
32ec8896 18752 return res;
047b2264
JJ
18753}
18754
9437c45b 18755static const char *
dda8d76d 18756get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18757{
18758 static char buff[64];
103f02d3 18759
dda8d76d 18760 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18761 switch (e_type)
18762 {
57346661 18763 case NT_AUXV:
1ec5cd37 18764 return _("NT_AUXV (auxiliary vector)");
57346661 18765 case NT_PRSTATUS:
1ec5cd37 18766 return _("NT_PRSTATUS (prstatus structure)");
57346661 18767 case NT_FPREGSET:
1ec5cd37 18768 return _("NT_FPREGSET (floating point registers)");
57346661 18769 case NT_PRPSINFO:
1ec5cd37 18770 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18771 case NT_TASKSTRUCT:
1ec5cd37 18772 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18773 case NT_GDB_TDESC:
18774 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18775 case NT_PRXFPREG:
1ec5cd37 18776 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18777 case NT_PPC_VMX:
18778 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18779 case NT_PPC_VSX:
18780 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18781 case NT_PPC_TAR:
18782 return _("NT_PPC_TAR (ppc TAR register)");
18783 case NT_PPC_PPR:
18784 return _("NT_PPC_PPR (ppc PPR register)");
18785 case NT_PPC_DSCR:
18786 return _("NT_PPC_DSCR (ppc DSCR register)");
18787 case NT_PPC_EBB:
18788 return _("NT_PPC_EBB (ppc EBB registers)");
18789 case NT_PPC_PMU:
18790 return _("NT_PPC_PMU (ppc PMU registers)");
18791 case NT_PPC_TM_CGPR:
18792 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18793 case NT_PPC_TM_CFPR:
18794 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18795 case NT_PPC_TM_CVMX:
18796 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18797 case NT_PPC_TM_CVSX:
3fd21718 18798 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18799 case NT_PPC_TM_SPR:
18800 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18801 case NT_PPC_TM_CTAR:
18802 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18803 case NT_PPC_TM_CPPR:
18804 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18805 case NT_PPC_TM_CDSCR:
18806 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18807 case NT_386_TLS:
18808 return _("NT_386_TLS (x86 TLS information)");
18809 case NT_386_IOPERM:
18810 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18811 case NT_X86_XSTATE:
18812 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18813 case NT_X86_CET:
18814 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18815 case NT_S390_HIGH_GPRS:
18816 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18817 case NT_S390_TIMER:
18818 return _("NT_S390_TIMER (s390 timer register)");
18819 case NT_S390_TODCMP:
18820 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18821 case NT_S390_TODPREG:
18822 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18823 case NT_S390_CTRS:
18824 return _("NT_S390_CTRS (s390 control registers)");
18825 case NT_S390_PREFIX:
18826 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18827 case NT_S390_LAST_BREAK:
18828 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18829 case NT_S390_SYSTEM_CALL:
18830 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18831 case NT_S390_TDB:
18832 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18833 case NT_S390_VXRS_LOW:
18834 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18835 case NT_S390_VXRS_HIGH:
18836 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18837 case NT_S390_GS_CB:
18838 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18839 case NT_S390_GS_BC:
18840 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18841 case NT_ARM_VFP:
18842 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18843 case NT_ARM_TLS:
18844 return _("NT_ARM_TLS (AArch TLS registers)");
18845 case NT_ARM_HW_BREAK:
18846 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18847 case NT_ARM_HW_WATCH:
18848 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18849 case NT_ARM_SVE:
18850 return _("NT_ARM_SVE (AArch SVE registers)");
18851 case NT_ARM_PAC_MASK:
18852 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
3af2785c
LM
18853 case NT_ARM_PACA_KEYS:
18854 return _("NT_ARM_PACA_KEYS (ARM pointer authentication address keys)");
18855 case NT_ARM_PACG_KEYS:
18856 return _("NT_ARM_PACG_KEYS (ARM pointer authentication generic keys)");
3b2bef8b
LM
18857 case NT_ARM_TAGGED_ADDR_CTRL:
18858 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
3af2785c
LM
18859 case NT_ARM_PAC_ENABLED_KEYS:
18860 return _("NT_ARM_PAC_ENABLED_KEYS (AArch64 pointer authentication enabled keys)");
27456742
AK
18861 case NT_ARC_V2:
18862 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18863 case NT_RISCV_CSR:
18864 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18865 case NT_PSTATUS:
1ec5cd37 18866 return _("NT_PSTATUS (pstatus structure)");
57346661 18867 case NT_FPREGS:
1ec5cd37 18868 return _("NT_FPREGS (floating point registers)");
57346661 18869 case NT_PSINFO:
1ec5cd37 18870 return _("NT_PSINFO (psinfo structure)");
57346661 18871 case NT_LWPSTATUS:
1ec5cd37 18872 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18873 case NT_LWPSINFO:
1ec5cd37 18874 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18875 case NT_WIN32PSTATUS:
1ec5cd37 18876 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18877 case NT_SIGINFO:
18878 return _("NT_SIGINFO (siginfo_t data)");
18879 case NT_FILE:
18880 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18881 default:
18882 break;
18883 }
18884 else
18885 switch (e_type)
18886 {
18887 case NT_VERSION:
18888 return _("NT_VERSION (version)");
18889 case NT_ARCH:
18890 return _("NT_ARCH (architecture)");
9ef920e9 18891 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18892 return _("OPEN");
9ef920e9 18893 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18894 return _("func");
c8795e1f
NC
18895 case NT_GO_BUILDID:
18896 return _("GO BUILDID");
1ec5cd37
NC
18897 default:
18898 break;
18899 }
18900
e9e44622 18901 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18902 return buff;
779fe533
NC
18903}
18904
015dc7e1 18905static bool
9ece1fa9
TT
18906print_core_note (Elf_Internal_Note *pnote)
18907{
18908 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18909 bfd_vma count, page_size;
18910 unsigned char *descdata, *filenames, *descend;
18911
18912 if (pnote->type != NT_FILE)
04ac15ab
AS
18913 {
18914 if (do_wide)
18915 printf ("\n");
015dc7e1 18916 return true;
04ac15ab 18917 }
9ece1fa9
TT
18918
18919#ifndef BFD64
18920 if (!is_32bit_elf)
18921 {
18922 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18923 /* Still "successful". */
015dc7e1 18924 return true;
9ece1fa9
TT
18925 }
18926#endif
18927
18928 if (pnote->descsz < 2 * addr_size)
18929 {
32ec8896 18930 error (_(" Malformed note - too short for header\n"));
015dc7e1 18931 return false;
9ece1fa9
TT
18932 }
18933
18934 descdata = (unsigned char *) pnote->descdata;
18935 descend = descdata + pnote->descsz;
18936
18937 if (descdata[pnote->descsz - 1] != '\0')
18938 {
32ec8896 18939 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18940 return false;
9ece1fa9
TT
18941 }
18942
18943 count = byte_get (descdata, addr_size);
18944 descdata += addr_size;
18945
18946 page_size = byte_get (descdata, addr_size);
18947 descdata += addr_size;
18948
5396a86e
AM
18949 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18950 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18951 {
32ec8896 18952 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18953 return false;
9ece1fa9
TT
18954 }
18955
18956 printf (_(" Page size: "));
18957 print_vma (page_size, DEC);
18958 printf ("\n");
18959
18960 printf (_(" %*s%*s%*s\n"),
18961 (int) (2 + 2 * addr_size), _("Start"),
18962 (int) (4 + 2 * addr_size), _("End"),
18963 (int) (4 + 2 * addr_size), _("Page Offset"));
18964 filenames = descdata + count * 3 * addr_size;
595712bb 18965 while (count-- > 0)
9ece1fa9
TT
18966 {
18967 bfd_vma start, end, file_ofs;
18968
18969 if (filenames == descend)
18970 {
32ec8896 18971 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18972 return false;
9ece1fa9
TT
18973 }
18974
18975 start = byte_get (descdata, addr_size);
18976 descdata += addr_size;
18977 end = byte_get (descdata, addr_size);
18978 descdata += addr_size;
18979 file_ofs = byte_get (descdata, addr_size);
18980 descdata += addr_size;
18981
18982 printf (" ");
18983 print_vma (start, FULL_HEX);
18984 printf (" ");
18985 print_vma (end, FULL_HEX);
18986 printf (" ");
18987 print_vma (file_ofs, FULL_HEX);
18988 printf ("\n %s\n", filenames);
18989
18990 filenames += 1 + strlen ((char *) filenames);
18991 }
18992
015dc7e1 18993 return true;
9ece1fa9
TT
18994}
18995
1118d252
RM
18996static const char *
18997get_gnu_elf_note_type (unsigned e_type)
18998{
1449284b 18999 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
19000 switch (e_type)
19001 {
19002 case NT_GNU_ABI_TAG:
19003 return _("NT_GNU_ABI_TAG (ABI version tag)");
19004 case NT_GNU_HWCAP:
19005 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
19006 case NT_GNU_BUILD_ID:
19007 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
19008 case NT_GNU_GOLD_VERSION:
19009 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
19010 case NT_GNU_PROPERTY_TYPE_0:
19011 return _("NT_GNU_PROPERTY_TYPE_0");
19012 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
19013 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
19014 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
19015 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 19016 default:
1449284b
NC
19017 {
19018 static char buff[64];
1118d252 19019
1449284b
NC
19020 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19021 return buff;
19022 }
19023 }
1118d252
RM
19024}
19025
a9eafb08
L
19026static void
19027decode_x86_compat_isa (unsigned int bitmask)
19028{
19029 while (bitmask)
19030 {
19031 unsigned int bit = bitmask & (- bitmask);
19032
19033 bitmask &= ~ bit;
19034 switch (bit)
19035 {
19036 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19037 printf ("i486");
19038 break;
19039 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19040 printf ("586");
19041 break;
19042 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19043 printf ("686");
19044 break;
19045 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19046 printf ("SSE");
19047 break;
19048 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19049 printf ("SSE2");
19050 break;
19051 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19052 printf ("SSE3");
19053 break;
19054 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19055 printf ("SSSE3");
19056 break;
19057 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19058 printf ("SSE4_1");
19059 break;
19060 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19061 printf ("SSE4_2");
19062 break;
19063 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19064 printf ("AVX");
19065 break;
19066 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19067 printf ("AVX2");
19068 break;
19069 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19070 printf ("AVX512F");
19071 break;
19072 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19073 printf ("AVX512CD");
19074 break;
19075 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19076 printf ("AVX512ER");
19077 break;
19078 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19079 printf ("AVX512PF");
19080 break;
19081 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19082 printf ("AVX512VL");
19083 break;
19084 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19085 printf ("AVX512DQ");
19086 break;
19087 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19088 printf ("AVX512BW");
19089 break;
65b3d26e
L
19090 default:
19091 printf (_("<unknown: %x>"), bit);
19092 break;
a9eafb08
L
19093 }
19094 if (bitmask)
19095 printf (", ");
19096 }
19097}
19098
9ef920e9 19099static void
32930e4e 19100decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19101{
0a59decb 19102 if (!bitmask)
90c745dc
L
19103 {
19104 printf (_("<None>"));
19105 return;
19106 }
90c745dc 19107
9ef920e9
NC
19108 while (bitmask)
19109 {
1fc87489 19110 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19111
19112 bitmask &= ~ bit;
19113 switch (bit)
19114 {
32930e4e 19115 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19116 printf ("CMOV");
19117 break;
32930e4e 19118 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19119 printf ("SSE");
19120 break;
32930e4e 19121 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19122 printf ("SSE2");
19123 break;
32930e4e 19124 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19125 printf ("SSE3");
19126 break;
32930e4e 19127 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19128 printf ("SSSE3");
19129 break;
32930e4e 19130 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19131 printf ("SSE4_1");
19132 break;
32930e4e 19133 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19134 printf ("SSE4_2");
19135 break;
32930e4e 19136 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19137 printf ("AVX");
19138 break;
32930e4e 19139 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19140 printf ("AVX2");
19141 break;
32930e4e 19142 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19143 printf ("FMA");
19144 break;
32930e4e 19145 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19146 printf ("AVX512F");
19147 break;
32930e4e 19148 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19149 printf ("AVX512CD");
19150 break;
32930e4e 19151 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19152 printf ("AVX512ER");
19153 break;
32930e4e 19154 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19155 printf ("AVX512PF");
19156 break;
32930e4e 19157 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19158 printf ("AVX512VL");
19159 break;
32930e4e 19160 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19161 printf ("AVX512DQ");
19162 break;
32930e4e 19163 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19164 printf ("AVX512BW");
19165 break;
32930e4e 19166 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19167 printf ("AVX512_4FMAPS");
19168 break;
32930e4e 19169 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19170 printf ("AVX512_4VNNIW");
19171 break;
32930e4e 19172 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19173 printf ("AVX512_BITALG");
19174 break;
32930e4e 19175 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19176 printf ("AVX512_IFMA");
19177 break;
32930e4e 19178 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19179 printf ("AVX512_VBMI");
19180 break;
32930e4e 19181 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19182 printf ("AVX512_VBMI2");
19183 break;
32930e4e 19184 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19185 printf ("AVX512_VNNI");
19186 break;
32930e4e 19187 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19188 printf ("AVX512_BF16");
19189 break;
65b3d26e
L
19190 default:
19191 printf (_("<unknown: %x>"), bit);
19192 break;
9ef920e9
NC
19193 }
19194 if (bitmask)
19195 printf (", ");
19196 }
19197}
19198
32930e4e
L
19199static void
19200decode_x86_isa (unsigned int bitmask)
19201{
32930e4e
L
19202 while (bitmask)
19203 {
19204 unsigned int bit = bitmask & (- bitmask);
19205
19206 bitmask &= ~ bit;
19207 switch (bit)
19208 {
b0ab0693
L
19209 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19210 printf ("x86-64-baseline");
19211 break;
32930e4e
L
19212 case GNU_PROPERTY_X86_ISA_1_V2:
19213 printf ("x86-64-v2");
19214 break;
19215 case GNU_PROPERTY_X86_ISA_1_V3:
19216 printf ("x86-64-v3");
19217 break;
19218 case GNU_PROPERTY_X86_ISA_1_V4:
19219 printf ("x86-64-v4");
19220 break;
19221 default:
19222 printf (_("<unknown: %x>"), bit);
19223 break;
19224 }
19225 if (bitmask)
19226 printf (", ");
19227 }
19228}
19229
ee2fdd6f 19230static void
a9eafb08 19231decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19232{
0a59decb 19233 if (!bitmask)
90c745dc
L
19234 {
19235 printf (_("<None>"));
19236 return;
19237 }
90c745dc 19238
ee2fdd6f
L
19239 while (bitmask)
19240 {
19241 unsigned int bit = bitmask & (- bitmask);
19242
19243 bitmask &= ~ bit;
19244 switch (bit)
19245 {
19246 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19247 printf ("IBT");
ee2fdd6f 19248 break;
48580982 19249 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19250 printf ("SHSTK");
48580982 19251 break;
279d901e
L
19252 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19253 printf ("LAM_U48");
19254 break;
19255 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19256 printf ("LAM_U57");
19257 break;
ee2fdd6f
L
19258 default:
19259 printf (_("<unknown: %x>"), bit);
19260 break;
19261 }
19262 if (bitmask)
19263 printf (", ");
19264 }
19265}
19266
a9eafb08
L
19267static void
19268decode_x86_feature_2 (unsigned int bitmask)
19269{
0a59decb 19270 if (!bitmask)
90c745dc
L
19271 {
19272 printf (_("<None>"));
19273 return;
19274 }
90c745dc 19275
a9eafb08
L
19276 while (bitmask)
19277 {
19278 unsigned int bit = bitmask & (- bitmask);
19279
19280 bitmask &= ~ bit;
19281 switch (bit)
19282 {
19283 case GNU_PROPERTY_X86_FEATURE_2_X86:
19284 printf ("x86");
19285 break;
19286 case GNU_PROPERTY_X86_FEATURE_2_X87:
19287 printf ("x87");
19288 break;
19289 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19290 printf ("MMX");
19291 break;
19292 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19293 printf ("XMM");
19294 break;
19295 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19296 printf ("YMM");
19297 break;
19298 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19299 printf ("ZMM");
19300 break;
a308b89d
L
19301 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19302 printf ("TMM");
19303 break;
32930e4e
L
19304 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19305 printf ("MASK");
19306 break;
a9eafb08
L
19307 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19308 printf ("FXSR");
19309 break;
19310 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19311 printf ("XSAVE");
19312 break;
19313 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19314 printf ("XSAVEOPT");
19315 break;
19316 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19317 printf ("XSAVEC");
19318 break;
65b3d26e
L
19319 default:
19320 printf (_("<unknown: %x>"), bit);
19321 break;
a9eafb08
L
19322 }
19323 if (bitmask)
19324 printf (", ");
19325 }
19326}
19327
cd702818
SD
19328static void
19329decode_aarch64_feature_1_and (unsigned int bitmask)
19330{
19331 while (bitmask)
19332 {
19333 unsigned int bit = bitmask & (- bitmask);
19334
19335 bitmask &= ~ bit;
19336 switch (bit)
19337 {
19338 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19339 printf ("BTI");
19340 break;
19341
19342 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19343 printf ("PAC");
19344 break;
19345
19346 default:
19347 printf (_("<unknown: %x>"), bit);
19348 break;
19349 }
19350 if (bitmask)
19351 printf (", ");
19352 }
19353}
19354
6320fd00
L
19355static void
19356decode_1_needed (unsigned int bitmask)
19357{
19358 while (bitmask)
19359 {
19360 unsigned int bit = bitmask & (- bitmask);
19361
19362 bitmask &= ~ bit;
19363 switch (bit)
19364 {
19365 case GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS:
19366 printf ("indirect external access");
19367 break;
19368 default:
19369 printf (_("<unknown: %x>"), bit);
19370 break;
19371 }
19372 if (bitmask)
19373 printf (", ");
19374 }
19375}
19376
9ef920e9 19377static void
dda8d76d 19378print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19379{
19380 unsigned char * ptr = (unsigned char *) pnote->descdata;
19381 unsigned char * ptr_end = ptr + pnote->descsz;
19382 unsigned int size = is_32bit_elf ? 4 : 8;
19383
19384 printf (_(" Properties: "));
19385
1fc87489 19386 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19387 {
19388 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19389 return;
19390 }
19391
6ab2c4ed 19392 while (ptr < ptr_end)
9ef920e9 19393 {
1fc87489 19394 unsigned int j;
6ab2c4ed
MC
19395 unsigned int type;
19396 unsigned int datasz;
19397
19398 if ((size_t) (ptr_end - ptr) < 8)
19399 {
19400 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19401 break;
19402 }
19403
19404 type = byte_get (ptr, 4);
19405 datasz = byte_get (ptr + 4, 4);
9ef920e9 19406
1fc87489 19407 ptr += 8;
9ef920e9 19408
6ab2c4ed 19409 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19410 {
1fc87489
L
19411 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19412 type, datasz);
9ef920e9 19413 break;
1fc87489 19414 }
9ef920e9 19415
1fc87489
L
19416 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19417 {
dda8d76d
NC
19418 if (filedata->file_header.e_machine == EM_X86_64
19419 || filedata->file_header.e_machine == EM_IAMCU
19420 || filedata->file_header.e_machine == EM_386)
1fc87489 19421 {
aa7bca9b
L
19422 unsigned int bitmask;
19423
19424 if (datasz == 4)
0a59decb 19425 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19426 else
19427 bitmask = 0;
19428
1fc87489
L
19429 switch (type)
19430 {
19431 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19432 if (datasz != 4)
aa7bca9b
L
19433 printf (_("x86 ISA used: <corrupt length: %#x> "),
19434 datasz);
1fc87489 19435 else
aa7bca9b
L
19436 {
19437 printf ("x86 ISA used: ");
19438 decode_x86_isa (bitmask);
19439 }
1fc87489 19440 goto next;
9ef920e9 19441
1fc87489 19442 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19443 if (datasz != 4)
aa7bca9b
L
19444 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19445 datasz);
1fc87489 19446 else
aa7bca9b
L
19447 {
19448 printf ("x86 ISA needed: ");
19449 decode_x86_isa (bitmask);
19450 }
1fc87489 19451 goto next;
9ef920e9 19452
ee2fdd6f 19453 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19454 if (datasz != 4)
aa7bca9b
L
19455 printf (_("x86 feature: <corrupt length: %#x> "),
19456 datasz);
ee2fdd6f 19457 else
aa7bca9b
L
19458 {
19459 printf ("x86 feature: ");
a9eafb08
L
19460 decode_x86_feature_1 (bitmask);
19461 }
19462 goto next;
19463
19464 case GNU_PROPERTY_X86_FEATURE_2_USED:
19465 if (datasz != 4)
19466 printf (_("x86 feature used: <corrupt length: %#x> "),
19467 datasz);
19468 else
19469 {
19470 printf ("x86 feature used: ");
19471 decode_x86_feature_2 (bitmask);
19472 }
19473 goto next;
19474
19475 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19476 if (datasz != 4)
19477 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19478 else
19479 {
19480 printf ("x86 feature needed: ");
19481 decode_x86_feature_2 (bitmask);
19482 }
19483 goto next;
19484
19485 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19486 if (datasz != 4)
19487 printf (_("x86 ISA used: <corrupt length: %#x> "),
19488 datasz);
19489 else
19490 {
19491 printf ("x86 ISA used: ");
19492 decode_x86_compat_isa (bitmask);
19493 }
19494 goto next;
19495
19496 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19497 if (datasz != 4)
19498 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19499 datasz);
19500 else
19501 {
19502 printf ("x86 ISA needed: ");
19503 decode_x86_compat_isa (bitmask);
aa7bca9b 19504 }
ee2fdd6f
L
19505 goto next;
19506
32930e4e
L
19507 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19508 if (datasz != 4)
19509 printf (_("x86 ISA used: <corrupt length: %#x> "),
19510 datasz);
19511 else
19512 {
19513 printf ("x86 ISA used: ");
19514 decode_x86_compat_2_isa (bitmask);
19515 }
19516 goto next;
19517
19518 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19519 if (datasz != 4)
19520 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19521 datasz);
19522 else
19523 {
19524 printf ("x86 ISA needed: ");
19525 decode_x86_compat_2_isa (bitmask);
19526 }
19527 goto next;
19528
1fc87489
L
19529 default:
19530 break;
19531 }
19532 }
cd702818
SD
19533 else if (filedata->file_header.e_machine == EM_AARCH64)
19534 {
19535 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19536 {
19537 printf ("AArch64 feature: ");
19538 if (datasz != 4)
19539 printf (_("<corrupt length: %#x> "), datasz);
19540 else
19541 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19542 goto next;
19543 }
19544 }
1fc87489
L
19545 }
19546 else
19547 {
19548 switch (type)
9ef920e9 19549 {
1fc87489
L
19550 case GNU_PROPERTY_STACK_SIZE:
19551 printf (_("stack size: "));
19552 if (datasz != size)
19553 printf (_("<corrupt length: %#x> "), datasz);
19554 else
19555 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19556 goto next;
19557
19558 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19559 printf ("no copy on protected ");
19560 if (datasz)
19561 printf (_("<corrupt length: %#x> "), datasz);
19562 goto next;
19563
19564 default:
5a767724
L
19565 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19566 && type <= GNU_PROPERTY_UINT32_AND_HI)
19567 || (type >= GNU_PROPERTY_UINT32_OR_LO
19568 && type <= GNU_PROPERTY_UINT32_OR_HI))
19569 {
6320fd00
L
19570 switch (type)
19571 {
19572 case GNU_PROPERTY_1_NEEDED:
19573 if (datasz != 4)
19574 printf (_("1_needed: <corrupt length: %#x> "),
19575 datasz);
19576 else
19577 {
19578 unsigned int bitmask = byte_get (ptr, 4);
19579 printf ("1_needed: ");
19580 decode_1_needed (bitmask);
19581 }
19582 goto next;
19583
19584 default:
19585 break;
19586 }
5a767724
L
19587 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19588 printf (_("UINT32_AND (%#x): "), type);
19589 else
19590 printf (_("UINT32_OR (%#x): "), type);
19591 if (datasz != 4)
19592 printf (_("<corrupt length: %#x> "), datasz);
19593 else
19594 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19595 goto next;
19596 }
9ef920e9
NC
19597 break;
19598 }
9ef920e9
NC
19599 }
19600
1fc87489
L
19601 if (type < GNU_PROPERTY_LOPROC)
19602 printf (_("<unknown type %#x data: "), type);
19603 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19604 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19605 else
19606 printf (_("<application-specific type %#x data: "), type);
19607 for (j = 0; j < datasz; ++j)
19608 printf ("%02x ", ptr[j] & 0xff);
19609 printf (">");
19610
dc1e8a47 19611 next:
9ef920e9 19612 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19613 if (ptr == ptr_end)
19614 break;
1fc87489 19615
6ab2c4ed
MC
19616 if (do_wide)
19617 printf (", ");
19618 else
19619 printf ("\n\t");
9ef920e9
NC
19620 }
19621
19622 printf ("\n");
19623}
19624
015dc7e1 19625static bool
dda8d76d 19626print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19627{
1449284b 19628 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19629 switch (pnote->type)
19630 {
19631 case NT_GNU_BUILD_ID:
19632 {
19633 unsigned long i;
19634
19635 printf (_(" Build ID: "));
19636 for (i = 0; i < pnote->descsz; ++i)
19637 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19638 printf ("\n");
664f90a3
TT
19639 }
19640 break;
19641
19642 case NT_GNU_ABI_TAG:
19643 {
19644 unsigned long os, major, minor, subminor;
19645 const char *osname;
19646
3102e897
NC
19647 /* PR 17531: file: 030-599401-0.004. */
19648 if (pnote->descsz < 16)
19649 {
19650 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19651 break;
19652 }
19653
664f90a3
TT
19654 os = byte_get ((unsigned char *) pnote->descdata, 4);
19655 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19656 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19657 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19658
19659 switch (os)
19660 {
19661 case GNU_ABI_TAG_LINUX:
19662 osname = "Linux";
19663 break;
19664 case GNU_ABI_TAG_HURD:
19665 osname = "Hurd";
19666 break;
19667 case GNU_ABI_TAG_SOLARIS:
19668 osname = "Solaris";
19669 break;
19670 case GNU_ABI_TAG_FREEBSD:
19671 osname = "FreeBSD";
19672 break;
19673 case GNU_ABI_TAG_NETBSD:
19674 osname = "NetBSD";
19675 break;
14ae95f2
RM
19676 case GNU_ABI_TAG_SYLLABLE:
19677 osname = "Syllable";
19678 break;
19679 case GNU_ABI_TAG_NACL:
19680 osname = "NaCl";
19681 break;
664f90a3
TT
19682 default:
19683 osname = "Unknown";
19684 break;
19685 }
19686
19687 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19688 major, minor, subminor);
19689 }
19690 break;
926c5385
CC
19691
19692 case NT_GNU_GOLD_VERSION:
19693 {
19694 unsigned long i;
19695
19696 printf (_(" Version: "));
19697 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19698 printf ("%c", pnote->descdata[i]);
19699 printf ("\n");
19700 }
19701 break;
1449284b
NC
19702
19703 case NT_GNU_HWCAP:
19704 {
19705 unsigned long num_entries, mask;
19706
19707 /* Hardware capabilities information. Word 0 is the number of entries.
19708 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19709 is a series of entries, where each entry is a single byte followed
19710 by a nul terminated string. The byte gives the bit number to test
19711 if enabled in the bitmask. */
19712 printf (_(" Hardware Capabilities: "));
19713 if (pnote->descsz < 8)
19714 {
32ec8896 19715 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19716 return false;
1449284b
NC
19717 }
19718 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19719 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19720 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19721 /* FIXME: Add code to display the entries... */
19722 }
19723 break;
19724
9ef920e9 19725 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19726 print_gnu_property_note (filedata, pnote);
9ef920e9 19727 break;
9abca702 19728
1449284b
NC
19729 default:
19730 /* Handle unrecognised types. An error message should have already been
19731 created by get_gnu_elf_note_type(), so all that we need to do is to
19732 display the data. */
19733 {
19734 unsigned long i;
19735
19736 printf (_(" Description data: "));
19737 for (i = 0; i < pnote->descsz; ++i)
19738 printf ("%02x ", pnote->descdata[i] & 0xff);
19739 printf ("\n");
19740 }
19741 break;
664f90a3
TT
19742 }
19743
015dc7e1 19744 return true;
664f90a3
TT
19745}
19746
685080f2
NC
19747static const char *
19748get_v850_elf_note_type (enum v850_notes n_type)
19749{
19750 static char buff[64];
19751
19752 switch (n_type)
19753 {
19754 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19755 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19756 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19757 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19758 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19759 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19760 default:
19761 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19762 return buff;
19763 }
19764}
19765
015dc7e1 19766static bool
685080f2
NC
19767print_v850_note (Elf_Internal_Note * pnote)
19768{
19769 unsigned int val;
19770
19771 if (pnote->descsz != 4)
015dc7e1 19772 return false;
32ec8896 19773
685080f2
NC
19774 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19775
19776 if (val == 0)
19777 {
19778 printf (_("not set\n"));
015dc7e1 19779 return true;
685080f2
NC
19780 }
19781
19782 switch (pnote->type)
19783 {
19784 case V850_NOTE_ALIGNMENT:
19785 switch (val)
19786 {
015dc7e1
AM
19787 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19788 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19789 }
19790 break;
14ae95f2 19791
685080f2
NC
19792 case V850_NOTE_DATA_SIZE:
19793 switch (val)
19794 {
015dc7e1
AM
19795 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19796 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19797 }
19798 break;
14ae95f2 19799
685080f2
NC
19800 case V850_NOTE_FPU_INFO:
19801 switch (val)
19802 {
015dc7e1
AM
19803 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19804 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19805 }
19806 break;
14ae95f2 19807
685080f2
NC
19808 case V850_NOTE_MMU_INFO:
19809 case V850_NOTE_CACHE_INFO:
19810 case V850_NOTE_SIMD_INFO:
19811 if (val == EF_RH850_SIMD)
19812 {
19813 printf (_("yes\n"));
015dc7e1 19814 return true;
685080f2
NC
19815 }
19816 break;
19817
19818 default:
19819 /* An 'unknown note type' message will already have been displayed. */
19820 break;
19821 }
19822
19823 printf (_("unknown value: %x\n"), val);
015dc7e1 19824 return false;
685080f2
NC
19825}
19826
015dc7e1 19827static bool
c6056a74
SF
19828process_netbsd_elf_note (Elf_Internal_Note * pnote)
19829{
19830 unsigned int version;
19831
19832 switch (pnote->type)
19833 {
19834 case NT_NETBSD_IDENT:
b966f55f
AM
19835 if (pnote->descsz < 1)
19836 break;
c6056a74
SF
19837 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19838 if ((version / 10000) % 100)
b966f55f 19839 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19840 version, version / 100000000, (version / 1000000) % 100,
19841 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19842 'A' + (version / 10000) % 26);
c6056a74
SF
19843 else
19844 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19845 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19846 (version / 100) % 100);
015dc7e1 19847 return true;
c6056a74
SF
19848
19849 case NT_NETBSD_MARCH:
9abca702 19850 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19851 pnote->descdata);
015dc7e1 19852 return true;
c6056a74 19853
9abca702 19854 case NT_NETBSD_PAX:
b966f55f
AM
19855 if (pnote->descsz < 1)
19856 break;
9abca702
CZ
19857 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19858 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19859 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19860 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19861 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19862 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19863 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19864 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19865 return true;
c6056a74 19866 }
b966f55f
AM
19867
19868 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19869 pnote->descsz, pnote->type);
015dc7e1 19870 return false;
c6056a74
SF
19871}
19872
f4ddf30f 19873static const char *
dda8d76d 19874get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19875{
f4ddf30f
JB
19876 switch (e_type)
19877 {
19878 case NT_FREEBSD_THRMISC:
19879 return _("NT_THRMISC (thrmisc structure)");
19880 case NT_FREEBSD_PROCSTAT_PROC:
19881 return _("NT_PROCSTAT_PROC (proc data)");
19882 case NT_FREEBSD_PROCSTAT_FILES:
19883 return _("NT_PROCSTAT_FILES (files data)");
19884 case NT_FREEBSD_PROCSTAT_VMMAP:
19885 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19886 case NT_FREEBSD_PROCSTAT_GROUPS:
19887 return _("NT_PROCSTAT_GROUPS (groups data)");
19888 case NT_FREEBSD_PROCSTAT_UMASK:
19889 return _("NT_PROCSTAT_UMASK (umask data)");
19890 case NT_FREEBSD_PROCSTAT_RLIMIT:
19891 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19892 case NT_FREEBSD_PROCSTAT_OSREL:
19893 return _("NT_PROCSTAT_OSREL (osreldate data)");
19894 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19895 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19896 case NT_FREEBSD_PROCSTAT_AUXV:
19897 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19898 case NT_FREEBSD_PTLWPINFO:
19899 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19900 }
dda8d76d 19901 return get_note_type (filedata, e_type);
f4ddf30f
JB
19902}
19903
9437c45b 19904static const char *
dda8d76d 19905get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19906{
19907 static char buff[64];
19908
540e6170
CZ
19909 switch (e_type)
19910 {
19911 case NT_NETBSDCORE_PROCINFO:
19912 /* NetBSD core "procinfo" structure. */
19913 return _("NetBSD procinfo structure");
9437c45b 19914
540e6170
CZ
19915 case NT_NETBSDCORE_AUXV:
19916 return _("NetBSD ELF auxiliary vector data");
9437c45b 19917
06d949ec
KR
19918 case NT_NETBSDCORE_LWPSTATUS:
19919 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19920
540e6170 19921 default:
06d949ec 19922 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19923 defined for NetBSD core files. If the note type is less
19924 than the start of the machine-dependent note types, we don't
19925 understand it. */
19926
19927 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19928 {
19929 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19930 return buff;
19931 }
19932 break;
9437c45b
JT
19933 }
19934
dda8d76d 19935 switch (filedata->file_header.e_machine)
9437c45b
JT
19936 {
19937 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19938 and PT_GETFPREGS == mach+2. */
19939
19940 case EM_OLD_ALPHA:
19941 case EM_ALPHA:
19942 case EM_SPARC:
19943 case EM_SPARC32PLUS:
19944 case EM_SPARCV9:
19945 switch (e_type)
19946 {
2b692964 19947 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19948 return _("PT_GETREGS (reg structure)");
2b692964 19949 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19950 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19951 default:
19952 break;
19953 }
19954 break;
19955
c0d38b0e
CZ
19956 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19957 There's also old PT___GETREGS40 == mach + 1 for old reg
19958 structure which lacks GBR. */
19959 case EM_SH:
19960 switch (e_type)
19961 {
19962 case NT_NETBSDCORE_FIRSTMACH + 1:
19963 return _("PT___GETREGS40 (old reg structure)");
19964 case NT_NETBSDCORE_FIRSTMACH + 3:
19965 return _("PT_GETREGS (reg structure)");
19966 case NT_NETBSDCORE_FIRSTMACH + 5:
19967 return _("PT_GETFPREGS (fpreg structure)");
19968 default:
19969 break;
19970 }
19971 break;
19972
9437c45b
JT
19973 /* On all other arch's, PT_GETREGS == mach+1 and
19974 PT_GETFPREGS == mach+3. */
19975 default:
19976 switch (e_type)
19977 {
2b692964 19978 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19979 return _("PT_GETREGS (reg structure)");
2b692964 19980 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19981 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19982 default:
19983 break;
19984 }
19985 }
19986
9cf03b7e 19987 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19988 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19989 return buff;
19990}
19991
70616151
TT
19992static const char *
19993get_stapsdt_note_type (unsigned e_type)
19994{
19995 static char buff[64];
19996
19997 switch (e_type)
19998 {
19999 case NT_STAPSDT:
20000 return _("NT_STAPSDT (SystemTap probe descriptors)");
20001
20002 default:
20003 break;
20004 }
20005
20006 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20007 return buff;
20008}
20009
015dc7e1 20010static bool
c6a9fc58
TT
20011print_stapsdt_note (Elf_Internal_Note *pnote)
20012{
3ca60c57
NC
20013 size_t len, maxlen;
20014 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
20015 char *data = pnote->descdata;
20016 char *data_end = pnote->descdata + pnote->descsz;
20017 bfd_vma pc, base_addr, semaphore;
20018 char *provider, *probe, *arg_fmt;
20019
3ca60c57
NC
20020 if (pnote->descsz < (addr_size * 3))
20021 goto stapdt_note_too_small;
20022
c6a9fc58
TT
20023 pc = byte_get ((unsigned char *) data, addr_size);
20024 data += addr_size;
3ca60c57 20025
c6a9fc58
TT
20026 base_addr = byte_get ((unsigned char *) data, addr_size);
20027 data += addr_size;
3ca60c57 20028
c6a9fc58
TT
20029 semaphore = byte_get ((unsigned char *) data, addr_size);
20030 data += addr_size;
20031
3ca60c57
NC
20032 if (data >= data_end)
20033 goto stapdt_note_too_small;
20034 maxlen = data_end - data;
20035 len = strnlen (data, maxlen);
20036 if (len < maxlen)
20037 {
20038 provider = data;
20039 data += len + 1;
20040 }
20041 else
20042 goto stapdt_note_too_small;
20043
20044 if (data >= data_end)
20045 goto stapdt_note_too_small;
20046 maxlen = data_end - data;
20047 len = strnlen (data, maxlen);
20048 if (len < maxlen)
20049 {
20050 probe = data;
20051 data += len + 1;
20052 }
20053 else
20054 goto stapdt_note_too_small;
9abca702 20055
3ca60c57
NC
20056 if (data >= data_end)
20057 goto stapdt_note_too_small;
20058 maxlen = data_end - data;
20059 len = strnlen (data, maxlen);
20060 if (len < maxlen)
20061 {
20062 arg_fmt = data;
20063 data += len + 1;
20064 }
20065 else
20066 goto stapdt_note_too_small;
c6a9fc58
TT
20067
20068 printf (_(" Provider: %s\n"), provider);
20069 printf (_(" Name: %s\n"), probe);
20070 printf (_(" Location: "));
20071 print_vma (pc, FULL_HEX);
20072 printf (_(", Base: "));
20073 print_vma (base_addr, FULL_HEX);
20074 printf (_(", Semaphore: "));
20075 print_vma (semaphore, FULL_HEX);
9cf03b7e 20076 printf ("\n");
c6a9fc58
TT
20077 printf (_(" Arguments: %s\n"), arg_fmt);
20078
20079 return data == data_end;
3ca60c57
NC
20080
20081 stapdt_note_too_small:
20082 printf (_(" <corrupt - note is too small>\n"));
20083 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20084 return false;
c6a9fc58
TT
20085}
20086
00e98fc7
TG
20087static const char *
20088get_ia64_vms_note_type (unsigned e_type)
20089{
20090 static char buff[64];
20091
20092 switch (e_type)
20093 {
20094 case NT_VMS_MHD:
20095 return _("NT_VMS_MHD (module header)");
20096 case NT_VMS_LNM:
20097 return _("NT_VMS_LNM (language name)");
20098 case NT_VMS_SRC:
20099 return _("NT_VMS_SRC (source files)");
20100 case NT_VMS_TITLE:
9cf03b7e 20101 return "NT_VMS_TITLE";
00e98fc7
TG
20102 case NT_VMS_EIDC:
20103 return _("NT_VMS_EIDC (consistency check)");
20104 case NT_VMS_FPMODE:
20105 return _("NT_VMS_FPMODE (FP mode)");
20106 case NT_VMS_LINKTIME:
9cf03b7e 20107 return "NT_VMS_LINKTIME";
00e98fc7
TG
20108 case NT_VMS_IMGNAM:
20109 return _("NT_VMS_IMGNAM (image name)");
20110 case NT_VMS_IMGID:
20111 return _("NT_VMS_IMGID (image id)");
20112 case NT_VMS_LINKID:
20113 return _("NT_VMS_LINKID (link id)");
20114 case NT_VMS_IMGBID:
20115 return _("NT_VMS_IMGBID (build id)");
20116 case NT_VMS_GSTNAM:
20117 return _("NT_VMS_GSTNAM (sym table name)");
20118 case NT_VMS_ORIG_DYN:
9cf03b7e 20119 return "NT_VMS_ORIG_DYN";
00e98fc7 20120 case NT_VMS_PATCHTIME:
9cf03b7e 20121 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20122 default:
20123 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20124 return buff;
20125 }
20126}
20127
015dc7e1 20128static bool
00e98fc7
TG
20129print_ia64_vms_note (Elf_Internal_Note * pnote)
20130{
8d18bf79
NC
20131 int maxlen = pnote->descsz;
20132
20133 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20134 goto desc_size_fail;
20135
00e98fc7
TG
20136 switch (pnote->type)
20137 {
20138 case NT_VMS_MHD:
8d18bf79
NC
20139 if (maxlen <= 36)
20140 goto desc_size_fail;
20141
20142 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20143
20144 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20145 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20146 if (l + 34 < maxlen)
20147 {
20148 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20149 if (l + 35 < maxlen)
20150 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20151 else
20152 printf (_(" Module version : <missing>\n"));
20153 }
00e98fc7 20154 else
8d18bf79
NC
20155 {
20156 printf (_(" Module name : <missing>\n"));
20157 printf (_(" Module version : <missing>\n"));
20158 }
00e98fc7 20159 break;
8d18bf79 20160
00e98fc7 20161 case NT_VMS_LNM:
8d18bf79 20162 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20163 break;
8d18bf79 20164
00e98fc7
TG
20165#ifdef BFD64
20166 case NT_VMS_FPMODE:
9cf03b7e 20167 printf (_(" Floating Point mode: "));
8d18bf79
NC
20168 if (maxlen < 8)
20169 goto desc_size_fail;
20170 /* FIXME: Generate an error if descsz > 8 ? */
20171
4a5cb34f 20172 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20173 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20174 break;
8d18bf79 20175
00e98fc7
TG
20176 case NT_VMS_LINKTIME:
20177 printf (_(" Link time: "));
8d18bf79
NC
20178 if (maxlen < 8)
20179 goto desc_size_fail;
20180 /* FIXME: Generate an error if descsz > 8 ? */
20181
00e98fc7 20182 print_vms_time
8d18bf79 20183 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20184 printf ("\n");
20185 break;
8d18bf79 20186
00e98fc7
TG
20187 case NT_VMS_PATCHTIME:
20188 printf (_(" Patch time: "));
8d18bf79
NC
20189 if (maxlen < 8)
20190 goto desc_size_fail;
20191 /* FIXME: Generate an error if descsz > 8 ? */
20192
00e98fc7 20193 print_vms_time
8d18bf79 20194 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20195 printf ("\n");
20196 break;
8d18bf79 20197
00e98fc7 20198 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20199 if (maxlen < 34)
20200 goto desc_size_fail;
20201
00e98fc7
TG
20202 printf (_(" Major id: %u, minor id: %u\n"),
20203 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20204 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20205 printf (_(" Last modified : "));
00e98fc7
TG
20206 print_vms_time
20207 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20208 printf (_("\n Link flags : "));
4a5cb34f 20209 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20210 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20211 printf (_(" Header flags: 0x%08x\n"),
948f632f 20212 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20213 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20214 break;
20215#endif
8d18bf79 20216
00e98fc7 20217 case NT_VMS_IMGNAM:
8d18bf79 20218 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20219 break;
8d18bf79 20220
00e98fc7 20221 case NT_VMS_GSTNAM:
8d18bf79 20222 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20223 break;
8d18bf79 20224
00e98fc7 20225 case NT_VMS_IMGID:
8d18bf79 20226 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20227 break;
8d18bf79 20228
00e98fc7 20229 case NT_VMS_LINKID:
8d18bf79 20230 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20231 break;
8d18bf79 20232
00e98fc7 20233 default:
015dc7e1 20234 return false;
00e98fc7 20235 }
8d18bf79 20236
015dc7e1 20237 return true;
8d18bf79
NC
20238
20239 desc_size_fail:
20240 printf (_(" <corrupt - data size is too small>\n"));
20241 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20242 return false;
00e98fc7
TG
20243}
20244
fd486f32
AM
20245struct build_attr_cache {
20246 Filedata *filedata;
20247 char *strtab;
20248 unsigned long strtablen;
20249 Elf_Internal_Sym *symtab;
20250 unsigned long nsyms;
20251} ba_cache;
20252
6f156d7a
NC
20253/* Find the symbol associated with a build attribute that is attached
20254 to address OFFSET. If PNAME is non-NULL then store the name of
20255 the symbol (if found) in the provided pointer, Returns NULL if a
20256 symbol could not be found. */
c799a79d 20257
6f156d7a 20258static Elf_Internal_Sym *
015dc7e1
AM
20259get_symbol_for_build_attribute (Filedata *filedata,
20260 unsigned long offset,
20261 bool is_open_attr,
20262 const char **pname)
9ef920e9 20263{
fd486f32
AM
20264 Elf_Internal_Sym *saved_sym = NULL;
20265 Elf_Internal_Sym *sym;
9ef920e9 20266
dda8d76d 20267 if (filedata->section_headers != NULL
fd486f32 20268 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20269 {
c799a79d 20270 Elf_Internal_Shdr * symsec;
9ef920e9 20271
fd486f32
AM
20272 free (ba_cache.strtab);
20273 ba_cache.strtab = NULL;
20274 free (ba_cache.symtab);
20275 ba_cache.symtab = NULL;
20276
c799a79d 20277 /* Load the symbol and string sections. */
dda8d76d
NC
20278 for (symsec = filedata->section_headers;
20279 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20280 symsec ++)
9ef920e9 20281 {
28d13567
AM
20282 if (symsec->sh_type == SHT_SYMTAB
20283 && get_symtab (filedata, symsec,
20284 &ba_cache.symtab, &ba_cache.nsyms,
20285 &ba_cache.strtab, &ba_cache.strtablen))
20286 break;
9ef920e9 20287 }
fd486f32 20288 ba_cache.filedata = filedata;
9ef920e9
NC
20289 }
20290
fd486f32 20291 if (ba_cache.symtab == NULL)
6f156d7a 20292 return NULL;
9ef920e9 20293
c799a79d 20294 /* Find a symbol whose value matches offset. */
fd486f32 20295 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20296 if (sym->st_value == offset)
20297 {
fd486f32 20298 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20299 /* Huh ? This should not happen. */
20300 continue;
9ef920e9 20301
fd486f32 20302 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20303 continue;
9ef920e9 20304
9b9b1092 20305 /* The AArch64, ARM and RISC-V architectures define mapping symbols
8fd75781 20306 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20307 if (ba_cache.strtab[sym->st_name] == '$'
20308 && ba_cache.strtab[sym->st_name + 1] != 0
20309 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20310 continue;
20311
c799a79d
NC
20312 if (is_open_attr)
20313 {
20314 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20315 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20316 FUNC symbols entirely. */
20317 switch (ELF_ST_TYPE (sym->st_info))
20318 {
c799a79d 20319 case STT_OBJECT:
6f156d7a 20320 case STT_FILE:
c799a79d 20321 saved_sym = sym;
6f156d7a
NC
20322 if (sym->st_size)
20323 {
20324 /* If the symbol has a size associated
20325 with it then we can stop searching. */
fd486f32 20326 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20327 }
c799a79d 20328 continue;
9ef920e9 20329
c799a79d
NC
20330 case STT_FUNC:
20331 /* Ignore function symbols. */
20332 continue;
20333
20334 default:
20335 break;
20336 }
20337
20338 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20339 {
c799a79d
NC
20340 case STB_GLOBAL:
20341 if (saved_sym == NULL
20342 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20343 saved_sym = sym;
20344 break;
c871dade 20345
c799a79d
NC
20346 case STB_LOCAL:
20347 if (saved_sym == NULL)
20348 saved_sym = sym;
20349 break;
20350
20351 default:
9ef920e9
NC
20352 break;
20353 }
20354 }
c799a79d
NC
20355 else
20356 {
20357 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20358 continue;
20359
20360 saved_sym = sym;
20361 break;
20362 }
20363 }
20364
6f156d7a 20365 if (saved_sym && pname)
fd486f32 20366 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20367
20368 return saved_sym;
c799a79d
NC
20369}
20370
d20e98ab
NC
20371/* Returns true iff addr1 and addr2 are in the same section. */
20372
015dc7e1 20373static bool
d20e98ab
NC
20374same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20375{
20376 Elf_Internal_Shdr * a1;
20377 Elf_Internal_Shdr * a2;
20378
20379 a1 = find_section_by_address (filedata, addr1);
20380 a2 = find_section_by_address (filedata, addr2);
9abca702 20381
d20e98ab
NC
20382 return a1 == a2 && a1 != NULL;
20383}
20384
015dc7e1 20385static bool
dda8d76d
NC
20386print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20387 Filedata * filedata)
c799a79d 20388{
015dc7e1
AM
20389 static unsigned long global_offset = 0;
20390 static unsigned long global_end = 0;
20391 static unsigned long func_offset = 0;
20392 static unsigned long func_end = 0;
c871dade 20393
015dc7e1
AM
20394 Elf_Internal_Sym *sym;
20395 const char *name;
20396 unsigned long start;
20397 unsigned long end;
20398 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20399
20400 switch (pnote->descsz)
c799a79d 20401 {
6f156d7a
NC
20402 case 0:
20403 /* A zero-length description means that the range of
20404 the previous note of the same type should be used. */
c799a79d 20405 if (is_open_attr)
c871dade 20406 {
6f156d7a
NC
20407 if (global_end > global_offset)
20408 printf (_(" Applies to region from %#lx to %#lx\n"),
20409 global_offset, global_end);
20410 else
20411 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20412 }
20413 else
20414 {
6f156d7a
NC
20415 if (func_end > func_offset)
20416 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20417 else
20418 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20419 }
015dc7e1 20420 return true;
9ef920e9 20421
6f156d7a
NC
20422 case 4:
20423 start = byte_get ((unsigned char *) pnote->descdata, 4);
20424 end = 0;
20425 break;
20426
20427 case 8:
c74147bb
NC
20428 start = byte_get ((unsigned char *) pnote->descdata, 4);
20429 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20430 break;
20431
20432 case 16:
20433 start = byte_get ((unsigned char *) pnote->descdata, 8);
20434 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20435 break;
9abca702 20436
6f156d7a 20437 default:
c799a79d
NC
20438 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20439 printf (_(" <invalid descsz>"));
015dc7e1 20440 return false;
c799a79d
NC
20441 }
20442
6f156d7a
NC
20443 name = NULL;
20444 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20445 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20446 in order to avoid them being confused with the start address of the
20447 first function in the file... */
20448 if (sym == NULL && is_open_attr)
20449 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20450 & name);
6f156d7a
NC
20451
20452 if (end == 0 && sym != NULL && sym->st_size > 0)
20453 end = start + sym->st_size;
c799a79d
NC
20454
20455 if (is_open_attr)
20456 {
d20e98ab
NC
20457 /* FIXME: Need to properly allow for section alignment.
20458 16 is just the alignment used on x86_64. */
20459 if (global_end > 0
20460 && start > BFD_ALIGN (global_end, 16)
20461 /* Build notes are not guaranteed to be organised in order of
20462 increasing address, but we should find the all of the notes
20463 for one section in the same place. */
20464 && same_section (filedata, start, global_end))
6f156d7a
NC
20465 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20466 global_end + 1, start - 1);
20467
20468 printf (_(" Applies to region from %#lx"), start);
20469 global_offset = start;
20470
20471 if (end)
20472 {
20473 printf (_(" to %#lx"), end);
20474 global_end = end;
20475 }
c799a79d
NC
20476 }
20477 else
20478 {
6f156d7a
NC
20479 printf (_(" Applies to region from %#lx"), start);
20480 func_offset = start;
20481
20482 if (end)
20483 {
20484 printf (_(" to %#lx"), end);
20485 func_end = end;
20486 }
c799a79d
NC
20487 }
20488
6f156d7a
NC
20489 if (sym && name)
20490 printf (_(" (%s)"), name);
20491
20492 printf ("\n");
015dc7e1 20493 return true;
9ef920e9
NC
20494}
20495
015dc7e1 20496static bool
9ef920e9
NC
20497print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20498{
1d15e434
NC
20499 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20500 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20501 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20502 char name_type;
20503 char name_attribute;
1d15e434 20504 const char * expected_types;
9ef920e9
NC
20505 const char * name = pnote->namedata;
20506 const char * text;
88305e1b 20507 signed int left;
9ef920e9
NC
20508
20509 if (name == NULL || pnote->namesz < 2)
20510 {
20511 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20512 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20513 return false;
9ef920e9
NC
20514 }
20515
6f156d7a
NC
20516 if (do_wide)
20517 left = 28;
20518 else
20519 left = 20;
88305e1b
NC
20520
20521 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20522 if (name[0] == 'G' && name[1] == 'A')
20523 {
6f156d7a
NC
20524 if (pnote->namesz < 4)
20525 {
20526 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20527 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20528 return false;
6f156d7a
NC
20529 }
20530
88305e1b
NC
20531 printf ("GA");
20532 name += 2;
20533 left -= 2;
20534 }
20535
9ef920e9
NC
20536 switch ((name_type = * name))
20537 {
20538 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20539 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20540 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20541 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20542 printf ("%c", * name);
88305e1b 20543 left --;
9ef920e9
NC
20544 break;
20545 default:
20546 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20547 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20548 return false;
9ef920e9
NC
20549 }
20550
9ef920e9
NC
20551 ++ name;
20552 text = NULL;
20553
20554 switch ((name_attribute = * name))
20555 {
20556 case GNU_BUILD_ATTRIBUTE_VERSION:
20557 text = _("<version>");
1d15e434 20558 expected_types = string_expected;
9ef920e9
NC
20559 ++ name;
20560 break;
20561 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20562 text = _("<stack prot>");
75d7d298 20563 expected_types = "!+*";
9ef920e9
NC
20564 ++ name;
20565 break;
20566 case GNU_BUILD_ATTRIBUTE_RELRO:
20567 text = _("<relro>");
1d15e434 20568 expected_types = bool_expected;
9ef920e9
NC
20569 ++ name;
20570 break;
20571 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20572 text = _("<stack size>");
1d15e434 20573 expected_types = number_expected;
9ef920e9
NC
20574 ++ name;
20575 break;
20576 case GNU_BUILD_ATTRIBUTE_TOOL:
20577 text = _("<tool>");
1d15e434 20578 expected_types = string_expected;
9ef920e9
NC
20579 ++ name;
20580 break;
20581 case GNU_BUILD_ATTRIBUTE_ABI:
20582 text = _("<ABI>");
20583 expected_types = "$*";
20584 ++ name;
20585 break;
20586 case GNU_BUILD_ATTRIBUTE_PIC:
20587 text = _("<PIC>");
1d15e434 20588 expected_types = number_expected;
9ef920e9
NC
20589 ++ name;
20590 break;
a8be5506
NC
20591 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20592 text = _("<short enum>");
1d15e434 20593 expected_types = bool_expected;
a8be5506
NC
20594 ++ name;
20595 break;
9ef920e9
NC
20596 default:
20597 if (ISPRINT (* name))
20598 {
20599 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20600
20601 if (len > left && ! do_wide)
20602 len = left;
75d7d298 20603 printf ("%.*s:", len, name);
9ef920e9 20604 left -= len;
0dd6ae21 20605 name += len;
9ef920e9
NC
20606 }
20607 else
20608 {
3e6b6445 20609 static char tmpbuf [128];
88305e1b 20610
3e6b6445
NC
20611 error (_("unrecognised byte in name field: %d\n"), * name);
20612 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20613 text = tmpbuf;
20614 name ++;
9ef920e9
NC
20615 }
20616 expected_types = "*$!+";
20617 break;
20618 }
20619
20620 if (text)
88305e1b 20621 left -= printf ("%s", text);
9ef920e9
NC
20622
20623 if (strchr (expected_types, name_type) == NULL)
75d7d298 20624 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20625
20626 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20627 {
20628 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20629 (unsigned long) pnote->namesz,
20630 (long) (name - pnote->namedata));
015dc7e1 20631 return false;
9ef920e9
NC
20632 }
20633
20634 if (left < 1 && ! do_wide)
015dc7e1 20635 return true;
9ef920e9
NC
20636
20637 switch (name_type)
20638 {
20639 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20640 {
b06b2c92 20641 unsigned int bytes;
ddef72cd
NC
20642 unsigned long long val = 0;
20643 unsigned int shift = 0;
20644 char * decoded = NULL;
20645
b06b2c92
NC
20646 bytes = pnote->namesz - (name - pnote->namedata);
20647 if (bytes > 0)
20648 /* The -1 is because the name field is always 0 terminated, and we
20649 want to be able to ensure that the shift in the while loop below
20650 will not overflow. */
20651 -- bytes;
20652
ddef72cd
NC
20653 if (bytes > sizeof (val))
20654 {
3e6b6445
NC
20655 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20656 bytes);
20657 bytes = sizeof (val);
ddef72cd 20658 }
3e6b6445
NC
20659 /* We do not bother to warn if bytes == 0 as this can
20660 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20661
20662 while (bytes --)
20663 {
54b8331d 20664 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20665
20666 val |= byte << shift;
9ef920e9
NC
20667 shift += 8;
20668 }
20669
75d7d298 20670 switch (name_attribute)
9ef920e9 20671 {
75d7d298 20672 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20673 switch (val)
20674 {
75d7d298
NC
20675 case 0: decoded = "static"; break;
20676 case 1: decoded = "pic"; break;
20677 case 2: decoded = "PIC"; break;
20678 case 3: decoded = "pie"; break;
20679 case 4: decoded = "PIE"; break;
20680 default: break;
9ef920e9 20681 }
75d7d298
NC
20682 break;
20683 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20684 switch (val)
9ef920e9 20685 {
75d7d298
NC
20686 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20687 case 0: decoded = "off"; break;
20688 case 1: decoded = "on"; break;
20689 case 2: decoded = "all"; break;
20690 case 3: decoded = "strong"; break;
20691 case 4: decoded = "explicit"; break;
20692 default: break;
9ef920e9 20693 }
75d7d298
NC
20694 break;
20695 default:
20696 break;
9ef920e9
NC
20697 }
20698
75d7d298 20699 if (decoded != NULL)
3e6b6445
NC
20700 {
20701 print_symbol (-left, decoded);
20702 left = 0;
20703 }
20704 else if (val == 0)
20705 {
20706 printf ("0x0");
20707 left -= 3;
20708 }
9ef920e9 20709 else
75d7d298
NC
20710 {
20711 if (do_wide)
ddef72cd 20712 left -= printf ("0x%llx", val);
75d7d298 20713 else
ddef72cd 20714 left -= printf ("0x%-.*llx", left, val);
75d7d298 20715 }
9ef920e9
NC
20716 }
20717 break;
20718 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20719 left -= print_symbol (- left, name);
20720 break;
20721 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20722 left -= print_symbol (- left, "true");
20723 break;
20724 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20725 left -= print_symbol (- left, "false");
20726 break;
20727 }
20728
20729 if (do_wide && left > 0)
20730 printf ("%-*s", left, " ");
9abca702 20731
015dc7e1 20732 return true;
9ef920e9
NC
20733}
20734
6d118b09
NC
20735/* Note that by the ELF standard, the name field is already null byte
20736 terminated, and namesz includes the terminating null byte.
20737 I.E. the value of namesz for the name "FSF" is 4.
20738
e3c8793a 20739 If the value of namesz is zero, there is no name present. */
9ef920e9 20740
015dc7e1 20741static bool
9ef920e9 20742process_note (Elf_Internal_Note * pnote,
dda8d76d 20743 Filedata * filedata)
779fe533 20744{
2cf0635d
NC
20745 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20746 const char * nt;
9437c45b
JT
20747
20748 if (pnote->namesz == 0)
1ec5cd37
NC
20749 /* If there is no note name, then use the default set of
20750 note type strings. */
dda8d76d 20751 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20752
24d127aa 20753 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20754 /* GNU-specific object file notes. */
20755 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20756
24d127aa 20757 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20758 /* FreeBSD-specific core file notes. */
dda8d76d 20759 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20760
24d127aa 20761 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20762 /* NetBSD-specific core file notes. */
dda8d76d 20763 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20764
24d127aa 20765 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20766 /* NetBSD-specific core file notes. */
20767 return process_netbsd_elf_note (pnote);
20768
24d127aa 20769 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20770 /* NetBSD-specific core file notes. */
20771 return process_netbsd_elf_note (pnote);
20772
e9b095a5 20773 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20774 {
20775 /* SPU-specific core file notes. */
20776 nt = pnote->namedata + 4;
20777 name = "SPU";
20778 }
20779
24d127aa 20780 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20781 /* VMS/ia64-specific file notes. */
20782 nt = get_ia64_vms_note_type (pnote->type);
20783
24d127aa 20784 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20785 nt = get_stapsdt_note_type (pnote->type);
20786
9437c45b 20787 else
1ec5cd37
NC
20788 /* Don't recognize this note name; just use the default set of
20789 note type strings. */
dda8d76d 20790 nt = get_note_type (filedata, pnote->type);
9437c45b 20791
1449284b 20792 printf (" ");
9ef920e9 20793
24d127aa 20794 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20795 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20796 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20797 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20798 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20799 print_gnu_build_attribute_name (pnote);
20800 else
20801 print_symbol (-20, name);
20802
20803 if (do_wide)
20804 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20805 else
20806 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20807
24d127aa 20808 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20809 return print_ia64_vms_note (pnote);
24d127aa 20810 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20811 return print_gnu_note (filedata, pnote);
24d127aa 20812 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20813 return print_stapsdt_note (pnote);
24d127aa 20814 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20815 return print_core_note (pnote);
24d127aa 20816 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20817 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20818 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20819 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20820 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20821 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20822
9ef920e9 20823 if (pnote->descsz)
1449284b
NC
20824 {
20825 unsigned long i;
20826
20827 printf (_(" description data: "));
20828 for (i = 0; i < pnote->descsz; i++)
178d8719 20829 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20830 if (!do_wide)
20831 printf ("\n");
1449284b
NC
20832 }
20833
9ef920e9
NC
20834 if (do_wide)
20835 printf ("\n");
20836
015dc7e1 20837 return true;
1449284b 20838}
6d118b09 20839
015dc7e1 20840static bool
dda8d76d
NC
20841process_notes_at (Filedata * filedata,
20842 Elf_Internal_Shdr * section,
20843 bfd_vma offset,
82ed9683
L
20844 bfd_vma length,
20845 bfd_vma align)
779fe533 20846{
015dc7e1
AM
20847 Elf_External_Note *pnotes;
20848 Elf_External_Note *external;
20849 char *end;
20850 bool res = true;
103f02d3 20851
779fe533 20852 if (length <= 0)
015dc7e1 20853 return false;
103f02d3 20854
1449284b
NC
20855 if (section)
20856 {
dda8d76d 20857 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20858 if (pnotes)
32ec8896 20859 {
dda8d76d 20860 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20861 {
20862 free (pnotes);
015dc7e1 20863 return false;
f761cb13 20864 }
32ec8896 20865 }
1449284b
NC
20866 }
20867 else
82ed9683 20868 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20869 _("notes"));
4dff97b2 20870
dd24e3da 20871 if (pnotes == NULL)
015dc7e1 20872 return false;
779fe533 20873
103f02d3 20874 external = pnotes;
103f02d3 20875
ca0e11aa
NC
20876 if (filedata->is_separate)
20877 printf (_("In linked file '%s': "), filedata->file_name);
20878 else
20879 printf ("\n");
1449284b 20880 if (section)
ca0e11aa 20881 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20882 else
ca0e11aa 20883 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20884 (unsigned long) offset, (unsigned long) length);
20885
82ed9683
L
20886 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20887 specifies that notes should be aligned to 4 bytes in 32-bit
20888 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20889 we also support 4 byte alignment in 64-bit objects. If section
20890 alignment is less than 4, we treate alignment as 4 bytes. */
20891 if (align < 4)
20892 align = 4;
20893 else if (align != 4 && align != 8)
20894 {
20895 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20896 (long) align);
a788aedd 20897 free (pnotes);
015dc7e1 20898 return false;
82ed9683
L
20899 }
20900
dbe15e4e 20901 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20902
c8071705
NC
20903 end = (char *) pnotes + length;
20904 while ((char *) external < end)
779fe533 20905 {
b34976b6 20906 Elf_Internal_Note inote;
15b42fb0 20907 size_t min_notesz;
4dff97b2 20908 char * next;
2cf0635d 20909 char * temp = NULL;
c8071705 20910 size_t data_remaining = end - (char *) external;
6d118b09 20911
dda8d76d 20912 if (!is_ia64_vms (filedata))
15b42fb0 20913 {
9dd3a467
NC
20914 /* PR binutils/15191
20915 Make sure that there is enough data to read. */
15b42fb0
AM
20916 min_notesz = offsetof (Elf_External_Note, name);
20917 if (data_remaining < min_notesz)
9dd3a467 20918 {
d3a49aa8
AM
20919 warn (ngettext ("Corrupt note: only %ld byte remains, "
20920 "not enough for a full note\n",
20921 "Corrupt note: only %ld bytes remain, "
20922 "not enough for a full note\n",
20923 data_remaining),
20924 (long) data_remaining);
9dd3a467
NC
20925 break;
20926 }
5396a86e
AM
20927 data_remaining -= min_notesz;
20928
15b42fb0
AM
20929 inote.type = BYTE_GET (external->type);
20930 inote.namesz = BYTE_GET (external->namesz);
20931 inote.namedata = external->name;
20932 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20933 inote.descdata = ((char *) external
4dff97b2 20934 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20935 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20936 next = ((char *) external
4dff97b2 20937 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20938 }
00e98fc7 20939 else
15b42fb0
AM
20940 {
20941 Elf64_External_VMS_Note *vms_external;
00e98fc7 20942
9dd3a467
NC
20943 /* PR binutils/15191
20944 Make sure that there is enough data to read. */
15b42fb0
AM
20945 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20946 if (data_remaining < min_notesz)
9dd3a467 20947 {
d3a49aa8
AM
20948 warn (ngettext ("Corrupt note: only %ld byte remains, "
20949 "not enough for a full note\n",
20950 "Corrupt note: only %ld bytes remain, "
20951 "not enough for a full note\n",
20952 data_remaining),
20953 (long) data_remaining);
9dd3a467
NC
20954 break;
20955 }
5396a86e 20956 data_remaining -= min_notesz;
3e55a963 20957
15b42fb0
AM
20958 vms_external = (Elf64_External_VMS_Note *) external;
20959 inote.type = BYTE_GET (vms_external->type);
20960 inote.namesz = BYTE_GET (vms_external->namesz);
20961 inote.namedata = vms_external->name;
20962 inote.descsz = BYTE_GET (vms_external->descsz);
20963 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20964 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20965 next = inote.descdata + align_power (inote.descsz, 3);
20966 }
20967
5396a86e
AM
20968 /* PR 17531: file: 3443835e. */
20969 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20970 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20971 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20972 || (size_t) (next - inote.descdata) < inote.descsz
20973 || ((size_t) (next - inote.descdata)
20974 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20975 {
15b42fb0 20976 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20977 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20978 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20979 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20980 break;
20981 }
20982
15b42fb0 20983 external = (Elf_External_Note *) next;
dd24e3da 20984
6d118b09
NC
20985 /* Verify that name is null terminated. It appears that at least
20986 one version of Linux (RedHat 6.0) generates corefiles that don't
20987 comply with the ELF spec by failing to include the null byte in
20988 namesz. */
18344509 20989 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20990 {
5396a86e 20991 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20992 {
5396a86e
AM
20993 temp = (char *) malloc (inote.namesz + 1);
20994 if (temp == NULL)
20995 {
20996 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20997 res = false;
5396a86e
AM
20998 break;
20999 }
76da6bbe 21000
5396a86e
AM
21001 memcpy (temp, inote.namedata, inote.namesz);
21002 inote.namedata = temp;
21003 }
21004 inote.namedata[inote.namesz] = 0;
6d118b09
NC
21005 }
21006
dda8d76d 21007 if (! process_note (& inote, filedata))
015dc7e1 21008 res = false;
103f02d3 21009
9db70fc3
AM
21010 free (temp);
21011 temp = NULL;
779fe533
NC
21012 }
21013
21014 free (pnotes);
103f02d3 21015
779fe533
NC
21016 return res;
21017}
21018
015dc7e1 21019static bool
dda8d76d 21020process_corefile_note_segments (Filedata * filedata)
779fe533 21021{
015dc7e1 21022 Elf_Internal_Phdr *segment;
b34976b6 21023 unsigned int i;
015dc7e1 21024 bool res = true;
103f02d3 21025
dda8d76d 21026 if (! get_program_headers (filedata))
015dc7e1 21027 return true;
103f02d3 21028
dda8d76d
NC
21029 for (i = 0, segment = filedata->program_headers;
21030 i < filedata->file_header.e_phnum;
b34976b6 21031 i++, segment++)
779fe533
NC
21032 {
21033 if (segment->p_type == PT_NOTE)
dda8d76d 21034 if (! process_notes_at (filedata, NULL,
32ec8896 21035 (bfd_vma) segment->p_offset,
82ed9683
L
21036 (bfd_vma) segment->p_filesz,
21037 (bfd_vma) segment->p_align))
015dc7e1 21038 res = false;
779fe533 21039 }
103f02d3 21040
779fe533
NC
21041 return res;
21042}
21043
015dc7e1 21044static bool
dda8d76d 21045process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
21046{
21047 Elf_External_Note * pnotes;
21048 Elf_External_Note * external;
c8071705 21049 char * end;
015dc7e1 21050 bool res = true;
685080f2
NC
21051
21052 if (length <= 0)
015dc7e1 21053 return false;
685080f2 21054
dda8d76d 21055 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
21056 _("v850 notes"));
21057 if (pnotes == NULL)
015dc7e1 21058 return false;
685080f2
NC
21059
21060 external = pnotes;
c8071705 21061 end = (char*) pnotes + length;
685080f2
NC
21062
21063 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21064 (unsigned long) offset, (unsigned long) length);
21065
c8071705 21066 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21067 {
21068 Elf_External_Note * next;
21069 Elf_Internal_Note inote;
21070
21071 inote.type = BYTE_GET (external->type);
21072 inote.namesz = BYTE_GET (external->namesz);
21073 inote.namedata = external->name;
21074 inote.descsz = BYTE_GET (external->descsz);
21075 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21076 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21077
c8071705
NC
21078 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21079 {
21080 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21081 inote.descdata = inote.namedata;
21082 inote.namesz = 0;
21083 }
21084
685080f2
NC
21085 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21086
c8071705 21087 if ( ((char *) next > end)
685080f2
NC
21088 || ((char *) next < (char *) pnotes))
21089 {
21090 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21091 (unsigned long) ((char *) external - (char *) pnotes));
21092 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21093 inote.type, inote.namesz, inote.descsz);
21094 break;
21095 }
21096
21097 external = next;
21098
21099 /* Prevent out-of-bounds indexing. */
c8071705 21100 if ( inote.namedata + inote.namesz > end
685080f2
NC
21101 || inote.namedata + inote.namesz < inote.namedata)
21102 {
21103 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21104 (unsigned long) ((char *) external - (char *) pnotes));
21105 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21106 inote.type, inote.namesz, inote.descsz);
21107 break;
21108 }
21109
21110 printf (" %s: ", get_v850_elf_note_type (inote.type));
21111
21112 if (! print_v850_note (& inote))
21113 {
015dc7e1 21114 res = false;
685080f2
NC
21115 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21116 inote.namesz, inote.descsz);
21117 }
21118 }
21119
21120 free (pnotes);
21121
21122 return res;
21123}
21124
015dc7e1 21125static bool
dda8d76d 21126process_note_sections (Filedata * filedata)
1ec5cd37 21127{
015dc7e1 21128 Elf_Internal_Shdr *section;
1ec5cd37 21129 unsigned long i;
32ec8896 21130 unsigned int n = 0;
015dc7e1 21131 bool res = true;
1ec5cd37 21132
dda8d76d
NC
21133 for (i = 0, section = filedata->section_headers;
21134 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21135 i++, section++)
685080f2
NC
21136 {
21137 if (section->sh_type == SHT_NOTE)
21138 {
dda8d76d 21139 if (! process_notes_at (filedata, section,
32ec8896 21140 (bfd_vma) section->sh_offset,
82ed9683
L
21141 (bfd_vma) section->sh_size,
21142 (bfd_vma) section->sh_addralign))
015dc7e1 21143 res = false;
685080f2
NC
21144 n++;
21145 }
21146
dda8d76d
NC
21147 if (( filedata->file_header.e_machine == EM_V800
21148 || filedata->file_header.e_machine == EM_V850
21149 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21150 && section->sh_type == SHT_RENESAS_INFO)
21151 {
dda8d76d 21152 if (! process_v850_notes (filedata,
32ec8896
NC
21153 (bfd_vma) section->sh_offset,
21154 (bfd_vma) section->sh_size))
015dc7e1 21155 res = false;
685080f2
NC
21156 n++;
21157 }
21158 }
df565f32
NC
21159
21160 if (n == 0)
21161 /* Try processing NOTE segments instead. */
dda8d76d 21162 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21163
21164 return res;
21165}
21166
015dc7e1 21167static bool
dda8d76d 21168process_notes (Filedata * filedata)
779fe533
NC
21169{
21170 /* If we have not been asked to display the notes then do nothing. */
21171 if (! do_notes)
015dc7e1 21172 return true;
103f02d3 21173
dda8d76d
NC
21174 if (filedata->file_header.e_type != ET_CORE)
21175 return process_note_sections (filedata);
103f02d3 21176
779fe533 21177 /* No program headers means no NOTE segment. */
dda8d76d
NC
21178 if (filedata->file_header.e_phnum > 0)
21179 return process_corefile_note_segments (filedata);
779fe533 21180
ca0e11aa
NC
21181 if (filedata->is_separate)
21182 printf (_("No notes found in linked file '%s'.\n"),
21183 filedata->file_name);
21184 else
21185 printf (_("No notes found file.\n"));
21186
015dc7e1 21187 return true;
779fe533
NC
21188}
21189
60abdbed
NC
21190static unsigned char *
21191display_public_gnu_attributes (unsigned char * start,
21192 const unsigned char * const end)
21193{
21194 printf (_(" Unknown GNU attribute: %s\n"), start);
21195
21196 start += strnlen ((char *) start, end - start);
21197 display_raw_attribute (start, end);
21198
21199 return (unsigned char *) end;
21200}
21201
21202static unsigned char *
21203display_generic_attribute (unsigned char * start,
21204 unsigned int tag,
21205 const unsigned char * const end)
21206{
21207 if (tag == 0)
21208 return (unsigned char *) end;
21209
21210 return display_tag_value (tag, start, end);
21211}
21212
015dc7e1 21213static bool
dda8d76d 21214process_arch_specific (Filedata * filedata)
252b5132 21215{
a952a375 21216 if (! do_arch)
015dc7e1 21217 return true;
a952a375 21218
dda8d76d 21219 switch (filedata->file_header.e_machine)
252b5132 21220 {
53a346d8
CZ
21221 case EM_ARC:
21222 case EM_ARC_COMPACT:
21223 case EM_ARC_COMPACT2:
dda8d76d 21224 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21225 display_arc_attribute,
21226 display_generic_attribute);
11c1ff18 21227 case EM_ARM:
dda8d76d 21228 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21229 display_arm_attribute,
21230 display_generic_attribute);
21231
252b5132 21232 case EM_MIPS:
4fe85591 21233 case EM_MIPS_RS3_LE:
dda8d76d 21234 return process_mips_specific (filedata);
60abdbed
NC
21235
21236 case EM_MSP430:
dda8d76d 21237 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21238 display_msp430_attribute,
c0ea7c52 21239 display_msp430_gnu_attribute);
60abdbed 21240
2dc8dd17
JW
21241 case EM_RISCV:
21242 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21243 display_riscv_attribute,
21244 display_generic_attribute);
21245
35c08157 21246 case EM_NDS32:
dda8d76d 21247 return process_nds32_specific (filedata);
60abdbed 21248
85f7484a
PB
21249 case EM_68K:
21250 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21251 display_m68k_gnu_attribute);
21252
34c8bcba 21253 case EM_PPC:
b82317dd 21254 case EM_PPC64:
dda8d76d 21255 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21256 display_power_gnu_attribute);
21257
643f7afb
AK
21258 case EM_S390:
21259 case EM_S390_OLD:
dda8d76d 21260 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21261 display_s390_gnu_attribute);
21262
9e8c70f9
DM
21263 case EM_SPARC:
21264 case EM_SPARC32PLUS:
21265 case EM_SPARCV9:
dda8d76d 21266 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21267 display_sparc_gnu_attribute);
21268
59e6276b 21269 case EM_TI_C6000:
dda8d76d 21270 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21271 display_tic6x_attribute,
21272 display_generic_attribute);
21273
0861f561
CQ
21274 case EM_CSKY:
21275 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21276 display_csky_attribute, NULL);
21277
252b5132 21278 default:
dda8d76d 21279 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21280 display_public_gnu_attributes,
21281 display_generic_attribute);
252b5132 21282 }
252b5132
RH
21283}
21284
015dc7e1 21285static bool
dda8d76d 21286get_file_header (Filedata * filedata)
252b5132 21287{
9ea033b2 21288 /* Read in the identity array. */
dda8d76d 21289 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21290 return false;
252b5132 21291
9ea033b2 21292 /* Determine how to read the rest of the header. */
dda8d76d 21293 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21294 {
1a0670f3
AM
21295 default:
21296 case ELFDATANONE:
adab8cdc
AO
21297 case ELFDATA2LSB:
21298 byte_get = byte_get_little_endian;
21299 byte_put = byte_put_little_endian;
21300 break;
21301 case ELFDATA2MSB:
21302 byte_get = byte_get_big_endian;
21303 byte_put = byte_put_big_endian;
21304 break;
9ea033b2
NC
21305 }
21306
21307 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21308 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21309
21310 /* Read in the rest of the header. */
21311 if (is_32bit_elf)
21312 {
21313 Elf32_External_Ehdr ehdr32;
252b5132 21314
dda8d76d 21315 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21316 return false;
103f02d3 21317
dda8d76d
NC
21318 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21319 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21320 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21321 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21322 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21323 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21324 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21325 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21326 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21327 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21328 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21329 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21330 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21331 }
252b5132 21332 else
9ea033b2
NC
21333 {
21334 Elf64_External_Ehdr ehdr64;
a952a375
NC
21335
21336 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21337 we will not be able to cope with the 64bit data found in
21338 64 ELF files. Detect this now and abort before we start
50c2245b 21339 overwriting things. */
a952a375
NC
21340 if (sizeof (bfd_vma) < 8)
21341 {
e3c8793a
NC
21342 error (_("This instance of readelf has been built without support for a\n\
2134364 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21344 return false;
a952a375 21345 }
103f02d3 21346
dda8d76d 21347 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21348 return false;
103f02d3 21349
dda8d76d
NC
21350 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21351 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21352 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21353 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21354 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21355 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21356 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21357 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21358 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21359 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21360 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21361 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21362 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21363 }
252b5132 21364
015dc7e1 21365 return true;
252b5132
RH
21366}
21367
13acb58d
AM
21368static void
21369free_filedata (Filedata *filedata)
21370{
21371 free (filedata->program_interpreter);
13acb58d 21372 free (filedata->program_headers);
13acb58d 21373 free (filedata->section_headers);
13acb58d 21374 free (filedata->string_table);
13acb58d 21375 free (filedata->dump.dump_sects);
13acb58d 21376 free (filedata->dynamic_strings);
13acb58d 21377 free (filedata->dynamic_symbols);
13acb58d 21378 free (filedata->dynamic_syminfo);
13acb58d 21379 free (filedata->dynamic_section);
13acb58d
AM
21380
21381 while (filedata->symtab_shndx_list != NULL)
21382 {
21383 elf_section_list *next = filedata->symtab_shndx_list->next;
21384 free (filedata->symtab_shndx_list);
21385 filedata->symtab_shndx_list = next;
21386 }
21387
21388 free (filedata->section_headers_groups);
13acb58d
AM
21389
21390 if (filedata->section_groups)
21391 {
21392 size_t i;
21393 struct group_list * g;
21394 struct group_list * next;
21395
21396 for (i = 0; i < filedata->group_count; i++)
21397 {
21398 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21399 {
21400 next = g->next;
21401 free (g);
21402 }
21403 }
21404
21405 free (filedata->section_groups);
13acb58d 21406 }
066f8fbe
AM
21407 memset (&filedata->section_headers, 0,
21408 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21409}
21410
dda8d76d
NC
21411static void
21412close_file (Filedata * filedata)
21413{
21414 if (filedata)
21415 {
21416 if (filedata->handle)
21417 fclose (filedata->handle);
21418 free (filedata);
21419 }
21420}
21421
21422void
21423close_debug_file (void * data)
21424{
13acb58d 21425 free_filedata ((Filedata *) data);
dda8d76d
NC
21426 close_file ((Filedata *) data);
21427}
21428
21429static Filedata *
015dc7e1 21430open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21431{
21432 struct stat statbuf;
21433 Filedata * filedata = NULL;
21434
21435 if (stat (pathname, & statbuf) < 0
21436 || ! S_ISREG (statbuf.st_mode))
21437 goto fail;
21438
21439 filedata = calloc (1, sizeof * filedata);
21440 if (filedata == NULL)
21441 goto fail;
21442
21443 filedata->handle = fopen (pathname, "rb");
21444 if (filedata->handle == NULL)
21445 goto fail;
21446
21447 filedata->file_size = (bfd_size_type) statbuf.st_size;
21448 filedata->file_name = pathname;
ca0e11aa 21449 filedata->is_separate = is_separate;
dda8d76d
NC
21450
21451 if (! get_file_header (filedata))
21452 goto fail;
21453
4de91c10
AM
21454 if (!get_section_headers (filedata, false))
21455 goto fail;
dda8d76d
NC
21456
21457 return filedata;
21458
21459 fail:
21460 if (filedata)
21461 {
21462 if (filedata->handle)
21463 fclose (filedata->handle);
21464 free (filedata);
21465 }
21466 return NULL;
21467}
21468
21469void *
21470open_debug_file (const char * pathname)
21471{
015dc7e1 21472 return open_file (pathname, true);
dda8d76d
NC
21473}
21474
835f2fae
NC
21475static void
21476initialise_dump_sects (Filedata * filedata)
21477{
21478 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21479 Note we do this even if cmdline_dump_sects is empty because we
21480 must make sure that the dump_sets array is zeroed out before each
21481 object file is processed. */
21482 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21483 memset (filedata->dump.dump_sects, 0,
21484 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21485
21486 if (cmdline.num_dump_sects > 0)
21487 {
21488 if (filedata->dump.num_dump_sects == 0)
21489 /* A sneaky way of allocating the dump_sects array. */
21490 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21491
21492 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21493 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21494 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21495 }
21496}
21497
fb52b2f4
NC
21498/* Process one ELF object file according to the command line options.
21499 This file may actually be stored in an archive. The file is
32ec8896
NC
21500 positioned at the start of the ELF object. Returns TRUE if no
21501 problems were encountered, FALSE otherwise. */
fb52b2f4 21502
015dc7e1 21503static bool
dda8d76d 21504process_object (Filedata * filedata)
252b5132 21505{
015dc7e1 21506 bool have_separate_files;
252b5132 21507 unsigned int i;
015dc7e1 21508 bool res;
252b5132 21509
dda8d76d 21510 if (! get_file_header (filedata))
252b5132 21511 {
dda8d76d 21512 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21513 return false;
252b5132
RH
21514 }
21515
21516 /* Initialise per file variables. */
978c4450
AM
21517 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21518 filedata->version_info[i] = 0;
252b5132 21519
978c4450
AM
21520 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21521 filedata->dynamic_info[i] = 0;
21522 filedata->dynamic_info_DT_GNU_HASH = 0;
21523 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21524
21525 /* Process the file. */
21526 if (show_name)
dda8d76d 21527 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21528
835f2fae 21529 initialise_dump_sects (filedata);
d70c5fc7 21530
4de91c10
AM
21531 /* There may be some extensions in the first section header. Don't
21532 bomb if we can't read it. */
21533 get_section_headers (filedata, true);
21534
dda8d76d 21535 if (! process_file_header (filedata))
4de91c10
AM
21536 {
21537 res = false;
21538 goto out;
21539 }
252b5132 21540
e331b18d
AM
21541 /* Throw away the single section header read above, so that we
21542 re-read the entire set. */
21543 free (filedata->section_headers);
21544 filedata->section_headers = NULL;
21545
dda8d76d 21546 if (! process_section_headers (filedata))
2f62977e 21547 {
32ec8896 21548 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21549 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21550
2f62977e 21551 if (! do_using_dynamic)
015dc7e1 21552 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21553 }
252b5132 21554
dda8d76d 21555 if (! process_section_groups (filedata))
32ec8896 21556 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21557 do_unwind = false;
d1f5c6e3 21558
93df3340
AM
21559 process_program_headers (filedata);
21560
21561 res = process_dynamic_section (filedata);
252b5132 21562
dda8d76d 21563 if (! process_relocs (filedata))
015dc7e1 21564 res = false;
252b5132 21565
dda8d76d 21566 if (! process_unwind (filedata))
015dc7e1 21567 res = false;
4d6ed7c8 21568
dda8d76d 21569 if (! process_symbol_table (filedata))
015dc7e1 21570 res = false;
252b5132 21571
0f03783c 21572 if (! process_lto_symbol_tables (filedata))
015dc7e1 21573 res = false;
b9e920ec 21574
dda8d76d 21575 if (! process_syminfo (filedata))
015dc7e1 21576 res = false;
252b5132 21577
dda8d76d 21578 if (! process_version_sections (filedata))
015dc7e1 21579 res = false;
252b5132 21580
82ed9683 21581 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21582 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21583 else
015dc7e1 21584 have_separate_files = false;
dda8d76d
NC
21585
21586 if (! process_section_contents (filedata))
015dc7e1 21587 res = false;
f5842774 21588
24841daa 21589 if (have_separate_files)
dda8d76d 21590 {
24841daa
NC
21591 separate_info * d;
21592
21593 for (d = first_separate_info; d != NULL; d = d->next)
21594 {
835f2fae
NC
21595 initialise_dump_sects (d->handle);
21596
ca0e11aa 21597 if (process_links && ! process_file_header (d->handle))
015dc7e1 21598 res = false;
ca0e11aa 21599 else if (! process_section_headers (d->handle))
015dc7e1 21600 res = false;
d6bfbc39 21601 else if (! process_section_contents (d->handle))
015dc7e1 21602 res = false;
ca0e11aa
NC
21603 else if (process_links)
21604 {
ca0e11aa 21605 if (! process_section_groups (d->handle))
015dc7e1 21606 res = false;
93df3340 21607 process_program_headers (d->handle);
ca0e11aa 21608 if (! process_dynamic_section (d->handle))
015dc7e1 21609 res = false;
ca0e11aa 21610 if (! process_relocs (d->handle))
015dc7e1 21611 res = false;
ca0e11aa 21612 if (! process_unwind (d->handle))
015dc7e1 21613 res = false;
ca0e11aa 21614 if (! process_symbol_table (d->handle))
015dc7e1 21615 res = false;
ca0e11aa 21616 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21617 res = false;
ca0e11aa 21618 if (! process_syminfo (d->handle))
015dc7e1 21619 res = false;
ca0e11aa 21620 if (! process_version_sections (d->handle))
015dc7e1 21621 res = false;
ca0e11aa 21622 if (! process_notes (d->handle))
015dc7e1 21623 res = false;
ca0e11aa 21624 }
24841daa
NC
21625 }
21626
21627 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21628 }
21629
21630 if (! process_notes (filedata))
015dc7e1 21631 res = false;
103f02d3 21632
dda8d76d 21633 if (! process_gnu_liblist (filedata))
015dc7e1 21634 res = false;
047b2264 21635
dda8d76d 21636 if (! process_arch_specific (filedata))
015dc7e1 21637 res = false;
252b5132 21638
4de91c10 21639 out:
13acb58d 21640 free_filedata (filedata);
e4b17d5c 21641
19e6b90e 21642 free_debug_memory ();
18bd398b 21643
32ec8896 21644 return res;
252b5132
RH
21645}
21646
2cf0635d 21647/* Process an ELF archive.
32ec8896
NC
21648 On entry the file is positioned just after the ARMAG string.
21649 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21650
015dc7e1
AM
21651static bool
21652process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21653{
21654 struct archive_info arch;
21655 struct archive_info nested_arch;
21656 size_t got;
015dc7e1 21657 bool ret = true;
2cf0635d 21658
015dc7e1 21659 show_name = true;
2cf0635d
NC
21660
21661 /* The ARCH structure is used to hold information about this archive. */
21662 arch.file_name = NULL;
21663 arch.file = NULL;
21664 arch.index_array = NULL;
21665 arch.sym_table = NULL;
21666 arch.longnames = NULL;
21667
21668 /* The NESTED_ARCH structure is used as a single-item cache of information
21669 about a nested archive (when members of a thin archive reside within
21670 another regular archive file). */
21671 nested_arch.file_name = NULL;
21672 nested_arch.file = NULL;
21673 nested_arch.index_array = NULL;
21674 nested_arch.sym_table = NULL;
21675 nested_arch.longnames = NULL;
21676
dda8d76d 21677 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21678 filedata->file_size, is_thin_archive,
21679 do_archive_index) != 0)
2cf0635d 21680 {
015dc7e1 21681 ret = false;
2cf0635d 21682 goto out;
4145f1d5 21683 }
fb52b2f4 21684
4145f1d5
NC
21685 if (do_archive_index)
21686 {
2cf0635d 21687 if (arch.sym_table == NULL)
1cb7d8b1
AM
21688 error (_("%s: unable to dump the index as none was found\n"),
21689 filedata->file_name);
4145f1d5
NC
21690 else
21691 {
591f7597 21692 unsigned long i, l;
4145f1d5
NC
21693 unsigned long current_pos;
21694
1cb7d8b1
AM
21695 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21696 "in the symbol table)\n"),
21697 filedata->file_name, (unsigned long) arch.index_num,
21698 arch.sym_size);
dda8d76d
NC
21699
21700 current_pos = ftell (filedata->handle);
4145f1d5 21701
2cf0635d 21702 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21703 {
1cb7d8b1
AM
21704 if (i == 0
21705 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21706 {
21707 char * member_name
21708 = get_archive_member_name_at (&arch, arch.index_array[i],
21709 &nested_arch);
2cf0635d 21710
1cb7d8b1
AM
21711 if (member_name != NULL)
21712 {
21713 char * qualified_name
21714 = make_qualified_name (&arch, &nested_arch,
21715 member_name);
2cf0635d 21716
1cb7d8b1
AM
21717 if (qualified_name != NULL)
21718 {
21719 printf (_("Contents of binary %s at offset "),
21720 qualified_name);
c2a7d3f5
NC
21721 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21722 putchar ('\n');
1cb7d8b1
AM
21723 free (qualified_name);
21724 }
fd486f32 21725 free (member_name);
4145f1d5
NC
21726 }
21727 }
2cf0635d
NC
21728
21729 if (l >= arch.sym_size)
4145f1d5 21730 {
1cb7d8b1
AM
21731 error (_("%s: end of the symbol table reached "
21732 "before the end of the index\n"),
dda8d76d 21733 filedata->file_name);
015dc7e1 21734 ret = false;
cb8f3167 21735 break;
4145f1d5 21736 }
591f7597 21737 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21738 printf ("\t%.*s\n",
21739 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21740 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21741 }
21742
67ce483b 21743 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21744 l = (l + 7) & ~ 7;
21745 else
21746 l += l & 1;
21747
2cf0635d 21748 if (l < arch.sym_size)
32ec8896 21749 {
d3a49aa8
AM
21750 error (ngettext ("%s: %ld byte remains in the symbol table, "
21751 "but without corresponding entries in "
21752 "the index table\n",
21753 "%s: %ld bytes remain in the symbol table, "
21754 "but without corresponding entries in "
21755 "the index table\n",
21756 arch.sym_size - l),
dda8d76d 21757 filedata->file_name, arch.sym_size - l);
015dc7e1 21758 ret = false;
32ec8896 21759 }
4145f1d5 21760
dda8d76d 21761 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21762 {
1cb7d8b1
AM
21763 error (_("%s: failed to seek back to start of object files "
21764 "in the archive\n"),
dda8d76d 21765 filedata->file_name);
015dc7e1 21766 ret = false;
2cf0635d 21767 goto out;
4145f1d5 21768 }
fb52b2f4 21769 }
4145f1d5
NC
21770
21771 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21772 && !do_segments && !do_header && !do_dump && !do_version
21773 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21774 && !do_section_groups && !do_dyn_syms)
2cf0635d 21775 {
015dc7e1 21776 ret = true; /* Archive index only. */
2cf0635d
NC
21777 goto out;
21778 }
fb52b2f4
NC
21779 }
21780
fb52b2f4
NC
21781 while (1)
21782 {
2cf0635d
NC
21783 char * name;
21784 size_t namelen;
21785 char * qualified_name;
21786
21787 /* Read the next archive header. */
dda8d76d 21788 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21789 {
21790 error (_("%s: failed to seek to next archive header\n"),
21791 arch.file_name);
015dc7e1 21792 ret = false;
1cb7d8b1
AM
21793 break;
21794 }
dda8d76d 21795 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21796 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21797 {
21798 if (got == 0)
2cf0635d 21799 break;
28e817cc
NC
21800 /* PR 24049 - we cannot use filedata->file_name as this will
21801 have already been freed. */
21802 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21803
015dc7e1 21804 ret = false;
1cb7d8b1
AM
21805 break;
21806 }
2cf0635d 21807 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21808 {
21809 error (_("%s: did not find a valid archive header\n"),
21810 arch.file_name);
015dc7e1 21811 ret = false;
1cb7d8b1
AM
21812 break;
21813 }
2cf0635d
NC
21814
21815 arch.next_arhdr_offset += sizeof arch.arhdr;
21816
978c4450 21817 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
2cf0635d
NC
21818
21819 name = get_archive_member_name (&arch, &nested_arch);
21820 if (name == NULL)
fb52b2f4 21821 {
28e817cc 21822 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21823 ret = false;
d989285c 21824 break;
fb52b2f4 21825 }
2cf0635d 21826 namelen = strlen (name);
fb52b2f4 21827
2cf0635d
NC
21828 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21829 if (qualified_name == NULL)
fb52b2f4 21830 {
28e817cc 21831 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21832 free (name);
015dc7e1 21833 ret = false;
d989285c 21834 break;
fb52b2f4
NC
21835 }
21836
2cf0635d 21837 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21838 {
21839 /* This is a proxy for an external member of a thin archive. */
21840 Filedata * member_filedata;
21841 char * member_file_name = adjust_relative_path
dda8d76d 21842 (filedata->file_name, name, namelen);
32ec8896 21843
fd486f32 21844 free (name);
1cb7d8b1
AM
21845 if (member_file_name == NULL)
21846 {
fd486f32 21847 free (qualified_name);
015dc7e1 21848 ret = false;
1cb7d8b1
AM
21849 break;
21850 }
2cf0635d 21851
015dc7e1 21852 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21853 if (member_filedata == NULL)
21854 {
21855 error (_("Input file '%s' is not readable.\n"), member_file_name);
21856 free (member_file_name);
fd486f32 21857 free (qualified_name);
015dc7e1 21858 ret = false;
1cb7d8b1
AM
21859 break;
21860 }
2cf0635d 21861
978c4450 21862 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21863 member_filedata->file_name = qualified_name;
2cf0635d 21864
75a2da57
AH
21865 /* The call to process_object() expects the file to be at the beginning. */
21866 rewind (member_filedata->handle);
21867
1cb7d8b1 21868 if (! process_object (member_filedata))
015dc7e1 21869 ret = false;
2cf0635d 21870
1cb7d8b1
AM
21871 close_file (member_filedata);
21872 free (member_file_name);
1cb7d8b1 21873 }
2cf0635d 21874 else if (is_thin_archive)
1cb7d8b1
AM
21875 {
21876 Filedata thin_filedata;
eb02c04d 21877
1cb7d8b1 21878 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21879
a043396b
NC
21880 /* PR 15140: Allow for corrupt thin archives. */
21881 if (nested_arch.file == NULL)
21882 {
21883 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21884 qualified_name, name);
fd486f32
AM
21885 free (qualified_name);
21886 free (name);
015dc7e1 21887 ret = false;
a043396b
NC
21888 break;
21889 }
fd486f32 21890 free (name);
a043396b 21891
1cb7d8b1 21892 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21893 filedata->archive_file_offset
21894 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21895
1cb7d8b1
AM
21896 /* The nested archive file will have been opened and setup by
21897 get_archive_member_name. */
978c4450
AM
21898 if (fseek (nested_arch.file, filedata->archive_file_offset,
21899 SEEK_SET) != 0)
1cb7d8b1
AM
21900 {
21901 error (_("%s: failed to seek to archive member.\n"),
21902 nested_arch.file_name);
fd486f32 21903 free (qualified_name);
015dc7e1 21904 ret = false;
1cb7d8b1
AM
21905 break;
21906 }
2cf0635d 21907
dda8d76d
NC
21908 thin_filedata.handle = nested_arch.file;
21909 thin_filedata.file_name = qualified_name;
9abca702 21910
1cb7d8b1 21911 if (! process_object (& thin_filedata))
015dc7e1 21912 ret = false;
1cb7d8b1 21913 }
2cf0635d 21914 else
1cb7d8b1 21915 {
fd486f32 21916 free (name);
978c4450 21917 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21918 filedata->file_name = qualified_name;
1cb7d8b1 21919 if (! process_object (filedata))
015dc7e1 21920 ret = false;
237877b8 21921 arch.next_arhdr_offset += (filedata->archive_file_size + 1) & -2;
4c836627 21922 /* Stop looping with "negative" archive_file_size. */
978c4450 21923 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21924 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21925 }
fb52b2f4 21926
2cf0635d 21927 free (qualified_name);
fb52b2f4
NC
21928 }
21929
4145f1d5 21930 out:
2cf0635d
NC
21931 if (nested_arch.file != NULL)
21932 fclose (nested_arch.file);
21933 release_archive (&nested_arch);
21934 release_archive (&arch);
fb52b2f4 21935
d989285c 21936 return ret;
fb52b2f4
NC
21937}
21938
015dc7e1 21939static bool
2cf0635d 21940process_file (char * file_name)
fb52b2f4 21941{
dda8d76d 21942 Filedata * filedata = NULL;
fb52b2f4
NC
21943 struct stat statbuf;
21944 char armag[SARMAG];
015dc7e1 21945 bool ret = true;
fb52b2f4
NC
21946
21947 if (stat (file_name, &statbuf) < 0)
21948 {
f24ddbdd
NC
21949 if (errno == ENOENT)
21950 error (_("'%s': No such file\n"), file_name);
21951 else
21952 error (_("Could not locate '%s'. System error message: %s\n"),
21953 file_name, strerror (errno));
015dc7e1 21954 return false;
f24ddbdd
NC
21955 }
21956
21957 if (! S_ISREG (statbuf.st_mode))
21958 {
21959 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21960 return false;
fb52b2f4
NC
21961 }
21962
dda8d76d
NC
21963 filedata = calloc (1, sizeof * filedata);
21964 if (filedata == NULL)
21965 {
21966 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21967 return false;
dda8d76d
NC
21968 }
21969
21970 filedata->file_name = file_name;
21971 filedata->handle = fopen (file_name, "rb");
21972 if (filedata->handle == NULL)
fb52b2f4 21973 {
f24ddbdd 21974 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21975 free (filedata);
015dc7e1 21976 return false;
fb52b2f4
NC
21977 }
21978
dda8d76d 21979 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21980 {
4145f1d5 21981 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21982 fclose (filedata->handle);
21983 free (filedata);
015dc7e1 21984 return false;
fb52b2f4
NC
21985 }
21986
dda8d76d 21987 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21988 filedata->is_separate = false;
f54498b4 21989
fb52b2f4 21990 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21991 {
015dc7e1
AM
21992 if (! process_archive (filedata, false))
21993 ret = false;
32ec8896 21994 }
2cf0635d 21995 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21996 {
015dc7e1
AM
21997 if ( ! process_archive (filedata, true))
21998 ret = false;
32ec8896 21999 }
fb52b2f4
NC
22000 else
22001 {
1b513401 22002 if (do_archive_index && !check_all)
4145f1d5
NC
22003 error (_("File %s is not an archive so its index cannot be displayed.\n"),
22004 file_name);
22005
dda8d76d 22006 rewind (filedata->handle);
978c4450 22007 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 22008
dda8d76d 22009 if (! process_object (filedata))
015dc7e1 22010 ret = false;
fb52b2f4
NC
22011 }
22012
dda8d76d 22013 fclose (filedata->handle);
8fb879cd
AM
22014 free (filedata->section_headers);
22015 free (filedata->program_headers);
22016 free (filedata->string_table);
6431e409 22017 free (filedata->dump.dump_sects);
dda8d76d 22018 free (filedata);
32ec8896 22019
fd486f32 22020 free (ba_cache.strtab);
1bd6175a 22021 ba_cache.strtab = NULL;
fd486f32 22022 free (ba_cache.symtab);
1bd6175a 22023 ba_cache.symtab = NULL;
fd486f32
AM
22024 ba_cache.filedata = NULL;
22025
fb52b2f4
NC
22026 return ret;
22027}
22028
252b5132
RH
22029#ifdef SUPPORT_DISASSEMBLY
22030/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 22031 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 22032 symbols. */
252b5132
RH
22033
22034void
2cf0635d 22035print_address (unsigned int addr, FILE * outfile)
252b5132
RH
22036{
22037 fprintf (outfile,"0x%8.8x", addr);
22038}
22039
e3c8793a 22040/* Needed by the i386 disassembler. */
dda8d76d 22041
252b5132
RH
22042void
22043db_task_printsym (unsigned int addr)
22044{
22045 print_address (addr, stderr);
22046}
22047#endif
22048
22049int
2cf0635d 22050main (int argc, char ** argv)
252b5132 22051{
ff78d6d6
L
22052 int err;
22053
87b9f255 22054#ifdef HAVE_LC_MESSAGES
252b5132 22055 setlocale (LC_MESSAGES, "");
3882b010 22056#endif
3882b010 22057 setlocale (LC_CTYPE, "");
252b5132
RH
22058 bindtextdomain (PACKAGE, LOCALEDIR);
22059 textdomain (PACKAGE);
22060
869b9d07
MM
22061 expandargv (&argc, &argv);
22062
dda8d76d 22063 parse_args (& cmdline, argc, argv);
59f14fc0 22064
18bd398b 22065 if (optind < (argc - 1))
1b513401
NC
22066 /* When displaying information for more than one file,
22067 prefix the information with the file name. */
015dc7e1 22068 show_name = true;
5656ba2c
L
22069 else if (optind >= argc)
22070 {
1b513401 22071 /* Ensure that the warning is always displayed. */
015dc7e1 22072 do_checks = true;
1b513401 22073
5656ba2c
L
22074 warn (_("Nothing to do.\n"));
22075 usage (stderr);
22076 }
18bd398b 22077
015dc7e1 22078 err = false;
252b5132 22079 while (optind < argc)
32ec8896 22080 if (! process_file (argv[optind++]))
015dc7e1 22081 err = true;
252b5132 22082
9db70fc3 22083 free (cmdline.dump_sects);
252b5132 22084
7d9813f1
NA
22085 free (dump_ctf_symtab_name);
22086 free (dump_ctf_strtab_name);
22087 free (dump_ctf_parent_name);
22088
32ec8896 22089 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22090}