]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
Automatic date update in version.in
[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
NC
10945 {
10946 if (filedata->dynamic_nent == 1)
10947 {
10948 if (filedata->is_separate)
10949 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains 1 entry:\n"),
10950 filedata->file_name,
10951 filedata->dynamic_addr);
10952 else
10953 printf (_("\nDynamic section at offset 0x%lx contains 1 entry:\n"),
10954 filedata->dynamic_addr);
10955 }
10956 else
10957 {
10958 if (filedata->is_separate)
10959 printf (_("\nIn linked file '%s' the dynamic section at offset 0x%lx contains %lu entries:\n"),
10960 filedata->file_name,
10961 filedata->dynamic_addr,
10962 (unsigned long) filedata->dynamic_nent);
10963 else
10964 printf (_("\nDynamic section at offset 0x%lx contains %lu entries:\n"),
10965 filedata->dynamic_addr,
10966 (unsigned long) filedata->dynamic_nent);
10967 }
10968 }
252b5132
RH
10969 if (do_dynamic)
10970 printf (_(" Tag Type Name/Value\n"));
10971
978c4450
AM
10972 for (entry = filedata->dynamic_section;
10973 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10974 entry++)
252b5132
RH
10975 {
10976 if (do_dynamic)
f7a99963 10977 {
2cf0635d 10978 const char * dtype;
e699b9ff 10979
f7a99963
NC
10980 putchar (' ');
10981 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10982 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10983 printf (" (%s)%*s", dtype,
32ec8896 10984 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10985 }
252b5132
RH
10986
10987 switch (entry->d_tag)
10988 {
d1133906
NC
10989 case DT_FLAGS:
10990 if (do_dynamic)
e9e44622 10991 print_dynamic_flags (entry->d_un.d_val);
d1133906 10992 break;
76da6bbe 10993
252b5132
RH
10994 case DT_AUXILIARY:
10995 case DT_FILTER:
019148e4
L
10996 case DT_CONFIG:
10997 case DT_DEPAUDIT:
10998 case DT_AUDIT:
252b5132
RH
10999 if (do_dynamic)
11000 {
019148e4 11001 switch (entry->d_tag)
b34976b6 11002 {
019148e4
L
11003 case DT_AUXILIARY:
11004 printf (_("Auxiliary library"));
11005 break;
11006
11007 case DT_FILTER:
11008 printf (_("Filter library"));
11009 break;
11010
b34976b6 11011 case DT_CONFIG:
019148e4
L
11012 printf (_("Configuration file"));
11013 break;
11014
11015 case DT_DEPAUDIT:
11016 printf (_("Dependency audit library"));
11017 break;
11018
11019 case DT_AUDIT:
11020 printf (_("Audit library"));
11021 break;
11022 }
252b5132 11023
978c4450
AM
11024 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11025 printf (": [%s]\n",
11026 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 11027 else
f7a99963
NC
11028 {
11029 printf (": ");
11030 print_vma (entry->d_un.d_val, PREFIX_HEX);
11031 putchar ('\n');
11032 }
252b5132
RH
11033 }
11034 break;
11035
dcefbbbd 11036 case DT_FEATURE:
252b5132
RH
11037 if (do_dynamic)
11038 {
11039 printf (_("Flags:"));
86f55779 11040
252b5132
RH
11041 if (entry->d_un.d_val == 0)
11042 printf (_(" None\n"));
11043 else
11044 {
11045 unsigned long int val = entry->d_un.d_val;
86f55779 11046
252b5132
RH
11047 if (val & DTF_1_PARINIT)
11048 {
11049 printf (" PARINIT");
11050 val ^= DTF_1_PARINIT;
11051 }
dcefbbbd
L
11052 if (val & DTF_1_CONFEXP)
11053 {
11054 printf (" CONFEXP");
11055 val ^= DTF_1_CONFEXP;
11056 }
252b5132
RH
11057 if (val != 0)
11058 printf (" %lx", val);
11059 puts ("");
11060 }
11061 }
11062 break;
11063
11064 case DT_POSFLAG_1:
11065 if (do_dynamic)
11066 {
11067 printf (_("Flags:"));
86f55779 11068
252b5132
RH
11069 if (entry->d_un.d_val == 0)
11070 printf (_(" None\n"));
11071 else
11072 {
11073 unsigned long int val = entry->d_un.d_val;
86f55779 11074
252b5132
RH
11075 if (val & DF_P1_LAZYLOAD)
11076 {
11077 printf (" LAZYLOAD");
11078 val ^= DF_P1_LAZYLOAD;
11079 }
11080 if (val & DF_P1_GROUPPERM)
11081 {
11082 printf (" GROUPPERM");
11083 val ^= DF_P1_GROUPPERM;
11084 }
11085 if (val != 0)
11086 printf (" %lx", val);
11087 puts ("");
11088 }
11089 }
11090 break;
11091
11092 case DT_FLAGS_1:
11093 if (do_dynamic)
11094 {
11095 printf (_("Flags:"));
11096 if (entry->d_un.d_val == 0)
11097 printf (_(" None\n"));
11098 else
11099 {
11100 unsigned long int val = entry->d_un.d_val;
86f55779 11101
252b5132
RH
11102 if (val & DF_1_NOW)
11103 {
11104 printf (" NOW");
11105 val ^= DF_1_NOW;
11106 }
11107 if (val & DF_1_GLOBAL)
11108 {
11109 printf (" GLOBAL");
11110 val ^= DF_1_GLOBAL;
11111 }
11112 if (val & DF_1_GROUP)
11113 {
11114 printf (" GROUP");
11115 val ^= DF_1_GROUP;
11116 }
11117 if (val & DF_1_NODELETE)
11118 {
11119 printf (" NODELETE");
11120 val ^= DF_1_NODELETE;
11121 }
11122 if (val & DF_1_LOADFLTR)
11123 {
11124 printf (" LOADFLTR");
11125 val ^= DF_1_LOADFLTR;
11126 }
11127 if (val & DF_1_INITFIRST)
11128 {
11129 printf (" INITFIRST");
11130 val ^= DF_1_INITFIRST;
11131 }
11132 if (val & DF_1_NOOPEN)
11133 {
11134 printf (" NOOPEN");
11135 val ^= DF_1_NOOPEN;
11136 }
11137 if (val & DF_1_ORIGIN)
11138 {
11139 printf (" ORIGIN");
11140 val ^= DF_1_ORIGIN;
11141 }
11142 if (val & DF_1_DIRECT)
11143 {
11144 printf (" DIRECT");
11145 val ^= DF_1_DIRECT;
11146 }
11147 if (val & DF_1_TRANS)
11148 {
11149 printf (" TRANS");
11150 val ^= DF_1_TRANS;
11151 }
11152 if (val & DF_1_INTERPOSE)
11153 {
11154 printf (" INTERPOSE");
11155 val ^= DF_1_INTERPOSE;
11156 }
f7db6139 11157 if (val & DF_1_NODEFLIB)
dcefbbbd 11158 {
f7db6139
L
11159 printf (" NODEFLIB");
11160 val ^= DF_1_NODEFLIB;
dcefbbbd
L
11161 }
11162 if (val & DF_1_NODUMP)
11163 {
11164 printf (" NODUMP");
11165 val ^= DF_1_NODUMP;
11166 }
34b60028 11167 if (val & DF_1_CONFALT)
dcefbbbd 11168 {
34b60028
L
11169 printf (" CONFALT");
11170 val ^= DF_1_CONFALT;
11171 }
11172 if (val & DF_1_ENDFILTEE)
11173 {
11174 printf (" ENDFILTEE");
11175 val ^= DF_1_ENDFILTEE;
11176 }
11177 if (val & DF_1_DISPRELDNE)
11178 {
11179 printf (" DISPRELDNE");
11180 val ^= DF_1_DISPRELDNE;
11181 }
11182 if (val & DF_1_DISPRELPND)
11183 {
11184 printf (" DISPRELPND");
11185 val ^= DF_1_DISPRELPND;
11186 }
11187 if (val & DF_1_NODIRECT)
11188 {
11189 printf (" NODIRECT");
11190 val ^= DF_1_NODIRECT;
11191 }
11192 if (val & DF_1_IGNMULDEF)
11193 {
11194 printf (" IGNMULDEF");
11195 val ^= DF_1_IGNMULDEF;
11196 }
11197 if (val & DF_1_NOKSYMS)
11198 {
11199 printf (" NOKSYMS");
11200 val ^= DF_1_NOKSYMS;
11201 }
11202 if (val & DF_1_NOHDR)
11203 {
11204 printf (" NOHDR");
11205 val ^= DF_1_NOHDR;
11206 }
11207 if (val & DF_1_EDITED)
11208 {
11209 printf (" EDITED");
11210 val ^= DF_1_EDITED;
11211 }
11212 if (val & DF_1_NORELOC)
11213 {
11214 printf (" NORELOC");
11215 val ^= DF_1_NORELOC;
11216 }
11217 if (val & DF_1_SYMINTPOSE)
11218 {
11219 printf (" SYMINTPOSE");
11220 val ^= DF_1_SYMINTPOSE;
11221 }
11222 if (val & DF_1_GLOBAUDIT)
11223 {
11224 printf (" GLOBAUDIT");
11225 val ^= DF_1_GLOBAUDIT;
11226 }
11227 if (val & DF_1_SINGLETON)
11228 {
11229 printf (" SINGLETON");
11230 val ^= DF_1_SINGLETON;
dcefbbbd 11231 }
5c383f02
RO
11232 if (val & DF_1_STUB)
11233 {
11234 printf (" STUB");
11235 val ^= DF_1_STUB;
11236 }
11237 if (val & DF_1_PIE)
11238 {
11239 printf (" PIE");
11240 val ^= DF_1_PIE;
11241 }
b1202ffa
L
11242 if (val & DF_1_KMOD)
11243 {
11244 printf (" KMOD");
11245 val ^= DF_1_KMOD;
11246 }
11247 if (val & DF_1_WEAKFILTER)
11248 {
11249 printf (" WEAKFILTER");
11250 val ^= DF_1_WEAKFILTER;
11251 }
11252 if (val & DF_1_NOCOMMON)
11253 {
11254 printf (" NOCOMMON");
11255 val ^= DF_1_NOCOMMON;
11256 }
252b5132
RH
11257 if (val != 0)
11258 printf (" %lx", val);
11259 puts ("");
11260 }
11261 }
11262 break;
11263
11264 case DT_PLTREL:
978c4450 11265 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 11266 if (do_dynamic)
dda8d76d 11267 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
11268 break;
11269
11270 case DT_NULL :
11271 case DT_NEEDED :
11272 case DT_PLTGOT :
11273 case DT_HASH :
11274 case DT_STRTAB :
11275 case DT_SYMTAB :
11276 case DT_RELA :
11277 case DT_INIT :
11278 case DT_FINI :
11279 case DT_SONAME :
11280 case DT_RPATH :
11281 case DT_SYMBOLIC:
11282 case DT_REL :
11283 case DT_DEBUG :
11284 case DT_TEXTREL :
11285 case DT_JMPREL :
019148e4 11286 case DT_RUNPATH :
978c4450 11287 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
11288
11289 if (do_dynamic)
11290 {
2cf0635d 11291 char * name;
252b5132 11292
978c4450
AM
11293 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
11294 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11295 else
d79b3d50 11296 name = NULL;
252b5132
RH
11297
11298 if (name)
11299 {
11300 switch (entry->d_tag)
11301 {
11302 case DT_NEEDED:
11303 printf (_("Shared library: [%s]"), name);
11304
13acb58d
AM
11305 if (filedata->program_interpreter
11306 && streq (name, filedata->program_interpreter))
f7a99963 11307 printf (_(" program interpreter"));
252b5132
RH
11308 break;
11309
11310 case DT_SONAME:
f7a99963 11311 printf (_("Library soname: [%s]"), name);
252b5132
RH
11312 break;
11313
11314 case DT_RPATH:
f7a99963 11315 printf (_("Library rpath: [%s]"), name);
252b5132
RH
11316 break;
11317
019148e4
L
11318 case DT_RUNPATH:
11319 printf (_("Library runpath: [%s]"), name);
11320 break;
11321
252b5132 11322 default:
f7a99963
NC
11323 print_vma (entry->d_un.d_val, PREFIX_HEX);
11324 break;
252b5132
RH
11325 }
11326 }
11327 else
f7a99963
NC
11328 print_vma (entry->d_un.d_val, PREFIX_HEX);
11329
11330 putchar ('\n');
252b5132
RH
11331 }
11332 break;
11333
11334 case DT_PLTRELSZ:
11335 case DT_RELASZ :
11336 case DT_STRSZ :
11337 case DT_RELSZ :
11338 case DT_RELAENT :
11339 case DT_SYMENT :
11340 case DT_RELENT :
978c4450 11341 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11342 /* Fall through. */
252b5132
RH
11343 case DT_PLTPADSZ:
11344 case DT_MOVEENT :
11345 case DT_MOVESZ :
11346 case DT_INIT_ARRAYSZ:
11347 case DT_FINI_ARRAYSZ:
047b2264
JJ
11348 case DT_GNU_CONFLICTSZ:
11349 case DT_GNU_LIBLISTSZ:
252b5132 11350 if (do_dynamic)
f7a99963
NC
11351 {
11352 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11353 printf (_(" (bytes)\n"));
f7a99963 11354 }
252b5132
RH
11355 break;
11356
11357 case DT_VERDEFNUM:
11358 case DT_VERNEEDNUM:
11359 case DT_RELACOUNT:
11360 case DT_RELCOUNT:
11361 if (do_dynamic)
f7a99963
NC
11362 {
11363 print_vma (entry->d_un.d_val, UNSIGNED);
11364 putchar ('\n');
11365 }
252b5132
RH
11366 break;
11367
11368 case DT_SYMINSZ:
11369 case DT_SYMINENT:
11370 case DT_SYMINFO:
11371 case DT_USED:
11372 case DT_INIT_ARRAY:
11373 case DT_FINI_ARRAY:
11374 if (do_dynamic)
11375 {
d79b3d50 11376 if (entry->d_tag == DT_USED
978c4450 11377 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11378 {
978c4450 11379 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11380
b34976b6 11381 if (*name)
252b5132
RH
11382 {
11383 printf (_("Not needed object: [%s]\n"), name);
11384 break;
11385 }
11386 }
103f02d3 11387
f7a99963
NC
11388 print_vma (entry->d_un.d_val, PREFIX_HEX);
11389 putchar ('\n');
252b5132
RH
11390 }
11391 break;
11392
11393 case DT_BIND_NOW:
11394 /* The value of this entry is ignored. */
35b1837e
AM
11395 if (do_dynamic)
11396 putchar ('\n');
252b5132 11397 break;
103f02d3 11398
047b2264
JJ
11399 case DT_GNU_PRELINKED:
11400 if (do_dynamic)
11401 {
2cf0635d 11402 struct tm * tmp;
91d6fa6a 11403 time_t atime = entry->d_un.d_val;
047b2264 11404
91d6fa6a 11405 tmp = gmtime (&atime);
071436c6
NC
11406 /* PR 17533 file: 041-1244816-0.004. */
11407 if (tmp == NULL)
5a2cbcf4
L
11408 printf (_("<corrupt time val: %lx"),
11409 (unsigned long) atime);
071436c6
NC
11410 else
11411 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11412 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11413 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11414
11415 }
11416 break;
11417
fdc90cb4 11418 case DT_GNU_HASH:
978c4450 11419 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11420 if (do_dynamic)
11421 {
11422 print_vma (entry->d_un.d_val, PREFIX_HEX);
11423 putchar ('\n');
11424 }
11425 break;
11426
a5da3dee
VDM
11427 case DT_GNU_FLAGS_1:
11428 if (do_dynamic)
11429 {
11430 printf (_("Flags:"));
11431 if (entry->d_un.d_val == 0)
11432 printf (_(" None\n"));
11433 else
11434 {
11435 unsigned long int val = entry->d_un.d_val;
11436
11437 if (val & DF_GNU_1_UNIQUE)
11438 {
11439 printf (" UNIQUE");
11440 val ^= DF_GNU_1_UNIQUE;
11441 }
11442 if (val != 0)
11443 printf (" %lx", val);
11444 puts ("");
11445 }
11446 }
11447 break;
11448
252b5132
RH
11449 default:
11450 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11451 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11452 = entry->d_un.d_val;
252b5132
RH
11453
11454 if (do_dynamic)
11455 {
dda8d76d 11456 switch (filedata->file_header.e_machine)
252b5132 11457 {
37c18eed
SD
11458 case EM_AARCH64:
11459 dynamic_section_aarch64_val (entry);
11460 break;
252b5132 11461 case EM_MIPS:
4fe85591 11462 case EM_MIPS_RS3_LE:
978c4450 11463 dynamic_section_mips_val (filedata, entry);
252b5132 11464 break;
103f02d3 11465 case EM_PARISC:
b2d38a17 11466 dynamic_section_parisc_val (entry);
103f02d3 11467 break;
ecc51f48 11468 case EM_IA_64:
b2d38a17 11469 dynamic_section_ia64_val (entry);
ecc51f48 11470 break;
252b5132 11471 default:
f7a99963
NC
11472 print_vma (entry->d_un.d_val, PREFIX_HEX);
11473 putchar ('\n');
252b5132
RH
11474 }
11475 }
11476 break;
11477 }
11478 }
11479
015dc7e1 11480 return true;
252b5132
RH
11481}
11482
11483static char *
d3ba0551 11484get_ver_flags (unsigned int flags)
252b5132 11485{
6d4f21f6 11486 static char buff[128];
252b5132
RH
11487
11488 buff[0] = 0;
11489
11490 if (flags == 0)
11491 return _("none");
11492
11493 if (flags & VER_FLG_BASE)
7bb1ad17 11494 strcat (buff, "BASE");
252b5132
RH
11495
11496 if (flags & VER_FLG_WEAK)
11497 {
11498 if (flags & VER_FLG_BASE)
7bb1ad17 11499 strcat (buff, " | ");
252b5132 11500
7bb1ad17 11501 strcat (buff, "WEAK");
252b5132
RH
11502 }
11503
44ec90b9
RO
11504 if (flags & VER_FLG_INFO)
11505 {
11506 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11507 strcat (buff, " | ");
44ec90b9 11508
7bb1ad17 11509 strcat (buff, "INFO");
44ec90b9
RO
11510 }
11511
11512 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11513 {
11514 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11515 strcat (buff, " | ");
11516
11517 strcat (buff, _("<unknown>"));
11518 }
252b5132
RH
11519
11520 return buff;
11521}
11522
11523/* Display the contents of the version sections. */
98fb390a 11524
015dc7e1 11525static bool
dda8d76d 11526process_version_sections (Filedata * filedata)
252b5132 11527{
2cf0635d 11528 Elf_Internal_Shdr * section;
b34976b6 11529 unsigned i;
015dc7e1 11530 bool found = false;
252b5132
RH
11531
11532 if (! do_version)
015dc7e1 11533 return true;
252b5132 11534
dda8d76d
NC
11535 for (i = 0, section = filedata->section_headers;
11536 i < filedata->file_header.e_shnum;
b34976b6 11537 i++, section++)
252b5132
RH
11538 {
11539 switch (section->sh_type)
11540 {
11541 case SHT_GNU_verdef:
11542 {
2cf0635d 11543 Elf_External_Verdef * edefs;
452bf675
AM
11544 unsigned long idx;
11545 unsigned long cnt;
2cf0635d 11546 char * endbuf;
252b5132 11547
015dc7e1 11548 found = true;
252b5132 11549
ca0e11aa
NC
11550 if (filedata->is_separate)
11551 printf (ngettext ("\nIn linked file '%s' the version definition section '%s' contains %u entry:\n",
11552 "\nIn linked file '%s' the version definition section '%s' contains %u entries:\n",
11553 section->sh_info),
11554 filedata->file_name,
11555 printable_section_name (filedata, section),
11556 section->sh_info);
11557 else
11558 printf (ngettext ("\nVersion definition section '%s' "
11559 "contains %u entry:\n",
11560 "\nVersion definition section '%s' "
11561 "contains %u entries:\n",
11562 section->sh_info),
11563 printable_section_name (filedata, section),
11564 section->sh_info);
047c3dbf 11565
ae9ac79e 11566 printf (_(" Addr: 0x"));
252b5132 11567 printf_vma (section->sh_addr);
233f82cf 11568 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11569 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11570 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11571
3f5e193b 11572 edefs = (Elf_External_Verdef *)
dda8d76d 11573 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11574 _("version definition section"));
a6e9f9df
AM
11575 if (!edefs)
11576 break;
59245841 11577 endbuf = (char *) edefs + section->sh_size;
252b5132 11578
1445030f 11579 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11580 {
2cf0635d
NC
11581 char * vstart;
11582 Elf_External_Verdef * edef;
b34976b6 11583 Elf_Internal_Verdef ent;
2cf0635d 11584 Elf_External_Verdaux * eaux;
b34976b6 11585 Elf_Internal_Verdaux aux;
452bf675 11586 unsigned long isum;
b34976b6 11587 int j;
103f02d3 11588
252b5132 11589 vstart = ((char *) edefs) + idx;
54806181
AM
11590 if (vstart + sizeof (*edef) > endbuf)
11591 break;
252b5132
RH
11592
11593 edef = (Elf_External_Verdef *) vstart;
11594
11595 ent.vd_version = BYTE_GET (edef->vd_version);
11596 ent.vd_flags = BYTE_GET (edef->vd_flags);
11597 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11598 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11599 ent.vd_hash = BYTE_GET (edef->vd_hash);
11600 ent.vd_aux = BYTE_GET (edef->vd_aux);
11601 ent.vd_next = BYTE_GET (edef->vd_next);
11602
452bf675 11603 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11604 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11605
11606 printf (_(" Index: %d Cnt: %d "),
11607 ent.vd_ndx, ent.vd_cnt);
11608
452bf675 11609 /* Check for overflow. */
1445030f 11610 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11611 break;
11612
252b5132
RH
11613 vstart += ent.vd_aux;
11614
1445030f
AM
11615 if (vstart + sizeof (*eaux) > endbuf)
11616 break;
252b5132
RH
11617 eaux = (Elf_External_Verdaux *) vstart;
11618
11619 aux.vda_name = BYTE_GET (eaux->vda_name);
11620 aux.vda_next = BYTE_GET (eaux->vda_next);
11621
978c4450
AM
11622 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11623 printf (_("Name: %s\n"),
11624 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11625 else
11626 printf (_("Name index: %ld\n"), aux.vda_name);
11627
11628 isum = idx + ent.vd_aux;
11629
b34976b6 11630 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11631 {
1445030f
AM
11632 if (aux.vda_next < sizeof (*eaux)
11633 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11634 {
11635 warn (_("Invalid vda_next field of %lx\n"),
11636 aux.vda_next);
11637 j = ent.vd_cnt;
11638 break;
11639 }
dd24e3da 11640 /* Check for overflow. */
7e26601c 11641 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11642 break;
11643
252b5132
RH
11644 isum += aux.vda_next;
11645 vstart += aux.vda_next;
11646
54806181
AM
11647 if (vstart + sizeof (*eaux) > endbuf)
11648 break;
1445030f 11649 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11650
11651 aux.vda_name = BYTE_GET (eaux->vda_name);
11652 aux.vda_next = BYTE_GET (eaux->vda_next);
11653
978c4450 11654 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11655 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11656 isum, j,
11657 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11658 else
452bf675 11659 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11660 isum, j, aux.vda_name);
11661 }
dd24e3da 11662
54806181
AM
11663 if (j < ent.vd_cnt)
11664 printf (_(" Version def aux past end of section\n"));
252b5132 11665
c9f02c3e
MR
11666 /* PR 17531:
11667 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11668 if (ent.vd_next < sizeof (*edef)
11669 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11670 {
11671 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11672 cnt = section->sh_info;
11673 break;
11674 }
452bf675 11675 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11676 break;
11677
252b5132
RH
11678 idx += ent.vd_next;
11679 }
dd24e3da 11680
54806181
AM
11681 if (cnt < section->sh_info)
11682 printf (_(" Version definition past end of section\n"));
252b5132
RH
11683
11684 free (edefs);
11685 }
11686 break;
103f02d3 11687
252b5132
RH
11688 case SHT_GNU_verneed:
11689 {
2cf0635d 11690 Elf_External_Verneed * eneed;
452bf675
AM
11691 unsigned long idx;
11692 unsigned long cnt;
2cf0635d 11693 char * endbuf;
252b5132 11694
015dc7e1 11695 found = true;
252b5132 11696
ca0e11aa
NC
11697 if (filedata->is_separate)
11698 printf (ngettext ("\nIn linked file '%s' the version needs section '%s' contains %u entry:\n",
11699 "\nIn linked file '%s' the version needs section '%s' contains %u entries:\n",
11700 section->sh_info),
11701 filedata->file_name,
11702 printable_section_name (filedata, section),
11703 section->sh_info);
11704 else
11705 printf (ngettext ("\nVersion needs section '%s' "
11706 "contains %u entry:\n",
11707 "\nVersion needs section '%s' "
11708 "contains %u entries:\n",
11709 section->sh_info),
11710 printable_section_name (filedata, section),
11711 section->sh_info);
047c3dbf 11712
252b5132
RH
11713 printf (_(" Addr: 0x"));
11714 printf_vma (section->sh_addr);
72de5009 11715 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11716 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11717 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11718
dda8d76d 11719 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11720 section->sh_offset, 1,
11721 section->sh_size,
9cf03b7e 11722 _("Version Needs section"));
a6e9f9df
AM
11723 if (!eneed)
11724 break;
59245841 11725 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11726
11727 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11728 {
2cf0635d 11729 Elf_External_Verneed * entry;
b34976b6 11730 Elf_Internal_Verneed ent;
452bf675 11731 unsigned long isum;
b34976b6 11732 int j;
2cf0635d 11733 char * vstart;
252b5132
RH
11734
11735 vstart = ((char *) eneed) + idx;
54806181
AM
11736 if (vstart + sizeof (*entry) > endbuf)
11737 break;
252b5132
RH
11738
11739 entry = (Elf_External_Verneed *) vstart;
11740
11741 ent.vn_version = BYTE_GET (entry->vn_version);
11742 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11743 ent.vn_file = BYTE_GET (entry->vn_file);
11744 ent.vn_aux = BYTE_GET (entry->vn_aux);
11745 ent.vn_next = BYTE_GET (entry->vn_next);
11746
452bf675 11747 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11748
978c4450
AM
11749 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11750 printf (_(" File: %s"),
11751 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11752 else
11753 printf (_(" File: %lx"), ent.vn_file);
11754
11755 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11756
dd24e3da 11757 /* Check for overflow. */
7e26601c 11758 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11759 break;
252b5132
RH
11760 vstart += ent.vn_aux;
11761
11762 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11763 {
2cf0635d 11764 Elf_External_Vernaux * eaux;
b34976b6 11765 Elf_Internal_Vernaux aux;
252b5132 11766
54806181
AM
11767 if (vstart + sizeof (*eaux) > endbuf)
11768 break;
252b5132
RH
11769 eaux = (Elf_External_Vernaux *) vstart;
11770
11771 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11772 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11773 aux.vna_other = BYTE_GET (eaux->vna_other);
11774 aux.vna_name = BYTE_GET (eaux->vna_name);
11775 aux.vna_next = BYTE_GET (eaux->vna_next);
11776
978c4450 11777 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11778 printf (_(" %#06lx: Name: %s"),
978c4450 11779 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11780 else
452bf675 11781 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11782 isum, aux.vna_name);
11783
11784 printf (_(" Flags: %s Version: %d\n"),
11785 get_ver_flags (aux.vna_flags), aux.vna_other);
11786
1445030f
AM
11787 if (aux.vna_next < sizeof (*eaux)
11788 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11789 {
11790 warn (_("Invalid vna_next field of %lx\n"),
11791 aux.vna_next);
11792 j = ent.vn_cnt;
11793 break;
11794 }
1445030f
AM
11795 /* Check for overflow. */
11796 if (aux.vna_next > (size_t) (endbuf - vstart))
11797 break;
252b5132
RH
11798 isum += aux.vna_next;
11799 vstart += aux.vna_next;
11800 }
9cf03b7e 11801
54806181 11802 if (j < ent.vn_cnt)
f9a6a8f0 11803 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11804
1445030f
AM
11805 if (ent.vn_next < sizeof (*entry)
11806 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11807 {
452bf675 11808 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11809 cnt = section->sh_info;
11810 break;
11811 }
1445030f
AM
11812 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11813 break;
252b5132
RH
11814 idx += ent.vn_next;
11815 }
9cf03b7e 11816
54806181 11817 if (cnt < section->sh_info)
9cf03b7e 11818 warn (_("Missing Version Needs information\n"));
103f02d3 11819
252b5132
RH
11820 free (eneed);
11821 }
11822 break;
11823
11824 case SHT_GNU_versym:
11825 {
2cf0635d 11826 Elf_Internal_Shdr * link_section;
8b73c356
NC
11827 size_t total;
11828 unsigned int cnt;
2cf0635d
NC
11829 unsigned char * edata;
11830 unsigned short * data;
11831 char * strtab;
11832 Elf_Internal_Sym * symbols;
11833 Elf_Internal_Shdr * string_sec;
ba5cdace 11834 unsigned long num_syms;
d3ba0551 11835 long off;
252b5132 11836
dda8d76d 11837 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11838 break;
11839
dda8d76d 11840 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11841 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11842
dda8d76d 11843 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11844 break;
11845
015dc7e1 11846 found = true;
252b5132 11847
4de91c10 11848 symbols = get_elf_symbols (filedata, link_section, & num_syms);
dd24e3da
NC
11849 if (symbols == NULL)
11850 break;
252b5132 11851
dda8d76d 11852 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11853
dda8d76d 11854 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11855 string_sec->sh_size,
11856 _("version string table"));
a6e9f9df 11857 if (!strtab)
0429c154
MS
11858 {
11859 free (symbols);
11860 break;
11861 }
252b5132 11862
ca0e11aa
NC
11863 if (filedata->is_separate)
11864 printf (ngettext ("\nIn linked file '%s' the version symbols section '%s' contains %lu entry:\n",
11865 "\nIn linked file '%s' the version symbols section '%s' contains %lu entries:\n",
11866 total),
11867 filedata->file_name,
11868 printable_section_name (filedata, section),
11869 (unsigned long) total);
11870 else
11871 printf (ngettext ("\nVersion symbols section '%s' "
11872 "contains %lu entry:\n",
11873 "\nVersion symbols section '%s' "
11874 "contains %lu entries:\n",
11875 total),
11876 printable_section_name (filedata, section),
11877 (unsigned long) total);
252b5132 11878
ae9ac79e 11879 printf (_(" Addr: 0x"));
252b5132 11880 printf_vma (section->sh_addr);
72de5009 11881 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11882 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11883 printable_section_name (filedata, link_section));
252b5132 11884
dda8d76d 11885 off = offset_from_vma (filedata,
978c4450 11886 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11887 total * sizeof (short));
95099889
AM
11888 edata = (unsigned char *) get_data (NULL, filedata, off,
11889 sizeof (short), total,
11890 _("version symbol data"));
a6e9f9df
AM
11891 if (!edata)
11892 {
11893 free (strtab);
0429c154 11894 free (symbols);
a6e9f9df
AM
11895 break;
11896 }
252b5132 11897
3f5e193b 11898 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11899
11900 for (cnt = total; cnt --;)
b34976b6
AM
11901 data[cnt] = byte_get (edata + cnt * sizeof (short),
11902 sizeof (short));
252b5132
RH
11903
11904 free (edata);
11905
11906 for (cnt = 0; cnt < total; cnt += 4)
11907 {
11908 int j, nn;
ab273396
AM
11909 char *name;
11910 char *invalid = _("*invalid*");
252b5132
RH
11911
11912 printf (" %03x:", cnt);
11913
11914 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11915 switch (data[cnt + j])
252b5132
RH
11916 {
11917 case 0:
11918 fputs (_(" 0 (*local*) "), stdout);
11919 break;
11920
11921 case 1:
11922 fputs (_(" 1 (*global*) "), stdout);
11923 break;
11924
11925 default:
c244d050
NC
11926 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11927 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11928
dd24e3da 11929 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11930 array, break to avoid an out-of-bounds read. */
11931 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11932 {
11933 warn (_("invalid index into symbol array\n"));
11934 break;
11935 }
11936
ab273396 11937 name = NULL;
978c4450 11938 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11939 {
b34976b6
AM
11940 Elf_Internal_Verneed ivn;
11941 unsigned long offset;
252b5132 11942
d93f0186 11943 offset = offset_from_vma
978c4450
AM
11944 (filedata,
11945 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11946 sizeof (Elf_External_Verneed));
252b5132 11947
b34976b6 11948 do
252b5132 11949 {
b34976b6
AM
11950 Elf_Internal_Vernaux ivna;
11951 Elf_External_Verneed evn;
11952 Elf_External_Vernaux evna;
11953 unsigned long a_off;
252b5132 11954
dda8d76d 11955 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11956 _("version need")) == NULL)
11957 break;
0b4362b0 11958
252b5132
RH
11959 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11960 ivn.vn_next = BYTE_GET (evn.vn_next);
11961
11962 a_off = offset + ivn.vn_aux;
11963
11964 do
11965 {
dda8d76d 11966 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11967 1, _("version need aux (2)")) == NULL)
11968 {
11969 ivna.vna_next = 0;
11970 ivna.vna_other = 0;
11971 }
11972 else
11973 {
11974 ivna.vna_next = BYTE_GET (evna.vna_next);
11975 ivna.vna_other = BYTE_GET (evna.vna_other);
11976 }
252b5132
RH
11977
11978 a_off += ivna.vna_next;
11979 }
b34976b6 11980 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11981 && ivna.vna_next != 0);
11982
b34976b6 11983 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11984 {
11985 ivna.vna_name = BYTE_GET (evna.vna_name);
11986
54806181 11987 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11988 name = invalid;
54806181
AM
11989 else
11990 name = strtab + ivna.vna_name;
252b5132
RH
11991 break;
11992 }
11993
11994 offset += ivn.vn_next;
11995 }
11996 while (ivn.vn_next);
11997 }
00d93f34 11998
ab273396 11999 if (data[cnt + j] != 0x8001
978c4450 12000 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 12001 {
b34976b6
AM
12002 Elf_Internal_Verdef ivd;
12003 Elf_External_Verdef evd;
12004 unsigned long offset;
252b5132 12005
d93f0186 12006 offset = offset_from_vma
978c4450
AM
12007 (filedata,
12008 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 12009 sizeof evd);
252b5132
RH
12010
12011 do
12012 {
dda8d76d 12013 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
12014 _("version def")) == NULL)
12015 {
12016 ivd.vd_next = 0;
948f632f 12017 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
12018 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
12019 break;
59245841
NC
12020 }
12021 else
12022 {
12023 ivd.vd_next = BYTE_GET (evd.vd_next);
12024 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12025 }
252b5132
RH
12026
12027 offset += ivd.vd_next;
12028 }
c244d050 12029 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
12030 && ivd.vd_next != 0);
12031
c244d050 12032 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 12033 {
b34976b6
AM
12034 Elf_External_Verdaux evda;
12035 Elf_Internal_Verdaux ivda;
252b5132
RH
12036
12037 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12038
dda8d76d 12039 if (get_data (&evda, filedata,
59245841
NC
12040 offset - ivd.vd_next + ivd.vd_aux,
12041 sizeof (evda), 1,
12042 _("version def aux")) == NULL)
12043 break;
252b5132
RH
12044
12045 ivda.vda_name = BYTE_GET (evda.vda_name);
12046
54806181 12047 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
12048 name = invalid;
12049 else if (name != NULL && name != invalid)
12050 name = _("*both*");
54806181
AM
12051 else
12052 name = strtab + ivda.vda_name;
252b5132
RH
12053 }
12054 }
ab273396
AM
12055 if (name != NULL)
12056 nn += printf ("(%s%-*s",
12057 name,
12058 12 - (int) strlen (name),
12059 ")");
252b5132
RH
12060
12061 if (nn < 18)
12062 printf ("%*c", 18 - nn, ' ');
12063 }
12064
12065 putchar ('\n');
12066 }
12067
12068 free (data);
12069 free (strtab);
12070 free (symbols);
12071 }
12072 break;
103f02d3 12073
252b5132
RH
12074 default:
12075 break;
12076 }
12077 }
12078
12079 if (! found)
ca0e11aa
NC
12080 {
12081 if (filedata->is_separate)
12082 printf (_("\nNo version information found in linked file '%s'.\n"),
12083 filedata->file_name);
12084 else
12085 printf (_("\nNo version information found in this file.\n"));
12086 }
252b5132 12087
015dc7e1 12088 return true;
252b5132
RH
12089}
12090
d1133906 12091static const char *
dda8d76d 12092get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 12093{
89246a0e 12094 static char buff[64];
252b5132
RH
12095
12096 switch (binding)
12097 {
b34976b6
AM
12098 case STB_LOCAL: return "LOCAL";
12099 case STB_GLOBAL: return "GLOBAL";
12100 case STB_WEAK: return "WEAK";
252b5132
RH
12101 default:
12102 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
12103 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
12104 binding);
252b5132 12105 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
12106 {
12107 if (binding == STB_GNU_UNIQUE
df3a023b 12108 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
12109 return "UNIQUE";
12110 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
12111 }
252b5132 12112 else
e9e44622 12113 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
12114 return buff;
12115 }
12116}
12117
d1133906 12118static const char *
dda8d76d 12119get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 12120{
89246a0e 12121 static char buff[64];
252b5132
RH
12122
12123 switch (type)
12124 {
b34976b6
AM
12125 case STT_NOTYPE: return "NOTYPE";
12126 case STT_OBJECT: return "OBJECT";
12127 case STT_FUNC: return "FUNC";
12128 case STT_SECTION: return "SECTION";
12129 case STT_FILE: return "FILE";
12130 case STT_COMMON: return "COMMON";
12131 case STT_TLS: return "TLS";
15ab5209
DB
12132 case STT_RELC: return "RELC";
12133 case STT_SRELC: return "SRELC";
252b5132
RH
12134 default:
12135 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 12136 {
dda8d76d 12137 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 12138 return "THUMB_FUNC";
103f02d3 12139
dda8d76d 12140 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
12141 return "REGISTER";
12142
dda8d76d 12143 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
12144 return "PARISC_MILLI";
12145
e9e44622 12146 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 12147 }
252b5132 12148 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 12149 {
dda8d76d 12150 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
12151 {
12152 if (type == STT_HP_OPAQUE)
12153 return "HP_OPAQUE";
12154 if (type == STT_HP_STUB)
12155 return "HP_STUB";
12156 }
12157
d8045f23 12158 if (type == STT_GNU_IFUNC
dda8d76d 12159 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 12160 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
12161 return "IFUNC";
12162
e9e44622 12163 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 12164 }
252b5132 12165 else
e9e44622 12166 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
12167 return buff;
12168 }
12169}
12170
d1133906 12171static const char *
d3ba0551 12172get_symbol_visibility (unsigned int visibility)
d1133906
NC
12173{
12174 switch (visibility)
12175 {
b34976b6
AM
12176 case STV_DEFAULT: return "DEFAULT";
12177 case STV_INTERNAL: return "INTERNAL";
12178 case STV_HIDDEN: return "HIDDEN";
d1133906 12179 case STV_PROTECTED: return "PROTECTED";
bee0ee85 12180 default:
27a45f42 12181 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 12182 return _("<unknown>");
d1133906
NC
12183 }
12184}
12185
2057d69d
CZ
12186static const char *
12187get_alpha_symbol_other (unsigned int other)
9abca702 12188{
2057d69d
CZ
12189 switch (other)
12190 {
12191 case STO_ALPHA_NOPV: return "NOPV";
12192 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
12193 default:
27a45f42 12194 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 12195 return _("<unknown>");
9abca702 12196 }
2057d69d
CZ
12197}
12198
fd85a6a1
NC
12199static const char *
12200get_solaris_symbol_visibility (unsigned int visibility)
12201{
12202 switch (visibility)
12203 {
12204 case 4: return "EXPORTED";
12205 case 5: return "SINGLETON";
12206 case 6: return "ELIMINATE";
12207 default: return get_symbol_visibility (visibility);
12208 }
12209}
12210
2301ed1c
SN
12211static const char *
12212get_aarch64_symbol_other (unsigned int other)
12213{
12214 static char buf[32];
12215
12216 if (other & STO_AARCH64_VARIANT_PCS)
12217 {
12218 other &= ~STO_AARCH64_VARIANT_PCS;
12219 if (other == 0)
12220 return "VARIANT_PCS";
12221 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
12222 return buf;
12223 }
12224 return NULL;
12225}
12226
5e2b0d47
NC
12227static const char *
12228get_mips_symbol_other (unsigned int other)
12229{
12230 switch (other)
12231 {
32ec8896
NC
12232 case STO_OPTIONAL: return "OPTIONAL";
12233 case STO_MIPS_PLT: return "MIPS PLT";
12234 case STO_MIPS_PIC: return "MIPS PIC";
12235 case STO_MICROMIPS: return "MICROMIPS";
12236 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
12237 case STO_MIPS16: return "MIPS16";
12238 default: return NULL;
5e2b0d47
NC
12239 }
12240}
12241
28f997cf 12242static const char *
dda8d76d 12243get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 12244{
dda8d76d 12245 if (is_ia64_vms (filedata))
28f997cf
TG
12246 {
12247 static char res[32];
12248
12249 res[0] = 0;
12250
12251 /* Function types is for images and .STB files only. */
dda8d76d 12252 switch (filedata->file_header.e_type)
28f997cf
TG
12253 {
12254 case ET_DYN:
12255 case ET_EXEC:
12256 switch (VMS_ST_FUNC_TYPE (other))
12257 {
12258 case VMS_SFT_CODE_ADDR:
12259 strcat (res, " CA");
12260 break;
12261 case VMS_SFT_SYMV_IDX:
12262 strcat (res, " VEC");
12263 break;
12264 case VMS_SFT_FD:
12265 strcat (res, " FD");
12266 break;
12267 case VMS_SFT_RESERVE:
12268 strcat (res, " RSV");
12269 break;
12270 default:
bee0ee85
NC
12271 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
12272 VMS_ST_FUNC_TYPE (other));
12273 strcat (res, " <unknown>");
12274 break;
28f997cf
TG
12275 }
12276 break;
12277 default:
12278 break;
12279 }
12280 switch (VMS_ST_LINKAGE (other))
12281 {
12282 case VMS_STL_IGNORE:
12283 strcat (res, " IGN");
12284 break;
12285 case VMS_STL_RESERVE:
12286 strcat (res, " RSV");
12287 break;
12288 case VMS_STL_STD:
12289 strcat (res, " STD");
12290 break;
12291 case VMS_STL_LNK:
12292 strcat (res, " LNK");
12293 break;
12294 default:
bee0ee85
NC
12295 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
12296 VMS_ST_LINKAGE (other));
12297 strcat (res, " <unknown>");
12298 break;
28f997cf
TG
12299 }
12300
12301 if (res[0] != 0)
12302 return res + 1;
12303 else
12304 return res;
12305 }
12306 return NULL;
12307}
12308
6911b7dc
AM
12309static const char *
12310get_ppc64_symbol_other (unsigned int other)
12311{
14732552
AM
12312 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
12313 return NULL;
12314
12315 other >>= STO_PPC64_LOCAL_BIT;
12316 if (other <= 6)
6911b7dc 12317 {
89246a0e 12318 static char buf[64];
14732552
AM
12319 if (other >= 2)
12320 other = ppc64_decode_local_entry (other);
12321 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
12322 return buf;
12323 }
12324 return NULL;
12325}
12326
5e2b0d47 12327static const char *
dda8d76d 12328get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
12329{
12330 const char * result = NULL;
89246a0e 12331 static char buff [64];
5e2b0d47
NC
12332
12333 if (other == 0)
12334 return "";
12335
dda8d76d 12336 switch (filedata->file_header.e_machine)
5e2b0d47 12337 {
2057d69d
CZ
12338 case EM_ALPHA:
12339 result = get_alpha_symbol_other (other);
12340 break;
2301ed1c
SN
12341 case EM_AARCH64:
12342 result = get_aarch64_symbol_other (other);
12343 break;
5e2b0d47
NC
12344 case EM_MIPS:
12345 result = get_mips_symbol_other (other);
28f997cf
TG
12346 break;
12347 case EM_IA_64:
dda8d76d 12348 result = get_ia64_symbol_other (filedata, other);
28f997cf 12349 break;
6911b7dc
AM
12350 case EM_PPC64:
12351 result = get_ppc64_symbol_other (other);
12352 break;
5e2b0d47 12353 default:
fd85a6a1 12354 result = NULL;
5e2b0d47
NC
12355 break;
12356 }
12357
12358 if (result)
12359 return result;
12360
12361 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12362 return buff;
12363}
12364
d1133906 12365static const char *
dda8d76d 12366get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12367{
b34976b6 12368 static char buff[32];
5cf1065c 12369
252b5132
RH
12370 switch (type)
12371 {
b34976b6
AM
12372 case SHN_UNDEF: return "UND";
12373 case SHN_ABS: return "ABS";
12374 case SHN_COMMON: return "COM";
252b5132 12375 default:
9ce701e2 12376 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12377 && filedata->file_header.e_machine == EM_IA_64
12378 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12379 return "ANSI_COM";
12380 else if ((filedata->file_header.e_machine == EM_X86_64
12381 || filedata->file_header.e_machine == EM_L1OM
12382 || filedata->file_header.e_machine == EM_K1OM)
12383 && type == SHN_X86_64_LCOMMON)
12384 return "LARGE_COM";
12385 else if ((type == SHN_MIPS_SCOMMON
12386 && filedata->file_header.e_machine == EM_MIPS)
12387 || (type == SHN_TIC6X_SCOMMON
12388 && filedata->file_header.e_machine == EM_TI_C6000))
12389 return "SCOM";
12390 else if (type == SHN_MIPS_SUNDEFINED
12391 && filedata->file_header.e_machine == EM_MIPS)
12392 return "SUND";
12393 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12394 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12395 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12396 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12397 else if (type >= SHN_LORESERVE)
12398 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12399 else if (filedata->file_header.e_shnum != 0
12400 && type >= filedata->file_header.e_shnum)
12401 sprintf (buff, _("bad section index[%3d]"), type);
12402 else
12403 sprintf (buff, "%3d", type);
12404 break;
fd85a6a1
NC
12405 }
12406
10ca4b04 12407 return buff;
6bd1a22c
L
12408}
12409
bb4d2ac2 12410static const char *
dda8d76d 12411get_symbol_version_string (Filedata * filedata,
015dc7e1 12412 bool is_dynsym,
1449284b
NC
12413 const char * strtab,
12414 unsigned long int strtab_size,
12415 unsigned int si,
12416 Elf_Internal_Sym * psym,
12417 enum versioned_symbol_info * sym_info,
12418 unsigned short * vna_other)
bb4d2ac2 12419{
ab273396
AM
12420 unsigned char data[2];
12421 unsigned short vers_data;
12422 unsigned long offset;
7a815dd5 12423 unsigned short max_vd_ndx;
bb4d2ac2 12424
ab273396 12425 if (!is_dynsym
978c4450 12426 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12427 return NULL;
bb4d2ac2 12428
978c4450
AM
12429 offset = offset_from_vma (filedata,
12430 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12431 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12432
dda8d76d 12433 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12434 sizeof (data), 1, _("version data")) == NULL)
12435 return NULL;
12436
12437 vers_data = byte_get (data, 2);
bb4d2ac2 12438
1f6f5dba 12439 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12440 return NULL;
bb4d2ac2 12441
0b8b7609 12442 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12443 max_vd_ndx = 0;
12444
ab273396
AM
12445 /* Usually we'd only see verdef for defined symbols, and verneed for
12446 undefined symbols. However, symbols defined by the linker in
12447 .dynbss for variables copied from a shared library in order to
12448 avoid text relocations are defined yet have verneed. We could
12449 use a heuristic to detect the special case, for example, check
12450 for verneed first on symbols defined in SHT_NOBITS sections, but
12451 it is simpler and more reliable to just look for both verdef and
12452 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12453
ab273396
AM
12454 if (psym->st_shndx != SHN_UNDEF
12455 && vers_data != 0x8001
978c4450 12456 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12457 {
12458 Elf_Internal_Verdef ivd;
12459 Elf_Internal_Verdaux ivda;
12460 Elf_External_Verdaux evda;
12461 unsigned long off;
bb4d2ac2 12462
dda8d76d 12463 off = offset_from_vma (filedata,
978c4450 12464 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12465 sizeof (Elf_External_Verdef));
12466
12467 do
bb4d2ac2 12468 {
ab273396
AM
12469 Elf_External_Verdef evd;
12470
dda8d76d 12471 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12472 _("version def")) == NULL)
12473 {
12474 ivd.vd_ndx = 0;
12475 ivd.vd_aux = 0;
12476 ivd.vd_next = 0;
1f6f5dba 12477 ivd.vd_flags = 0;
ab273396
AM
12478 }
12479 else
bb4d2ac2 12480 {
ab273396
AM
12481 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12482 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12483 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12484 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12485 }
bb4d2ac2 12486
7a815dd5
L
12487 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12488 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12489
ab273396
AM
12490 off += ivd.vd_next;
12491 }
12492 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12493
ab273396
AM
12494 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12495 {
9abca702 12496 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12497 return NULL;
12498
ab273396
AM
12499 off -= ivd.vd_next;
12500 off += ivd.vd_aux;
bb4d2ac2 12501
dda8d76d 12502 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12503 _("version def aux")) != NULL)
12504 {
12505 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12506
ab273396 12507 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12508 return (ivda.vda_name < strtab_size
12509 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12510 }
12511 }
12512 }
bb4d2ac2 12513
978c4450 12514 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12515 {
12516 Elf_External_Verneed evn;
12517 Elf_Internal_Verneed ivn;
12518 Elf_Internal_Vernaux ivna;
bb4d2ac2 12519
dda8d76d 12520 offset = offset_from_vma (filedata,
978c4450 12521 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12522 sizeof evn);
12523 do
12524 {
12525 unsigned long vna_off;
bb4d2ac2 12526
dda8d76d 12527 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12528 _("version need")) == NULL)
12529 {
12530 ivna.vna_next = 0;
12531 ivna.vna_other = 0;
12532 ivna.vna_name = 0;
12533 break;
12534 }
bb4d2ac2 12535
ab273396
AM
12536 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12537 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12538
ab273396 12539 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12540
ab273396
AM
12541 do
12542 {
12543 Elf_External_Vernaux evna;
bb4d2ac2 12544
dda8d76d 12545 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12546 _("version need aux (3)")) == NULL)
bb4d2ac2 12547 {
ab273396
AM
12548 ivna.vna_next = 0;
12549 ivna.vna_other = 0;
12550 ivna.vna_name = 0;
bb4d2ac2 12551 }
bb4d2ac2 12552 else
bb4d2ac2 12553 {
ab273396
AM
12554 ivna.vna_other = BYTE_GET (evna.vna_other);
12555 ivna.vna_next = BYTE_GET (evna.vna_next);
12556 ivna.vna_name = BYTE_GET (evna.vna_name);
12557 }
bb4d2ac2 12558
ab273396
AM
12559 vna_off += ivna.vna_next;
12560 }
12561 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12562
ab273396
AM
12563 if (ivna.vna_other == vers_data)
12564 break;
bb4d2ac2 12565
ab273396
AM
12566 offset += ivn.vn_next;
12567 }
12568 while (ivn.vn_next != 0);
bb4d2ac2 12569
ab273396
AM
12570 if (ivna.vna_other == vers_data)
12571 {
12572 *sym_info = symbol_undefined;
12573 *vna_other = ivna.vna_other;
12574 return (ivna.vna_name < strtab_size
12575 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12576 }
7a815dd5
L
12577 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12578 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12579 return _("<corrupt>");
bb4d2ac2 12580 }
ab273396 12581 return NULL;
bb4d2ac2
L
12582}
12583
047c3dbf
NL
12584/* Display a symbol size on stdout. Format is based on --sym-base setting. */
12585
12586static unsigned int
12587print_dynamic_symbol_size (bfd_vma vma, int base)
12588{
12589 switch (base)
12590 {
12591 case 8:
12592 return print_vma (vma, OCTAL_5);
12593
12594 case 10:
12595 return print_vma (vma, UNSIGNED_5);
12596
12597 case 16:
12598 return print_vma (vma, PREFIX_HEX_5);
12599
12600 case 0:
12601 default:
12602 return print_vma (vma, DEC_5);
12603 }
12604}
12605
10ca4b04
L
12606static void
12607print_dynamic_symbol (Filedata *filedata, unsigned long si,
12608 Elf_Internal_Sym *symtab,
12609 Elf_Internal_Shdr *section,
12610 char *strtab, size_t strtab_size)
252b5132 12611{
10ca4b04
L
12612 const char *version_string;
12613 enum versioned_symbol_info sym_info;
12614 unsigned short vna_other;
23356397
NC
12615 bool is_valid;
12616 const char * sstr;
10ca4b04 12617 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12618
10ca4b04
L
12619 printf ("%6ld: ", si);
12620 print_vma (psym->st_value, LONG_HEX);
12621 putchar (' ');
047c3dbf 12622 print_dynamic_symbol_size (psym->st_size, sym_base);
10ca4b04
L
12623 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12624 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12625 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12626 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12627 else
252b5132 12628 {
10ca4b04 12629 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12630
10ca4b04
L
12631 printf (" %-7s", get_symbol_visibility (vis));
12632 /* Check to see if any other bits in the st_other field are set.
12633 Note - displaying this information disrupts the layout of the
12634 table being generated, but for the moment this case is very rare. */
12635 if (psym->st_other ^ vis)
12636 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12637 }
10ca4b04 12638 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab 12639
23356397
NC
12640 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION
12641 && psym->st_shndx < filedata->file_header.e_shnum
12642 && psym->st_name == 0)
12643 {
12644 is_valid = SECTION_NAME_VALID (filedata->section_headers + psym->st_shndx);
12645 sstr = is_valid ?
12646 SECTION_NAME_PRINT (filedata->section_headers + psym->st_shndx)
12647 : _("<corrupt>");
12648 }
12649 else
12650 {
12651 is_valid = VALID_SYMBOL_NAME (strtab, strtab_size, psym->st_name);
12652 sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
12653 }
10ca4b04
L
12654
12655 version_string
12656 = get_symbol_version_string (filedata,
12657 (section == NULL
12658 || section->sh_type == SHT_DYNSYM),
12659 strtab, strtab_size, si,
12660 psym, &sym_info, &vna_other);
b9e920ec 12661
0942c7ab
NC
12662 int len_avail = 21;
12663 if (! do_wide && version_string != NULL)
12664 {
ddb43bab 12665 char buffer[16];
0942c7ab 12666
ddb43bab 12667 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12668
12669 if (sym_info == symbol_undefined)
12670 len_avail -= sprintf (buffer," (%d)", vna_other);
12671 else if (sym_info != symbol_hidden)
12672 len_avail -= 1;
12673 }
12674
12675 print_symbol (len_avail, sstr);
b9e920ec 12676
10ca4b04
L
12677 if (version_string)
12678 {
12679 if (sym_info == symbol_undefined)
12680 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12681 else
10ca4b04
L
12682 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12683 version_string);
12684 }
6bd1a22c 12685
10ca4b04 12686 putchar ('\n');
6bd1a22c 12687
10ca4b04
L
12688 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12689 && section != NULL
12690 && si >= section->sh_info
12691 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12692 && filedata->file_header.e_machine != EM_MIPS
12693 /* Solaris binaries have been found to violate this requirement as
12694 well. Not sure if this is a bug or an ABI requirement. */
12695 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12696 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12697 si, printable_section_name (filedata, section), section->sh_info);
12698}
f16a9783 12699
0f03783c
NC
12700static const char *
12701get_lto_kind (unsigned int kind)
12702{
12703 switch (kind)
12704 {
12705 case 0: return "DEF";
12706 case 1: return "WEAKDEF";
12707 case 2: return "UNDEF";
12708 case 3: return "WEAKUNDEF";
12709 case 4: return "COMMON";
12710 default:
12711 break;
12712 }
12713
12714 static char buffer[30];
12715 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12716 sprintf (buffer, "<unknown: %u>", kind);
12717 return buffer;
12718}
12719
12720static const char *
12721get_lto_visibility (unsigned int visibility)
12722{
12723 switch (visibility)
12724 {
12725 case 0: return "DEFAULT";
12726 case 1: return "PROTECTED";
12727 case 2: return "INTERNAL";
12728 case 3: return "HIDDEN";
12729 default:
12730 break;
12731 }
12732
12733 static char buffer[30];
12734 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12735 sprintf (buffer, "<unknown: %u>", visibility);
12736 return buffer;
12737}
12738
12739static const char *
12740get_lto_sym_type (unsigned int sym_type)
12741{
12742 switch (sym_type)
12743 {
12744 case 0: return "UNKNOWN";
12745 case 1: return "FUNCTION";
12746 case 2: return "VARIABLE";
12747 default:
12748 break;
12749 }
12750
12751 static char buffer[30];
12752 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12753 sprintf (buffer, "<unknown: %u>", sym_type);
12754 return buffer;
12755}
12756
12757/* Display an LTO format symbol table.
12758 FIXME: The format of LTO symbol tables is not formalized.
12759 So this code could need changing in the future. */
12760
015dc7e1 12761static bool
0f03783c
NC
12762display_lto_symtab (Filedata * filedata,
12763 Elf_Internal_Shdr * section)
12764{
12765 if (section->sh_size == 0)
12766 {
ca0e11aa
NC
12767 if (filedata->is_separate)
12768 printf (_("\nThe LTO Symbol table section '%s' in linked file '%s' is empty!\n"),
12769 printable_section_name (filedata, section),
12770 filedata->file_name);
12771 else
12772 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12773 printable_section_name (filedata, section));
047c3dbf 12774
015dc7e1 12775 return true;
0f03783c
NC
12776 }
12777
12778 if (section->sh_size > filedata->file_size)
12779 {
12780 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12781 printable_section_name (filedata, section),
12782 (unsigned long) section->sh_size);
015dc7e1 12783 return false;
0f03783c
NC
12784 }
12785
12786 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12787 section->sh_size, 1, _("LTO symbols"));
12788 if (alloced_data == NULL)
015dc7e1 12789 return false;
0f03783c
NC
12790
12791 /* Look for extended data for the symbol table. */
12792 Elf_Internal_Shdr * ext;
12793 void * ext_data_orig = NULL;
12794 char * ext_data = NULL;
12795 char * ext_data_end = NULL;
12796 char * ext_name = NULL;
12797
12798 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12799 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12800 && ext_name != NULL /* Paranoia. */
12801 && (ext = find_section (filedata, ext_name)) != NULL)
12802 {
12803 if (ext->sh_size < 3)
12804 error (_("LTO Symbol extension table '%s' is empty!\n"),
12805 printable_section_name (filedata, ext));
12806 else
12807 {
12808 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12809 ext->sh_size, 1,
12810 _("LTO ext symbol data"));
12811 if (ext_data != NULL)
12812 {
12813 ext_data_end = ext_data + ext->sh_size;
12814 if (* ext_data++ != 1)
12815 error (_("Unexpected version number in symbol extension table\n"));
12816 }
12817 }
12818 }
b9e920ec 12819
0f03783c
NC
12820 const unsigned char * data = (const unsigned char *) alloced_data;
12821 const unsigned char * end = data + section->sh_size;
12822
ca0e11aa
NC
12823 if (filedata->is_separate)
12824 printf (_("\nIn linked file '%s': "), filedata->file_name);
12825 else
12826 printf ("\n");
12827
0f03783c
NC
12828 if (ext_data_orig != NULL)
12829 {
12830 if (do_wide)
ca0e11aa 12831 printf (_("LTO Symbol table '%s' and extension table '%s' contain:\n"),
0f03783c
NC
12832 printable_section_name (filedata, section),
12833 printable_section_name (filedata, ext));
12834 else
12835 {
ca0e11aa 12836 printf (_("LTO Symbol table '%s'\n"),
0f03783c
NC
12837 printable_section_name (filedata, section));
12838 printf (_(" and extension table '%s' contain:\n"),
12839 printable_section_name (filedata, ext));
12840 }
12841 }
12842 else
ca0e11aa 12843 printf (_("LTO Symbol table '%s' contains:\n"),
0f03783c 12844 printable_section_name (filedata, section));
b9e920ec 12845
0f03783c 12846 /* FIXME: Add a wide version. */
b9e920ec 12847 if (ext_data_orig != NULL)
0f03783c
NC
12848 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12849 else
12850 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12851
12852 /* FIXME: We do not handle style prefixes. */
12853
12854 while (data < end)
12855 {
12856 const unsigned char * sym_name = data;
12857 data += strnlen ((const char *) sym_name, end - data) + 1;
12858 if (data >= end)
12859 goto fail;
12860
12861 const unsigned char * comdat_key = data;
12862 data += strnlen ((const char *) comdat_key, end - data) + 1;
12863 if (data >= end)
12864 goto fail;
12865
12866 if (data + 2 + 8 + 4 > end)
12867 goto fail;
12868
12869 unsigned int kind = *data++;
12870 unsigned int visibility = *data++;
12871
12872 elf_vma size = byte_get (data, 8);
12873 data += 8;
12874
12875 elf_vma slot = byte_get (data, 4);
12876 data += 4;
12877
12878 if (ext_data != NULL)
12879 {
12880 if (ext_data < (ext_data_end - 1))
12881 {
12882 unsigned int sym_type = * ext_data ++;
12883 unsigned int sec_kind = * ext_data ++;
12884
12885 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12886 * comdat_key == 0 ? "-" : (char *) comdat_key,
12887 get_lto_kind (kind),
12888 get_lto_visibility (visibility),
12889 (long) size,
12890 (long) slot,
12891 get_lto_sym_type (sym_type),
12892 (long) sec_kind);
12893 print_symbol (6, (const char *) sym_name);
12894 }
12895 else
12896 {
12897 error (_("Ran out of LTO symbol extension data\n"));
12898 ext_data = NULL;
12899 /* FIXME: return FAIL result ? */
12900 }
12901 }
12902 else
12903 {
12904 printf (" %10s %10s %11s %08lx %08lx _",
12905 * comdat_key == 0 ? "-" : (char *) comdat_key,
12906 get_lto_kind (kind),
12907 get_lto_visibility (visibility),
12908 (long) size,
12909 (long) slot);
12910 print_symbol (21, (const char *) sym_name);
12911 }
12912 putchar ('\n');
12913 }
12914
12915 if (ext_data != NULL && ext_data < ext_data_end)
12916 {
12917 error (_("Data remains in the LTO symbol extension table\n"));
12918 goto fail;
12919 }
12920
12921 free (alloced_data);
12922 free (ext_data_orig);
12923 free (ext_name);
015dc7e1 12924 return true;
b9e920ec 12925
0f03783c
NC
12926 fail:
12927 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12928 free (alloced_data);
12929 free (ext_data_orig);
12930 free (ext_name);
015dc7e1 12931 return false;
0f03783c
NC
12932}
12933
12934/* Display LTO symbol tables. */
12935
015dc7e1 12936static bool
0f03783c
NC
12937process_lto_symbol_tables (Filedata * filedata)
12938{
12939 Elf_Internal_Shdr * section;
12940 unsigned int i;
015dc7e1 12941 bool res = true;
0f03783c
NC
12942
12943 if (!do_lto_syms)
015dc7e1 12944 return true;
0f03783c
NC
12945
12946 if (filedata->section_headers == NULL)
015dc7e1 12947 return true;
0f03783c
NC
12948
12949 for (i = 0, section = filedata->section_headers;
12950 i < filedata->file_header.e_shnum;
12951 i++, section++)
b9e920ec 12952 if (SECTION_NAME_VALID (section)
08dedd66 12953 && startswith (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12954 res &= display_lto_symtab (filedata, section);
12955
b9e920ec 12956 return res;
0f03783c
NC
12957}
12958
10ca4b04 12959/* Dump the symbol table. */
0f03783c 12960
015dc7e1 12961static bool
10ca4b04
L
12962process_symbol_table (Filedata * filedata)
12963{
12964 Elf_Internal_Shdr * section;
f16a9783 12965
10ca4b04 12966 if (!do_syms && !do_dyn_syms && !do_histogram)
015dc7e1 12967 return true;
6bd1a22c 12968
978c4450 12969 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12970 && do_syms
12971 && do_using_dynamic
978c4450
AM
12972 && filedata->dynamic_strings != NULL
12973 && filedata->dynamic_symbols != NULL)
6bd1a22c 12974 {
10ca4b04 12975 unsigned long si;
6bd1a22c 12976
ca0e11aa
NC
12977 if (filedata->is_separate)
12978 {
12979 printf (ngettext ("\nIn linked file '%s' the dynamic symbol table contains %lu entry:\n",
12980 "\nIn linked file '%s' the dynamic symbol table contains %lu entries:\n",
12981 filedata->num_dynamic_syms),
12982 filedata->file_name,
12983 filedata->num_dynamic_syms);
12984 }
12985 else
12986 {
12987 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12988 "\nSymbol table for image contains %lu entries:\n",
12989 filedata->num_dynamic_syms),
12990 filedata->num_dynamic_syms);
12991 }
10ca4b04
L
12992 if (is_32bit_elf)
12993 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12994 else
12995 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12996
978c4450
AM
12997 for (si = 0; si < filedata->num_dynamic_syms; si++)
12998 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12999 filedata->dynamic_strings,
13000 filedata->dynamic_strings_length);
252b5132 13001 }
8b73c356 13002 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 13003 && filedata->section_headers != NULL)
252b5132 13004 {
b34976b6 13005 unsigned int i;
252b5132 13006
dda8d76d
NC
13007 for (i = 0, section = filedata->section_headers;
13008 i < filedata->file_header.e_shnum;
252b5132
RH
13009 i++, section++)
13010 {
2cf0635d 13011 char * strtab = NULL;
c256ffe7 13012 unsigned long int strtab_size = 0;
2cf0635d 13013 Elf_Internal_Sym * symtab;
ef3df110 13014 unsigned long si, num_syms;
252b5132 13015
2c610e4b
L
13016 if ((section->sh_type != SHT_SYMTAB
13017 && section->sh_type != SHT_DYNSYM)
13018 || (!do_syms
13019 && section->sh_type == SHT_SYMTAB))
252b5132
RH
13020 continue;
13021
dd24e3da
NC
13022 if (section->sh_entsize == 0)
13023 {
13024 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 13025 printable_section_name (filedata, section));
dd24e3da
NC
13026 continue;
13027 }
13028
d3a49aa8 13029 num_syms = section->sh_size / section->sh_entsize;
ca0e11aa
NC
13030
13031 if (filedata->is_separate)
13032 printf (ngettext ("\nIn linked file '%s' symbol section '%s' contains %lu entry:\n",
13033 "\nIn linked file '%s' symbol section '%s' contains %lu entries:\n",
13034 num_syms),
13035 filedata->file_name,
13036 printable_section_name (filedata, section),
13037 num_syms);
13038 else
13039 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
13040 "\nSymbol table '%s' contains %lu entries:\n",
13041 num_syms),
13042 printable_section_name (filedata, section),
13043 num_syms);
dd24e3da 13044
f7a99963 13045 if (is_32bit_elf)
ca47b30c 13046 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 13047 else
ca47b30c 13048 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 13049
4de91c10 13050 symtab = get_elf_symbols (filedata, section, & num_syms);
252b5132
RH
13051 if (symtab == NULL)
13052 continue;
13053
dda8d76d 13054 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 13055 {
dda8d76d
NC
13056 strtab = filedata->string_table;
13057 strtab_size = filedata->string_table_length;
c256ffe7 13058 }
dda8d76d 13059 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 13060 {
2cf0635d 13061 Elf_Internal_Shdr * string_sec;
252b5132 13062
dda8d76d 13063 string_sec = filedata->section_headers + section->sh_link;
252b5132 13064
dda8d76d 13065 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
13066 1, string_sec->sh_size,
13067 _("string table"));
c256ffe7 13068 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
13069 }
13070
10ca4b04
L
13071 for (si = 0; si < num_syms; si++)
13072 print_dynamic_symbol (filedata, si, symtab, section,
13073 strtab, strtab_size);
252b5132
RH
13074
13075 free (symtab);
dda8d76d 13076 if (strtab != filedata->string_table)
252b5132
RH
13077 free (strtab);
13078 }
13079 }
13080 else if (do_syms)
13081 printf
13082 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
13083
978c4450 13084 if (do_histogram && filedata->buckets != NULL)
252b5132 13085 {
2cf0635d
NC
13086 unsigned long * lengths;
13087 unsigned long * counts;
66543521
AM
13088 unsigned long hn;
13089 bfd_vma si;
13090 unsigned long maxlength = 0;
13091 unsigned long nzero_counts = 0;
13092 unsigned long nsyms = 0;
6bd6a03d 13093 char *visited;
252b5132 13094
d3a49aa8
AM
13095 printf (ngettext ("\nHistogram for bucket list length "
13096 "(total of %lu bucket):\n",
13097 "\nHistogram for bucket list length "
13098 "(total of %lu buckets):\n",
978c4450
AM
13099 (unsigned long) filedata->nbuckets),
13100 (unsigned long) filedata->nbuckets);
252b5132 13101
978c4450
AM
13102 lengths = (unsigned long *) calloc (filedata->nbuckets,
13103 sizeof (*lengths));
252b5132
RH
13104 if (lengths == NULL)
13105 {
8b73c356 13106 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 13107 goto err_out;
252b5132 13108 }
978c4450
AM
13109 visited = xcmalloc (filedata->nchains, 1);
13110 memset (visited, 0, filedata->nchains);
8b73c356
NC
13111
13112 printf (_(" Length Number %% of total Coverage\n"));
978c4450 13113 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 13114 {
978c4450 13115 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 13116 {
b34976b6 13117 ++nsyms;
252b5132 13118 if (maxlength < ++lengths[hn])
b34976b6 13119 ++maxlength;
978c4450 13120 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
13121 {
13122 error (_("histogram chain is corrupt\n"));
13123 break;
13124 }
13125 visited[si] = 1;
252b5132
RH
13126 }
13127 }
6bd6a03d 13128 free (visited);
252b5132 13129
3f5e193b 13130 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
13131 if (counts == NULL)
13132 {
b2e951ec 13133 free (lengths);
8b73c356 13134 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 13135 goto err_out;
252b5132
RH
13136 }
13137
978c4450 13138 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 13139 ++counts[lengths[hn]];
252b5132 13140
978c4450 13141 if (filedata->nbuckets > 0)
252b5132 13142 {
66543521
AM
13143 unsigned long i;
13144 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13145 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 13146 for (i = 1; i <= maxlength; ++i)
103f02d3 13147 {
66543521
AM
13148 nzero_counts += counts[i] * i;
13149 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13150 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
13151 (nzero_counts * 100.0) / nsyms);
13152 }
252b5132
RH
13153 }
13154
13155 free (counts);
13156 free (lengths);
13157 }
13158
978c4450
AM
13159 free (filedata->buckets);
13160 filedata->buckets = NULL;
13161 filedata->nbuckets = 0;
13162 free (filedata->chains);
13163 filedata->chains = NULL;
252b5132 13164
978c4450 13165 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 13166 {
2cf0635d
NC
13167 unsigned long * lengths;
13168 unsigned long * counts;
fdc90cb4
JJ
13169 unsigned long hn;
13170 unsigned long maxlength = 0;
13171 unsigned long nzero_counts = 0;
13172 unsigned long nsyms = 0;
fdc90cb4 13173
f16a9783 13174 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 13175 "(total of %lu bucket):\n",
f16a9783 13176 "\nHistogram for `%s' bucket list length "
d3a49aa8 13177 "(total of %lu buckets):\n",
978c4450
AM
13178 (unsigned long) filedata->ngnubuckets),
13179 GNU_HASH_SECTION_NAME (filedata),
13180 (unsigned long) filedata->ngnubuckets);
8b73c356 13181
978c4450
AM
13182 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
13183 sizeof (*lengths));
fdc90cb4
JJ
13184 if (lengths == NULL)
13185 {
8b73c356 13186 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 13187 goto err_out;
fdc90cb4
JJ
13188 }
13189
fdc90cb4
JJ
13190 printf (_(" Length Number %% of total Coverage\n"));
13191
978c4450
AM
13192 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
13193 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
13194 {
13195 bfd_vma off, length = 1;
13196
978c4450 13197 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 13198 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
13199 off < filedata->ngnuchains
13200 && (filedata->gnuchains[off] & 1) == 0;
071436c6 13201 ++off)
fdc90cb4
JJ
13202 ++length;
13203 lengths[hn] = length;
13204 if (length > maxlength)
13205 maxlength = length;
13206 nsyms += length;
13207 }
13208
3f5e193b 13209 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
13210 if (counts == NULL)
13211 {
b2e951ec 13212 free (lengths);
8b73c356 13213 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 13214 goto err_out;
fdc90cb4
JJ
13215 }
13216
978c4450 13217 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
13218 ++counts[lengths[hn]];
13219
978c4450 13220 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
13221 {
13222 unsigned long j;
13223 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 13224 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
13225 for (j = 1; j <= maxlength; ++j)
13226 {
13227 nzero_counts += counts[j] * j;
13228 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 13229 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
13230 (nzero_counts * 100.0) / nsyms);
13231 }
13232 }
13233
13234 free (counts);
13235 free (lengths);
fdc90cb4 13236 }
978c4450
AM
13237 free (filedata->gnubuckets);
13238 filedata->gnubuckets = NULL;
13239 filedata->ngnubuckets = 0;
13240 free (filedata->gnuchains);
13241 filedata->gnuchains = NULL;
13242 filedata->ngnuchains = 0;
13243 free (filedata->mipsxlat);
13244 filedata->mipsxlat = NULL;
015dc7e1 13245 return true;
fd486f32
AM
13246
13247 err_out:
978c4450
AM
13248 free (filedata->gnubuckets);
13249 filedata->gnubuckets = NULL;
13250 filedata->ngnubuckets = 0;
13251 free (filedata->gnuchains);
13252 filedata->gnuchains = NULL;
13253 filedata->ngnuchains = 0;
13254 free (filedata->mipsxlat);
13255 filedata->mipsxlat = NULL;
13256 free (filedata->buckets);
13257 filedata->buckets = NULL;
13258 filedata->nbuckets = 0;
13259 free (filedata->chains);
13260 filedata->chains = NULL;
015dc7e1 13261 return false;
252b5132
RH
13262}
13263
015dc7e1 13264static bool
ca0e11aa 13265process_syminfo (Filedata * filedata)
252b5132 13266{
b4c96d0d 13267 unsigned int i;
252b5132 13268
978c4450 13269 if (filedata->dynamic_syminfo == NULL
252b5132
RH
13270 || !do_dynamic)
13271 /* No syminfo, this is ok. */
015dc7e1 13272 return true;
252b5132
RH
13273
13274 /* There better should be a dynamic symbol section. */
978c4450 13275 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
015dc7e1 13276 return false;
252b5132 13277
ca0e11aa
NC
13278 if (filedata->is_separate)
13279 printf (ngettext ("\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entry:\n",
13280 "\nIn linked file '%s: the dynamic info segment at offset 0x%lx contains %d entries:\n",
13281 filedata->dynamic_syminfo_nent),
13282 filedata->file_name,
13283 filedata->dynamic_syminfo_offset,
13284 filedata->dynamic_syminfo_nent);
13285 else
d3a49aa8
AM
13286 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
13287 "contains %d entry:\n",
13288 "\nDynamic info segment at offset 0x%lx "
13289 "contains %d entries:\n",
978c4450 13290 filedata->dynamic_syminfo_nent),
ca0e11aa
NC
13291 filedata->dynamic_syminfo_offset,
13292 filedata->dynamic_syminfo_nent);
252b5132
RH
13293
13294 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 13295 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 13296 {
978c4450 13297 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 13298
31104126 13299 printf ("%4d: ", i);
978c4450 13300 if (i >= filedata->num_dynamic_syms)
4082ef84 13301 printf (_("<corrupt index>"));
978c4450
AM
13302 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
13303 print_symbol (30, GET_DYNAMIC_NAME (filedata,
13304 filedata->dynamic_symbols[i].st_name));
d79b3d50 13305 else
978c4450 13306 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 13307 putchar (' ');
252b5132 13308
978c4450 13309 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
13310 {
13311 case SYMINFO_BT_SELF:
13312 fputs ("SELF ", stdout);
13313 break;
13314 case SYMINFO_BT_PARENT:
13315 fputs ("PARENT ", stdout);
13316 break;
13317 default:
978c4450
AM
13318 if (filedata->dynamic_syminfo[i].si_boundto > 0
13319 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
13320 && VALID_DYNAMIC_NAME (filedata,
13321 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 13322 {
978c4450
AM
13323 print_symbol (10, GET_DYNAMIC_NAME (filedata,
13324 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
13325 putchar (' ' );
13326 }
252b5132 13327 else
978c4450 13328 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
13329 break;
13330 }
13331
13332 if (flags & SYMINFO_FLG_DIRECT)
13333 printf (" DIRECT");
13334 if (flags & SYMINFO_FLG_PASSTHRU)
13335 printf (" PASSTHRU");
13336 if (flags & SYMINFO_FLG_COPY)
13337 printf (" COPY");
13338 if (flags & SYMINFO_FLG_LAZYLOAD)
13339 printf (" LAZYLOAD");
13340
13341 puts ("");
13342 }
13343
015dc7e1 13344 return true;
252b5132
RH
13345}
13346
75802ccb
CE
13347/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
13348 is contained by the region START .. END. The types of ADDR, START
13349 and END should all be the same. Note both ADDR + NELEM and END
13350 point to just beyond the end of the regions that are being tested. */
13351#define IN_RANGE(START,END,ADDR,NELEM) \
13352 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 13353
cf13d699
NC
13354/* Check to see if the given reloc needs to be handled in a target specific
13355 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
13356 FALSE.
13357
13358 If called with reloc == NULL, then this is a signal that reloc processing
13359 for the current section has finished, and any saved state should be
13360 discarded. */
09c11c86 13361
015dc7e1 13362static bool
dda8d76d
NC
13363target_specific_reloc_handling (Filedata * filedata,
13364 Elf_Internal_Rela * reloc,
13365 unsigned char * start,
13366 unsigned char * end,
13367 Elf_Internal_Sym * symtab,
13368 unsigned long num_syms)
252b5132 13369{
f84ce13b
NC
13370 unsigned int reloc_type = 0;
13371 unsigned long sym_index = 0;
13372
13373 if (reloc)
13374 {
dda8d76d 13375 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
13376 sym_index = get_reloc_symindex (reloc->r_info);
13377 }
252b5132 13378
dda8d76d 13379 switch (filedata->file_header.e_machine)
252b5132 13380 {
13761a11
NC
13381 case EM_MSP430:
13382 case EM_MSP430_OLD:
13383 {
13384 static Elf_Internal_Sym * saved_sym = NULL;
13385
f84ce13b
NC
13386 if (reloc == NULL)
13387 {
13388 saved_sym = NULL;
015dc7e1 13389 return true;
f84ce13b
NC
13390 }
13391
13761a11
NC
13392 switch (reloc_type)
13393 {
13394 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 13395 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 13396 if (uses_msp430x_relocs (filedata))
13761a11 13397 break;
1a0670f3 13398 /* Fall through. */
13761a11 13399 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 13400 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
13401 /* PR 21139. */
13402 if (sym_index >= num_syms)
13403 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
13404 sym_index);
13405 else
13406 saved_sym = symtab + sym_index;
015dc7e1 13407 return true;
13761a11
NC
13408
13409 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13410 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
13411 goto handle_sym_diff;
0b4362b0 13412
13761a11
NC
13413 case 5: /* R_MSP430_16_BYTE */
13414 case 9: /* R_MSP430_8 */
7d81bc93 13415 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 13416 if (uses_msp430x_relocs (filedata))
13761a11
NC
13417 break;
13418 goto handle_sym_diff;
13419
13420 case 2: /* R_MSP430_ABS16 */
13421 case 15: /* R_MSP430X_ABS16 */
7d81bc93 13422 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 13423 if (! uses_msp430x_relocs (filedata))
13761a11
NC
13424 break;
13425 goto handle_sym_diff;
0b4362b0 13426
13761a11
NC
13427 handle_sym_diff:
13428 if (saved_sym != NULL)
13429 {
13430 bfd_vma value;
5a805384 13431 unsigned int reloc_size = 0;
7d81bc93
JL
13432 int leb_ret = 0;
13433 switch (reloc_type)
13434 {
13435 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13436 reloc_size = 4;
13437 break;
13438 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13439 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384 13440 if (reloc->r_offset < (size_t) (end - start))
015dc7e1 13441 read_leb128 (start + reloc->r_offset, end, false,
5a805384 13442 &reloc_size, &leb_ret);
7d81bc93
JL
13443 break;
13444 default:
13445 reloc_size = 2;
13446 break;
13447 }
13761a11 13448
5a805384 13449 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13450 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13451 "ULEB128 value\n"),
13452 (long) reloc->r_offset);
13453 else if (sym_index >= num_syms)
f84ce13b
NC
13454 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13455 sym_index);
03f7786e 13456 else
f84ce13b
NC
13457 {
13458 value = reloc->r_addend + (symtab[sym_index].st_value
13459 - saved_sym->st_value);
13460
b32e566b 13461 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13462 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13463 else
13464 /* PR 21137 */
13465 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13466 (long) reloc->r_offset);
f84ce13b 13467 }
13761a11
NC
13468
13469 saved_sym = NULL;
015dc7e1 13470 return true;
13761a11
NC
13471 }
13472 break;
13473
13474 default:
13475 if (saved_sym != NULL)
071436c6 13476 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13477 break;
13478 }
13479 break;
13480 }
13481
cf13d699
NC
13482 case EM_MN10300:
13483 case EM_CYGNUS_MN10300:
13484 {
13485 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13486
f84ce13b
NC
13487 if (reloc == NULL)
13488 {
13489 saved_sym = NULL;
015dc7e1 13490 return true;
f84ce13b
NC
13491 }
13492
cf13d699
NC
13493 switch (reloc_type)
13494 {
13495 case 34: /* R_MN10300_ALIGN */
015dc7e1 13496 return true;
cf13d699 13497 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13498 if (sym_index >= num_syms)
13499 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13500 sym_index);
13501 else
13502 saved_sym = symtab + sym_index;
015dc7e1 13503 return true;
f84ce13b 13504
cf13d699
NC
13505 case 1: /* R_MN10300_32 */
13506 case 2: /* R_MN10300_16 */
13507 if (saved_sym != NULL)
13508 {
03f7786e 13509 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13510 bfd_vma value;
252b5132 13511
f84ce13b
NC
13512 if (sym_index >= num_syms)
13513 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13514 sym_index);
03f7786e 13515 else
f84ce13b
NC
13516 {
13517 value = reloc->r_addend + (symtab[sym_index].st_value
13518 - saved_sym->st_value);
13519
b32e566b 13520 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13521 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13522 else
13523 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13524 (long) reloc->r_offset);
f84ce13b 13525 }
252b5132 13526
cf13d699 13527 saved_sym = NULL;
015dc7e1 13528 return true;
cf13d699
NC
13529 }
13530 break;
13531 default:
13532 if (saved_sym != NULL)
071436c6 13533 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13534 break;
13535 }
13536 break;
13537 }
6ff71e76
NC
13538
13539 case EM_RL78:
13540 {
13541 static bfd_vma saved_sym1 = 0;
13542 static bfd_vma saved_sym2 = 0;
13543 static bfd_vma value;
13544
f84ce13b
NC
13545 if (reloc == NULL)
13546 {
13547 saved_sym1 = saved_sym2 = 0;
015dc7e1 13548 return true;
f84ce13b
NC
13549 }
13550
6ff71e76
NC
13551 switch (reloc_type)
13552 {
13553 case 0x80: /* R_RL78_SYM. */
13554 saved_sym1 = saved_sym2;
f84ce13b
NC
13555 if (sym_index >= num_syms)
13556 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13557 sym_index);
13558 else
13559 {
13560 saved_sym2 = symtab[sym_index].st_value;
13561 saved_sym2 += reloc->r_addend;
13562 }
015dc7e1 13563 return true;
6ff71e76
NC
13564
13565 case 0x83: /* R_RL78_OPsub. */
13566 value = saved_sym1 - saved_sym2;
13567 saved_sym2 = saved_sym1 = 0;
015dc7e1 13568 return true;
6ff71e76
NC
13569 break;
13570
13571 case 0x41: /* R_RL78_ABS32. */
b32e566b 13572 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13573 byte_put (start + reloc->r_offset, value, 4);
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 case 0x43: /* R_RL78_ABS16. */
b32e566b 13581 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13582 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13583 else
13584 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13585 (long) reloc->r_offset);
6ff71e76 13586 value = 0;
015dc7e1 13587 return true;
6ff71e76
NC
13588
13589 default:
13590 break;
13591 }
13592 break;
13593 }
252b5132
RH
13594 }
13595
015dc7e1 13596 return false;
252b5132
RH
13597}
13598
aca88567
NC
13599/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13600 DWARF debug sections. This is a target specific test. Note - we do not
13601 go through the whole including-target-headers-multiple-times route, (as
13602 we have already done with <elf/h8.h>) because this would become very
13603 messy and even then this function would have to contain target specific
13604 information (the names of the relocs instead of their numeric values).
13605 FIXME: This is not the correct way to solve this problem. The proper way
13606 is to have target specific reloc sizing and typing functions created by
13607 the reloc-macros.h header, in the same way that it already creates the
13608 reloc naming functions. */
13609
015dc7e1 13610static bool
dda8d76d 13611is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13612{
d347c9df 13613 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13614 switch (filedata->file_header.e_machine)
aca88567 13615 {
41e92641 13616 case EM_386:
22abe556 13617 case EM_IAMCU:
41e92641 13618 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13619 case EM_68K:
13620 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13621 case EM_860:
13622 return reloc_type == 1; /* R_860_32. */
13623 case EM_960:
13624 return reloc_type == 2; /* R_960_32. */
a06ea964 13625 case EM_AARCH64:
9282b95a
JW
13626 return (reloc_type == 258
13627 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13628 case EM_BPF:
13629 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13630 case EM_ADAPTEVA_EPIPHANY:
13631 return reloc_type == 3;
aca88567 13632 case EM_ALPHA:
137b6b5f 13633 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13634 case EM_ARC:
13635 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13636 case EM_ARC_COMPACT:
13637 case EM_ARC_COMPACT2:
13638 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13639 case EM_ARM:
13640 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13641 case EM_AVR_OLD:
aca88567
NC
13642 case EM_AVR:
13643 return reloc_type == 1;
13644 case EM_BLACKFIN:
13645 return reloc_type == 0x12; /* R_byte4_data. */
13646 case EM_CRIS:
13647 return reloc_type == 3; /* R_CRIS_32. */
13648 case EM_CR16:
13649 return reloc_type == 3; /* R_CR16_NUM32. */
13650 case EM_CRX:
13651 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13652 case EM_CSKY:
13653 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13654 case EM_CYGNUS_FRV:
13655 return reloc_type == 1;
41e92641
NC
13656 case EM_CYGNUS_D10V:
13657 case EM_D10V:
13658 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13659 case EM_CYGNUS_D30V:
13660 case EM_D30V:
13661 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13662 case EM_DLX:
13663 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13664 case EM_CYGNUS_FR30:
13665 case EM_FR30:
13666 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13667 case EM_FT32:
13668 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13669 case EM_H8S:
13670 case EM_H8_300:
13671 case EM_H8_300H:
13672 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13673 case EM_IA_64:
262cdac7
AM
13674 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13675 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13676 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13677 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13678 case EM_IP2K_OLD:
13679 case EM_IP2K:
13680 return reloc_type == 2; /* R_IP2K_32. */
13681 case EM_IQ2000:
13682 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13683 case EM_LATTICEMICO32:
13684 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13685 case EM_M32C_OLD:
aca88567
NC
13686 case EM_M32C:
13687 return reloc_type == 3; /* R_M32C_32. */
13688 case EM_M32R:
13689 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13690 case EM_68HC11:
13691 case EM_68HC12:
13692 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13693 case EM_S12Z:
2849d19f
JD
13694 return reloc_type == 7 || /* R_S12Z_EXT32 */
13695 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13696 case EM_MCORE:
13697 return reloc_type == 1; /* R_MCORE_ADDR32. */
13698 case EM_CYGNUS_MEP:
13699 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13700 case EM_METAG:
13701 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13702 case EM_MICROBLAZE:
13703 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13704 case EM_MIPS:
13705 return reloc_type == 2; /* R_MIPS_32. */
13706 case EM_MMIX:
13707 return reloc_type == 4; /* R_MMIX_32. */
13708 case EM_CYGNUS_MN10200:
13709 case EM_MN10200:
13710 return reloc_type == 1; /* R_MN10200_32. */
13711 case EM_CYGNUS_MN10300:
13712 case EM_MN10300:
13713 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13714 case EM_MOXIE:
13715 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13716 case EM_MSP430_OLD:
13717 case EM_MSP430:
13761a11 13718 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13719 case EM_MT:
13720 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13721 case EM_NDS32:
13722 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13723 case EM_ALTERA_NIOS2:
36591ba1 13724 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13725 case EM_NIOS32:
13726 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13727 case EM_OR1K:
13728 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13729 case EM_PARISC:
9abca702 13730 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13731 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13732 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13733 case EM_PJ:
13734 case EM_PJ_OLD:
13735 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13736 case EM_PPC64:
13737 return reloc_type == 1; /* R_PPC64_ADDR32. */
13738 case EM_PPC:
13739 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13740 case EM_TI_PRU:
13741 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13742 case EM_RISCV:
13743 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13744 case EM_RL78:
13745 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13746 case EM_RX:
13747 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13748 case EM_S370:
13749 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13750 case EM_S390_OLD:
13751 case EM_S390:
13752 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13753 case EM_SCORE:
13754 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13755 case EM_SH:
13756 return reloc_type == 1; /* R_SH_DIR32. */
13757 case EM_SPARC32PLUS:
13758 case EM_SPARCV9:
13759 case EM_SPARC:
13760 return reloc_type == 3 /* R_SPARC_32. */
13761 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13762 case EM_SPU:
13763 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13764 case EM_TI_C6000:
13765 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13766 case EM_TILEGX:
13767 return reloc_type == 2; /* R_TILEGX_32. */
13768 case EM_TILEPRO:
13769 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13770 case EM_CYGNUS_V850:
13771 case EM_V850:
13772 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13773 case EM_V800:
13774 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13775 case EM_VAX:
13776 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13777 case EM_VISIUM:
13778 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13779 case EM_WEBASSEMBLY:
13780 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13781 case EM_X86_64:
8a9036a4 13782 case EM_L1OM:
7a9068fe 13783 case EM_K1OM:
aca88567 13784 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13785 case EM_XC16X:
13786 case EM_C166:
13787 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13788 case EM_XGATE:
13789 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13790 case EM_XSTORMY16:
13791 return reloc_type == 1; /* R_XSTROMY16_32. */
13792 case EM_XTENSA_OLD:
13793 case EM_XTENSA:
13794 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13795 case EM_Z80:
13796 return reloc_type == 6; /* R_Z80_32. */
aca88567 13797 default:
bee0ee85
NC
13798 {
13799 static unsigned int prev_warn = 0;
13800
13801 /* Avoid repeating the same warning multiple times. */
dda8d76d 13802 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13803 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13804 filedata->file_header.e_machine);
13805 prev_warn = filedata->file_header.e_machine;
015dc7e1 13806 return false;
bee0ee85 13807 }
aca88567
NC
13808 }
13809}
13810
13811/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13812 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13813
015dc7e1 13814static bool
dda8d76d 13815is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13816{
dda8d76d 13817 switch (filedata->file_header.e_machine)
d347c9df 13818 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13819 {
41e92641 13820 case EM_386:
22abe556 13821 case EM_IAMCU:
3e0873ac 13822 return reloc_type == 2; /* R_386_PC32. */
aca88567 13823 case EM_68K:
3e0873ac 13824 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13825 case EM_AARCH64:
13826 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13827 case EM_ADAPTEVA_EPIPHANY:
13828 return reloc_type == 6;
aca88567
NC
13829 case EM_ALPHA:
13830 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13831 case EM_ARC_COMPACT:
13832 case EM_ARC_COMPACT2:
13833 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13834 case EM_ARM:
3e0873ac 13835 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13836 case EM_AVR_OLD:
13837 case EM_AVR:
13838 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13839 case EM_MICROBLAZE:
13840 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13841 case EM_OR1K:
13842 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13843 case EM_PARISC:
85acf597 13844 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13845 case EM_PPC:
13846 return reloc_type == 26; /* R_PPC_REL32. */
13847 case EM_PPC64:
3e0873ac 13848 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13849 case EM_RISCV:
13850 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13851 case EM_S390_OLD:
13852 case EM_S390:
3e0873ac 13853 return reloc_type == 5; /* R_390_PC32. */
aca88567 13854 case EM_SH:
3e0873ac 13855 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13856 case EM_SPARC32PLUS:
13857 case EM_SPARCV9:
13858 case EM_SPARC:
3e0873ac 13859 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13860 case EM_SPU:
13861 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13862 case EM_TILEGX:
13863 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13864 case EM_TILEPRO:
13865 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13866 case EM_VISIUM:
13867 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13868 case EM_X86_64:
8a9036a4 13869 case EM_L1OM:
7a9068fe 13870 case EM_K1OM:
3e0873ac 13871 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13872 case EM_VAX:
13873 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13874 case EM_XTENSA_OLD:
13875 case EM_XTENSA:
13876 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13877 default:
13878 /* Do not abort or issue an error message here. Not all targets use
13879 pc-relative 32-bit relocs in their DWARF debug information and we
13880 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13881 more helpful warning message will be generated by apply_relocations
13882 anyway, so just return. */
015dc7e1 13883 return false;
aca88567
NC
13884 }
13885}
13886
13887/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13888 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13889
015dc7e1 13890static bool
dda8d76d 13891is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13892{
dda8d76d 13893 switch (filedata->file_header.e_machine)
aca88567 13894 {
a06ea964
NC
13895 case EM_AARCH64:
13896 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13897 case EM_ALPHA:
13898 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13899 case EM_IA_64:
262cdac7
AM
13900 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13901 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13902 case EM_PARISC:
13903 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13904 case EM_PPC64:
13905 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13906 case EM_RISCV:
13907 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13908 case EM_SPARC32PLUS:
13909 case EM_SPARCV9:
13910 case EM_SPARC:
714da62f
NC
13911 return reloc_type == 32 /* R_SPARC_64. */
13912 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13913 case EM_X86_64:
8a9036a4 13914 case EM_L1OM:
7a9068fe 13915 case EM_K1OM:
aca88567 13916 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13917 case EM_S390_OLD:
13918 case EM_S390:
aa137e4d
NC
13919 return reloc_type == 22; /* R_S390_64. */
13920 case EM_TILEGX:
13921 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13922 case EM_MIPS:
aa137e4d 13923 return reloc_type == 18; /* R_MIPS_64. */
aca88567 13924 default:
015dc7e1 13925 return false;
aca88567
NC
13926 }
13927}
13928
85acf597
RH
13929/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13930 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13931
015dc7e1 13932static bool
dda8d76d 13933is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13934{
dda8d76d 13935 switch (filedata->file_header.e_machine)
85acf597 13936 {
a06ea964
NC
13937 case EM_AARCH64:
13938 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13939 case EM_ALPHA:
aa137e4d 13940 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13941 case EM_IA_64:
262cdac7
AM
13942 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13943 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13944 case EM_PARISC:
aa137e4d 13945 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13946 case EM_PPC64:
aa137e4d 13947 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13948 case EM_SPARC32PLUS:
13949 case EM_SPARCV9:
13950 case EM_SPARC:
aa137e4d 13951 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13952 case EM_X86_64:
8a9036a4 13953 case EM_L1OM:
7a9068fe 13954 case EM_K1OM:
aa137e4d 13955 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13956 case EM_S390_OLD:
13957 case EM_S390:
aa137e4d
NC
13958 return reloc_type == 23; /* R_S390_PC64. */
13959 case EM_TILEGX:
13960 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597 13961 default:
015dc7e1 13962 return false;
85acf597
RH
13963 }
13964}
13965
4dc3c23d
AM
13966/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13967 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13968
015dc7e1 13969static bool
dda8d76d 13970is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13971{
dda8d76d 13972 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13973 {
13974 case EM_CYGNUS_MN10200:
13975 case EM_MN10200:
13976 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13977 case EM_FT32:
13978 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13979 case EM_Z80:
13980 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d 13981 default:
015dc7e1 13982 return false;
4dc3c23d
AM
13983 }
13984}
13985
aca88567
NC
13986/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13987 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13988
015dc7e1 13989static bool
dda8d76d 13990is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13991{
d347c9df 13992 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13993 switch (filedata->file_header.e_machine)
4b78141a 13994 {
886a2506
NC
13995 case EM_ARC:
13996 case EM_ARC_COMPACT:
13997 case EM_ARC_COMPACT2:
13998 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13999 case EM_ADAPTEVA_EPIPHANY:
14000 return reloc_type == 5;
aca88567
NC
14001 case EM_AVR_OLD:
14002 case EM_AVR:
14003 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
14004 case EM_CYGNUS_D10V:
14005 case EM_D10V:
14006 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
14007 case EM_FT32:
14008 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
14009 case EM_H8S:
14010 case EM_H8_300:
14011 case EM_H8_300H:
aca88567
NC
14012 return reloc_type == R_H8_DIR16;
14013 case EM_IP2K_OLD:
14014 case EM_IP2K:
14015 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 14016 case EM_M32C_OLD:
f4236fe4
DD
14017 case EM_M32C:
14018 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
14019 case EM_CYGNUS_MN10200:
14020 case EM_MN10200:
14021 return reloc_type == 2; /* R_MN10200_16. */
14022 case EM_CYGNUS_MN10300:
14023 case EM_MN10300:
14024 return reloc_type == 2; /* R_MN10300_16. */
aca88567 14025 case EM_MSP430:
dda8d76d 14026 if (uses_msp430x_relocs (filedata))
13761a11 14027 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 14028 /* Fall through. */
78c8d46c 14029 case EM_MSP430_OLD:
aca88567 14030 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
14031 case EM_NDS32:
14032 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 14033 case EM_ALTERA_NIOS2:
36591ba1 14034 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
14035 case EM_NIOS32:
14036 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
14037 case EM_OR1K:
14038 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
14039 case EM_RISCV:
14040 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
14041 case EM_TI_PRU:
14042 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
14043 case EM_TI_C6000:
14044 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
14045 case EM_VISIUM:
14046 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
14047 case EM_XC16X:
14048 case EM_C166:
14049 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
14050 case EM_XGATE:
14051 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
14052 case EM_Z80:
14053 return reloc_type == 4; /* R_Z80_16. */
4b78141a 14054 default:
015dc7e1 14055 return false;
4b78141a
NC
14056 }
14057}
14058
39e07931
AS
14059/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14060 a 8-bit absolute RELA relocation used in DWARF debug sections. */
14061
015dc7e1 14062static bool
39e07931
AS
14063is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14064{
14065 switch (filedata->file_header.e_machine)
14066 {
14067 case EM_RISCV:
14068 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
14069 case EM_Z80:
14070 return reloc_type == 1; /* R_Z80_8. */
39e07931 14071 default:
015dc7e1 14072 return false;
39e07931
AS
14073 }
14074}
14075
14076/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14077 a 6-bit absolute RELA relocation used in DWARF debug sections. */
14078
015dc7e1 14079static bool
39e07931
AS
14080is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
14081{
14082 switch (filedata->file_header.e_machine)
14083 {
14084 case EM_RISCV:
14085 return reloc_type == 53; /* R_RISCV_SET6. */
14086 default:
015dc7e1 14087 return false;
39e07931
AS
14088 }
14089}
14090
03336641
JW
14091/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14092 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
14093
015dc7e1 14094static bool
03336641
JW
14095is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14096{
14097 /* Please keep this table alpha-sorted for ease of visual lookup. */
14098 switch (filedata->file_header.e_machine)
14099 {
14100 case EM_RISCV:
14101 return reloc_type == 35; /* R_RISCV_ADD32. */
14102 default:
015dc7e1 14103 return false;
03336641
JW
14104 }
14105}
14106
14107/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14108 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
14109
015dc7e1 14110static bool
03336641
JW
14111is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14112{
14113 /* Please keep this table alpha-sorted for ease of visual lookup. */
14114 switch (filedata->file_header.e_machine)
14115 {
14116 case EM_RISCV:
14117 return reloc_type == 39; /* R_RISCV_SUB32. */
14118 default:
015dc7e1 14119 return false;
03336641
JW
14120 }
14121}
14122
14123/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14124 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
14125
015dc7e1 14126static bool
03336641
JW
14127is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14128{
14129 /* Please keep this table alpha-sorted for ease of visual lookup. */
14130 switch (filedata->file_header.e_machine)
14131 {
14132 case EM_RISCV:
14133 return reloc_type == 36; /* R_RISCV_ADD64. */
14134 default:
015dc7e1 14135 return false;
03336641
JW
14136 }
14137}
14138
14139/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14140 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
14141
015dc7e1 14142static bool
03336641
JW
14143is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14144{
14145 /* Please keep this table alpha-sorted for ease of visual lookup. */
14146 switch (filedata->file_header.e_machine)
14147 {
14148 case EM_RISCV:
14149 return reloc_type == 40; /* R_RISCV_SUB64. */
14150 default:
015dc7e1 14151 return false;
03336641
JW
14152 }
14153}
14154
14155/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14156 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
14157
015dc7e1 14158static bool
03336641
JW
14159is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14160{
14161 /* Please keep this table alpha-sorted for ease of visual lookup. */
14162 switch (filedata->file_header.e_machine)
14163 {
14164 case EM_RISCV:
14165 return reloc_type == 34; /* R_RISCV_ADD16. */
14166 default:
015dc7e1 14167 return false;
03336641
JW
14168 }
14169}
14170
14171/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14172 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
14173
015dc7e1 14174static bool
03336641
JW
14175is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14176{
14177 /* Please keep this table alpha-sorted for ease of visual lookup. */
14178 switch (filedata->file_header.e_machine)
14179 {
14180 case EM_RISCV:
14181 return reloc_type == 38; /* R_RISCV_SUB16. */
14182 default:
015dc7e1 14183 return false;
03336641
JW
14184 }
14185}
14186
14187/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14188 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
14189
015dc7e1 14190static bool
03336641
JW
14191is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
14192{
14193 /* Please keep this table alpha-sorted for ease of visual lookup. */
14194 switch (filedata->file_header.e_machine)
14195 {
14196 case EM_RISCV:
14197 return reloc_type == 33; /* R_RISCV_ADD8. */
14198 default:
015dc7e1 14199 return false;
03336641
JW
14200 }
14201}
14202
14203/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14204 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
14205
015dc7e1 14206static bool
03336641
JW
14207is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14208{
14209 /* Please keep this table alpha-sorted for ease of visual lookup. */
14210 switch (filedata->file_header.e_machine)
14211 {
14212 case EM_RISCV:
14213 return reloc_type == 37; /* R_RISCV_SUB8. */
14214 default:
015dc7e1 14215 return false;
03336641
JW
14216 }
14217}
14218
39e07931
AS
14219/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
14220 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
14221
015dc7e1 14222static bool
39e07931
AS
14223is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
14224{
14225 switch (filedata->file_header.e_machine)
14226 {
14227 case EM_RISCV:
14228 return reloc_type == 52; /* R_RISCV_SUB6. */
14229 default:
015dc7e1 14230 return false;
39e07931
AS
14231 }
14232}
14233
2a7b2e88
JK
14234/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
14235 relocation entries (possibly formerly used for SHT_GROUP sections). */
14236
015dc7e1 14237static bool
dda8d76d 14238is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 14239{
dda8d76d 14240 switch (filedata->file_header.e_machine)
2a7b2e88 14241 {
cb8f3167 14242 case EM_386: /* R_386_NONE. */
d347c9df 14243 case EM_68K: /* R_68K_NONE. */
cfb8c092 14244 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
14245 case EM_ALPHA: /* R_ALPHA_NONE. */
14246 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 14247 case EM_ARC: /* R_ARC_NONE. */
886a2506 14248 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 14249 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 14250 case EM_ARM: /* R_ARM_NONE. */
d347c9df 14251 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 14252 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
14253 case EM_FT32: /* R_FT32_NONE. */
14254 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 14255 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
14256 case EM_L1OM: /* R_X86_64_NONE. */
14257 case EM_M32R: /* R_M32R_NONE. */
14258 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 14259 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 14260 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
14261 case EM_NIOS32: /* R_NIOS_NONE. */
14262 case EM_OR1K: /* R_OR1K_NONE. */
14263 case EM_PARISC: /* R_PARISC_NONE. */
14264 case EM_PPC64: /* R_PPC64_NONE. */
14265 case EM_PPC: /* R_PPC_NONE. */
e23eba97 14266 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
14267 case EM_S390: /* R_390_NONE. */
14268 case EM_S390_OLD:
14269 case EM_SH: /* R_SH_NONE. */
14270 case EM_SPARC32PLUS:
14271 case EM_SPARC: /* R_SPARC_NONE. */
14272 case EM_SPARCV9:
aa137e4d
NC
14273 case EM_TILEGX: /* R_TILEGX_NONE. */
14274 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
14275 case EM_TI_C6000:/* R_C6000_NONE. */
14276 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 14277 case EM_XC16X:
6655dba2 14278 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 14279 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 14280 return reloc_type == 0;
d347c9df 14281
a06ea964
NC
14282 case EM_AARCH64:
14283 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
14284 case EM_AVR_OLD:
14285 case EM_AVR:
14286 return (reloc_type == 0 /* R_AVR_NONE. */
14287 || reloc_type == 30 /* R_AVR_DIFF8. */
14288 || reloc_type == 31 /* R_AVR_DIFF16. */
14289 || reloc_type == 32 /* R_AVR_DIFF32. */);
14290 case EM_METAG:
14291 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
14292 case EM_NDS32:
14293 return (reloc_type == 0 /* R_XTENSA_NONE. */
14294 || reloc_type == 204 /* R_NDS32_DIFF8. */
14295 || reloc_type == 205 /* R_NDS32_DIFF16. */
14296 || reloc_type == 206 /* R_NDS32_DIFF32. */
14297 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
14298 case EM_TI_PRU:
14299 return (reloc_type == 0 /* R_PRU_NONE. */
14300 || reloc_type == 65 /* R_PRU_DIFF8. */
14301 || reloc_type == 66 /* R_PRU_DIFF16. */
14302 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
14303 case EM_XTENSA_OLD:
14304 case EM_XTENSA:
4dc3c23d
AM
14305 return (reloc_type == 0 /* R_XTENSA_NONE. */
14306 || reloc_type == 17 /* R_XTENSA_DIFF8. */
14307 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
14308 || reloc_type == 19 /* R_XTENSA_DIFF32. */
14309 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
14310 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
14311 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
14312 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
14313 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
14314 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88 14315 }
015dc7e1 14316 return false;
2a7b2e88
JK
14317}
14318
d1c4b12b
NC
14319/* Returns TRUE if there is a relocation against
14320 section NAME at OFFSET bytes. */
14321
015dc7e1 14322bool
d1c4b12b
NC
14323reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
14324{
14325 Elf_Internal_Rela * relocs;
14326 Elf_Internal_Rela * rp;
14327
14328 if (dsec == NULL || dsec->reloc_info == NULL)
015dc7e1 14329 return false;
d1c4b12b
NC
14330
14331 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
14332
14333 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
14334 if (rp->r_offset == offset)
015dc7e1 14335 return true;
d1c4b12b 14336
015dc7e1 14337 return false;
d1c4b12b
NC
14338}
14339
cf13d699 14340/* Apply relocations to a section.
32ec8896
NC
14341 Returns TRUE upon success, FALSE otherwise.
14342 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
14343 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
14344 will be set to the number of relocs loaded.
14345
cf13d699 14346 Note: So far support has been added only for those relocations
32ec8896
NC
14347 which can be found in debug sections. FIXME: Add support for
14348 more relocations ? */
1b315056 14349
015dc7e1 14350static bool
dda8d76d 14351apply_relocations (Filedata * filedata,
d1c4b12b
NC
14352 const Elf_Internal_Shdr * section,
14353 unsigned char * start,
14354 bfd_size_type size,
1449284b 14355 void ** relocs_return,
d1c4b12b 14356 unsigned long * num_relocs_return)
1b315056 14357{
cf13d699 14358 Elf_Internal_Shdr * relsec;
0d2a7a93 14359 unsigned char * end = start + size;
cb8f3167 14360
d1c4b12b
NC
14361 if (relocs_return != NULL)
14362 {
14363 * (Elf_Internal_Rela **) relocs_return = NULL;
14364 * num_relocs_return = 0;
14365 }
14366
dda8d76d 14367 if (filedata->file_header.e_type != ET_REL)
32ec8896 14368 /* No relocs to apply. */
015dc7e1 14369 return true;
1b315056 14370
cf13d699 14371 /* Find the reloc section associated with the section. */
dda8d76d
NC
14372 for (relsec = filedata->section_headers;
14373 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 14374 ++relsec)
252b5132 14375 {
015dc7e1 14376 bool is_rela;
41e92641 14377 unsigned long num_relocs;
2cf0635d
NC
14378 Elf_Internal_Rela * relocs;
14379 Elf_Internal_Rela * rp;
14380 Elf_Internal_Shdr * symsec;
14381 Elf_Internal_Sym * symtab;
ba5cdace 14382 unsigned long num_syms;
2cf0635d 14383 Elf_Internal_Sym * sym;
252b5132 14384
41e92641 14385 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14386 || relsec->sh_info >= filedata->file_header.e_shnum
14387 || filedata->section_headers + relsec->sh_info != section
c256ffe7 14388 || relsec->sh_size == 0
dda8d76d 14389 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 14390 continue;
428409d5 14391
a788aedd
AM
14392 symsec = filedata->section_headers + relsec->sh_link;
14393 if (symsec->sh_type != SHT_SYMTAB
14394 && symsec->sh_type != SHT_DYNSYM)
015dc7e1 14395 return false;
a788aedd 14396
41e92641
NC
14397 is_rela = relsec->sh_type == SHT_RELA;
14398
14399 if (is_rela)
14400 {
dda8d76d 14401 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 14402 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14403 return false;
41e92641
NC
14404 }
14405 else
14406 {
dda8d76d 14407 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 14408 relsec->sh_size, & relocs, & num_relocs))
015dc7e1 14409 return false;
41e92641
NC
14410 }
14411
14412 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 14413 if (filedata->file_header.e_machine == EM_SH)
015dc7e1 14414 is_rela = false;
428409d5 14415
4de91c10 14416 symtab = get_elf_symbols (filedata, symsec, & num_syms);
103f02d3 14417
41e92641 14418 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 14419 {
015dc7e1
AM
14420 bfd_vma addend;
14421 unsigned int reloc_type;
14422 unsigned int reloc_size;
14423 bool reloc_inplace = false;
14424 bool reloc_subtract = false;
14425 unsigned char *rloc;
14426 unsigned long sym_index;
4b78141a 14427
dda8d76d 14428 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14429
dda8d76d 14430 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14431 continue;
dda8d76d 14432 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14433 continue;
dda8d76d
NC
14434 else if (is_32bit_abs_reloc (filedata, reloc_type)
14435 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14436 reloc_size = 4;
dda8d76d
NC
14437 else if (is_64bit_abs_reloc (filedata, reloc_type)
14438 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14439 reloc_size = 8;
dda8d76d 14440 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14441 reloc_size = 3;
dda8d76d 14442 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14443 reloc_size = 2;
39e07931
AS
14444 else if (is_8bit_abs_reloc (filedata, reloc_type)
14445 || is_6bit_abs_reloc (filedata, reloc_type))
14446 reloc_size = 1;
03336641
JW
14447 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14448 reloc_type))
14449 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14450 {
14451 reloc_size = 4;
015dc7e1 14452 reloc_inplace = true;
03336641
JW
14453 }
14454 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14455 reloc_type))
14456 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14457 {
14458 reloc_size = 8;
015dc7e1 14459 reloc_inplace = true;
03336641
JW
14460 }
14461 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14462 reloc_type))
14463 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14464 {
14465 reloc_size = 2;
015dc7e1 14466 reloc_inplace = true;
03336641
JW
14467 }
14468 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14469 reloc_type))
14470 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14471 {
14472 reloc_size = 1;
015dc7e1 14473 reloc_inplace = true;
03336641 14474 }
39e07931
AS
14475 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14476 reloc_type)))
14477 {
14478 reloc_size = 1;
015dc7e1 14479 reloc_inplace = true;
39e07931 14480 }
aca88567 14481 else
4b78141a 14482 {
bee0ee85 14483 static unsigned int prev_reloc = 0;
dda8d76d 14484
bee0ee85
NC
14485 if (reloc_type != prev_reloc)
14486 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14487 reloc_type, printable_section_name (filedata, section));
bee0ee85 14488 prev_reloc = reloc_type;
4b78141a
NC
14489 continue;
14490 }
103f02d3 14491
91d6fa6a 14492 rloc = start + rp->r_offset;
75802ccb 14493 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14494 {
14495 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14496 (unsigned long) rp->r_offset,
dda8d76d 14497 printable_section_name (filedata, section));
700dd8b7
L
14498 continue;
14499 }
103f02d3 14500
ba5cdace
NC
14501 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14502 if (sym_index >= num_syms)
14503 {
14504 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14505 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14506 continue;
14507 }
14508 sym = symtab + sym_index;
41e92641
NC
14509
14510 /* If the reloc has a symbol associated with it,
55f25fc3
L
14511 make sure that it is of an appropriate type.
14512
14513 Relocations against symbols without type can happen.
14514 Gcc -feliminate-dwarf2-dups may generate symbols
14515 without type for debug info.
14516
14517 Icc generates relocations against function symbols
14518 instead of local labels.
14519
14520 Relocations against object symbols can happen, eg when
14521 referencing a global array. For an example of this see
14522 the _clz.o binary in libgcc.a. */
aca88567 14523 if (sym != symtab
b8871f35 14524 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14525 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14526 {
d3a49aa8 14527 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14528 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14529 printable_section_name (filedata, relsec),
d3a49aa8 14530 (long int)(rp - relocs));
aca88567 14531 continue;
5b18a4bc 14532 }
252b5132 14533
4dc3c23d
AM
14534 addend = 0;
14535 if (is_rela)
14536 addend += rp->r_addend;
c47320c3
AM
14537 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14538 partial_inplace. */
4dc3c23d 14539 if (!is_rela
dda8d76d 14540 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14541 && reloc_type == 1)
dda8d76d
NC
14542 || ((filedata->file_header.e_machine == EM_PJ
14543 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14544 && reloc_type == 1)
dda8d76d
NC
14545 || ((filedata->file_header.e_machine == EM_D30V
14546 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14547 && reloc_type == 12)
14548 || reloc_inplace)
39e07931
AS
14549 {
14550 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14551 addend += byte_get (rloc, reloc_size) & 0x3f;
14552 else
14553 addend += byte_get (rloc, reloc_size);
14554 }
cb8f3167 14555
dda8d76d
NC
14556 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14557 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14558 {
14559 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14560 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14561 addend -= 8;
91d6fa6a 14562 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14563 reloc_size);
14564 }
39e07931
AS
14565 else if (is_6bit_abs_reloc (filedata, reloc_type)
14566 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14567 {
14568 if (reloc_subtract)
14569 addend -= sym->st_value;
14570 else
14571 addend += sym->st_value;
14572 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14573 byte_put (rloc, addend, reloc_size);
14574 }
03336641
JW
14575 else if (reloc_subtract)
14576 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14577 else
91d6fa6a 14578 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14579 }
252b5132 14580
5b18a4bc 14581 free (symtab);
f84ce13b
NC
14582 /* Let the target specific reloc processing code know that
14583 we have finished with these relocs. */
dda8d76d 14584 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14585
14586 if (relocs_return)
14587 {
14588 * (Elf_Internal_Rela **) relocs_return = relocs;
14589 * num_relocs_return = num_relocs;
14590 }
14591 else
14592 free (relocs);
14593
5b18a4bc
NC
14594 break;
14595 }
32ec8896 14596
015dc7e1 14597 return true;
5b18a4bc 14598}
103f02d3 14599
cf13d699 14600#ifdef SUPPORT_DISASSEMBLY
015dc7e1 14601static bool
dda8d76d 14602disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14603{
dda8d76d 14604 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14605
74e1a04b 14606 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14607
015dc7e1 14608 return true;
cf13d699
NC
14609}
14610#endif
14611
14612/* Reads in the contents of SECTION from FILE, returning a pointer
14613 to a malloc'ed buffer or NULL if something went wrong. */
14614
14615static char *
dda8d76d 14616get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14617{
dda8d76d 14618 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14619
14620 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14621 {
c6b78c96 14622 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14623 printable_section_name (filedata, section));
cf13d699
NC
14624 return NULL;
14625 }
14626
dda8d76d 14627 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14628 _("section contents"));
cf13d699
NC
14629}
14630
0e602686
NC
14631/* Uncompresses a section that was compressed using zlib, in place. */
14632
015dc7e1 14633static bool
dda8d76d
NC
14634uncompress_section_contents (unsigned char ** buffer,
14635 dwarf_size_type uncompressed_size,
14636 dwarf_size_type * size)
0e602686
NC
14637{
14638 dwarf_size_type compressed_size = *size;
14639 unsigned char * compressed_buffer = *buffer;
14640 unsigned char * uncompressed_buffer;
14641 z_stream strm;
14642 int rc;
14643
14644 /* It is possible the section consists of several compressed
14645 buffers concatenated together, so we uncompress in a loop. */
14646 /* PR 18313: The state field in the z_stream structure is supposed
14647 to be invisible to the user (ie us), but some compilers will
14648 still complain about it being used without initialisation. So
14649 we first zero the entire z_stream structure and then set the fields
14650 that we need. */
14651 memset (& strm, 0, sizeof strm);
14652 strm.avail_in = compressed_size;
14653 strm.next_in = (Bytef *) compressed_buffer;
14654 strm.avail_out = uncompressed_size;
14655 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14656
14657 rc = inflateInit (& strm);
14658 while (strm.avail_in > 0)
14659 {
14660 if (rc != Z_OK)
3624a6c1 14661 break;
0e602686
NC
14662 strm.next_out = ((Bytef *) uncompressed_buffer
14663 + (uncompressed_size - strm.avail_out));
14664 rc = inflate (&strm, Z_FINISH);
14665 if (rc != Z_STREAM_END)
3624a6c1 14666 break;
0e602686
NC
14667 rc = inflateReset (& strm);
14668 }
ad92f33d
AM
14669 if (inflateEnd (& strm) != Z_OK
14670 || rc != Z_OK
0e602686
NC
14671 || strm.avail_out != 0)
14672 goto fail;
14673
14674 *buffer = uncompressed_buffer;
14675 *size = uncompressed_size;
015dc7e1 14676 return true;
0e602686
NC
14677
14678 fail:
14679 free (uncompressed_buffer);
14680 /* Indicate decompression failure. */
14681 *buffer = NULL;
015dc7e1 14682 return false;
0e602686 14683}
dd24e3da 14684
015dc7e1 14685static bool
dda8d76d 14686dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14687{
015dc7e1
AM
14688 Elf_Internal_Shdr *relsec;
14689 bfd_size_type num_bytes;
14690 unsigned char *data;
14691 unsigned char *end;
14692 unsigned char *real_start;
14693 unsigned char *start;
14694 bool some_strings_shown;
cf13d699 14695
dda8d76d 14696 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14697 if (start == NULL)
c6b78c96 14698 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14699 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
c6b78c96 14700
0e602686 14701 num_bytes = section->sh_size;
cf13d699 14702
835f2fae
NC
14703 if (filedata->is_separate)
14704 printf (_("\nString dump of section '%s' in linked file %s:\n"),
14705 printable_section_name (filedata, section),
14706 filedata->file_name);
14707 else
14708 printf (_("\nString dump of section '%s':\n"),
14709 printable_section_name (filedata, section));
cf13d699 14710
0e602686
NC
14711 if (decompress_dumps)
14712 {
14713 dwarf_size_type new_size = num_bytes;
14714 dwarf_size_type uncompressed_size = 0;
14715
14716 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14717 {
14718 Elf_Internal_Chdr chdr;
14719 unsigned int compression_header_size
ebdf1ebf
NC
14720 = get_compression_header (& chdr, (unsigned char *) start,
14721 num_bytes);
5844b465
NC
14722 if (compression_header_size == 0)
14723 /* An error message will have already been generated
14724 by get_compression_header. */
14725 goto error_out;
0e602686 14726
813dabb9 14727 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14728 {
813dabb9 14729 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14730 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14731 goto error_out;
813dabb9 14732 }
813dabb9
L
14733 uncompressed_size = chdr.ch_size;
14734 start += compression_header_size;
14735 new_size -= compression_header_size;
0e602686
NC
14736 }
14737 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14738 {
14739 /* Read the zlib header. In this case, it should be "ZLIB"
14740 followed by the uncompressed section size, 8 bytes in
14741 big-endian order. */
14742 uncompressed_size = start[4]; uncompressed_size <<= 8;
14743 uncompressed_size += start[5]; uncompressed_size <<= 8;
14744 uncompressed_size += start[6]; uncompressed_size <<= 8;
14745 uncompressed_size += start[7]; uncompressed_size <<= 8;
14746 uncompressed_size += start[8]; uncompressed_size <<= 8;
14747 uncompressed_size += start[9]; uncompressed_size <<= 8;
14748 uncompressed_size += start[10]; uncompressed_size <<= 8;
14749 uncompressed_size += start[11];
14750 start += 12;
14751 new_size -= 12;
14752 }
14753
1835f746
NC
14754 if (uncompressed_size)
14755 {
14756 if (uncompress_section_contents (& start,
14757 uncompressed_size, & new_size))
14758 num_bytes = new_size;
14759 else
14760 {
14761 error (_("Unable to decompress section %s\n"),
dda8d76d 14762 printable_section_name (filedata, section));
f761cb13 14763 goto error_out;
1835f746
NC
14764 }
14765 }
bc303e5d
NC
14766 else
14767 start = real_start;
0e602686 14768 }
fd8008d8 14769
cf13d699
NC
14770 /* If the section being dumped has relocations against it the user might
14771 be expecting these relocations to have been applied. Check for this
14772 case and issue a warning message in order to avoid confusion.
14773 FIXME: Maybe we ought to have an option that dumps a section with
14774 relocs applied ? */
dda8d76d
NC
14775 for (relsec = filedata->section_headers;
14776 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14777 ++relsec)
14778 {
14779 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14780 || relsec->sh_info >= filedata->file_header.e_shnum
14781 || filedata->section_headers + relsec->sh_info != section
cf13d699 14782 || relsec->sh_size == 0
dda8d76d 14783 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14784 continue;
14785
14786 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14787 break;
14788 }
14789
cf13d699
NC
14790 data = start;
14791 end = start + num_bytes;
015dc7e1 14792 some_strings_shown = false;
cf13d699 14793
ba3265d0
NC
14794#ifdef HAVE_MBSTATE_T
14795 mbstate_t state;
14796 /* Initialise the multibyte conversion state. */
14797 memset (& state, 0, sizeof (state));
14798#endif
14799
015dc7e1 14800 bool continuing = false;
ba3265d0 14801
cf13d699
NC
14802 while (data < end)
14803 {
14804 while (!ISPRINT (* data))
14805 if (++ data >= end)
14806 break;
14807
14808 if (data < end)
14809 {
071436c6
NC
14810 size_t maxlen = end - data;
14811
ba3265d0
NC
14812 if (continuing)
14813 {
14814 printf (" ");
015dc7e1 14815 continuing = false;
ba3265d0
NC
14816 }
14817 else
14818 {
d1ce973e 14819 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14820 }
14821
4082ef84
NC
14822 if (maxlen > 0)
14823 {
f3da8a96 14824 char c = 0;
ba3265d0
NC
14825
14826 while (maxlen)
14827 {
14828 c = *data++;
14829
14830 if (c == 0)
14831 break;
14832
14833 /* PR 25543: Treat new-lines as string-ending characters. */
14834 if (c == '\n')
14835 {
14836 printf ("\\n\n");
14837 if (*data != 0)
015dc7e1 14838 continuing = true;
ba3265d0
NC
14839 break;
14840 }
14841
14842 /* Do not print control characters directly as they can affect terminal
14843 settings. Such characters usually appear in the names generated
14844 by the assembler for local labels. */
14845 if (ISCNTRL (c))
14846 {
14847 printf ("^%c", c + 0x40);
14848 }
14849 else if (ISPRINT (c))
14850 {
14851 putchar (c);
14852 }
14853 else
14854 {
14855 size_t n;
14856#ifdef HAVE_MBSTATE_T
14857 wchar_t w;
14858#endif
14859 /* Let printf do the hard work of displaying multibyte characters. */
14860 printf ("%.1s", data - 1);
14861#ifdef HAVE_MBSTATE_T
14862 /* Try to find out how many bytes made up the character that was
14863 just printed. Advance the symbol pointer past the bytes that
14864 were displayed. */
14865 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14866#else
14867 n = 1;
14868#endif
14869 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14870 data += (n - 1);
14871 }
14872 }
14873
14874 if (c != '\n')
14875 putchar ('\n');
4082ef84
NC
14876 }
14877 else
14878 {
14879 printf (_("<corrupt>\n"));
14880 data = end;
14881 }
015dc7e1 14882 some_strings_shown = true;
cf13d699
NC
14883 }
14884 }
14885
14886 if (! some_strings_shown)
14887 printf (_(" No strings found in this section."));
14888
0e602686 14889 free (real_start);
cf13d699
NC
14890
14891 putchar ('\n');
015dc7e1 14892 return true;
f761cb13
AM
14893
14894error_out:
14895 free (real_start);
015dc7e1 14896 return false;
cf13d699
NC
14897}
14898
015dc7e1
AM
14899static bool
14900dump_section_as_bytes (Elf_Internal_Shdr *section,
14901 Filedata *filedata,
14902 bool relocate)
cf13d699
NC
14903{
14904 Elf_Internal_Shdr * relsec;
0e602686
NC
14905 bfd_size_type bytes;
14906 bfd_size_type section_size;
14907 bfd_vma addr;
14908 unsigned char * data;
14909 unsigned char * real_start;
14910 unsigned char * start;
14911
dda8d76d 14912 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14913 if (start == NULL)
c6b78c96 14914 /* PR 21820: Do not fail if the section was empty. */
63b4cc53 14915 return section->sh_size == 0 || section->sh_type == SHT_NOBITS;
32ec8896 14916
0e602686 14917 section_size = section->sh_size;
cf13d699 14918
835f2fae
NC
14919 if (filedata->is_separate)
14920 printf (_("\nHex dump of section '%s' in linked file %s:\n"),
14921 printable_section_name (filedata, section),
14922 filedata->file_name);
14923 else
14924 printf (_("\nHex dump of section '%s':\n"),
14925 printable_section_name (filedata, section));
cf13d699 14926
0e602686
NC
14927 if (decompress_dumps)
14928 {
14929 dwarf_size_type new_size = section_size;
14930 dwarf_size_type uncompressed_size = 0;
14931
14932 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14933 {
14934 Elf_Internal_Chdr chdr;
14935 unsigned int compression_header_size
ebdf1ebf 14936 = get_compression_header (& chdr, start, section_size);
0e602686 14937
5844b465
NC
14938 if (compression_header_size == 0)
14939 /* An error message will have already been generated
14940 by get_compression_header. */
14941 goto error_out;
14942
813dabb9 14943 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14944 {
813dabb9 14945 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14946 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14947 goto error_out;
0e602686 14948 }
813dabb9
L
14949 uncompressed_size = chdr.ch_size;
14950 start += compression_header_size;
14951 new_size -= compression_header_size;
0e602686
NC
14952 }
14953 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14954 {
14955 /* Read the zlib header. In this case, it should be "ZLIB"
14956 followed by the uncompressed section size, 8 bytes in
14957 big-endian order. */
14958 uncompressed_size = start[4]; uncompressed_size <<= 8;
14959 uncompressed_size += start[5]; uncompressed_size <<= 8;
14960 uncompressed_size += start[6]; uncompressed_size <<= 8;
14961 uncompressed_size += start[7]; uncompressed_size <<= 8;
14962 uncompressed_size += start[8]; uncompressed_size <<= 8;
14963 uncompressed_size += start[9]; uncompressed_size <<= 8;
14964 uncompressed_size += start[10]; uncompressed_size <<= 8;
14965 uncompressed_size += start[11];
14966 start += 12;
14967 new_size -= 12;
14968 }
14969
f055032e
NC
14970 if (uncompressed_size)
14971 {
14972 if (uncompress_section_contents (& start, uncompressed_size,
14973 & new_size))
bc303e5d
NC
14974 {
14975 section_size = new_size;
14976 }
f055032e
NC
14977 else
14978 {
14979 error (_("Unable to decompress section %s\n"),
dda8d76d 14980 printable_section_name (filedata, section));
bc303e5d 14981 /* FIXME: Print the section anyway ? */
f761cb13 14982 goto error_out;
f055032e
NC
14983 }
14984 }
bc303e5d
NC
14985 else
14986 start = real_start;
0e602686 14987 }
14ae95f2 14988
cf13d699
NC
14989 if (relocate)
14990 {
dda8d76d 14991 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14992 goto error_out;
cf13d699
NC
14993 }
14994 else
14995 {
14996 /* If the section being dumped has relocations against it the user might
14997 be expecting these relocations to have been applied. Check for this
14998 case and issue a warning message in order to avoid confusion.
14999 FIXME: Maybe we ought to have an option that dumps a section with
15000 relocs applied ? */
dda8d76d
NC
15001 for (relsec = filedata->section_headers;
15002 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
15003 ++relsec)
15004 {
15005 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
15006 || relsec->sh_info >= filedata->file_header.e_shnum
15007 || filedata->section_headers + relsec->sh_info != section
cf13d699 15008 || relsec->sh_size == 0
dda8d76d 15009 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
15010 continue;
15011
15012 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
15013 break;
15014 }
15015 }
15016
15017 addr = section->sh_addr;
0e602686 15018 bytes = section_size;
cf13d699
NC
15019 data = start;
15020
15021 while (bytes)
15022 {
15023 int j;
15024 int k;
15025 int lbytes;
15026
15027 lbytes = (bytes > 16 ? 16 : bytes);
15028
15029 printf (" 0x%8.8lx ", (unsigned long) addr);
15030
15031 for (j = 0; j < 16; j++)
15032 {
15033 if (j < lbytes)
15034 printf ("%2.2x", data[j]);
15035 else
15036 printf (" ");
15037
15038 if ((j & 3) == 3)
15039 printf (" ");
15040 }
15041
15042 for (j = 0; j < lbytes; j++)
15043 {
15044 k = data[j];
15045 if (k >= ' ' && k < 0x7f)
15046 printf ("%c", k);
15047 else
15048 printf (".");
15049 }
15050
15051 putchar ('\n');
15052
15053 data += lbytes;
15054 addr += lbytes;
15055 bytes -= lbytes;
15056 }
15057
0e602686 15058 free (real_start);
cf13d699
NC
15059
15060 putchar ('\n');
015dc7e1 15061 return true;
f761cb13
AM
15062
15063 error_out:
15064 free (real_start);
015dc7e1 15065 return false;
cf13d699
NC
15066}
15067
094e34f2 15068#ifdef ENABLE_LIBCTF
7d9813f1
NA
15069static ctf_sect_t *
15070shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
15071{
b9e920ec 15072 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
15073 buf->cts_size = shdr->sh_size;
15074 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
15075
15076 return buf;
15077}
15078
15079/* Formatting callback function passed to ctf_dump. Returns either the pointer
15080 it is passed, or a pointer to newly-allocated storage, in which case
15081 dump_ctf() will free it when it no longer needs it. */
15082
2f6ecaed
NA
15083static char *
15084dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
15085 char *s, void *arg)
7d9813f1 15086{
3e50a591 15087 const char *blanks = arg;
7d9813f1
NA
15088 char *new_s;
15089
3e50a591 15090 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
15091 return s;
15092 return new_s;
15093}
15094
926c9e76
NA
15095/* Dump CTF errors/warnings. */
15096static void
139633c3 15097dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
15098{
15099 ctf_next_t *it = NULL;
15100 char *errtext;
15101 int is_warning;
15102 int err;
15103
15104 /* Dump accumulated errors and warnings. */
15105 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
15106 {
5e9b84f7 15107 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
15108 errtext);
15109 free (errtext);
15110 }
15111 if (err != ECTF_NEXT_END)
15112 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
15113}
15114
2f6ecaed
NA
15115/* Dump one CTF archive member. */
15116
15117static int
139633c3 15118dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 15119{
139633c3 15120 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
15121 const char *things[] = {"Header", "Labels", "Data objects",
15122 "Function objects", "Variables", "Types", "Strings",
15123 ""};
15124 const char **thing;
15125 size_t i;
8b37e7b6 15126 int err = 0;
2f6ecaed
NA
15127
15128 /* Only print out the name of non-default-named archive members.
15129 The name .ctf appears everywhere, even for things that aren't
15130 really archives, so printing it out is liable to be confusing.
15131
15132 The parent, if there is one, is the default-owned archive member:
15133 avoid importing it into itself. (This does no harm, but looks
15134 confusing.) */
15135
15136 if (strcmp (name, ".ctf") != 0)
15137 {
15138 printf (_("\nCTF archive member: %s:\n"), name);
15139 ctf_import (ctf, parent);
15140 }
15141
15142 for (i = 0, thing = things; *thing[0]; thing++, i++)
15143 {
15144 ctf_dump_state_t *s = NULL;
15145 char *item;
15146
15147 printf ("\n %s:\n", *thing);
15148 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
15149 (void *) " ")) != NULL)
15150 {
15151 printf ("%s\n", item);
15152 free (item);
15153 }
15154
15155 if (ctf_errno (ctf))
15156 {
15157 error (_("Iteration failed: %s, %s\n"), *thing,
15158 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
15159 err = 1;
15160 goto out;
2f6ecaed
NA
15161 }
15162 }
8b37e7b6
NA
15163
15164 out:
926c9e76 15165 dump_ctf_errs (ctf);
8b37e7b6 15166 return err;
2f6ecaed
NA
15167}
15168
015dc7e1 15169static bool
7d9813f1
NA
15170dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
15171{
15172 Elf_Internal_Shdr * parent_sec = NULL;
15173 Elf_Internal_Shdr * symtab_sec = NULL;
15174 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
15175 void * data = NULL;
15176 void * symdata = NULL;
15177 void * strdata = NULL;
15178 void * parentdata = NULL;
15179 ctf_sect_t ctfsect, symsect, strsect, parentsect;
15180 ctf_sect_t * symsectp = NULL;
15181 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
15182 ctf_archive_t * ctfa = NULL;
15183 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 15184 ctf_dict_t * parent = NULL;
7d9813f1 15185
7d9813f1 15186 int err;
015dc7e1 15187 bool ret = false;
7d9813f1
NA
15188
15189 shdr_to_ctf_sect (&ctfsect, section, filedata);
15190 data = get_section_contents (section, filedata);
15191 ctfsect.cts_data = data;
15192
616febde 15193 if (!dump_ctf_symtab_name)
3d16b64e 15194 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
15195
15196 if (!dump_ctf_strtab_name)
3d16b64e 15197 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
15198
15199 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
15200 {
15201 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
15202 {
15203 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
15204 goto fail;
15205 }
15206 if ((symdata = (void *) get_data (NULL, filedata,
15207 symtab_sec->sh_offset, 1,
15208 symtab_sec->sh_size,
15209 _("symbols"))) == NULL)
15210 goto fail;
15211 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
15212 symsect.cts_data = symdata;
15213 }
835f2fae 15214
df16e041 15215 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
15216 {
15217 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
15218 {
15219 error (_("No string table section named %s\n"),
15220 dump_ctf_strtab_name);
15221 goto fail;
15222 }
15223 if ((strdata = (void *) get_data (NULL, filedata,
15224 strtab_sec->sh_offset, 1,
15225 strtab_sec->sh_size,
15226 _("strings"))) == NULL)
15227 goto fail;
15228 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
15229 strsect.cts_data = strdata;
15230 }
835f2fae 15231
7d9813f1
NA
15232 if (dump_ctf_parent_name)
15233 {
15234 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
15235 {
15236 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
15237 goto fail;
15238 }
15239 if ((parentdata = (void *) get_data (NULL, filedata,
15240 parent_sec->sh_offset, 1,
15241 parent_sec->sh_size,
15242 _("CTF parent"))) == NULL)
15243 goto fail;
15244 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
15245 parentsect.cts_data = parentdata;
15246 }
15247
2f6ecaed
NA
15248 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
15249 libctf papers over the difference, so we can pretend it is always an
15250 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 15251
2f6ecaed 15252 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 15253 {
926c9e76 15254 dump_ctf_errs (NULL);
7d9813f1
NA
15255 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15256 goto fail;
15257 }
15258
96c61be5
NA
15259 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
15260 != ELFDATA2MSB);
15261
7d9813f1
NA
15262 if (parentdata)
15263 {
2f6ecaed
NA
15264 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
15265 &err)) == NULL)
7d9813f1 15266 {
926c9e76 15267 dump_ctf_errs (NULL);
7d9813f1
NA
15268 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15269 goto fail;
15270 }
2f6ecaed
NA
15271 lookparent = parenta;
15272 }
15273 else
15274 lookparent = ctfa;
7d9813f1 15275
2f6ecaed
NA
15276 /* Assume that the applicable parent archive member is the default one.
15277 (This is what all known implementations are expected to do, if they
15278 put CTFs and their parents in archives together.) */
ae41200b 15279 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 15280 {
926c9e76 15281 dump_ctf_errs (NULL);
2f6ecaed
NA
15282 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
15283 goto fail;
7d9813f1
NA
15284 }
15285
015dc7e1 15286 ret = true;
7d9813f1 15287
835f2fae
NC
15288 if (filedata->is_separate)
15289 printf (_("\nDump of CTF section '%s' in linked file %s:\n"),
15290 printable_section_name (filedata, section),
15291 filedata->file_name);
15292 else
15293 printf (_("\nDump of CTF section '%s':\n"),
15294 printable_section_name (filedata, section));
7d9813f1 15295
83d59285
NA
15296 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
15297 {
15298 dump_ctf_errs (NULL);
15299 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
015dc7e1 15300 ret = false;
83d59285 15301 }
7d9813f1
NA
15302
15303 fail:
139633c3 15304 ctf_dict_close (parent);
2f6ecaed
NA
15305 ctf_close (ctfa);
15306 ctf_close (parenta);
7d9813f1
NA
15307 free (parentdata);
15308 free (data);
15309 free (symdata);
15310 free (strdata);
15311 return ret;
15312}
094e34f2 15313#endif
7d9813f1 15314
015dc7e1 15315static bool
dda8d76d
NC
15316load_specific_debug_section (enum dwarf_section_display_enum debug,
15317 const Elf_Internal_Shdr * sec,
15318 void * data)
1007acb3 15319{
2cf0635d 15320 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 15321 char buf [64];
dda8d76d 15322 Filedata * filedata = (Filedata *) data;
9abca702 15323
19e6b90e 15324 if (section->start != NULL)
dda8d76d
NC
15325 {
15326 /* If it is already loaded, do nothing. */
15327 if (streq (section->filename, filedata->file_name))
015dc7e1 15328 return true;
dda8d76d
NC
15329 free (section->start);
15330 }
1007acb3 15331
19e6b90e
L
15332 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
15333 section->address = sec->sh_addr;
dda8d76d
NC
15334 section->filename = filedata->file_name;
15335 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
15336 sec->sh_offset, 1,
15337 sec->sh_size, buf);
59245841
NC
15338 if (section->start == NULL)
15339 section->size = 0;
15340 else
15341 {
77115a4a
L
15342 unsigned char *start = section->start;
15343 dwarf_size_type size = sec->sh_size;
dab394de 15344 dwarf_size_type uncompressed_size = 0;
77115a4a
L
15345
15346 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
15347 {
15348 Elf_Internal_Chdr chdr;
d8024a91
NC
15349 unsigned int compression_header_size;
15350
f53be977
L
15351 if (size < (is_32bit_elf
15352 ? sizeof (Elf32_External_Chdr)
15353 : sizeof (Elf64_External_Chdr)))
d8024a91 15354 {
55be8fd0 15355 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 15356 section->name);
015dc7e1 15357 return false;
d8024a91
NC
15358 }
15359
ebdf1ebf 15360 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
15361 if (compression_header_size == 0)
15362 /* An error message will have already been generated
15363 by get_compression_header. */
015dc7e1 15364 return false;
d8024a91 15365
813dabb9
L
15366 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
15367 {
15368 warn (_("section '%s' has unsupported compress type: %d\n"),
15369 section->name, chdr.ch_type);
015dc7e1 15370 return false;
813dabb9 15371 }
dab394de 15372 uncompressed_size = chdr.ch_size;
77115a4a
L
15373 start += compression_header_size;
15374 size -= compression_header_size;
15375 }
dab394de
L
15376 else if (size > 12 && streq ((char *) start, "ZLIB"))
15377 {
15378 /* Read the zlib header. In this case, it should be "ZLIB"
15379 followed by the uncompressed section size, 8 bytes in
15380 big-endian order. */
15381 uncompressed_size = start[4]; uncompressed_size <<= 8;
15382 uncompressed_size += start[5]; uncompressed_size <<= 8;
15383 uncompressed_size += start[6]; uncompressed_size <<= 8;
15384 uncompressed_size += start[7]; uncompressed_size <<= 8;
15385 uncompressed_size += start[8]; uncompressed_size <<= 8;
15386 uncompressed_size += start[9]; uncompressed_size <<= 8;
15387 uncompressed_size += start[10]; uncompressed_size <<= 8;
15388 uncompressed_size += start[11];
15389 start += 12;
15390 size -= 12;
15391 }
15392
1835f746 15393 if (uncompressed_size)
77115a4a 15394 {
1835f746
NC
15395 if (uncompress_section_contents (&start, uncompressed_size,
15396 &size))
15397 {
15398 /* Free the compressed buffer, update the section buffer
15399 and the section size if uncompress is successful. */
15400 free (section->start);
15401 section->start = start;
15402 }
15403 else
15404 {
15405 error (_("Unable to decompress section %s\n"),
dda8d76d 15406 printable_section_name (filedata, sec));
015dc7e1 15407 return false;
1835f746 15408 }
77115a4a 15409 }
bc303e5d 15410
77115a4a 15411 section->size = size;
59245841 15412 }
4a114e3e 15413
1b315056 15414 if (section->start == NULL)
015dc7e1 15415 return false;
1b315056 15416
19e6b90e 15417 if (debug_displays [debug].relocate)
32ec8896 15418 {
dda8d76d 15419 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896 15420 & section->reloc_info, & section->num_relocs))
015dc7e1 15421 return false;
32ec8896 15422 }
d1c4b12b
NC
15423 else
15424 {
15425 section->reloc_info = NULL;
15426 section->num_relocs = 0;
15427 }
1007acb3 15428
015dc7e1 15429 return true;
1007acb3
L
15430}
15431
301a9420
AM
15432#if HAVE_LIBDEBUGINFOD
15433/* Return a hex string representation of the build-id. */
15434unsigned char *
15435get_build_id (void * data)
15436{
ca0e11aa 15437 Filedata * filedata = (Filedata *) data;
301a9420
AM
15438 Elf_Internal_Shdr * shdr;
15439 unsigned long i;
15440
55be8fd0
NC
15441 /* Iterate through notes to find note.gnu.build-id.
15442 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15443 for (i = 0, shdr = filedata->section_headers;
15444 i < filedata->file_header.e_shnum && shdr != NULL;
15445 i++, shdr++)
15446 {
15447 if (shdr->sh_type != SHT_NOTE)
15448 continue;
15449
15450 char * next;
15451 char * end;
15452 size_t data_remaining;
15453 size_t min_notesz;
15454 Elf_External_Note * enote;
15455 Elf_Internal_Note inote;
15456
15457 bfd_vma offset = shdr->sh_offset;
15458 bfd_vma align = shdr->sh_addralign;
15459 bfd_vma length = shdr->sh_size;
15460
15461 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15462 if (enote == NULL)
15463 continue;
15464
15465 if (align < 4)
15466 align = 4;
15467 else if (align != 4 && align != 8)
f761cb13
AM
15468 {
15469 free (enote);
15470 continue;
15471 }
301a9420
AM
15472
15473 end = (char *) enote + length;
15474 data_remaining = end - (char *) enote;
15475
15476 if (!is_ia64_vms (filedata))
15477 {
15478 min_notesz = offsetof (Elf_External_Note, name);
15479 if (data_remaining < min_notesz)
15480 {
55be8fd0
NC
15481 warn (_("\
15482malformed note encountered in section %s whilst scanning for build-id note\n"),
15483 printable_section_name (filedata, shdr));
f761cb13 15484 free (enote);
55be8fd0 15485 continue;
301a9420
AM
15486 }
15487 data_remaining -= min_notesz;
15488
15489 inote.type = BYTE_GET (enote->type);
15490 inote.namesz = BYTE_GET (enote->namesz);
15491 inote.namedata = enote->name;
15492 inote.descsz = BYTE_GET (enote->descsz);
15493 inote.descdata = ((char *) enote
15494 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15495 inote.descpos = offset + (inote.descdata - (char *) enote);
15496 next = ((char *) enote
15497 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15498 }
15499 else
15500 {
15501 Elf64_External_VMS_Note *vms_enote;
15502
15503 /* PR binutils/15191
15504 Make sure that there is enough data to read. */
15505 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15506 if (data_remaining < min_notesz)
15507 {
55be8fd0
NC
15508 warn (_("\
15509malformed note encountered in section %s whilst scanning for build-id note\n"),
15510 printable_section_name (filedata, shdr));
f761cb13 15511 free (enote);
55be8fd0 15512 continue;
301a9420
AM
15513 }
15514 data_remaining -= min_notesz;
15515
15516 vms_enote = (Elf64_External_VMS_Note *) enote;
15517 inote.type = BYTE_GET (vms_enote->type);
15518 inote.namesz = BYTE_GET (vms_enote->namesz);
15519 inote.namedata = vms_enote->name;
15520 inote.descsz = BYTE_GET (vms_enote->descsz);
15521 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15522 inote.descpos = offset + (inote.descdata - (char *) enote);
15523 next = inote.descdata + align_power (inote.descsz, 3);
15524 }
15525
15526 /* Skip malformed notes. */
15527 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15528 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15529 || (size_t) (next - inote.descdata) < inote.descsz
15530 || ((size_t) (next - inote.descdata)
15531 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15532 {
55be8fd0
NC
15533 warn (_("\
15534malformed note encountered in section %s whilst scanning for build-id note\n"),
15535 printable_section_name (filedata, shdr));
f761cb13 15536 free (enote);
301a9420
AM
15537 continue;
15538 }
15539
15540 /* Check if this is the build-id note. If so then convert the build-id
15541 bytes to a hex string. */
15542 if (inote.namesz > 0
24d127aa 15543 && startswith (inote.namedata, "GNU")
301a9420
AM
15544 && inote.type == NT_GNU_BUILD_ID)
15545 {
15546 unsigned long j;
15547 char * build_id;
15548
15549 build_id = malloc (inote.descsz * 2 + 1);
15550 if (build_id == NULL)
f761cb13
AM
15551 {
15552 free (enote);
15553 return NULL;
15554 }
301a9420
AM
15555
15556 for (j = 0; j < inote.descsz; ++j)
15557 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15558 build_id[inote.descsz * 2] = '\0';
f761cb13 15559 free (enote);
301a9420 15560
55be8fd0 15561 return (unsigned char *) build_id;
301a9420 15562 }
f761cb13 15563 free (enote);
301a9420
AM
15564 }
15565
15566 return NULL;
15567}
15568#endif /* HAVE_LIBDEBUGINFOD */
15569
657d0d47
CC
15570/* If this is not NULL, load_debug_section will only look for sections
15571 within the list of sections given here. */
32ec8896 15572static unsigned int * section_subset = NULL;
657d0d47 15573
015dc7e1 15574bool
dda8d76d 15575load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15576{
2cf0635d
NC
15577 struct dwarf_section * section = &debug_displays [debug].section;
15578 Elf_Internal_Shdr * sec;
dda8d76d
NC
15579 Filedata * filedata = (Filedata *) data;
15580
f425ec66
NC
15581 /* Without section headers we cannot find any sections. */
15582 if (filedata->section_headers == NULL)
015dc7e1 15583 return false;
f425ec66 15584
9c1ce108
AM
15585 if (filedata->string_table == NULL
15586 && filedata->file_header.e_shstrndx != SHN_UNDEF
15587 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15588 {
15589 Elf_Internal_Shdr * strs;
15590
15591 /* Read in the string table, so that we have section names to scan. */
15592 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15593
4dff97b2 15594 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15595 {
9c1ce108
AM
15596 filedata->string_table
15597 = (char *) get_data (NULL, filedata, strs->sh_offset,
15598 1, strs->sh_size, _("string table"));
dda8d76d 15599
9c1ce108
AM
15600 filedata->string_table_length
15601 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15602 }
15603 }
d966045b
DJ
15604
15605 /* Locate the debug section. */
dda8d76d 15606 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15607 if (sec != NULL)
15608 section->name = section->uncompressed_name;
15609 else
15610 {
dda8d76d 15611 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15612 if (sec != NULL)
15613 section->name = section->compressed_name;
15614 }
15615 if (sec == NULL)
015dc7e1 15616 return false;
d966045b 15617
657d0d47
CC
15618 /* If we're loading from a subset of sections, and we've loaded
15619 a section matching this name before, it's likely that it's a
15620 different one. */
15621 if (section_subset != NULL)
15622 free_debug_section (debug);
15623
dda8d76d 15624 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15625}
15626
19e6b90e
L
15627void
15628free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15629{
2cf0635d 15630 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15631
19e6b90e
L
15632 if (section->start == NULL)
15633 return;
1007acb3 15634
19e6b90e
L
15635 free ((char *) section->start);
15636 section->start = NULL;
15637 section->address = 0;
15638 section->size = 0;
a788aedd 15639
9db70fc3
AM
15640 free (section->reloc_info);
15641 section->reloc_info = NULL;
15642 section->num_relocs = 0;
1007acb3
L
15643}
15644
015dc7e1 15645static bool
dda8d76d 15646display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15647{
b9e920ec 15648 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15649 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15650 bfd_size_type length;
015dc7e1 15651 bool result = true;
3f5e193b 15652 int i;
1007acb3 15653
19e6b90e
L
15654 length = section->sh_size;
15655 if (length == 0)
1007acb3 15656 {
74e1a04b 15657 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
015dc7e1 15658 return true;
1007acb3 15659 }
5dff79d8
NC
15660 if (section->sh_type == SHT_NOBITS)
15661 {
15662 /* There is no point in dumping the contents of a debugging section
15663 which has the NOBITS type - the bits in the file will be random.
15664 This can happen when a file containing a .eh_frame section is
15665 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15666 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15667 print_name);
015dc7e1 15668 return false;
5dff79d8 15669 }
1007acb3 15670
24d127aa 15671 if (startswith (name, ".gnu.linkonce.wi."))
19e6b90e 15672 name = ".debug_info";
1007acb3 15673
19e6b90e
L
15674 /* See if we know how to display the contents of this section. */
15675 for (i = 0; i < max; i++)
d85bf2ba
NC
15676 {
15677 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15678 struct dwarf_section_display * display = debug_displays + i;
15679 struct dwarf_section * sec = & display->section;
d966045b 15680
d85bf2ba 15681 if (streq (sec->uncompressed_name, name)
24d127aa 15682 || (id == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15683 || streq (sec->compressed_name, name))
15684 {
015dc7e1 15685 bool secondary = (section != find_section (filedata, name));
1007acb3 15686
d85bf2ba
NC
15687 if (secondary)
15688 free_debug_section (id);
dda8d76d 15689
24d127aa 15690 if (i == line && startswith (name, ".debug_line."))
d85bf2ba
NC
15691 sec->name = name;
15692 else if (streq (sec->uncompressed_name, name))
15693 sec->name = sec->uncompressed_name;
15694 else
15695 sec->name = sec->compressed_name;
657d0d47 15696
d85bf2ba
NC
15697 if (load_specific_debug_section (id, section, filedata))
15698 {
15699 /* If this debug section is part of a CU/TU set in a .dwp file,
15700 restrict load_debug_section to the sections in that set. */
15701 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15702
d85bf2ba 15703 result &= display->display (sec, filedata);
657d0d47 15704
d85bf2ba 15705 section_subset = NULL;
1007acb3 15706
44266f36 15707 if (secondary || (id != info && id != abbrev && id != debug_addr))
d85bf2ba
NC
15708 free_debug_section (id);
15709 }
15710 break;
15711 }
15712 }
1007acb3 15713
19e6b90e 15714 if (i == max)
1007acb3 15715 {
74e1a04b 15716 printf (_("Unrecognized debug section: %s\n"), print_name);
015dc7e1 15717 result = false;
1007acb3
L
15718 }
15719
19e6b90e 15720 return result;
5b18a4bc 15721}
103f02d3 15722
aef1f6d0
DJ
15723/* Set DUMP_SECTS for all sections where dumps were requested
15724 based on section name. */
15725
15726static void
dda8d76d 15727initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15728{
2cf0635d 15729 struct dump_list_entry * cur;
aef1f6d0
DJ
15730
15731 for (cur = dump_sects_byname; cur; cur = cur->next)
15732 {
15733 unsigned int i;
015dc7e1 15734 bool any = false;
aef1f6d0 15735
dda8d76d 15736 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15737 if (SECTION_NAME_VALID (filedata->section_headers + i)
15738 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15739 {
6431e409 15740 request_dump_bynumber (&filedata->dump, i, cur->type);
015dc7e1 15741 any = true;
aef1f6d0
DJ
15742 }
15743
835f2fae
NC
15744 if (!any && !filedata->is_separate)
15745 warn (_("Section '%s' was not dumped because it does not exist\n"),
15746 cur->name);
aef1f6d0
DJ
15747 }
15748}
15749
015dc7e1 15750static bool
dda8d76d 15751process_section_contents (Filedata * filedata)
5b18a4bc 15752{
2cf0635d 15753 Elf_Internal_Shdr * section;
19e6b90e 15754 unsigned int i;
015dc7e1 15755 bool res = true;
103f02d3 15756
19e6b90e 15757 if (! do_dump)
015dc7e1 15758 return true;
103f02d3 15759
dda8d76d 15760 initialise_dumps_byname (filedata);
aef1f6d0 15761
dda8d76d 15762 for (i = 0, section = filedata->section_headers;
6431e409 15763 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15764 i++, section++)
15765 {
6431e409 15766 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15767
d6bfbc39
NC
15768 if (filedata->is_separate && ! process_links)
15769 dump &= DEBUG_DUMP;
047c3dbf 15770
19e6b90e 15771#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15772 if (dump & DISASS_DUMP)
15773 {
15774 if (! disassemble_section (section, filedata))
015dc7e1 15775 res = false;
dda8d76d 15776 }
19e6b90e 15777#endif
dda8d76d 15778 if (dump & HEX_DUMP)
32ec8896 15779 {
015dc7e1
AM
15780 if (! dump_section_as_bytes (section, filedata, false))
15781 res = false;
32ec8896 15782 }
103f02d3 15783
dda8d76d 15784 if (dump & RELOC_DUMP)
32ec8896 15785 {
015dc7e1
AM
15786 if (! dump_section_as_bytes (section, filedata, true))
15787 res = false;
32ec8896 15788 }
09c11c86 15789
dda8d76d 15790 if (dump & STRING_DUMP)
32ec8896 15791 {
dda8d76d 15792 if (! dump_section_as_strings (section, filedata))
015dc7e1 15793 res = false;
32ec8896 15794 }
cf13d699 15795
dda8d76d 15796 if (dump & DEBUG_DUMP)
32ec8896 15797 {
dda8d76d 15798 if (! display_debug_section (i, section, filedata))
015dc7e1 15799 res = false;
32ec8896 15800 }
7d9813f1 15801
094e34f2 15802#ifdef ENABLE_LIBCTF
7d9813f1
NA
15803 if (dump & CTF_DUMP)
15804 {
15805 if (! dump_section_as_ctf (section, filedata))
015dc7e1 15806 res = false;
7d9813f1 15807 }
094e34f2 15808#endif
5b18a4bc 15809 }
103f02d3 15810
835f2fae 15811 if (! filedata->is_separate)
0ee3043f 15812 {
835f2fae
NC
15813 /* Check to see if the user requested a
15814 dump of a section that does not exist. */
15815 for (; i < filedata->dump.num_dump_sects; i++)
15816 if (filedata->dump.dump_sects[i])
15817 {
ca0e11aa 15818 warn (_("Section %d was not dumped because it does not exist!\n"), i);
015dc7e1 15819 res = false;
835f2fae 15820 }
0ee3043f 15821 }
32ec8896
NC
15822
15823 return res;
5b18a4bc 15824}
103f02d3 15825
5b18a4bc 15826static void
19e6b90e 15827process_mips_fpe_exception (int mask)
5b18a4bc 15828{
19e6b90e
L
15829 if (mask)
15830 {
015dc7e1 15831 bool first = true;
32ec8896 15832
19e6b90e 15833 if (mask & OEX_FPU_INEX)
015dc7e1 15834 fputs ("INEX", stdout), first = false;
19e6b90e 15835 if (mask & OEX_FPU_UFLO)
015dc7e1 15836 printf ("%sUFLO", first ? "" : "|"), first = false;
19e6b90e 15837 if (mask & OEX_FPU_OFLO)
015dc7e1 15838 printf ("%sOFLO", first ? "" : "|"), first = false;
19e6b90e 15839 if (mask & OEX_FPU_DIV0)
015dc7e1 15840 printf ("%sDIV0", first ? "" : "|"), first = false;
19e6b90e
L
15841 if (mask & OEX_FPU_INVAL)
15842 printf ("%sINVAL", first ? "" : "|");
15843 }
5b18a4bc 15844 else
19e6b90e 15845 fputs ("0", stdout);
5b18a4bc 15846}
103f02d3 15847
f6f0e17b
NC
15848/* Display's the value of TAG at location P. If TAG is
15849 greater than 0 it is assumed to be an unknown tag, and
15850 a message is printed to this effect. Otherwise it is
15851 assumed that a message has already been printed.
15852
15853 If the bottom bit of TAG is set it assumed to have a
15854 string value, otherwise it is assumed to have an integer
15855 value.
15856
15857 Returns an updated P pointing to the first unread byte
15858 beyond the end of TAG's value.
15859
15860 Reads at or beyond END will not be made. */
15861
15862static unsigned char *
60abdbed 15863display_tag_value (signed int tag,
f6f0e17b
NC
15864 unsigned char * p,
15865 const unsigned char * const end)
15866{
15867 unsigned long val;
15868
15869 if (tag > 0)
15870 printf (" Tag_unknown_%d: ", tag);
15871
15872 if (p >= end)
15873 {
4082ef84 15874 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15875 }
15876 else if (tag & 1)
15877 {
071436c6
NC
15878 /* PR 17531 file: 027-19978-0.004. */
15879 size_t maxlen = (end - p) - 1;
15880
15881 putchar ('"');
4082ef84
NC
15882 if (maxlen > 0)
15883 {
15884 print_symbol ((int) maxlen, (const char *) p);
15885 p += strnlen ((char *) p, maxlen) + 1;
15886 }
15887 else
15888 {
15889 printf (_("<corrupt string tag>"));
15890 p = (unsigned char *) end;
15891 }
071436c6 15892 printf ("\"\n");
f6f0e17b
NC
15893 }
15894 else
15895 {
cd30bcef 15896 READ_ULEB (val, p, end);
f6f0e17b
NC
15897 printf ("%ld (0x%lx)\n", val, val);
15898 }
15899
4082ef84 15900 assert (p <= end);
f6f0e17b
NC
15901 return p;
15902}
15903
53a346d8
CZ
15904/* ARC ABI attributes section. */
15905
15906static unsigned char *
15907display_arc_attribute (unsigned char * p,
15908 const unsigned char * const end)
15909{
15910 unsigned int tag;
53a346d8
CZ
15911 unsigned int val;
15912
cd30bcef 15913 READ_ULEB (tag, p, end);
53a346d8
CZ
15914
15915 switch (tag)
15916 {
15917 case Tag_ARC_PCS_config:
cd30bcef 15918 READ_ULEB (val, p, end);
53a346d8
CZ
15919 printf (" Tag_ARC_PCS_config: ");
15920 switch (val)
15921 {
15922 case 0:
15923 printf (_("Absent/Non standard\n"));
15924 break;
15925 case 1:
15926 printf (_("Bare metal/mwdt\n"));
15927 break;
15928 case 2:
15929 printf (_("Bare metal/newlib\n"));
15930 break;
15931 case 3:
15932 printf (_("Linux/uclibc\n"));
15933 break;
15934 case 4:
15935 printf (_("Linux/glibc\n"));
15936 break;
15937 default:
15938 printf (_("Unknown\n"));
15939 break;
15940 }
15941 break;
15942
15943 case Tag_ARC_CPU_base:
cd30bcef 15944 READ_ULEB (val, p, end);
53a346d8
CZ
15945 printf (" Tag_ARC_CPU_base: ");
15946 switch (val)
15947 {
15948 default:
15949 case TAG_CPU_NONE:
15950 printf (_("Absent\n"));
15951 break;
15952 case TAG_CPU_ARC6xx:
15953 printf ("ARC6xx\n");
15954 break;
15955 case TAG_CPU_ARC7xx:
15956 printf ("ARC7xx\n");
15957 break;
15958 case TAG_CPU_ARCEM:
15959 printf ("ARCEM\n");
15960 break;
15961 case TAG_CPU_ARCHS:
15962 printf ("ARCHS\n");
15963 break;
15964 }
15965 break;
15966
15967 case Tag_ARC_CPU_variation:
cd30bcef 15968 READ_ULEB (val, p, end);
53a346d8
CZ
15969 printf (" Tag_ARC_CPU_variation: ");
15970 switch (val)
15971 {
15972 default:
15973 if (val > 0 && val < 16)
53a346d8 15974 printf ("Core%d\n", val);
d8cbc93b
JL
15975 else
15976 printf ("Unknown\n");
15977 break;
15978
53a346d8
CZ
15979 case 0:
15980 printf (_("Absent\n"));
15981 break;
15982 }
15983 break;
15984
15985 case Tag_ARC_CPU_name:
15986 printf (" Tag_ARC_CPU_name: ");
15987 p = display_tag_value (-1, p, end);
15988 break;
15989
15990 case Tag_ARC_ABI_rf16:
cd30bcef 15991 READ_ULEB (val, p, end);
53a346d8
CZ
15992 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15993 break;
15994
15995 case Tag_ARC_ABI_osver:
cd30bcef 15996 READ_ULEB (val, p, end);
53a346d8
CZ
15997 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15998 break;
15999
16000 case Tag_ARC_ABI_pic:
16001 case Tag_ARC_ABI_sda:
cd30bcef 16002 READ_ULEB (val, p, end);
53a346d8
CZ
16003 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
16004 : " Tag_ARC_ABI_pic: ");
16005 switch (val)
16006 {
16007 case 0:
16008 printf (_("Absent\n"));
16009 break;
16010 case 1:
16011 printf ("MWDT\n");
16012 break;
16013 case 2:
16014 printf ("GNU\n");
16015 break;
16016 default:
16017 printf (_("Unknown\n"));
16018 break;
16019 }
16020 break;
16021
16022 case Tag_ARC_ABI_tls:
cd30bcef 16023 READ_ULEB (val, p, end);
53a346d8
CZ
16024 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
16025 break;
16026
16027 case Tag_ARC_ABI_enumsize:
cd30bcef 16028 READ_ULEB (val, p, end);
53a346d8
CZ
16029 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
16030 _("smallest"));
16031 break;
16032
16033 case Tag_ARC_ABI_exceptions:
cd30bcef 16034 READ_ULEB (val, p, end);
53a346d8
CZ
16035 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
16036 : _("default"));
16037 break;
16038
16039 case Tag_ARC_ABI_double_size:
cd30bcef 16040 READ_ULEB (val, p, end);
53a346d8
CZ
16041 printf (" Tag_ARC_ABI_double_size: %d\n", val);
16042 break;
16043
16044 case Tag_ARC_ISA_config:
16045 printf (" Tag_ARC_ISA_config: ");
16046 p = display_tag_value (-1, p, end);
16047 break;
16048
16049 case Tag_ARC_ISA_apex:
16050 printf (" Tag_ARC_ISA_apex: ");
16051 p = display_tag_value (-1, p, end);
16052 break;
16053
16054 case Tag_ARC_ISA_mpy_option:
cd30bcef 16055 READ_ULEB (val, p, end);
53a346d8
CZ
16056 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
16057 break;
16058
db1e1b45 16059 case Tag_ARC_ATR_version:
cd30bcef 16060 READ_ULEB (val, p, end);
db1e1b45 16061 printf (" Tag_ARC_ATR_version: %d\n", val);
16062 break;
16063
53a346d8
CZ
16064 default:
16065 return display_tag_value (tag & 1, p, end);
16066 }
16067
16068 return p;
16069}
16070
11c1ff18
PB
16071/* ARM EABI attributes section. */
16072typedef struct
16073{
70e99720 16074 unsigned int tag;
2cf0635d 16075 const char * name;
11c1ff18 16076 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 16077 unsigned int type;
288f0ba2 16078 const char *const *table;
11c1ff18
PB
16079} arm_attr_public_tag;
16080
288f0ba2 16081static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 16082 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 16083 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 16084 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
16085static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
16086static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 16087 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 16088static const char *const arm_attr_tag_FP_arch[] =
bca38921 16089 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 16090 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
16091static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
16092static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
16093 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
16094 "NEON for ARMv8.1"};
288f0ba2 16095static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
16096 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
16097 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 16098static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 16099 {"V6", "SB", "TLS", "Unused"};
288f0ba2 16100static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 16101 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 16102static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 16103 {"Absolute", "PC-relative", "None"};
288f0ba2 16104static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 16105 {"None", "direct", "GOT-indirect"};
288f0ba2 16106static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 16107 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
16108static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
16109static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 16110 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
16111static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
16112static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
16113static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 16114 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 16115static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 16116 {"Unused", "small", "int", "forced to int"};
288f0ba2 16117static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 16118 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 16119static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 16120 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 16121static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 16122 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 16123static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
16124 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16125 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 16126static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
16127 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
16128 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
16129static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
16130static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 16131 {"Not Allowed", "Allowed"};
288f0ba2 16132static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 16133 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 16134static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 16135 {"Follow architecture", "Allowed"};
288f0ba2 16136static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 16137 {"Not Allowed", "Allowed"};
288f0ba2 16138static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 16139 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 16140 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
16141static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
16142static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 16143 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 16144 "TrustZone and Virtualization Extensions"};
288f0ba2 16145static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 16146 {"Not Allowed", "Allowed"};
11c1ff18 16147
288f0ba2 16148static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
16149 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
16150
11c1ff18
PB
16151#define LOOKUP(id, name) \
16152 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 16153static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
16154{
16155 {4, "CPU_raw_name", 1, NULL},
16156 {5, "CPU_name", 1, NULL},
16157 LOOKUP(6, CPU_arch),
16158 {7, "CPU_arch_profile", 0, NULL},
16159 LOOKUP(8, ARM_ISA_use),
16160 LOOKUP(9, THUMB_ISA_use),
75375b3e 16161 LOOKUP(10, FP_arch),
11c1ff18 16162 LOOKUP(11, WMMX_arch),
f5f53991
AS
16163 LOOKUP(12, Advanced_SIMD_arch),
16164 LOOKUP(13, PCS_config),
11c1ff18
PB
16165 LOOKUP(14, ABI_PCS_R9_use),
16166 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 16167 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
16168 LOOKUP(17, ABI_PCS_GOT_use),
16169 LOOKUP(18, ABI_PCS_wchar_t),
16170 LOOKUP(19, ABI_FP_rounding),
16171 LOOKUP(20, ABI_FP_denormal),
16172 LOOKUP(21, ABI_FP_exceptions),
16173 LOOKUP(22, ABI_FP_user_exceptions),
16174 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
16175 {24, "ABI_align_needed", 0, NULL},
16176 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
16177 LOOKUP(26, ABI_enum_size),
16178 LOOKUP(27, ABI_HardFP_use),
16179 LOOKUP(28, ABI_VFP_args),
16180 LOOKUP(29, ABI_WMMX_args),
16181 LOOKUP(30, ABI_optimization_goals),
16182 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 16183 {32, "compatibility", 0, NULL},
f5f53991 16184 LOOKUP(34, CPU_unaligned_access),
75375b3e 16185 LOOKUP(36, FP_HP_extension),
8e79c3df 16186 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
16187 LOOKUP(42, MPextension_use),
16188 LOOKUP(44, DIV_use),
15afaa63 16189 LOOKUP(46, DSP_extension),
a7ad558c 16190 LOOKUP(48, MVE_arch),
f5f53991
AS
16191 {64, "nodefaults", 0, NULL},
16192 {65, "also_compatible_with", 0, NULL},
16193 LOOKUP(66, T2EE_use),
16194 {67, "conformance", 1, NULL},
16195 LOOKUP(68, Virtualization_use),
cd21e546 16196 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
16197};
16198#undef LOOKUP
16199
11c1ff18 16200static unsigned char *
f6f0e17b
NC
16201display_arm_attribute (unsigned char * p,
16202 const unsigned char * const end)
11c1ff18 16203{
70e99720 16204 unsigned int tag;
70e99720 16205 unsigned int val;
2cf0635d 16206 arm_attr_public_tag * attr;
11c1ff18 16207 unsigned i;
70e99720 16208 unsigned int type;
11c1ff18 16209
cd30bcef 16210 READ_ULEB (tag, p, end);
11c1ff18 16211 attr = NULL;
2cf0635d 16212 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
16213 {
16214 if (arm_attr_public_tags[i].tag == tag)
16215 {
16216 attr = &arm_attr_public_tags[i];
16217 break;
16218 }
16219 }
16220
16221 if (attr)
16222 {
16223 printf (" Tag_%s: ", attr->name);
16224 switch (attr->type)
16225 {
16226 case 0:
16227 switch (tag)
16228 {
16229 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 16230 READ_ULEB (val, p, end);
11c1ff18
PB
16231 switch (val)
16232 {
2b692964
NC
16233 case 0: printf (_("None\n")); break;
16234 case 'A': printf (_("Application\n")); break;
16235 case 'R': printf (_("Realtime\n")); break;
16236 case 'M': printf (_("Microcontroller\n")); break;
16237 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
16238 default: printf ("??? (%d)\n", val); break;
16239 }
16240 break;
16241
75375b3e 16242 case 24: /* Tag_align_needed. */
cd30bcef 16243 READ_ULEB (val, p, end);
75375b3e
MGD
16244 switch (val)
16245 {
2b692964
NC
16246 case 0: printf (_("None\n")); break;
16247 case 1: printf (_("8-byte\n")); break;
16248 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
16249 case 3: printf ("??? 3\n"); break;
16250 default:
16251 if (val <= 12)
dd24e3da 16252 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16253 1 << val);
16254 else
16255 printf ("??? (%d)\n", val);
16256 break;
16257 }
16258 break;
16259
16260 case 25: /* Tag_align_preserved. */
cd30bcef 16261 READ_ULEB (val, p, end);
75375b3e
MGD
16262 switch (val)
16263 {
2b692964
NC
16264 case 0: printf (_("None\n")); break;
16265 case 1: printf (_("8-byte, except leaf SP\n")); break;
16266 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
16267 case 3: printf ("??? 3\n"); break;
16268 default:
16269 if (val <= 12)
dd24e3da 16270 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
16271 1 << val);
16272 else
16273 printf ("??? (%d)\n", val);
16274 break;
16275 }
16276 break;
16277
11c1ff18 16278 case 32: /* Tag_compatibility. */
071436c6 16279 {
cd30bcef 16280 READ_ULEB (val, p, end);
071436c6 16281 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16282 if (p < end - 1)
16283 {
16284 size_t maxlen = (end - p) - 1;
16285
16286 print_symbol ((int) maxlen, (const char *) p);
16287 p += strnlen ((char *) p, maxlen) + 1;
16288 }
16289 else
16290 {
16291 printf (_("<corrupt>"));
16292 p = (unsigned char *) end;
16293 }
071436c6 16294 putchar ('\n');
071436c6 16295 }
11c1ff18
PB
16296 break;
16297
f5f53991 16298 case 64: /* Tag_nodefaults. */
541a3cbd
NC
16299 /* PR 17531: file: 001-505008-0.01. */
16300 if (p < end)
16301 p++;
2b692964 16302 printf (_("True\n"));
f5f53991
AS
16303 break;
16304
16305 case 65: /* Tag_also_compatible_with. */
cd30bcef 16306 READ_ULEB (val, p, end);
f5f53991
AS
16307 if (val == 6 /* Tag_CPU_arch. */)
16308 {
cd30bcef 16309 READ_ULEB (val, p, end);
071436c6 16310 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
16311 printf ("??? (%d)\n", val);
16312 else
16313 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
16314 }
16315 else
16316 printf ("???\n");
071436c6
NC
16317 while (p < end && *(p++) != '\0' /* NUL terminator. */)
16318 ;
f5f53991
AS
16319 break;
16320
11c1ff18 16321 default:
bee0ee85
NC
16322 printf (_("<unknown: %d>\n"), tag);
16323 break;
11c1ff18
PB
16324 }
16325 return p;
16326
16327 case 1:
f6f0e17b 16328 return display_tag_value (-1, p, end);
11c1ff18 16329 case 2:
f6f0e17b 16330 return display_tag_value (0, p, end);
11c1ff18
PB
16331
16332 default:
16333 assert (attr->type & 0x80);
cd30bcef 16334 READ_ULEB (val, p, end);
11c1ff18
PB
16335 type = attr->type & 0x7f;
16336 if (val >= type)
16337 printf ("??? (%d)\n", val);
16338 else
16339 printf ("%s\n", attr->table[val]);
16340 return p;
16341 }
16342 }
11c1ff18 16343
f6f0e17b 16344 return display_tag_value (tag, p, end);
11c1ff18
PB
16345}
16346
104d59d1 16347static unsigned char *
60bca95a 16348display_gnu_attribute (unsigned char * p,
60abdbed 16349 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 16350 const unsigned char * const end)
104d59d1 16351{
cd30bcef 16352 unsigned int tag;
60abdbed 16353 unsigned int val;
104d59d1 16354
cd30bcef 16355 READ_ULEB (tag, p, end);
104d59d1
JM
16356
16357 /* Tag_compatibility is the only generic GNU attribute defined at
16358 present. */
16359 if (tag == 32)
16360 {
cd30bcef 16361 READ_ULEB (val, p, end);
071436c6
NC
16362
16363 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
16364 if (p == end)
16365 {
071436c6 16366 printf (_("<corrupt>\n"));
f6f0e17b
NC
16367 warn (_("corrupt vendor attribute\n"));
16368 }
16369 else
16370 {
4082ef84
NC
16371 if (p < end - 1)
16372 {
16373 size_t maxlen = (end - p) - 1;
071436c6 16374
4082ef84
NC
16375 print_symbol ((int) maxlen, (const char *) p);
16376 p += strnlen ((char *) p, maxlen) + 1;
16377 }
16378 else
16379 {
16380 printf (_("<corrupt>"));
16381 p = (unsigned char *) end;
16382 }
071436c6 16383 putchar ('\n');
f6f0e17b 16384 }
104d59d1
JM
16385 return p;
16386 }
16387
16388 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 16389 return display_proc_gnu_attribute (p, tag, end);
104d59d1 16390
f6f0e17b 16391 return display_tag_value (tag, p, end);
104d59d1
JM
16392}
16393
85f7484a
PB
16394static unsigned char *
16395display_m68k_gnu_attribute (unsigned char * p,
16396 unsigned int tag,
16397 const unsigned char * const end)
16398{
16399 unsigned int val;
16400
16401 if (tag == Tag_GNU_M68K_ABI_FP)
16402 {
16403 printf (" Tag_GNU_M68K_ABI_FP: ");
16404 if (p == end)
16405 {
16406 printf (_("<corrupt>\n"));
16407 return p;
16408 }
16409 READ_ULEB (val, p, end);
16410
16411 if (val > 3)
16412 printf ("(%#x), ", val);
16413
16414 switch (val & 3)
16415 {
16416 case 0:
16417 printf (_("unspecified hard/soft float\n"));
16418 break;
16419 case 1:
16420 printf (_("hard float\n"));
16421 break;
16422 case 2:
16423 printf (_("soft float\n"));
16424 break;
16425 }
16426 return p;
16427 }
16428
16429 return display_tag_value (tag & 1, p, end);
16430}
16431
34c8bcba 16432static unsigned char *
f6f0e17b 16433display_power_gnu_attribute (unsigned char * p,
60abdbed 16434 unsigned int tag,
f6f0e17b 16435 const unsigned char * const end)
34c8bcba 16436{
005d79fd 16437 unsigned int val;
34c8bcba
JM
16438
16439 if (tag == Tag_GNU_Power_ABI_FP)
16440 {
34c8bcba 16441 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 16442 if (p == end)
005d79fd
AM
16443 {
16444 printf (_("<corrupt>\n"));
16445 return p;
16446 }
cd30bcef 16447 READ_ULEB (val, p, end);
60bca95a 16448
005d79fd
AM
16449 if (val > 15)
16450 printf ("(%#x), ", val);
16451
16452 switch (val & 3)
34c8bcba
JM
16453 {
16454 case 0:
005d79fd 16455 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16456 break;
16457 case 1:
005d79fd 16458 printf (_("hard float, "));
34c8bcba
JM
16459 break;
16460 case 2:
005d79fd 16461 printf (_("soft float, "));
34c8bcba 16462 break;
3c7b9897 16463 case 3:
005d79fd 16464 printf (_("single-precision hard float, "));
3c7b9897 16465 break;
005d79fd
AM
16466 }
16467
16468 switch (val & 0xC)
16469 {
16470 case 0:
16471 printf (_("unspecified long double\n"));
16472 break;
16473 case 4:
16474 printf (_("128-bit IBM long double\n"));
16475 break;
16476 case 8:
16477 printf (_("64-bit long double\n"));
16478 break;
16479 case 12:
16480 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16481 break;
16482 }
16483 return p;
005d79fd 16484 }
34c8bcba 16485
c6e65352
DJ
16486 if (tag == Tag_GNU_Power_ABI_Vector)
16487 {
c6e65352 16488 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16489 if (p == end)
005d79fd
AM
16490 {
16491 printf (_("<corrupt>\n"));
16492 return p;
16493 }
cd30bcef 16494 READ_ULEB (val, p, end);
005d79fd
AM
16495
16496 if (val > 3)
16497 printf ("(%#x), ", val);
16498
16499 switch (val & 3)
c6e65352
DJ
16500 {
16501 case 0:
005d79fd 16502 printf (_("unspecified\n"));
c6e65352
DJ
16503 break;
16504 case 1:
005d79fd 16505 printf (_("generic\n"));
c6e65352
DJ
16506 break;
16507 case 2:
16508 printf ("AltiVec\n");
16509 break;
16510 case 3:
16511 printf ("SPE\n");
16512 break;
c6e65352
DJ
16513 }
16514 return p;
005d79fd 16515 }
c6e65352 16516
f82e0623
NF
16517 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16518 {
005d79fd 16519 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16520 if (p == end)
f6f0e17b 16521 {
005d79fd 16522 printf (_("<corrupt>\n"));
f6f0e17b
NC
16523 return p;
16524 }
cd30bcef 16525 READ_ULEB (val, p, end);
0b4362b0 16526
005d79fd
AM
16527 if (val > 2)
16528 printf ("(%#x), ", val);
16529
16530 switch (val & 3)
16531 {
16532 case 0:
16533 printf (_("unspecified\n"));
16534 break;
16535 case 1:
16536 printf ("r3/r4\n");
16537 break;
16538 case 2:
16539 printf (_("memory\n"));
16540 break;
16541 case 3:
16542 printf ("???\n");
16543 break;
16544 }
f82e0623
NF
16545 return p;
16546 }
16547
f6f0e17b 16548 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16549}
16550
643f7afb
AK
16551static unsigned char *
16552display_s390_gnu_attribute (unsigned char * p,
60abdbed 16553 unsigned int tag,
643f7afb
AK
16554 const unsigned char * const end)
16555{
cd30bcef 16556 unsigned int val;
643f7afb
AK
16557
16558 if (tag == Tag_GNU_S390_ABI_Vector)
16559 {
643f7afb 16560 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16561 READ_ULEB (val, p, end);
643f7afb
AK
16562
16563 switch (val)
16564 {
16565 case 0:
16566 printf (_("any\n"));
16567 break;
16568 case 1:
16569 printf (_("software\n"));
16570 break;
16571 case 2:
16572 printf (_("hardware\n"));
16573 break;
16574 default:
16575 printf ("??? (%d)\n", val);
16576 break;
16577 }
16578 return p;
16579 }
16580
16581 return display_tag_value (tag & 1, p, end);
16582}
16583
9e8c70f9 16584static void
60abdbed 16585display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16586{
16587 if (mask)
16588 {
015dc7e1 16589 bool first = true;
071436c6 16590
9e8c70f9 16591 if (mask & ELF_SPARC_HWCAP_MUL32)
015dc7e1 16592 fputs ("mul32", stdout), first = false;
9e8c70f9 16593 if (mask & ELF_SPARC_HWCAP_DIV32)
015dc7e1 16594 printf ("%sdiv32", first ? "" : "|"), first = false;
9e8c70f9 16595 if (mask & ELF_SPARC_HWCAP_FSMULD)
015dc7e1 16596 printf ("%sfsmuld", first ? "" : "|"), first = false;
9e8c70f9 16597 if (mask & ELF_SPARC_HWCAP_V8PLUS)
015dc7e1 16598 printf ("%sv8plus", first ? "" : "|"), first = false;
9e8c70f9 16599 if (mask & ELF_SPARC_HWCAP_POPC)
015dc7e1 16600 printf ("%spopc", first ? "" : "|"), first = false;
9e8c70f9 16601 if (mask & ELF_SPARC_HWCAP_VIS)
015dc7e1 16602 printf ("%svis", first ? "" : "|"), first = false;
9e8c70f9 16603 if (mask & ELF_SPARC_HWCAP_VIS2)
015dc7e1 16604 printf ("%svis2", first ? "" : "|"), first = false;
9e8c70f9 16605 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
015dc7e1 16606 printf ("%sASIBlkInit", first ? "" : "|"), first = false;
9e8c70f9 16607 if (mask & ELF_SPARC_HWCAP_FMAF)
015dc7e1 16608 printf ("%sfmaf", first ? "" : "|"), first = false;
9e8c70f9 16609 if (mask & ELF_SPARC_HWCAP_VIS3)
015dc7e1 16610 printf ("%svis3", first ? "" : "|"), first = false;
9e8c70f9 16611 if (mask & ELF_SPARC_HWCAP_HPC)
015dc7e1 16612 printf ("%shpc", first ? "" : "|"), first = false;
9e8c70f9 16613 if (mask & ELF_SPARC_HWCAP_RANDOM)
015dc7e1 16614 printf ("%srandom", first ? "" : "|"), first = false;
9e8c70f9 16615 if (mask & ELF_SPARC_HWCAP_TRANS)
015dc7e1 16616 printf ("%strans", first ? "" : "|"), first = false;
9e8c70f9 16617 if (mask & ELF_SPARC_HWCAP_FJFMAU)
015dc7e1 16618 printf ("%sfjfmau", first ? "" : "|"), first = false;
9e8c70f9 16619 if (mask & ELF_SPARC_HWCAP_IMA)
015dc7e1 16620 printf ("%sima", first ? "" : "|"), first = false;
9e8c70f9 16621 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
015dc7e1 16622 printf ("%scspare", first ? "" : "|"), first = false;
9e8c70f9
DM
16623 }
16624 else
071436c6
NC
16625 fputc ('0', stdout);
16626 fputc ('\n', stdout);
9e8c70f9
DM
16627}
16628
3d68f91c 16629static void
60abdbed 16630display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16631{
16632 if (mask)
16633 {
015dc7e1 16634 bool first = true;
071436c6 16635
3d68f91c 16636 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
015dc7e1 16637 fputs ("fjathplus", stdout), first = false;
3d68f91c 16638 if (mask & ELF_SPARC_HWCAP2_VIS3B)
015dc7e1 16639 printf ("%svis3b", first ? "" : "|"), first = false;
3d68f91c 16640 if (mask & ELF_SPARC_HWCAP2_ADP)
015dc7e1 16641 printf ("%sadp", first ? "" : "|"), first = false;
3d68f91c 16642 if (mask & ELF_SPARC_HWCAP2_SPARC5)
015dc7e1 16643 printf ("%ssparc5", first ? "" : "|"), first = false;
3d68f91c 16644 if (mask & ELF_SPARC_HWCAP2_MWAIT)
015dc7e1 16645 printf ("%smwait", first ? "" : "|"), first = false;
3d68f91c 16646 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
015dc7e1 16647 printf ("%sxmpmul", first ? "" : "|"), first = false;
3d68f91c 16648 if (mask & ELF_SPARC_HWCAP2_XMONT)
015dc7e1 16649 printf ("%sxmont2", first ? "" : "|"), first = false;
3d68f91c 16650 if (mask & ELF_SPARC_HWCAP2_NSEC)
015dc7e1 16651 printf ("%snsec", first ? "" : "|"), first = false;
3d68f91c 16652 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
015dc7e1 16653 printf ("%sfjathhpc", first ? "" : "|"), first = false;
3d68f91c 16654 if (mask & ELF_SPARC_HWCAP2_FJDES)
015dc7e1 16655 printf ("%sfjdes", first ? "" : "|"), first = false;
3d68f91c 16656 if (mask & ELF_SPARC_HWCAP2_FJAES)
015dc7e1 16657 printf ("%sfjaes", first ? "" : "|"), first = false;
3d68f91c
JM
16658 }
16659 else
071436c6
NC
16660 fputc ('0', stdout);
16661 fputc ('\n', stdout);
3d68f91c
JM
16662}
16663
9e8c70f9 16664static unsigned char *
f6f0e17b 16665display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16666 unsigned int tag,
f6f0e17b 16667 const unsigned char * const end)
9e8c70f9 16668{
cd30bcef 16669 unsigned int val;
3d68f91c 16670
9e8c70f9
DM
16671 if (tag == Tag_GNU_Sparc_HWCAPS)
16672 {
cd30bcef 16673 READ_ULEB (val, p, end);
9e8c70f9 16674 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16675 display_sparc_hwcaps (val);
16676 return p;
3d68f91c
JM
16677 }
16678 if (tag == Tag_GNU_Sparc_HWCAPS2)
16679 {
cd30bcef 16680 READ_ULEB (val, p, end);
3d68f91c
JM
16681 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16682 display_sparc_hwcaps2 (val);
16683 return p;
16684 }
9e8c70f9 16685
f6f0e17b 16686 return display_tag_value (tag, p, end);
9e8c70f9
DM
16687}
16688
351cdf24 16689static void
32ec8896 16690print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16691{
16692 switch (val)
16693 {
16694 case Val_GNU_MIPS_ABI_FP_ANY:
16695 printf (_("Hard or soft float\n"));
16696 break;
16697 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16698 printf (_("Hard float (double precision)\n"));
16699 break;
16700 case Val_GNU_MIPS_ABI_FP_SINGLE:
16701 printf (_("Hard float (single precision)\n"));
16702 break;
16703 case Val_GNU_MIPS_ABI_FP_SOFT:
16704 printf (_("Soft float\n"));
16705 break;
16706 case Val_GNU_MIPS_ABI_FP_OLD_64:
16707 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16708 break;
16709 case Val_GNU_MIPS_ABI_FP_XX:
16710 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16711 break;
16712 case Val_GNU_MIPS_ABI_FP_64:
16713 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16714 break;
16715 case Val_GNU_MIPS_ABI_FP_64A:
16716 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16717 break;
3350cc01
CM
16718 case Val_GNU_MIPS_ABI_FP_NAN2008:
16719 printf (_("NaN 2008 compatibility\n"));
16720 break;
351cdf24
MF
16721 default:
16722 printf ("??? (%d)\n", val);
16723 break;
16724 }
16725}
16726
2cf19d5c 16727static unsigned char *
f6f0e17b 16728display_mips_gnu_attribute (unsigned char * p,
60abdbed 16729 unsigned int tag,
f6f0e17b 16730 const unsigned char * const end)
2cf19d5c 16731{
2cf19d5c
JM
16732 if (tag == Tag_GNU_MIPS_ABI_FP)
16733 {
32ec8896 16734 unsigned int val;
f6f0e17b 16735
2cf19d5c 16736 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16737 READ_ULEB (val, p, end);
351cdf24 16738 print_mips_fp_abi_value (val);
2cf19d5c
JM
16739 return p;
16740 }
16741
a9f58168
CF
16742 if (tag == Tag_GNU_MIPS_ABI_MSA)
16743 {
32ec8896 16744 unsigned int val;
a9f58168 16745
a9f58168 16746 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16747 READ_ULEB (val, p, end);
a9f58168
CF
16748
16749 switch (val)
16750 {
16751 case Val_GNU_MIPS_ABI_MSA_ANY:
16752 printf (_("Any MSA or not\n"));
16753 break;
16754 case Val_GNU_MIPS_ABI_MSA_128:
16755 printf (_("128-bit MSA\n"));
16756 break;
16757 default:
16758 printf ("??? (%d)\n", val);
16759 break;
16760 }
16761 return p;
16762 }
16763
f6f0e17b 16764 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16765}
16766
59e6276b 16767static unsigned char *
f6f0e17b
NC
16768display_tic6x_attribute (unsigned char * p,
16769 const unsigned char * const end)
59e6276b 16770{
60abdbed 16771 unsigned int tag;
cd30bcef 16772 unsigned int val;
59e6276b 16773
cd30bcef 16774 READ_ULEB (tag, p, end);
59e6276b
JM
16775
16776 switch (tag)
16777 {
75fa6dc1 16778 case Tag_ISA:
75fa6dc1 16779 printf (" Tag_ISA: ");
cd30bcef 16780 READ_ULEB (val, p, end);
59e6276b
JM
16781
16782 switch (val)
16783 {
75fa6dc1 16784 case C6XABI_Tag_ISA_none:
59e6276b
JM
16785 printf (_("None\n"));
16786 break;
75fa6dc1 16787 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16788 printf ("C62x\n");
16789 break;
75fa6dc1 16790 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16791 printf ("C67x\n");
16792 break;
75fa6dc1 16793 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16794 printf ("C67x+\n");
16795 break;
75fa6dc1 16796 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16797 printf ("C64x\n");
16798 break;
75fa6dc1 16799 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16800 printf ("C64x+\n");
16801 break;
75fa6dc1 16802 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16803 printf ("C674x\n");
16804 break;
16805 default:
16806 printf ("??? (%d)\n", val);
16807 break;
16808 }
16809 return p;
16810
87779176 16811 case Tag_ABI_wchar_t:
87779176 16812 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16813 READ_ULEB (val, p, end);
87779176
JM
16814 switch (val)
16815 {
16816 case 0:
16817 printf (_("Not used\n"));
16818 break;
16819 case 1:
16820 printf (_("2 bytes\n"));
16821 break;
16822 case 2:
16823 printf (_("4 bytes\n"));
16824 break;
16825 default:
16826 printf ("??? (%d)\n", val);
16827 break;
16828 }
16829 return p;
16830
16831 case Tag_ABI_stack_align_needed:
87779176 16832 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16833 READ_ULEB (val, p, end);
87779176
JM
16834 switch (val)
16835 {
16836 case 0:
16837 printf (_("8-byte\n"));
16838 break;
16839 case 1:
16840 printf (_("16-byte\n"));
16841 break;
16842 default:
16843 printf ("??? (%d)\n", val);
16844 break;
16845 }
16846 return p;
16847
16848 case Tag_ABI_stack_align_preserved:
cd30bcef 16849 READ_ULEB (val, p, end);
87779176
JM
16850 printf (" Tag_ABI_stack_align_preserved: ");
16851 switch (val)
16852 {
16853 case 0:
16854 printf (_("8-byte\n"));
16855 break;
16856 case 1:
16857 printf (_("16-byte\n"));
16858 break;
16859 default:
16860 printf ("??? (%d)\n", val);
16861 break;
16862 }
16863 return p;
16864
b5593623 16865 case Tag_ABI_DSBT:
cd30bcef 16866 READ_ULEB (val, p, end);
b5593623
JM
16867 printf (" Tag_ABI_DSBT: ");
16868 switch (val)
16869 {
16870 case 0:
16871 printf (_("DSBT addressing not used\n"));
16872 break;
16873 case 1:
16874 printf (_("DSBT addressing used\n"));
16875 break;
16876 default:
16877 printf ("??? (%d)\n", val);
16878 break;
16879 }
16880 return p;
16881
87779176 16882 case Tag_ABI_PID:
cd30bcef 16883 READ_ULEB (val, p, end);
87779176
JM
16884 printf (" Tag_ABI_PID: ");
16885 switch (val)
16886 {
16887 case 0:
16888 printf (_("Data addressing position-dependent\n"));
16889 break;
16890 case 1:
16891 printf (_("Data addressing position-independent, GOT near DP\n"));
16892 break;
16893 case 2:
16894 printf (_("Data addressing position-independent, GOT far from DP\n"));
16895 break;
16896 default:
16897 printf ("??? (%d)\n", val);
16898 break;
16899 }
16900 return p;
16901
16902 case Tag_ABI_PIC:
cd30bcef 16903 READ_ULEB (val, p, end);
87779176
JM
16904 printf (" Tag_ABI_PIC: ");
16905 switch (val)
16906 {
16907 case 0:
16908 printf (_("Code addressing position-dependent\n"));
16909 break;
16910 case 1:
16911 printf (_("Code addressing position-independent\n"));
16912 break;
16913 default:
16914 printf ("??? (%d)\n", val);
16915 break;
16916 }
16917 return p;
16918
16919 case Tag_ABI_array_object_alignment:
cd30bcef 16920 READ_ULEB (val, p, end);
87779176
JM
16921 printf (" Tag_ABI_array_object_alignment: ");
16922 switch (val)
16923 {
16924 case 0:
16925 printf (_("8-byte\n"));
16926 break;
16927 case 1:
16928 printf (_("4-byte\n"));
16929 break;
16930 case 2:
16931 printf (_("16-byte\n"));
16932 break;
16933 default:
16934 printf ("??? (%d)\n", val);
16935 break;
16936 }
16937 return p;
16938
16939 case Tag_ABI_array_object_align_expected:
cd30bcef 16940 READ_ULEB (val, p, end);
87779176
JM
16941 printf (" Tag_ABI_array_object_align_expected: ");
16942 switch (val)
16943 {
16944 case 0:
16945 printf (_("8-byte\n"));
16946 break;
16947 case 1:
16948 printf (_("4-byte\n"));
16949 break;
16950 case 2:
16951 printf (_("16-byte\n"));
16952 break;
16953 default:
16954 printf ("??? (%d)\n", val);
16955 break;
16956 }
16957 return p;
16958
3cbd1c06 16959 case Tag_ABI_compatibility:
071436c6 16960 {
cd30bcef 16961 READ_ULEB (val, p, end);
071436c6 16962 printf (" Tag_ABI_compatibility: ");
071436c6 16963 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16964 if (p < end - 1)
16965 {
16966 size_t maxlen = (end - p) - 1;
16967
16968 print_symbol ((int) maxlen, (const char *) p);
16969 p += strnlen ((char *) p, maxlen) + 1;
16970 }
16971 else
16972 {
16973 printf (_("<corrupt>"));
16974 p = (unsigned char *) end;
16975 }
071436c6 16976 putchar ('\n');
071436c6
NC
16977 return p;
16978 }
87779176
JM
16979
16980 case Tag_ABI_conformance:
071436c6 16981 {
4082ef84
NC
16982 printf (" Tag_ABI_conformance: \"");
16983 if (p < end - 1)
16984 {
16985 size_t maxlen = (end - p) - 1;
071436c6 16986
4082ef84
NC
16987 print_symbol ((int) maxlen, (const char *) p);
16988 p += strnlen ((char *) p, maxlen) + 1;
16989 }
16990 else
16991 {
16992 printf (_("<corrupt>"));
16993 p = (unsigned char *) end;
16994 }
071436c6 16995 printf ("\"\n");
071436c6
NC
16996 return p;
16997 }
59e6276b
JM
16998 }
16999
f6f0e17b
NC
17000 return display_tag_value (tag, p, end);
17001}
59e6276b 17002
f6f0e17b 17003static void
60abdbed 17004display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
17005{
17006 unsigned long addr = 0;
17007 size_t bytes = end - p;
17008
feceaa59 17009 assert (end >= p);
f6f0e17b 17010 while (bytes)
87779176 17011 {
f6f0e17b
NC
17012 int j;
17013 int k;
17014 int lbytes = (bytes > 16 ? 16 : bytes);
17015
17016 printf (" 0x%8.8lx ", addr);
17017
17018 for (j = 0; j < 16; j++)
17019 {
17020 if (j < lbytes)
17021 printf ("%2.2x", p[j]);
17022 else
17023 printf (" ");
17024
17025 if ((j & 3) == 3)
17026 printf (" ");
17027 }
17028
17029 for (j = 0; j < lbytes; j++)
17030 {
17031 k = p[j];
17032 if (k >= ' ' && k < 0x7f)
17033 printf ("%c", k);
17034 else
17035 printf (".");
17036 }
17037
17038 putchar ('\n');
17039
17040 p += lbytes;
17041 bytes -= lbytes;
17042 addr += lbytes;
87779176 17043 }
59e6276b 17044
f6f0e17b 17045 putchar ('\n');
59e6276b
JM
17046}
17047
13761a11 17048static unsigned char *
b0191216 17049display_msp430_attribute (unsigned char * p,
13761a11
NC
17050 const unsigned char * const end)
17051{
60abdbed
NC
17052 unsigned int val;
17053 unsigned int tag;
13761a11 17054
cd30bcef 17055 READ_ULEB (tag, p, end);
0b4362b0 17056
13761a11
NC
17057 switch (tag)
17058 {
17059 case OFBA_MSPABI_Tag_ISA:
13761a11 17060 printf (" Tag_ISA: ");
cd30bcef 17061 READ_ULEB (val, p, end);
13761a11
NC
17062 switch (val)
17063 {
17064 case 0: printf (_("None\n")); break;
17065 case 1: printf (_("MSP430\n")); break;
17066 case 2: printf (_("MSP430X\n")); break;
17067 default: printf ("??? (%d)\n", val); break;
17068 }
17069 break;
17070
17071 case OFBA_MSPABI_Tag_Code_Model:
13761a11 17072 printf (" Tag_Code_Model: ");
cd30bcef 17073 READ_ULEB (val, p, end);
13761a11
NC
17074 switch (val)
17075 {
17076 case 0: printf (_("None\n")); break;
17077 case 1: printf (_("Small\n")); break;
17078 case 2: printf (_("Large\n")); break;
17079 default: printf ("??? (%d)\n", val); break;
17080 }
17081 break;
17082
17083 case OFBA_MSPABI_Tag_Data_Model:
13761a11 17084 printf (" Tag_Data_Model: ");
cd30bcef 17085 READ_ULEB (val, p, end);
13761a11
NC
17086 switch (val)
17087 {
17088 case 0: printf (_("None\n")); break;
17089 case 1: printf (_("Small\n")); break;
17090 case 2: printf (_("Large\n")); break;
17091 case 3: printf (_("Restricted Large\n")); break;
17092 default: printf ("??? (%d)\n", val); break;
17093 }
17094 break;
17095
17096 default:
17097 printf (_(" <unknown tag %d>: "), tag);
17098
17099 if (tag & 1)
17100 {
071436c6 17101 putchar ('"');
4082ef84
NC
17102 if (p < end - 1)
17103 {
17104 size_t maxlen = (end - p) - 1;
17105
17106 print_symbol ((int) maxlen, (const char *) p);
17107 p += strnlen ((char *) p, maxlen) + 1;
17108 }
17109 else
17110 {
17111 printf (_("<corrupt>"));
17112 p = (unsigned char *) end;
17113 }
071436c6 17114 printf ("\"\n");
13761a11
NC
17115 }
17116 else
17117 {
cd30bcef 17118 READ_ULEB (val, p, end);
13761a11
NC
17119 printf ("%d (0x%x)\n", val, val);
17120 }
17121 break;
17122 }
17123
4082ef84 17124 assert (p <= end);
13761a11
NC
17125 return p;
17126}
17127
c0ea7c52
JL
17128static unsigned char *
17129display_msp430_gnu_attribute (unsigned char * p,
17130 unsigned int tag,
17131 const unsigned char * const end)
17132{
17133 if (tag == Tag_GNU_MSP430_Data_Region)
17134 {
cd30bcef 17135 unsigned int val;
c0ea7c52 17136
c0ea7c52 17137 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 17138 READ_ULEB (val, p, end);
c0ea7c52
JL
17139
17140 switch (val)
17141 {
17142 case Val_GNU_MSP430_Data_Region_Any:
17143 printf (_("Any Region\n"));
17144 break;
17145 case Val_GNU_MSP430_Data_Region_Lower:
17146 printf (_("Lower Region Only\n"));
17147 break;
17148 default:
cd30bcef 17149 printf ("??? (%u)\n", val);
c0ea7c52
JL
17150 }
17151 return p;
17152 }
17153 return display_tag_value (tag & 1, p, end);
17154}
17155
2dc8dd17
JW
17156struct riscv_attr_tag_t {
17157 const char *name;
cd30bcef 17158 unsigned int tag;
2dc8dd17
JW
17159};
17160
17161static struct riscv_attr_tag_t riscv_attr_tag[] =
17162{
17163#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
17164 T(arch),
17165 T(priv_spec),
17166 T(priv_spec_minor),
17167 T(priv_spec_revision),
17168 T(unaligned_access),
17169 T(stack_align),
17170#undef T
17171};
17172
17173static unsigned char *
17174display_riscv_attribute (unsigned char *p,
17175 const unsigned char * const end)
17176{
cd30bcef
AM
17177 unsigned int val;
17178 unsigned int tag;
2dc8dd17
JW
17179 struct riscv_attr_tag_t *attr = NULL;
17180 unsigned i;
17181
cd30bcef 17182 READ_ULEB (tag, p, end);
2dc8dd17
JW
17183
17184 /* Find the name of attribute. */
17185 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
17186 {
17187 if (riscv_attr_tag[i].tag == tag)
17188 {
17189 attr = &riscv_attr_tag[i];
17190 break;
17191 }
17192 }
17193
17194 if (attr)
17195 printf (" %s: ", attr->name);
17196 else
17197 return display_tag_value (tag, p, end);
17198
17199 switch (tag)
17200 {
17201 case Tag_RISCV_priv_spec:
17202 case Tag_RISCV_priv_spec_minor:
17203 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
17204 READ_ULEB (val, p, end);
17205 printf (_("%u\n"), val);
2dc8dd17
JW
17206 break;
17207 case Tag_RISCV_unaligned_access:
cd30bcef 17208 READ_ULEB (val, p, end);
2dc8dd17
JW
17209 switch (val)
17210 {
17211 case 0:
17212 printf (_("No unaligned access\n"));
17213 break;
17214 case 1:
17215 printf (_("Unaligned access\n"));
17216 break;
17217 }
17218 break;
17219 case Tag_RISCV_stack_align:
cd30bcef
AM
17220 READ_ULEB (val, p, end);
17221 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
17222 break;
17223 case Tag_RISCV_arch:
17224 p = display_tag_value (-1, p, end);
17225 break;
17226 default:
17227 return display_tag_value (tag, p, end);
17228 }
17229
17230 return p;
17231}
17232
0861f561
CQ
17233static unsigned char *
17234display_csky_attribute (unsigned char * p,
17235 const unsigned char * const end)
17236{
17237 unsigned int tag;
17238 unsigned int val;
17239 READ_ULEB (tag, p, end);
17240
17241 if (tag >= Tag_CSKY_MAX)
17242 {
17243 return display_tag_value (-1, p, end);
17244 }
17245
17246 switch (tag)
17247 {
17248 case Tag_CSKY_ARCH_NAME:
17249 printf (" Tag_CSKY_ARCH_NAME:\t\t");
17250 return display_tag_value (-1, p, end);
17251 case Tag_CSKY_CPU_NAME:
17252 printf (" Tag_CSKY_CPU_NAME:\t\t");
17253 return display_tag_value (-1, p, end);
17254
17255 case Tag_CSKY_ISA_FLAGS:
17256 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
17257 return display_tag_value (0, p, end);
17258 case Tag_CSKY_ISA_EXT_FLAGS:
17259 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
17260 return display_tag_value (0, p, end);
17261
17262 case Tag_CSKY_DSP_VERSION:
17263 printf (" Tag_CSKY_DSP_VERSION:\t\t");
17264 READ_ULEB (val, p, end);
17265 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
17266 printf ("DSP Extension\n");
17267 else if (val == VAL_CSKY_DSP_VERSION_2)
17268 printf ("DSP 2.0\n");
17269 break;
17270
17271 case Tag_CSKY_VDSP_VERSION:
17272 printf (" Tag_CSKY_VDSP_VERSION:\t");
17273 READ_ULEB (val, p, end);
17274 printf ("VDSP Version %d\n", val);
17275 break;
17276
17277 case Tag_CSKY_FPU_VERSION:
17278 printf (" Tag_CSKY_FPU_VERSION:\t\t");
17279 READ_ULEB (val, p, end);
17280 if (val == VAL_CSKY_FPU_VERSION_1)
17281 printf ("ABIV1 FPU Version 1\n");
17282 else if (val == VAL_CSKY_FPU_VERSION_2)
17283 printf ("FPU Version 2\n");
17284 break;
17285
17286 case Tag_CSKY_FPU_ABI:
17287 printf (" Tag_CSKY_FPU_ABI:\t\t");
17288 READ_ULEB (val, p, end);
17289 if (val == VAL_CSKY_FPU_ABI_HARD)
17290 printf ("Hard\n");
17291 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
17292 printf ("SoftFP\n");
17293 else if (val == VAL_CSKY_FPU_ABI_SOFT)
17294 printf ("Soft\n");
17295 break;
17296 case Tag_CSKY_FPU_ROUNDING:
17297 READ_ULEB (val, p, end);
17298 if (val == 1) {
17299 printf (" Tag_CSKY_FPU_ROUNDING:\t");
17300 printf ("Needed\n");
17301 }
17302 break;
17303 case Tag_CSKY_FPU_DENORMAL:
17304 READ_ULEB (val, p, end);
17305 if (val == 1) {
17306 printf (" Tag_CSKY_FPU_DENORMAL:\t");
17307 printf ("Needed\n");
17308 }
17309 break;
17310 case Tag_CSKY_FPU_Exception:
17311 READ_ULEB (val, p, end);
17312 if (val == 1) {
17313 printf (" Tag_CSKY_FPU_Exception:\t");
17314 printf ("Needed\n");
17315 }
17316 break;
17317 case Tag_CSKY_FPU_NUMBER_MODULE:
17318 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
17319 return display_tag_value (-1, p, end);
17320 case Tag_CSKY_FPU_HARDFP:
17321 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
17322 READ_ULEB (val, p, end);
17323 if (val & VAL_CSKY_FPU_HARDFP_HALF)
17324 printf (" Half");
17325 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
17326 printf (" Single");
17327 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
17328 printf (" Double");
17329 printf ("\n");
17330 break;
17331 default:
17332 return display_tag_value (tag, p, end);
17333 }
17334 return p;
17335}
17336
015dc7e1 17337static bool
dda8d76d 17338process_attributes (Filedata * filedata,
60bca95a 17339 const char * public_name,
104d59d1 17340 unsigned int proc_type,
f6f0e17b 17341 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 17342 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 17343{
2cf0635d 17344 Elf_Internal_Shdr * sect;
11c1ff18 17345 unsigned i;
015dc7e1 17346 bool res = true;
11c1ff18
PB
17347
17348 /* Find the section header so that we get the size. */
dda8d76d
NC
17349 for (i = 0, sect = filedata->section_headers;
17350 i < filedata->file_header.e_shnum;
11c1ff18
PB
17351 i++, sect++)
17352 {
071436c6
NC
17353 unsigned char * contents;
17354 unsigned char * p;
17355
104d59d1 17356 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
17357 continue;
17358
dda8d76d 17359 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 17360 sect->sh_size, _("attributes"));
60bca95a 17361 if (contents == NULL)
32ec8896 17362 {
015dc7e1 17363 res = false;
32ec8896
NC
17364 continue;
17365 }
60bca95a 17366
11c1ff18 17367 p = contents;
60abdbed
NC
17368 /* The first character is the version of the attributes.
17369 Currently only version 1, (aka 'A') is recognised here. */
17370 if (*p != 'A')
32ec8896
NC
17371 {
17372 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
015dc7e1 17373 res = false;
32ec8896 17374 }
60abdbed 17375 else
11c1ff18 17376 {
071436c6
NC
17377 bfd_vma section_len;
17378
17379 section_len = sect->sh_size - 1;
11c1ff18 17380 p++;
60bca95a 17381
071436c6 17382 while (section_len > 0)
11c1ff18 17383 {
071436c6 17384 bfd_vma attr_len;
e9847026 17385 unsigned int namelen;
015dc7e1
AM
17386 bool public_section;
17387 bool gnu_section;
11c1ff18 17388
071436c6 17389 if (section_len <= 4)
e0a31db1
NC
17390 {
17391 error (_("Tag section ends prematurely\n"));
015dc7e1 17392 res = false;
e0a31db1
NC
17393 break;
17394 }
071436c6 17395 attr_len = byte_get (p, 4);
11c1ff18 17396 p += 4;
60bca95a 17397
071436c6 17398 if (attr_len > section_len)
11c1ff18 17399 {
071436c6
NC
17400 error (_("Bad attribute length (%u > %u)\n"),
17401 (unsigned) attr_len, (unsigned) section_len);
17402 attr_len = section_len;
015dc7e1 17403 res = false;
11c1ff18 17404 }
74e1a04b 17405 /* PR 17531: file: 001-101425-0.004 */
071436c6 17406 else if (attr_len < 5)
74e1a04b 17407 {
071436c6 17408 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
015dc7e1 17409 res = false;
74e1a04b
NC
17410 break;
17411 }
e9847026 17412
071436c6
NC
17413 section_len -= attr_len;
17414 attr_len -= 4;
17415
17416 namelen = strnlen ((char *) p, attr_len) + 1;
17417 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
17418 {
17419 error (_("Corrupt attribute section name\n"));
015dc7e1 17420 res = false;
e9847026
NC
17421 break;
17422 }
17423
071436c6
NC
17424 printf (_("Attribute Section: "));
17425 print_symbol (INT_MAX, (const char *) p);
17426 putchar ('\n');
60bca95a
NC
17427
17428 if (public_name && streq ((char *) p, public_name))
015dc7e1 17429 public_section = true;
11c1ff18 17430 else
015dc7e1 17431 public_section = false;
60bca95a
NC
17432
17433 if (streq ((char *) p, "gnu"))
015dc7e1 17434 gnu_section = true;
104d59d1 17435 else
015dc7e1 17436 gnu_section = false;
60bca95a 17437
11c1ff18 17438 p += namelen;
071436c6 17439 attr_len -= namelen;
e0a31db1 17440
071436c6 17441 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 17442 {
e0a31db1 17443 int tag;
cd30bcef 17444 unsigned int val;
11c1ff18 17445 bfd_vma size;
071436c6 17446 unsigned char * end;
60bca95a 17447
e0a31db1 17448 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17449 if (attr_len < 6)
e0a31db1
NC
17450 {
17451 error (_("Unused bytes at end of section\n"));
015dc7e1 17452 res = false;
e0a31db1
NC
17453 section_len = 0;
17454 break;
17455 }
17456
17457 tag = *(p++);
11c1ff18 17458 size = byte_get (p, 4);
071436c6 17459 if (size > attr_len)
11c1ff18 17460 {
e9847026 17461 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17462 (unsigned) size, (unsigned) attr_len);
015dc7e1 17463 res = false;
071436c6 17464 size = attr_len;
11c1ff18 17465 }
e0a31db1
NC
17466 /* PR binutils/17531: Safe handling of corrupt files. */
17467 if (size < 6)
17468 {
17469 error (_("Bad subsection length (%u < 6)\n"),
17470 (unsigned) size);
015dc7e1 17471 res = false;
e0a31db1
NC
17472 section_len = 0;
17473 break;
17474 }
60bca95a 17475
071436c6 17476 attr_len -= size;
11c1ff18 17477 end = p + size - 1;
071436c6 17478 assert (end <= contents + sect->sh_size);
11c1ff18 17479 p += 4;
60bca95a 17480
11c1ff18
PB
17481 switch (tag)
17482 {
17483 case 1:
2b692964 17484 printf (_("File Attributes\n"));
11c1ff18
PB
17485 break;
17486 case 2:
2b692964 17487 printf (_("Section Attributes:"));
11c1ff18
PB
17488 goto do_numlist;
17489 case 3:
2b692964 17490 printf (_("Symbol Attributes:"));
1a0670f3 17491 /* Fall through. */
11c1ff18
PB
17492 do_numlist:
17493 for (;;)
17494 {
cd30bcef 17495 READ_ULEB (val, p, end);
11c1ff18
PB
17496 if (val == 0)
17497 break;
17498 printf (" %d", val);
17499 }
17500 printf ("\n");
17501 break;
17502 default:
2b692964 17503 printf (_("Unknown tag: %d\n"), tag);
015dc7e1 17504 public_section = false;
11c1ff18
PB
17505 break;
17506 }
60bca95a 17507
071436c6 17508 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17509 {
17510 while (p < end)
f6f0e17b 17511 p = display_pub_attribute (p, end);
60abdbed 17512 assert (p == end);
104d59d1 17513 }
071436c6 17514 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17515 {
17516 while (p < end)
17517 p = display_gnu_attribute (p,
f6f0e17b
NC
17518 display_proc_gnu_attribute,
17519 end);
60abdbed 17520 assert (p == end);
11c1ff18 17521 }
071436c6 17522 else if (p < end)
11c1ff18 17523 {
071436c6 17524 printf (_(" Unknown attribute:\n"));
f6f0e17b 17525 display_raw_attribute (p, end);
11c1ff18
PB
17526 p = end;
17527 }
071436c6
NC
17528 else
17529 attr_len = 0;
11c1ff18
PB
17530 }
17531 }
17532 }
d70c5fc7 17533
60bca95a 17534 free (contents);
11c1ff18 17535 }
32ec8896
NC
17536
17537 return res;
11c1ff18
PB
17538}
17539
ccb4c951
RS
17540/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17541 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17542 and return the VMA of the next entry, or -1 if there was a problem.
17543 Does not read from DATA_END or beyond. */
ccb4c951
RS
17544
17545static bfd_vma
82b1b41b
NC
17546print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17547 unsigned char * data_end)
ccb4c951
RS
17548{
17549 printf (" ");
17550 print_vma (addr, LONG_HEX);
17551 printf (" ");
17552 if (addr < pltgot + 0xfff0)
17553 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17554 else
17555 printf ("%10s", "");
17556 printf (" ");
17557 if (data == NULL)
2b692964 17558 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17559 else
17560 {
17561 bfd_vma entry;
82b1b41b 17562 unsigned char * from = data + addr - pltgot;
ccb4c951 17563
82b1b41b
NC
17564 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17565 {
17566 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17567 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17568 return (bfd_vma) -1;
17569 }
17570 else
17571 {
17572 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17573 print_vma (entry, LONG_HEX);
17574 }
ccb4c951
RS
17575 }
17576 return addr + (is_32bit_elf ? 4 : 8);
17577}
17578
861fb55a
DJ
17579/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17580 PLTGOT. Print the Address and Initial fields of an entry at VMA
17581 ADDR and return the VMA of the next entry. */
17582
17583static bfd_vma
2cf0635d 17584print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17585{
17586 printf (" ");
17587 print_vma (addr, LONG_HEX);
17588 printf (" ");
17589 if (data == NULL)
2b692964 17590 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17591 else
17592 {
17593 bfd_vma entry;
17594
17595 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17596 print_vma (entry, LONG_HEX);
17597 }
17598 return addr + (is_32bit_elf ? 4 : 8);
17599}
17600
351cdf24
MF
17601static void
17602print_mips_ases (unsigned int mask)
17603{
17604 if (mask & AFL_ASE_DSP)
17605 fputs ("\n\tDSP ASE", stdout);
17606 if (mask & AFL_ASE_DSPR2)
17607 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17608 if (mask & AFL_ASE_DSPR3)
17609 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17610 if (mask & AFL_ASE_EVA)
17611 fputs ("\n\tEnhanced VA Scheme", stdout);
17612 if (mask & AFL_ASE_MCU)
17613 fputs ("\n\tMCU (MicroController) ASE", stdout);
17614 if (mask & AFL_ASE_MDMX)
17615 fputs ("\n\tMDMX ASE", stdout);
17616 if (mask & AFL_ASE_MIPS3D)
17617 fputs ("\n\tMIPS-3D ASE", stdout);
17618 if (mask & AFL_ASE_MT)
17619 fputs ("\n\tMT ASE", stdout);
17620 if (mask & AFL_ASE_SMARTMIPS)
17621 fputs ("\n\tSmartMIPS ASE", stdout);
17622 if (mask & AFL_ASE_VIRT)
17623 fputs ("\n\tVZ ASE", stdout);
17624 if (mask & AFL_ASE_MSA)
17625 fputs ("\n\tMSA ASE", stdout);
17626 if (mask & AFL_ASE_MIPS16)
17627 fputs ("\n\tMIPS16 ASE", stdout);
17628 if (mask & AFL_ASE_MICROMIPS)
17629 fputs ("\n\tMICROMIPS ASE", stdout);
17630 if (mask & AFL_ASE_XPA)
17631 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17632 if (mask & AFL_ASE_MIPS16E2)
17633 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17634 if (mask & AFL_ASE_CRC)
17635 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17636 if (mask & AFL_ASE_GINV)
17637 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17638 if (mask & AFL_ASE_LOONGSON_MMI)
17639 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17640 if (mask & AFL_ASE_LOONGSON_CAM)
17641 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17642 if (mask & AFL_ASE_LOONGSON_EXT)
17643 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17644 if (mask & AFL_ASE_LOONGSON_EXT2)
17645 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17646 if (mask == 0)
17647 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17648 else if ((mask & ~AFL_ASE_MASK) != 0)
17649 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17650}
17651
17652static void
17653print_mips_isa_ext (unsigned int isa_ext)
17654{
17655 switch (isa_ext)
17656 {
17657 case 0:
17658 fputs (_("None"), stdout);
17659 break;
17660 case AFL_EXT_XLR:
17661 fputs ("RMI XLR", stdout);
17662 break;
2c629856
N
17663 case AFL_EXT_OCTEON3:
17664 fputs ("Cavium Networks Octeon3", stdout);
17665 break;
351cdf24
MF
17666 case AFL_EXT_OCTEON2:
17667 fputs ("Cavium Networks Octeon2", stdout);
17668 break;
17669 case AFL_EXT_OCTEONP:
17670 fputs ("Cavium Networks OcteonP", stdout);
17671 break;
351cdf24
MF
17672 case AFL_EXT_OCTEON:
17673 fputs ("Cavium Networks Octeon", stdout);
17674 break;
17675 case AFL_EXT_5900:
17676 fputs ("Toshiba R5900", stdout);
17677 break;
17678 case AFL_EXT_4650:
17679 fputs ("MIPS R4650", stdout);
17680 break;
17681 case AFL_EXT_4010:
17682 fputs ("LSI R4010", stdout);
17683 break;
17684 case AFL_EXT_4100:
17685 fputs ("NEC VR4100", stdout);
17686 break;
17687 case AFL_EXT_3900:
17688 fputs ("Toshiba R3900", stdout);
17689 break;
17690 case AFL_EXT_10000:
17691 fputs ("MIPS R10000", stdout);
17692 break;
17693 case AFL_EXT_SB1:
17694 fputs ("Broadcom SB-1", stdout);
17695 break;
17696 case AFL_EXT_4111:
17697 fputs ("NEC VR4111/VR4181", stdout);
17698 break;
17699 case AFL_EXT_4120:
17700 fputs ("NEC VR4120", stdout);
17701 break;
17702 case AFL_EXT_5400:
17703 fputs ("NEC VR5400", stdout);
17704 break;
17705 case AFL_EXT_5500:
17706 fputs ("NEC VR5500", stdout);
17707 break;
17708 case AFL_EXT_LOONGSON_2E:
17709 fputs ("ST Microelectronics Loongson 2E", stdout);
17710 break;
17711 case AFL_EXT_LOONGSON_2F:
17712 fputs ("ST Microelectronics Loongson 2F", stdout);
17713 break;
38bf472a
MR
17714 case AFL_EXT_INTERAPTIV_MR2:
17715 fputs ("Imagination interAptiv MR2", stdout);
17716 break;
351cdf24 17717 default:
00ac7aa0 17718 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17719 }
17720}
17721
32ec8896 17722static signed int
351cdf24
MF
17723get_mips_reg_size (int reg_size)
17724{
17725 return (reg_size == AFL_REG_NONE) ? 0
17726 : (reg_size == AFL_REG_32) ? 32
17727 : (reg_size == AFL_REG_64) ? 64
17728 : (reg_size == AFL_REG_128) ? 128
17729 : -1;
17730}
17731
015dc7e1 17732static bool
dda8d76d 17733process_mips_specific (Filedata * filedata)
5b18a4bc 17734{
2cf0635d 17735 Elf_Internal_Dyn * entry;
351cdf24 17736 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17737 size_t liblist_offset = 0;
17738 size_t liblistno = 0;
17739 size_t conflictsno = 0;
17740 size_t options_offset = 0;
17741 size_t conflicts_offset = 0;
861fb55a
DJ
17742 size_t pltrelsz = 0;
17743 size_t pltrel = 0;
ccb4c951 17744 bfd_vma pltgot = 0;
861fb55a
DJ
17745 bfd_vma mips_pltgot = 0;
17746 bfd_vma jmprel = 0;
ccb4c951
RS
17747 bfd_vma local_gotno = 0;
17748 bfd_vma gotsym = 0;
17749 bfd_vma symtabno = 0;
015dc7e1 17750 bool res = true;
103f02d3 17751
dda8d76d 17752 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896 17753 display_mips_gnu_attribute))
015dc7e1 17754 res = false;
2cf19d5c 17755
dda8d76d 17756 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17757
17758 if (sect != NULL)
17759 {
17760 Elf_External_ABIFlags_v0 *abiflags_ext;
17761 Elf_Internal_ABIFlags_v0 abiflags_in;
17762
17763 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17764 {
17765 error (_("Corrupt MIPS ABI Flags section.\n"));
015dc7e1 17766 res = false;
32ec8896 17767 }
351cdf24
MF
17768 else
17769 {
dda8d76d 17770 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17771 sect->sh_size, _("MIPS ABI Flags section"));
17772 if (abiflags_ext)
17773 {
17774 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17775 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17776 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17777 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17778 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17779 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17780 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17781 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17782 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17783 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17784 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17785
17786 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17787 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17788 if (abiflags_in.isa_rev > 1)
17789 printf ("r%d", abiflags_in.isa_rev);
17790 printf ("\nGPR size: %d",
17791 get_mips_reg_size (abiflags_in.gpr_size));
17792 printf ("\nCPR1 size: %d",
17793 get_mips_reg_size (abiflags_in.cpr1_size));
17794 printf ("\nCPR2 size: %d",
17795 get_mips_reg_size (abiflags_in.cpr2_size));
17796 fputs ("\nFP ABI: ", stdout);
17797 print_mips_fp_abi_value (abiflags_in.fp_abi);
17798 fputs ("ISA Extension: ", stdout);
17799 print_mips_isa_ext (abiflags_in.isa_ext);
17800 fputs ("\nASEs:", stdout);
17801 print_mips_ases (abiflags_in.ases);
17802 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17803 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17804 fputc ('\n', stdout);
17805 free (abiflags_ext);
17806 }
17807 }
17808 }
17809
19e6b90e 17810 /* We have a lot of special sections. Thanks SGI! */
978c4450 17811 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17812 {
17813 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17814 sect = find_section (filedata, ".got");
bbdd9a68
MR
17815 if (sect != NULL)
17816 {
17817 unsigned char *data_end;
17818 unsigned char *data;
17819 bfd_vma ent, end;
17820 int addr_size;
17821
17822 pltgot = sect->sh_addr;
17823
17824 ent = pltgot;
17825 addr_size = (is_32bit_elf ? 4 : 8);
17826 end = pltgot + sect->sh_size;
17827
dda8d76d 17828 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17829 end - pltgot, 1,
17830 _("Global Offset Table data"));
17831 /* PR 12855: Null data is handled gracefully throughout. */
17832 data_end = data + (end - pltgot);
17833
17834 printf (_("\nStatic GOT:\n"));
17835 printf (_(" Canonical gp value: "));
17836 print_vma (ent + 0x7ff0, LONG_HEX);
17837 printf ("\n\n");
17838
17839 /* In a dynamic binary GOT[0] is reserved for the dynamic
17840 loader to store the lazy resolver pointer, however in
17841 a static binary it may well have been omitted and GOT
17842 reduced to a table of addresses.
17843 PR 21344: Check for the entry being fully available
17844 before fetching it. */
17845 if (data
17846 && data + ent - pltgot + addr_size <= data_end
17847 && byte_get (data + ent - pltgot, addr_size) == 0)
17848 {
17849 printf (_(" Reserved entries:\n"));
17850 printf (_(" %*s %10s %*s\n"),
17851 addr_size * 2, _("Address"), _("Access"),
17852 addr_size * 2, _("Value"));
17853 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17854 printf ("\n");
17855 if (ent == (bfd_vma) -1)
17856 goto sgot_print_fail;
17857
17858 /* Check for the MSB of GOT[1] being set, identifying a
17859 GNU object. This entry will be used by some runtime
17860 loaders, to store the module pointer. Otherwise this
17861 is an ordinary local entry.
17862 PR 21344: Check for the entry being fully available
17863 before fetching it. */
17864 if (data
17865 && data + ent - pltgot + addr_size <= data_end
17866 && (byte_get (data + ent - pltgot, addr_size)
17867 >> (addr_size * 8 - 1)) != 0)
17868 {
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 printf ("\n");
17875 }
17876
f17e9d8a 17877 if (data != NULL && ent < end)
bbdd9a68
MR
17878 {
17879 printf (_(" Local entries:\n"));
17880 printf (" %*s %10s %*s\n",
17881 addr_size * 2, _("Address"), _("Access"),
17882 addr_size * 2, _("Value"));
17883 while (ent < end)
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
17893 sgot_print_fail:
9db70fc3 17894 free (data);
bbdd9a68
MR
17895 }
17896 return res;
17897 }
252b5132 17898
978c4450 17899 for (entry = filedata->dynamic_section;
071436c6 17900 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17901 (entry < filedata->dynamic_section + filedata->dynamic_nent
17902 && entry->d_tag != DT_NULL);
071436c6 17903 ++entry)
252b5132
RH
17904 switch (entry->d_tag)
17905 {
17906 case DT_MIPS_LIBLIST:
d93f0186 17907 liblist_offset
dda8d76d 17908 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17909 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17910 break;
17911 case DT_MIPS_LIBLISTNO:
17912 liblistno = entry->d_un.d_val;
17913 break;
17914 case DT_MIPS_OPTIONS:
dda8d76d 17915 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17916 break;
17917 case DT_MIPS_CONFLICT:
d93f0186 17918 conflicts_offset
dda8d76d 17919 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17920 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17921 break;
17922 case DT_MIPS_CONFLICTNO:
17923 conflictsno = entry->d_un.d_val;
17924 break;
ccb4c951 17925 case DT_PLTGOT:
861fb55a
DJ
17926 pltgot = entry->d_un.d_ptr;
17927 break;
ccb4c951
RS
17928 case DT_MIPS_LOCAL_GOTNO:
17929 local_gotno = entry->d_un.d_val;
17930 break;
17931 case DT_MIPS_GOTSYM:
17932 gotsym = entry->d_un.d_val;
17933 break;
17934 case DT_MIPS_SYMTABNO:
17935 symtabno = entry->d_un.d_val;
17936 break;
861fb55a
DJ
17937 case DT_MIPS_PLTGOT:
17938 mips_pltgot = entry->d_un.d_ptr;
17939 break;
17940 case DT_PLTREL:
17941 pltrel = entry->d_un.d_val;
17942 break;
17943 case DT_PLTRELSZ:
17944 pltrelsz = entry->d_un.d_val;
17945 break;
17946 case DT_JMPREL:
17947 jmprel = entry->d_un.d_ptr;
17948 break;
252b5132
RH
17949 default:
17950 break;
17951 }
17952
17953 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17954 {
2cf0635d 17955 Elf32_External_Lib * elib;
252b5132
RH
17956 size_t cnt;
17957
dda8d76d 17958 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17959 sizeof (Elf32_External_Lib),
17960 liblistno,
17961 _("liblist section data"));
a6e9f9df 17962 if (elib)
252b5132 17963 {
d3a49aa8
AM
17964 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17965 "\nSection '.liblist' contains %lu entries:\n",
17966 (unsigned long) liblistno),
a6e9f9df 17967 (unsigned long) liblistno);
2b692964 17968 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17969 stdout);
17970
17971 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17972 {
a6e9f9df 17973 Elf32_Lib liblist;
91d6fa6a 17974 time_t atime;
d5b07ef4 17975 char timebuf[128];
2cf0635d 17976 struct tm * tmp;
a6e9f9df
AM
17977
17978 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17979 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17980 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17981 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17982 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17983
91d6fa6a 17984 tmp = gmtime (&atime);
e9e44622
JJ
17985 snprintf (timebuf, sizeof (timebuf),
17986 "%04u-%02u-%02uT%02u:%02u:%02u",
17987 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17988 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17989
31104126 17990 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17991 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17992 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17993 else
2b692964 17994 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17995 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17996 liblist.l_version);
a6e9f9df
AM
17997
17998 if (liblist.l_flags == 0)
2b692964 17999 puts (_(" NONE"));
a6e9f9df
AM
18000 else
18001 {
18002 static const struct
252b5132 18003 {
2cf0635d 18004 const char * name;
a6e9f9df 18005 int bit;
252b5132 18006 }
a6e9f9df
AM
18007 l_flags_vals[] =
18008 {
18009 { " EXACT_MATCH", LL_EXACT_MATCH },
18010 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
18011 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
18012 { " EXPORTS", LL_EXPORTS },
18013 { " DELAY_LOAD", LL_DELAY_LOAD },
18014 { " DELTA", LL_DELTA }
18015 };
18016 int flags = liblist.l_flags;
18017 size_t fcnt;
18018
60bca95a 18019 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
18020 if ((flags & l_flags_vals[fcnt].bit) != 0)
18021 {
18022 fputs (l_flags_vals[fcnt].name, stdout);
18023 flags ^= l_flags_vals[fcnt].bit;
18024 }
18025 if (flags != 0)
18026 printf (" %#x", (unsigned int) flags);
252b5132 18027
a6e9f9df
AM
18028 puts ("");
18029 }
252b5132 18030 }
252b5132 18031
a6e9f9df
AM
18032 free (elib);
18033 }
32ec8896 18034 else
015dc7e1 18035 res = false;
252b5132
RH
18036 }
18037
18038 if (options_offset != 0)
18039 {
2cf0635d 18040 Elf_External_Options * eopt;
252b5132
RH
18041 size_t offset;
18042 int cnt;
dda8d76d 18043 sect = filedata->section_headers;
252b5132
RH
18044
18045 /* Find the section header so that we get the size. */
dda8d76d 18046 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 18047 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
18048 if (sect == NULL)
18049 {
18050 error (_("No MIPS_OPTIONS header found\n"));
015dc7e1 18051 return false;
071436c6 18052 }
7fc0c668
NC
18053 /* PR 24243 */
18054 if (sect->sh_size < sizeof (* eopt))
18055 {
18056 error (_("The MIPS options section is too small.\n"));
015dc7e1 18057 return false;
7fc0c668 18058 }
252b5132 18059
dda8d76d 18060 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 18061 sect->sh_size, _("options"));
a6e9f9df 18062 if (eopt)
252b5132 18063 {
fd17d1e6 18064 Elf_Internal_Options option;
76da6bbe 18065
a6e9f9df 18066 offset = cnt = 0;
82b1b41b 18067 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 18068 {
2cf0635d 18069 Elf_External_Options * eoption;
fd17d1e6 18070 unsigned int optsize;
252b5132 18071
a6e9f9df 18072 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 18073
fd17d1e6 18074 optsize = BYTE_GET (eoption->size);
76da6bbe 18075
82b1b41b 18076 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
18077 if (optsize < sizeof (* eopt)
18078 || optsize > sect->sh_size - offset)
82b1b41b 18079 {
645f43a8 18080 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 18081 optsize);
645f43a8 18082 free (eopt);
015dc7e1 18083 return false;
82b1b41b 18084 }
fd17d1e6 18085 offset += optsize;
a6e9f9df
AM
18086 ++cnt;
18087 }
252b5132 18088
d3a49aa8
AM
18089 printf (ngettext ("\nSection '%s' contains %d entry:\n",
18090 "\nSection '%s' contains %d entries:\n",
18091 cnt),
dda8d76d 18092 printable_section_name (filedata, sect), cnt);
76da6bbe 18093
82b1b41b 18094 offset = 0;
a6e9f9df 18095 while (cnt-- > 0)
252b5132 18096 {
a6e9f9df 18097 size_t len;
fd17d1e6
AM
18098 Elf_External_Options * eoption;
18099
18100 eoption = (Elf_External_Options *) ((char *) eopt + offset);
18101
18102 option.kind = BYTE_GET (eoption->kind);
18103 option.size = BYTE_GET (eoption->size);
18104 option.section = BYTE_GET (eoption->section);
18105 option.info = BYTE_GET (eoption->info);
a6e9f9df 18106
fd17d1e6 18107 switch (option.kind)
252b5132 18108 {
a6e9f9df
AM
18109 case ODK_NULL:
18110 /* This shouldn't happen. */
d0c4e780 18111 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 18112 option.section, option.info);
a6e9f9df 18113 break;
2e6be59c 18114
a6e9f9df
AM
18115 case ODK_REGINFO:
18116 printf (" REGINFO ");
dda8d76d 18117 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 18118 {
2cf0635d 18119 Elf32_External_RegInfo * ereg;
b34976b6 18120 Elf32_RegInfo reginfo;
a6e9f9df 18121
2e6be59c 18122 /* 32bit form. */
fd17d1e6
AM
18123 if (option.size < (sizeof (Elf_External_Options)
18124 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
18125 {
18126 printf (_("<corrupt>\n"));
18127 error (_("Truncated MIPS REGINFO option\n"));
18128 cnt = 0;
18129 break;
18130 }
18131
fd17d1e6 18132 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 18133
a6e9f9df
AM
18134 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18135 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18136 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18137 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18138 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
18139 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
18140
d0c4e780
AM
18141 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
18142 reginfo.ri_gprmask, reginfo.ri_gp_value);
18143 printf (" "
18144 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18145 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18146 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18147 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18148 }
18149 else
18150 {
18151 /* 64 bit form. */
2cf0635d 18152 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
18153 Elf64_Internal_RegInfo reginfo;
18154
fd17d1e6
AM
18155 if (option.size < (sizeof (Elf_External_Options)
18156 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
18157 {
18158 printf (_("<corrupt>\n"));
18159 error (_("Truncated MIPS REGINFO option\n"));
18160 cnt = 0;
18161 break;
18162 }
18163
fd17d1e6 18164 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
18165 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
18166 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
18167 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
18168 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
18169 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 18170 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 18171
d0c4e780
AM
18172 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
18173 reginfo.ri_gprmask, reginfo.ri_gp_value);
18174 printf (" "
18175 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
18176 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
18177 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
18178 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
18179 }
fd17d1e6 18180 offset += option.size;
a6e9f9df 18181 continue;
2e6be59c 18182
a6e9f9df
AM
18183 case ODK_EXCEPTIONS:
18184 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 18185 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 18186 fputs (") fpe_max(", stdout);
fd17d1e6 18187 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
18188 fputs (")", stdout);
18189
fd17d1e6 18190 if (option.info & OEX_PAGE0)
a6e9f9df 18191 fputs (" PAGE0", stdout);
fd17d1e6 18192 if (option.info & OEX_SMM)
a6e9f9df 18193 fputs (" SMM", stdout);
fd17d1e6 18194 if (option.info & OEX_FPDBUG)
a6e9f9df 18195 fputs (" FPDBUG", stdout);
fd17d1e6 18196 if (option.info & OEX_DISMISS)
a6e9f9df
AM
18197 fputs (" DISMISS", stdout);
18198 break;
2e6be59c 18199
a6e9f9df
AM
18200 case ODK_PAD:
18201 fputs (" PAD ", stdout);
fd17d1e6 18202 if (option.info & OPAD_PREFIX)
a6e9f9df 18203 fputs (" PREFIX", stdout);
fd17d1e6 18204 if (option.info & OPAD_POSTFIX)
a6e9f9df 18205 fputs (" POSTFIX", stdout);
fd17d1e6 18206 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
18207 fputs (" SYMBOL", stdout);
18208 break;
2e6be59c 18209
a6e9f9df
AM
18210 case ODK_HWPATCH:
18211 fputs (" HWPATCH ", stdout);
fd17d1e6 18212 if (option.info & OHW_R4KEOP)
a6e9f9df 18213 fputs (" R4KEOP", stdout);
fd17d1e6 18214 if (option.info & OHW_R8KPFETCH)
a6e9f9df 18215 fputs (" R8KPFETCH", stdout);
fd17d1e6 18216 if (option.info & OHW_R5KEOP)
a6e9f9df 18217 fputs (" R5KEOP", stdout);
fd17d1e6 18218 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
18219 fputs (" R5KCVTL", stdout);
18220 break;
2e6be59c 18221
a6e9f9df
AM
18222 case ODK_FILL:
18223 fputs (" FILL ", stdout);
18224 /* XXX Print content of info word? */
18225 break;
2e6be59c 18226
a6e9f9df
AM
18227 case ODK_TAGS:
18228 fputs (" TAGS ", stdout);
18229 /* XXX Print content of info word? */
18230 break;
2e6be59c 18231
a6e9f9df
AM
18232 case ODK_HWAND:
18233 fputs (" HWAND ", stdout);
fd17d1e6 18234 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18235 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18236 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18237 fputs (" R4KEOP_CLEAN", stdout);
18238 break;
2e6be59c 18239
a6e9f9df
AM
18240 case ODK_HWOR:
18241 fputs (" HWOR ", stdout);
fd17d1e6 18242 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 18243 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 18244 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
18245 fputs (" R4KEOP_CLEAN", stdout);
18246 break;
2e6be59c 18247
a6e9f9df 18248 case ODK_GP_GROUP:
d0c4e780 18249 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
18250 option.info & OGP_GROUP,
18251 (option.info & OGP_SELF) >> 16);
a6e9f9df 18252 break;
2e6be59c 18253
a6e9f9df 18254 case ODK_IDENT:
d0c4e780 18255 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
18256 option.info & OGP_GROUP,
18257 (option.info & OGP_SELF) >> 16);
a6e9f9df 18258 break;
2e6be59c 18259
a6e9f9df
AM
18260 default:
18261 /* This shouldn't happen. */
d0c4e780 18262 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 18263 option.kind, option.section, option.info);
a6e9f9df 18264 break;
252b5132 18265 }
a6e9f9df 18266
2cf0635d 18267 len = sizeof (* eopt);
fd17d1e6 18268 while (len < option.size)
82b1b41b 18269 {
fd17d1e6 18270 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 18271
82b1b41b
NC
18272 if (ISPRINT (datum))
18273 printf ("%c", datum);
18274 else
18275 printf ("\\%03o", datum);
18276 len ++;
18277 }
a6e9f9df 18278 fputs ("\n", stdout);
82b1b41b 18279
fd17d1e6 18280 offset += option.size;
252b5132 18281 }
a6e9f9df 18282 free (eopt);
252b5132 18283 }
32ec8896 18284 else
015dc7e1 18285 res = false;
252b5132
RH
18286 }
18287
18288 if (conflicts_offset != 0 && conflictsno != 0)
18289 {
2cf0635d 18290 Elf32_Conflict * iconf;
252b5132
RH
18291 size_t cnt;
18292
978c4450 18293 if (filedata->dynamic_symbols == NULL)
252b5132 18294 {
591a748a 18295 error (_("conflict list found without a dynamic symbol table\n"));
015dc7e1 18296 return false;
252b5132
RH
18297 }
18298
7296a62a
NC
18299 /* PR 21345 - print a slightly more helpful error message
18300 if we are sure that the cmalloc will fail. */
645f43a8 18301 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
18302 {
18303 error (_("Overlarge number of conflicts detected: %lx\n"),
18304 (long) conflictsno);
015dc7e1 18305 return false;
7296a62a
NC
18306 }
18307
3f5e193b 18308 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
18309 if (iconf == NULL)
18310 {
8b73c356 18311 error (_("Out of memory allocating space for dynamic conflicts\n"));
015dc7e1 18312 return false;
252b5132
RH
18313 }
18314
9ea033b2 18315 if (is_32bit_elf)
252b5132 18316 {
2cf0635d 18317 Elf32_External_Conflict * econf32;
a6e9f9df 18318
3f5e193b 18319 econf32 = (Elf32_External_Conflict *)
95099889
AM
18320 get_data (NULL, filedata, conflicts_offset,
18321 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 18322 if (!econf32)
5a814d6d
AM
18323 {
18324 free (iconf);
015dc7e1 18325 return false;
5a814d6d 18326 }
252b5132
RH
18327
18328 for (cnt = 0; cnt < conflictsno; ++cnt)
18329 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
18330
18331 free (econf32);
252b5132
RH
18332 }
18333 else
18334 {
2cf0635d 18335 Elf64_External_Conflict * econf64;
a6e9f9df 18336
3f5e193b 18337 econf64 = (Elf64_External_Conflict *)
95099889
AM
18338 get_data (NULL, filedata, conflicts_offset,
18339 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 18340 if (!econf64)
5a814d6d
AM
18341 {
18342 free (iconf);
015dc7e1 18343 return false;
5a814d6d 18344 }
252b5132
RH
18345
18346 for (cnt = 0; cnt < conflictsno; ++cnt)
18347 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
18348
18349 free (econf64);
252b5132
RH
18350 }
18351
d3a49aa8
AM
18352 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
18353 "\nSection '.conflict' contains %lu entries:\n",
18354 (unsigned long) conflictsno),
c7e7ca54 18355 (unsigned long) conflictsno);
252b5132
RH
18356 puts (_(" Num: Index Value Name"));
18357
18358 for (cnt = 0; cnt < conflictsno; ++cnt)
18359 {
b34976b6 18360 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 18361
978c4450 18362 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 18363 printf (_("<corrupt symbol index>"));
d79b3d50 18364 else
e0a31db1
NC
18365 {
18366 Elf_Internal_Sym * psym;
18367
978c4450 18368 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
18369 print_vma (psym->st_value, FULL_HEX);
18370 putchar (' ');
978c4450
AM
18371 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18372 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18373 else
18374 printf (_("<corrupt: %14ld>"), psym->st_name);
18375 }
31104126 18376 putchar ('\n');
252b5132
RH
18377 }
18378
252b5132
RH
18379 free (iconf);
18380 }
18381
ccb4c951
RS
18382 if (pltgot != 0 && local_gotno != 0)
18383 {
91d6fa6a 18384 bfd_vma ent, local_end, global_end;
bbeee7ea 18385 size_t i, offset;
2cf0635d 18386 unsigned char * data;
82b1b41b 18387 unsigned char * data_end;
bbeee7ea 18388 int addr_size;
ccb4c951 18389
91d6fa6a 18390 ent = pltgot;
ccb4c951
RS
18391 addr_size = (is_32bit_elf ? 4 : 8);
18392 local_end = pltgot + local_gotno * addr_size;
ccb4c951 18393
74e1a04b
NC
18394 /* PR binutils/17533 file: 012-111227-0.004 */
18395 if (symtabno < gotsym)
18396 {
18397 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 18398 (unsigned long) gotsym, (unsigned long) symtabno);
015dc7e1 18399 return false;
74e1a04b 18400 }
82b1b41b 18401
74e1a04b 18402 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
18403 /* PR 17531: file: 54c91a34. */
18404 if (global_end < local_end)
18405 {
18406 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
015dc7e1 18407 return false;
82b1b41b 18408 }
948f632f 18409
dda8d76d
NC
18410 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
18411 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
18412 global_end - pltgot, 1,
18413 _("Global Offset Table data"));
919383ac 18414 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 18415 data_end = data + (global_end - pltgot);
59245841 18416
ccb4c951
RS
18417 printf (_("\nPrimary GOT:\n"));
18418 printf (_(" Canonical gp value: "));
18419 print_vma (pltgot + 0x7ff0, LONG_HEX);
18420 printf ("\n\n");
18421
18422 printf (_(" Reserved entries:\n"));
18423 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
18424 addr_size * 2, _("Address"), _("Access"),
18425 addr_size * 2, _("Initial"));
82b1b41b 18426 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 18427 printf (_(" Lazy resolver\n"));
82b1b41b
NC
18428 if (ent == (bfd_vma) -1)
18429 goto got_print_fail;
75ec1fdb 18430
c4ab9505
MR
18431 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
18432 This entry will be used by some runtime loaders, to store the
18433 module pointer. Otherwise this is an ordinary local entry.
18434 PR 21344: Check for the entry being fully available before
18435 fetching it. */
18436 if (data
18437 && data + ent - pltgot + addr_size <= data_end
18438 && (byte_get (data + ent - pltgot, addr_size)
18439 >> (addr_size * 8 - 1)) != 0)
18440 {
18441 ent = print_mips_got_entry (data, pltgot, ent, data_end);
18442 printf (_(" Module pointer (GNU extension)\n"));
18443 if (ent == (bfd_vma) -1)
18444 goto got_print_fail;
ccb4c951
RS
18445 }
18446 printf ("\n");
18447
f17e9d8a 18448 if (data != NULL && ent < local_end)
ccb4c951
RS
18449 {
18450 printf (_(" Local entries:\n"));
cc5914eb 18451 printf (" %*s %10s %*s\n",
2b692964
NC
18452 addr_size * 2, _("Address"), _("Access"),
18453 addr_size * 2, _("Initial"));
91d6fa6a 18454 while (ent < local_end)
ccb4c951 18455 {
82b1b41b 18456 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18457 printf ("\n");
82b1b41b
NC
18458 if (ent == (bfd_vma) -1)
18459 goto got_print_fail;
ccb4c951
RS
18460 }
18461 printf ("\n");
18462 }
18463
f17e9d8a 18464 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18465 {
18466 int sym_width;
18467
18468 printf (_(" Global entries:\n"));
cc5914eb 18469 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18470 addr_size * 2, _("Address"),
18471 _("Access"),
2b692964 18472 addr_size * 2, _("Initial"),
9cf03b7e
NC
18473 addr_size * 2, _("Sym.Val."),
18474 _("Type"),
18475 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18476 _("Ndx"), _("Name"));
0b4362b0 18477
ccb4c951 18478 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18479
ccb4c951
RS
18480 for (i = gotsym; i < symtabno; i++)
18481 {
82b1b41b 18482 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18483 printf (" ");
e0a31db1 18484
978c4450 18485 if (filedata->dynamic_symbols == NULL)
e0a31db1 18486 printf (_("<no dynamic symbols>"));
978c4450 18487 else if (i < filedata->num_dynamic_syms)
e0a31db1 18488 {
978c4450 18489 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18490
18491 print_vma (psym->st_value, LONG_HEX);
18492 printf (" %-7s %3s ",
dda8d76d
NC
18493 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18494 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18495
978c4450
AM
18496 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18497 print_symbol (sym_width,
18498 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18499 else
18500 printf (_("<corrupt: %14ld>"), psym->st_name);
18501 }
ccb4c951 18502 else
7fc5ac57
JBG
18503 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18504 (unsigned long) i);
e0a31db1 18505
ccb4c951 18506 printf ("\n");
82b1b41b
NC
18507 if (ent == (bfd_vma) -1)
18508 break;
ccb4c951
RS
18509 }
18510 printf ("\n");
18511 }
18512
82b1b41b 18513 got_print_fail:
9db70fc3 18514 free (data);
ccb4c951
RS
18515 }
18516
861fb55a
DJ
18517 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18518 {
91d6fa6a 18519 bfd_vma ent, end;
861fb55a
DJ
18520 size_t offset, rel_offset;
18521 unsigned long count, i;
2cf0635d 18522 unsigned char * data;
861fb55a 18523 int addr_size, sym_width;
2cf0635d 18524 Elf_Internal_Rela * rels;
861fb55a 18525
dda8d76d 18526 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18527 if (pltrel == DT_RELA)
18528 {
dda8d76d 18529 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18530 return false;
861fb55a
DJ
18531 }
18532 else
18533 {
dda8d76d 18534 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
015dc7e1 18535 return false;
861fb55a
DJ
18536 }
18537
91d6fa6a 18538 ent = mips_pltgot;
861fb55a
DJ
18539 addr_size = (is_32bit_elf ? 4 : 8);
18540 end = mips_pltgot + (2 + count) * addr_size;
18541
dda8d76d
NC
18542 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18543 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18544 1, _("Procedure Linkage Table data"));
59245841 18545 if (data == NULL)
288f0ba2
AM
18546 {
18547 free (rels);
015dc7e1 18548 return false;
288f0ba2 18549 }
59245841 18550
9cf03b7e 18551 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18552 printf (_(" Reserved entries:\n"));
18553 printf (_(" %*s %*s Purpose\n"),
2b692964 18554 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18555 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18556 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18557 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18558 printf (_(" Module pointer\n"));
861fb55a
DJ
18559 printf ("\n");
18560
18561 printf (_(" Entries:\n"));
cc5914eb 18562 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18563 addr_size * 2, _("Address"),
18564 addr_size * 2, _("Initial"),
18565 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18566 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18567 for (i = 0; i < count; i++)
18568 {
df97ab2a 18569 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18570
91d6fa6a 18571 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18572 printf (" ");
e0a31db1 18573
978c4450 18574 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18575 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18576 else
e0a31db1 18577 {
978c4450 18578 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18579
18580 print_vma (psym->st_value, LONG_HEX);
18581 printf (" %-7s %3s ",
dda8d76d
NC
18582 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18583 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18584 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18585 print_symbol (sym_width,
18586 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18587 else
18588 printf (_("<corrupt: %14ld>"), psym->st_name);
18589 }
861fb55a
DJ
18590 printf ("\n");
18591 }
18592 printf ("\n");
18593
9db70fc3 18594 free (data);
861fb55a
DJ
18595 free (rels);
18596 }
18597
32ec8896 18598 return res;
252b5132
RH
18599}
18600
015dc7e1 18601static bool
dda8d76d 18602process_nds32_specific (Filedata * filedata)
35c08157
KLC
18603{
18604 Elf_Internal_Shdr *sect = NULL;
18605
dda8d76d 18606 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18607 if (sect != NULL && sect->sh_size >= 4)
35c08157 18608 {
9c7b8e9b
AM
18609 unsigned char *buf;
18610 unsigned int flag;
35c08157
KLC
18611
18612 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18613 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18614 _("NDS32 elf flags section"));
35c08157 18615
9c7b8e9b 18616 if (buf == NULL)
015dc7e1 18617 return false;
32ec8896 18618
9c7b8e9b
AM
18619 flag = byte_get (buf, 4);
18620 free (buf);
18621 switch (flag & 0x3)
35c08157
KLC
18622 {
18623 case 0:
18624 printf ("(VEC_SIZE):\tNo entry.\n");
18625 break;
18626 case 1:
18627 printf ("(VEC_SIZE):\t4 bytes\n");
18628 break;
18629 case 2:
18630 printf ("(VEC_SIZE):\t16 bytes\n");
18631 break;
18632 case 3:
18633 printf ("(VEC_SIZE):\treserved\n");
18634 break;
18635 }
18636 }
18637
015dc7e1 18638 return true;
35c08157
KLC
18639}
18640
015dc7e1 18641static bool
dda8d76d 18642process_gnu_liblist (Filedata * filedata)
047b2264 18643{
2cf0635d
NC
18644 Elf_Internal_Shdr * section;
18645 Elf_Internal_Shdr * string_sec;
18646 Elf32_External_Lib * elib;
18647 char * strtab;
c256ffe7 18648 size_t strtab_size;
047b2264 18649 size_t cnt;
d3a49aa8 18650 unsigned long num_liblist;
047b2264 18651 unsigned i;
015dc7e1 18652 bool res = true;
047b2264
JJ
18653
18654 if (! do_arch)
015dc7e1 18655 return true;
047b2264 18656
dda8d76d
NC
18657 for (i = 0, section = filedata->section_headers;
18658 i < filedata->file_header.e_shnum;
b34976b6 18659 i++, section++)
047b2264
JJ
18660 {
18661 switch (section->sh_type)
18662 {
18663 case SHT_GNU_LIBLIST:
dda8d76d 18664 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18665 break;
18666
3f5e193b 18667 elib = (Elf32_External_Lib *)
dda8d76d 18668 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18669 _("liblist section data"));
047b2264
JJ
18670
18671 if (elib == NULL)
32ec8896 18672 {
015dc7e1 18673 res = false;
32ec8896
NC
18674 break;
18675 }
047b2264 18676
dda8d76d
NC
18677 string_sec = filedata->section_headers + section->sh_link;
18678 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18679 string_sec->sh_size,
18680 _("liblist string table"));
047b2264
JJ
18681 if (strtab == NULL
18682 || section->sh_entsize != sizeof (Elf32_External_Lib))
18683 {
18684 free (elib);
2842702f 18685 free (strtab);
015dc7e1 18686 res = false;
047b2264
JJ
18687 break;
18688 }
59245841 18689 strtab_size = string_sec->sh_size;
047b2264 18690
d3a49aa8
AM
18691 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18692 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18693 "\nLibrary list section '%s' contains %lu entries:\n",
18694 num_liblist),
dda8d76d 18695 printable_section_name (filedata, section),
d3a49aa8 18696 num_liblist);
047b2264 18697
2b692964 18698 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18699
18700 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18701 ++cnt)
18702 {
18703 Elf32_Lib liblist;
91d6fa6a 18704 time_t atime;
d5b07ef4 18705 char timebuf[128];
2cf0635d 18706 struct tm * tmp;
047b2264
JJ
18707
18708 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18709 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18710 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18711 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18712 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18713
91d6fa6a 18714 tmp = gmtime (&atime);
e9e44622
JJ
18715 snprintf (timebuf, sizeof (timebuf),
18716 "%04u-%02u-%02uT%02u:%02u:%02u",
18717 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18718 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18719
18720 printf ("%3lu: ", (unsigned long) cnt);
18721 if (do_wide)
c256ffe7 18722 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18723 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18724 else
c256ffe7 18725 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18726 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18727 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18728 liblist.l_version, liblist.l_flags);
18729 }
18730
18731 free (elib);
2842702f 18732 free (strtab);
047b2264
JJ
18733 }
18734 }
18735
32ec8896 18736 return res;
047b2264
JJ
18737}
18738
9437c45b 18739static const char *
dda8d76d 18740get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18741{
18742 static char buff[64];
103f02d3 18743
dda8d76d 18744 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18745 switch (e_type)
18746 {
57346661 18747 case NT_AUXV:
1ec5cd37 18748 return _("NT_AUXV (auxiliary vector)");
57346661 18749 case NT_PRSTATUS:
1ec5cd37 18750 return _("NT_PRSTATUS (prstatus structure)");
57346661 18751 case NT_FPREGSET:
1ec5cd37 18752 return _("NT_FPREGSET (floating point registers)");
57346661 18753 case NT_PRPSINFO:
1ec5cd37 18754 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18755 case NT_TASKSTRUCT:
1ec5cd37 18756 return _("NT_TASKSTRUCT (task structure)");
b63a5e38
AB
18757 case NT_GDB_TDESC:
18758 return _("NT_GDB_TDESC (GDB XML target description)");
57346661 18759 case NT_PRXFPREG:
1ec5cd37 18760 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18761 case NT_PPC_VMX:
18762 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18763 case NT_PPC_VSX:
18764 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18765 case NT_PPC_TAR:
18766 return _("NT_PPC_TAR (ppc TAR register)");
18767 case NT_PPC_PPR:
18768 return _("NT_PPC_PPR (ppc PPR register)");
18769 case NT_PPC_DSCR:
18770 return _("NT_PPC_DSCR (ppc DSCR register)");
18771 case NT_PPC_EBB:
18772 return _("NT_PPC_EBB (ppc EBB registers)");
18773 case NT_PPC_PMU:
18774 return _("NT_PPC_PMU (ppc PMU registers)");
18775 case NT_PPC_TM_CGPR:
18776 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18777 case NT_PPC_TM_CFPR:
18778 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18779 case NT_PPC_TM_CVMX:
18780 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18781 case NT_PPC_TM_CVSX:
3fd21718 18782 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18783 case NT_PPC_TM_SPR:
18784 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18785 case NT_PPC_TM_CTAR:
18786 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18787 case NT_PPC_TM_CPPR:
18788 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18789 case NT_PPC_TM_CDSCR:
18790 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18791 case NT_386_TLS:
18792 return _("NT_386_TLS (x86 TLS information)");
18793 case NT_386_IOPERM:
18794 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18795 case NT_X86_XSTATE:
18796 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18797 case NT_X86_CET:
18798 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18799 case NT_S390_HIGH_GPRS:
18800 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18801 case NT_S390_TIMER:
18802 return _("NT_S390_TIMER (s390 timer register)");
18803 case NT_S390_TODCMP:
18804 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18805 case NT_S390_TODPREG:
18806 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18807 case NT_S390_CTRS:
18808 return _("NT_S390_CTRS (s390 control registers)");
18809 case NT_S390_PREFIX:
18810 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18811 case NT_S390_LAST_BREAK:
18812 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18813 case NT_S390_SYSTEM_CALL:
18814 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18815 case NT_S390_TDB:
18816 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18817 case NT_S390_VXRS_LOW:
18818 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18819 case NT_S390_VXRS_HIGH:
18820 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18821 case NT_S390_GS_CB:
18822 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18823 case NT_S390_GS_BC:
18824 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18825 case NT_ARM_VFP:
18826 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18827 case NT_ARM_TLS:
18828 return _("NT_ARM_TLS (AArch TLS registers)");
18829 case NT_ARM_HW_BREAK:
18830 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18831 case NT_ARM_HW_WATCH:
18832 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
3b2bef8b
LM
18833 case NT_ARM_SVE:
18834 return _("NT_ARM_SVE (AArch SVE registers)");
18835 case NT_ARM_PAC_MASK:
18836 return _("NT_ARM_PAC_MASK (AArch pointer authentication code masks)");
18837 case NT_ARM_TAGGED_ADDR_CTRL:
18838 return _("NT_ARM_TAGGED_ADDR_CTRL (AArch tagged address control)");
27456742
AK
18839 case NT_ARC_V2:
18840 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
db6092f3
AB
18841 case NT_RISCV_CSR:
18842 return _("NT_RISCV_CSR (RISC-V control and status registers)");
57346661 18843 case NT_PSTATUS:
1ec5cd37 18844 return _("NT_PSTATUS (pstatus structure)");
57346661 18845 case NT_FPREGS:
1ec5cd37 18846 return _("NT_FPREGS (floating point registers)");
57346661 18847 case NT_PSINFO:
1ec5cd37 18848 return _("NT_PSINFO (psinfo structure)");
57346661 18849 case NT_LWPSTATUS:
1ec5cd37 18850 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18851 case NT_LWPSINFO:
1ec5cd37 18852 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18853 case NT_WIN32PSTATUS:
1ec5cd37 18854 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18855 case NT_SIGINFO:
18856 return _("NT_SIGINFO (siginfo_t data)");
18857 case NT_FILE:
18858 return _("NT_FILE (mapped files)");
894982bf
LM
18859 case NT_MEMTAG:
18860 return _("NT_MEMTAG (memory tags)");
1ec5cd37
NC
18861 default:
18862 break;
18863 }
18864 else
18865 switch (e_type)
18866 {
18867 case NT_VERSION:
18868 return _("NT_VERSION (version)");
18869 case NT_ARCH:
18870 return _("NT_ARCH (architecture)");
9ef920e9 18871 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18872 return _("OPEN");
9ef920e9 18873 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18874 return _("func");
c8795e1f
NC
18875 case NT_GO_BUILDID:
18876 return _("GO BUILDID");
1ec5cd37
NC
18877 default:
18878 break;
18879 }
18880
e9e44622 18881 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18882 return buff;
779fe533
NC
18883}
18884
015dc7e1 18885static bool
9ece1fa9
TT
18886print_core_note (Elf_Internal_Note *pnote)
18887{
18888 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18889 bfd_vma count, page_size;
18890 unsigned char *descdata, *filenames, *descend;
18891
18892 if (pnote->type != NT_FILE)
04ac15ab
AS
18893 {
18894 if (do_wide)
18895 printf ("\n");
015dc7e1 18896 return true;
04ac15ab 18897 }
9ece1fa9
TT
18898
18899#ifndef BFD64
18900 if (!is_32bit_elf)
18901 {
18902 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18903 /* Still "successful". */
015dc7e1 18904 return true;
9ece1fa9
TT
18905 }
18906#endif
18907
18908 if (pnote->descsz < 2 * addr_size)
18909 {
32ec8896 18910 error (_(" Malformed note - too short for header\n"));
015dc7e1 18911 return false;
9ece1fa9
TT
18912 }
18913
18914 descdata = (unsigned char *) pnote->descdata;
18915 descend = descdata + pnote->descsz;
18916
18917 if (descdata[pnote->descsz - 1] != '\0')
18918 {
32ec8896 18919 error (_(" Malformed note - does not end with \\0\n"));
015dc7e1 18920 return false;
9ece1fa9
TT
18921 }
18922
18923 count = byte_get (descdata, addr_size);
18924 descdata += addr_size;
18925
18926 page_size = byte_get (descdata, addr_size);
18927 descdata += addr_size;
18928
5396a86e
AM
18929 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18930 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18931 {
32ec8896 18932 error (_(" Malformed note - too short for supplied file count\n"));
015dc7e1 18933 return false;
9ece1fa9
TT
18934 }
18935
18936 printf (_(" Page size: "));
18937 print_vma (page_size, DEC);
18938 printf ("\n");
18939
18940 printf (_(" %*s%*s%*s\n"),
18941 (int) (2 + 2 * addr_size), _("Start"),
18942 (int) (4 + 2 * addr_size), _("End"),
18943 (int) (4 + 2 * addr_size), _("Page Offset"));
18944 filenames = descdata + count * 3 * addr_size;
595712bb 18945 while (count-- > 0)
9ece1fa9
TT
18946 {
18947 bfd_vma start, end, file_ofs;
18948
18949 if (filenames == descend)
18950 {
32ec8896 18951 error (_(" Malformed note - filenames end too early\n"));
015dc7e1 18952 return false;
9ece1fa9
TT
18953 }
18954
18955 start = byte_get (descdata, addr_size);
18956 descdata += addr_size;
18957 end = byte_get (descdata, addr_size);
18958 descdata += addr_size;
18959 file_ofs = byte_get (descdata, addr_size);
18960 descdata += addr_size;
18961
18962 printf (" ");
18963 print_vma (start, FULL_HEX);
18964 printf (" ");
18965 print_vma (end, FULL_HEX);
18966 printf (" ");
18967 print_vma (file_ofs, FULL_HEX);
18968 printf ("\n %s\n", filenames);
18969
18970 filenames += 1 + strlen ((char *) filenames);
18971 }
18972
015dc7e1 18973 return true;
9ece1fa9
TT
18974}
18975
1118d252
RM
18976static const char *
18977get_gnu_elf_note_type (unsigned e_type)
18978{
1449284b 18979 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18980 switch (e_type)
18981 {
18982 case NT_GNU_ABI_TAG:
18983 return _("NT_GNU_ABI_TAG (ABI version tag)");
18984 case NT_GNU_HWCAP:
18985 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18986 case NT_GNU_BUILD_ID:
18987 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18988 case NT_GNU_GOLD_VERSION:
18989 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18990 case NT_GNU_PROPERTY_TYPE_0:
18991 return _("NT_GNU_PROPERTY_TYPE_0");
18992 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18993 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18994 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18995 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18996 default:
1449284b
NC
18997 {
18998 static char buff[64];
1118d252 18999
1449284b
NC
19000 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19001 return buff;
19002 }
19003 }
1118d252
RM
19004}
19005
a9eafb08
L
19006static void
19007decode_x86_compat_isa (unsigned int bitmask)
19008{
19009 while (bitmask)
19010 {
19011 unsigned int bit = bitmask & (- bitmask);
19012
19013 bitmask &= ~ bit;
19014 switch (bit)
19015 {
19016 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
19017 printf ("i486");
19018 break;
19019 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
19020 printf ("586");
19021 break;
19022 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
19023 printf ("686");
19024 break;
19025 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
19026 printf ("SSE");
19027 break;
19028 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
19029 printf ("SSE2");
19030 break;
19031 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
19032 printf ("SSE3");
19033 break;
19034 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
19035 printf ("SSSE3");
19036 break;
19037 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
19038 printf ("SSE4_1");
19039 break;
19040 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
19041 printf ("SSE4_2");
19042 break;
19043 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
19044 printf ("AVX");
19045 break;
19046 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
19047 printf ("AVX2");
19048 break;
19049 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
19050 printf ("AVX512F");
19051 break;
19052 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
19053 printf ("AVX512CD");
19054 break;
19055 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
19056 printf ("AVX512ER");
19057 break;
19058 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
19059 printf ("AVX512PF");
19060 break;
19061 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
19062 printf ("AVX512VL");
19063 break;
19064 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
19065 printf ("AVX512DQ");
19066 break;
19067 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
19068 printf ("AVX512BW");
19069 break;
65b3d26e
L
19070 default:
19071 printf (_("<unknown: %x>"), bit);
19072 break;
a9eafb08
L
19073 }
19074 if (bitmask)
19075 printf (", ");
19076 }
19077}
19078
9ef920e9 19079static void
32930e4e 19080decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 19081{
0a59decb 19082 if (!bitmask)
90c745dc
L
19083 {
19084 printf (_("<None>"));
19085 return;
19086 }
90c745dc 19087
9ef920e9
NC
19088 while (bitmask)
19089 {
1fc87489 19090 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
19091
19092 bitmask &= ~ bit;
19093 switch (bit)
19094 {
32930e4e 19095 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
19096 printf ("CMOV");
19097 break;
32930e4e 19098 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
19099 printf ("SSE");
19100 break;
32930e4e 19101 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
19102 printf ("SSE2");
19103 break;
32930e4e 19104 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
19105 printf ("SSE3");
19106 break;
32930e4e 19107 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
19108 printf ("SSSE3");
19109 break;
32930e4e 19110 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
19111 printf ("SSE4_1");
19112 break;
32930e4e 19113 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
19114 printf ("SSE4_2");
19115 break;
32930e4e 19116 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
19117 printf ("AVX");
19118 break;
32930e4e 19119 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
19120 printf ("AVX2");
19121 break;
32930e4e 19122 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
19123 printf ("FMA");
19124 break;
32930e4e 19125 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
19126 printf ("AVX512F");
19127 break;
32930e4e 19128 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
19129 printf ("AVX512CD");
19130 break;
32930e4e 19131 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
19132 printf ("AVX512ER");
19133 break;
32930e4e 19134 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
19135 printf ("AVX512PF");
19136 break;
32930e4e 19137 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
19138 printf ("AVX512VL");
19139 break;
32930e4e 19140 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
19141 printf ("AVX512DQ");
19142 break;
32930e4e 19143 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
19144 printf ("AVX512BW");
19145 break;
32930e4e 19146 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
19147 printf ("AVX512_4FMAPS");
19148 break;
32930e4e 19149 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
19150 printf ("AVX512_4VNNIW");
19151 break;
32930e4e 19152 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
19153 printf ("AVX512_BITALG");
19154 break;
32930e4e 19155 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
19156 printf ("AVX512_IFMA");
19157 break;
32930e4e 19158 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
19159 printf ("AVX512_VBMI");
19160 break;
32930e4e 19161 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
19162 printf ("AVX512_VBMI2");
19163 break;
32930e4e 19164 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
19165 printf ("AVX512_VNNI");
19166 break;
32930e4e 19167 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
19168 printf ("AVX512_BF16");
19169 break;
65b3d26e
L
19170 default:
19171 printf (_("<unknown: %x>"), bit);
19172 break;
9ef920e9
NC
19173 }
19174 if (bitmask)
19175 printf (", ");
19176 }
19177}
19178
32930e4e
L
19179static void
19180decode_x86_isa (unsigned int bitmask)
19181{
32930e4e
L
19182 while (bitmask)
19183 {
19184 unsigned int bit = bitmask & (- bitmask);
19185
19186 bitmask &= ~ bit;
19187 switch (bit)
19188 {
b0ab0693
L
19189 case GNU_PROPERTY_X86_ISA_1_BASELINE:
19190 printf ("x86-64-baseline");
19191 break;
32930e4e
L
19192 case GNU_PROPERTY_X86_ISA_1_V2:
19193 printf ("x86-64-v2");
19194 break;
19195 case GNU_PROPERTY_X86_ISA_1_V3:
19196 printf ("x86-64-v3");
19197 break;
19198 case GNU_PROPERTY_X86_ISA_1_V4:
19199 printf ("x86-64-v4");
19200 break;
19201 default:
19202 printf (_("<unknown: %x>"), bit);
19203 break;
19204 }
19205 if (bitmask)
19206 printf (", ");
19207 }
19208}
19209
ee2fdd6f 19210static void
a9eafb08 19211decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 19212{
0a59decb 19213 if (!bitmask)
90c745dc
L
19214 {
19215 printf (_("<None>"));
19216 return;
19217 }
90c745dc 19218
ee2fdd6f
L
19219 while (bitmask)
19220 {
19221 unsigned int bit = bitmask & (- bitmask);
19222
19223 bitmask &= ~ bit;
19224 switch (bit)
19225 {
19226 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 19227 printf ("IBT");
ee2fdd6f 19228 break;
48580982 19229 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 19230 printf ("SHSTK");
48580982 19231 break;
279d901e
L
19232 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
19233 printf ("LAM_U48");
19234 break;
19235 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
19236 printf ("LAM_U57");
19237 break;
ee2fdd6f
L
19238 default:
19239 printf (_("<unknown: %x>"), bit);
19240 break;
19241 }
19242 if (bitmask)
19243 printf (", ");
19244 }
19245}
19246
a9eafb08
L
19247static void
19248decode_x86_feature_2 (unsigned int bitmask)
19249{
0a59decb 19250 if (!bitmask)
90c745dc
L
19251 {
19252 printf (_("<None>"));
19253 return;
19254 }
90c745dc 19255
a9eafb08
L
19256 while (bitmask)
19257 {
19258 unsigned int bit = bitmask & (- bitmask);
19259
19260 bitmask &= ~ bit;
19261 switch (bit)
19262 {
19263 case GNU_PROPERTY_X86_FEATURE_2_X86:
19264 printf ("x86");
19265 break;
19266 case GNU_PROPERTY_X86_FEATURE_2_X87:
19267 printf ("x87");
19268 break;
19269 case GNU_PROPERTY_X86_FEATURE_2_MMX:
19270 printf ("MMX");
19271 break;
19272 case GNU_PROPERTY_X86_FEATURE_2_XMM:
19273 printf ("XMM");
19274 break;
19275 case GNU_PROPERTY_X86_FEATURE_2_YMM:
19276 printf ("YMM");
19277 break;
19278 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
19279 printf ("ZMM");
19280 break;
a308b89d
L
19281 case GNU_PROPERTY_X86_FEATURE_2_TMM:
19282 printf ("TMM");
19283 break;
32930e4e
L
19284 case GNU_PROPERTY_X86_FEATURE_2_MASK:
19285 printf ("MASK");
19286 break;
a9eafb08
L
19287 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
19288 printf ("FXSR");
19289 break;
19290 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
19291 printf ("XSAVE");
19292 break;
19293 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
19294 printf ("XSAVEOPT");
19295 break;
19296 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
19297 printf ("XSAVEC");
19298 break;
65b3d26e
L
19299 default:
19300 printf (_("<unknown: %x>"), bit);
19301 break;
a9eafb08
L
19302 }
19303 if (bitmask)
19304 printf (", ");
19305 }
19306}
19307
cd702818
SD
19308static void
19309decode_aarch64_feature_1_and (unsigned int bitmask)
19310{
19311 while (bitmask)
19312 {
19313 unsigned int bit = bitmask & (- bitmask);
19314
19315 bitmask &= ~ bit;
19316 switch (bit)
19317 {
19318 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
19319 printf ("BTI");
19320 break;
19321
19322 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
19323 printf ("PAC");
19324 break;
19325
19326 default:
19327 printf (_("<unknown: %x>"), bit);
19328 break;
19329 }
19330 if (bitmask)
19331 printf (", ");
19332 }
19333}
19334
9ef920e9 19335static void
dda8d76d 19336print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
19337{
19338 unsigned char * ptr = (unsigned char *) pnote->descdata;
19339 unsigned char * ptr_end = ptr + pnote->descsz;
19340 unsigned int size = is_32bit_elf ? 4 : 8;
19341
19342 printf (_(" Properties: "));
19343
1fc87489 19344 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
19345 {
19346 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
19347 return;
19348 }
19349
6ab2c4ed 19350 while (ptr < ptr_end)
9ef920e9 19351 {
1fc87489 19352 unsigned int j;
6ab2c4ed
MC
19353 unsigned int type;
19354 unsigned int datasz;
19355
19356 if ((size_t) (ptr_end - ptr) < 8)
19357 {
19358 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
19359 break;
19360 }
19361
19362 type = byte_get (ptr, 4);
19363 datasz = byte_get (ptr + 4, 4);
9ef920e9 19364
1fc87489 19365 ptr += 8;
9ef920e9 19366
6ab2c4ed 19367 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 19368 {
1fc87489
L
19369 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
19370 type, datasz);
9ef920e9 19371 break;
1fc87489 19372 }
9ef920e9 19373
1fc87489
L
19374 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
19375 {
dda8d76d
NC
19376 if (filedata->file_header.e_machine == EM_X86_64
19377 || filedata->file_header.e_machine == EM_IAMCU
19378 || filedata->file_header.e_machine == EM_386)
1fc87489 19379 {
aa7bca9b
L
19380 unsigned int bitmask;
19381
19382 if (datasz == 4)
0a59decb 19383 bitmask = byte_get (ptr, 4);
aa7bca9b
L
19384 else
19385 bitmask = 0;
19386
1fc87489
L
19387 switch (type)
19388 {
19389 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 19390 if (datasz != 4)
aa7bca9b
L
19391 printf (_("x86 ISA used: <corrupt length: %#x> "),
19392 datasz);
1fc87489 19393 else
aa7bca9b
L
19394 {
19395 printf ("x86 ISA used: ");
19396 decode_x86_isa (bitmask);
19397 }
1fc87489 19398 goto next;
9ef920e9 19399
1fc87489 19400 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 19401 if (datasz != 4)
aa7bca9b
L
19402 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19403 datasz);
1fc87489 19404 else
aa7bca9b
L
19405 {
19406 printf ("x86 ISA needed: ");
19407 decode_x86_isa (bitmask);
19408 }
1fc87489 19409 goto next;
9ef920e9 19410
ee2fdd6f 19411 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 19412 if (datasz != 4)
aa7bca9b
L
19413 printf (_("x86 feature: <corrupt length: %#x> "),
19414 datasz);
ee2fdd6f 19415 else
aa7bca9b
L
19416 {
19417 printf ("x86 feature: ");
a9eafb08
L
19418 decode_x86_feature_1 (bitmask);
19419 }
19420 goto next;
19421
19422 case GNU_PROPERTY_X86_FEATURE_2_USED:
19423 if (datasz != 4)
19424 printf (_("x86 feature used: <corrupt length: %#x> "),
19425 datasz);
19426 else
19427 {
19428 printf ("x86 feature used: ");
19429 decode_x86_feature_2 (bitmask);
19430 }
19431 goto next;
19432
19433 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
19434 if (datasz != 4)
19435 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
19436 else
19437 {
19438 printf ("x86 feature needed: ");
19439 decode_x86_feature_2 (bitmask);
19440 }
19441 goto next;
19442
19443 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
19444 if (datasz != 4)
19445 printf (_("x86 ISA used: <corrupt length: %#x> "),
19446 datasz);
19447 else
19448 {
19449 printf ("x86 ISA used: ");
19450 decode_x86_compat_isa (bitmask);
19451 }
19452 goto next;
19453
19454 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
19455 if (datasz != 4)
19456 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19457 datasz);
19458 else
19459 {
19460 printf ("x86 ISA needed: ");
19461 decode_x86_compat_isa (bitmask);
aa7bca9b 19462 }
ee2fdd6f
L
19463 goto next;
19464
32930e4e
L
19465 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19466 if (datasz != 4)
19467 printf (_("x86 ISA used: <corrupt length: %#x> "),
19468 datasz);
19469 else
19470 {
19471 printf ("x86 ISA used: ");
19472 decode_x86_compat_2_isa (bitmask);
19473 }
19474 goto next;
19475
19476 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19477 if (datasz != 4)
19478 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19479 datasz);
19480 else
19481 {
19482 printf ("x86 ISA needed: ");
19483 decode_x86_compat_2_isa (bitmask);
19484 }
19485 goto next;
19486
1fc87489
L
19487 default:
19488 break;
19489 }
19490 }
cd702818
SD
19491 else if (filedata->file_header.e_machine == EM_AARCH64)
19492 {
19493 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19494 {
19495 printf ("AArch64 feature: ");
19496 if (datasz != 4)
19497 printf (_("<corrupt length: %#x> "), datasz);
19498 else
19499 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19500 goto next;
19501 }
19502 }
1fc87489
L
19503 }
19504 else
19505 {
19506 switch (type)
9ef920e9 19507 {
1fc87489
L
19508 case GNU_PROPERTY_STACK_SIZE:
19509 printf (_("stack size: "));
19510 if (datasz != size)
19511 printf (_("<corrupt length: %#x> "), datasz);
19512 else
19513 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19514 goto next;
19515
19516 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19517 printf ("no copy on protected ");
19518 if (datasz)
19519 printf (_("<corrupt length: %#x> "), datasz);
19520 goto next;
19521
19522 default:
5a767724
L
19523 if ((type >= GNU_PROPERTY_UINT32_AND_LO
19524 && type <= GNU_PROPERTY_UINT32_AND_HI)
19525 || (type >= GNU_PROPERTY_UINT32_OR_LO
19526 && type <= GNU_PROPERTY_UINT32_OR_HI))
19527 {
19528 if (type <= GNU_PROPERTY_UINT32_AND_HI)
19529 printf (_("UINT32_AND (%#x): "), type);
19530 else
19531 printf (_("UINT32_OR (%#x): "), type);
19532 if (datasz != 4)
19533 printf (_("<corrupt length: %#x> "), datasz);
19534 else
19535 printf ("%#x", (unsigned int) byte_get (ptr, 4));
19536 goto next;
19537 }
9ef920e9
NC
19538 break;
19539 }
9ef920e9
NC
19540 }
19541
1fc87489
L
19542 if (type < GNU_PROPERTY_LOPROC)
19543 printf (_("<unknown type %#x data: "), type);
19544 else if (type < GNU_PROPERTY_LOUSER)
8c3853d9 19545 printf (_("<processor-specific type %#x data: "), type);
1fc87489
L
19546 else
19547 printf (_("<application-specific type %#x data: "), type);
19548 for (j = 0; j < datasz; ++j)
19549 printf ("%02x ", ptr[j] & 0xff);
19550 printf (">");
19551
dc1e8a47 19552 next:
9ef920e9 19553 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19554 if (ptr == ptr_end)
19555 break;
1fc87489 19556
6ab2c4ed
MC
19557 if (do_wide)
19558 printf (", ");
19559 else
19560 printf ("\n\t");
9ef920e9
NC
19561 }
19562
19563 printf ("\n");
19564}
19565
015dc7e1 19566static bool
dda8d76d 19567print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19568{
1449284b 19569 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19570 switch (pnote->type)
19571 {
19572 case NT_GNU_BUILD_ID:
19573 {
19574 unsigned long i;
19575
19576 printf (_(" Build ID: "));
19577 for (i = 0; i < pnote->descsz; ++i)
19578 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19579 printf ("\n");
664f90a3
TT
19580 }
19581 break;
19582
19583 case NT_GNU_ABI_TAG:
19584 {
19585 unsigned long os, major, minor, subminor;
19586 const char *osname;
19587
3102e897
NC
19588 /* PR 17531: file: 030-599401-0.004. */
19589 if (pnote->descsz < 16)
19590 {
19591 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19592 break;
19593 }
19594
664f90a3
TT
19595 os = byte_get ((unsigned char *) pnote->descdata, 4);
19596 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19597 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19598 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19599
19600 switch (os)
19601 {
19602 case GNU_ABI_TAG_LINUX:
19603 osname = "Linux";
19604 break;
19605 case GNU_ABI_TAG_HURD:
19606 osname = "Hurd";
19607 break;
19608 case GNU_ABI_TAG_SOLARIS:
19609 osname = "Solaris";
19610 break;
19611 case GNU_ABI_TAG_FREEBSD:
19612 osname = "FreeBSD";
19613 break;
19614 case GNU_ABI_TAG_NETBSD:
19615 osname = "NetBSD";
19616 break;
14ae95f2
RM
19617 case GNU_ABI_TAG_SYLLABLE:
19618 osname = "Syllable";
19619 break;
19620 case GNU_ABI_TAG_NACL:
19621 osname = "NaCl";
19622 break;
664f90a3
TT
19623 default:
19624 osname = "Unknown";
19625 break;
19626 }
19627
19628 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19629 major, minor, subminor);
19630 }
19631 break;
926c5385
CC
19632
19633 case NT_GNU_GOLD_VERSION:
19634 {
19635 unsigned long i;
19636
19637 printf (_(" Version: "));
19638 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19639 printf ("%c", pnote->descdata[i]);
19640 printf ("\n");
19641 }
19642 break;
1449284b
NC
19643
19644 case NT_GNU_HWCAP:
19645 {
19646 unsigned long num_entries, mask;
19647
19648 /* Hardware capabilities information. Word 0 is the number of entries.
19649 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19650 is a series of entries, where each entry is a single byte followed
19651 by a nul terminated string. The byte gives the bit number to test
19652 if enabled in the bitmask. */
19653 printf (_(" Hardware Capabilities: "));
19654 if (pnote->descsz < 8)
19655 {
32ec8896 19656 error (_("<corrupt GNU_HWCAP>\n"));
015dc7e1 19657 return false;
1449284b
NC
19658 }
19659 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19660 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19661 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19662 /* FIXME: Add code to display the entries... */
19663 }
19664 break;
19665
9ef920e9 19666 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19667 print_gnu_property_note (filedata, pnote);
9ef920e9 19668 break;
9abca702 19669
1449284b
NC
19670 default:
19671 /* Handle unrecognised types. An error message should have already been
19672 created by get_gnu_elf_note_type(), so all that we need to do is to
19673 display the data. */
19674 {
19675 unsigned long i;
19676
19677 printf (_(" Description data: "));
19678 for (i = 0; i < pnote->descsz; ++i)
19679 printf ("%02x ", pnote->descdata[i] & 0xff);
19680 printf ("\n");
19681 }
19682 break;
664f90a3
TT
19683 }
19684
015dc7e1 19685 return true;
664f90a3
TT
19686}
19687
685080f2
NC
19688static const char *
19689get_v850_elf_note_type (enum v850_notes n_type)
19690{
19691 static char buff[64];
19692
19693 switch (n_type)
19694 {
19695 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19696 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19697 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19698 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19699 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19700 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19701 default:
19702 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19703 return buff;
19704 }
19705}
19706
015dc7e1 19707static bool
685080f2
NC
19708print_v850_note (Elf_Internal_Note * pnote)
19709{
19710 unsigned int val;
19711
19712 if (pnote->descsz != 4)
015dc7e1 19713 return false;
32ec8896 19714
685080f2
NC
19715 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19716
19717 if (val == 0)
19718 {
19719 printf (_("not set\n"));
015dc7e1 19720 return true;
685080f2
NC
19721 }
19722
19723 switch (pnote->type)
19724 {
19725 case V850_NOTE_ALIGNMENT:
19726 switch (val)
19727 {
015dc7e1
AM
19728 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return true;
19729 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return true;
685080f2
NC
19730 }
19731 break;
14ae95f2 19732
685080f2
NC
19733 case V850_NOTE_DATA_SIZE:
19734 switch (val)
19735 {
015dc7e1
AM
19736 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return true;
19737 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return true;
685080f2
NC
19738 }
19739 break;
14ae95f2 19740
685080f2
NC
19741 case V850_NOTE_FPU_INFO:
19742 switch (val)
19743 {
015dc7e1
AM
19744 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return true;
19745 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return true;
685080f2
NC
19746 }
19747 break;
14ae95f2 19748
685080f2
NC
19749 case V850_NOTE_MMU_INFO:
19750 case V850_NOTE_CACHE_INFO:
19751 case V850_NOTE_SIMD_INFO:
19752 if (val == EF_RH850_SIMD)
19753 {
19754 printf (_("yes\n"));
015dc7e1 19755 return true;
685080f2
NC
19756 }
19757 break;
19758
19759 default:
19760 /* An 'unknown note type' message will already have been displayed. */
19761 break;
19762 }
19763
19764 printf (_("unknown value: %x\n"), val);
015dc7e1 19765 return false;
685080f2
NC
19766}
19767
015dc7e1 19768static bool
c6056a74
SF
19769process_netbsd_elf_note (Elf_Internal_Note * pnote)
19770{
19771 unsigned int version;
19772
19773 switch (pnote->type)
19774 {
19775 case NT_NETBSD_IDENT:
b966f55f
AM
19776 if (pnote->descsz < 1)
19777 break;
c6056a74
SF
19778 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19779 if ((version / 10000) % 100)
b966f55f 19780 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19781 version, version / 100000000, (version / 1000000) % 100,
19782 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19783 'A' + (version / 10000) % 26);
c6056a74
SF
19784 else
19785 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19786 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19787 (version / 100) % 100);
015dc7e1 19788 return true;
c6056a74
SF
19789
19790 case NT_NETBSD_MARCH:
9abca702 19791 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19792 pnote->descdata);
015dc7e1 19793 return true;
c6056a74 19794
9abca702 19795 case NT_NETBSD_PAX:
b966f55f
AM
19796 if (pnote->descsz < 1)
19797 break;
9abca702
CZ
19798 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19799 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19800 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19801 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19802 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19803 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19804 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19805 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
015dc7e1 19806 return true;
c6056a74 19807 }
b966f55f
AM
19808
19809 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19810 pnote->descsz, pnote->type);
015dc7e1 19811 return false;
c6056a74
SF
19812}
19813
f4ddf30f 19814static const char *
dda8d76d 19815get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19816{
f4ddf30f
JB
19817 switch (e_type)
19818 {
19819 case NT_FREEBSD_THRMISC:
19820 return _("NT_THRMISC (thrmisc structure)");
19821 case NT_FREEBSD_PROCSTAT_PROC:
19822 return _("NT_PROCSTAT_PROC (proc data)");
19823 case NT_FREEBSD_PROCSTAT_FILES:
19824 return _("NT_PROCSTAT_FILES (files data)");
19825 case NT_FREEBSD_PROCSTAT_VMMAP:
19826 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19827 case NT_FREEBSD_PROCSTAT_GROUPS:
19828 return _("NT_PROCSTAT_GROUPS (groups data)");
19829 case NT_FREEBSD_PROCSTAT_UMASK:
19830 return _("NT_PROCSTAT_UMASK (umask data)");
19831 case NT_FREEBSD_PROCSTAT_RLIMIT:
19832 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19833 case NT_FREEBSD_PROCSTAT_OSREL:
19834 return _("NT_PROCSTAT_OSREL (osreldate data)");
19835 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19836 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19837 case NT_FREEBSD_PROCSTAT_AUXV:
19838 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19839 case NT_FREEBSD_PTLWPINFO:
19840 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19841 }
dda8d76d 19842 return get_note_type (filedata, e_type);
f4ddf30f
JB
19843}
19844
9437c45b 19845static const char *
dda8d76d 19846get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19847{
19848 static char buff[64];
19849
540e6170
CZ
19850 switch (e_type)
19851 {
19852 case NT_NETBSDCORE_PROCINFO:
19853 /* NetBSD core "procinfo" structure. */
19854 return _("NetBSD procinfo structure");
9437c45b 19855
540e6170
CZ
19856 case NT_NETBSDCORE_AUXV:
19857 return _("NetBSD ELF auxiliary vector data");
9437c45b 19858
06d949ec
KR
19859 case NT_NETBSDCORE_LWPSTATUS:
19860 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
06d949ec 19861
540e6170 19862 default:
06d949ec 19863 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19864 defined for NetBSD core files. If the note type is less
19865 than the start of the machine-dependent note types, we don't
19866 understand it. */
19867
19868 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19869 {
19870 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19871 return buff;
19872 }
19873 break;
9437c45b
JT
19874 }
19875
dda8d76d 19876 switch (filedata->file_header.e_machine)
9437c45b
JT
19877 {
19878 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19879 and PT_GETFPREGS == mach+2. */
19880
19881 case EM_OLD_ALPHA:
19882 case EM_ALPHA:
19883 case EM_SPARC:
19884 case EM_SPARC32PLUS:
19885 case EM_SPARCV9:
19886 switch (e_type)
19887 {
2b692964 19888 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19889 return _("PT_GETREGS (reg structure)");
2b692964 19890 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19891 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19892 default:
19893 break;
19894 }
19895 break;
19896
c0d38b0e
CZ
19897 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19898 There's also old PT___GETREGS40 == mach + 1 for old reg
19899 structure which lacks GBR. */
19900 case EM_SH:
19901 switch (e_type)
19902 {
19903 case NT_NETBSDCORE_FIRSTMACH + 1:
19904 return _("PT___GETREGS40 (old reg structure)");
19905 case NT_NETBSDCORE_FIRSTMACH + 3:
19906 return _("PT_GETREGS (reg structure)");
19907 case NT_NETBSDCORE_FIRSTMACH + 5:
19908 return _("PT_GETFPREGS (fpreg structure)");
19909 default:
19910 break;
19911 }
19912 break;
19913
9437c45b
JT
19914 /* On all other arch's, PT_GETREGS == mach+1 and
19915 PT_GETFPREGS == mach+3. */
19916 default:
19917 switch (e_type)
19918 {
2b692964 19919 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19920 return _("PT_GETREGS (reg structure)");
2b692964 19921 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19922 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19923 default:
19924 break;
19925 }
19926 }
19927
9cf03b7e 19928 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19929 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19930 return buff;
19931}
19932
70616151
TT
19933static const char *
19934get_stapsdt_note_type (unsigned e_type)
19935{
19936 static char buff[64];
19937
19938 switch (e_type)
19939 {
19940 case NT_STAPSDT:
19941 return _("NT_STAPSDT (SystemTap probe descriptors)");
19942
19943 default:
19944 break;
19945 }
19946
19947 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19948 return buff;
19949}
19950
015dc7e1 19951static bool
c6a9fc58
TT
19952print_stapsdt_note (Elf_Internal_Note *pnote)
19953{
3ca60c57
NC
19954 size_t len, maxlen;
19955 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19956 char *data = pnote->descdata;
19957 char *data_end = pnote->descdata + pnote->descsz;
19958 bfd_vma pc, base_addr, semaphore;
19959 char *provider, *probe, *arg_fmt;
19960
3ca60c57
NC
19961 if (pnote->descsz < (addr_size * 3))
19962 goto stapdt_note_too_small;
19963
c6a9fc58
TT
19964 pc = byte_get ((unsigned char *) data, addr_size);
19965 data += addr_size;
3ca60c57 19966
c6a9fc58
TT
19967 base_addr = byte_get ((unsigned char *) data, addr_size);
19968 data += addr_size;
3ca60c57 19969
c6a9fc58
TT
19970 semaphore = byte_get ((unsigned char *) data, addr_size);
19971 data += addr_size;
19972
3ca60c57
NC
19973 if (data >= data_end)
19974 goto stapdt_note_too_small;
19975 maxlen = data_end - data;
19976 len = strnlen (data, maxlen);
19977 if (len < maxlen)
19978 {
19979 provider = data;
19980 data += len + 1;
19981 }
19982 else
19983 goto stapdt_note_too_small;
19984
19985 if (data >= data_end)
19986 goto stapdt_note_too_small;
19987 maxlen = data_end - data;
19988 len = strnlen (data, maxlen);
19989 if (len < maxlen)
19990 {
19991 probe = data;
19992 data += len + 1;
19993 }
19994 else
19995 goto stapdt_note_too_small;
9abca702 19996
3ca60c57
NC
19997 if (data >= data_end)
19998 goto stapdt_note_too_small;
19999 maxlen = data_end - data;
20000 len = strnlen (data, maxlen);
20001 if (len < maxlen)
20002 {
20003 arg_fmt = data;
20004 data += len + 1;
20005 }
20006 else
20007 goto stapdt_note_too_small;
c6a9fc58
TT
20008
20009 printf (_(" Provider: %s\n"), provider);
20010 printf (_(" Name: %s\n"), probe);
20011 printf (_(" Location: "));
20012 print_vma (pc, FULL_HEX);
20013 printf (_(", Base: "));
20014 print_vma (base_addr, FULL_HEX);
20015 printf (_(", Semaphore: "));
20016 print_vma (semaphore, FULL_HEX);
9cf03b7e 20017 printf ("\n");
c6a9fc58
TT
20018 printf (_(" Arguments: %s\n"), arg_fmt);
20019
20020 return data == data_end;
3ca60c57
NC
20021
20022 stapdt_note_too_small:
20023 printf (_(" <corrupt - note is too small>\n"));
20024 error (_("corrupt stapdt note - the data size is too small\n"));
015dc7e1 20025 return false;
c6a9fc58
TT
20026}
20027
00e98fc7
TG
20028static const char *
20029get_ia64_vms_note_type (unsigned e_type)
20030{
20031 static char buff[64];
20032
20033 switch (e_type)
20034 {
20035 case NT_VMS_MHD:
20036 return _("NT_VMS_MHD (module header)");
20037 case NT_VMS_LNM:
20038 return _("NT_VMS_LNM (language name)");
20039 case NT_VMS_SRC:
20040 return _("NT_VMS_SRC (source files)");
20041 case NT_VMS_TITLE:
9cf03b7e 20042 return "NT_VMS_TITLE";
00e98fc7
TG
20043 case NT_VMS_EIDC:
20044 return _("NT_VMS_EIDC (consistency check)");
20045 case NT_VMS_FPMODE:
20046 return _("NT_VMS_FPMODE (FP mode)");
20047 case NT_VMS_LINKTIME:
9cf03b7e 20048 return "NT_VMS_LINKTIME";
00e98fc7
TG
20049 case NT_VMS_IMGNAM:
20050 return _("NT_VMS_IMGNAM (image name)");
20051 case NT_VMS_IMGID:
20052 return _("NT_VMS_IMGID (image id)");
20053 case NT_VMS_LINKID:
20054 return _("NT_VMS_LINKID (link id)");
20055 case NT_VMS_IMGBID:
20056 return _("NT_VMS_IMGBID (build id)");
20057 case NT_VMS_GSTNAM:
20058 return _("NT_VMS_GSTNAM (sym table name)");
20059 case NT_VMS_ORIG_DYN:
9cf03b7e 20060 return "NT_VMS_ORIG_DYN";
00e98fc7 20061 case NT_VMS_PATCHTIME:
9cf03b7e 20062 return "NT_VMS_PATCHTIME";
00e98fc7
TG
20063 default:
20064 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
20065 return buff;
20066 }
20067}
20068
015dc7e1 20069static bool
00e98fc7
TG
20070print_ia64_vms_note (Elf_Internal_Note * pnote)
20071{
8d18bf79
NC
20072 int maxlen = pnote->descsz;
20073
20074 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
20075 goto desc_size_fail;
20076
00e98fc7
TG
20077 switch (pnote->type)
20078 {
20079 case NT_VMS_MHD:
8d18bf79
NC
20080 if (maxlen <= 36)
20081 goto desc_size_fail;
20082
20083 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
20084
20085 printf (_(" Creation date : %.17s\n"), pnote->descdata);
20086 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
20087 if (l + 34 < maxlen)
20088 {
20089 printf (_(" Module name : %s\n"), pnote->descdata + 34);
20090 if (l + 35 < maxlen)
20091 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
20092 else
20093 printf (_(" Module version : <missing>\n"));
20094 }
00e98fc7 20095 else
8d18bf79
NC
20096 {
20097 printf (_(" Module name : <missing>\n"));
20098 printf (_(" Module version : <missing>\n"));
20099 }
00e98fc7 20100 break;
8d18bf79 20101
00e98fc7 20102 case NT_VMS_LNM:
8d18bf79 20103 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20104 break;
8d18bf79 20105
00e98fc7
TG
20106#ifdef BFD64
20107 case NT_VMS_FPMODE:
9cf03b7e 20108 printf (_(" Floating Point mode: "));
8d18bf79
NC
20109 if (maxlen < 8)
20110 goto desc_size_fail;
20111 /* FIXME: Generate an error if descsz > 8 ? */
20112
4a5cb34f 20113 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 20114 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 20115 break;
8d18bf79 20116
00e98fc7
TG
20117 case NT_VMS_LINKTIME:
20118 printf (_(" Link time: "));
8d18bf79
NC
20119 if (maxlen < 8)
20120 goto desc_size_fail;
20121 /* FIXME: Generate an error if descsz > 8 ? */
20122
00e98fc7 20123 print_vms_time
8d18bf79 20124 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20125 printf ("\n");
20126 break;
8d18bf79 20127
00e98fc7
TG
20128 case NT_VMS_PATCHTIME:
20129 printf (_(" Patch time: "));
8d18bf79
NC
20130 if (maxlen < 8)
20131 goto desc_size_fail;
20132 /* FIXME: Generate an error if descsz > 8 ? */
20133
00e98fc7 20134 print_vms_time
8d18bf79 20135 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
20136 printf ("\n");
20137 break;
8d18bf79 20138
00e98fc7 20139 case NT_VMS_ORIG_DYN:
8d18bf79
NC
20140 if (maxlen < 34)
20141 goto desc_size_fail;
20142
00e98fc7
TG
20143 printf (_(" Major id: %u, minor id: %u\n"),
20144 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
20145 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 20146 printf (_(" Last modified : "));
00e98fc7
TG
20147 print_vms_time
20148 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 20149 printf (_("\n Link flags : "));
4a5cb34f 20150 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 20151 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 20152 printf (_(" Header flags: 0x%08x\n"),
948f632f 20153 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 20154 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
20155 break;
20156#endif
8d18bf79 20157
00e98fc7 20158 case NT_VMS_IMGNAM:
8d18bf79 20159 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20160 break;
8d18bf79 20161
00e98fc7 20162 case NT_VMS_GSTNAM:
8d18bf79 20163 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20164 break;
8d18bf79 20165
00e98fc7 20166 case NT_VMS_IMGID:
8d18bf79 20167 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20168 break;
8d18bf79 20169
00e98fc7 20170 case NT_VMS_LINKID:
8d18bf79 20171 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 20172 break;
8d18bf79 20173
00e98fc7 20174 default:
015dc7e1 20175 return false;
00e98fc7 20176 }
8d18bf79 20177
015dc7e1 20178 return true;
8d18bf79
NC
20179
20180 desc_size_fail:
20181 printf (_(" <corrupt - data size is too small>\n"));
20182 error (_("corrupt IA64 note: data size is too small\n"));
015dc7e1 20183 return false;
00e98fc7
TG
20184}
20185
fd486f32
AM
20186struct build_attr_cache {
20187 Filedata *filedata;
20188 char *strtab;
20189 unsigned long strtablen;
20190 Elf_Internal_Sym *symtab;
20191 unsigned long nsyms;
20192} ba_cache;
20193
6f156d7a
NC
20194/* Find the symbol associated with a build attribute that is attached
20195 to address OFFSET. If PNAME is non-NULL then store the name of
20196 the symbol (if found) in the provided pointer, Returns NULL if a
20197 symbol could not be found. */
c799a79d 20198
6f156d7a 20199static Elf_Internal_Sym *
015dc7e1
AM
20200get_symbol_for_build_attribute (Filedata *filedata,
20201 unsigned long offset,
20202 bool is_open_attr,
20203 const char **pname)
9ef920e9 20204{
fd486f32
AM
20205 Elf_Internal_Sym *saved_sym = NULL;
20206 Elf_Internal_Sym *sym;
9ef920e9 20207
dda8d76d 20208 if (filedata->section_headers != NULL
fd486f32 20209 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 20210 {
c799a79d 20211 Elf_Internal_Shdr * symsec;
9ef920e9 20212
fd486f32
AM
20213 free (ba_cache.strtab);
20214 ba_cache.strtab = NULL;
20215 free (ba_cache.symtab);
20216 ba_cache.symtab = NULL;
20217
c799a79d 20218 /* Load the symbol and string sections. */
dda8d76d
NC
20219 for (symsec = filedata->section_headers;
20220 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 20221 symsec ++)
9ef920e9 20222 {
28d13567
AM
20223 if (symsec->sh_type == SHT_SYMTAB
20224 && get_symtab (filedata, symsec,
20225 &ba_cache.symtab, &ba_cache.nsyms,
20226 &ba_cache.strtab, &ba_cache.strtablen))
20227 break;
9ef920e9 20228 }
fd486f32 20229 ba_cache.filedata = filedata;
9ef920e9
NC
20230 }
20231
fd486f32 20232 if (ba_cache.symtab == NULL)
6f156d7a 20233 return NULL;
9ef920e9 20234
c799a79d 20235 /* Find a symbol whose value matches offset. */
fd486f32 20236 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
20237 if (sym->st_value == offset)
20238 {
fd486f32 20239 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
20240 /* Huh ? This should not happen. */
20241 continue;
9ef920e9 20242
fd486f32 20243 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 20244 continue;
9ef920e9 20245
8fd75781
NC
20246 /* The AArch64 and ARM architectures define mapping symbols
20247 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
20248 if (ba_cache.strtab[sym->st_name] == '$'
20249 && ba_cache.strtab[sym->st_name + 1] != 0
20250 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
20251 continue;
20252
c799a79d
NC
20253 if (is_open_attr)
20254 {
20255 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
20256 and FILE or OBJECT symbols over NOTYPE symbols. We skip
20257 FUNC symbols entirely. */
20258 switch (ELF_ST_TYPE (sym->st_info))
20259 {
c799a79d 20260 case STT_OBJECT:
6f156d7a 20261 case STT_FILE:
c799a79d 20262 saved_sym = sym;
6f156d7a
NC
20263 if (sym->st_size)
20264 {
20265 /* If the symbol has a size associated
20266 with it then we can stop searching. */
fd486f32 20267 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 20268 }
c799a79d 20269 continue;
9ef920e9 20270
c799a79d
NC
20271 case STT_FUNC:
20272 /* Ignore function symbols. */
20273 continue;
20274
20275 default:
20276 break;
20277 }
20278
20279 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 20280 {
c799a79d
NC
20281 case STB_GLOBAL:
20282 if (saved_sym == NULL
20283 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
20284 saved_sym = sym;
20285 break;
c871dade 20286
c799a79d
NC
20287 case STB_LOCAL:
20288 if (saved_sym == NULL)
20289 saved_sym = sym;
20290 break;
20291
20292 default:
9ef920e9
NC
20293 break;
20294 }
20295 }
c799a79d
NC
20296 else
20297 {
20298 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
20299 continue;
20300
20301 saved_sym = sym;
20302 break;
20303 }
20304 }
20305
6f156d7a 20306 if (saved_sym && pname)
fd486f32 20307 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
20308
20309 return saved_sym;
c799a79d
NC
20310}
20311
d20e98ab
NC
20312/* Returns true iff addr1 and addr2 are in the same section. */
20313
015dc7e1 20314static bool
d20e98ab
NC
20315same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
20316{
20317 Elf_Internal_Shdr * a1;
20318 Elf_Internal_Shdr * a2;
20319
20320 a1 = find_section_by_address (filedata, addr1);
20321 a2 = find_section_by_address (filedata, addr2);
9abca702 20322
d20e98ab
NC
20323 return a1 == a2 && a1 != NULL;
20324}
20325
015dc7e1 20326static bool
dda8d76d
NC
20327print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
20328 Filedata * filedata)
c799a79d 20329{
015dc7e1
AM
20330 static unsigned long global_offset = 0;
20331 static unsigned long global_end = 0;
20332 static unsigned long func_offset = 0;
20333 static unsigned long func_end = 0;
c871dade 20334
015dc7e1
AM
20335 Elf_Internal_Sym *sym;
20336 const char *name;
20337 unsigned long start;
20338 unsigned long end;
20339 bool is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
6f156d7a
NC
20340
20341 switch (pnote->descsz)
c799a79d 20342 {
6f156d7a
NC
20343 case 0:
20344 /* A zero-length description means that the range of
20345 the previous note of the same type should be used. */
c799a79d 20346 if (is_open_attr)
c871dade 20347 {
6f156d7a
NC
20348 if (global_end > global_offset)
20349 printf (_(" Applies to region from %#lx to %#lx\n"),
20350 global_offset, global_end);
20351 else
20352 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
20353 }
20354 else
20355 {
6f156d7a
NC
20356 if (func_end > func_offset)
20357 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
20358 else
20359 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 20360 }
015dc7e1 20361 return true;
9ef920e9 20362
6f156d7a
NC
20363 case 4:
20364 start = byte_get ((unsigned char *) pnote->descdata, 4);
20365 end = 0;
20366 break;
20367
20368 case 8:
c74147bb
NC
20369 start = byte_get ((unsigned char *) pnote->descdata, 4);
20370 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
6f156d7a
NC
20371 break;
20372
20373 case 16:
20374 start = byte_get ((unsigned char *) pnote->descdata, 8);
20375 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
20376 break;
9abca702 20377
6f156d7a 20378 default:
c799a79d
NC
20379 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
20380 printf (_(" <invalid descsz>"));
015dc7e1 20381 return false;
c799a79d
NC
20382 }
20383
6f156d7a
NC
20384 name = NULL;
20385 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
20386 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
20387 in order to avoid them being confused with the start address of the
20388 first function in the file... */
20389 if (sym == NULL && is_open_attr)
20390 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
20391 & name);
6f156d7a
NC
20392
20393 if (end == 0 && sym != NULL && sym->st_size > 0)
20394 end = start + sym->st_size;
c799a79d
NC
20395
20396 if (is_open_attr)
20397 {
d20e98ab
NC
20398 /* FIXME: Need to properly allow for section alignment.
20399 16 is just the alignment used on x86_64. */
20400 if (global_end > 0
20401 && start > BFD_ALIGN (global_end, 16)
20402 /* Build notes are not guaranteed to be organised in order of
20403 increasing address, but we should find the all of the notes
20404 for one section in the same place. */
20405 && same_section (filedata, start, global_end))
6f156d7a
NC
20406 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
20407 global_end + 1, start - 1);
20408
20409 printf (_(" Applies to region from %#lx"), start);
20410 global_offset = start;
20411
20412 if (end)
20413 {
20414 printf (_(" to %#lx"), end);
20415 global_end = end;
20416 }
c799a79d
NC
20417 }
20418 else
20419 {
6f156d7a
NC
20420 printf (_(" Applies to region from %#lx"), start);
20421 func_offset = start;
20422
20423 if (end)
20424 {
20425 printf (_(" to %#lx"), end);
20426 func_end = end;
20427 }
c799a79d
NC
20428 }
20429
6f156d7a
NC
20430 if (sym && name)
20431 printf (_(" (%s)"), name);
20432
20433 printf ("\n");
015dc7e1 20434 return true;
9ef920e9
NC
20435}
20436
015dc7e1 20437static bool
9ef920e9
NC
20438print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
20439{
1d15e434
NC
20440 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
20441 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
20442 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
20443 char name_type;
20444 char name_attribute;
1d15e434 20445 const char * expected_types;
9ef920e9
NC
20446 const char * name = pnote->namedata;
20447 const char * text;
88305e1b 20448 signed int left;
9ef920e9
NC
20449
20450 if (name == NULL || pnote->namesz < 2)
20451 {
20452 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 20453 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20454 return false;
9ef920e9
NC
20455 }
20456
6f156d7a
NC
20457 if (do_wide)
20458 left = 28;
20459 else
20460 left = 20;
88305e1b
NC
20461
20462 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20463 if (name[0] == 'G' && name[1] == 'A')
20464 {
6f156d7a
NC
20465 if (pnote->namesz < 4)
20466 {
20467 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20468 print_symbol (-20, _(" <corrupt name>"));
015dc7e1 20469 return false;
6f156d7a
NC
20470 }
20471
88305e1b
NC
20472 printf ("GA");
20473 name += 2;
20474 left -= 2;
20475 }
20476
9ef920e9
NC
20477 switch ((name_type = * name))
20478 {
20479 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20480 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20481 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20482 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20483 printf ("%c", * name);
88305e1b 20484 left --;
9ef920e9
NC
20485 break;
20486 default:
20487 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20488 print_symbol (-20, _("<unknown name type>"));
015dc7e1 20489 return false;
9ef920e9
NC
20490 }
20491
9ef920e9
NC
20492 ++ name;
20493 text = NULL;
20494
20495 switch ((name_attribute = * name))
20496 {
20497 case GNU_BUILD_ATTRIBUTE_VERSION:
20498 text = _("<version>");
1d15e434 20499 expected_types = string_expected;
9ef920e9
NC
20500 ++ name;
20501 break;
20502 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20503 text = _("<stack prot>");
75d7d298 20504 expected_types = "!+*";
9ef920e9
NC
20505 ++ name;
20506 break;
20507 case GNU_BUILD_ATTRIBUTE_RELRO:
20508 text = _("<relro>");
1d15e434 20509 expected_types = bool_expected;
9ef920e9
NC
20510 ++ name;
20511 break;
20512 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20513 text = _("<stack size>");
1d15e434 20514 expected_types = number_expected;
9ef920e9
NC
20515 ++ name;
20516 break;
20517 case GNU_BUILD_ATTRIBUTE_TOOL:
20518 text = _("<tool>");
1d15e434 20519 expected_types = string_expected;
9ef920e9
NC
20520 ++ name;
20521 break;
20522 case GNU_BUILD_ATTRIBUTE_ABI:
20523 text = _("<ABI>");
20524 expected_types = "$*";
20525 ++ name;
20526 break;
20527 case GNU_BUILD_ATTRIBUTE_PIC:
20528 text = _("<PIC>");
1d15e434 20529 expected_types = number_expected;
9ef920e9
NC
20530 ++ name;
20531 break;
a8be5506
NC
20532 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20533 text = _("<short enum>");
1d15e434 20534 expected_types = bool_expected;
a8be5506
NC
20535 ++ name;
20536 break;
9ef920e9
NC
20537 default:
20538 if (ISPRINT (* name))
20539 {
20540 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20541
20542 if (len > left && ! do_wide)
20543 len = left;
75d7d298 20544 printf ("%.*s:", len, name);
9ef920e9 20545 left -= len;
0dd6ae21 20546 name += len;
9ef920e9
NC
20547 }
20548 else
20549 {
3e6b6445 20550 static char tmpbuf [128];
88305e1b 20551
3e6b6445
NC
20552 error (_("unrecognised byte in name field: %d\n"), * name);
20553 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20554 text = tmpbuf;
20555 name ++;
9ef920e9
NC
20556 }
20557 expected_types = "*$!+";
20558 break;
20559 }
20560
20561 if (text)
88305e1b 20562 left -= printf ("%s", text);
9ef920e9
NC
20563
20564 if (strchr (expected_types, name_type) == NULL)
75d7d298 20565 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20566
20567 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20568 {
20569 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20570 (unsigned long) pnote->namesz,
20571 (long) (name - pnote->namedata));
015dc7e1 20572 return false;
9ef920e9
NC
20573 }
20574
20575 if (left < 1 && ! do_wide)
015dc7e1 20576 return true;
9ef920e9
NC
20577
20578 switch (name_type)
20579 {
20580 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20581 {
b06b2c92 20582 unsigned int bytes;
ddef72cd
NC
20583 unsigned long long val = 0;
20584 unsigned int shift = 0;
20585 char * decoded = NULL;
20586
b06b2c92
NC
20587 bytes = pnote->namesz - (name - pnote->namedata);
20588 if (bytes > 0)
20589 /* The -1 is because the name field is always 0 terminated, and we
20590 want to be able to ensure that the shift in the while loop below
20591 will not overflow. */
20592 -- bytes;
20593
ddef72cd
NC
20594 if (bytes > sizeof (val))
20595 {
3e6b6445
NC
20596 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20597 bytes);
20598 bytes = sizeof (val);
ddef72cd 20599 }
3e6b6445
NC
20600 /* We do not bother to warn if bytes == 0 as this can
20601 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20602
20603 while (bytes --)
20604 {
54b8331d 20605 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20606
20607 val |= byte << shift;
9ef920e9
NC
20608 shift += 8;
20609 }
20610
75d7d298 20611 switch (name_attribute)
9ef920e9 20612 {
75d7d298 20613 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20614 switch (val)
20615 {
75d7d298
NC
20616 case 0: decoded = "static"; break;
20617 case 1: decoded = "pic"; break;
20618 case 2: decoded = "PIC"; break;
20619 case 3: decoded = "pie"; break;
20620 case 4: decoded = "PIE"; break;
20621 default: break;
9ef920e9 20622 }
75d7d298
NC
20623 break;
20624 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20625 switch (val)
9ef920e9 20626 {
75d7d298
NC
20627 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20628 case 0: decoded = "off"; break;
20629 case 1: decoded = "on"; break;
20630 case 2: decoded = "all"; break;
20631 case 3: decoded = "strong"; break;
20632 case 4: decoded = "explicit"; break;
20633 default: break;
9ef920e9 20634 }
75d7d298
NC
20635 break;
20636 default:
20637 break;
9ef920e9
NC
20638 }
20639
75d7d298 20640 if (decoded != NULL)
3e6b6445
NC
20641 {
20642 print_symbol (-left, decoded);
20643 left = 0;
20644 }
20645 else if (val == 0)
20646 {
20647 printf ("0x0");
20648 left -= 3;
20649 }
9ef920e9 20650 else
75d7d298
NC
20651 {
20652 if (do_wide)
ddef72cd 20653 left -= printf ("0x%llx", val);
75d7d298 20654 else
ddef72cd 20655 left -= printf ("0x%-.*llx", left, val);
75d7d298 20656 }
9ef920e9
NC
20657 }
20658 break;
20659 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20660 left -= print_symbol (- left, name);
20661 break;
20662 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20663 left -= print_symbol (- left, "true");
20664 break;
20665 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20666 left -= print_symbol (- left, "false");
20667 break;
20668 }
20669
20670 if (do_wide && left > 0)
20671 printf ("%-*s", left, " ");
9abca702 20672
015dc7e1 20673 return true;
9ef920e9
NC
20674}
20675
6d118b09
NC
20676/* Note that by the ELF standard, the name field is already null byte
20677 terminated, and namesz includes the terminating null byte.
20678 I.E. the value of namesz for the name "FSF" is 4.
20679
e3c8793a 20680 If the value of namesz is zero, there is no name present. */
9ef920e9 20681
015dc7e1 20682static bool
9ef920e9 20683process_note (Elf_Internal_Note * pnote,
dda8d76d 20684 Filedata * filedata)
779fe533 20685{
2cf0635d
NC
20686 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20687 const char * nt;
9437c45b
JT
20688
20689 if (pnote->namesz == 0)
1ec5cd37
NC
20690 /* If there is no note name, then use the default set of
20691 note type strings. */
dda8d76d 20692 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20693
24d127aa 20694 else if (startswith (pnote->namedata, "GNU"))
1118d252
RM
20695 /* GNU-specific object file notes. */
20696 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f 20697
24d127aa 20698 else if (startswith (pnote->namedata, "FreeBSD"))
f4ddf30f 20699 /* FreeBSD-specific core file notes. */
dda8d76d 20700 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20701
24d127aa 20702 else if (startswith (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20703 /* NetBSD-specific core file notes. */
dda8d76d 20704 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20705
24d127aa 20706 else if (startswith (pnote->namedata, "NetBSD"))
c6056a74
SF
20707 /* NetBSD-specific core file notes. */
20708 return process_netbsd_elf_note (pnote);
20709
24d127aa 20710 else if (startswith (pnote->namedata, "PaX"))
9abca702
CZ
20711 /* NetBSD-specific core file notes. */
20712 return process_netbsd_elf_note (pnote);
20713
e9b095a5 20714 else if (startswith (pnote->namedata, "SPU/"))
b15fa79e
AM
20715 {
20716 /* SPU-specific core file notes. */
20717 nt = pnote->namedata + 4;
20718 name = "SPU";
20719 }
20720
24d127aa 20721 else if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7
TG
20722 /* VMS/ia64-specific file notes. */
20723 nt = get_ia64_vms_note_type (pnote->type);
20724
24d127aa 20725 else if (startswith (pnote->namedata, "stapsdt"))
70616151
TT
20726 nt = get_stapsdt_note_type (pnote->type);
20727
9437c45b 20728 else
1ec5cd37
NC
20729 /* Don't recognize this note name; just use the default set of
20730 note type strings. */
dda8d76d 20731 nt = get_note_type (filedata, pnote->type);
9437c45b 20732
1449284b 20733 printf (" ");
9ef920e9 20734
24d127aa 20735 if (((startswith (pnote->namedata, "GA")
483767a3
AM
20736 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20737 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20738 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20739 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20740 print_gnu_build_attribute_name (pnote);
20741 else
20742 print_symbol (-20, name);
20743
20744 if (do_wide)
20745 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20746 else
20747 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7 20748
24d127aa 20749 if (startswith (pnote->namedata, "IPF/VMS"))
00e98fc7 20750 return print_ia64_vms_note (pnote);
24d127aa 20751 else if (startswith (pnote->namedata, "GNU"))
dda8d76d 20752 return print_gnu_note (filedata, pnote);
24d127aa 20753 else if (startswith (pnote->namedata, "stapsdt"))
c6a9fc58 20754 return print_stapsdt_note (pnote);
24d127aa 20755 else if (startswith (pnote->namedata, "CORE"))
9ece1fa9 20756 return print_core_note (pnote);
24d127aa 20757 else if (((startswith (pnote->namedata, "GA")
483767a3
AM
20758 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20759 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20760 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20761 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20762 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20763
9ef920e9 20764 if (pnote->descsz)
1449284b
NC
20765 {
20766 unsigned long i;
20767
20768 printf (_(" description data: "));
20769 for (i = 0; i < pnote->descsz; i++)
178d8719 20770 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20771 if (!do_wide)
20772 printf ("\n");
1449284b
NC
20773 }
20774
9ef920e9
NC
20775 if (do_wide)
20776 printf ("\n");
20777
015dc7e1 20778 return true;
1449284b 20779}
6d118b09 20780
015dc7e1 20781static bool
dda8d76d
NC
20782process_notes_at (Filedata * filedata,
20783 Elf_Internal_Shdr * section,
20784 bfd_vma offset,
82ed9683
L
20785 bfd_vma length,
20786 bfd_vma align)
779fe533 20787{
015dc7e1
AM
20788 Elf_External_Note *pnotes;
20789 Elf_External_Note *external;
20790 char *end;
20791 bool res = true;
103f02d3 20792
779fe533 20793 if (length <= 0)
015dc7e1 20794 return false;
103f02d3 20795
1449284b
NC
20796 if (section)
20797 {
dda8d76d 20798 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20799 if (pnotes)
32ec8896 20800 {
dda8d76d 20801 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20802 {
20803 free (pnotes);
015dc7e1 20804 return false;
f761cb13 20805 }
32ec8896 20806 }
1449284b
NC
20807 }
20808 else
82ed9683 20809 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20810 _("notes"));
4dff97b2 20811
dd24e3da 20812 if (pnotes == NULL)
015dc7e1 20813 return false;
779fe533 20814
103f02d3 20815 external = pnotes;
103f02d3 20816
ca0e11aa
NC
20817 if (filedata->is_separate)
20818 printf (_("In linked file '%s': "), filedata->file_name);
20819 else
20820 printf ("\n");
1449284b 20821 if (section)
ca0e11aa 20822 printf (_("Displaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b 20823 else
ca0e11aa 20824 printf (_("Displaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
1449284b
NC
20825 (unsigned long) offset, (unsigned long) length);
20826
82ed9683
L
20827 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20828 specifies that notes should be aligned to 4 bytes in 32-bit
20829 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20830 we also support 4 byte alignment in 64-bit objects. If section
20831 alignment is less than 4, we treate alignment as 4 bytes. */
20832 if (align < 4)
20833 align = 4;
20834 else if (align != 4 && align != 8)
20835 {
20836 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20837 (long) align);
a788aedd 20838 free (pnotes);
015dc7e1 20839 return false;
82ed9683
L
20840 }
20841
dbe15e4e 20842 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20843
c8071705
NC
20844 end = (char *) pnotes + length;
20845 while ((char *) external < end)
779fe533 20846 {
b34976b6 20847 Elf_Internal_Note inote;
15b42fb0 20848 size_t min_notesz;
4dff97b2 20849 char * next;
2cf0635d 20850 char * temp = NULL;
c8071705 20851 size_t data_remaining = end - (char *) external;
6d118b09 20852
dda8d76d 20853 if (!is_ia64_vms (filedata))
15b42fb0 20854 {
9dd3a467
NC
20855 /* PR binutils/15191
20856 Make sure that there is enough data to read. */
15b42fb0
AM
20857 min_notesz = offsetof (Elf_External_Note, name);
20858 if (data_remaining < min_notesz)
9dd3a467 20859 {
d3a49aa8
AM
20860 warn (ngettext ("Corrupt note: only %ld byte remains, "
20861 "not enough for a full note\n",
20862 "Corrupt note: only %ld bytes remain, "
20863 "not enough for a full note\n",
20864 data_remaining),
20865 (long) data_remaining);
9dd3a467
NC
20866 break;
20867 }
5396a86e
AM
20868 data_remaining -= min_notesz;
20869
15b42fb0
AM
20870 inote.type = BYTE_GET (external->type);
20871 inote.namesz = BYTE_GET (external->namesz);
20872 inote.namedata = external->name;
20873 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20874 inote.descdata = ((char *) external
4dff97b2 20875 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20876 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20877 next = ((char *) external
4dff97b2 20878 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20879 }
00e98fc7 20880 else
15b42fb0
AM
20881 {
20882 Elf64_External_VMS_Note *vms_external;
00e98fc7 20883
9dd3a467
NC
20884 /* PR binutils/15191
20885 Make sure that there is enough data to read. */
15b42fb0
AM
20886 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20887 if (data_remaining < min_notesz)
9dd3a467 20888 {
d3a49aa8
AM
20889 warn (ngettext ("Corrupt note: only %ld byte remains, "
20890 "not enough for a full note\n",
20891 "Corrupt note: only %ld bytes remain, "
20892 "not enough for a full note\n",
20893 data_remaining),
20894 (long) data_remaining);
9dd3a467
NC
20895 break;
20896 }
5396a86e 20897 data_remaining -= min_notesz;
3e55a963 20898
15b42fb0
AM
20899 vms_external = (Elf64_External_VMS_Note *) external;
20900 inote.type = BYTE_GET (vms_external->type);
20901 inote.namesz = BYTE_GET (vms_external->namesz);
20902 inote.namedata = vms_external->name;
20903 inote.descsz = BYTE_GET (vms_external->descsz);
20904 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20905 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20906 next = inote.descdata + align_power (inote.descsz, 3);
20907 }
20908
5396a86e
AM
20909 /* PR 17531: file: 3443835e. */
20910 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20911 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20912 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20913 || (size_t) (next - inote.descdata) < inote.descsz
20914 || ((size_t) (next - inote.descdata)
20915 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20916 {
15b42fb0 20917 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20918 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20919 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20920 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20921 break;
20922 }
20923
15b42fb0 20924 external = (Elf_External_Note *) next;
dd24e3da 20925
6d118b09
NC
20926 /* Verify that name is null terminated. It appears that at least
20927 one version of Linux (RedHat 6.0) generates corefiles that don't
20928 comply with the ELF spec by failing to include the null byte in
20929 namesz. */
18344509 20930 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20931 {
5396a86e 20932 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20933 {
5396a86e
AM
20934 temp = (char *) malloc (inote.namesz + 1);
20935 if (temp == NULL)
20936 {
20937 error (_("Out of memory allocating space for inote name\n"));
015dc7e1 20938 res = false;
5396a86e
AM
20939 break;
20940 }
76da6bbe 20941
5396a86e
AM
20942 memcpy (temp, inote.namedata, inote.namesz);
20943 inote.namedata = temp;
20944 }
20945 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20946 }
20947
dda8d76d 20948 if (! process_note (& inote, filedata))
015dc7e1 20949 res = false;
103f02d3 20950
9db70fc3
AM
20951 free (temp);
20952 temp = NULL;
779fe533
NC
20953 }
20954
20955 free (pnotes);
103f02d3 20956
779fe533
NC
20957 return res;
20958}
20959
015dc7e1 20960static bool
dda8d76d 20961process_corefile_note_segments (Filedata * filedata)
779fe533 20962{
015dc7e1 20963 Elf_Internal_Phdr *segment;
b34976b6 20964 unsigned int i;
015dc7e1 20965 bool res = true;
103f02d3 20966
dda8d76d 20967 if (! get_program_headers (filedata))
015dc7e1 20968 return true;
103f02d3 20969
dda8d76d
NC
20970 for (i = 0, segment = filedata->program_headers;
20971 i < filedata->file_header.e_phnum;
b34976b6 20972 i++, segment++)
779fe533
NC
20973 {
20974 if (segment->p_type == PT_NOTE)
dda8d76d 20975 if (! process_notes_at (filedata, NULL,
32ec8896 20976 (bfd_vma) segment->p_offset,
82ed9683
L
20977 (bfd_vma) segment->p_filesz,
20978 (bfd_vma) segment->p_align))
015dc7e1 20979 res = false;
779fe533 20980 }
103f02d3 20981
779fe533
NC
20982 return res;
20983}
20984
015dc7e1 20985static bool
dda8d76d 20986process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20987{
20988 Elf_External_Note * pnotes;
20989 Elf_External_Note * external;
c8071705 20990 char * end;
015dc7e1 20991 bool res = true;
685080f2
NC
20992
20993 if (length <= 0)
015dc7e1 20994 return false;
685080f2 20995
dda8d76d 20996 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20997 _("v850 notes"));
20998 if (pnotes == NULL)
015dc7e1 20999 return false;
685080f2
NC
21000
21001 external = pnotes;
c8071705 21002 end = (char*) pnotes + length;
685080f2
NC
21003
21004 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
21005 (unsigned long) offset, (unsigned long) length);
21006
c8071705 21007 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
21008 {
21009 Elf_External_Note * next;
21010 Elf_Internal_Note inote;
21011
21012 inote.type = BYTE_GET (external->type);
21013 inote.namesz = BYTE_GET (external->namesz);
21014 inote.namedata = external->name;
21015 inote.descsz = BYTE_GET (external->descsz);
21016 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
21017 inote.descpos = offset + (inote.descdata - (char *) pnotes);
21018
c8071705
NC
21019 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
21020 {
21021 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
21022 inote.descdata = inote.namedata;
21023 inote.namesz = 0;
21024 }
21025
685080f2
NC
21026 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
21027
c8071705 21028 if ( ((char *) next > end)
685080f2
NC
21029 || ((char *) next < (char *) pnotes))
21030 {
21031 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
21032 (unsigned long) ((char *) external - (char *) pnotes));
21033 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21034 inote.type, inote.namesz, inote.descsz);
21035 break;
21036 }
21037
21038 external = next;
21039
21040 /* Prevent out-of-bounds indexing. */
c8071705 21041 if ( inote.namedata + inote.namesz > end
685080f2
NC
21042 || inote.namedata + inote.namesz < inote.namedata)
21043 {
21044 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
21045 (unsigned long) ((char *) external - (char *) pnotes));
21046 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
21047 inote.type, inote.namesz, inote.descsz);
21048 break;
21049 }
21050
21051 printf (" %s: ", get_v850_elf_note_type (inote.type));
21052
21053 if (! print_v850_note (& inote))
21054 {
015dc7e1 21055 res = false;
685080f2
NC
21056 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
21057 inote.namesz, inote.descsz);
21058 }
21059 }
21060
21061 free (pnotes);
21062
21063 return res;
21064}
21065
015dc7e1 21066static bool
dda8d76d 21067process_note_sections (Filedata * filedata)
1ec5cd37 21068{
015dc7e1 21069 Elf_Internal_Shdr *section;
1ec5cd37 21070 unsigned long i;
32ec8896 21071 unsigned int n = 0;
015dc7e1 21072 bool res = true;
1ec5cd37 21073
dda8d76d
NC
21074 for (i = 0, section = filedata->section_headers;
21075 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 21076 i++, section++)
685080f2
NC
21077 {
21078 if (section->sh_type == SHT_NOTE)
21079 {
dda8d76d 21080 if (! process_notes_at (filedata, section,
32ec8896 21081 (bfd_vma) section->sh_offset,
82ed9683
L
21082 (bfd_vma) section->sh_size,
21083 (bfd_vma) section->sh_addralign))
015dc7e1 21084 res = false;
685080f2
NC
21085 n++;
21086 }
21087
dda8d76d
NC
21088 if (( filedata->file_header.e_machine == EM_V800
21089 || filedata->file_header.e_machine == EM_V850
21090 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
21091 && section->sh_type == SHT_RENESAS_INFO)
21092 {
dda8d76d 21093 if (! process_v850_notes (filedata,
32ec8896
NC
21094 (bfd_vma) section->sh_offset,
21095 (bfd_vma) section->sh_size))
015dc7e1 21096 res = false;
685080f2
NC
21097 n++;
21098 }
21099 }
df565f32
NC
21100
21101 if (n == 0)
21102 /* Try processing NOTE segments instead. */
dda8d76d 21103 return process_corefile_note_segments (filedata);
1ec5cd37
NC
21104
21105 return res;
21106}
21107
015dc7e1 21108static bool
dda8d76d 21109process_notes (Filedata * filedata)
779fe533
NC
21110{
21111 /* If we have not been asked to display the notes then do nothing. */
21112 if (! do_notes)
015dc7e1 21113 return true;
103f02d3 21114
dda8d76d
NC
21115 if (filedata->file_header.e_type != ET_CORE)
21116 return process_note_sections (filedata);
103f02d3 21117
779fe533 21118 /* No program headers means no NOTE segment. */
dda8d76d
NC
21119 if (filedata->file_header.e_phnum > 0)
21120 return process_corefile_note_segments (filedata);
779fe533 21121
ca0e11aa
NC
21122 if (filedata->is_separate)
21123 printf (_("No notes found in linked file '%s'.\n"),
21124 filedata->file_name);
21125 else
21126 printf (_("No notes found file.\n"));
21127
015dc7e1 21128 return true;
779fe533
NC
21129}
21130
60abdbed
NC
21131static unsigned char *
21132display_public_gnu_attributes (unsigned char * start,
21133 const unsigned char * const end)
21134{
21135 printf (_(" Unknown GNU attribute: %s\n"), start);
21136
21137 start += strnlen ((char *) start, end - start);
21138 display_raw_attribute (start, end);
21139
21140 return (unsigned char *) end;
21141}
21142
21143static unsigned char *
21144display_generic_attribute (unsigned char * start,
21145 unsigned int tag,
21146 const unsigned char * const end)
21147{
21148 if (tag == 0)
21149 return (unsigned char *) end;
21150
21151 return display_tag_value (tag, start, end);
21152}
21153
015dc7e1 21154static bool
dda8d76d 21155process_arch_specific (Filedata * filedata)
252b5132 21156{
a952a375 21157 if (! do_arch)
015dc7e1 21158 return true;
a952a375 21159
dda8d76d 21160 switch (filedata->file_header.e_machine)
252b5132 21161 {
53a346d8
CZ
21162 case EM_ARC:
21163 case EM_ARC_COMPACT:
21164 case EM_ARC_COMPACT2:
dda8d76d 21165 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
21166 display_arc_attribute,
21167 display_generic_attribute);
11c1ff18 21168 case EM_ARM:
dda8d76d 21169 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
21170 display_arm_attribute,
21171 display_generic_attribute);
21172
252b5132 21173 case EM_MIPS:
4fe85591 21174 case EM_MIPS_RS3_LE:
dda8d76d 21175 return process_mips_specific (filedata);
60abdbed
NC
21176
21177 case EM_MSP430:
dda8d76d 21178 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 21179 display_msp430_attribute,
c0ea7c52 21180 display_msp430_gnu_attribute);
60abdbed 21181
2dc8dd17
JW
21182 case EM_RISCV:
21183 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
21184 display_riscv_attribute,
21185 display_generic_attribute);
21186
35c08157 21187 case EM_NDS32:
dda8d76d 21188 return process_nds32_specific (filedata);
60abdbed 21189
85f7484a
PB
21190 case EM_68K:
21191 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
21192 display_m68k_gnu_attribute);
21193
34c8bcba 21194 case EM_PPC:
b82317dd 21195 case EM_PPC64:
dda8d76d 21196 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21197 display_power_gnu_attribute);
21198
643f7afb
AK
21199 case EM_S390:
21200 case EM_S390_OLD:
dda8d76d 21201 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21202 display_s390_gnu_attribute);
21203
9e8c70f9
DM
21204 case EM_SPARC:
21205 case EM_SPARC32PLUS:
21206 case EM_SPARCV9:
dda8d76d 21207 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
21208 display_sparc_gnu_attribute);
21209
59e6276b 21210 case EM_TI_C6000:
dda8d76d 21211 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
21212 display_tic6x_attribute,
21213 display_generic_attribute);
21214
0861f561
CQ
21215 case EM_CSKY:
21216 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
21217 display_csky_attribute, NULL);
21218
252b5132 21219 default:
dda8d76d 21220 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
21221 display_public_gnu_attributes,
21222 display_generic_attribute);
252b5132 21223 }
252b5132
RH
21224}
21225
015dc7e1 21226static bool
dda8d76d 21227get_file_header (Filedata * filedata)
252b5132 21228{
9ea033b2 21229 /* Read in the identity array. */
dda8d76d 21230 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21231 return false;
252b5132 21232
9ea033b2 21233 /* Determine how to read the rest of the header. */
dda8d76d 21234 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 21235 {
1a0670f3
AM
21236 default:
21237 case ELFDATANONE:
adab8cdc
AO
21238 case ELFDATA2LSB:
21239 byte_get = byte_get_little_endian;
21240 byte_put = byte_put_little_endian;
21241 break;
21242 case ELFDATA2MSB:
21243 byte_get = byte_get_big_endian;
21244 byte_put = byte_put_big_endian;
21245 break;
9ea033b2
NC
21246 }
21247
21248 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 21249 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
21250
21251 /* Read in the rest of the header. */
21252 if (is_32bit_elf)
21253 {
21254 Elf32_External_Ehdr ehdr32;
252b5132 21255
dda8d76d 21256 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21257 return false;
103f02d3 21258
dda8d76d
NC
21259 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
21260 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
21261 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
21262 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
21263 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
21264 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
21265 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
21266 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
21267 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
21268 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
21269 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
21270 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
21271 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 21272 }
252b5132 21273 else
9ea033b2
NC
21274 {
21275 Elf64_External_Ehdr ehdr64;
a952a375
NC
21276
21277 /* If we have been compiled with sizeof (bfd_vma) == 4, then
21278 we will not be able to cope with the 64bit data found in
21279 64 ELF files. Detect this now and abort before we start
50c2245b 21280 overwriting things. */
a952a375
NC
21281 if (sizeof (bfd_vma) < 8)
21282 {
e3c8793a
NC
21283 error (_("This instance of readelf has been built without support for a\n\
2128464 bit data type and so it cannot read 64 bit ELF files.\n"));
015dc7e1 21285 return false;
a952a375 21286 }
103f02d3 21287
dda8d76d 21288 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
015dc7e1 21289 return false;
103f02d3 21290
dda8d76d
NC
21291 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
21292 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
21293 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
21294 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
21295 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
21296 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
21297 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
21298 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
21299 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
21300 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
21301 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
21302 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
21303 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 21304 }
252b5132 21305
015dc7e1 21306 return true;
252b5132
RH
21307}
21308
13acb58d
AM
21309static void
21310free_filedata (Filedata *filedata)
21311{
21312 free (filedata->program_interpreter);
13acb58d 21313 free (filedata->program_headers);
13acb58d 21314 free (filedata->section_headers);
13acb58d 21315 free (filedata->string_table);
13acb58d 21316 free (filedata->dump.dump_sects);
13acb58d 21317 free (filedata->dynamic_strings);
13acb58d 21318 free (filedata->dynamic_symbols);
13acb58d 21319 free (filedata->dynamic_syminfo);
13acb58d 21320 free (filedata->dynamic_section);
13acb58d
AM
21321
21322 while (filedata->symtab_shndx_list != NULL)
21323 {
21324 elf_section_list *next = filedata->symtab_shndx_list->next;
21325 free (filedata->symtab_shndx_list);
21326 filedata->symtab_shndx_list = next;
21327 }
21328
21329 free (filedata->section_headers_groups);
13acb58d
AM
21330
21331 if (filedata->section_groups)
21332 {
21333 size_t i;
21334 struct group_list * g;
21335 struct group_list * next;
21336
21337 for (i = 0; i < filedata->group_count; i++)
21338 {
21339 for (g = filedata->section_groups [i].root; g != NULL; g = next)
21340 {
21341 next = g->next;
21342 free (g);
21343 }
21344 }
21345
21346 free (filedata->section_groups);
13acb58d 21347 }
066f8fbe
AM
21348 memset (&filedata->section_headers, 0,
21349 sizeof (Filedata) - offsetof (Filedata, section_headers));
13acb58d
AM
21350}
21351
dda8d76d
NC
21352static void
21353close_file (Filedata * filedata)
21354{
21355 if (filedata)
21356 {
21357 if (filedata->handle)
21358 fclose (filedata->handle);
21359 free (filedata);
21360 }
21361}
21362
21363void
21364close_debug_file (void * data)
21365{
13acb58d 21366 free_filedata ((Filedata *) data);
dda8d76d
NC
21367 close_file ((Filedata *) data);
21368}
21369
21370static Filedata *
015dc7e1 21371open_file (const char * pathname, bool is_separate)
dda8d76d
NC
21372{
21373 struct stat statbuf;
21374 Filedata * filedata = NULL;
21375
21376 if (stat (pathname, & statbuf) < 0
21377 || ! S_ISREG (statbuf.st_mode))
21378 goto fail;
21379
21380 filedata = calloc (1, sizeof * filedata);
21381 if (filedata == NULL)
21382 goto fail;
21383
21384 filedata->handle = fopen (pathname, "rb");
21385 if (filedata->handle == NULL)
21386 goto fail;
21387
21388 filedata->file_size = (bfd_size_type) statbuf.st_size;
21389 filedata->file_name = pathname;
ca0e11aa 21390 filedata->is_separate = is_separate;
dda8d76d
NC
21391
21392 if (! get_file_header (filedata))
21393 goto fail;
21394
4de91c10
AM
21395 if (!get_section_headers (filedata, false))
21396 goto fail;
dda8d76d
NC
21397
21398 return filedata;
21399
21400 fail:
21401 if (filedata)
21402 {
21403 if (filedata->handle)
21404 fclose (filedata->handle);
21405 free (filedata);
21406 }
21407 return NULL;
21408}
21409
21410void *
21411open_debug_file (const char * pathname)
21412{
015dc7e1 21413 return open_file (pathname, true);
dda8d76d
NC
21414}
21415
835f2fae
NC
21416static void
21417initialise_dump_sects (Filedata * filedata)
21418{
21419 /* Initialise the dump_sects array from the cmdline_dump_sects array.
21420 Note we do this even if cmdline_dump_sects is empty because we
21421 must make sure that the dump_sets array is zeroed out before each
21422 object file is processed. */
21423 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
21424 memset (filedata->dump.dump_sects, 0,
21425 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21426
21427 if (cmdline.num_dump_sects > 0)
21428 {
21429 if (filedata->dump.num_dump_sects == 0)
21430 /* A sneaky way of allocating the dump_sects array. */
21431 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
21432
21433 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
21434 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
21435 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
21436 }
21437}
21438
fb52b2f4
NC
21439/* Process one ELF object file according to the command line options.
21440 This file may actually be stored in an archive. The file is
32ec8896
NC
21441 positioned at the start of the ELF object. Returns TRUE if no
21442 problems were encountered, FALSE otherwise. */
fb52b2f4 21443
015dc7e1 21444static bool
dda8d76d 21445process_object (Filedata * filedata)
252b5132 21446{
015dc7e1 21447 bool have_separate_files;
252b5132 21448 unsigned int i;
015dc7e1 21449 bool res;
252b5132 21450
dda8d76d 21451 if (! get_file_header (filedata))
252b5132 21452 {
dda8d76d 21453 error (_("%s: Failed to read file header\n"), filedata->file_name);
015dc7e1 21454 return false;
252b5132
RH
21455 }
21456
21457 /* Initialise per file variables. */
978c4450
AM
21458 for (i = ARRAY_SIZE (filedata->version_info); i--;)
21459 filedata->version_info[i] = 0;
252b5132 21460
978c4450
AM
21461 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
21462 filedata->dynamic_info[i] = 0;
21463 filedata->dynamic_info_DT_GNU_HASH = 0;
21464 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
21465
21466 /* Process the file. */
21467 if (show_name)
dda8d76d 21468 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 21469
835f2fae 21470 initialise_dump_sects (filedata);
d70c5fc7 21471
4de91c10
AM
21472 /* There may be some extensions in the first section header. Don't
21473 bomb if we can't read it. */
21474 get_section_headers (filedata, true);
21475
dda8d76d 21476 if (! process_file_header (filedata))
4de91c10
AM
21477 {
21478 res = false;
21479 goto out;
21480 }
252b5132 21481
e331b18d
AM
21482 /* Throw away the single section header read above, so that we
21483 re-read the entire set. */
21484 free (filedata->section_headers);
21485 filedata->section_headers = NULL;
21486
dda8d76d 21487 if (! process_section_headers (filedata))
2f62977e 21488 {
32ec8896 21489 /* Without loaded section headers we cannot process lots of things. */
015dc7e1 21490 do_unwind = do_version = do_dump = do_arch = false;
252b5132 21491
2f62977e 21492 if (! do_using_dynamic)
015dc7e1 21493 do_syms = do_dyn_syms = do_reloc = false;
2f62977e 21494 }
252b5132 21495
dda8d76d 21496 if (! process_section_groups (filedata))
32ec8896 21497 /* Without loaded section groups we cannot process unwind. */
015dc7e1 21498 do_unwind = false;
d1f5c6e3 21499
93df3340
AM
21500 process_program_headers (filedata);
21501
21502 res = process_dynamic_section (filedata);
252b5132 21503
dda8d76d 21504 if (! process_relocs (filedata))
015dc7e1 21505 res = false;
252b5132 21506
dda8d76d 21507 if (! process_unwind (filedata))
015dc7e1 21508 res = false;
4d6ed7c8 21509
dda8d76d 21510 if (! process_symbol_table (filedata))
015dc7e1 21511 res = false;
252b5132 21512
0f03783c 21513 if (! process_lto_symbol_tables (filedata))
015dc7e1 21514 res = false;
b9e920ec 21515
dda8d76d 21516 if (! process_syminfo (filedata))
015dc7e1 21517 res = false;
252b5132 21518
dda8d76d 21519 if (! process_version_sections (filedata))
015dc7e1 21520 res = false;
252b5132 21521
82ed9683 21522 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21523 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21524 else
015dc7e1 21525 have_separate_files = false;
dda8d76d
NC
21526
21527 if (! process_section_contents (filedata))
015dc7e1 21528 res = false;
f5842774 21529
24841daa 21530 if (have_separate_files)
dda8d76d 21531 {
24841daa
NC
21532 separate_info * d;
21533
21534 for (d = first_separate_info; d != NULL; d = d->next)
21535 {
835f2fae
NC
21536 initialise_dump_sects (d->handle);
21537
ca0e11aa 21538 if (process_links && ! process_file_header (d->handle))
015dc7e1 21539 res = false;
ca0e11aa 21540 else if (! process_section_headers (d->handle))
015dc7e1 21541 res = false;
d6bfbc39 21542 else if (! process_section_contents (d->handle))
015dc7e1 21543 res = false;
ca0e11aa
NC
21544 else if (process_links)
21545 {
ca0e11aa 21546 if (! process_section_groups (d->handle))
015dc7e1 21547 res = false;
93df3340 21548 process_program_headers (d->handle);
ca0e11aa 21549 if (! process_dynamic_section (d->handle))
015dc7e1 21550 res = false;
ca0e11aa 21551 if (! process_relocs (d->handle))
015dc7e1 21552 res = false;
ca0e11aa 21553 if (! process_unwind (d->handle))
015dc7e1 21554 res = false;
ca0e11aa 21555 if (! process_symbol_table (d->handle))
015dc7e1 21556 res = false;
ca0e11aa 21557 if (! process_lto_symbol_tables (d->handle))
015dc7e1 21558 res = false;
ca0e11aa 21559 if (! process_syminfo (d->handle))
015dc7e1 21560 res = false;
ca0e11aa 21561 if (! process_version_sections (d->handle))
015dc7e1 21562 res = false;
ca0e11aa 21563 if (! process_notes (d->handle))
015dc7e1 21564 res = false;
ca0e11aa 21565 }
24841daa
NC
21566 }
21567
21568 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21569 }
21570
21571 if (! process_notes (filedata))
015dc7e1 21572 res = false;
103f02d3 21573
dda8d76d 21574 if (! process_gnu_liblist (filedata))
015dc7e1 21575 res = false;
047b2264 21576
dda8d76d 21577 if (! process_arch_specific (filedata))
015dc7e1 21578 res = false;
252b5132 21579
4de91c10 21580 out:
13acb58d 21581 free_filedata (filedata);
e4b17d5c 21582
19e6b90e 21583 free_debug_memory ();
18bd398b 21584
32ec8896 21585 return res;
252b5132
RH
21586}
21587
2cf0635d 21588/* Process an ELF archive.
32ec8896
NC
21589 On entry the file is positioned just after the ARMAG string.
21590 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21591
015dc7e1
AM
21592static bool
21593process_archive (Filedata * filedata, bool is_thin_archive)
2cf0635d
NC
21594{
21595 struct archive_info arch;
21596 struct archive_info nested_arch;
21597 size_t got;
015dc7e1 21598 bool ret = true;
2cf0635d 21599
015dc7e1 21600 show_name = true;
2cf0635d
NC
21601
21602 /* The ARCH structure is used to hold information about this archive. */
21603 arch.file_name = NULL;
21604 arch.file = NULL;
21605 arch.index_array = NULL;
21606 arch.sym_table = NULL;
21607 arch.longnames = NULL;
21608
21609 /* The NESTED_ARCH structure is used as a single-item cache of information
21610 about a nested archive (when members of a thin archive reside within
21611 another regular archive file). */
21612 nested_arch.file_name = NULL;
21613 nested_arch.file = NULL;
21614 nested_arch.index_array = NULL;
21615 nested_arch.sym_table = NULL;
21616 nested_arch.longnames = NULL;
21617
dda8d76d 21618 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21619 filedata->file_size, is_thin_archive,
21620 do_archive_index) != 0)
2cf0635d 21621 {
015dc7e1 21622 ret = false;
2cf0635d 21623 goto out;
4145f1d5 21624 }
fb52b2f4 21625
4145f1d5
NC
21626 if (do_archive_index)
21627 {
2cf0635d 21628 if (arch.sym_table == NULL)
1cb7d8b1
AM
21629 error (_("%s: unable to dump the index as none was found\n"),
21630 filedata->file_name);
4145f1d5
NC
21631 else
21632 {
591f7597 21633 unsigned long i, l;
4145f1d5
NC
21634 unsigned long current_pos;
21635
1cb7d8b1
AM
21636 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21637 "in the symbol table)\n"),
21638 filedata->file_name, (unsigned long) arch.index_num,
21639 arch.sym_size);
dda8d76d
NC
21640
21641 current_pos = ftell (filedata->handle);
4145f1d5 21642
2cf0635d 21643 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21644 {
1cb7d8b1
AM
21645 if (i == 0
21646 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21647 {
21648 char * member_name
21649 = get_archive_member_name_at (&arch, arch.index_array[i],
21650 &nested_arch);
2cf0635d 21651
1cb7d8b1
AM
21652 if (member_name != NULL)
21653 {
21654 char * qualified_name
21655 = make_qualified_name (&arch, &nested_arch,
21656 member_name);
2cf0635d 21657
1cb7d8b1
AM
21658 if (qualified_name != NULL)
21659 {
21660 printf (_("Contents of binary %s at offset "),
21661 qualified_name);
c2a7d3f5
NC
21662 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21663 putchar ('\n');
1cb7d8b1
AM
21664 free (qualified_name);
21665 }
fd486f32 21666 free (member_name);
4145f1d5
NC
21667 }
21668 }
2cf0635d
NC
21669
21670 if (l >= arch.sym_size)
4145f1d5 21671 {
1cb7d8b1
AM
21672 error (_("%s: end of the symbol table reached "
21673 "before the end of the index\n"),
dda8d76d 21674 filedata->file_name);
015dc7e1 21675 ret = false;
cb8f3167 21676 break;
4145f1d5 21677 }
591f7597 21678 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21679 printf ("\t%.*s\n",
21680 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21681 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21682 }
21683
67ce483b 21684 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21685 l = (l + 7) & ~ 7;
21686 else
21687 l += l & 1;
21688
2cf0635d 21689 if (l < arch.sym_size)
32ec8896 21690 {
d3a49aa8
AM
21691 error (ngettext ("%s: %ld byte remains in the symbol table, "
21692 "but without corresponding entries in "
21693 "the index table\n",
21694 "%s: %ld bytes remain in the symbol table, "
21695 "but without corresponding entries in "
21696 "the index table\n",
21697 arch.sym_size - l),
dda8d76d 21698 filedata->file_name, arch.sym_size - l);
015dc7e1 21699 ret = false;
32ec8896 21700 }
4145f1d5 21701
dda8d76d 21702 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21703 {
1cb7d8b1
AM
21704 error (_("%s: failed to seek back to start of object files "
21705 "in the archive\n"),
dda8d76d 21706 filedata->file_name);
015dc7e1 21707 ret = false;
2cf0635d 21708 goto out;
4145f1d5 21709 }
fb52b2f4 21710 }
4145f1d5
NC
21711
21712 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21713 && !do_segments && !do_header && !do_dump && !do_version
21714 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21715 && !do_section_groups && !do_dyn_syms)
2cf0635d 21716 {
015dc7e1 21717 ret = true; /* Archive index only. */
2cf0635d
NC
21718 goto out;
21719 }
fb52b2f4
NC
21720 }
21721
fb52b2f4
NC
21722 while (1)
21723 {
2cf0635d
NC
21724 char * name;
21725 size_t namelen;
21726 char * qualified_name;
21727
21728 /* Read the next archive header. */
dda8d76d 21729 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21730 {
21731 error (_("%s: failed to seek to next archive header\n"),
21732 arch.file_name);
015dc7e1 21733 ret = false;
1cb7d8b1
AM
21734 break;
21735 }
dda8d76d 21736 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21737 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21738 {
21739 if (got == 0)
2cf0635d 21740 break;
28e817cc
NC
21741 /* PR 24049 - we cannot use filedata->file_name as this will
21742 have already been freed. */
21743 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21744
015dc7e1 21745 ret = false;
1cb7d8b1
AM
21746 break;
21747 }
2cf0635d 21748 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21749 {
21750 error (_("%s: did not find a valid archive header\n"),
21751 arch.file_name);
015dc7e1 21752 ret = false;
1cb7d8b1
AM
21753 break;
21754 }
2cf0635d
NC
21755
21756 arch.next_arhdr_offset += sizeof arch.arhdr;
21757
978c4450
AM
21758 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21759 if (filedata->archive_file_size & 01)
21760 ++filedata->archive_file_size;
2cf0635d
NC
21761
21762 name = get_archive_member_name (&arch, &nested_arch);
21763 if (name == NULL)
fb52b2f4 21764 {
28e817cc 21765 error (_("%s: bad archive file name\n"), arch.file_name);
015dc7e1 21766 ret = false;
d989285c 21767 break;
fb52b2f4 21768 }
2cf0635d 21769 namelen = strlen (name);
fb52b2f4 21770
2cf0635d
NC
21771 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21772 if (qualified_name == NULL)
fb52b2f4 21773 {
28e817cc 21774 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21775 free (name);
015dc7e1 21776 ret = false;
d989285c 21777 break;
fb52b2f4
NC
21778 }
21779
2cf0635d 21780 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21781 {
21782 /* This is a proxy for an external member of a thin archive. */
21783 Filedata * member_filedata;
21784 char * member_file_name = adjust_relative_path
dda8d76d 21785 (filedata->file_name, name, namelen);
32ec8896 21786
fd486f32 21787 free (name);
1cb7d8b1
AM
21788 if (member_file_name == NULL)
21789 {
fd486f32 21790 free (qualified_name);
015dc7e1 21791 ret = false;
1cb7d8b1
AM
21792 break;
21793 }
2cf0635d 21794
015dc7e1 21795 member_filedata = open_file (member_file_name, false);
1cb7d8b1
AM
21796 if (member_filedata == NULL)
21797 {
21798 error (_("Input file '%s' is not readable.\n"), member_file_name);
21799 free (member_file_name);
fd486f32 21800 free (qualified_name);
015dc7e1 21801 ret = false;
1cb7d8b1
AM
21802 break;
21803 }
2cf0635d 21804
978c4450 21805 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21806 member_filedata->file_name = qualified_name;
2cf0635d 21807
75a2da57
AH
21808 /* The call to process_object() expects the file to be at the beginning. */
21809 rewind (member_filedata->handle);
21810
1cb7d8b1 21811 if (! process_object (member_filedata))
015dc7e1 21812 ret = false;
2cf0635d 21813
1cb7d8b1
AM
21814 close_file (member_filedata);
21815 free (member_file_name);
1cb7d8b1 21816 }
2cf0635d 21817 else if (is_thin_archive)
1cb7d8b1
AM
21818 {
21819 Filedata thin_filedata;
eb02c04d 21820
1cb7d8b1 21821 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21822
a043396b
NC
21823 /* PR 15140: Allow for corrupt thin archives. */
21824 if (nested_arch.file == NULL)
21825 {
21826 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21827 qualified_name, name);
fd486f32
AM
21828 free (qualified_name);
21829 free (name);
015dc7e1 21830 ret = false;
a043396b
NC
21831 break;
21832 }
fd486f32 21833 free (name);
a043396b 21834
1cb7d8b1 21835 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21836 filedata->archive_file_offset
21837 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21838
1cb7d8b1
AM
21839 /* The nested archive file will have been opened and setup by
21840 get_archive_member_name. */
978c4450
AM
21841 if (fseek (nested_arch.file, filedata->archive_file_offset,
21842 SEEK_SET) != 0)
1cb7d8b1
AM
21843 {
21844 error (_("%s: failed to seek to archive member.\n"),
21845 nested_arch.file_name);
fd486f32 21846 free (qualified_name);
015dc7e1 21847 ret = false;
1cb7d8b1
AM
21848 break;
21849 }
2cf0635d 21850
dda8d76d
NC
21851 thin_filedata.handle = nested_arch.file;
21852 thin_filedata.file_name = qualified_name;
9abca702 21853
1cb7d8b1 21854 if (! process_object (& thin_filedata))
015dc7e1 21855 ret = false;
1cb7d8b1 21856 }
2cf0635d 21857 else
1cb7d8b1 21858 {
fd486f32 21859 free (name);
978c4450 21860 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21861 filedata->file_name = qualified_name;
1cb7d8b1 21862 if (! process_object (filedata))
015dc7e1 21863 ret = false;
978c4450 21864 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21865 /* Stop looping with "negative" archive_file_size. */
978c4450 21866 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21867 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21868 }
fb52b2f4 21869
2cf0635d 21870 free (qualified_name);
fb52b2f4
NC
21871 }
21872
4145f1d5 21873 out:
2cf0635d
NC
21874 if (nested_arch.file != NULL)
21875 fclose (nested_arch.file);
21876 release_archive (&nested_arch);
21877 release_archive (&arch);
fb52b2f4 21878
d989285c 21879 return ret;
fb52b2f4
NC
21880}
21881
015dc7e1 21882static bool
2cf0635d 21883process_file (char * file_name)
fb52b2f4 21884{
dda8d76d 21885 Filedata * filedata = NULL;
fb52b2f4
NC
21886 struct stat statbuf;
21887 char armag[SARMAG];
015dc7e1 21888 bool ret = true;
fb52b2f4
NC
21889
21890 if (stat (file_name, &statbuf) < 0)
21891 {
f24ddbdd
NC
21892 if (errno == ENOENT)
21893 error (_("'%s': No such file\n"), file_name);
21894 else
21895 error (_("Could not locate '%s'. System error message: %s\n"),
21896 file_name, strerror (errno));
015dc7e1 21897 return false;
f24ddbdd
NC
21898 }
21899
21900 if (! S_ISREG (statbuf.st_mode))
21901 {
21902 error (_("'%s' is not an ordinary file\n"), file_name);
015dc7e1 21903 return false;
fb52b2f4
NC
21904 }
21905
dda8d76d
NC
21906 filedata = calloc (1, sizeof * filedata);
21907 if (filedata == NULL)
21908 {
21909 error (_("Out of memory allocating file data structure\n"));
015dc7e1 21910 return false;
dda8d76d
NC
21911 }
21912
21913 filedata->file_name = file_name;
21914 filedata->handle = fopen (file_name, "rb");
21915 if (filedata->handle == NULL)
fb52b2f4 21916 {
f24ddbdd 21917 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21918 free (filedata);
015dc7e1 21919 return false;
fb52b2f4
NC
21920 }
21921
dda8d76d 21922 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21923 {
4145f1d5 21924 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21925 fclose (filedata->handle);
21926 free (filedata);
015dc7e1 21927 return false;
fb52b2f4
NC
21928 }
21929
dda8d76d 21930 filedata->file_size = (bfd_size_type) statbuf.st_size;
015dc7e1 21931 filedata->is_separate = false;
f54498b4 21932
fb52b2f4 21933 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21934 {
015dc7e1
AM
21935 if (! process_archive (filedata, false))
21936 ret = false;
32ec8896 21937 }
2cf0635d 21938 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21939 {
015dc7e1
AM
21940 if ( ! process_archive (filedata, true))
21941 ret = false;
32ec8896 21942 }
fb52b2f4
NC
21943 else
21944 {
1b513401 21945 if (do_archive_index && !check_all)
4145f1d5
NC
21946 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21947 file_name);
21948
dda8d76d 21949 rewind (filedata->handle);
978c4450 21950 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21951
dda8d76d 21952 if (! process_object (filedata))
015dc7e1 21953 ret = false;
fb52b2f4
NC
21954 }
21955
dda8d76d 21956 fclose (filedata->handle);
8fb879cd
AM
21957 free (filedata->section_headers);
21958 free (filedata->program_headers);
21959 free (filedata->string_table);
6431e409 21960 free (filedata->dump.dump_sects);
dda8d76d 21961 free (filedata);
32ec8896 21962
fd486f32 21963 free (ba_cache.strtab);
1bd6175a 21964 ba_cache.strtab = NULL;
fd486f32 21965 free (ba_cache.symtab);
1bd6175a 21966 ba_cache.symtab = NULL;
fd486f32
AM
21967 ba_cache.filedata = NULL;
21968
fb52b2f4
NC
21969 return ret;
21970}
21971
252b5132
RH
21972#ifdef SUPPORT_DISASSEMBLY
21973/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21974 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21975 symbols. */
252b5132
RH
21976
21977void
2cf0635d 21978print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21979{
21980 fprintf (outfile,"0x%8.8x", addr);
21981}
21982
e3c8793a 21983/* Needed by the i386 disassembler. */
dda8d76d 21984
252b5132
RH
21985void
21986db_task_printsym (unsigned int addr)
21987{
21988 print_address (addr, stderr);
21989}
21990#endif
21991
21992int
2cf0635d 21993main (int argc, char ** argv)
252b5132 21994{
ff78d6d6
L
21995 int err;
21996
87b9f255 21997#ifdef HAVE_LC_MESSAGES
252b5132 21998 setlocale (LC_MESSAGES, "");
3882b010 21999#endif
3882b010 22000 setlocale (LC_CTYPE, "");
252b5132
RH
22001 bindtextdomain (PACKAGE, LOCALEDIR);
22002 textdomain (PACKAGE);
22003
869b9d07
MM
22004 expandargv (&argc, &argv);
22005
dda8d76d 22006 parse_args (& cmdline, argc, argv);
59f14fc0 22007
18bd398b 22008 if (optind < (argc - 1))
1b513401
NC
22009 /* When displaying information for more than one file,
22010 prefix the information with the file name. */
015dc7e1 22011 show_name = true;
5656ba2c
L
22012 else if (optind >= argc)
22013 {
1b513401 22014 /* Ensure that the warning is always displayed. */
015dc7e1 22015 do_checks = true;
1b513401 22016
5656ba2c
L
22017 warn (_("Nothing to do.\n"));
22018 usage (stderr);
22019 }
18bd398b 22020
015dc7e1 22021 err = false;
252b5132 22022 while (optind < argc)
32ec8896 22023 if (! process_file (argv[optind++]))
015dc7e1 22024 err = true;
252b5132 22025
9db70fc3 22026 free (cmdline.dump_sects);
252b5132 22027
7d9813f1
NA
22028 free (dump_ctf_symtab_name);
22029 free (dump_ctf_strtab_name);
22030 free (dump_ctf_parent_name);
22031
32ec8896 22032 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 22033}