]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - binutils/readelf.c
gdb/fortran: support ALLOCATED builtin
[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>
3bfcb652 47#ifdef HAVE_WCHAR_H
7bfd842d 48#include <wchar.h>
3bfcb652 49#endif
252b5132 50
a952a375 51#if __GNUC__ >= 2
19936277 52/* Define BFD64 here, even if our default architecture is 32 bit ELF
a952a375 53 as this will allow us to read in and parse 64bit and 32bit ELF files.
b34976b6 54 Only do this if we believe that the compiler can support a 64 bit
a952a375 55 data type. For now we only rely on GCC being able to do this. */
19936277 56#define BFD64
a952a375
NC
57#endif
58
3db64b00
AM
59#include "bfd.h"
60#include "bucomm.h"
3284fe0c 61#include "elfcomm.h"
19e6b90e 62#include "dwarf.h"
7d9813f1 63#include "ctf-api.h"
79bc120c 64#include "demangle.h"
252b5132
RH
65
66#include "elf/common.h"
67#include "elf/external.h"
68#include "elf/internal.h"
252b5132 69
4b78141a
NC
70
71/* Included here, before RELOC_MACROS_GEN_FUNC is defined, so that
72 we can obtain the H8 reloc numbers. We need these for the
73 get_reloc_size() function. We include h8.h again after defining
74 RELOC_MACROS_GEN_FUNC so that we get the naming function as well. */
75
76#include "elf/h8.h"
77#undef _ELF_H8_H
78
79/* Undo the effects of #including reloc-macros.h. */
80
81#undef START_RELOC_NUMBERS
82#undef RELOC_NUMBER
83#undef FAKE_RELOC
84#undef EMPTY_RELOC
85#undef END_RELOC_NUMBERS
86#undef _RELOC_MACROS_H
87
252b5132
RH
88/* The following headers use the elf/reloc-macros.h file to
89 automatically generate relocation recognition functions
90 such as elf_mips_reloc_type() */
91
92#define RELOC_MACROS_GEN_FUNC
93
a06ea964 94#include "elf/aarch64.h"
252b5132 95#include "elf/alpha.h"
3b16e843 96#include "elf/arc.h"
252b5132 97#include "elf/arm.h"
3b16e843 98#include "elf/avr.h"
1d65ded4 99#include "elf/bfin.h"
60bca95a 100#include "elf/cr16.h"
3b16e843 101#include "elf/cris.h"
1c0d3aa6 102#include "elf/crx.h"
b8891f8d 103#include "elf/csky.h"
252b5132
RH
104#include "elf/d10v.h"
105#include "elf/d30v.h"
d172d4ba 106#include "elf/dlx.h"
aca4efc7 107#include "elf/bpf.h"
cfb8c092 108#include "elf/epiphany.h"
252b5132 109#include "elf/fr30.h"
5c70f934 110#include "elf/frv.h"
3f8107ab 111#include "elf/ft32.h"
3b16e843
NC
112#include "elf/h8.h"
113#include "elf/hppa.h"
114#include "elf/i386.h"
f954747f
AM
115#include "elf/i370.h"
116#include "elf/i860.h"
117#include "elf/i960.h"
3b16e843 118#include "elf/ia64.h"
1e4cf259 119#include "elf/ip2k.h"
84e94c90 120#include "elf/lm32.h"
1c0d3aa6 121#include "elf/iq2000.h"
49f58d10 122#include "elf/m32c.h"
3b16e843
NC
123#include "elf/m32r.h"
124#include "elf/m68k.h"
75751cd9 125#include "elf/m68hc11.h"
7b4ae824 126#include "elf/s12z.h"
252b5132 127#include "elf/mcore.h"
15ab5209 128#include "elf/mep.h"
a3c62988 129#include "elf/metag.h"
7ba29e2a 130#include "elf/microblaze.h"
3b16e843 131#include "elf/mips.h"
3c3bdf30 132#include "elf/mmix.h"
3b16e843
NC
133#include "elf/mn10200.h"
134#include "elf/mn10300.h"
5506d11a 135#include "elf/moxie.h"
4970f871 136#include "elf/mt.h"
2469cfa2 137#include "elf/msp430.h"
35c08157 138#include "elf/nds32.h"
fe944acf 139#include "elf/nfp.h"
13761a11 140#include "elf/nios2.h"
73589c9d 141#include "elf/or1k.h"
7d466069 142#include "elf/pj.h"
3b16e843 143#include "elf/ppc.h"
c833c019 144#include "elf/ppc64.h"
2b100bb5 145#include "elf/pru.h"
03336641 146#include "elf/riscv.h"
99c513f6 147#include "elf/rl78.h"
c7927a3c 148#include "elf/rx.h"
a85d7ed0 149#include "elf/s390.h"
1c0d3aa6 150#include "elf/score.h"
3b16e843
NC
151#include "elf/sh.h"
152#include "elf/sparc.h"
e9f53129 153#include "elf/spu.h"
40b36596 154#include "elf/tic6x.h"
aa137e4d
NC
155#include "elf/tilegx.h"
156#include "elf/tilepro.h"
3b16e843 157#include "elf/v850.h"
179d3252 158#include "elf/vax.h"
619ed720 159#include "elf/visium.h"
f96bd6c2 160#include "elf/wasm32.h"
3b16e843 161#include "elf/x86-64.h"
c29aca4a 162#include "elf/xc16x.h"
f6c1a2d5 163#include "elf/xgate.h"
93fbbb04 164#include "elf/xstormy16.h"
88da6820 165#include "elf/xtensa.h"
6655dba2 166#include "elf/z80.h"
252b5132 167
252b5132 168#include "getopt.h"
566b0d53 169#include "libiberty.h"
09c11c86 170#include "safe-ctype.h"
2cf0635d 171#include "filenames.h"
252b5132 172
15b42fb0
AM
173#ifndef offsetof
174#define offsetof(TYPE, MEMBER) ((size_t) &(((TYPE *) 0)->MEMBER))
175#endif
176
6a40cf0c
NC
177typedef struct elf_section_list
178{
dda8d76d
NC
179 Elf_Internal_Shdr * hdr;
180 struct elf_section_list * next;
6a40cf0c
NC
181} elf_section_list;
182
dda8d76d
NC
183/* Flag bits indicating particular types of dump. */
184#define HEX_DUMP (1 << 0) /* The -x command line switch. */
185#define DISASS_DUMP (1 << 1) /* The -i command line switch. */
186#define DEBUG_DUMP (1 << 2) /* The -w command line switch. */
187#define STRING_DUMP (1 << 3) /* The -p command line switch. */
188#define RELOC_DUMP (1 << 4) /* The -R command line switch. */
d344b407 189#define CTF_DUMP (1 << 5) /* The --ctf command line switch. */
dda8d76d
NC
190
191typedef unsigned char dump_type;
192
193/* A linked list of the section names for which dumps were requested. */
194struct dump_list_entry
195{
196 char * name;
197 dump_type type;
198 struct dump_list_entry * next;
199};
200
6431e409
AM
201/* A dynamic array of flags indicating for which sections a dump
202 has been requested via command line switches. */
1b513401
NC
203struct dump_data
204{
6431e409
AM
205 dump_type * dump_sects;
206 unsigned int num_dump_sects;
207};
208
209static struct dump_data cmdline;
210
211static struct dump_list_entry * dump_sects_byname;
212
2cf0635d 213char * program_name = "readelf";
dda8d76d 214
32ec8896
NC
215static bfd_boolean show_name = FALSE;
216static bfd_boolean do_dynamic = FALSE;
217static bfd_boolean do_syms = FALSE;
218static bfd_boolean do_dyn_syms = FALSE;
0f03783c 219static bfd_boolean do_lto_syms = FALSE;
32ec8896
NC
220static bfd_boolean do_reloc = FALSE;
221static bfd_boolean do_sections = FALSE;
222static bfd_boolean do_section_groups = FALSE;
223static bfd_boolean do_section_details = FALSE;
224static bfd_boolean do_segments = FALSE;
225static bfd_boolean do_unwind = FALSE;
226static bfd_boolean do_using_dynamic = FALSE;
227static bfd_boolean do_header = FALSE;
228static bfd_boolean do_dump = FALSE;
229static bfd_boolean do_version = FALSE;
230static bfd_boolean do_histogram = FALSE;
231static bfd_boolean do_debugging = FALSE;
7d9813f1 232static bfd_boolean do_ctf = FALSE;
32ec8896
NC
233static bfd_boolean do_arch = FALSE;
234static bfd_boolean do_notes = FALSE;
235static bfd_boolean do_archive_index = FALSE;
1b513401 236static bfd_boolean check_all = FALSE;
32ec8896
NC
237static bfd_boolean is_32bit_elf = FALSE;
238static bfd_boolean decompress_dumps = FALSE;
0942c7ab 239static bfd_boolean do_not_show_symbol_truncation = FALSE;
79bc120c
NC
240static bfd_boolean do_demangle = FALSE; /* Pretty print C++ symbol names. */
241static int demangle_flags = DMGL_ANSI | DMGL_PARAMS;
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;
262 FILE * handle;
263 bfd_size_type file_size;
264 Elf_Internal_Ehdr file_header;
265 Elf_Internal_Shdr * section_headers;
266 Elf_Internal_Phdr * program_headers;
267 char * string_table;
268 unsigned long string_table_length;
269 unsigned long archive_file_offset;
270 unsigned long archive_file_size;
271 unsigned long dynamic_addr;
272 bfd_size_type dynamic_size;
273 size_t dynamic_nent;
274 Elf_Internal_Dyn * dynamic_section;
8ac10c5b 275 Elf_Internal_Shdr * dynamic_strtab_section;
978c4450
AM
276 char * dynamic_strings;
277 unsigned long dynamic_strings_length;
8ac10c5b 278 Elf_Internal_Shdr * dynamic_symtab_section;
978c4450
AM
279 unsigned long num_dynamic_syms;
280 Elf_Internal_Sym * dynamic_symbols;
281 bfd_vma version_info[16];
282 unsigned int dynamic_syminfo_nent;
283 Elf_Internal_Syminfo * dynamic_syminfo;
284 unsigned long dynamic_syminfo_offset;
285 bfd_size_type nbuckets;
286 bfd_size_type nchains;
287 bfd_vma * buckets;
288 bfd_vma * chains;
289 bfd_size_type ngnubuckets;
290 bfd_size_type ngnuchains;
291 bfd_vma * gnubuckets;
292 bfd_vma * gnuchains;
293 bfd_vma * mipsxlat;
294 bfd_vma gnusymidx;
295 char program_interpreter[PATH_MAX];
296 bfd_vma dynamic_info[DT_ENCODING];
297 bfd_vma dynamic_info_DT_GNU_HASH;
298 bfd_vma dynamic_info_DT_MIPS_XHASH;
299 elf_section_list * symtab_shndx_list;
300 size_t group_count;
301 struct group * section_groups;
302 struct group ** section_headers_groups;
303 /* A dynamic array of flags indicating for which sections a dump of
304 some kind has been requested. It is reset on a per-object file
305 basis and then initialised from the cmdline_dump_sects array,
306 the results of interpreting the -w switch, and the
307 dump_sects_byname list. */
308 struct dump_data dump;
309} Filedata;
aef1f6d0 310
c256ffe7 311/* How to print a vma value. */
843dd992
NC
312typedef enum print_mode
313{
314 HEX,
315 DEC,
316 DEC_5,
317 UNSIGNED,
318 PREFIX_HEX,
319 FULL_HEX,
320 LONG_HEX
321}
322print_mode;
323
bb4d2ac2
L
324/* Versioned symbol info. */
325enum versioned_symbol_info
326{
327 symbol_undefined,
328 symbol_hidden,
329 symbol_public
330};
331
32ec8896 332static const char * get_symbol_version_string
dda8d76d 333 (Filedata *, bfd_boolean, const char *, unsigned long, unsigned,
32ec8896 334 Elf_Internal_Sym *, enum versioned_symbol_info *, unsigned short *);
bb4d2ac2 335
9c19a809
NC
336#define UNKNOWN -1
337
b9e920ec
AM
338#define SECTION_NAME(X) \
339 (filedata->string_table + (X)->sh_name)
340
341#define SECTION_NAME_VALID(X) \
342 ((X) != NULL \
343 && filedata->string_table != NULL \
344 && (X)->sh_name < filedata->string_table_length)
345
346#define SECTION_NAME_PRINT(X) \
347 ((X) == NULL ? _("<none>") \
348 : filedata->string_table == NULL ? _("<no-strings>") \
349 : (X)->sh_name >= filedata->string_table_length ? _("<corrupt>") \
350 : filedata->string_table + (X)->sh_name)
252b5132 351
ee42cf8c 352#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
252b5132 353
ba5cdace
NC
354#define GET_ELF_SYMBOLS(file, section, sym_count) \
355 (is_32bit_elf ? get_32bit_elf_symbols (file, section, sym_count) \
356 : get_64bit_elf_symbols (file, section, sym_count))
9ea033b2 357
10ca4b04
L
358#define VALID_SYMBOL_NAME(strtab, strtab_size, offset) \
359 (strtab != NULL && offset < strtab_size)
978c4450
AM
360#define VALID_DYNAMIC_NAME(filedata, offset) \
361 VALID_SYMBOL_NAME (filedata->dynamic_strings, \
362 filedata->dynamic_strings_length, offset)
d79b3d50
NC
363/* GET_DYNAMIC_NAME asssumes that VALID_DYNAMIC_NAME has
364 already been called and verified that the string exists. */
978c4450
AM
365#define GET_DYNAMIC_NAME(filedata, offset) \
366 (filedata->dynamic_strings + offset)
18bd398b 367
61865e30
NC
368#define REMOVE_ARCH_BITS(ADDR) \
369 do \
370 { \
dda8d76d 371 if (filedata->file_header.e_machine == EM_ARM) \
61865e30
NC
372 (ADDR) &= ~1; \
373 } \
374 while (0)
f16a9783
MS
375
376/* Get the correct GNU hash section name. */
978c4450
AM
377#define GNU_HASH_SECTION_NAME(filedata) \
378 filedata->dynamic_info_DT_MIPS_XHASH ? ".MIPS.xhash" : ".gnu.hash"
d79b3d50 379\f
66cfc0fd
AM
380/* Print a BFD_VMA to an internal buffer, for use in error messages.
381 BFD_FMA_FMT can't be used in translated strings. */
382
383static const char *
384bfd_vmatoa (char *fmtch, bfd_vma value)
385{
386 /* bfd_vmatoa is used more then once in a printf call for output.
387 Cycle through an array of buffers. */
388 static int buf_pos = 0;
389 static struct bfd_vmatoa_buf
390 {
391 char place[64];
392 } buf[4];
393 char *ret;
394 char fmt[32];
395
396 ret = buf[buf_pos++].place;
397 buf_pos %= ARRAY_SIZE (buf);
398
399 sprintf (fmt, "%%%s%s", BFD_VMA_FMT, fmtch);
400 snprintf (ret, sizeof (buf[0].place), fmt, value);
401 return ret;
402}
403
dda8d76d
NC
404/* Retrieve NMEMB structures, each SIZE bytes long from FILEDATA starting at
405 OFFSET + the offset of the current archive member, if we are examining an
406 archive. Put the retrieved data into VAR, if it is not NULL. Otherwise
407 allocate a buffer using malloc and fill that. In either case return the
408 pointer to the start of the retrieved data or NULL if something went wrong.
409 If something does go wrong and REASON is not NULL then emit an error
410 message using REASON as part of the context. */
59245841 411
c256ffe7 412static void *
dda8d76d
NC
413get_data (void * var,
414 Filedata * filedata,
415 unsigned long offset,
416 bfd_size_type size,
417 bfd_size_type nmemb,
418 const char * reason)
a6e9f9df 419{
2cf0635d 420 void * mvar;
57028622 421 bfd_size_type amt = size * nmemb;
a6e9f9df 422
c256ffe7 423 if (size == 0 || nmemb == 0)
a6e9f9df
AM
424 return NULL;
425
57028622
NC
426 /* If the size_t type is smaller than the bfd_size_type, eg because
427 you are building a 32-bit tool on a 64-bit host, then make sure
428 that when the sizes are cast to (size_t) no information is lost. */
7c1c1904
AM
429 if ((size_t) size != size
430 || (size_t) nmemb != nmemb
431 || (size_t) amt != amt)
57028622
NC
432 {
433 if (reason)
66cfc0fd
AM
434 error (_("Size truncation prevents reading %s"
435 " elements of size %s for %s\n"),
436 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
437 return NULL;
438 }
439
440 /* Check for size overflow. */
7c1c1904 441 if (amt / size != nmemb || (size_t) amt + 1 == 0)
57028622
NC
442 {
443 if (reason)
66cfc0fd
AM
444 error (_("Size overflow prevents reading %s"
445 " elements of size %s for %s\n"),
446 bfd_vmatoa ("u", nmemb), bfd_vmatoa ("u", size), reason);
57028622
NC
447 return NULL;
448 }
449
c22b42ce 450 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
c9c1d674 451 attempting to allocate memory when the read is bound to fail. */
978c4450
AM
452 if (filedata->archive_file_offset > filedata->file_size
453 || offset > filedata->file_size - filedata->archive_file_offset
454 || amt > filedata->file_size - filedata->archive_file_offset - offset)
a6e9f9df 455 {
049b0c3a 456 if (reason)
66cfc0fd
AM
457 error (_("Reading %s bytes extends past end of file for %s\n"),
458 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
459 return NULL;
460 }
461
978c4450
AM
462 if (fseek (filedata->handle, filedata->archive_file_offset + offset,
463 SEEK_SET))
071436c6
NC
464 {
465 if (reason)
c9c1d674 466 error (_("Unable to seek to 0x%lx for %s\n"),
978c4450 467 filedata->archive_file_offset + offset, reason);
071436c6
NC
468 return NULL;
469 }
470
a6e9f9df
AM
471 mvar = var;
472 if (mvar == NULL)
473 {
7c1c1904
AM
474 /* + 1 so that we can '\0' terminate invalid string table sections. */
475 mvar = malloc ((size_t) amt + 1);
a6e9f9df
AM
476
477 if (mvar == NULL)
478 {
049b0c3a 479 if (reason)
66cfc0fd
AM
480 error (_("Out of memory allocating %s bytes for %s\n"),
481 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
482 return NULL;
483 }
c256ffe7 484
c9c1d674 485 ((char *) mvar)[amt] = '\0';
a6e9f9df
AM
486 }
487
dda8d76d 488 if (fread (mvar, (size_t) size, (size_t) nmemb, filedata->handle) != nmemb)
a6e9f9df 489 {
049b0c3a 490 if (reason)
66cfc0fd
AM
491 error (_("Unable to read in %s bytes of %s\n"),
492 bfd_vmatoa ("u", amt), reason);
a6e9f9df
AM
493 if (mvar != var)
494 free (mvar);
495 return NULL;
496 }
497
498 return mvar;
499}
500
32ec8896
NC
501/* Print a VMA value in the MODE specified.
502 Returns the number of characters displayed. */
cb8f3167 503
32ec8896 504static unsigned int
14a91970 505print_vma (bfd_vma vma, print_mode mode)
66543521 506{
32ec8896 507 unsigned int nc = 0;
66543521 508
14a91970 509 switch (mode)
66543521 510 {
14a91970
AM
511 case FULL_HEX:
512 nc = printf ("0x");
1a0670f3 513 /* Fall through. */
14a91970 514 case LONG_HEX:
f7a99963 515#ifdef BFD64
14a91970 516 if (is_32bit_elf)
437c2fb7 517 return nc + printf ("%8.8" BFD_VMA_FMT "x", vma);
f7a99963 518#endif
14a91970
AM
519 printf_vma (vma);
520 return nc + 16;
b19aac67 521
14a91970
AM
522 case DEC_5:
523 if (vma <= 99999)
524 return printf ("%5" BFD_VMA_FMT "d", vma);
1a0670f3 525 /* Fall through. */
14a91970
AM
526 case PREFIX_HEX:
527 nc = printf ("0x");
1a0670f3 528 /* Fall through. */
14a91970
AM
529 case HEX:
530 return nc + printf ("%" BFD_VMA_FMT "x", vma);
b19aac67 531
14a91970
AM
532 case DEC:
533 return printf ("%" BFD_VMA_FMT "d", vma);
b19aac67 534
14a91970
AM
535 case UNSIGNED:
536 return printf ("%" BFD_VMA_FMT "u", vma);
32ec8896
NC
537
538 default:
539 /* FIXME: Report unrecognised mode ? */
540 return 0;
f7a99963 541 }
f7a99963
NC
542}
543
7bfd842d 544/* Display a symbol on stdout. Handles the display of control characters and
3bfcb652 545 multibye characters (assuming the host environment supports them).
31104126 546
7bfd842d
NC
547 Display at most abs(WIDTH) characters, truncating as necessary, unless do_wide is true.
548
0942c7ab
NC
549 If truncation will happen and do_not_show_symbol_truncation is FALSE then display
550 abs(WIDTH) - 5 characters followed by "[...]".
551
7bfd842d
NC
552 If WIDTH is negative then ensure that the output is at least (- WIDTH) characters,
553 padding as necessary.
171191ba
NC
554
555 Returns the number of emitted characters. */
556
557static unsigned int
0942c7ab 558print_symbol (signed int width, const char * symbol)
31104126 559{
171191ba 560 bfd_boolean extra_padding = FALSE;
0942c7ab 561 bfd_boolean do_dots = FALSE;
32ec8896 562 signed int num_printed = 0;
3bfcb652 563#ifdef HAVE_MBSTATE_T
7bfd842d 564 mbstate_t state;
3bfcb652 565#endif
32ec8896 566 unsigned int width_remaining;
79bc120c 567 const void * alloced_symbol = NULL;
961c521f 568
7bfd842d 569 if (width < 0)
961c521f 570 {
88305e1b 571 /* Keep the width positive. This helps the code below. */
961c521f 572 width = - width;
171191ba 573 extra_padding = TRUE;
0b4362b0 574 }
56d8f8a9
NC
575 else if (width == 0)
576 return 0;
961c521f 577
7bfd842d
NC
578 if (do_wide)
579 /* Set the remaining width to a very large value.
580 This simplifies the code below. */
581 width_remaining = INT_MAX;
582 else
0942c7ab
NC
583 {
584 width_remaining = width;
585 if (! do_not_show_symbol_truncation
586 && (int) strlen (symbol) > width)
587 {
588 width_remaining -= 5;
589 if ((int) width_remaining < 0)
590 width_remaining = 0;
591 do_dots = TRUE;
592 }
593 }
cb8f3167 594
3bfcb652 595#ifdef HAVE_MBSTATE_T
7bfd842d
NC
596 /* Initialise the multibyte conversion state. */
597 memset (& state, 0, sizeof (state));
3bfcb652 598#endif
961c521f 599
79bc120c
NC
600 if (do_demangle && *symbol)
601 {
602 const char * res = cplus_demangle (symbol, demangle_flags);
603
604 if (res != NULL)
605 alloced_symbol = symbol = res;
606 }
607
7bfd842d
NC
608 while (width_remaining)
609 {
610 size_t n;
7bfd842d 611 const char c = *symbol++;
961c521f 612
7bfd842d 613 if (c == 0)
961c521f
NC
614 break;
615
7bfd842d
NC
616 /* Do not print control characters directly as they can affect terminal
617 settings. Such characters usually appear in the names generated
618 by the assembler for local labels. */
619 if (ISCNTRL (c))
961c521f 620 {
7bfd842d 621 if (width_remaining < 2)
961c521f
NC
622 break;
623
7bfd842d
NC
624 printf ("^%c", c + 0x40);
625 width_remaining -= 2;
171191ba 626 num_printed += 2;
961c521f 627 }
7bfd842d
NC
628 else if (ISPRINT (c))
629 {
630 putchar (c);
631 width_remaining --;
632 num_printed ++;
633 }
961c521f
NC
634 else
635 {
3bfcb652
NC
636#ifdef HAVE_MBSTATE_T
637 wchar_t w;
638#endif
7bfd842d
NC
639 /* Let printf do the hard work of displaying multibyte characters. */
640 printf ("%.1s", symbol - 1);
641 width_remaining --;
642 num_printed ++;
643
3bfcb652 644#ifdef HAVE_MBSTATE_T
7bfd842d
NC
645 /* Try to find out how many bytes made up the character that was
646 just printed. Advance the symbol pointer past the bytes that
647 were displayed. */
648 n = mbrtowc (& w, symbol - 1, MB_CUR_MAX, & state);
3bfcb652
NC
649#else
650 n = 1;
651#endif
7bfd842d
NC
652 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
653 symbol += (n - 1);
961c521f 654 }
961c521f 655 }
171191ba 656
0942c7ab
NC
657 if (do_dots)
658 num_printed += printf ("[...]");
659
7bfd842d 660 if (extra_padding && num_printed < width)
171191ba
NC
661 {
662 /* Fill in the remaining spaces. */
7bfd842d
NC
663 printf ("%-*s", width - num_printed, " ");
664 num_printed = width;
171191ba
NC
665 }
666
79bc120c 667 free ((void *) alloced_symbol);
171191ba 668 return num_printed;
31104126
NC
669}
670
1449284b 671/* Returns a pointer to a static buffer containing a printable version of
74e1a04b
NC
672 the given section's name. Like print_symbol, except that it does not try
673 to print multibyte characters, it just interprets them as hex values. */
674
675static const char *
dda8d76d 676printable_section_name (Filedata * filedata, const Elf_Internal_Shdr * sec)
74e1a04b
NC
677{
678#define MAX_PRINT_SEC_NAME_LEN 128
679 static char sec_name_buf [MAX_PRINT_SEC_NAME_LEN + 1];
b9e920ec 680 const char * name = SECTION_NAME_PRINT (sec);
74e1a04b
NC
681 char * buf = sec_name_buf;
682 char c;
683 unsigned int remaining = MAX_PRINT_SEC_NAME_LEN;
684
685 while ((c = * name ++) != 0)
686 {
687 if (ISCNTRL (c))
688 {
689 if (remaining < 2)
690 break;
948f632f 691
74e1a04b
NC
692 * buf ++ = '^';
693 * buf ++ = c + 0x40;
694 remaining -= 2;
695 }
696 else if (ISPRINT (c))
697 {
698 * buf ++ = c;
699 remaining -= 1;
700 }
701 else
702 {
703 static char hex[17] = "0123456789ABCDEF";
704
705 if (remaining < 4)
706 break;
707 * buf ++ = '<';
708 * buf ++ = hex[(c & 0xf0) >> 4];
709 * buf ++ = hex[c & 0x0f];
710 * buf ++ = '>';
711 remaining -= 4;
712 }
713
714 if (remaining == 0)
715 break;
716 }
717
718 * buf = 0;
719 return sec_name_buf;
720}
721
722static const char *
dda8d76d 723printable_section_name_from_index (Filedata * filedata, unsigned long ndx)
74e1a04b 724{
dda8d76d 725 if (ndx >= filedata->file_header.e_shnum)
74e1a04b
NC
726 return _("<corrupt>");
727
dda8d76d 728 return printable_section_name (filedata, filedata->section_headers + ndx);
74e1a04b
NC
729}
730
89fac5e3
RS
731/* Return a pointer to section NAME, or NULL if no such section exists. */
732
733static Elf_Internal_Shdr *
dda8d76d 734find_section (Filedata * filedata, const char * name)
89fac5e3
RS
735{
736 unsigned int i;
737
68807c3c
NC
738 if (filedata->section_headers == NULL)
739 return NULL;
dda8d76d
NC
740
741 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
742 if (SECTION_NAME_VALID (filedata->section_headers + i)
743 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 744 return filedata->section_headers + i;
89fac5e3
RS
745
746 return NULL;
747}
748
0b6ae522
DJ
749/* Return a pointer to a section containing ADDR, or NULL if no such
750 section exists. */
751
752static Elf_Internal_Shdr *
dda8d76d 753find_section_by_address (Filedata * filedata, bfd_vma addr)
0b6ae522
DJ
754{
755 unsigned int i;
756
68807c3c
NC
757 if (filedata->section_headers == NULL)
758 return NULL;
759
dda8d76d 760 for (i = 0; i < filedata->file_header.e_shnum; i++)
0b6ae522 761 {
dda8d76d
NC
762 Elf_Internal_Shdr *sec = filedata->section_headers + i;
763
0b6ae522
DJ
764 if (addr >= sec->sh_addr && addr < sec->sh_addr + sec->sh_size)
765 return sec;
766 }
767
768 return NULL;
769}
770
071436c6 771static Elf_Internal_Shdr *
dda8d76d 772find_section_by_type (Filedata * filedata, unsigned int type)
071436c6
NC
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++)
071436c6 780 {
dda8d76d
NC
781 Elf_Internal_Shdr *sec = filedata->section_headers + i;
782
071436c6
NC
783 if (sec->sh_type == type)
784 return sec;
785 }
786
787 return NULL;
788}
789
657d0d47
CC
790/* Return a pointer to section NAME, or NULL if no such section exists,
791 restricted to the list of sections given in SET. */
792
793static Elf_Internal_Shdr *
dda8d76d 794find_section_in_set (Filedata * filedata, const char * name, unsigned int * set)
657d0d47
CC
795{
796 unsigned int i;
797
68807c3c
NC
798 if (filedata->section_headers == NULL)
799 return NULL;
800
657d0d47
CC
801 if (set != NULL)
802 {
803 while ((i = *set++) > 0)
b814a36d
NC
804 {
805 /* See PR 21156 for a reproducer. */
dda8d76d 806 if (i >= filedata->file_header.e_shnum)
b814a36d
NC
807 continue; /* FIXME: Should we issue an error message ? */
808
b9e920ec
AM
809 if (SECTION_NAME_VALID (filedata->section_headers + i)
810 && streq (SECTION_NAME (filedata->section_headers + i), name))
dda8d76d 811 return filedata->section_headers + i;
b814a36d 812 }
657d0d47
CC
813 }
814
dda8d76d 815 return find_section (filedata, name);
657d0d47
CC
816}
817
32ec8896 818/* Return TRUE if the current file is for IA-64 machine and OpenVMS ABI.
28f997cf
TG
819 This OS has so many departures from the ELF standard that we test it at
820 many places. */
821
32ec8896 822static inline bfd_boolean
dda8d76d 823is_ia64_vms (Filedata * filedata)
28f997cf 824{
dda8d76d
NC
825 return filedata->file_header.e_machine == EM_IA_64
826 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS;
28f997cf
TG
827}
828
bcedfee6 829/* Guess the relocation size commonly used by the specific machines. */
252b5132 830
32ec8896 831static bfd_boolean
2dc4cec1 832guess_is_rela (unsigned int e_machine)
252b5132 833{
9c19a809 834 switch (e_machine)
252b5132
RH
835 {
836 /* Targets that use REL relocations. */
252b5132 837 case EM_386:
22abe556 838 case EM_IAMCU:
f954747f 839 case EM_960:
e9f53129 840 case EM_ARM:
2b0337b0 841 case EM_D10V:
252b5132 842 case EM_CYGNUS_D10V:
e9f53129 843 case EM_DLX:
252b5132 844 case EM_MIPS:
4fe85591 845 case EM_MIPS_RS3_LE:
e9f53129 846 case EM_CYGNUS_M32R:
1c0d3aa6 847 case EM_SCORE:
f6c1a2d5 848 case EM_XGATE:
fe944acf 849 case EM_NFP:
aca4efc7 850 case EM_BPF:
9c19a809 851 return FALSE;
103f02d3 852
252b5132
RH
853 /* Targets that use RELA relocations. */
854 case EM_68K:
f954747f 855 case EM_860:
a06ea964 856 case EM_AARCH64:
cfb8c092 857 case EM_ADAPTEVA_EPIPHANY:
e9f53129
AM
858 case EM_ALPHA:
859 case EM_ALTERA_NIOS2:
886a2506
NC
860 case EM_ARC:
861 case EM_ARC_COMPACT:
862 case EM_ARC_COMPACT2:
e9f53129
AM
863 case EM_AVR:
864 case EM_AVR_OLD:
865 case EM_BLACKFIN:
60bca95a 866 case EM_CR16:
e9f53129
AM
867 case EM_CRIS:
868 case EM_CRX:
b8891f8d 869 case EM_CSKY:
2b0337b0 870 case EM_D30V:
252b5132 871 case EM_CYGNUS_D30V:
2b0337b0 872 case EM_FR30:
3f8107ab 873 case EM_FT32:
252b5132 874 case EM_CYGNUS_FR30:
5c70f934 875 case EM_CYGNUS_FRV:
e9f53129
AM
876 case EM_H8S:
877 case EM_H8_300:
878 case EM_H8_300H:
800eeca4 879 case EM_IA_64:
1e4cf259
NC
880 case EM_IP2K:
881 case EM_IP2K_OLD:
3b36097d 882 case EM_IQ2000:
84e94c90 883 case EM_LATTICEMICO32:
ff7eeb89 884 case EM_M32C_OLD:
49f58d10 885 case EM_M32C:
e9f53129
AM
886 case EM_M32R:
887 case EM_MCORE:
15ab5209 888 case EM_CYGNUS_MEP:
a3c62988 889 case EM_METAG:
e9f53129
AM
890 case EM_MMIX:
891 case EM_MN10200:
892 case EM_CYGNUS_MN10200:
893 case EM_MN10300:
894 case EM_CYGNUS_MN10300:
5506d11a 895 case EM_MOXIE:
e9f53129
AM
896 case EM_MSP430:
897 case EM_MSP430_OLD:
d031aafb 898 case EM_MT:
35c08157 899 case EM_NDS32:
64fd6348 900 case EM_NIOS32:
73589c9d 901 case EM_OR1K:
e9f53129
AM
902 case EM_PPC64:
903 case EM_PPC:
2b100bb5 904 case EM_TI_PRU:
e23eba97 905 case EM_RISCV:
99c513f6 906 case EM_RL78:
c7927a3c 907 case EM_RX:
e9f53129
AM
908 case EM_S390:
909 case EM_S390_OLD:
910 case EM_SH:
911 case EM_SPARC:
912 case EM_SPARC32PLUS:
913 case EM_SPARCV9:
914 case EM_SPU:
40b36596 915 case EM_TI_C6000:
aa137e4d
NC
916 case EM_TILEGX:
917 case EM_TILEPRO:
708e2187 918 case EM_V800:
e9f53129
AM
919 case EM_V850:
920 case EM_CYGNUS_V850:
921 case EM_VAX:
619ed720 922 case EM_VISIUM:
e9f53129 923 case EM_X86_64:
8a9036a4 924 case EM_L1OM:
7a9068fe 925 case EM_K1OM:
e9f53129
AM
926 case EM_XSTORMY16:
927 case EM_XTENSA:
928 case EM_XTENSA_OLD:
7ba29e2a
NC
929 case EM_MICROBLAZE:
930 case EM_MICROBLAZE_OLD:
f96bd6c2 931 case EM_WEBASSEMBLY:
9c19a809 932 return TRUE;
103f02d3 933
e9f53129
AM
934 case EM_68HC05:
935 case EM_68HC08:
936 case EM_68HC11:
937 case EM_68HC16:
938 case EM_FX66:
939 case EM_ME16:
d1133906 940 case EM_MMA:
d1133906
NC
941 case EM_NCPU:
942 case EM_NDR1:
e9f53129 943 case EM_PCP:
d1133906 944 case EM_ST100:
e9f53129 945 case EM_ST19:
d1133906 946 case EM_ST7:
e9f53129
AM
947 case EM_ST9PLUS:
948 case EM_STARCORE:
d1133906 949 case EM_SVX:
e9f53129 950 case EM_TINYJ:
9c19a809
NC
951 default:
952 warn (_("Don't know about relocations on this machine architecture\n"));
953 return FALSE;
954 }
955}
252b5132 956
dda8d76d 957/* Load RELA type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
958 Returns TRUE upon success, FALSE otherwise. If successful then a
959 pointer to a malloc'ed buffer containing the relocs is placed in *RELASP,
960 and the number of relocs loaded is placed in *NRELASP. It is the caller's
961 responsibility to free the allocated buffer. */
962
963static bfd_boolean
dda8d76d
NC
964slurp_rela_relocs (Filedata * filedata,
965 unsigned long rel_offset,
966 unsigned long rel_size,
967 Elf_Internal_Rela ** relasp,
968 unsigned long * nrelasp)
9c19a809 969{
2cf0635d 970 Elf_Internal_Rela * relas;
8b73c356 971 size_t nrelas;
4d6ed7c8 972 unsigned int i;
252b5132 973
4d6ed7c8
NC
974 if (is_32bit_elf)
975 {
2cf0635d 976 Elf32_External_Rela * erelas;
103f02d3 977
dda8d76d 978 erelas = (Elf32_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 979 rel_size, _("32-bit relocation data"));
a6e9f9df 980 if (!erelas)
32ec8896 981 return FALSE;
252b5132 982
4d6ed7c8 983 nrelas = rel_size / sizeof (Elf32_External_Rela);
103f02d3 984
3f5e193b
NC
985 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
986 sizeof (Elf_Internal_Rela));
103f02d3 987
4d6ed7c8
NC
988 if (relas == NULL)
989 {
c256ffe7 990 free (erelas);
591a748a 991 error (_("out of memory parsing relocs\n"));
32ec8896 992 return FALSE;
4d6ed7c8 993 }
103f02d3 994
4d6ed7c8
NC
995 for (i = 0; i < nrelas; i++)
996 {
997 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
998 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 999 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
4d6ed7c8 1000 }
103f02d3 1001
4d6ed7c8
NC
1002 free (erelas);
1003 }
1004 else
1005 {
2cf0635d 1006 Elf64_External_Rela * erelas;
103f02d3 1007
dda8d76d 1008 erelas = (Elf64_External_Rela *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1009 rel_size, _("64-bit relocation data"));
a6e9f9df 1010 if (!erelas)
32ec8896 1011 return FALSE;
4d6ed7c8
NC
1012
1013 nrelas = rel_size / sizeof (Elf64_External_Rela);
103f02d3 1014
3f5e193b
NC
1015 relas = (Elf_Internal_Rela *) cmalloc (nrelas,
1016 sizeof (Elf_Internal_Rela));
103f02d3 1017
4d6ed7c8
NC
1018 if (relas == NULL)
1019 {
c256ffe7 1020 free (erelas);
591a748a 1021 error (_("out of memory parsing relocs\n"));
32ec8896 1022 return FALSE;
9c19a809 1023 }
4d6ed7c8
NC
1024
1025 for (i = 0; i < nrelas; i++)
9c19a809 1026 {
66543521
AM
1027 relas[i].r_offset = BYTE_GET (erelas[i].r_offset);
1028 relas[i].r_info = BYTE_GET (erelas[i].r_info);
598aaa76 1029 relas[i].r_addend = BYTE_GET_SIGNED (erelas[i].r_addend);
861fb55a
DJ
1030
1031 /* The #ifdef BFD64 below is to prevent a compile time
1032 warning. We know that if we do not have a 64 bit data
1033 type that we will never execute this code anyway. */
1034#ifdef BFD64
dda8d76d
NC
1035 if (filedata->file_header.e_machine == EM_MIPS
1036 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1037 {
1038 /* In little-endian objects, r_info isn't really a
1039 64-bit little-endian value: it has a 32-bit
1040 little-endian symbol index followed by four
1041 individual byte fields. Reorder INFO
1042 accordingly. */
91d6fa6a
NC
1043 bfd_vma inf = relas[i].r_info;
1044 inf = (((inf & 0xffffffff) << 32)
1045 | ((inf >> 56) & 0xff)
1046 | ((inf >> 40) & 0xff00)
1047 | ((inf >> 24) & 0xff0000)
1048 | ((inf >> 8) & 0xff000000));
1049 relas[i].r_info = inf;
861fb55a
DJ
1050 }
1051#endif /* BFD64 */
4d6ed7c8 1052 }
103f02d3 1053
4d6ed7c8
NC
1054 free (erelas);
1055 }
32ec8896 1056
4d6ed7c8
NC
1057 *relasp = relas;
1058 *nrelasp = nrelas;
32ec8896 1059 return TRUE;
4d6ed7c8 1060}
103f02d3 1061
dda8d76d 1062/* Load REL type relocations from FILEDATA at REL_OFFSET extending for REL_SIZE bytes.
32ec8896
NC
1063 Returns TRUE upon success, FALSE otherwise. If successful then a
1064 pointer to a malloc'ed buffer containing the relocs is placed in *RELSP,
1065 and the number of relocs loaded is placed in *NRELSP. It is the caller's
1066 responsibility to free the allocated buffer. */
1067
1068static bfd_boolean
dda8d76d
NC
1069slurp_rel_relocs (Filedata * filedata,
1070 unsigned long rel_offset,
1071 unsigned long rel_size,
1072 Elf_Internal_Rela ** relsp,
1073 unsigned long * nrelsp)
4d6ed7c8 1074{
2cf0635d 1075 Elf_Internal_Rela * rels;
8b73c356 1076 size_t nrels;
4d6ed7c8 1077 unsigned int i;
103f02d3 1078
4d6ed7c8
NC
1079 if (is_32bit_elf)
1080 {
2cf0635d 1081 Elf32_External_Rel * erels;
103f02d3 1082
dda8d76d 1083 erels = (Elf32_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1084 rel_size, _("32-bit relocation data"));
a6e9f9df 1085 if (!erels)
32ec8896 1086 return FALSE;
103f02d3 1087
4d6ed7c8 1088 nrels = rel_size / sizeof (Elf32_External_Rel);
103f02d3 1089
3f5e193b 1090 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1091
4d6ed7c8
NC
1092 if (rels == NULL)
1093 {
c256ffe7 1094 free (erels);
591a748a 1095 error (_("out of memory parsing relocs\n"));
32ec8896 1096 return FALSE;
4d6ed7c8
NC
1097 }
1098
1099 for (i = 0; i < nrels; i++)
1100 {
1101 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1102 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1103 rels[i].r_addend = 0;
9ea033b2 1104 }
4d6ed7c8
NC
1105
1106 free (erels);
9c19a809
NC
1107 }
1108 else
1109 {
2cf0635d 1110 Elf64_External_Rel * erels;
9ea033b2 1111
dda8d76d 1112 erels = (Elf64_External_Rel *) get_data (NULL, filedata, rel_offset, 1,
9cf03b7e 1113 rel_size, _("64-bit relocation data"));
a6e9f9df 1114 if (!erels)
32ec8896 1115 return FALSE;
103f02d3 1116
4d6ed7c8 1117 nrels = rel_size / sizeof (Elf64_External_Rel);
103f02d3 1118
3f5e193b 1119 rels = (Elf_Internal_Rela *) cmalloc (nrels, sizeof (Elf_Internal_Rela));
103f02d3 1120
4d6ed7c8 1121 if (rels == NULL)
9c19a809 1122 {
c256ffe7 1123 free (erels);
591a748a 1124 error (_("out of memory parsing relocs\n"));
32ec8896 1125 return FALSE;
4d6ed7c8 1126 }
103f02d3 1127
4d6ed7c8
NC
1128 for (i = 0; i < nrels; i++)
1129 {
66543521
AM
1130 rels[i].r_offset = BYTE_GET (erels[i].r_offset);
1131 rels[i].r_info = BYTE_GET (erels[i].r_info);
c8286bd1 1132 rels[i].r_addend = 0;
861fb55a
DJ
1133
1134 /* The #ifdef BFD64 below is to prevent a compile time
1135 warning. We know that if we do not have a 64 bit data
1136 type that we will never execute this code anyway. */
1137#ifdef BFD64
dda8d76d
NC
1138 if (filedata->file_header.e_machine == EM_MIPS
1139 && filedata->file_header.e_ident[EI_DATA] != ELFDATA2MSB)
861fb55a
DJ
1140 {
1141 /* In little-endian objects, r_info isn't really a
1142 64-bit little-endian value: it has a 32-bit
1143 little-endian symbol index followed by four
1144 individual byte fields. Reorder INFO
1145 accordingly. */
91d6fa6a
NC
1146 bfd_vma inf = rels[i].r_info;
1147 inf = (((inf & 0xffffffff) << 32)
1148 | ((inf >> 56) & 0xff)
1149 | ((inf >> 40) & 0xff00)
1150 | ((inf >> 24) & 0xff0000)
1151 | ((inf >> 8) & 0xff000000));
1152 rels[i].r_info = inf;
861fb55a
DJ
1153 }
1154#endif /* BFD64 */
4d6ed7c8 1155 }
103f02d3 1156
4d6ed7c8
NC
1157 free (erels);
1158 }
32ec8896 1159
4d6ed7c8
NC
1160 *relsp = rels;
1161 *nrelsp = nrels;
32ec8896 1162 return TRUE;
4d6ed7c8 1163}
103f02d3 1164
aca88567
NC
1165/* Returns the reloc type extracted from the reloc info field. */
1166
1167static unsigned int
dda8d76d 1168get_reloc_type (Filedata * filedata, bfd_vma reloc_info)
aca88567
NC
1169{
1170 if (is_32bit_elf)
1171 return ELF32_R_TYPE (reloc_info);
1172
dda8d76d 1173 switch (filedata->file_header.e_machine)
aca88567
NC
1174 {
1175 case EM_MIPS:
1176 /* Note: We assume that reloc_info has already been adjusted for us. */
1177 return ELF64_MIPS_R_TYPE (reloc_info);
1178
1179 case EM_SPARCV9:
1180 return ELF64_R_TYPE_ID (reloc_info);
1181
1182 default:
1183 return ELF64_R_TYPE (reloc_info);
1184 }
1185}
1186
1187/* Return the symbol index extracted from the reloc info field. */
1188
1189static bfd_vma
1190get_reloc_symindex (bfd_vma reloc_info)
1191{
1192 return is_32bit_elf ? ELF32_R_SYM (reloc_info) : ELF64_R_SYM (reloc_info);
1193}
1194
13761a11 1195static inline bfd_boolean
dda8d76d 1196uses_msp430x_relocs (Filedata * filedata)
13761a11
NC
1197{
1198 return
dda8d76d 1199 filedata->file_header.e_machine == EM_MSP430 /* Paranoia. */
13761a11 1200 /* GCC uses osabi == ELFOSBI_STANDALONE. */
dda8d76d 1201 && (((filedata->file_header.e_flags & EF_MSP430_MACH) == E_MSP430_MACH_MSP430X)
13761a11 1202 /* TI compiler uses ELFOSABI_NONE. */
dda8d76d 1203 || (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_NONE));
13761a11
NC
1204}
1205
d3ba0551
AM
1206/* Display the contents of the relocation data found at the specified
1207 offset. */
ee42cf8c 1208
32ec8896 1209static bfd_boolean
dda8d76d
NC
1210dump_relocations (Filedata * filedata,
1211 unsigned long rel_offset,
1212 unsigned long rel_size,
1213 Elf_Internal_Sym * symtab,
1214 unsigned long nsyms,
1215 char * strtab,
1216 unsigned long strtablen,
1217 int is_rela,
1218 bfd_boolean is_dynsym)
4d6ed7c8 1219{
32ec8896 1220 unsigned long i;
2cf0635d 1221 Elf_Internal_Rela * rels;
32ec8896 1222 bfd_boolean res = TRUE;
103f02d3 1223
4d6ed7c8 1224 if (is_rela == UNKNOWN)
dda8d76d 1225 is_rela = guess_is_rela (filedata->file_header.e_machine);
103f02d3 1226
4d6ed7c8
NC
1227 if (is_rela)
1228 {
dda8d76d 1229 if (!slurp_rela_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1230 return FALSE;
4d6ed7c8
NC
1231 }
1232 else
1233 {
dda8d76d 1234 if (!slurp_rel_relocs (filedata, rel_offset, rel_size, &rels, &rel_size))
32ec8896 1235 return FALSE;
252b5132
RH
1236 }
1237
410f7a12
L
1238 if (is_32bit_elf)
1239 {
1240 if (is_rela)
2c71103e
NC
1241 {
1242 if (do_wide)
1243 printf (_(" Offset Info Type Sym. Value Symbol's Name + Addend\n"));
1244 else
1245 printf (_(" Offset Info Type Sym.Value Sym. Name + Addend\n"));
1246 }
410f7a12 1247 else
2c71103e
NC
1248 {
1249 if (do_wide)
1250 printf (_(" Offset Info Type Sym. Value Symbol's Name\n"));
1251 else
1252 printf (_(" Offset Info Type Sym.Value Sym. Name\n"));
1253 }
410f7a12 1254 }
252b5132 1255 else
410f7a12
L
1256 {
1257 if (is_rela)
2c71103e
NC
1258 {
1259 if (do_wide)
8beeaeb7 1260 printf (_(" Offset Info Type Symbol's Value Symbol's Name + Addend\n"));
2c71103e
NC
1261 else
1262 printf (_(" Offset Info Type Sym. Value Sym. Name + Addend\n"));
1263 }
410f7a12 1264 else
2c71103e
NC
1265 {
1266 if (do_wide)
8beeaeb7 1267 printf (_(" Offset Info Type Symbol's Value Symbol's Name\n"));
2c71103e
NC
1268 else
1269 printf (_(" Offset Info Type Sym. Value Sym. Name\n"));
1270 }
410f7a12 1271 }
252b5132
RH
1272
1273 for (i = 0; i < rel_size; i++)
1274 {
2cf0635d 1275 const char * rtype;
b34976b6 1276 bfd_vma offset;
91d6fa6a 1277 bfd_vma inf;
b34976b6
AM
1278 bfd_vma symtab_index;
1279 bfd_vma type;
103f02d3 1280
b34976b6 1281 offset = rels[i].r_offset;
91d6fa6a 1282 inf = rels[i].r_info;
103f02d3 1283
dda8d76d 1284 type = get_reloc_type (filedata, inf);
91d6fa6a 1285 symtab_index = get_reloc_symindex (inf);
252b5132 1286
410f7a12
L
1287 if (is_32bit_elf)
1288 {
39dbeff8
AM
1289 printf ("%8.8lx %8.8lx ",
1290 (unsigned long) offset & 0xffffffff,
91d6fa6a 1291 (unsigned long) inf & 0xffffffff);
410f7a12
L
1292 }
1293 else
1294 {
39dbeff8 1295 printf (do_wide
d1ce973e
AM
1296 ? "%16.16" BFD_VMA_FMT "x %16.16" BFD_VMA_FMT "x "
1297 : "%12.12" BFD_VMA_FMT "x %12.12" BFD_VMA_FMT "x ",
91d6fa6a 1298 offset, inf);
410f7a12 1299 }
103f02d3 1300
dda8d76d 1301 switch (filedata->file_header.e_machine)
252b5132
RH
1302 {
1303 default:
1304 rtype = NULL;
1305 break;
1306
a06ea964
NC
1307 case EM_AARCH64:
1308 rtype = elf_aarch64_reloc_type (type);
1309 break;
1310
2b0337b0 1311 case EM_M32R:
252b5132 1312 case EM_CYGNUS_M32R:
9ea033b2 1313 rtype = elf_m32r_reloc_type (type);
252b5132
RH
1314 break;
1315
1316 case EM_386:
22abe556 1317 case EM_IAMCU:
9ea033b2 1318 rtype = elf_i386_reloc_type (type);
252b5132
RH
1319 break;
1320
ba2685cc
AM
1321 case EM_68HC11:
1322 case EM_68HC12:
1323 rtype = elf_m68hc11_reloc_type (type);
1324 break;
75751cd9 1325
7b4ae824
JD
1326 case EM_S12Z:
1327 rtype = elf_s12z_reloc_type (type);
1328 break;
1329
252b5132 1330 case EM_68K:
9ea033b2 1331 rtype = elf_m68k_reloc_type (type);
252b5132
RH
1332 break;
1333
f954747f
AM
1334 case EM_960:
1335 rtype = elf_i960_reloc_type (type);
1336 break;
1337
adde6300 1338 case EM_AVR:
2b0337b0 1339 case EM_AVR_OLD:
adde6300
AM
1340 rtype = elf_avr_reloc_type (type);
1341 break;
1342
9ea033b2
NC
1343 case EM_OLD_SPARCV9:
1344 case EM_SPARC32PLUS:
1345 case EM_SPARCV9:
252b5132 1346 case EM_SPARC:
9ea033b2 1347 rtype = elf_sparc_reloc_type (type);
252b5132
RH
1348 break;
1349
e9f53129
AM
1350 case EM_SPU:
1351 rtype = elf_spu_reloc_type (type);
1352 break;
1353
708e2187
NC
1354 case EM_V800:
1355 rtype = v800_reloc_type (type);
1356 break;
2b0337b0 1357 case EM_V850:
252b5132 1358 case EM_CYGNUS_V850:
9ea033b2 1359 rtype = v850_reloc_type (type);
252b5132
RH
1360 break;
1361
2b0337b0 1362 case EM_D10V:
252b5132 1363 case EM_CYGNUS_D10V:
9ea033b2 1364 rtype = elf_d10v_reloc_type (type);
252b5132
RH
1365 break;
1366
2b0337b0 1367 case EM_D30V:
252b5132 1368 case EM_CYGNUS_D30V:
9ea033b2 1369 rtype = elf_d30v_reloc_type (type);
252b5132
RH
1370 break;
1371
d172d4ba
NC
1372 case EM_DLX:
1373 rtype = elf_dlx_reloc_type (type);
1374 break;
1375
252b5132 1376 case EM_SH:
9ea033b2 1377 rtype = elf_sh_reloc_type (type);
252b5132
RH
1378 break;
1379
2b0337b0 1380 case EM_MN10300:
252b5132 1381 case EM_CYGNUS_MN10300:
9ea033b2 1382 rtype = elf_mn10300_reloc_type (type);
252b5132
RH
1383 break;
1384
2b0337b0 1385 case EM_MN10200:
252b5132 1386 case EM_CYGNUS_MN10200:
9ea033b2 1387 rtype = elf_mn10200_reloc_type (type);
252b5132
RH
1388 break;
1389
2b0337b0 1390 case EM_FR30:
252b5132 1391 case EM_CYGNUS_FR30:
9ea033b2 1392 rtype = elf_fr30_reloc_type (type);
252b5132
RH
1393 break;
1394
ba2685cc
AM
1395 case EM_CYGNUS_FRV:
1396 rtype = elf_frv_reloc_type (type);
1397 break;
5c70f934 1398
b8891f8d
AJ
1399 case EM_CSKY:
1400 rtype = elf_csky_reloc_type (type);
1401 break;
1402
3f8107ab
AM
1403 case EM_FT32:
1404 rtype = elf_ft32_reloc_type (type);
1405 break;
1406
252b5132 1407 case EM_MCORE:
9ea033b2 1408 rtype = elf_mcore_reloc_type (type);
252b5132
RH
1409 break;
1410
3c3bdf30
NC
1411 case EM_MMIX:
1412 rtype = elf_mmix_reloc_type (type);
1413 break;
1414
5506d11a
AM
1415 case EM_MOXIE:
1416 rtype = elf_moxie_reloc_type (type);
1417 break;
1418
2469cfa2 1419 case EM_MSP430:
dda8d76d 1420 if (uses_msp430x_relocs (filedata))
13761a11
NC
1421 {
1422 rtype = elf_msp430x_reloc_type (type);
1423 break;
1424 }
1a0670f3 1425 /* Fall through. */
2469cfa2
NC
1426 case EM_MSP430_OLD:
1427 rtype = elf_msp430_reloc_type (type);
1428 break;
1429
35c08157
KLC
1430 case EM_NDS32:
1431 rtype = elf_nds32_reloc_type (type);
1432 break;
1433
252b5132 1434 case EM_PPC:
9ea033b2 1435 rtype = elf_ppc_reloc_type (type);
252b5132
RH
1436 break;
1437
c833c019
AM
1438 case EM_PPC64:
1439 rtype = elf_ppc64_reloc_type (type);
1440 break;
1441
252b5132 1442 case EM_MIPS:
4fe85591 1443 case EM_MIPS_RS3_LE:
9ea033b2 1444 rtype = elf_mips_reloc_type (type);
252b5132
RH
1445 break;
1446
e23eba97
NC
1447 case EM_RISCV:
1448 rtype = elf_riscv_reloc_type (type);
1449 break;
1450
252b5132 1451 case EM_ALPHA:
9ea033b2 1452 rtype = elf_alpha_reloc_type (type);
252b5132
RH
1453 break;
1454
1455 case EM_ARM:
9ea033b2 1456 rtype = elf_arm_reloc_type (type);
252b5132
RH
1457 break;
1458
584da044 1459 case EM_ARC:
886a2506
NC
1460 case EM_ARC_COMPACT:
1461 case EM_ARC_COMPACT2:
9ea033b2 1462 rtype = elf_arc_reloc_type (type);
252b5132
RH
1463 break;
1464
1465 case EM_PARISC:
69e617ca 1466 rtype = elf_hppa_reloc_type (type);
252b5132 1467 break;
7d466069 1468
b8720f9d
JL
1469 case EM_H8_300:
1470 case EM_H8_300H:
1471 case EM_H8S:
1472 rtype = elf_h8_reloc_type (type);
1473 break;
1474
73589c9d
CS
1475 case EM_OR1K:
1476 rtype = elf_or1k_reloc_type (type);
3b16e843
NC
1477 break;
1478
7d466069 1479 case EM_PJ:
2b0337b0 1480 case EM_PJ_OLD:
7d466069
ILT
1481 rtype = elf_pj_reloc_type (type);
1482 break;
800eeca4
JW
1483 case EM_IA_64:
1484 rtype = elf_ia64_reloc_type (type);
1485 break;
1b61cf92
HPN
1486
1487 case EM_CRIS:
1488 rtype = elf_cris_reloc_type (type);
1489 break;
535c37ff 1490
f954747f
AM
1491 case EM_860:
1492 rtype = elf_i860_reloc_type (type);
1493 break;
1494
bcedfee6 1495 case EM_X86_64:
8a9036a4 1496 case EM_L1OM:
7a9068fe 1497 case EM_K1OM:
bcedfee6
NC
1498 rtype = elf_x86_64_reloc_type (type);
1499 break;
a85d7ed0 1500
f954747f
AM
1501 case EM_S370:
1502 rtype = i370_reloc_type (type);
1503 break;
1504
53c7db4b
KH
1505 case EM_S390_OLD:
1506 case EM_S390:
1507 rtype = elf_s390_reloc_type (type);
1508 break;
93fbbb04 1509
1c0d3aa6
NC
1510 case EM_SCORE:
1511 rtype = elf_score_reloc_type (type);
1512 break;
1513
93fbbb04
GK
1514 case EM_XSTORMY16:
1515 rtype = elf_xstormy16_reloc_type (type);
1516 break;
179d3252 1517
1fe1f39c
NC
1518 case EM_CRX:
1519 rtype = elf_crx_reloc_type (type);
1520 break;
1521
179d3252
JT
1522 case EM_VAX:
1523 rtype = elf_vax_reloc_type (type);
1524 break;
1e4cf259 1525
619ed720
EB
1526 case EM_VISIUM:
1527 rtype = elf_visium_reloc_type (type);
1528 break;
1529
aca4efc7
JM
1530 case EM_BPF:
1531 rtype = elf_bpf_reloc_type (type);
1532 break;
1533
cfb8c092
NC
1534 case EM_ADAPTEVA_EPIPHANY:
1535 rtype = elf_epiphany_reloc_type (type);
1536 break;
1537
1e4cf259
NC
1538 case EM_IP2K:
1539 case EM_IP2K_OLD:
1540 rtype = elf_ip2k_reloc_type (type);
1541 break;
3b36097d
SC
1542
1543 case EM_IQ2000:
1544 rtype = elf_iq2000_reloc_type (type);
1545 break;
88da6820
NC
1546
1547 case EM_XTENSA_OLD:
1548 case EM_XTENSA:
1549 rtype = elf_xtensa_reloc_type (type);
1550 break;
a34e3ecb 1551
84e94c90
NC
1552 case EM_LATTICEMICO32:
1553 rtype = elf_lm32_reloc_type (type);
1554 break;
1555
ff7eeb89 1556 case EM_M32C_OLD:
49f58d10
JB
1557 case EM_M32C:
1558 rtype = elf_m32c_reloc_type (type);
1559 break;
1560
d031aafb
NS
1561 case EM_MT:
1562 rtype = elf_mt_reloc_type (type);
a34e3ecb 1563 break;
1d65ded4
CM
1564
1565 case EM_BLACKFIN:
1566 rtype = elf_bfin_reloc_type (type);
1567 break;
15ab5209
DB
1568
1569 case EM_CYGNUS_MEP:
1570 rtype = elf_mep_reloc_type (type);
1571 break;
60bca95a
NC
1572
1573 case EM_CR16:
1574 rtype = elf_cr16_reloc_type (type);
1575 break;
dd24e3da 1576
7ba29e2a
NC
1577 case EM_MICROBLAZE:
1578 case EM_MICROBLAZE_OLD:
1579 rtype = elf_microblaze_reloc_type (type);
1580 break;
c7927a3c 1581
99c513f6
DD
1582 case EM_RL78:
1583 rtype = elf_rl78_reloc_type (type);
1584 break;
1585
c7927a3c
NC
1586 case EM_RX:
1587 rtype = elf_rx_reloc_type (type);
1588 break;
c29aca4a 1589
a3c62988
NC
1590 case EM_METAG:
1591 rtype = elf_metag_reloc_type (type);
1592 break;
1593
c29aca4a
NC
1594 case EM_XC16X:
1595 case EM_C166:
1596 rtype = elf_xc16x_reloc_type (type);
1597 break;
40b36596
JM
1598
1599 case EM_TI_C6000:
1600 rtype = elf_tic6x_reloc_type (type);
1601 break;
aa137e4d
NC
1602
1603 case EM_TILEGX:
1604 rtype = elf_tilegx_reloc_type (type);
1605 break;
1606
1607 case EM_TILEPRO:
1608 rtype = elf_tilepro_reloc_type (type);
1609 break;
f6c1a2d5 1610
f96bd6c2
PC
1611 case EM_WEBASSEMBLY:
1612 rtype = elf_wasm32_reloc_type (type);
1613 break;
1614
f6c1a2d5
NC
1615 case EM_XGATE:
1616 rtype = elf_xgate_reloc_type (type);
1617 break;
36591ba1
SL
1618
1619 case EM_ALTERA_NIOS2:
1620 rtype = elf_nios2_reloc_type (type);
1621 break;
2b100bb5
DD
1622
1623 case EM_TI_PRU:
1624 rtype = elf_pru_reloc_type (type);
1625 break;
fe944acf
FT
1626
1627 case EM_NFP:
1628 if (EF_NFP_MACH (filedata->file_header.e_flags) == E_NFP_MACH_3200)
1629 rtype = elf_nfp3200_reloc_type (type);
1630 else
1631 rtype = elf_nfp_reloc_type (type);
1632 break;
6655dba2
SB
1633
1634 case EM_Z80:
1635 rtype = elf_z80_reloc_type (type);
1636 break;
252b5132
RH
1637 }
1638
1639 if (rtype == NULL)
39dbeff8 1640 printf (_("unrecognized: %-7lx"), (unsigned long) type & 0xffffffff);
252b5132 1641 else
5c144731 1642 printf (do_wide ? "%-22s" : "%-17.17s", rtype);
252b5132 1643
dda8d76d 1644 if (filedata->file_header.e_machine == EM_ALPHA
157c2599 1645 && rtype != NULL
7ace3541
RH
1646 && streq (rtype, "R_ALPHA_LITUSE")
1647 && is_rela)
1648 {
1649 switch (rels[i].r_addend)
1650 {
1651 case LITUSE_ALPHA_ADDR: rtype = "ADDR"; break;
1652 case LITUSE_ALPHA_BASE: rtype = "BASE"; break;
1653 case LITUSE_ALPHA_BYTOFF: rtype = "BYTOFF"; break;
1654 case LITUSE_ALPHA_JSR: rtype = "JSR"; break;
1655 case LITUSE_ALPHA_TLSGD: rtype = "TLSGD"; break;
1656 case LITUSE_ALPHA_TLSLDM: rtype = "TLSLDM"; break;
1657 case LITUSE_ALPHA_JSRDIRECT: rtype = "JSRDIRECT"; break;
1658 default: rtype = NULL;
1659 }
32ec8896 1660
7ace3541
RH
1661 if (rtype)
1662 printf (" (%s)", rtype);
1663 else
1664 {
1665 putchar (' ');
1666 printf (_("<unknown addend: %lx>"),
1667 (unsigned long) rels[i].r_addend);
32ec8896 1668 res = FALSE;
7ace3541
RH
1669 }
1670 }
1671 else if (symtab_index)
252b5132 1672 {
af3fc3bc 1673 if (symtab == NULL || symtab_index >= nsyms)
32ec8896 1674 {
27a45f42
AS
1675 error (_(" bad symbol index: %08lx in reloc\n"),
1676 (unsigned long) symtab_index);
32ec8896
NC
1677 res = FALSE;
1678 }
af3fc3bc 1679 else
19936277 1680 {
2cf0635d 1681 Elf_Internal_Sym * psym;
bb4d2ac2
L
1682 const char * version_string;
1683 enum versioned_symbol_info sym_info;
1684 unsigned short vna_other;
19936277 1685
af3fc3bc 1686 psym = symtab + symtab_index;
103f02d3 1687
bb4d2ac2 1688 version_string
dda8d76d 1689 = get_symbol_version_string (filedata, is_dynsym,
bb4d2ac2
L
1690 strtab, strtablen,
1691 symtab_index,
1692 psym,
1693 &sym_info,
1694 &vna_other);
1695
af3fc3bc 1696 printf (" ");
171191ba 1697
d8045f23
NC
1698 if (ELF_ST_TYPE (psym->st_info) == STT_GNU_IFUNC)
1699 {
1700 const char * name;
1701 unsigned int len;
1702 unsigned int width = is_32bit_elf ? 8 : 14;
1703
1704 /* Relocations against GNU_IFUNC symbols do not use the value
1705 of the symbol as the address to relocate against. Instead
1706 they invoke the function named by the symbol and use its
1707 result as the address for relocation.
1708
1709 To indicate this to the user, do not display the value of
1710 the symbol in the "Symbols's Value" field. Instead show
1711 its name followed by () as a hint that the symbol is
1712 invoked. */
1713
1714 if (strtab == NULL
1715 || psym->st_name == 0
1716 || psym->st_name >= strtablen)
1717 name = "??";
1718 else
1719 name = strtab + psym->st_name;
1720
1721 len = print_symbol (width, name);
bb4d2ac2
L
1722 if (version_string)
1723 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1724 version_string);
d8045f23
NC
1725 printf ("()%-*s", len <= width ? (width + 1) - len : 1, " ");
1726 }
1727 else
1728 {
1729 print_vma (psym->st_value, LONG_HEX);
171191ba 1730
d8045f23
NC
1731 printf (is_32bit_elf ? " " : " ");
1732 }
103f02d3 1733
af3fc3bc 1734 if (psym->st_name == 0)
f1ef08cb 1735 {
2cf0635d 1736 const char * sec_name = "<null>";
f1ef08cb
AM
1737 char name_buf[40];
1738
1739 if (ELF_ST_TYPE (psym->st_info) == STT_SECTION)
1740 {
dda8d76d 1741 if (psym->st_shndx < filedata->file_header.e_shnum)
b9e920ec
AM
1742 sec_name = SECTION_NAME_PRINT (filedata->section_headers
1743 + psym->st_shndx);
f1ef08cb
AM
1744 else if (psym->st_shndx == SHN_ABS)
1745 sec_name = "ABS";
1746 else if (psym->st_shndx == SHN_COMMON)
1747 sec_name = "COMMON";
dda8d76d 1748 else if ((filedata->file_header.e_machine == EM_MIPS
ac145307 1749 && psym->st_shndx == SHN_MIPS_SCOMMON)
dda8d76d 1750 || (filedata->file_header.e_machine == EM_TI_C6000
ac145307 1751 && psym->st_shndx == SHN_TIC6X_SCOMMON))
172553c7 1752 sec_name = "SCOMMON";
dda8d76d 1753 else if (filedata->file_header.e_machine == EM_MIPS
172553c7
TS
1754 && psym->st_shndx == SHN_MIPS_SUNDEFINED)
1755 sec_name = "SUNDEF";
dda8d76d
NC
1756 else if ((filedata->file_header.e_machine == EM_X86_64
1757 || filedata->file_header.e_machine == EM_L1OM
1758 || filedata->file_header.e_machine == EM_K1OM)
3b22753a
L
1759 && psym->st_shndx == SHN_X86_64_LCOMMON)
1760 sec_name = "LARGE_COMMON";
dda8d76d
NC
1761 else if (filedata->file_header.e_machine == EM_IA_64
1762 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX
9ce701e2
L
1763 && psym->st_shndx == SHN_IA_64_ANSI_COMMON)
1764 sec_name = "ANSI_COM";
dda8d76d 1765 else if (is_ia64_vms (filedata)
148b93f2
NC
1766 && psym->st_shndx == SHN_IA_64_VMS_SYMVEC)
1767 sec_name = "VMS_SYMVEC";
f1ef08cb
AM
1768 else
1769 {
1770 sprintf (name_buf, "<section 0x%x>",
1771 (unsigned int) psym->st_shndx);
1772 sec_name = name_buf;
1773 }
1774 }
1775 print_symbol (22, sec_name);
1776 }
af3fc3bc 1777 else if (strtab == NULL)
d79b3d50 1778 printf (_("<string table index: %3ld>"), psym->st_name);
c256ffe7 1779 else if (psym->st_name >= strtablen)
32ec8896 1780 {
27a45f42
AS
1781 error (_("<corrupt string table index: %3ld>\n"),
1782 psym->st_name);
32ec8896
NC
1783 res = FALSE;
1784 }
af3fc3bc 1785 else
bb4d2ac2
L
1786 {
1787 print_symbol (22, strtab + psym->st_name);
1788 if (version_string)
1789 printf (sym_info == symbol_public ? "@@%s" : "@%s",
1790 version_string);
1791 }
103f02d3 1792
af3fc3bc 1793 if (is_rela)
171191ba 1794 {
7360e63f 1795 bfd_vma off = rels[i].r_addend;
171191ba 1796
7360e63f 1797 if ((bfd_signed_vma) off < 0)
598aaa76 1798 printf (" - %" BFD_VMA_FMT "x", - off);
171191ba 1799 else
598aaa76 1800 printf (" + %" BFD_VMA_FMT "x", off);
171191ba 1801 }
19936277 1802 }
252b5132 1803 }
1b228002 1804 else if (is_rela)
f7a99963 1805 {
7360e63f 1806 bfd_vma off = rels[i].r_addend;
e04d7088
L
1807
1808 printf ("%*c", is_32bit_elf ? 12 : 20, ' ');
7360e63f 1809 if ((bfd_signed_vma) off < 0)
e04d7088
L
1810 printf ("-%" BFD_VMA_FMT "x", - off);
1811 else
1812 printf ("%" BFD_VMA_FMT "x", off);
f7a99963 1813 }
252b5132 1814
dda8d76d 1815 if (filedata->file_header.e_machine == EM_SPARCV9
157c2599
NC
1816 && rtype != NULL
1817 && streq (rtype, "R_SPARC_OLO10"))
91d6fa6a 1818 printf (" + %lx", (unsigned long) ELF64_R_TYPE_DATA (inf));
351b4b40 1819
252b5132 1820 putchar ('\n');
2c71103e 1821
aca88567 1822#ifdef BFD64
dda8d76d 1823 if (! is_32bit_elf && filedata->file_header.e_machine == EM_MIPS)
2c71103e 1824 {
91d6fa6a
NC
1825 bfd_vma type2 = ELF64_MIPS_R_TYPE2 (inf);
1826 bfd_vma type3 = ELF64_MIPS_R_TYPE3 (inf);
2cf0635d
NC
1827 const char * rtype2 = elf_mips_reloc_type (type2);
1828 const char * rtype3 = elf_mips_reloc_type (type3);
aca88567 1829
2c71103e
NC
1830 printf (" Type2: ");
1831
1832 if (rtype2 == NULL)
39dbeff8
AM
1833 printf (_("unrecognized: %-7lx"),
1834 (unsigned long) type2 & 0xffffffff);
2c71103e
NC
1835 else
1836 printf ("%-17.17s", rtype2);
1837
18bd398b 1838 printf ("\n Type3: ");
2c71103e
NC
1839
1840 if (rtype3 == NULL)
39dbeff8
AM
1841 printf (_("unrecognized: %-7lx"),
1842 (unsigned long) type3 & 0xffffffff);
2c71103e
NC
1843 else
1844 printf ("%-17.17s", rtype3);
1845
53c7db4b 1846 putchar ('\n');
2c71103e 1847 }
aca88567 1848#endif /* BFD64 */
252b5132
RH
1849 }
1850
c8286bd1 1851 free (rels);
32ec8896
NC
1852
1853 return res;
252b5132
RH
1854}
1855
37c18eed
SD
1856static const char *
1857get_aarch64_dynamic_type (unsigned long type)
1858{
1859 switch (type)
1860 {
1861 case DT_AARCH64_BTI_PLT: return "AARCH64_BTI_PLT";
1dbade74 1862 case DT_AARCH64_PAC_PLT: return "AARCH64_PAC_PLT";
2301ed1c 1863 case DT_AARCH64_VARIANT_PCS: return "AARCH64_VARIANT_PCS";
37c18eed
SD
1864 default:
1865 return NULL;
1866 }
1867}
1868
252b5132 1869static const char *
d3ba0551 1870get_mips_dynamic_type (unsigned long type)
252b5132
RH
1871{
1872 switch (type)
1873 {
1874 case DT_MIPS_RLD_VERSION: return "MIPS_RLD_VERSION";
1875 case DT_MIPS_TIME_STAMP: return "MIPS_TIME_STAMP";
1876 case DT_MIPS_ICHECKSUM: return "MIPS_ICHECKSUM";
1877 case DT_MIPS_IVERSION: return "MIPS_IVERSION";
1878 case DT_MIPS_FLAGS: return "MIPS_FLAGS";
1879 case DT_MIPS_BASE_ADDRESS: return "MIPS_BASE_ADDRESS";
1880 case DT_MIPS_MSYM: return "MIPS_MSYM";
1881 case DT_MIPS_CONFLICT: return "MIPS_CONFLICT";
1882 case DT_MIPS_LIBLIST: return "MIPS_LIBLIST";
1883 case DT_MIPS_LOCAL_GOTNO: return "MIPS_LOCAL_GOTNO";
1884 case DT_MIPS_CONFLICTNO: return "MIPS_CONFLICTNO";
1885 case DT_MIPS_LIBLISTNO: return "MIPS_LIBLISTNO";
1886 case DT_MIPS_SYMTABNO: return "MIPS_SYMTABNO";
1887 case DT_MIPS_UNREFEXTNO: return "MIPS_UNREFEXTNO";
1888 case DT_MIPS_GOTSYM: return "MIPS_GOTSYM";
1889 case DT_MIPS_HIPAGENO: return "MIPS_HIPAGENO";
1890 case DT_MIPS_RLD_MAP: return "MIPS_RLD_MAP";
a5499fa4 1891 case DT_MIPS_RLD_MAP_REL: return "MIPS_RLD_MAP_REL";
252b5132
RH
1892 case DT_MIPS_DELTA_CLASS: return "MIPS_DELTA_CLASS";
1893 case DT_MIPS_DELTA_CLASS_NO: return "MIPS_DELTA_CLASS_NO";
1894 case DT_MIPS_DELTA_INSTANCE: return "MIPS_DELTA_INSTANCE";
1895 case DT_MIPS_DELTA_INSTANCE_NO: return "MIPS_DELTA_INSTANCE_NO";
1896 case DT_MIPS_DELTA_RELOC: return "MIPS_DELTA_RELOC";
1897 case DT_MIPS_DELTA_RELOC_NO: return "MIPS_DELTA_RELOC_NO";
1898 case DT_MIPS_DELTA_SYM: return "MIPS_DELTA_SYM";
1899 case DT_MIPS_DELTA_SYM_NO: return "MIPS_DELTA_SYM_NO";
1900 case DT_MIPS_DELTA_CLASSSYM: return "MIPS_DELTA_CLASSSYM";
1901 case DT_MIPS_DELTA_CLASSSYM_NO: return "MIPS_DELTA_CLASSSYM_NO";
1902 case DT_MIPS_CXX_FLAGS: return "MIPS_CXX_FLAGS";
1903 case DT_MIPS_PIXIE_INIT: return "MIPS_PIXIE_INIT";
1904 case DT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
1905 case DT_MIPS_LOCALPAGE_GOTIDX: return "MIPS_LOCALPAGE_GOTIDX";
1906 case DT_MIPS_LOCAL_GOTIDX: return "MIPS_LOCAL_GOTIDX";
1907 case DT_MIPS_HIDDEN_GOTIDX: return "MIPS_HIDDEN_GOTIDX";
1908 case DT_MIPS_PROTECTED_GOTIDX: return "MIPS_PROTECTED_GOTIDX";
1909 case DT_MIPS_OPTIONS: return "MIPS_OPTIONS";
1910 case DT_MIPS_INTERFACE: return "MIPS_INTERFACE";
1911 case DT_MIPS_DYNSTR_ALIGN: return "MIPS_DYNSTR_ALIGN";
1912 case DT_MIPS_INTERFACE_SIZE: return "MIPS_INTERFACE_SIZE";
1913 case DT_MIPS_RLD_TEXT_RESOLVE_ADDR: return "MIPS_RLD_TEXT_RESOLVE_ADDR";
1914 case DT_MIPS_PERF_SUFFIX: return "MIPS_PERF_SUFFIX";
1915 case DT_MIPS_COMPACT_SIZE: return "MIPS_COMPACT_SIZE";
1916 case DT_MIPS_GP_VALUE: return "MIPS_GP_VALUE";
1917 case DT_MIPS_AUX_DYNAMIC: return "MIPS_AUX_DYNAMIC";
861fb55a
DJ
1918 case DT_MIPS_PLTGOT: return "MIPS_PLTGOT";
1919 case DT_MIPS_RWPLT: return "MIPS_RWPLT";
f16a9783 1920 case DT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
1921 default:
1922 return NULL;
1923 }
1924}
1925
9a097730 1926static const char *
d3ba0551 1927get_sparc64_dynamic_type (unsigned long type)
9a097730
RH
1928{
1929 switch (type)
1930 {
1931 case DT_SPARC_REGISTER: return "SPARC_REGISTER";
1932 default:
1933 return NULL;
1934 }
103f02d3
UD
1935}
1936
7490d522
AM
1937static const char *
1938get_ppc_dynamic_type (unsigned long type)
1939{
1940 switch (type)
1941 {
a7f2871e 1942 case DT_PPC_GOT: return "PPC_GOT";
e8910a83 1943 case DT_PPC_OPT: return "PPC_OPT";
7490d522
AM
1944 default:
1945 return NULL;
1946 }
1947}
1948
f1cb7e17 1949static const char *
d3ba0551 1950get_ppc64_dynamic_type (unsigned long type)
f1cb7e17
AM
1951{
1952 switch (type)
1953 {
a7f2871e
AM
1954 case DT_PPC64_GLINK: return "PPC64_GLINK";
1955 case DT_PPC64_OPD: return "PPC64_OPD";
1956 case DT_PPC64_OPDSZ: return "PPC64_OPDSZ";
e8910a83 1957 case DT_PPC64_OPT: return "PPC64_OPT";
f1cb7e17
AM
1958 default:
1959 return NULL;
1960 }
1961}
1962
103f02d3 1963static const char *
d3ba0551 1964get_parisc_dynamic_type (unsigned long type)
103f02d3
UD
1965{
1966 switch (type)
1967 {
1968 case DT_HP_LOAD_MAP: return "HP_LOAD_MAP";
1969 case DT_HP_DLD_FLAGS: return "HP_DLD_FLAGS";
1970 case DT_HP_DLD_HOOK: return "HP_DLD_HOOK";
1971 case DT_HP_UX10_INIT: return "HP_UX10_INIT";
1972 case DT_HP_UX10_INITSZ: return "HP_UX10_INITSZ";
1973 case DT_HP_PREINIT: return "HP_PREINIT";
1974 case DT_HP_PREINITSZ: return "HP_PREINITSZ";
1975 case DT_HP_NEEDED: return "HP_NEEDED";
1976 case DT_HP_TIME_STAMP: return "HP_TIME_STAMP";
1977 case DT_HP_CHECKSUM: return "HP_CHECKSUM";
1978 case DT_HP_GST_SIZE: return "HP_GST_SIZE";
1979 case DT_HP_GST_VERSION: return "HP_GST_VERSION";
1980 case DT_HP_GST_HASHVAL: return "HP_GST_HASHVAL";
eec8f817
DA
1981 case DT_HP_EPLTREL: return "HP_GST_EPLTREL";
1982 case DT_HP_EPLTRELSZ: return "HP_GST_EPLTRELSZ";
1983 case DT_HP_FILTERED: return "HP_FILTERED";
1984 case DT_HP_FILTER_TLS: return "HP_FILTER_TLS";
1985 case DT_HP_COMPAT_FILTERED: return "HP_COMPAT_FILTERED";
1986 case DT_HP_LAZYLOAD: return "HP_LAZYLOAD";
1987 case DT_HP_BIND_NOW_COUNT: return "HP_BIND_NOW_COUNT";
1988 case DT_PLT: return "PLT";
1989 case DT_PLT_SIZE: return "PLT_SIZE";
1990 case DT_DLT: return "DLT";
1991 case DT_DLT_SIZE: return "DLT_SIZE";
103f02d3
UD
1992 default:
1993 return NULL;
1994 }
1995}
9a097730 1996
ecc51f48 1997static const char *
d3ba0551 1998get_ia64_dynamic_type (unsigned long type)
ecc51f48
NC
1999{
2000 switch (type)
2001 {
148b93f2
NC
2002 case DT_IA_64_PLT_RESERVE: return "IA_64_PLT_RESERVE";
2003 case DT_IA_64_VMS_SUBTYPE: return "VMS_SUBTYPE";
2004 case DT_IA_64_VMS_IMGIOCNT: return "VMS_IMGIOCNT";
2005 case DT_IA_64_VMS_LNKFLAGS: return "VMS_LNKFLAGS";
2006 case DT_IA_64_VMS_VIR_MEM_BLK_SIZ: return "VMS_VIR_MEM_BLK_SIZ";
2007 case DT_IA_64_VMS_IDENT: return "VMS_IDENT";
2008 case DT_IA_64_VMS_NEEDED_IDENT: return "VMS_NEEDED_IDENT";
2009 case DT_IA_64_VMS_IMG_RELA_CNT: return "VMS_IMG_RELA_CNT";
2010 case DT_IA_64_VMS_SEG_RELA_CNT: return "VMS_SEG_RELA_CNT";
2011 case DT_IA_64_VMS_FIXUP_RELA_CNT: return "VMS_FIXUP_RELA_CNT";
2012 case DT_IA_64_VMS_FIXUP_NEEDED: return "VMS_FIXUP_NEEDED";
2013 case DT_IA_64_VMS_SYMVEC_CNT: return "VMS_SYMVEC_CNT";
2014 case DT_IA_64_VMS_XLATED: return "VMS_XLATED";
2015 case DT_IA_64_VMS_STACKSIZE: return "VMS_STACKSIZE";
2016 case DT_IA_64_VMS_UNWINDSZ: return "VMS_UNWINDSZ";
2017 case DT_IA_64_VMS_UNWIND_CODSEG: return "VMS_UNWIND_CODSEG";
2018 case DT_IA_64_VMS_UNWIND_INFOSEG: return "VMS_UNWIND_INFOSEG";
2019 case DT_IA_64_VMS_LINKTIME: return "VMS_LINKTIME";
2020 case DT_IA_64_VMS_SEG_NO: return "VMS_SEG_NO";
2021 case DT_IA_64_VMS_SYMVEC_OFFSET: return "VMS_SYMVEC_OFFSET";
2022 case DT_IA_64_VMS_SYMVEC_SEG: return "VMS_SYMVEC_SEG";
2023 case DT_IA_64_VMS_UNWIND_OFFSET: return "VMS_UNWIND_OFFSET";
2024 case DT_IA_64_VMS_UNWIND_SEG: return "VMS_UNWIND_SEG";
2025 case DT_IA_64_VMS_STRTAB_OFFSET: return "VMS_STRTAB_OFFSET";
2026 case DT_IA_64_VMS_SYSVER_OFFSET: return "VMS_SYSVER_OFFSET";
2027 case DT_IA_64_VMS_IMG_RELA_OFF: return "VMS_IMG_RELA_OFF";
2028 case DT_IA_64_VMS_SEG_RELA_OFF: return "VMS_SEG_RELA_OFF";
2029 case DT_IA_64_VMS_FIXUP_RELA_OFF: return "VMS_FIXUP_RELA_OFF";
2030 case DT_IA_64_VMS_PLTGOT_OFFSET: return "VMS_PLTGOT_OFFSET";
2031 case DT_IA_64_VMS_PLTGOT_SEG: return "VMS_PLTGOT_SEG";
2032 case DT_IA_64_VMS_FPMODE: return "VMS_FPMODE";
ecc51f48
NC
2033 default:
2034 return NULL;
2035 }
2036}
2037
fd85a6a1
NC
2038static const char *
2039get_solaris_section_type (unsigned long type)
2040{
2041 switch (type)
2042 {
2043 case 0x6fffffee: return "SUNW_ancillary";
2044 case 0x6fffffef: return "SUNW_capchain";
2045 case 0x6ffffff0: return "SUNW_capinfo";
2046 case 0x6ffffff1: return "SUNW_symsort";
2047 case 0x6ffffff2: return "SUNW_tlssort";
2048 case 0x6ffffff3: return "SUNW_LDYNSYM";
2049 case 0x6ffffff4: return "SUNW_dof";
2050 case 0x6ffffff5: return "SUNW_cap";
2051 case 0x6ffffff6: return "SUNW_SIGNATURE";
2052 case 0x6ffffff7: return "SUNW_ANNOTATE";
2053 case 0x6ffffff8: return "SUNW_DEBUGSTR";
2054 case 0x6ffffff9: return "SUNW_DEBUG";
2055 case 0x6ffffffa: return "SUNW_move";
2056 case 0x6ffffffb: return "SUNW_COMDAT";
2057 case 0x6ffffffc: return "SUNW_syminfo";
2058 case 0x6ffffffd: return "SUNW_verdef";
2059 case 0x6ffffffe: return "SUNW_verneed";
2060 case 0x6fffffff: return "SUNW_versym";
2061 case 0x70000000: return "SPARC_GOTDATA";
2062 default: return NULL;
2063 }
2064}
2065
fabcb361
RH
2066static const char *
2067get_alpha_dynamic_type (unsigned long type)
2068{
2069 switch (type)
2070 {
2071 case DT_ALPHA_PLTRO: return "ALPHA_PLTRO";
32ec8896 2072 default: return NULL;
fabcb361
RH
2073 }
2074}
2075
1c0d3aa6
NC
2076static const char *
2077get_score_dynamic_type (unsigned long type)
2078{
2079 switch (type)
2080 {
2081 case DT_SCORE_BASE_ADDRESS: return "SCORE_BASE_ADDRESS";
2082 case DT_SCORE_LOCAL_GOTNO: return "SCORE_LOCAL_GOTNO";
2083 case DT_SCORE_SYMTABNO: return "SCORE_SYMTABNO";
2084 case DT_SCORE_GOTSYM: return "SCORE_GOTSYM";
2085 case DT_SCORE_UNREFEXTNO: return "SCORE_UNREFEXTNO";
2086 case DT_SCORE_HIPAGENO: return "SCORE_HIPAGENO";
32ec8896 2087 default: return NULL;
1c0d3aa6
NC
2088 }
2089}
2090
40b36596
JM
2091static const char *
2092get_tic6x_dynamic_type (unsigned long type)
2093{
2094 switch (type)
2095 {
2096 case DT_C6000_GSYM_OFFSET: return "C6000_GSYM_OFFSET";
2097 case DT_C6000_GSTR_OFFSET: return "C6000_GSTR_OFFSET";
2098 case DT_C6000_DSBT_BASE: return "C6000_DSBT_BASE";
2099 case DT_C6000_DSBT_SIZE: return "C6000_DSBT_SIZE";
2100 case DT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
2101 case DT_C6000_DSBT_INDEX: return "C6000_DSBT_INDEX";
32ec8896 2102 default: return NULL;
40b36596
JM
2103 }
2104}
1c0d3aa6 2105
36591ba1
SL
2106static const char *
2107get_nios2_dynamic_type (unsigned long type)
2108{
2109 switch (type)
2110 {
2111 case DT_NIOS2_GP: return "NIOS2_GP";
32ec8896 2112 default: return NULL;
36591ba1
SL
2113 }
2114}
2115
fd85a6a1
NC
2116static const char *
2117get_solaris_dynamic_type (unsigned long type)
2118{
2119 switch (type)
2120 {
2121 case 0x6000000d: return "SUNW_AUXILIARY";
2122 case 0x6000000e: return "SUNW_RTLDINF";
2123 case 0x6000000f: return "SUNW_FILTER";
2124 case 0x60000010: return "SUNW_CAP";
2125 case 0x60000011: return "SUNW_SYMTAB";
2126 case 0x60000012: return "SUNW_SYMSZ";
2127 case 0x60000013: return "SUNW_SORTENT";
2128 case 0x60000014: return "SUNW_SYMSORT";
2129 case 0x60000015: return "SUNW_SYMSORTSZ";
2130 case 0x60000016: return "SUNW_TLSSORT";
2131 case 0x60000017: return "SUNW_TLSSORTSZ";
2132 case 0x60000018: return "SUNW_CAPINFO";
2133 case 0x60000019: return "SUNW_STRPAD";
2134 case 0x6000001a: return "SUNW_CAPCHAIN";
2135 case 0x6000001b: return "SUNW_LDMACH";
2136 case 0x6000001d: return "SUNW_CAPCHAINENT";
2137 case 0x6000001f: return "SUNW_CAPCHAINSZ";
2138 case 0x60000021: return "SUNW_PARENT";
2139 case 0x60000023: return "SUNW_ASLR";
2140 case 0x60000025: return "SUNW_RELAX";
2141 case 0x60000029: return "SUNW_NXHEAP";
2142 case 0x6000002b: return "SUNW_NXSTACK";
2143
2144 case 0x70000001: return "SPARC_REGISTER";
2145 case 0x7ffffffd: return "AUXILIARY";
2146 case 0x7ffffffe: return "USED";
2147 case 0x7fffffff: return "FILTER";
2148
15f205b1 2149 default: return NULL;
fd85a6a1
NC
2150 }
2151}
2152
252b5132 2153static const char *
dda8d76d 2154get_dynamic_type (Filedata * filedata, unsigned long type)
252b5132 2155{
e9e44622 2156 static char buff[64];
252b5132
RH
2157
2158 switch (type)
2159 {
2160 case DT_NULL: return "NULL";
2161 case DT_NEEDED: return "NEEDED";
2162 case DT_PLTRELSZ: return "PLTRELSZ";
2163 case DT_PLTGOT: return "PLTGOT";
2164 case DT_HASH: return "HASH";
2165 case DT_STRTAB: return "STRTAB";
2166 case DT_SYMTAB: return "SYMTAB";
2167 case DT_RELA: return "RELA";
2168 case DT_RELASZ: return "RELASZ";
2169 case DT_RELAENT: return "RELAENT";
2170 case DT_STRSZ: return "STRSZ";
2171 case DT_SYMENT: return "SYMENT";
2172 case DT_INIT: return "INIT";
2173 case DT_FINI: return "FINI";
2174 case DT_SONAME: return "SONAME";
2175 case DT_RPATH: return "RPATH";
2176 case DT_SYMBOLIC: return "SYMBOLIC";
2177 case DT_REL: return "REL";
2178 case DT_RELSZ: return "RELSZ";
2179 case DT_RELENT: return "RELENT";
2180 case DT_PLTREL: return "PLTREL";
2181 case DT_DEBUG: return "DEBUG";
2182 case DT_TEXTREL: return "TEXTREL";
2183 case DT_JMPREL: return "JMPREL";
2184 case DT_BIND_NOW: return "BIND_NOW";
2185 case DT_INIT_ARRAY: return "INIT_ARRAY";
2186 case DT_FINI_ARRAY: return "FINI_ARRAY";
2187 case DT_INIT_ARRAYSZ: return "INIT_ARRAYSZ";
2188 case DT_FINI_ARRAYSZ: return "FINI_ARRAYSZ";
d1133906
NC
2189 case DT_RUNPATH: return "RUNPATH";
2190 case DT_FLAGS: return "FLAGS";
2d0e6f43 2191
d1133906
NC
2192 case DT_PREINIT_ARRAY: return "PREINIT_ARRAY";
2193 case DT_PREINIT_ARRAYSZ: return "PREINIT_ARRAYSZ";
6d913794 2194 case DT_SYMTAB_SHNDX: return "SYMTAB_SHNDX";
103f02d3 2195
05107a46 2196 case DT_CHECKSUM: return "CHECKSUM";
252b5132
RH
2197 case DT_PLTPADSZ: return "PLTPADSZ";
2198 case DT_MOVEENT: return "MOVEENT";
2199 case DT_MOVESZ: return "MOVESZ";
dcefbbbd 2200 case DT_FEATURE: return "FEATURE";
252b5132
RH
2201 case DT_POSFLAG_1: return "POSFLAG_1";
2202 case DT_SYMINSZ: return "SYMINSZ";
2203 case DT_SYMINENT: return "SYMINENT"; /* aka VALRNGHI */
103f02d3 2204
252b5132 2205 case DT_ADDRRNGLO: return "ADDRRNGLO";
dcefbbbd
L
2206 case DT_CONFIG: return "CONFIG";
2207 case DT_DEPAUDIT: return "DEPAUDIT";
2208 case DT_AUDIT: return "AUDIT";
2209 case DT_PLTPAD: return "PLTPAD";
2210 case DT_MOVETAB: return "MOVETAB";
252b5132 2211 case DT_SYMINFO: return "SYMINFO"; /* aka ADDRRNGHI */
103f02d3 2212
252b5132 2213 case DT_VERSYM: return "VERSYM";
103f02d3 2214
67a4f2b7
AO
2215 case DT_TLSDESC_GOT: return "TLSDESC_GOT";
2216 case DT_TLSDESC_PLT: return "TLSDESC_PLT";
252b5132
RH
2217 case DT_RELACOUNT: return "RELACOUNT";
2218 case DT_RELCOUNT: return "RELCOUNT";
2219 case DT_FLAGS_1: return "FLAGS_1";
2220 case DT_VERDEF: return "VERDEF";
2221 case DT_VERDEFNUM: return "VERDEFNUM";
2222 case DT_VERNEED: return "VERNEED";
2223 case DT_VERNEEDNUM: return "VERNEEDNUM";
103f02d3 2224
019148e4 2225 case DT_AUXILIARY: return "AUXILIARY";
252b5132
RH
2226 case DT_USED: return "USED";
2227 case DT_FILTER: return "FILTER";
103f02d3 2228
047b2264
JJ
2229 case DT_GNU_PRELINKED: return "GNU_PRELINKED";
2230 case DT_GNU_CONFLICT: return "GNU_CONFLICT";
2231 case DT_GNU_CONFLICTSZ: return "GNU_CONFLICTSZ";
2232 case DT_GNU_LIBLIST: return "GNU_LIBLIST";
2233 case DT_GNU_LIBLISTSZ: return "GNU_LIBLISTSZ";
fdc90cb4 2234 case DT_GNU_HASH: return "GNU_HASH";
a5da3dee 2235 case DT_GNU_FLAGS_1: return "GNU_FLAGS_1";
047b2264 2236
252b5132
RH
2237 default:
2238 if ((type >= DT_LOPROC) && (type <= DT_HIPROC))
2239 {
2cf0635d 2240 const char * result;
103f02d3 2241
dda8d76d 2242 switch (filedata->file_header.e_machine)
252b5132 2243 {
37c18eed
SD
2244 case EM_AARCH64:
2245 result = get_aarch64_dynamic_type (type);
2246 break;
252b5132 2247 case EM_MIPS:
4fe85591 2248 case EM_MIPS_RS3_LE:
252b5132
RH
2249 result = get_mips_dynamic_type (type);
2250 break;
9a097730
RH
2251 case EM_SPARCV9:
2252 result = get_sparc64_dynamic_type (type);
2253 break;
7490d522
AM
2254 case EM_PPC:
2255 result = get_ppc_dynamic_type (type);
2256 break;
f1cb7e17
AM
2257 case EM_PPC64:
2258 result = get_ppc64_dynamic_type (type);
2259 break;
ecc51f48
NC
2260 case EM_IA_64:
2261 result = get_ia64_dynamic_type (type);
2262 break;
fabcb361
RH
2263 case EM_ALPHA:
2264 result = get_alpha_dynamic_type (type);
2265 break;
1c0d3aa6
NC
2266 case EM_SCORE:
2267 result = get_score_dynamic_type (type);
2268 break;
40b36596
JM
2269 case EM_TI_C6000:
2270 result = get_tic6x_dynamic_type (type);
2271 break;
36591ba1
SL
2272 case EM_ALTERA_NIOS2:
2273 result = get_nios2_dynamic_type (type);
2274 break;
252b5132 2275 default:
dda8d76d 2276 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2277 result = get_solaris_dynamic_type (type);
2278 else
2279 result = NULL;
252b5132
RH
2280 break;
2281 }
2282
2283 if (result != NULL)
2284 return result;
2285
e9e44622 2286 snprintf (buff, sizeof (buff), _("Processor Specific: %lx"), type);
252b5132 2287 }
eec8f817 2288 else if (((type >= DT_LOOS) && (type <= DT_HIOS))
dda8d76d 2289 || (filedata->file_header.e_machine == EM_PARISC
eec8f817 2290 && (type >= OLD_DT_LOOS) && (type <= OLD_DT_HIOS)))
103f02d3 2291 {
2cf0635d 2292 const char * result;
103f02d3 2293
dda8d76d 2294 switch (filedata->file_header.e_machine)
103f02d3
UD
2295 {
2296 case EM_PARISC:
2297 result = get_parisc_dynamic_type (type);
2298 break;
148b93f2
NC
2299 case EM_IA_64:
2300 result = get_ia64_dynamic_type (type);
2301 break;
103f02d3 2302 default:
dda8d76d 2303 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
2304 result = get_solaris_dynamic_type (type);
2305 else
2306 result = NULL;
103f02d3
UD
2307 break;
2308 }
2309
2310 if (result != NULL)
2311 return result;
2312
e9e44622
JJ
2313 snprintf (buff, sizeof (buff), _("Operating System specific: %lx"),
2314 type);
103f02d3 2315 }
252b5132 2316 else
e9e44622 2317 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), type);
103f02d3 2318
252b5132
RH
2319 return buff;
2320 }
2321}
2322
2323static char *
d3ba0551 2324get_file_type (unsigned e_type)
252b5132 2325{
89246a0e 2326 static char buff[64];
252b5132
RH
2327
2328 switch (e_type)
2329 {
32ec8896
NC
2330 case ET_NONE: return _("NONE (None)");
2331 case ET_REL: return _("REL (Relocatable file)");
2332 case ET_EXEC: return _("EXEC (Executable file)");
2333 case ET_DYN: return _("DYN (Shared object file)");
2334 case ET_CORE: return _("CORE (Core file)");
252b5132
RH
2335
2336 default:
2337 if ((e_type >= ET_LOPROC) && (e_type <= ET_HIPROC))
e9e44622 2338 snprintf (buff, sizeof (buff), _("Processor Specific: (%x)"), e_type);
252b5132 2339 else if ((e_type >= ET_LOOS) && (e_type <= ET_HIOS))
e9e44622 2340 snprintf (buff, sizeof (buff), _("OS Specific: (%x)"), e_type);
252b5132 2341 else
e9e44622 2342 snprintf (buff, sizeof (buff), _("<unknown>: %x"), e_type);
252b5132
RH
2343 return buff;
2344 }
2345}
2346
2347static char *
d3ba0551 2348get_machine_name (unsigned e_machine)
252b5132 2349{
b34976b6 2350 static char buff[64]; /* XXX */
252b5132
RH
2351
2352 switch (e_machine)
2353 {
55e22ca8
NC
2354 /* Please keep this switch table sorted by increasing EM_ value. */
2355 /* 0 */
c45021f2
NC
2356 case EM_NONE: return _("None");
2357 case EM_M32: return "WE32100";
2358 case EM_SPARC: return "Sparc";
2359 case EM_386: return "Intel 80386";
2360 case EM_68K: return "MC68000";
2361 case EM_88K: return "MC88000";
22abe556 2362 case EM_IAMCU: return "Intel MCU";
fb70ec17 2363 case EM_860: return "Intel 80860";
c45021f2
NC
2364 case EM_MIPS: return "MIPS R3000";
2365 case EM_S370: return "IBM System/370";
55e22ca8 2366 /* 10 */
7036c0e1 2367 case EM_MIPS_RS3_LE: return "MIPS R4000 big-endian";
252b5132 2368 case EM_OLD_SPARCV9: return "Sparc v9 (old)";
c45021f2 2369 case EM_PARISC: return "HPPA";
55e22ca8 2370 case EM_VPP550: return "Fujitsu VPP500";
7036c0e1 2371 case EM_SPARC32PLUS: return "Sparc v8+" ;
d7867d17 2372 case EM_960: return "Intel 80960";
c45021f2 2373 case EM_PPC: return "PowerPC";
55e22ca8 2374 /* 20 */
285d1771 2375 case EM_PPC64: return "PowerPC64";
55e22ca8
NC
2376 case EM_S390_OLD:
2377 case EM_S390: return "IBM S/390";
2378 case EM_SPU: return "SPU";
2379 /* 30 */
2380 case EM_V800: return "Renesas V850 (using RH850 ABI)";
c45021f2
NC
2381 case EM_FR20: return "Fujitsu FR20";
2382 case EM_RH32: return "TRW RH32";
b34976b6 2383 case EM_MCORE: return "MCORE";
55e22ca8 2384 /* 40 */
7036c0e1
AJ
2385 case EM_ARM: return "ARM";
2386 case EM_OLD_ALPHA: return "Digital Alpha (old)";
ef230218 2387 case EM_SH: return "Renesas / SuperH SH";
c45021f2
NC
2388 case EM_SPARCV9: return "Sparc v9";
2389 case EM_TRICORE: return "Siemens Tricore";
584da044 2390 case EM_ARC: return "ARC";
c2dcd04e
NC
2391 case EM_H8_300: return "Renesas H8/300";
2392 case EM_H8_300H: return "Renesas H8/300H";
2393 case EM_H8S: return "Renesas H8S";
2394 case EM_H8_500: return "Renesas H8/500";
55e22ca8 2395 /* 50 */
30800947 2396 case EM_IA_64: return "Intel IA-64";
252b5132
RH
2397 case EM_MIPS_X: return "Stanford MIPS-X";
2398 case EM_COLDFIRE: return "Motorola Coldfire";
55e22ca8 2399 case EM_68HC12: return "Motorola MC68HC12 Microcontroller";
7036c0e1
AJ
2400 case EM_MMA: return "Fujitsu Multimedia Accelerator";
2401 case EM_PCP: return "Siemens PCP";
2402 case EM_NCPU: return "Sony nCPU embedded RISC processor";
2403 case EM_NDR1: return "Denso NDR1 microprocesspr";
2404 case EM_STARCORE: return "Motorola Star*Core processor";
2405 case EM_ME16: return "Toyota ME16 processor";
55e22ca8 2406 /* 60 */
7036c0e1
AJ
2407 case EM_ST100: return "STMicroelectronics ST100 processor";
2408 case EM_TINYJ: return "Advanced Logic Corp. TinyJ embedded processor";
55e22ca8 2409 case EM_X86_64: return "Advanced Micro Devices X86-64";
11636f9e
JM
2410 case EM_PDSP: return "Sony DSP processor";
2411 case EM_PDP10: return "Digital Equipment Corp. PDP-10";
2412 case EM_PDP11: return "Digital Equipment Corp. PDP-11";
7036c0e1
AJ
2413 case EM_FX66: return "Siemens FX66 microcontroller";
2414 case EM_ST9PLUS: return "STMicroelectronics ST9+ 8/16 bit microcontroller";
2415 case EM_ST7: return "STMicroelectronics ST7 8-bit microcontroller";
2416 case EM_68HC16: return "Motorola MC68HC16 Microcontroller";
55e22ca8 2417 /* 70 */
7036c0e1
AJ
2418 case EM_68HC11: return "Motorola MC68HC11 Microcontroller";
2419 case EM_68HC08: return "Motorola MC68HC08 Microcontroller";
2420 case EM_68HC05: return "Motorola MC68HC05 Microcontroller";
2421 case EM_SVX: return "Silicon Graphics SVx";
2422 case EM_ST19: return "STMicroelectronics ST19 8-bit microcontroller";
2423 case EM_VAX: return "Digital VAX";
1b61cf92 2424 case EM_CRIS: return "Axis Communications 32-bit embedded processor";
c45021f2
NC
2425 case EM_JAVELIN: return "Infineon Technologies 32-bit embedded cpu";
2426 case EM_FIREPATH: return "Element 14 64-bit DSP processor";
2427 case EM_ZSP: return "LSI Logic's 16-bit DSP processor";
55e22ca8 2428 /* 80 */
b34976b6 2429 case EM_MMIX: return "Donald Knuth's educational 64-bit processor";
c45021f2 2430 case EM_HUANY: return "Harvard Universitys's machine-independent object format";
3b36097d 2431 case EM_PRISM: return "Vitesse Prism";
55e22ca8
NC
2432 case EM_AVR_OLD:
2433 case EM_AVR: return "Atmel AVR 8-bit microcontroller";
2434 case EM_CYGNUS_FR30:
2435 case EM_FR30: return "Fujitsu FR30";
2436 case EM_CYGNUS_D10V:
2437 case EM_D10V: return "d10v";
2438 case EM_CYGNUS_D30V:
2439 case EM_D30V: return "d30v";
2440 case EM_CYGNUS_V850:
2441 case EM_V850: return "Renesas V850";
2442 case EM_CYGNUS_M32R:
2443 case EM_M32R: return "Renesas M32R (formerly Mitsubishi M32r)";
2444 case EM_CYGNUS_MN10300:
2445 case EM_MN10300: return "mn10300";
2446 /* 90 */
2447 case EM_CYGNUS_MN10200:
2448 case EM_MN10200: return "mn10200";
2449 case EM_PJ: return "picoJava";
73589c9d 2450 case EM_OR1K: return "OpenRISC 1000";
55e22ca8 2451 case EM_ARC_COMPACT: return "ARCompact";
88da6820
NC
2452 case EM_XTENSA_OLD:
2453 case EM_XTENSA: return "Tensilica Xtensa Processor";
11636f9e
JM
2454 case EM_VIDEOCORE: return "Alphamosaic VideoCore processor";
2455 case EM_TMM_GPP: return "Thompson Multimedia General Purpose Processor";
2456 case EM_NS32K: return "National Semiconductor 32000 series";
2457 case EM_TPC: return "Tenor Network TPC processor";
55e22ca8
NC
2458 case EM_SNP1K: return "Trebia SNP 1000 processor";
2459 /* 100 */
9abca702 2460 case EM_ST200: return "STMicroelectronics ST200 microcontroller";
55e22ca8
NC
2461 case EM_IP2K_OLD:
2462 case EM_IP2K: return "Ubicom IP2xxx 8-bit microcontrollers";
11636f9e
JM
2463 case EM_MAX: return "MAX Processor";
2464 case EM_CR: return "National Semiconductor CompactRISC";
2465 case EM_F2MC16: return "Fujitsu F2MC16";
2466 case EM_MSP430: return "Texas Instruments msp430 microcontroller";
7bbe5bc5 2467 case EM_BLACKFIN: return "Analog Devices Blackfin";
11636f9e
JM
2468 case EM_SE_C33: return "S1C33 Family of Seiko Epson processors";
2469 case EM_SEP: return "Sharp embedded microprocessor";
2470 case EM_ARCA: return "Arca RISC microprocessor";
55e22ca8 2471 /* 110 */
11636f9e
JM
2472 case EM_UNICORE: return "Unicore";
2473 case EM_EXCESS: return "eXcess 16/32/64-bit configurable embedded CPU";
2474 case EM_DXP: return "Icera Semiconductor Inc. Deep Execution Processor";
64fd6348 2475 case EM_ALTERA_NIOS2: return "Altera Nios II";
55e22ca8
NC
2476 case EM_CRX: return "National Semiconductor CRX microprocessor";
2477 case EM_XGATE: return "Motorola XGATE embedded processor";
c29aca4a 2478 case EM_C166:
d70c5fc7 2479 case EM_XC16X: return "Infineon Technologies xc16x";
11636f9e
JM
2480 case EM_M16C: return "Renesas M16C series microprocessors";
2481 case EM_DSPIC30F: return "Microchip Technology dsPIC30F Digital Signal Controller";
2482 case EM_CE: return "Freescale Communication Engine RISC core";
55e22ca8
NC
2483 /* 120 */
2484 case EM_M32C: return "Renesas M32c";
2485 /* 130 */
11636f9e
JM
2486 case EM_TSK3000: return "Altium TSK3000 core";
2487 case EM_RS08: return "Freescale RS08 embedded processor";
2488 case EM_ECOG2: return "Cyan Technology eCOG2 microprocessor";
55e22ca8 2489 case EM_SCORE: return "SUNPLUS S+Core";
11636f9e
JM
2490 case EM_DSP24: return "New Japan Radio (NJR) 24-bit DSP Processor";
2491 case EM_VIDEOCORE3: return "Broadcom VideoCore III processor";
55e22ca8 2492 case EM_LATTICEMICO32: return "Lattice Mico32";
11636f9e 2493 case EM_SE_C17: return "Seiko Epson C17 family";
55e22ca8 2494 /* 140 */
11636f9e
JM
2495 case EM_TI_C6000: return "Texas Instruments TMS320C6000 DSP family";
2496 case EM_TI_C2000: return "Texas Instruments TMS320C2000 DSP family";
2497 case EM_TI_C5500: return "Texas Instruments TMS320C55x DSP family";
55e22ca8
NC
2498 case EM_TI_PRU: return "TI PRU I/O processor";
2499 /* 160 */
11636f9e
JM
2500 case EM_MMDSP_PLUS: return "STMicroelectronics 64bit VLIW Data Signal Processor";
2501 case EM_CYPRESS_M8C: return "Cypress M8C microprocessor";
2502 case EM_R32C: return "Renesas R32C series microprocessors";
2503 case EM_TRIMEDIA: return "NXP Semiconductors TriMedia architecture family";
2504 case EM_QDSP6: return "QUALCOMM DSP6 Processor";
2505 case EM_8051: return "Intel 8051 and variants";
2506 case EM_STXP7X: return "STMicroelectronics STxP7x family";
2507 case EM_NDS32: return "Andes Technology compact code size embedded RISC processor family";
2508 case EM_ECOG1X: return "Cyan Technology eCOG1X family";
2509 case EM_MAXQ30: return "Dallas Semiconductor MAXQ30 Core microcontrollers";
55e22ca8 2510 /* 170 */
11636f9e
JM
2511 case EM_XIMO16: return "New Japan Radio (NJR) 16-bit DSP Processor";
2512 case EM_MANIK: return "M2000 Reconfigurable RISC Microprocessor";
2513 case EM_CRAYNV2: return "Cray Inc. NV2 vector architecture";
c7927a3c 2514 case EM_RX: return "Renesas RX";
a3c62988 2515 case EM_METAG: return "Imagination Technologies Meta processor architecture";
11636f9e
JM
2516 case EM_MCST_ELBRUS: return "MCST Elbrus general purpose hardware architecture";
2517 case EM_ECOG16: return "Cyan Technology eCOG16 family";
55e22ca8
NC
2518 case EM_CR16:
2519 case EM_MICROBLAZE:
2520 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
11636f9e
JM
2521 case EM_ETPU: return "Freescale Extended Time Processing Unit";
2522 case EM_SLE9X: return "Infineon Technologies SLE9X core";
55e22ca8
NC
2523 /* 180 */
2524 case EM_L1OM: return "Intel L1OM";
2525 case EM_K1OM: return "Intel K1OM";
2526 case EM_INTEL182: return "Intel (reserved)";
2527 case EM_AARCH64: return "AArch64";
2528 case EM_ARM184: return "ARM (reserved)";
2529 case EM_AVR32: return "Atmel Corporation 32-bit microprocessor";
11636f9e
JM
2530 case EM_STM8: return "STMicroeletronics STM8 8-bit microcontroller";
2531 case EM_TILE64: return "Tilera TILE64 multicore architecture family";
2532 case EM_TILEPRO: return "Tilera TILEPro multicore architecture family";
55e22ca8 2533 /* 190 */
11636f9e 2534 case EM_CUDA: return "NVIDIA CUDA architecture";
55e22ca8 2535 case EM_TILEGX: return "Tilera TILE-Gx multicore architecture family";
6d913794
NC
2536 case EM_CLOUDSHIELD: return "CloudShield architecture family";
2537 case EM_COREA_1ST: return "KIPO-KAIST Core-A 1st generation processor family";
2538 case EM_COREA_2ND: return "KIPO-KAIST Core-A 2nd generation processor family";
55e22ca8 2539 case EM_ARC_COMPACT2: return "ARCv2";
6d913794 2540 case EM_OPEN8: return "Open8 8-bit RISC soft processor core";
55e22ca8 2541 case EM_RL78: return "Renesas RL78";
6d913794 2542 case EM_VIDEOCORE5: return "Broadcom VideoCore V processor";
55e22ca8
NC
2543 case EM_78K0R: return "Renesas 78K0R";
2544 /* 200 */
6d913794 2545 case EM_56800EX: return "Freescale 56800EX Digital Signal Controller (DSC)";
15f205b1
NC
2546 case EM_BA1: return "Beyond BA1 CPU architecture";
2547 case EM_BA2: return "Beyond BA2 CPU architecture";
6d913794
NC
2548 case EM_XCORE: return "XMOS xCORE processor family";
2549 case EM_MCHP_PIC: return "Microchip 8-bit PIC(r) family";
55e22ca8 2550 /* 210 */
6d913794
NC
2551 case EM_KM32: return "KM211 KM32 32-bit processor";
2552 case EM_KMX32: return "KM211 KMX32 32-bit processor";
2553 case EM_KMX16: return "KM211 KMX16 16-bit processor";
2554 case EM_KMX8: return "KM211 KMX8 8-bit processor";
2555 case EM_KVARC: return "KM211 KVARC processor";
15f205b1 2556 case EM_CDP: return "Paneve CDP architecture family";
6d913794
NC
2557 case EM_COGE: return "Cognitive Smart Memory Processor";
2558 case EM_COOL: return "Bluechip Systems CoolEngine";
2559 case EM_NORC: return "Nanoradio Optimized RISC";
2560 case EM_CSR_KALIMBA: return "CSR Kalimba architecture family";
55e22ca8 2561 /* 220 */
15f205b1 2562 case EM_Z80: return "Zilog Z80";
55e22ca8
NC
2563 case EM_VISIUM: return "CDS VISIUMcore processor";
2564 case EM_FT32: return "FTDI Chip FT32";
2565 case EM_MOXIE: return "Moxie";
2566 case EM_AMDGPU: return "AMD GPU";
4cf2ad72
CC
2567 /* 230 (all reserved) */
2568 /* 240 */
55e22ca8
NC
2569 case EM_RISCV: return "RISC-V";
2570 case EM_LANAI: return "Lanai 32-bit processor";
4cf2ad72
CC
2571 case EM_CEVA: return "CEVA Processor Architecture Family";
2572 case EM_CEVA_X2: return "CEVA X2 Processor Family";
55e22ca8 2573 case EM_BPF: return "Linux BPF";
4cf2ad72
CC
2574 case EM_GRAPHCORE_IPU: return "Graphcore Intelligent Processing Unit";
2575 case EM_IMG1: return "Imagination Technologies";
2576 /* 250 */
fe944acf 2577 case EM_NFP: return "Netronome Flow Processor";
4cf2ad72
CC
2578 case EM_VE: return "NEC Vector Engine";
2579 case EM_CSKY: return "C-SKY";
2580 case EM_ARC_COMPACT3_64: return "Synopsys ARCv2.3 64-bit";
2581 case EM_MCS6502: return "MOS Technology MCS 6502 processor";
2582 case EM_ARC_COMPACT3: return "Synopsys ARCv2.3 32-bit";
2583 case EM_KVX: return "Kalray VLIW core of the MPPA processor family";
2584 case EM_65816: return "WDC 65816/65C816";
2585 case EM_LOONGARCH: return "Loongson Loongarch";
2586 case EM_KF32: return "ChipON KungFu32";
55e22ca8
NC
2587
2588 /* Large numbers... */
2589 case EM_MT: return "Morpho Techologies MT processor";
2590 case EM_ALPHA: return "Alpha";
2591 case EM_WEBASSEMBLY: return "Web Assembly";
9abca702 2592 case EM_DLX: return "OpenDLX";
55e22ca8
NC
2593 case EM_XSTORMY16: return "Sanyo XStormy16 CPU core";
2594 case EM_IQ2000: return "Vitesse IQ2000";
2595 case EM_M32C_OLD:
2596 case EM_NIOS32: return "Altera Nios";
2597 case EM_CYGNUS_MEP: return "Toshiba MeP Media Engine";
2598 case EM_ADAPTEVA_EPIPHANY: return "Adapteva EPIPHANY";
2599 case EM_CYGNUS_FRV: return "Fujitsu FR-V";
637b1970 2600 case EM_S12Z: return "Freescale S12Z";
55e22ca8 2601
252b5132 2602 default:
35d9dd2f 2603 snprintf (buff, sizeof (buff), _("<unknown>: 0x%x"), e_machine);
252b5132
RH
2604 return buff;
2605 }
2606}
2607
a9522a21
AB
2608static void
2609decode_ARC_machine_flags (unsigned e_flags, unsigned e_machine, char buf[])
2610{
2611 /* ARC has two machine types EM_ARC_COMPACT and EM_ARC_COMPACT2. Some
6987d5a1 2612 other compilers don't specify an architecture type in the e_flags, and
a9522a21
AB
2613 instead use EM_ARC_COMPACT for old ARC600, ARC601, and ARC700
2614 architectures, and switch to EM_ARC_COMPACT2 for newer ARCEM and ARCHS
2615 architectures.
2616
2617 Th GNU tools follows this use of EM_ARC_COMPACT and EM_ARC_COMPACT2,
2618 but also sets a specific architecture type in the e_flags field.
2619
2620 However, when decoding the flags we don't worry if we see an
2621 unexpected pairing, for example EM_ARC_COMPACT machine type, with
2622 ARCEM architecture type. */
2623
2624 switch (e_flags & EF_ARC_MACH_MSK)
2625 {
2626 /* We only expect these to occur for EM_ARC_COMPACT2. */
2627 case EF_ARC_CPU_ARCV2EM:
2628 strcat (buf, ", ARC EM");
2629 break;
2630 case EF_ARC_CPU_ARCV2HS:
2631 strcat (buf, ", ARC HS");
2632 break;
2633
2634 /* We only expect these to occur for EM_ARC_COMPACT. */
2635 case E_ARC_MACH_ARC600:
2636 strcat (buf, ", ARC600");
2637 break;
2638 case E_ARC_MACH_ARC601:
2639 strcat (buf, ", ARC601");
2640 break;
2641 case E_ARC_MACH_ARC700:
2642 strcat (buf, ", ARC700");
2643 break;
2644
2645 /* The only times we should end up here are (a) A corrupt ELF, (b) A
2646 new ELF with new architecture being read by an old version of
2647 readelf, or (c) An ELF built with non-GNU compiler that does not
2648 set the architecture in the e_flags. */
2649 default:
2650 if (e_machine == EM_ARC_COMPACT)
2651 strcat (buf, ", Unknown ARCompact");
2652 else
2653 strcat (buf, ", Unknown ARC");
2654 break;
2655 }
2656
2657 switch (e_flags & EF_ARC_OSABI_MSK)
2658 {
2659 case E_ARC_OSABI_ORIG:
2660 strcat (buf, ", (ABI:legacy)");
2661 break;
2662 case E_ARC_OSABI_V2:
2663 strcat (buf, ", (ABI:v2)");
2664 break;
2665 /* Only upstream 3.9+ kernels will support ARCv2 ISA. */
2666 case E_ARC_OSABI_V3:
2667 strcat (buf, ", v3 no-legacy-syscalls ABI");
2668 break;
53a346d8
CZ
2669 case E_ARC_OSABI_V4:
2670 strcat (buf, ", v4 ABI");
2671 break;
a9522a21
AB
2672 default:
2673 strcat (buf, ", unrecognised ARC OSABI flag");
2674 break;
2675 }
2676}
2677
f3485b74 2678static void
d3ba0551 2679decode_ARM_machine_flags (unsigned e_flags, char buf[])
f3485b74
NC
2680{
2681 unsigned eabi;
32ec8896 2682 bfd_boolean unknown = FALSE;
f3485b74
NC
2683
2684 eabi = EF_ARM_EABI_VERSION (e_flags);
2685 e_flags &= ~ EF_ARM_EABIMASK;
2686
2687 /* Handle "generic" ARM flags. */
2688 if (e_flags & EF_ARM_RELEXEC)
2689 {
2690 strcat (buf, ", relocatable executable");
2691 e_flags &= ~ EF_ARM_RELEXEC;
2692 }
76da6bbe 2693
18a20338
CL
2694 if (e_flags & EF_ARM_PIC)
2695 {
2696 strcat (buf, ", position independent");
2697 e_flags &= ~ EF_ARM_PIC;
2698 }
2699
f3485b74
NC
2700 /* Now handle EABI specific flags. */
2701 switch (eabi)
2702 {
2703 default:
2c71103e 2704 strcat (buf, ", <unrecognized EABI>");
f3485b74 2705 if (e_flags)
32ec8896 2706 unknown = TRUE;
f3485b74
NC
2707 break;
2708
2709 case EF_ARM_EABI_VER1:
a5bcd848 2710 strcat (buf, ", Version1 EABI");
f3485b74
NC
2711 while (e_flags)
2712 {
2713 unsigned flag;
76da6bbe 2714
f3485b74
NC
2715 /* Process flags one bit at a time. */
2716 flag = e_flags & - e_flags;
2717 e_flags &= ~ flag;
76da6bbe 2718
f3485b74
NC
2719 switch (flag)
2720 {
a5bcd848 2721 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
f3485b74
NC
2722 strcat (buf, ", sorted symbol tables");
2723 break;
76da6bbe 2724
f3485b74 2725 default:
32ec8896 2726 unknown = TRUE;
f3485b74
NC
2727 break;
2728 }
2729 }
2730 break;
76da6bbe 2731
a5bcd848
PB
2732 case EF_ARM_EABI_VER2:
2733 strcat (buf, ", Version2 EABI");
2734 while (e_flags)
2735 {
2736 unsigned flag;
2737
2738 /* Process flags one bit at a time. */
2739 flag = e_flags & - e_flags;
2740 e_flags &= ~ flag;
2741
2742 switch (flag)
2743 {
2744 case EF_ARM_SYMSARESORTED: /* Conflicts with EF_ARM_INTERWORK. */
2745 strcat (buf, ", sorted symbol tables");
2746 break;
2747
2748 case EF_ARM_DYNSYMSUSESEGIDX:
2749 strcat (buf, ", dynamic symbols use segment index");
2750 break;
2751
2752 case EF_ARM_MAPSYMSFIRST:
2753 strcat (buf, ", mapping symbols precede others");
2754 break;
2755
2756 default:
32ec8896 2757 unknown = TRUE;
a5bcd848
PB
2758 break;
2759 }
2760 }
2761 break;
2762
d507cf36
PB
2763 case EF_ARM_EABI_VER3:
2764 strcat (buf, ", Version3 EABI");
8cb51566
PB
2765 break;
2766
2767 case EF_ARM_EABI_VER4:
2768 strcat (buf, ", Version4 EABI");
3bfcb652
NC
2769 while (e_flags)
2770 {
2771 unsigned flag;
2772
2773 /* Process flags one bit at a time. */
2774 flag = e_flags & - e_flags;
2775 e_flags &= ~ flag;
2776
2777 switch (flag)
2778 {
2779 case EF_ARM_BE8:
2780 strcat (buf, ", BE8");
2781 break;
2782
2783 case EF_ARM_LE8:
2784 strcat (buf, ", LE8");
2785 break;
2786
2787 default:
32ec8896 2788 unknown = TRUE;
3bfcb652
NC
2789 break;
2790 }
3bfcb652
NC
2791 }
2792 break;
3a4a14e9
PB
2793
2794 case EF_ARM_EABI_VER5:
2795 strcat (buf, ", Version5 EABI");
d507cf36
PB
2796 while (e_flags)
2797 {
2798 unsigned flag;
2799
2800 /* Process flags one bit at a time. */
2801 flag = e_flags & - e_flags;
2802 e_flags &= ~ flag;
2803
2804 switch (flag)
2805 {
2806 case EF_ARM_BE8:
2807 strcat (buf, ", BE8");
2808 break;
2809
2810 case EF_ARM_LE8:
2811 strcat (buf, ", LE8");
2812 break;
2813
3bfcb652
NC
2814 case EF_ARM_ABI_FLOAT_SOFT: /* Conflicts with EF_ARM_SOFT_FLOAT. */
2815 strcat (buf, ", soft-float ABI");
2816 break;
2817
2818 case EF_ARM_ABI_FLOAT_HARD: /* Conflicts with EF_ARM_VFP_FLOAT. */
2819 strcat (buf, ", hard-float ABI");
2820 break;
2821
d507cf36 2822 default:
32ec8896 2823 unknown = TRUE;
d507cf36
PB
2824 break;
2825 }
2826 }
2827 break;
2828
f3485b74 2829 case EF_ARM_EABI_UNKNOWN:
a5bcd848 2830 strcat (buf, ", GNU EABI");
f3485b74
NC
2831 while (e_flags)
2832 {
2833 unsigned flag;
76da6bbe 2834
f3485b74
NC
2835 /* Process flags one bit at a time. */
2836 flag = e_flags & - e_flags;
2837 e_flags &= ~ flag;
76da6bbe 2838
f3485b74
NC
2839 switch (flag)
2840 {
a5bcd848 2841 case EF_ARM_INTERWORK:
f3485b74
NC
2842 strcat (buf, ", interworking enabled");
2843 break;
76da6bbe 2844
a5bcd848 2845 case EF_ARM_APCS_26:
f3485b74
NC
2846 strcat (buf, ", uses APCS/26");
2847 break;
76da6bbe 2848
a5bcd848 2849 case EF_ARM_APCS_FLOAT:
f3485b74
NC
2850 strcat (buf, ", uses APCS/float");
2851 break;
76da6bbe 2852
a5bcd848 2853 case EF_ARM_PIC:
f3485b74
NC
2854 strcat (buf, ", position independent");
2855 break;
76da6bbe 2856
a5bcd848 2857 case EF_ARM_ALIGN8:
f3485b74
NC
2858 strcat (buf, ", 8 bit structure alignment");
2859 break;
76da6bbe 2860
a5bcd848 2861 case EF_ARM_NEW_ABI:
f3485b74
NC
2862 strcat (buf, ", uses new ABI");
2863 break;
76da6bbe 2864
a5bcd848 2865 case EF_ARM_OLD_ABI:
f3485b74
NC
2866 strcat (buf, ", uses old ABI");
2867 break;
76da6bbe 2868
a5bcd848 2869 case EF_ARM_SOFT_FLOAT:
f3485b74
NC
2870 strcat (buf, ", software FP");
2871 break;
76da6bbe 2872
90e01f86
ILT
2873 case EF_ARM_VFP_FLOAT:
2874 strcat (buf, ", VFP");
2875 break;
2876
fde78edd
NC
2877 case EF_ARM_MAVERICK_FLOAT:
2878 strcat (buf, ", Maverick FP");
2879 break;
2880
f3485b74 2881 default:
32ec8896 2882 unknown = TRUE;
f3485b74
NC
2883 break;
2884 }
2885 }
2886 }
f3485b74
NC
2887
2888 if (unknown)
2b692964 2889 strcat (buf,_(", <unknown>"));
f3485b74
NC
2890}
2891
343433df
AB
2892static void
2893decode_AVR_machine_flags (unsigned e_flags, char buf[], size_t size)
2894{
2895 --size; /* Leave space for null terminator. */
2896
2897 switch (e_flags & EF_AVR_MACH)
2898 {
2899 case E_AVR_MACH_AVR1:
2900 strncat (buf, ", avr:1", size);
2901 break;
2902 case E_AVR_MACH_AVR2:
2903 strncat (buf, ", avr:2", size);
2904 break;
2905 case E_AVR_MACH_AVR25:
2906 strncat (buf, ", avr:25", size);
2907 break;
2908 case E_AVR_MACH_AVR3:
2909 strncat (buf, ", avr:3", size);
2910 break;
2911 case E_AVR_MACH_AVR31:
2912 strncat (buf, ", avr:31", size);
2913 break;
2914 case E_AVR_MACH_AVR35:
2915 strncat (buf, ", avr:35", size);
2916 break;
2917 case E_AVR_MACH_AVR4:
2918 strncat (buf, ", avr:4", size);
2919 break;
2920 case E_AVR_MACH_AVR5:
2921 strncat (buf, ", avr:5", size);
2922 break;
2923 case E_AVR_MACH_AVR51:
2924 strncat (buf, ", avr:51", size);
2925 break;
2926 case E_AVR_MACH_AVR6:
2927 strncat (buf, ", avr:6", size);
2928 break;
2929 case E_AVR_MACH_AVRTINY:
2930 strncat (buf, ", avr:100", size);
2931 break;
2932 case E_AVR_MACH_XMEGA1:
2933 strncat (buf, ", avr:101", size);
2934 break;
2935 case E_AVR_MACH_XMEGA2:
2936 strncat (buf, ", avr:102", size);
2937 break;
2938 case E_AVR_MACH_XMEGA3:
2939 strncat (buf, ", avr:103", size);
2940 break;
2941 case E_AVR_MACH_XMEGA4:
2942 strncat (buf, ", avr:104", size);
2943 break;
2944 case E_AVR_MACH_XMEGA5:
2945 strncat (buf, ", avr:105", size);
2946 break;
2947 case E_AVR_MACH_XMEGA6:
2948 strncat (buf, ", avr:106", size);
2949 break;
2950 case E_AVR_MACH_XMEGA7:
2951 strncat (buf, ", avr:107", size);
2952 break;
2953 default:
2954 strncat (buf, ", avr:<unknown>", size);
2955 break;
2956 }
2957
2958 size -= strlen (buf);
2959 if (e_flags & EF_AVR_LINKRELAX_PREPARED)
2960 strncat (buf, ", link-relax", size);
2961}
2962
35c08157
KLC
2963static void
2964decode_NDS32_machine_flags (unsigned e_flags, char buf[], size_t size)
2965{
2966 unsigned abi;
2967 unsigned arch;
2968 unsigned config;
2969 unsigned version;
32ec8896
NC
2970 bfd_boolean has_fpu = FALSE;
2971 unsigned int r = 0;
35c08157
KLC
2972
2973 static const char *ABI_STRINGS[] =
2974 {
2975 "ABI v0", /* use r5 as return register; only used in N1213HC */
2976 "ABI v1", /* use r0 as return register */
2977 "ABI v2", /* use r0 as return register and don't reserve 24 bytes for arguments */
2978 "ABI v2fp", /* for FPU */
40c7a7cb
KLC
2979 "AABI",
2980 "ABI2 FP+"
35c08157
KLC
2981 };
2982 static const char *VER_STRINGS[] =
2983 {
2984 "Andes ELF V1.3 or older",
2985 "Andes ELF V1.3.1",
2986 "Andes ELF V1.4"
2987 };
2988 static const char *ARCH_STRINGS[] =
2989 {
2990 "",
2991 "Andes Star v1.0",
2992 "Andes Star v2.0",
2993 "Andes Star v3.0",
2994 "Andes Star v3.0m"
2995 };
2996
2997 abi = EF_NDS_ABI & e_flags;
2998 arch = EF_NDS_ARCH & e_flags;
2999 config = EF_NDS_INST & e_flags;
3000 version = EF_NDS32_ELF_VERSION & e_flags;
3001
3002 memset (buf, 0, size);
3003
3004 switch (abi)
3005 {
3006 case E_NDS_ABI_V0:
3007 case E_NDS_ABI_V1:
3008 case E_NDS_ABI_V2:
3009 case E_NDS_ABI_V2FP:
3010 case E_NDS_ABI_AABI:
40c7a7cb 3011 case E_NDS_ABI_V2FP_PLUS:
35c08157
KLC
3012 /* In case there are holes in the array. */
3013 r += snprintf (buf + r, size - r, ", %s", ABI_STRINGS[abi >> EF_NDS_ABI_SHIFT]);
3014 break;
3015
3016 default:
3017 r += snprintf (buf + r, size - r, ", <unrecognized ABI>");
3018 break;
3019 }
3020
3021 switch (version)
3022 {
3023 case E_NDS32_ELF_VER_1_2:
3024 case E_NDS32_ELF_VER_1_3:
3025 case E_NDS32_ELF_VER_1_4:
3026 r += snprintf (buf + r, size - r, ", %s", VER_STRINGS[version >> EF_NDS32_ELF_VERSION_SHIFT]);
3027 break;
3028
3029 default:
3030 r += snprintf (buf + r, size - r, ", <unrecognized ELF version number>");
3031 break;
3032 }
3033
3034 if (E_NDS_ABI_V0 == abi)
3035 {
3036 /* OLD ABI; only used in N1213HC, has performance extension 1. */
3037 r += snprintf (buf + r, size - r, ", Andes Star v1.0, N1213HC, MAC, PERF1");
3038 if (arch == E_NDS_ARCH_STAR_V1_0)
3039 r += snprintf (buf + r, size -r, ", 16b"); /* has 16-bit instructions */
3040 return;
3041 }
3042
3043 switch (arch)
3044 {
3045 case E_NDS_ARCH_STAR_V1_0:
3046 case E_NDS_ARCH_STAR_V2_0:
3047 case E_NDS_ARCH_STAR_V3_0:
3048 case E_NDS_ARCH_STAR_V3_M:
3049 r += snprintf (buf + r, size - r, ", %s", ARCH_STRINGS[arch >> EF_NDS_ARCH_SHIFT]);
3050 break;
3051
3052 default:
3053 r += snprintf (buf + r, size - r, ", <unrecognized architecture>");
3054 /* ARCH version determines how the e_flags are interpreted.
3055 If it is unknown, we cannot proceed. */
3056 return;
3057 }
3058
3059 /* Newer ABI; Now handle architecture specific flags. */
3060 if (arch == E_NDS_ARCH_STAR_V1_0)
3061 {
3062 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3063 r += snprintf (buf + r, size -r, ", MFUSR_PC");
3064
3065 if (!(config & E_NDS32_HAS_NO_MAC_INST))
3066 r += snprintf (buf + r, size -r, ", MAC");
3067
3068 if (config & E_NDS32_HAS_DIV_INST)
3069 r += snprintf (buf + r, size -r, ", DIV");
3070
3071 if (config & E_NDS32_HAS_16BIT_INST)
3072 r += snprintf (buf + r, size -r, ", 16b");
3073 }
3074 else
3075 {
3076 if (config & E_NDS32_HAS_MFUSR_PC_INST)
3077 {
3078 if (version <= E_NDS32_ELF_VER_1_3)
3079 r += snprintf (buf + r, size -r, ", [B8]");
3080 else
3081 r += snprintf (buf + r, size -r, ", EX9");
3082 }
3083
3084 if (config & E_NDS32_HAS_MAC_DX_INST)
3085 r += snprintf (buf + r, size -r, ", MAC_DX");
3086
3087 if (config & E_NDS32_HAS_DIV_DX_INST)
3088 r += snprintf (buf + r, size -r, ", DIV_DX");
3089
3090 if (config & E_NDS32_HAS_16BIT_INST)
3091 {
3092 if (version <= E_NDS32_ELF_VER_1_3)
3093 r += snprintf (buf + r, size -r, ", 16b");
3094 else
3095 r += snprintf (buf + r, size -r, ", IFC");
3096 }
3097 }
3098
3099 if (config & E_NDS32_HAS_EXT_INST)
3100 r += snprintf (buf + r, size -r, ", PERF1");
3101
3102 if (config & E_NDS32_HAS_EXT2_INST)
3103 r += snprintf (buf + r, size -r, ", PERF2");
3104
3105 if (config & E_NDS32_HAS_FPU_INST)
3106 {
32ec8896 3107 has_fpu = TRUE;
35c08157
KLC
3108 r += snprintf (buf + r, size -r, ", FPU_SP");
3109 }
3110
3111 if (config & E_NDS32_HAS_FPU_DP_INST)
3112 {
32ec8896 3113 has_fpu = TRUE;
35c08157
KLC
3114 r += snprintf (buf + r, size -r, ", FPU_DP");
3115 }
3116
3117 if (config & E_NDS32_HAS_FPU_MAC_INST)
3118 {
32ec8896 3119 has_fpu = TRUE;
35c08157
KLC
3120 r += snprintf (buf + r, size -r, ", FPU_MAC");
3121 }
3122
3123 if (has_fpu)
3124 {
3125 switch ((config & E_NDS32_FPU_REG_CONF) >> E_NDS32_FPU_REG_CONF_SHIFT)
3126 {
3127 case E_NDS32_FPU_REG_8SP_4DP:
3128 r += snprintf (buf + r, size -r, ", FPU_REG:8/4");
3129 break;
3130 case E_NDS32_FPU_REG_16SP_8DP:
3131 r += snprintf (buf + r, size -r, ", FPU_REG:16/8");
3132 break;
3133 case E_NDS32_FPU_REG_32SP_16DP:
3134 r += snprintf (buf + r, size -r, ", FPU_REG:32/16");
3135 break;
3136 case E_NDS32_FPU_REG_32SP_32DP:
3137 r += snprintf (buf + r, size -r, ", FPU_REG:32/32");
3138 break;
3139 }
3140 }
3141
3142 if (config & E_NDS32_HAS_AUDIO_INST)
3143 r += snprintf (buf + r, size -r, ", AUDIO");
3144
3145 if (config & E_NDS32_HAS_STRING_INST)
3146 r += snprintf (buf + r, size -r, ", STR");
3147
3148 if (config & E_NDS32_HAS_REDUCED_REGS)
3149 r += snprintf (buf + r, size -r, ", 16REG");
3150
3151 if (config & E_NDS32_HAS_VIDEO_INST)
3152 {
3153 if (version <= E_NDS32_ELF_VER_1_3)
3154 r += snprintf (buf + r, size -r, ", VIDEO");
3155 else
3156 r += snprintf (buf + r, size -r, ", SATURATION");
3157 }
3158
3159 if (config & E_NDS32_HAS_ENCRIPT_INST)
3160 r += snprintf (buf + r, size -r, ", ENCRP");
3161
3162 if (config & E_NDS32_HAS_L2C_INST)
3163 r += snprintf (buf + r, size -r, ", L2C");
3164}
3165
252b5132 3166static char *
dda8d76d 3167get_machine_flags (Filedata * filedata, unsigned e_flags, unsigned e_machine)
252b5132 3168{
b34976b6 3169 static char buf[1024];
252b5132
RH
3170
3171 buf[0] = '\0';
76da6bbe 3172
252b5132
RH
3173 if (e_flags)
3174 {
3175 switch (e_machine)
3176 {
3177 default:
3178 break;
3179
886a2506 3180 case EM_ARC_COMPACT2:
886a2506 3181 case EM_ARC_COMPACT:
a9522a21
AB
3182 decode_ARC_machine_flags (e_flags, e_machine, buf);
3183 break;
886a2506 3184
f3485b74
NC
3185 case EM_ARM:
3186 decode_ARM_machine_flags (e_flags, buf);
3187 break;
76da6bbe 3188
343433df
AB
3189 case EM_AVR:
3190 decode_AVR_machine_flags (e_flags, buf, sizeof buf);
3191 break;
3192
781303ce
MF
3193 case EM_BLACKFIN:
3194 if (e_flags & EF_BFIN_PIC)
3195 strcat (buf, ", PIC");
3196
3197 if (e_flags & EF_BFIN_FDPIC)
3198 strcat (buf, ", FDPIC");
3199
3200 if (e_flags & EF_BFIN_CODE_IN_L1)
3201 strcat (buf, ", code in L1");
3202
3203 if (e_flags & EF_BFIN_DATA_IN_L1)
3204 strcat (buf, ", data in L1");
3205
3206 break;
3207
ec2dfb42
AO
3208 case EM_CYGNUS_FRV:
3209 switch (e_flags & EF_FRV_CPU_MASK)
3210 {
3211 case EF_FRV_CPU_GENERIC:
3212 break;
3213
3214 default:
3215 strcat (buf, ", fr???");
3216 break;
57346661 3217
ec2dfb42
AO
3218 case EF_FRV_CPU_FR300:
3219 strcat (buf, ", fr300");
3220 break;
3221
3222 case EF_FRV_CPU_FR400:
3223 strcat (buf, ", fr400");
3224 break;
3225 case EF_FRV_CPU_FR405:
3226 strcat (buf, ", fr405");
3227 break;
3228
3229 case EF_FRV_CPU_FR450:
3230 strcat (buf, ", fr450");
3231 break;
3232
3233 case EF_FRV_CPU_FR500:
3234 strcat (buf, ", fr500");
3235 break;
3236 case EF_FRV_CPU_FR550:
3237 strcat (buf, ", fr550");
3238 break;
3239
3240 case EF_FRV_CPU_SIMPLE:
3241 strcat (buf, ", simple");
3242 break;
3243 case EF_FRV_CPU_TOMCAT:
3244 strcat (buf, ", tomcat");
3245 break;
3246 }
1c877e87 3247 break;
ec2dfb42 3248
53c7db4b 3249 case EM_68K:
425c6cb0 3250 if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_M68000)
76f57f3a 3251 strcat (buf, ", m68000");
425c6cb0 3252 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_CPU32)
3bdcfdf4
KH
3253 strcat (buf, ", cpu32");
3254 else if ((e_flags & EF_M68K_ARCH_MASK) == EF_M68K_FIDO)
3255 strcat (buf, ", fido_a");
425c6cb0 3256 else
266abb8f 3257 {
2cf0635d
NC
3258 char const * isa = _("unknown");
3259 char const * mac = _("unknown mac");
3260 char const * additional = NULL;
0112cd26 3261
c694fd50 3262 switch (e_flags & EF_M68K_CF_ISA_MASK)
266abb8f 3263 {
c694fd50 3264 case EF_M68K_CF_ISA_A_NODIV:
0b2e31dc
NS
3265 isa = "A";
3266 additional = ", nodiv";
3267 break;
c694fd50 3268 case EF_M68K_CF_ISA_A:
266abb8f
NS
3269 isa = "A";
3270 break;
c694fd50 3271 case EF_M68K_CF_ISA_A_PLUS:
266abb8f
NS
3272 isa = "A+";
3273 break;
c694fd50 3274 case EF_M68K_CF_ISA_B_NOUSP:
0b2e31dc
NS
3275 isa = "B";
3276 additional = ", nousp";
3277 break;
c694fd50 3278 case EF_M68K_CF_ISA_B:
266abb8f
NS
3279 isa = "B";
3280 break;
f608cd77
NS
3281 case EF_M68K_CF_ISA_C:
3282 isa = "C";
3283 break;
3284 case EF_M68K_CF_ISA_C_NODIV:
3285 isa = "C";
3286 additional = ", nodiv";
3287 break;
266abb8f
NS
3288 }
3289 strcat (buf, ", cf, isa ");
3290 strcat (buf, isa);
0b2e31dc
NS
3291 if (additional)
3292 strcat (buf, additional);
c694fd50 3293 if (e_flags & EF_M68K_CF_FLOAT)
0b2e31dc 3294 strcat (buf, ", float");
c694fd50 3295 switch (e_flags & EF_M68K_CF_MAC_MASK)
266abb8f
NS
3296 {
3297 case 0:
3298 mac = NULL;
3299 break;
c694fd50 3300 case EF_M68K_CF_MAC:
266abb8f
NS
3301 mac = "mac";
3302 break;
c694fd50 3303 case EF_M68K_CF_EMAC:
266abb8f
NS
3304 mac = "emac";
3305 break;
f608cd77
NS
3306 case EF_M68K_CF_EMAC_B:
3307 mac = "emac_b";
3308 break;
266abb8f
NS
3309 }
3310 if (mac)
3311 {
3312 strcat (buf, ", ");
3313 strcat (buf, mac);
3314 }
266abb8f 3315 }
53c7db4b 3316 break;
33c63f9d 3317
153a2776
NC
3318 case EM_CYGNUS_MEP:
3319 switch (e_flags & EF_MEP_CPU_MASK)
3320 {
3321 case EF_MEP_CPU_MEP: strcat (buf, ", generic MeP"); break;
3322 case EF_MEP_CPU_C2: strcat (buf, ", MeP C2"); break;
3323 case EF_MEP_CPU_C3: strcat (buf, ", MeP C3"); break;
3324 case EF_MEP_CPU_C4: strcat (buf, ", MeP C4"); break;
3325 case EF_MEP_CPU_C5: strcat (buf, ", MeP C5"); break;
3326 case EF_MEP_CPU_H1: strcat (buf, ", MeP H1"); break;
3327 default: strcat (buf, _(", <unknown MeP cpu type>")); break;
3328 }
3329
3330 switch (e_flags & EF_MEP_COP_MASK)
3331 {
3332 case EF_MEP_COP_NONE: break;
3333 case EF_MEP_COP_AVC: strcat (buf, ", AVC coprocessor"); break;
3334 case EF_MEP_COP_AVC2: strcat (buf, ", AVC2 coprocessor"); break;
3335 case EF_MEP_COP_FMAX: strcat (buf, ", FMAX coprocessor"); break;
3336 case EF_MEP_COP_IVC2: strcat (buf, ", IVC2 coprocessor"); break;
3337 default: strcat (buf, _("<unknown MeP copro type>")); break;
3338 }
3339
3340 if (e_flags & EF_MEP_LIBRARY)
3341 strcat (buf, ", Built for Library");
3342
3343 if (e_flags & EF_MEP_INDEX_MASK)
3344 sprintf (buf + strlen (buf), ", Configuration Index: %#x",
3345 e_flags & EF_MEP_INDEX_MASK);
3346
3347 if (e_flags & ~ EF_MEP_ALL_FLAGS)
3348 sprintf (buf + strlen (buf), _(", unknown flags bits: %#x"),
3349 e_flags & ~ EF_MEP_ALL_FLAGS);
3350 break;
3351
252b5132
RH
3352 case EM_PPC:
3353 if (e_flags & EF_PPC_EMB)
3354 strcat (buf, ", emb");
3355
3356 if (e_flags & EF_PPC_RELOCATABLE)
2b692964 3357 strcat (buf, _(", relocatable"));
252b5132
RH
3358
3359 if (e_flags & EF_PPC_RELOCATABLE_LIB)
2b692964 3360 strcat (buf, _(", relocatable-lib"));
252b5132
RH
3361 break;
3362
ee67d69a
AM
3363 case EM_PPC64:
3364 if (e_flags & EF_PPC64_ABI)
3365 {
3366 char abi[] = ", abiv0";
3367
3368 abi[6] += e_flags & EF_PPC64_ABI;
3369 strcat (buf, abi);
3370 }
3371 break;
3372
708e2187
NC
3373 case EM_V800:
3374 if ((e_flags & EF_RH850_ABI) == EF_RH850_ABI)
3375 strcat (buf, ", RH850 ABI");
0b4362b0 3376
708e2187
NC
3377 if (e_flags & EF_V800_850E3)
3378 strcat (buf, ", V3 architecture");
3379
3380 if ((e_flags & (EF_RH850_FPU_DOUBLE | EF_RH850_FPU_SINGLE)) == 0)
3381 strcat (buf, ", FPU not used");
3382
3383 if ((e_flags & (EF_RH850_REGMODE22 | EF_RH850_REGMODE32)) == 0)
3384 strcat (buf, ", regmode: COMMON");
3385
3386 if ((e_flags & (EF_RH850_GP_FIX | EF_RH850_GP_NOFIX)) == 0)
3387 strcat (buf, ", r4 not used");
3388
3389 if ((e_flags & (EF_RH850_EP_FIX | EF_RH850_EP_NOFIX)) == 0)
3390 strcat (buf, ", r30 not used");
3391
3392 if ((e_flags & (EF_RH850_TP_FIX | EF_RH850_TP_NOFIX)) == 0)
3393 strcat (buf, ", r5 not used");
3394
3395 if ((e_flags & (EF_RH850_REG2_RESERVE | EF_RH850_REG2_NORESERVE)) == 0)
3396 strcat (buf, ", r2 not used");
3397
3398 for (e_flags &= 0xFFFF; e_flags; e_flags &= ~ (e_flags & - e_flags))
3399 {
3400 switch (e_flags & - e_flags)
3401 {
3402 case EF_RH850_FPU_DOUBLE: strcat (buf, ", double precision FPU"); break;
3403 case EF_RH850_FPU_SINGLE: strcat (buf, ", single precision FPU"); break;
708e2187
NC
3404 case EF_RH850_REGMODE22: strcat (buf, ", regmode:22"); break;
3405 case EF_RH850_REGMODE32: strcat (buf, ", regmode:23"); break;
708e2187
NC
3406 case EF_RH850_GP_FIX: strcat (buf, ", r4 fixed"); break;
3407 case EF_RH850_GP_NOFIX: strcat (buf, ", r4 free"); break;
3408 case EF_RH850_EP_FIX: strcat (buf, ", r30 fixed"); break;
3409 case EF_RH850_EP_NOFIX: strcat (buf, ", r30 free"); break;
3410 case EF_RH850_TP_FIX: strcat (buf, ", r5 fixed"); break;
3411 case EF_RH850_TP_NOFIX: strcat (buf, ", r5 free"); break;
3412 case EF_RH850_REG2_RESERVE: strcat (buf, ", r2 fixed"); break;
3413 case EF_RH850_REG2_NORESERVE: strcat (buf, ", r2 free"); break;
3414 default: break;
3415 }
3416 }
3417 break;
3418
2b0337b0 3419 case EM_V850:
252b5132
RH
3420 case EM_CYGNUS_V850:
3421 switch (e_flags & EF_V850_ARCH)
3422 {
78c8d46c
NC
3423 case E_V850E3V5_ARCH:
3424 strcat (buf, ", v850e3v5");
3425 break;
1cd986c5
NC
3426 case E_V850E2V3_ARCH:
3427 strcat (buf, ", v850e2v3");
3428 break;
3429 case E_V850E2_ARCH:
3430 strcat (buf, ", v850e2");
3431 break;
3432 case E_V850E1_ARCH:
3433 strcat (buf, ", v850e1");
8ad30312 3434 break;
252b5132
RH
3435 case E_V850E_ARCH:
3436 strcat (buf, ", v850e");
3437 break;
252b5132
RH
3438 case E_V850_ARCH:
3439 strcat (buf, ", v850");
3440 break;
3441 default:
2b692964 3442 strcat (buf, _(", unknown v850 architecture variant"));
252b5132
RH
3443 break;
3444 }
3445 break;
3446
2b0337b0 3447 case EM_M32R:
252b5132
RH
3448 case EM_CYGNUS_M32R:
3449 if ((e_flags & EF_M32R_ARCH) == E_M32R_ARCH)
3450 strcat (buf, ", m32r");
252b5132
RH
3451 break;
3452
3453 case EM_MIPS:
4fe85591 3454 case EM_MIPS_RS3_LE:
252b5132
RH
3455 if (e_flags & EF_MIPS_NOREORDER)
3456 strcat (buf, ", noreorder");
3457
3458 if (e_flags & EF_MIPS_PIC)
3459 strcat (buf, ", pic");
3460
3461 if (e_flags & EF_MIPS_CPIC)
3462 strcat (buf, ", cpic");
3463
d1bdd336
TS
3464 if (e_flags & EF_MIPS_UCODE)
3465 strcat (buf, ", ugen_reserved");
3466
252b5132
RH
3467 if (e_flags & EF_MIPS_ABI2)
3468 strcat (buf, ", abi2");
3469
43521d43
TS
3470 if (e_flags & EF_MIPS_OPTIONS_FIRST)
3471 strcat (buf, ", odk first");
3472
a5d22d2a
TS
3473 if (e_flags & EF_MIPS_32BITMODE)
3474 strcat (buf, ", 32bitmode");
3475
ba92f887
MR
3476 if (e_flags & EF_MIPS_NAN2008)
3477 strcat (buf, ", nan2008");
3478
fef1b0b3
SE
3479 if (e_flags & EF_MIPS_FP64)
3480 strcat (buf, ", fp64");
3481
156c2f8b
NC
3482 switch ((e_flags & EF_MIPS_MACH))
3483 {
3484 case E_MIPS_MACH_3900: strcat (buf, ", 3900"); break;
3485 case E_MIPS_MACH_4010: strcat (buf, ", 4010"); break;
3486 case E_MIPS_MACH_4100: strcat (buf, ", 4100"); break;
156c2f8b 3487 case E_MIPS_MACH_4111: strcat (buf, ", 4111"); break;
810dfa6e
L
3488 case E_MIPS_MACH_4120: strcat (buf, ", 4120"); break;
3489 case E_MIPS_MACH_4650: strcat (buf, ", 4650"); break;
3490 case E_MIPS_MACH_5400: strcat (buf, ", 5400"); break;
3491 case E_MIPS_MACH_5500: strcat (buf, ", 5500"); break;
ef272caa 3492 case E_MIPS_MACH_5900: strcat (buf, ", 5900"); break;
c6c98b38 3493 case E_MIPS_MACH_SB1: strcat (buf, ", sb1"); break;
ebcb91b7 3494 case E_MIPS_MACH_9000: strcat (buf, ", 9000"); break;
350cc38d
MS
3495 case E_MIPS_MACH_LS2E: strcat (buf, ", loongson-2e"); break;
3496 case E_MIPS_MACH_LS2F: strcat (buf, ", loongson-2f"); break;
ac8cb70f 3497 case E_MIPS_MACH_GS464: strcat (buf, ", gs464"); break;
bd782c07 3498 case E_MIPS_MACH_GS464E: strcat (buf, ", gs464e"); break;
9108bc33 3499 case E_MIPS_MACH_GS264E: strcat (buf, ", gs264e"); break;
05c6f050 3500 case E_MIPS_MACH_OCTEON: strcat (buf, ", octeon"); break;
67c2a3e8 3501 case E_MIPS_MACH_OCTEON2: strcat (buf, ", octeon2"); break;
d32e5c54 3502 case E_MIPS_MACH_OCTEON3: strcat (buf, ", octeon3"); break;
52b6b6b9 3503 case E_MIPS_MACH_XLR: strcat (buf, ", xlr"); break;
38bf472a 3504 case E_MIPS_MACH_IAMR2: strcat (buf, ", interaptiv-mr2"); break;
43521d43
TS
3505 case 0:
3506 /* We simply ignore the field in this case to avoid confusion:
3507 MIPS ELF does not specify EF_MIPS_MACH, it is a GNU
3508 extension. */
3509 break;
2b692964 3510 default: strcat (buf, _(", unknown CPU")); break;
156c2f8b 3511 }
43521d43
TS
3512
3513 switch ((e_flags & EF_MIPS_ABI))
3514 {
3515 case E_MIPS_ABI_O32: strcat (buf, ", o32"); break;
3516 case E_MIPS_ABI_O64: strcat (buf, ", o64"); break;
3517 case E_MIPS_ABI_EABI32: strcat (buf, ", eabi32"); break;
3518 case E_MIPS_ABI_EABI64: strcat (buf, ", eabi64"); break;
3519 case 0:
3520 /* We simply ignore the field in this case to avoid confusion:
3521 MIPS ELF does not specify EF_MIPS_ABI, it is a GNU extension.
3522 This means it is likely to be an o32 file, but not for
3523 sure. */
3524 break;
2b692964 3525 default: strcat (buf, _(", unknown ABI")); break;
43521d43
TS
3526 }
3527
3528 if (e_flags & EF_MIPS_ARCH_ASE_MDMX)
3529 strcat (buf, ", mdmx");
3530
3531 if (e_flags & EF_MIPS_ARCH_ASE_M16)
3532 strcat (buf, ", mips16");
3533
df58fc94
RS
3534 if (e_flags & EF_MIPS_ARCH_ASE_MICROMIPS)
3535 strcat (buf, ", micromips");
3536
43521d43
TS
3537 switch ((e_flags & EF_MIPS_ARCH))
3538 {
3539 case E_MIPS_ARCH_1: strcat (buf, ", mips1"); break;
3540 case E_MIPS_ARCH_2: strcat (buf, ", mips2"); break;
3541 case E_MIPS_ARCH_3: strcat (buf, ", mips3"); break;
3542 case E_MIPS_ARCH_4: strcat (buf, ", mips4"); break;
3543 case E_MIPS_ARCH_5: strcat (buf, ", mips5"); break;
3544 case E_MIPS_ARCH_32: strcat (buf, ", mips32"); break;
cb44e358 3545 case E_MIPS_ARCH_32R2: strcat (buf, ", mips32r2"); break;
7361da2c 3546 case E_MIPS_ARCH_32R6: strcat (buf, ", mips32r6"); break;
43521d43 3547 case E_MIPS_ARCH_64: strcat (buf, ", mips64"); break;
5f74bc13 3548 case E_MIPS_ARCH_64R2: strcat (buf, ", mips64r2"); break;
7361da2c 3549 case E_MIPS_ARCH_64R6: strcat (buf, ", mips64r6"); break;
2b692964 3550 default: strcat (buf, _(", unknown ISA")); break;
43521d43 3551 }
252b5132 3552 break;
351b4b40 3553
35c08157
KLC
3554 case EM_NDS32:
3555 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
3556 break;
3557
fe944acf
FT
3558 case EM_NFP:
3559 switch (EF_NFP_MACH (e_flags))
3560 {
3561 case E_NFP_MACH_3200:
3562 strcat (buf, ", NFP-32xx");
3563 break;
3564 case E_NFP_MACH_6000:
3565 strcat (buf, ", NFP-6xxx");
3566 break;
3567 }
3568 break;
3569
e23eba97
NC
3570 case EM_RISCV:
3571 if (e_flags & EF_RISCV_RVC)
3572 strcat (buf, ", RVC");
2922d21d 3573
7f999549
JW
3574 if (e_flags & EF_RISCV_RVE)
3575 strcat (buf, ", RVE");
3576
2922d21d
AW
3577 switch (e_flags & EF_RISCV_FLOAT_ABI)
3578 {
3579 case EF_RISCV_FLOAT_ABI_SOFT:
3580 strcat (buf, ", soft-float ABI");
3581 break;
3582
3583 case EF_RISCV_FLOAT_ABI_SINGLE:
3584 strcat (buf, ", single-float ABI");
3585 break;
3586
3587 case EF_RISCV_FLOAT_ABI_DOUBLE:
3588 strcat (buf, ", double-float ABI");
3589 break;
3590
3591 case EF_RISCV_FLOAT_ABI_QUAD:
3592 strcat (buf, ", quad-float ABI");
3593 break;
3594 }
e23eba97
NC
3595 break;
3596
ccde1100
AO
3597 case EM_SH:
3598 switch ((e_flags & EF_SH_MACH_MASK))
3599 {
3600 case EF_SH1: strcat (buf, ", sh1"); break;
3601 case EF_SH2: strcat (buf, ", sh2"); break;
3602 case EF_SH3: strcat (buf, ", sh3"); break;
3603 case EF_SH_DSP: strcat (buf, ", sh-dsp"); break;
3604 case EF_SH3_DSP: strcat (buf, ", sh3-dsp"); break;
3605 case EF_SH4AL_DSP: strcat (buf, ", sh4al-dsp"); break;
3606 case EF_SH3E: strcat (buf, ", sh3e"); break;
3607 case EF_SH4: strcat (buf, ", sh4"); break;
3608 case EF_SH5: strcat (buf, ", sh5"); break;
3609 case EF_SH2E: strcat (buf, ", sh2e"); break;
3610 case EF_SH4A: strcat (buf, ", sh4a"); break;
1d70c7fb 3611 case EF_SH2A: strcat (buf, ", sh2a"); break;
ccde1100
AO
3612 case EF_SH4_NOFPU: strcat (buf, ", sh4-nofpu"); break;
3613 case EF_SH4A_NOFPU: strcat (buf, ", sh4a-nofpu"); break;
1d70c7fb 3614 case EF_SH2A_NOFPU: strcat (buf, ", sh2a-nofpu"); break;
0b92ab21
NH
3615 case EF_SH3_NOMMU: strcat (buf, ", sh3-nommu"); break;
3616 case EF_SH4_NOMMU_NOFPU: strcat (buf, ", sh4-nommu-nofpu"); break;
3617 case EF_SH2A_SH4_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh4-nommu-nofpu"); break;
3618 case EF_SH2A_SH3_NOFPU: strcat (buf, ", sh2a-nofpu-or-sh3-nommu"); break;
3619 case EF_SH2A_SH4: strcat (buf, ", sh2a-or-sh4"); break;
3620 case EF_SH2A_SH3E: strcat (buf, ", sh2a-or-sh3e"); break;
2b692964 3621 default: strcat (buf, _(", unknown ISA")); break;
ccde1100
AO
3622 }
3623
cec6a5b8
MR
3624 if (e_flags & EF_SH_PIC)
3625 strcat (buf, ", pic");
3626
3627 if (e_flags & EF_SH_FDPIC)
3628 strcat (buf, ", fdpic");
ccde1100 3629 break;
948f632f 3630
73589c9d
CS
3631 case EM_OR1K:
3632 if (e_flags & EF_OR1K_NODELAY)
3633 strcat (buf, ", no delay");
3634 break;
57346661 3635
351b4b40
RH
3636 case EM_SPARCV9:
3637 if (e_flags & EF_SPARC_32PLUS)
3638 strcat (buf, ", v8+");
3639
3640 if (e_flags & EF_SPARC_SUN_US1)
d07faca2
RH
3641 strcat (buf, ", ultrasparcI");
3642
3643 if (e_flags & EF_SPARC_SUN_US3)
3644 strcat (buf, ", ultrasparcIII");
351b4b40
RH
3645
3646 if (e_flags & EF_SPARC_HAL_R1)
3647 strcat (buf, ", halr1");
3648
3649 if (e_flags & EF_SPARC_LEDATA)
3650 strcat (buf, ", ledata");
3651
3652 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_TSO)
3653 strcat (buf, ", tso");
3654
3655 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_PSO)
3656 strcat (buf, ", pso");
3657
3658 if ((e_flags & EF_SPARCV9_MM) == EF_SPARCV9_RMO)
3659 strcat (buf, ", rmo");
3660 break;
7d466069 3661
103f02d3
UD
3662 case EM_PARISC:
3663 switch (e_flags & EF_PARISC_ARCH)
3664 {
3665 case EFA_PARISC_1_0:
3666 strcpy (buf, ", PA-RISC 1.0");
3667 break;
3668 case EFA_PARISC_1_1:
3669 strcpy (buf, ", PA-RISC 1.1");
3670 break;
3671 case EFA_PARISC_2_0:
3672 strcpy (buf, ", PA-RISC 2.0");
3673 break;
3674 default:
3675 break;
3676 }
3677 if (e_flags & EF_PARISC_TRAPNIL)
3678 strcat (buf, ", trapnil");
3679 if (e_flags & EF_PARISC_EXT)
3680 strcat (buf, ", ext");
3681 if (e_flags & EF_PARISC_LSB)
3682 strcat (buf, ", lsb");
3683 if (e_flags & EF_PARISC_WIDE)
3684 strcat (buf, ", wide");
3685 if (e_flags & EF_PARISC_NO_KABP)
3686 strcat (buf, ", no kabp");
3687 if (e_flags & EF_PARISC_LAZYSWAP)
3688 strcat (buf, ", lazyswap");
30800947 3689 break;
76da6bbe 3690
7d466069 3691 case EM_PJ:
2b0337b0 3692 case EM_PJ_OLD:
7d466069
ILT
3693 if ((e_flags & EF_PICOJAVA_NEWCALLS) == EF_PICOJAVA_NEWCALLS)
3694 strcat (buf, ", new calling convention");
3695
3696 if ((e_flags & EF_PICOJAVA_GNUCALLS) == EF_PICOJAVA_GNUCALLS)
3697 strcat (buf, ", gnu calling convention");
3698 break;
4d6ed7c8
NC
3699
3700 case EM_IA_64:
3701 if ((e_flags & EF_IA_64_ABI64))
3702 strcat (buf, ", 64-bit");
3703 else
3704 strcat (buf, ", 32-bit");
3705 if ((e_flags & EF_IA_64_REDUCEDFP))
3706 strcat (buf, ", reduced fp model");
3707 if ((e_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
3708 strcat (buf, ", no function descriptors, constant gp");
3709 else if ((e_flags & EF_IA_64_CONS_GP))
3710 strcat (buf, ", constant gp");
3711 if ((e_flags & EF_IA_64_ABSOLUTE))
3712 strcat (buf, ", absolute");
dda8d76d 3713 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
28f997cf
TG
3714 {
3715 if ((e_flags & EF_IA_64_VMS_LINKAGES))
3716 strcat (buf, ", vms_linkages");
3717 switch ((e_flags & EF_IA_64_VMS_COMCOD))
3718 {
3719 case EF_IA_64_VMS_COMCOD_SUCCESS:
3720 break;
3721 case EF_IA_64_VMS_COMCOD_WARNING:
3722 strcat (buf, ", warning");
3723 break;
3724 case EF_IA_64_VMS_COMCOD_ERROR:
3725 strcat (buf, ", error");
3726 break;
3727 case EF_IA_64_VMS_COMCOD_ABORT:
3728 strcat (buf, ", abort");
3729 break;
3730 default:
bee0ee85
NC
3731 warn (_("Unrecognised IA64 VMS Command Code: %x\n"),
3732 e_flags & EF_IA_64_VMS_COMCOD);
3733 strcat (buf, ", <unknown>");
28f997cf
TG
3734 }
3735 }
4d6ed7c8 3736 break;
179d3252
JT
3737
3738 case EM_VAX:
3739 if ((e_flags & EF_VAX_NONPIC))
3740 strcat (buf, ", non-PIC");
3741 if ((e_flags & EF_VAX_DFLOAT))
3742 strcat (buf, ", D-Float");
3743 if ((e_flags & EF_VAX_GFLOAT))
3744 strcat (buf, ", G-Float");
3745 break;
c7927a3c 3746
619ed720
EB
3747 case EM_VISIUM:
3748 if (e_flags & EF_VISIUM_ARCH_MCM)
3749 strcat (buf, ", mcm");
3750 else if (e_flags & EF_VISIUM_ARCH_MCM24)
3751 strcat (buf, ", mcm24");
3752 if (e_flags & EF_VISIUM_ARCH_GR6)
3753 strcat (buf, ", gr6");
3754 break;
3755
4046d87a 3756 case EM_RL78:
1740ba0c
NC
3757 switch (e_flags & E_FLAG_RL78_CPU_MASK)
3758 {
3759 case E_FLAG_RL78_ANY_CPU: break;
3760 case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
3761 case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
3762 case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
3763 }
856ea05c
KP
3764 if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
3765 strcat (buf, ", 64-bit doubles");
4046d87a 3766 break;
0b4362b0 3767
c7927a3c
NC
3768 case EM_RX:
3769 if (e_flags & E_FLAG_RX_64BIT_DOUBLES)
3770 strcat (buf, ", 64-bit doubles");
3771 if (e_flags & E_FLAG_RX_DSP)
dd24e3da 3772 strcat (buf, ", dsp");
d4cb0ea0 3773 if (e_flags & E_FLAG_RX_PID)
0b4362b0 3774 strcat (buf, ", pid");
708e2187
NC
3775 if (e_flags & E_FLAG_RX_ABI)
3776 strcat (buf, ", RX ABI");
3525236c
NC
3777 if (e_flags & E_FLAG_RX_SINSNS_SET)
3778 strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
3779 ? ", uses String instructions" : ", bans String instructions");
a117b0a5
YS
3780 if (e_flags & E_FLAG_RX_V2)
3781 strcat (buf, ", V2");
f87673e0
YS
3782 if (e_flags & E_FLAG_RX_V3)
3783 strcat (buf, ", V3");
d4cb0ea0 3784 break;
55786da2
AK
3785
3786 case EM_S390:
3787 if (e_flags & EF_S390_HIGH_GPRS)
3788 strcat (buf, ", highgprs");
d4cb0ea0 3789 break;
40b36596
JM
3790
3791 case EM_TI_C6000:
3792 if ((e_flags & EF_C6000_REL))
3793 strcat (buf, ", relocatable module");
d4cb0ea0 3794 break;
13761a11
NC
3795
3796 case EM_MSP430:
3797 strcat (buf, _(": architecture variant: "));
3798 switch (e_flags & EF_MSP430_MACH)
3799 {
3800 case E_MSP430_MACH_MSP430x11: strcat (buf, "MSP430x11"); break;
3801 case E_MSP430_MACH_MSP430x11x1 : strcat (buf, "MSP430x11x1 "); break;
3802 case E_MSP430_MACH_MSP430x12: strcat (buf, "MSP430x12"); break;
3803 case E_MSP430_MACH_MSP430x13: strcat (buf, "MSP430x13"); break;
3804 case E_MSP430_MACH_MSP430x14: strcat (buf, "MSP430x14"); break;
3805 case E_MSP430_MACH_MSP430x15: strcat (buf, "MSP430x15"); break;
3806 case E_MSP430_MACH_MSP430x16: strcat (buf, "MSP430x16"); break;
3807 case E_MSP430_MACH_MSP430x31: strcat (buf, "MSP430x31"); break;
3808 case E_MSP430_MACH_MSP430x32: strcat (buf, "MSP430x32"); break;
3809 case E_MSP430_MACH_MSP430x33: strcat (buf, "MSP430x33"); break;
3810 case E_MSP430_MACH_MSP430x41: strcat (buf, "MSP430x41"); break;
3811 case E_MSP430_MACH_MSP430x42: strcat (buf, "MSP430x42"); break;
3812 case E_MSP430_MACH_MSP430x43: strcat (buf, "MSP430x43"); break;
3813 case E_MSP430_MACH_MSP430x44: strcat (buf, "MSP430x44"); break;
3814 case E_MSP430_MACH_MSP430X : strcat (buf, "MSP430X"); break;
3815 default:
3816 strcat (buf, _(": unknown")); break;
3817 }
3818
3819 if (e_flags & ~ EF_MSP430_MACH)
3820 strcat (buf, _(": unknown extra flag bits also present"));
6655dba2
SB
3821 break;
3822
3823 case EM_Z80:
3824 switch (e_flags & EF_Z80_MACH_MSK)
3825 {
3826 case EF_Z80_MACH_Z80: strcat (buf, ", Z80"); break;
3827 case EF_Z80_MACH_Z180: strcat (buf, ", Z180"); break;
3828 case EF_Z80_MACH_R800: strcat (buf, ", R800"); break;
3829 case EF_Z80_MACH_EZ80_Z80: strcat (buf, ", EZ80"); break;
3830 case EF_Z80_MACH_EZ80_ADL: strcat (buf, ", EZ80, ADL"); break;
3831 case EF_Z80_MACH_GBZ80: strcat (buf, ", GBZ80"); break;
9fc0b501 3832 case EF_Z80_MACH_Z80N: strcat (buf, ", Z80N"); break;
6655dba2
SB
3833 default:
3834 strcat (buf, _(", unknown")); break;
3835 }
3836 break;
252b5132
RH
3837 }
3838 }
3839
3840 return buf;
3841}
3842
252b5132 3843static const char *
dda8d76d 3844get_osabi_name (Filedata * filedata, unsigned int osabi)
d3ba0551
AM
3845{
3846 static char buff[32];
3847
3848 switch (osabi)
3849 {
3850 case ELFOSABI_NONE: return "UNIX - System V";
3851 case ELFOSABI_HPUX: return "UNIX - HP-UX";
3852 case ELFOSABI_NETBSD: return "UNIX - NetBSD";
9c55345c 3853 case ELFOSABI_GNU: return "UNIX - GNU";
d3ba0551
AM
3854 case ELFOSABI_SOLARIS: return "UNIX - Solaris";
3855 case ELFOSABI_AIX: return "UNIX - AIX";
3856 case ELFOSABI_IRIX: return "UNIX - IRIX";
3857 case ELFOSABI_FREEBSD: return "UNIX - FreeBSD";
3858 case ELFOSABI_TRU64: return "UNIX - TRU64";
3859 case ELFOSABI_MODESTO: return "Novell - Modesto";
3860 case ELFOSABI_OPENBSD: return "UNIX - OpenBSD";
3861 case ELFOSABI_OPENVMS: return "VMS - OpenVMS";
3862 case ELFOSABI_NSK: return "HP - Non-Stop Kernel";
3b26c801 3863 case ELFOSABI_AROS: return "AROS";
11636f9e 3864 case ELFOSABI_FENIXOS: return "FenixOS";
6d913794
NC
3865 case ELFOSABI_CLOUDABI: return "Nuxi CloudABI";
3866 case ELFOSABI_OPENVOS: return "Stratus Technologies OpenVOS";
d3ba0551 3867 default:
40b36596 3868 if (osabi >= 64)
dda8d76d 3869 switch (filedata->file_header.e_machine)
40b36596
JM
3870 {
3871 case EM_ARM:
3872 switch (osabi)
3873 {
3874 case ELFOSABI_ARM: return "ARM";
18a20338 3875 case ELFOSABI_ARM_FDPIC: return "ARM FDPIC";
40b36596
JM
3876 default:
3877 break;
3878 }
3879 break;
3880
3881 case EM_MSP430:
3882 case EM_MSP430_OLD:
619ed720 3883 case EM_VISIUM:
40b36596
JM
3884 switch (osabi)
3885 {
3886 case ELFOSABI_STANDALONE: return _("Standalone App");
3887 default:
3888 break;
3889 }
3890 break;
3891
3892 case EM_TI_C6000:
3893 switch (osabi)
3894 {
3895 case ELFOSABI_C6000_ELFABI: return _("Bare-metal C6000");
3896 case ELFOSABI_C6000_LINUX: return "Linux C6000";
3897 default:
3898 break;
3899 }
3900 break;
3901
3902 default:
3903 break;
3904 }
e9e44622 3905 snprintf (buff, sizeof (buff), _("<unknown: %x>"), osabi);
d3ba0551
AM
3906 return buff;
3907 }
3908}
3909
a06ea964
NC
3910static const char *
3911get_aarch64_segment_type (unsigned long type)
3912{
3913 switch (type)
3914 {
32ec8896
NC
3915 case PT_AARCH64_ARCHEXT: return "AARCH64_ARCHEXT";
3916 default: return NULL;
a06ea964 3917 }
a06ea964
NC
3918}
3919
b294bdf8
MM
3920static const char *
3921get_arm_segment_type (unsigned long type)
3922{
3923 switch (type)
3924 {
32ec8896
NC
3925 case PT_ARM_EXIDX: return "EXIDX";
3926 default: return NULL;
b294bdf8 3927 }
b294bdf8
MM
3928}
3929
b4cbbe8f
AK
3930static const char *
3931get_s390_segment_type (unsigned long type)
3932{
3933 switch (type)
3934 {
3935 case PT_S390_PGSTE: return "S390_PGSTE";
3936 default: return NULL;
3937 }
3938}
3939
d3ba0551
AM
3940static const char *
3941get_mips_segment_type (unsigned long type)
252b5132
RH
3942{
3943 switch (type)
3944 {
32ec8896
NC
3945 case PT_MIPS_REGINFO: return "REGINFO";
3946 case PT_MIPS_RTPROC: return "RTPROC";
3947 case PT_MIPS_OPTIONS: return "OPTIONS";
3948 case PT_MIPS_ABIFLAGS: return "ABIFLAGS";
3949 default: return NULL;
252b5132 3950 }
252b5132
RH
3951}
3952
103f02d3 3953static const char *
d3ba0551 3954get_parisc_segment_type (unsigned long type)
103f02d3
UD
3955{
3956 switch (type)
3957 {
103f02d3
UD
3958 case PT_PARISC_ARCHEXT: return "PARISC_ARCHEXT";
3959 case PT_PARISC_UNWIND: return "PARISC_UNWIND";
61472819 3960 case PT_PARISC_WEAKORDER: return "PARISC_WEAKORDER";
32ec8896 3961 default: return NULL;
103f02d3 3962 }
103f02d3
UD
3963}
3964
4d6ed7c8 3965static const char *
d3ba0551 3966get_ia64_segment_type (unsigned long type)
4d6ed7c8
NC
3967{
3968 switch (type)
3969 {
3970 case PT_IA_64_ARCHEXT: return "IA_64_ARCHEXT";
3971 case PT_IA_64_UNWIND: return "IA_64_UNWIND";
32ec8896 3972 default: return NULL;
4d6ed7c8 3973 }
4d6ed7c8
NC
3974}
3975
40b36596
JM
3976static const char *
3977get_tic6x_segment_type (unsigned long type)
3978{
3979 switch (type)
3980 {
32ec8896
NC
3981 case PT_C6000_PHATTR: return "C6000_PHATTR";
3982 default: return NULL;
40b36596 3983 }
40b36596
JM
3984}
3985
df3a023b
AM
3986static const char *
3987get_hpux_segment_type (unsigned long type, unsigned e_machine)
3988{
3989 if (e_machine == EM_PARISC)
3990 switch (type)
3991 {
3992 case PT_HP_TLS: return "HP_TLS";
3993 case PT_HP_CORE_NONE: return "HP_CORE_NONE";
3994 case PT_HP_CORE_VERSION: return "HP_CORE_VERSION";
3995 case PT_HP_CORE_KERNEL: return "HP_CORE_KERNEL";
3996 case PT_HP_CORE_COMM: return "HP_CORE_COMM";
3997 case PT_HP_CORE_PROC: return "HP_CORE_PROC";
3998 case PT_HP_CORE_LOADABLE: return "HP_CORE_LOADABLE";
3999 case PT_HP_CORE_STACK: return "HP_CORE_STACK";
4000 case PT_HP_CORE_SHM: return "HP_CORE_SHM";
4001 case PT_HP_CORE_MMF: return "HP_CORE_MMF";
4002 case PT_HP_PARALLEL: return "HP_PARALLEL";
4003 case PT_HP_FASTBIND: return "HP_FASTBIND";
4004 case PT_HP_OPT_ANNOT: return "HP_OPT_ANNOT";
4005 case PT_HP_HSL_ANNOT: return "HP_HSL_ANNOT";
4006 case PT_HP_STACK: return "HP_STACK";
4007 case PT_HP_CORE_UTSNAME: return "HP_CORE_UTSNAME";
4008 default: return NULL;
4009 }
4010
4011 if (e_machine == EM_IA_64)
4012 switch (type)
4013 {
4014 case PT_HP_TLS: return "HP_TLS";
4015 case PT_IA_64_HP_OPT_ANOT: return "HP_OPT_ANNOT";
4016 case PT_IA_64_HP_HSL_ANOT: return "HP_HSL_ANNOT";
4017 case PT_IA_64_HP_STACK: return "HP_STACK";
4018 default: return NULL;
4019 }
4020
4021 return NULL;
4022}
4023
5522f910
NC
4024static const char *
4025get_solaris_segment_type (unsigned long type)
4026{
4027 switch (type)
4028 {
4029 case 0x6464e550: return "PT_SUNW_UNWIND";
4030 case 0x6474e550: return "PT_SUNW_EH_FRAME";
4031 case 0x6ffffff7: return "PT_LOSUNW";
4032 case 0x6ffffffa: return "PT_SUNWBSS";
4033 case 0x6ffffffb: return "PT_SUNWSTACK";
4034 case 0x6ffffffc: return "PT_SUNWDTRACE";
4035 case 0x6ffffffd: return "PT_SUNWCAP";
4036 case 0x6fffffff: return "PT_HISUNW";
32ec8896 4037 default: return NULL;
5522f910
NC
4038 }
4039}
4040
252b5132 4041static const char *
dda8d76d 4042get_segment_type (Filedata * filedata, unsigned long p_type)
252b5132 4043{
b34976b6 4044 static char buff[32];
252b5132
RH
4045
4046 switch (p_type)
4047 {
b34976b6
AM
4048 case PT_NULL: return "NULL";
4049 case PT_LOAD: return "LOAD";
252b5132 4050 case PT_DYNAMIC: return "DYNAMIC";
b34976b6
AM
4051 case PT_INTERP: return "INTERP";
4052 case PT_NOTE: return "NOTE";
4053 case PT_SHLIB: return "SHLIB";
4054 case PT_PHDR: return "PHDR";
13ae64f3 4055 case PT_TLS: return "TLS";
32ec8896 4056 case PT_GNU_EH_FRAME: return "GNU_EH_FRAME";
2b05f1b7 4057 case PT_GNU_STACK: return "GNU_STACK";
8c37241b 4058 case PT_GNU_RELRO: return "GNU_RELRO";
0a59decb 4059 case PT_GNU_PROPERTY: return "GNU_PROPERTY";
65765700 4060
3eba3ef3
NC
4061 case PT_OPENBSD_RANDOMIZE: return "OPENBSD_RANDOMIZE";
4062 case PT_OPENBSD_WXNEEDED: return "OPENBSD_WXNEEDED";
4063 case PT_OPENBSD_BOOTDATA: return "OPENBSD_BOOTDATA";
b9e920ec 4064
252b5132 4065 default:
df3a023b 4066 if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC))
252b5132 4067 {
2cf0635d 4068 const char * result;
103f02d3 4069
dda8d76d 4070 switch (filedata->file_header.e_machine)
252b5132 4071 {
a06ea964
NC
4072 case EM_AARCH64:
4073 result = get_aarch64_segment_type (p_type);
4074 break;
b294bdf8
MM
4075 case EM_ARM:
4076 result = get_arm_segment_type (p_type);
4077 break;
252b5132 4078 case EM_MIPS:
4fe85591 4079 case EM_MIPS_RS3_LE:
252b5132
RH
4080 result = get_mips_segment_type (p_type);
4081 break;
103f02d3
UD
4082 case EM_PARISC:
4083 result = get_parisc_segment_type (p_type);
4084 break;
4d6ed7c8
NC
4085 case EM_IA_64:
4086 result = get_ia64_segment_type (p_type);
4087 break;
40b36596
JM
4088 case EM_TI_C6000:
4089 result = get_tic6x_segment_type (p_type);
4090 break;
b4cbbe8f
AK
4091 case EM_S390:
4092 case EM_S390_OLD:
4093 result = get_s390_segment_type (p_type);
4094 break;
252b5132
RH
4095 default:
4096 result = NULL;
4097 break;
4098 }
103f02d3 4099
252b5132
RH
4100 if (result != NULL)
4101 return result;
103f02d3 4102
1a9ccd70 4103 sprintf (buff, "LOPROC+%#lx", p_type - PT_LOPROC);
252b5132
RH
4104 }
4105 else if ((p_type >= PT_LOOS) && (p_type <= PT_HIOS))
103f02d3 4106 {
df3a023b 4107 const char * result = NULL;
103f02d3 4108
df3a023b 4109 switch (filedata->file_header.e_ident[EI_OSABI])
103f02d3 4110 {
df3a023b
AM
4111 case ELFOSABI_GNU:
4112 case ELFOSABI_FREEBSD:
4113 if (p_type >= PT_GNU_MBIND_LO && p_type <= PT_GNU_MBIND_HI)
4114 {
4115 sprintf (buff, "GNU_MBIND+%#lx", p_type - PT_GNU_MBIND_LO);
4116 result = buff;
4117 }
103f02d3 4118 break;
df3a023b
AM
4119 case ELFOSABI_HPUX:
4120 result = get_hpux_segment_type (p_type,
4121 filedata->file_header.e_machine);
4122 break;
4123 case ELFOSABI_SOLARIS:
4124 result = get_solaris_segment_type (p_type);
00428cca 4125 break;
103f02d3 4126 default:
103f02d3
UD
4127 break;
4128 }
103f02d3
UD
4129 if (result != NULL)
4130 return result;
4131
1a9ccd70 4132 sprintf (buff, "LOOS+%#lx", p_type - PT_LOOS);
103f02d3 4133 }
252b5132 4134 else
e9e44622 4135 snprintf (buff, sizeof (buff), _("<unknown>: %lx"), p_type);
252b5132
RH
4136
4137 return buff;
4138 }
4139}
4140
53a346d8
CZ
4141static const char *
4142get_arc_section_type_name (unsigned int sh_type)
4143{
4144 switch (sh_type)
4145 {
4146 case SHT_ARC_ATTRIBUTES: return "ARC_ATTRIBUTES";
4147 default:
4148 break;
4149 }
4150 return NULL;
4151}
4152
252b5132 4153static const char *
d3ba0551 4154get_mips_section_type_name (unsigned int sh_type)
252b5132
RH
4155{
4156 switch (sh_type)
4157 {
b34976b6
AM
4158 case SHT_MIPS_LIBLIST: return "MIPS_LIBLIST";
4159 case SHT_MIPS_MSYM: return "MIPS_MSYM";
4160 case SHT_MIPS_CONFLICT: return "MIPS_CONFLICT";
4161 case SHT_MIPS_GPTAB: return "MIPS_GPTAB";
4162 case SHT_MIPS_UCODE: return "MIPS_UCODE";
4163 case SHT_MIPS_DEBUG: return "MIPS_DEBUG";
4164 case SHT_MIPS_REGINFO: return "MIPS_REGINFO";
4165 case SHT_MIPS_PACKAGE: return "MIPS_PACKAGE";
4166 case SHT_MIPS_PACKSYM: return "MIPS_PACKSYM";
4167 case SHT_MIPS_RELD: return "MIPS_RELD";
4168 case SHT_MIPS_IFACE: return "MIPS_IFACE";
4169 case SHT_MIPS_CONTENT: return "MIPS_CONTENT";
4170 case SHT_MIPS_OPTIONS: return "MIPS_OPTIONS";
4171 case SHT_MIPS_SHDR: return "MIPS_SHDR";
4172 case SHT_MIPS_FDESC: return "MIPS_FDESC";
4173 case SHT_MIPS_EXTSYM: return "MIPS_EXTSYM";
4174 case SHT_MIPS_DENSE: return "MIPS_DENSE";
4175 case SHT_MIPS_PDESC: return "MIPS_PDESC";
4176 case SHT_MIPS_LOCSYM: return "MIPS_LOCSYM";
4177 case SHT_MIPS_AUXSYM: return "MIPS_AUXSYM";
4178 case SHT_MIPS_OPTSYM: return "MIPS_OPTSYM";
4179 case SHT_MIPS_LOCSTR: return "MIPS_LOCSTR";
4180 case SHT_MIPS_LINE: return "MIPS_LINE";
4181 case SHT_MIPS_RFDESC: return "MIPS_RFDESC";
4182 case SHT_MIPS_DELTASYM: return "MIPS_DELTASYM";
4183 case SHT_MIPS_DELTAINST: return "MIPS_DELTAINST";
4184 case SHT_MIPS_DELTACLASS: return "MIPS_DELTACLASS";
4185 case SHT_MIPS_DWARF: return "MIPS_DWARF";
4186 case SHT_MIPS_DELTADECL: return "MIPS_DELTADECL";
4187 case SHT_MIPS_SYMBOL_LIB: return "MIPS_SYMBOL_LIB";
4188 case SHT_MIPS_EVENTS: return "MIPS_EVENTS";
4189 case SHT_MIPS_TRANSLATE: return "MIPS_TRANSLATE";
4190 case SHT_MIPS_PIXIE: return "MIPS_PIXIE";
4191 case SHT_MIPS_XLATE: return "MIPS_XLATE";
4192 case SHT_MIPS_XLATE_DEBUG: return "MIPS_XLATE_DEBUG";
4193 case SHT_MIPS_WHIRL: return "MIPS_WHIRL";
4194 case SHT_MIPS_EH_REGION: return "MIPS_EH_REGION";
4195 case SHT_MIPS_XLATE_OLD: return "MIPS_XLATE_OLD";
252b5132 4196 case SHT_MIPS_PDR_EXCEPTION: return "MIPS_PDR_EXCEPTION";
351cdf24 4197 case SHT_MIPS_ABIFLAGS: return "MIPS_ABIFLAGS";
f16a9783 4198 case SHT_MIPS_XHASH: return "MIPS_XHASH";
252b5132
RH
4199 default:
4200 break;
4201 }
4202 return NULL;
4203}
4204
103f02d3 4205static const char *
d3ba0551 4206get_parisc_section_type_name (unsigned int sh_type)
103f02d3
UD
4207{
4208 switch (sh_type)
4209 {
4210 case SHT_PARISC_EXT: return "PARISC_EXT";
4211 case SHT_PARISC_UNWIND: return "PARISC_UNWIND";
4212 case SHT_PARISC_DOC: return "PARISC_DOC";
eec8f817
DA
4213 case SHT_PARISC_ANNOT: return "PARISC_ANNOT";
4214 case SHT_PARISC_SYMEXTN: return "PARISC_SYMEXTN";
4215 case SHT_PARISC_STUBS: return "PARISC_STUBS";
61472819 4216 case SHT_PARISC_DLKM: return "PARISC_DLKM";
32ec8896 4217 default: return NULL;
103f02d3 4218 }
103f02d3
UD
4219}
4220
4d6ed7c8 4221static const char *
dda8d76d 4222get_ia64_section_type_name (Filedata * filedata, unsigned int sh_type)
4d6ed7c8 4223{
18bd398b 4224 /* If the top 8 bits are 0x78 the next 8 are the os/abi ID. */
ecc51f48 4225 if ((sh_type & 0xFF000000) == SHT_IA_64_LOPSREG)
dda8d76d 4226 return get_osabi_name (filedata, (sh_type & 0x00FF0000) >> 16);
0de14b54 4227
4d6ed7c8
NC
4228 switch (sh_type)
4229 {
148b93f2
NC
4230 case SHT_IA_64_EXT: return "IA_64_EXT";
4231 case SHT_IA_64_UNWIND: return "IA_64_UNWIND";
4232 case SHT_IA_64_PRIORITY_INIT: return "IA_64_PRIORITY_INIT";
4233 case SHT_IA_64_VMS_TRACE: return "VMS_TRACE";
4234 case SHT_IA_64_VMS_TIE_SIGNATURES: return "VMS_TIE_SIGNATURES";
4235 case SHT_IA_64_VMS_DEBUG: return "VMS_DEBUG";
4236 case SHT_IA_64_VMS_DEBUG_STR: return "VMS_DEBUG_STR";
4237 case SHT_IA_64_VMS_LINKAGES: return "VMS_LINKAGES";
4238 case SHT_IA_64_VMS_SYMBOL_VECTOR: return "VMS_SYMBOL_VECTOR";
4239 case SHT_IA_64_VMS_FIXUP: return "VMS_FIXUP";
4d6ed7c8
NC
4240 default:
4241 break;
4242 }
4243 return NULL;
4244}
4245
d2b2c203
DJ
4246static const char *
4247get_x86_64_section_type_name (unsigned int sh_type)
4248{
4249 switch (sh_type)
4250 {
4251 case SHT_X86_64_UNWIND: return "X86_64_UNWIND";
32ec8896 4252 default: return NULL;
d2b2c203 4253 }
d2b2c203
DJ
4254}
4255
a06ea964
NC
4256static const char *
4257get_aarch64_section_type_name (unsigned int sh_type)
4258{
4259 switch (sh_type)
4260 {
32ec8896
NC
4261 case SHT_AARCH64_ATTRIBUTES: return "AARCH64_ATTRIBUTES";
4262 default: return NULL;
a06ea964 4263 }
a06ea964
NC
4264}
4265
40a18ebd
NC
4266static const char *
4267get_arm_section_type_name (unsigned int sh_type)
4268{
4269 switch (sh_type)
4270 {
7f6fed87
NC
4271 case SHT_ARM_EXIDX: return "ARM_EXIDX";
4272 case SHT_ARM_PREEMPTMAP: return "ARM_PREEMPTMAP";
4273 case SHT_ARM_ATTRIBUTES: return "ARM_ATTRIBUTES";
4274 case SHT_ARM_DEBUGOVERLAY: return "ARM_DEBUGOVERLAY";
4275 case SHT_ARM_OVERLAYSECTION: return "ARM_OVERLAYSECTION";
32ec8896 4276 default: return NULL;
40a18ebd 4277 }
40a18ebd
NC
4278}
4279
40b36596
JM
4280static const char *
4281get_tic6x_section_type_name (unsigned int sh_type)
4282{
4283 switch (sh_type)
4284 {
32ec8896
NC
4285 case SHT_C6000_UNWIND: return "C6000_UNWIND";
4286 case SHT_C6000_PREEMPTMAP: return "C6000_PREEMPTMAP";
4287 case SHT_C6000_ATTRIBUTES: return "C6000_ATTRIBUTES";
4288 case SHT_TI_ICODE: return "TI_ICODE";
4289 case SHT_TI_XREF: return "TI_XREF";
4290 case SHT_TI_HANDLER: return "TI_HANDLER";
4291 case SHT_TI_INITINFO: return "TI_INITINFO";
4292 case SHT_TI_PHATTRS: return "TI_PHATTRS";
4293 default: return NULL;
40b36596 4294 }
40b36596
JM
4295}
4296
13761a11 4297static const char *
b0191216 4298get_msp430_section_type_name (unsigned int sh_type)
13761a11
NC
4299{
4300 switch (sh_type)
4301 {
32ec8896
NC
4302 case SHT_MSP430_SEC_FLAGS: return "MSP430_SEC_FLAGS";
4303 case SHT_MSP430_SYM_ALIASES: return "MSP430_SYM_ALIASES";
4304 case SHT_MSP430_ATTRIBUTES: return "MSP430_ATTRIBUTES";
4305 default: return NULL;
13761a11
NC
4306 }
4307}
4308
fe944acf
FT
4309static const char *
4310get_nfp_section_type_name (unsigned int sh_type)
4311{
4312 switch (sh_type)
4313 {
4314 case SHT_NFP_MECONFIG: return "NFP_MECONFIG";
4315 case SHT_NFP_INITREG: return "NFP_INITREG";
4316 case SHT_NFP_UDEBUG: return "NFP_UDEBUG";
4317 default: return NULL;
4318 }
4319}
4320
685080f2
NC
4321static const char *
4322get_v850_section_type_name (unsigned int sh_type)
4323{
4324 switch (sh_type)
4325 {
32ec8896
NC
4326 case SHT_V850_SCOMMON: return "V850 Small Common";
4327 case SHT_V850_TCOMMON: return "V850 Tiny Common";
4328 case SHT_V850_ZCOMMON: return "V850 Zero Common";
4329 case SHT_RENESAS_IOP: return "RENESAS IOP";
4330 case SHT_RENESAS_INFO: return "RENESAS INFO";
4331 default: return NULL;
685080f2
NC
4332 }
4333}
4334
2dc8dd17
JW
4335static const char *
4336get_riscv_section_type_name (unsigned int sh_type)
4337{
4338 switch (sh_type)
4339 {
4340 case SHT_RISCV_ATTRIBUTES: return "RISCV_ATTRIBUTES";
4341 default: return NULL;
4342 }
4343}
4344
0861f561
CQ
4345static const char *
4346get_csky_section_type_name (unsigned int sh_type)
4347{
4348 switch (sh_type)
4349 {
4350 case SHT_CSKY_ATTRIBUTES: return "CSKY_ATTRIBUTES";
4351 default: return NULL;
4352 }
4353}
4354
252b5132 4355static const char *
dda8d76d 4356get_section_type_name (Filedata * filedata, unsigned int sh_type)
252b5132 4357{
b34976b6 4358 static char buff[32];
9fb71ee4 4359 const char * result;
252b5132
RH
4360
4361 switch (sh_type)
4362 {
4363 case SHT_NULL: return "NULL";
4364 case SHT_PROGBITS: return "PROGBITS";
4365 case SHT_SYMTAB: return "SYMTAB";
4366 case SHT_STRTAB: return "STRTAB";
4367 case SHT_RELA: return "RELA";
4368 case SHT_HASH: return "HASH";
4369 case SHT_DYNAMIC: return "DYNAMIC";
4370 case SHT_NOTE: return "NOTE";
4371 case SHT_NOBITS: return "NOBITS";
4372 case SHT_REL: return "REL";
4373 case SHT_SHLIB: return "SHLIB";
4374 case SHT_DYNSYM: return "DYNSYM";
d1133906
NC
4375 case SHT_INIT_ARRAY: return "INIT_ARRAY";
4376 case SHT_FINI_ARRAY: return "FINI_ARRAY";
4377 case SHT_PREINIT_ARRAY: return "PREINIT_ARRAY";
fdc90cb4 4378 case SHT_GNU_HASH: return "GNU_HASH";
93ebe586 4379 case SHT_GROUP: return "GROUP";
67ce483b 4380 case SHT_SYMTAB_SHNDX: return "SYMTAB SECTION INDICES";
252b5132
RH
4381 case SHT_GNU_verdef: return "VERDEF";
4382 case SHT_GNU_verneed: return "VERNEED";
4383 case SHT_GNU_versym: return "VERSYM";
b34976b6
AM
4384 case 0x6ffffff0: return "VERSYM";
4385 case 0x6ffffffc: return "VERDEF";
252b5132
RH
4386 case 0x7ffffffd: return "AUXILIARY";
4387 case 0x7fffffff: return "FILTER";
047b2264 4388 case SHT_GNU_LIBLIST: return "GNU_LIBLIST";
252b5132
RH
4389
4390 default:
4391 if ((sh_type >= SHT_LOPROC) && (sh_type <= SHT_HIPROC))
4392 {
dda8d76d 4393 switch (filedata->file_header.e_machine)
252b5132 4394 {
53a346d8
CZ
4395 case EM_ARC:
4396 case EM_ARC_COMPACT:
4397 case EM_ARC_COMPACT2:
4398 result = get_arc_section_type_name (sh_type);
4399 break;
252b5132 4400 case EM_MIPS:
4fe85591 4401 case EM_MIPS_RS3_LE:
252b5132
RH
4402 result = get_mips_section_type_name (sh_type);
4403 break;
103f02d3
UD
4404 case EM_PARISC:
4405 result = get_parisc_section_type_name (sh_type);
4406 break;
4d6ed7c8 4407 case EM_IA_64:
dda8d76d 4408 result = get_ia64_section_type_name (filedata, sh_type);
4d6ed7c8 4409 break;
d2b2c203 4410 case EM_X86_64:
8a9036a4 4411 case EM_L1OM:
7a9068fe 4412 case EM_K1OM:
d2b2c203
DJ
4413 result = get_x86_64_section_type_name (sh_type);
4414 break;
a06ea964
NC
4415 case EM_AARCH64:
4416 result = get_aarch64_section_type_name (sh_type);
4417 break;
40a18ebd
NC
4418 case EM_ARM:
4419 result = get_arm_section_type_name (sh_type);
4420 break;
40b36596
JM
4421 case EM_TI_C6000:
4422 result = get_tic6x_section_type_name (sh_type);
4423 break;
13761a11 4424 case EM_MSP430:
b0191216 4425 result = get_msp430_section_type_name (sh_type);
13761a11 4426 break;
fe944acf
FT
4427 case EM_NFP:
4428 result = get_nfp_section_type_name (sh_type);
4429 break;
685080f2
NC
4430 case EM_V800:
4431 case EM_V850:
4432 case EM_CYGNUS_V850:
4433 result = get_v850_section_type_name (sh_type);
4434 break;
2dc8dd17
JW
4435 case EM_RISCV:
4436 result = get_riscv_section_type_name (sh_type);
4437 break;
0861f561
CQ
4438 case EM_CSKY:
4439 result = get_csky_section_type_name (sh_type);
4440 break;
252b5132
RH
4441 default:
4442 result = NULL;
4443 break;
4444 }
4445
4446 if (result != NULL)
4447 return result;
4448
9fb71ee4 4449 sprintf (buff, "LOPROC+%#x", sh_type - SHT_LOPROC);
252b5132
RH
4450 }
4451 else if ((sh_type >= SHT_LOOS) && (sh_type <= SHT_HIOS))
148b93f2 4452 {
dda8d76d 4453 switch (filedata->file_header.e_machine)
148b93f2
NC
4454 {
4455 case EM_IA_64:
dda8d76d 4456 result = get_ia64_section_type_name (filedata, sh_type);
148b93f2
NC
4457 break;
4458 default:
dda8d76d 4459 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
fd85a6a1
NC
4460 result = get_solaris_section_type (sh_type);
4461 else
1b4b80bf
NC
4462 {
4463 switch (sh_type)
4464 {
4465 case SHT_GNU_INCREMENTAL_INPUTS: result = "GNU_INCREMENTAL_INPUTS"; break;
4466 case SHT_GNU_ATTRIBUTES: result = "GNU_ATTRIBUTES"; break;
4467 case SHT_GNU_HASH: result = "GNU_HASH"; break;
4468 case SHT_GNU_LIBLIST: result = "GNU_LIBLIST"; break;
4469 default:
4470 result = NULL;
4471 break;
4472 }
4473 }
148b93f2
NC
4474 break;
4475 }
4476
4477 if (result != NULL)
4478 return result;
4479
9fb71ee4 4480 sprintf (buff, "LOOS+%#x", sh_type - SHT_LOOS);
148b93f2 4481 }
252b5132 4482 else if ((sh_type >= SHT_LOUSER) && (sh_type <= SHT_HIUSER))
685080f2 4483 {
dda8d76d 4484 switch (filedata->file_header.e_machine)
685080f2
NC
4485 {
4486 case EM_V800:
4487 case EM_V850:
4488 case EM_CYGNUS_V850:
9fb71ee4 4489 result = get_v850_section_type_name (sh_type);
a9fb83be 4490 break;
685080f2 4491 default:
9fb71ee4 4492 result = NULL;
685080f2
NC
4493 break;
4494 }
4495
9fb71ee4
NC
4496 if (result != NULL)
4497 return result;
4498
4499 sprintf (buff, "LOUSER+%#x", sh_type - SHT_LOUSER);
685080f2 4500 }
252b5132 4501 else
a7dbfd1c
NC
4502 /* This message is probably going to be displayed in a 15
4503 character wide field, so put the hex value first. */
4504 snprintf (buff, sizeof (buff), _("%08x: <unknown>"), sh_type);
103f02d3 4505
252b5132
RH
4506 return buff;
4507 }
4508}
4509
79bc120c
NC
4510enum long_option_values
4511{
4512 OPTION_DEBUG_DUMP = 512,
4513 OPTION_DYN_SYMS,
0f03783c 4514 OPTION_LTO_SYMS,
79bc120c
NC
4515 OPTION_DWARF_DEPTH,
4516 OPTION_DWARF_START,
4517 OPTION_DWARF_CHECK,
4518 OPTION_CTF_DUMP,
4519 OPTION_CTF_PARENT,
4520 OPTION_CTF_SYMBOLS,
4521 OPTION_CTF_STRINGS,
4522 OPTION_WITH_SYMBOL_VERSIONS,
4523 OPTION_RECURSE_LIMIT,
4524 OPTION_NO_RECURSE_LIMIT,
4525 OPTION_NO_DEMANGLING
4526};
2979dc34 4527
85b1c36d 4528static struct option options[] =
252b5132 4529{
79bc120c
NC
4530 /* Note - This table is alpha-sorted on the 'val'
4531 field in order to make adding new options easier. */
4532 {"arch-specific", no_argument, 0, 'A'},
b34976b6 4533 {"all", no_argument, 0, 'a'},
79bc120c
NC
4534 {"demangle", optional_argument, 0, 'C'},
4535 {"archive-index", no_argument, 0, 'c'},
4536 {"use-dynamic", no_argument, 0, 'D'},
4537 {"dynamic", no_argument, 0, 'd'},
b34976b6 4538 {"headers", no_argument, 0, 'e'},
79bc120c
NC
4539 {"section-groups", no_argument, 0, 'g'},
4540 {"help", no_argument, 0, 'H'},
4541 {"file-header", no_argument, 0, 'h'},
b34976b6 4542 {"histogram", no_argument, 0, 'I'},
79bc120c
NC
4543 {"lint", no_argument, 0, 'L'},
4544 {"enable-checks", no_argument, 0, 'L'},
4545 {"program-headers", no_argument, 0, 'l'},
b34976b6 4546 {"segments", no_argument, 0, 'l'},
595cf52e 4547 {"full-section-name",no_argument, 0, 'N'},
79bc120c
NC
4548 {"notes", no_argument, 0, 'n'},
4549 {"string-dump", required_argument, 0, 'p'},
4550 {"relocated-dump", required_argument, 0, 'R'},
4551 {"relocs", no_argument, 0, 'r'},
4552 {"section-headers", no_argument, 0, 'S'},
4553 {"sections", no_argument, 0, 'S'},
b34976b6
AM
4554 {"symbols", no_argument, 0, 's'},
4555 {"syms", no_argument, 0, 's'},
79bc120c
NC
4556 {"silent-truncation",no_argument, 0, 'T'},
4557 {"section-details", no_argument, 0, 't'},
09c11c86 4558 {"unwind", no_argument, 0, 'u'},
79bc120c
NC
4559 {"version-info", no_argument, 0, 'V'},
4560 {"version", no_argument, 0, 'v'},
4561 {"wide", no_argument, 0, 'W'},
b34976b6 4562 {"hex-dump", required_argument, 0, 'x'},
0e602686 4563 {"decompress", no_argument, 0, 'z'},
252b5132 4564
79bc120c
NC
4565 {"no-demangle", no_argument, 0, OPTION_NO_DEMANGLING},
4566 {"recurse-limit", no_argument, NULL, OPTION_RECURSE_LIMIT},
4567 {"no-recurse-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4568 {"no-recursion-limit", no_argument, NULL, OPTION_NO_RECURSE_LIMIT},
4569 {"dyn-syms", no_argument, 0, OPTION_DYN_SYMS},
0f03783c 4570 {"lto-syms", no_argument, 0, OPTION_LTO_SYMS},
79bc120c 4571 {"debug-dump", optional_argument, 0, OPTION_DEBUG_DUMP},
fd2f0033
TT
4572 {"dwarf-depth", required_argument, 0, OPTION_DWARF_DEPTH},
4573 {"dwarf-start", required_argument, 0, OPTION_DWARF_START},
4723351a 4574 {"dwarf-check", no_argument, 0, OPTION_DWARF_CHECK},
094e34f2 4575#ifdef ENABLE_LIBCTF
d344b407 4576 {"ctf", required_argument, 0, OPTION_CTF_DUMP},
7d9813f1
NA
4577 {"ctf-symbols", required_argument, 0, OPTION_CTF_SYMBOLS},
4578 {"ctf-strings", required_argument, 0, OPTION_CTF_STRINGS},
4579 {"ctf-parent", required_argument, 0, OPTION_CTF_PARENT},
094e34f2 4580#endif
7d9813f1 4581
b34976b6 4582 {0, no_argument, 0, 0}
252b5132
RH
4583};
4584
4585static void
2cf0635d 4586usage (FILE * stream)
252b5132 4587{
92f01d61
JM
4588 fprintf (stream, _("Usage: readelf <option(s)> elf-file(s)\n"));
4589 fprintf (stream, _(" Display information about the contents of ELF format files\n"));
4590 fprintf (stream, _(" Options are:\n\
8b53311e
NC
4591 -a --all Equivalent to: -h -l -S -s -r -d -V -A -I\n\
4592 -h --file-header Display the ELF file header\n\
4593 -l --program-headers Display the program headers\n\
4594 --segments An alias for --program-headers\n\
4595 -S --section-headers Display the sections' header\n\
4596 --sections An alias for --section-headers\n\
f5842774 4597 -g --section-groups Display the section groups\n\
5477e8a0 4598 -t --section-details Display the section details\n\
8b53311e
NC
4599 -e --headers Equivalent to: -h -l -S\n\
4600 -s --syms Display the symbol table\n\
3f08eb35 4601 --symbols An alias for --syms\n\
1b513401 4602 --dyn-syms Display the dynamic symbol table\n\
0f03783c 4603 --lto-syms Display LTO symbol tables\n\
79bc120c
NC
4604 -C --demangle[=STYLE] Decode low-level symbol names into user-level names\n\
4605 The STYLE, if specified, can be `auto' (the default),\n\
4606 `gnu', `lucid', `arm', `hp', `edg', `gnu-v3', `java'\n\
4607 or `gnat'\n\
4608 --no-demangle Do not demangle low-level symbol names. (This is the default)\n\
4609 --recurse-limit Enable a demangling recursion limit. (This is the default)\n\
4610 --no-recurse-limit Disable a demangling recursion limit\n\
8b53311e
NC
4611 -n --notes Display the core notes (if present)\n\
4612 -r --relocs Display the relocations (if present)\n\
4613 -u --unwind Display the unwind info (if present)\n\
b2d38a17 4614 -d --dynamic Display the dynamic section (if present)\n\
8b53311e 4615 -V --version-info Display the version sections (if present)\n\
1b31d05e 4616 -A --arch-specific Display architecture specific information (if any)\n\
4145f1d5 4617 -c --archive-index Display the symbol/file index in an archive\n\
8b53311e 4618 -D --use-dynamic Use the dynamic section info when displaying symbols\n\
1b513401 4619 -L --lint|--enable-checks Display warning messages for possible problems\n\
09c11c86
NC
4620 -x --hex-dump=<number|name>\n\
4621 Dump the contents of section <number|name> as bytes\n\
4622 -p --string-dump=<number|name>\n\
4623 Dump the contents of section <number|name> as strings\n\
cf13d699
NC
4624 -R --relocated-dump=<number|name>\n\
4625 Dump the contents of section <number|name> as relocated bytes\n\
0e602686 4626 -z --decompress Decompress section before dumping it\n\
e4b7104b 4627 -w[lLiaprmfFsoORtUuTgAckK] or\n\
1ed06042 4628 --debug-dump[=rawline,=decodedline,=info,=abbrev,=pubnames,=aranges,=macro,=frames,\n\
e4b7104b 4629 =frames-interp,=str,=str-offsets,=loc,=Ranges,=pubtypes,\n\
657d0d47 4630 =gdb_index,=trace_info,=trace_abbrev,=trace_aranges,\n\
dda8d76d
NC
4631 =addr,=cu_index,=links,=follow-links]\n\
4632 Display the contents of DWARF debug sections\n"));
fd2f0033
TT
4633 fprintf (stream, _("\
4634 --dwarf-depth=N Do not display DIEs at depth N or greater\n\
4635 --dwarf-start=N Display DIEs starting with N, at the same depth\n\
4636 or deeper\n"));
094e34f2 4637#ifdef ENABLE_LIBCTF
7d9813f1
NA
4638 fprintf (stream, _("\
4639 --ctf=<number|name> Display CTF info from section <number|name>\n\
4640 --ctf-parent=<number|name>\n\
4641 Use section <number|name> as the CTF parent\n\n\
4642 --ctf-symbols=<number|name>\n\
4643 Use section <number|name> as the CTF external symtab\n\n\
4644 --ctf-strings=<number|name>\n\
4645 Use section <number|name> as the CTF external strtab\n\n"));
094e34f2 4646#endif
7d9813f1 4647
252b5132 4648#ifdef SUPPORT_DISASSEMBLY
92f01d61 4649 fprintf (stream, _("\
09c11c86
NC
4650 -i --instruction-dump=<number|name>\n\
4651 Disassemble the contents of section <number|name>\n"));
252b5132 4652#endif
92f01d61 4653 fprintf (stream, _("\
8b53311e
NC
4654 -I --histogram Display histogram of bucket list lengths\n\
4655 -W --wide Allow output width to exceed 80 characters\n\
0942c7ab 4656 -T --silent-truncation If a symbol name is truncated, do not add a suffix [...]\n\
07012eee 4657 @<file> Read options from <file>\n\
8b53311e
NC
4658 -H --help Display this information\n\
4659 -v --version Display the version number of readelf\n"));
1118d252 4660
92f01d61
JM
4661 if (REPORT_BUGS_TO[0] && stream == stdout)
4662 fprintf (stdout, _("Report bugs to %s\n"), REPORT_BUGS_TO);
252b5132 4663
92f01d61 4664 exit (stream == stdout ? 0 : 1);
252b5132
RH
4665}
4666
18bd398b
NC
4667/* Record the fact that the user wants the contents of section number
4668 SECTION to be displayed using the method(s) encoded as flags bits
4669 in TYPE. Note, TYPE can be zero if we are creating the array for
4670 the first time. */
4671
252b5132 4672static void
6431e409
AM
4673request_dump_bynumber (struct dump_data *dumpdata,
4674 unsigned int section, dump_type type)
252b5132 4675{
6431e409 4676 if (section >= dumpdata->num_dump_sects)
252b5132 4677 {
2cf0635d 4678 dump_type * new_dump_sects;
252b5132 4679
3f5e193b 4680 new_dump_sects = (dump_type *) calloc (section + 1,
dda8d76d 4681 sizeof (* new_dump_sects));
252b5132
RH
4682
4683 if (new_dump_sects == NULL)
591a748a 4684 error (_("Out of memory allocating dump request table.\n"));
252b5132
RH
4685 else
4686 {
6431e409 4687 if (dumpdata->dump_sects)
21b65bac
NC
4688 {
4689 /* Copy current flag settings. */
6431e409
AM
4690 memcpy (new_dump_sects, dumpdata->dump_sects,
4691 dumpdata->num_dump_sects * sizeof (* new_dump_sects));
252b5132 4692
6431e409 4693 free (dumpdata->dump_sects);
21b65bac 4694 }
252b5132 4695
6431e409
AM
4696 dumpdata->dump_sects = new_dump_sects;
4697 dumpdata->num_dump_sects = section + 1;
252b5132
RH
4698 }
4699 }
4700
6431e409
AM
4701 if (dumpdata->dump_sects)
4702 dumpdata->dump_sects[section] |= type;
252b5132
RH
4703}
4704
aef1f6d0
DJ
4705/* Request a dump by section name. */
4706
4707static void
2cf0635d 4708request_dump_byname (const char * section, dump_type type)
aef1f6d0 4709{
2cf0635d 4710 struct dump_list_entry * new_request;
aef1f6d0 4711
3f5e193b
NC
4712 new_request = (struct dump_list_entry *)
4713 malloc (sizeof (struct dump_list_entry));
aef1f6d0 4714 if (!new_request)
591a748a 4715 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4716
4717 new_request->name = strdup (section);
4718 if (!new_request->name)
591a748a 4719 error (_("Out of memory allocating dump request table.\n"));
aef1f6d0
DJ
4720
4721 new_request->type = type;
4722
4723 new_request->next = dump_sects_byname;
4724 dump_sects_byname = new_request;
4725}
4726
cf13d699 4727static inline void
6431e409 4728request_dump (struct dump_data *dumpdata, dump_type type)
cf13d699
NC
4729{
4730 int section;
4731 char * cp;
4732
4733 do_dump++;
4734 section = strtoul (optarg, & cp, 0);
4735
4736 if (! *cp && section >= 0)
6431e409 4737 request_dump_bynumber (dumpdata, section, type);
cf13d699
NC
4738 else
4739 request_dump_byname (optarg, type);
4740}
4741
252b5132 4742static void
6431e409 4743parse_args (struct dump_data *dumpdata, int argc, char ** argv)
252b5132
RH
4744{
4745 int c;
4746
4747 if (argc < 2)
92f01d61 4748 usage (stderr);
252b5132
RH
4749
4750 while ((c = getopt_long
79bc120c 4751 (argc, argv, "ACDHILNR:STVWacdeghi:lnp:rstuvw::x:z", options, NULL)) != EOF)
252b5132 4752 {
252b5132
RH
4753 switch (c)
4754 {
4755 case 0:
4756 /* Long options. */
4757 break;
4758 case 'H':
92f01d61 4759 usage (stdout);
252b5132
RH
4760 break;
4761
4762 case 'a':
32ec8896
NC
4763 do_syms = TRUE;
4764 do_reloc = TRUE;
4765 do_unwind = TRUE;
4766 do_dynamic = TRUE;
4767 do_header = TRUE;
4768 do_sections = TRUE;
4769 do_section_groups = TRUE;
4770 do_segments = TRUE;
4771 do_version = TRUE;
4772 do_histogram = TRUE;
4773 do_arch = TRUE;
4774 do_notes = TRUE;
252b5132 4775 break;
79bc120c 4776
f5842774 4777 case 'g':
32ec8896 4778 do_section_groups = TRUE;
f5842774 4779 break;
5477e8a0 4780 case 't':
595cf52e 4781 case 'N':
32ec8896
NC
4782 do_sections = TRUE;
4783 do_section_details = TRUE;
595cf52e 4784 break;
252b5132 4785 case 'e':
32ec8896
NC
4786 do_header = TRUE;
4787 do_sections = TRUE;
4788 do_segments = TRUE;
252b5132 4789 break;
a952a375 4790 case 'A':
32ec8896 4791 do_arch = TRUE;
a952a375 4792 break;
252b5132 4793 case 'D':
32ec8896 4794 do_using_dynamic = TRUE;
252b5132
RH
4795 break;
4796 case 'r':
32ec8896 4797 do_reloc = TRUE;
252b5132 4798 break;
4d6ed7c8 4799 case 'u':
32ec8896 4800 do_unwind = TRUE;
4d6ed7c8 4801 break;
252b5132 4802 case 'h':
32ec8896 4803 do_header = TRUE;
252b5132
RH
4804 break;
4805 case 'l':
32ec8896 4806 do_segments = TRUE;
252b5132
RH
4807 break;
4808 case 's':
32ec8896 4809 do_syms = TRUE;
252b5132
RH
4810 break;
4811 case 'S':
32ec8896 4812 do_sections = TRUE;
252b5132
RH
4813 break;
4814 case 'd':
32ec8896 4815 do_dynamic = TRUE;
252b5132 4816 break;
a952a375 4817 case 'I':
32ec8896 4818 do_histogram = TRUE;
a952a375 4819 break;
779fe533 4820 case 'n':
32ec8896 4821 do_notes = TRUE;
779fe533 4822 break;
4145f1d5 4823 case 'c':
32ec8896 4824 do_archive_index = TRUE;
4145f1d5 4825 break;
1b513401
NC
4826 case 'L':
4827 do_checks = TRUE;
4828 break;
252b5132 4829 case 'x':
6431e409 4830 request_dump (dumpdata, HEX_DUMP);
aef1f6d0 4831 break;
09c11c86 4832 case 'p':
6431e409 4833 request_dump (dumpdata, STRING_DUMP);
cf13d699
NC
4834 break;
4835 case 'R':
6431e409 4836 request_dump (dumpdata, RELOC_DUMP);
09c11c86 4837 break;
0e602686 4838 case 'z':
32ec8896 4839 decompress_dumps = TRUE;
0e602686 4840 break;
252b5132 4841 case 'w':
32ec8896 4842 do_dump = TRUE;
0f03783c 4843 if (optarg == NULL)
613ff48b 4844 {
32ec8896 4845 do_debugging = TRUE;
613ff48b
CC
4846 dwarf_select_sections_all ();
4847 }
252b5132
RH
4848 else
4849 {
32ec8896 4850 do_debugging = FALSE;
4cb93e3b 4851 dwarf_select_sections_by_letters (optarg);
252b5132
RH
4852 }
4853 break;
2979dc34 4854 case OPTION_DEBUG_DUMP:
32ec8896 4855 do_dump = TRUE;
0f03783c 4856 if (optarg == NULL)
32ec8896 4857 do_debugging = TRUE;
2979dc34
JJ
4858 else
4859 {
32ec8896 4860 do_debugging = FALSE;
4cb93e3b 4861 dwarf_select_sections_by_names (optarg);
2979dc34
JJ
4862 }
4863 break;
fd2f0033
TT
4864 case OPTION_DWARF_DEPTH:
4865 {
4866 char *cp;
4867
4868 dwarf_cutoff_level = strtoul (optarg, & cp, 0);
4869 }
4870 break;
4871 case OPTION_DWARF_START:
4872 {
4873 char *cp;
4874
4875 dwarf_start_die = strtoul (optarg, & cp, 0);
4876 }
4877 break;
4723351a 4878 case OPTION_DWARF_CHECK:
32ec8896 4879 dwarf_check = TRUE;
4723351a 4880 break;
7d9813f1
NA
4881 case OPTION_CTF_DUMP:
4882 do_ctf = TRUE;
6431e409 4883 request_dump (dumpdata, CTF_DUMP);
7d9813f1
NA
4884 break;
4885 case OPTION_CTF_SYMBOLS:
df16e041 4886 free (dump_ctf_symtab_name);
7d9813f1
NA
4887 dump_ctf_symtab_name = strdup (optarg);
4888 break;
4889 case OPTION_CTF_STRINGS:
df16e041 4890 free (dump_ctf_strtab_name);
7d9813f1
NA
4891 dump_ctf_strtab_name = strdup (optarg);
4892 break;
4893 case OPTION_CTF_PARENT:
df16e041 4894 free (dump_ctf_parent_name);
7d9813f1
NA
4895 dump_ctf_parent_name = strdup (optarg);
4896 break;
2c610e4b 4897 case OPTION_DYN_SYMS:
32ec8896 4898 do_dyn_syms = TRUE;
2c610e4b 4899 break;
0f03783c
NC
4900 case OPTION_LTO_SYMS:
4901 do_lto_syms = TRUE;
4902 break;
252b5132
RH
4903#ifdef SUPPORT_DISASSEMBLY
4904 case 'i':
6431e409 4905 request_dump (dumpdata, DISASS_DUMP);
cf13d699 4906 break;
252b5132
RH
4907#endif
4908 case 'v':
4909 print_version (program_name);
4910 break;
4911 case 'V':
32ec8896 4912 do_version = TRUE;
252b5132 4913 break;
d974e256 4914 case 'W':
32ec8896 4915 do_wide = TRUE;
d974e256 4916 break;
0942c7ab
NC
4917 case 'T':
4918 do_not_show_symbol_truncation = TRUE;
4919 break;
79bc120c
NC
4920 case 'C':
4921 do_demangle = TRUE;
4922 if (optarg != NULL)
4923 {
4924 enum demangling_styles style;
4925
4926 style = cplus_demangle_name_to_style (optarg);
4927 if (style == unknown_demangling)
4928 error (_("unknown demangling style `%s'"), optarg);
4929
4930 cplus_demangle_set_style (style);
4931 }
4932 break;
4933 case OPTION_NO_DEMANGLING:
4934 do_demangle = FALSE;
4935 break;
4936 case OPTION_RECURSE_LIMIT:
4937 demangle_flags &= ~ DMGL_NO_RECURSE_LIMIT;
4938 break;
4939 case OPTION_NO_RECURSE_LIMIT:
4940 demangle_flags |= DMGL_NO_RECURSE_LIMIT;
4941 break;
4942 case OPTION_WITH_SYMBOL_VERSIONS:
4943 /* Ignored for backward compatibility. */
4944 break;
b9e920ec 4945
252b5132 4946 default:
252b5132
RH
4947 /* xgettext:c-format */
4948 error (_("Invalid option '-%c'\n"), c);
1a0670f3 4949 /* Fall through. */
252b5132 4950 case '?':
92f01d61 4951 usage (stderr);
252b5132
RH
4952 }
4953 }
4954
4d6ed7c8 4955 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
252b5132 4956 && !do_segments && !do_header && !do_dump && !do_version
f5842774 4957 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 4958 && !do_section_groups && !do_archive_index
0f03783c 4959 && !do_dyn_syms && !do_lto_syms)
1b513401
NC
4960 {
4961 if (do_checks)
4962 {
4963 check_all = TRUE;
4964 do_dynamic = do_syms = do_reloc = do_unwind = do_sections = TRUE;
4965 do_segments = do_header = do_dump = do_version = TRUE;
4966 do_histogram = do_debugging = do_arch = do_notes = TRUE;
4967 do_section_groups = do_archive_index = do_dyn_syms = TRUE;
0f03783c 4968 do_lto_syms = TRUE;
1b513401
NC
4969 }
4970 else
4971 usage (stderr);
4972 }
252b5132
RH
4973}
4974
4975static const char *
d3ba0551 4976get_elf_class (unsigned int elf_class)
252b5132 4977{
b34976b6 4978 static char buff[32];
103f02d3 4979
252b5132
RH
4980 switch (elf_class)
4981 {
4982 case ELFCLASSNONE: return _("none");
e3c8793a
NC
4983 case ELFCLASS32: return "ELF32";
4984 case ELFCLASS64: return "ELF64";
ab5e7794 4985 default:
e9e44622 4986 snprintf (buff, sizeof (buff), _("<unknown: %x>"), elf_class);
ab5e7794 4987 return buff;
252b5132
RH
4988 }
4989}
4990
4991static const char *
d3ba0551 4992get_data_encoding (unsigned int encoding)
252b5132 4993{
b34976b6 4994 static char buff[32];
103f02d3 4995
252b5132
RH
4996 switch (encoding)
4997 {
4998 case ELFDATANONE: return _("none");
33c63f9d
CM
4999 case ELFDATA2LSB: return _("2's complement, little endian");
5000 case ELFDATA2MSB: return _("2's complement, big endian");
103f02d3 5001 default:
e9e44622 5002 snprintf (buff, sizeof (buff), _("<unknown: %x>"), encoding);
ab5e7794 5003 return buff;
252b5132
RH
5004 }
5005}
5006
dda8d76d 5007/* Decode the data held in 'filedata->file_header'. */
ee42cf8c 5008
32ec8896 5009static bfd_boolean
dda8d76d 5010process_file_header (Filedata * filedata)
252b5132 5011{
dda8d76d
NC
5012 Elf_Internal_Ehdr * header = & filedata->file_header;
5013
5014 if ( header->e_ident[EI_MAG0] != ELFMAG0
5015 || header->e_ident[EI_MAG1] != ELFMAG1
5016 || header->e_ident[EI_MAG2] != ELFMAG2
5017 || header->e_ident[EI_MAG3] != ELFMAG3)
252b5132
RH
5018 {
5019 error
5020 (_("Not an ELF file - it has the wrong magic bytes at the start\n"));
32ec8896 5021 return FALSE;
252b5132
RH
5022 }
5023
955ff7fc 5024 init_dwarf_regnames_by_elf_machine_code (header->e_machine);
2dc4cec1 5025
252b5132
RH
5026 if (do_header)
5027 {
32ec8896 5028 unsigned i;
252b5132
RH
5029
5030 printf (_("ELF Header:\n"));
5031 printf (_(" Magic: "));
b34976b6 5032 for (i = 0; i < EI_NIDENT; i++)
dda8d76d 5033 printf ("%2.2x ", header->e_ident[i]);
252b5132
RH
5034 printf ("\n");
5035 printf (_(" Class: %s\n"),
dda8d76d 5036 get_elf_class (header->e_ident[EI_CLASS]));
252b5132 5037 printf (_(" Data: %s\n"),
dda8d76d 5038 get_data_encoding (header->e_ident[EI_DATA]));
e8a64888 5039 printf (_(" Version: %d%s\n"),
dda8d76d
NC
5040 header->e_ident[EI_VERSION],
5041 (header->e_ident[EI_VERSION] == EV_CURRENT
e8a64888 5042 ? _(" (current)")
dda8d76d 5043 : (header->e_ident[EI_VERSION] != EV_NONE
e8a64888 5044 ? _(" <unknown>")
789be9f7 5045 : "")));
252b5132 5046 printf (_(" OS/ABI: %s\n"),
dda8d76d 5047 get_osabi_name (filedata, header->e_ident[EI_OSABI]));
252b5132 5048 printf (_(" ABI Version: %d\n"),
dda8d76d 5049 header->e_ident[EI_ABIVERSION]);
252b5132 5050 printf (_(" Type: %s\n"),
dda8d76d 5051 get_file_type (header->e_type));
252b5132 5052 printf (_(" Machine: %s\n"),
dda8d76d 5053 get_machine_name (header->e_machine));
252b5132 5054 printf (_(" Version: 0x%lx\n"),
e8a64888 5055 header->e_version);
76da6bbe 5056
f7a99963 5057 printf (_(" Entry point address: "));
e8a64888 5058 print_vma (header->e_entry, PREFIX_HEX);
f7a99963 5059 printf (_("\n Start of program headers: "));
e8a64888 5060 print_vma (header->e_phoff, DEC);
f7a99963 5061 printf (_(" (bytes into file)\n Start of section headers: "));
e8a64888 5062 print_vma (header->e_shoff, DEC);
f7a99963 5063 printf (_(" (bytes into file)\n"));
76da6bbe 5064
252b5132 5065 printf (_(" Flags: 0x%lx%s\n"),
e8a64888 5066 header->e_flags,
dda8d76d 5067 get_machine_flags (filedata, header->e_flags, header->e_machine));
e8a64888
AM
5068 printf (_(" Size of this header: %u (bytes)\n"),
5069 header->e_ehsize);
5070 printf (_(" Size of program headers: %u (bytes)\n"),
5071 header->e_phentsize);
5072 printf (_(" Number of program headers: %u"),
5073 header->e_phnum);
dda8d76d
NC
5074 if (filedata->section_headers != NULL
5075 && header->e_phnum == PN_XNUM
5076 && filedata->section_headers[0].sh_info != 0)
e8a64888
AM
5077 {
5078 header->e_phnum = filedata->section_headers[0].sh_info;
5079 printf (" (%u)", header->e_phnum);
5080 }
2046a35d 5081 putc ('\n', stdout);
e8a64888
AM
5082 printf (_(" Size of section headers: %u (bytes)\n"),
5083 header->e_shentsize);
5084 printf (_(" Number of section headers: %u"),
5085 header->e_shnum);
dda8d76d 5086 if (filedata->section_headers != NULL && header->e_shnum == SHN_UNDEF)
e8a64888
AM
5087 {
5088 header->e_shnum = filedata->section_headers[0].sh_size;
5089 printf (" (%u)", header->e_shnum);
5090 }
560f3c1c 5091 putc ('\n', stdout);
e8a64888
AM
5092 printf (_(" Section header string table index: %u"),
5093 header->e_shstrndx);
dda8d76d
NC
5094 if (filedata->section_headers != NULL
5095 && header->e_shstrndx == (SHN_XINDEX & 0xffff))
e8a64888
AM
5096 {
5097 header->e_shstrndx = filedata->section_headers[0].sh_link;
5098 printf (" (%u)", header->e_shstrndx);
5099 }
5100 if (header->e_shstrndx != SHN_UNDEF
5101 && header->e_shstrndx >= header->e_shnum)
5102 {
5103 header->e_shstrndx = SHN_UNDEF;
5104 printf (_(" <corrupt: out of range>"));
5105 }
560f3c1c
AM
5106 putc ('\n', stdout);
5107 }
5108
dda8d76d 5109 if (filedata->section_headers != NULL)
560f3c1c 5110 {
dda8d76d
NC
5111 if (header->e_phnum == PN_XNUM
5112 && filedata->section_headers[0].sh_info != 0)
5113 header->e_phnum = filedata->section_headers[0].sh_info;
5114 if (header->e_shnum == SHN_UNDEF)
5115 header->e_shnum = filedata->section_headers[0].sh_size;
5116 if (header->e_shstrndx == (SHN_XINDEX & 0xffff))
5117 header->e_shstrndx = filedata->section_headers[0].sh_link;
9c1ce108 5118 if (header->e_shstrndx >= header->e_shnum)
dda8d76d
NC
5119 header->e_shstrndx = SHN_UNDEF;
5120 free (filedata->section_headers);
5121 filedata->section_headers = NULL;
252b5132 5122 }
103f02d3 5123
32ec8896 5124 return TRUE;
9ea033b2
NC
5125}
5126
dda8d76d
NC
5127/* Read in the program headers from FILEDATA and store them in PHEADERS.
5128 Returns TRUE upon success, FALSE otherwise. Loads 32-bit headers. */
5129
e0a31db1 5130static bfd_boolean
dda8d76d 5131get_32bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5132{
2cf0635d
NC
5133 Elf32_External_Phdr * phdrs;
5134 Elf32_External_Phdr * external;
5135 Elf_Internal_Phdr * internal;
b34976b6 5136 unsigned int i;
dda8d76d
NC
5137 unsigned int size = filedata->file_header.e_phentsize;
5138 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5139
5140 /* PR binutils/17531: Cope with unexpected section header sizes. */
5141 if (size == 0 || num == 0)
5142 return FALSE;
5143 if (size < sizeof * phdrs)
5144 {
5145 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5146 return FALSE;
5147 }
5148 if (size > sizeof * phdrs)
5149 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5150
dda8d76d 5151 phdrs = (Elf32_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1
NC
5152 size, num, _("program headers"));
5153 if (phdrs == NULL)
5154 return FALSE;
9ea033b2 5155
91d6fa6a 5156 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5157 i < filedata->file_header.e_phnum;
b34976b6 5158 i++, internal++, external++)
252b5132 5159 {
9ea033b2
NC
5160 internal->p_type = BYTE_GET (external->p_type);
5161 internal->p_offset = BYTE_GET (external->p_offset);
5162 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5163 internal->p_paddr = BYTE_GET (external->p_paddr);
5164 internal->p_filesz = BYTE_GET (external->p_filesz);
5165 internal->p_memsz = BYTE_GET (external->p_memsz);
5166 internal->p_flags = BYTE_GET (external->p_flags);
5167 internal->p_align = BYTE_GET (external->p_align);
252b5132
RH
5168 }
5169
9ea033b2 5170 free (phdrs);
e0a31db1 5171 return TRUE;
252b5132
RH
5172}
5173
dda8d76d
NC
5174/* Read in the program headers from FILEDATA and store them in PHEADERS.
5175 Returns TRUE upon success, FALSE otherwise. Loads 64-bit headers. */
5176
e0a31db1 5177static bfd_boolean
dda8d76d 5178get_64bit_program_headers (Filedata * filedata, Elf_Internal_Phdr * pheaders)
9ea033b2 5179{
2cf0635d
NC
5180 Elf64_External_Phdr * phdrs;
5181 Elf64_External_Phdr * external;
5182 Elf_Internal_Phdr * internal;
b34976b6 5183 unsigned int i;
dda8d76d
NC
5184 unsigned int size = filedata->file_header.e_phentsize;
5185 unsigned int num = filedata->file_header.e_phnum;
e0a31db1
NC
5186
5187 /* PR binutils/17531: Cope with unexpected section header sizes. */
5188 if (size == 0 || num == 0)
5189 return FALSE;
5190 if (size < sizeof * phdrs)
5191 {
5192 error (_("The e_phentsize field in the ELF header is less than the size of an ELF program header\n"));
5193 return FALSE;
5194 }
5195 if (size > sizeof * phdrs)
5196 warn (_("The e_phentsize field in the ELF header is larger than the size of an ELF program header\n"));
103f02d3 5197
dda8d76d 5198 phdrs = (Elf64_External_Phdr *) get_data (NULL, filedata, filedata->file_header.e_phoff,
e0a31db1 5199 size, num, _("program headers"));
a6e9f9df 5200 if (!phdrs)
e0a31db1 5201 return FALSE;
9ea033b2 5202
91d6fa6a 5203 for (i = 0, internal = pheaders, external = phdrs;
dda8d76d 5204 i < filedata->file_header.e_phnum;
b34976b6 5205 i++, internal++, external++)
9ea033b2
NC
5206 {
5207 internal->p_type = BYTE_GET (external->p_type);
5208 internal->p_flags = BYTE_GET (external->p_flags);
66543521
AM
5209 internal->p_offset = BYTE_GET (external->p_offset);
5210 internal->p_vaddr = BYTE_GET (external->p_vaddr);
5211 internal->p_paddr = BYTE_GET (external->p_paddr);
5212 internal->p_filesz = BYTE_GET (external->p_filesz);
5213 internal->p_memsz = BYTE_GET (external->p_memsz);
5214 internal->p_align = BYTE_GET (external->p_align);
9ea033b2
NC
5215 }
5216
5217 free (phdrs);
e0a31db1 5218 return TRUE;
9ea033b2 5219}
252b5132 5220
32ec8896 5221/* Returns TRUE if the program headers were read into `program_headers'. */
d93f0186 5222
32ec8896 5223static bfd_boolean
dda8d76d 5224get_program_headers (Filedata * filedata)
d93f0186 5225{
2cf0635d 5226 Elf_Internal_Phdr * phdrs;
d93f0186
NC
5227
5228 /* Check cache of prior read. */
dda8d76d 5229 if (filedata->program_headers != NULL)
32ec8896 5230 return TRUE;
d93f0186 5231
82156ab7
NC
5232 /* Be kind to memory checkers by looking for
5233 e_phnum values which we know must be invalid. */
dda8d76d 5234 if (filedata->file_header.e_phnum
82156ab7 5235 * (is_32bit_elf ? sizeof (Elf32_External_Phdr) : sizeof (Elf64_External_Phdr))
dda8d76d 5236 >= filedata->file_size)
82156ab7
NC
5237 {
5238 error (_("Too many program headers - %#x - the file is not that big\n"),
dda8d76d 5239 filedata->file_header.e_phnum);
82156ab7
NC
5240 return FALSE;
5241 }
d93f0186 5242
dda8d76d 5243 phdrs = (Elf_Internal_Phdr *) cmalloc (filedata->file_header.e_phnum,
82156ab7 5244 sizeof (Elf_Internal_Phdr));
d93f0186
NC
5245 if (phdrs == NULL)
5246 {
8b73c356 5247 error (_("Out of memory reading %u program headers\n"),
dda8d76d 5248 filedata->file_header.e_phnum);
32ec8896 5249 return FALSE;
d93f0186
NC
5250 }
5251
5252 if (is_32bit_elf
dda8d76d
NC
5253 ? get_32bit_program_headers (filedata, phdrs)
5254 : get_64bit_program_headers (filedata, phdrs))
d93f0186 5255 {
dda8d76d 5256 filedata->program_headers = phdrs;
32ec8896 5257 return TRUE;
d93f0186
NC
5258 }
5259
5260 free (phdrs);
32ec8896 5261 return FALSE;
d93f0186
NC
5262}
5263
32ec8896 5264/* Returns TRUE if the program headers were loaded. */
2f62977e 5265
32ec8896 5266static bfd_boolean
dda8d76d 5267process_program_headers (Filedata * filedata)
252b5132 5268{
2cf0635d 5269 Elf_Internal_Phdr * segment;
b34976b6 5270 unsigned int i;
1a9ccd70 5271 Elf_Internal_Phdr * previous_load = NULL;
252b5132 5272
978c4450
AM
5273 filedata->dynamic_addr = 0;
5274 filedata->dynamic_size = 0;
663f67df 5275
dda8d76d 5276 if (filedata->file_header.e_phnum == 0)
252b5132 5277 {
82f2dbf7 5278 /* PR binutils/12467. */
dda8d76d 5279 if (filedata->file_header.e_phoff != 0)
32ec8896
NC
5280 {
5281 warn (_("possibly corrupt ELF header - it has a non-zero program"
5282 " header offset, but no program headers\n"));
5283 return FALSE;
5284 }
82f2dbf7 5285 else if (do_segments)
252b5132 5286 printf (_("\nThere are no program headers in this file.\n"));
32ec8896 5287 return TRUE;
252b5132
RH
5288 }
5289
5290 if (do_segments && !do_header)
5291 {
dda8d76d
NC
5292 printf (_("\nElf file type is %s\n"), get_file_type (filedata->file_header.e_type));
5293 printf (_("Entry point 0x%s\n"), bfd_vmatoa ("x", filedata->file_header.e_entry));
d3a49aa8
AM
5294 printf (ngettext ("There is %d program header, starting at offset %s\n",
5295 "There are %d program headers, starting at offset %s\n",
dda8d76d
NC
5296 filedata->file_header.e_phnum),
5297 filedata->file_header.e_phnum,
5298 bfd_vmatoa ("u", filedata->file_header.e_phoff));
252b5132
RH
5299 }
5300
dda8d76d 5301 if (! get_program_headers (filedata))
6b4bf3bc 5302 return TRUE;
103f02d3 5303
252b5132
RH
5304 if (do_segments)
5305 {
dda8d76d 5306 if (filedata->file_header.e_phnum > 1)
3a1a2036
NC
5307 printf (_("\nProgram Headers:\n"));
5308 else
5309 printf (_("\nProgram Headers:\n"));
76da6bbe 5310
f7a99963
NC
5311 if (is_32bit_elf)
5312 printf
5313 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
d974e256
JJ
5314 else if (do_wide)
5315 printf
5316 (_(" Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align\n"));
f7a99963
NC
5317 else
5318 {
5319 printf
5320 (_(" Type Offset VirtAddr PhysAddr\n"));
5321 printf
5322 (_(" FileSiz MemSiz Flags Align\n"));
5323 }
252b5132
RH
5324 }
5325
dda8d76d
NC
5326 for (i = 0, segment = filedata->program_headers;
5327 i < filedata->file_header.e_phnum;
b34976b6 5328 i++, segment++)
252b5132
RH
5329 {
5330 if (do_segments)
5331 {
dda8d76d 5332 printf (" %-14.14s ", get_segment_type (filedata, segment->p_type));
f7a99963
NC
5333
5334 if (is_32bit_elf)
5335 {
5336 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5337 printf ("0x%8.8lx ", (unsigned long) segment->p_vaddr);
5338 printf ("0x%8.8lx ", (unsigned long) segment->p_paddr);
5339 printf ("0x%5.5lx ", (unsigned long) segment->p_filesz);
5340 printf ("0x%5.5lx ", (unsigned long) segment->p_memsz);
5341 printf ("%c%c%c ",
5342 (segment->p_flags & PF_R ? 'R' : ' '),
5343 (segment->p_flags & PF_W ? 'W' : ' '),
5344 (segment->p_flags & PF_X ? 'E' : ' '));
5345 printf ("%#lx", (unsigned long) segment->p_align);
5346 }
d974e256
JJ
5347 else if (do_wide)
5348 {
5349 if ((unsigned long) segment->p_offset == segment->p_offset)
5350 printf ("0x%6.6lx ", (unsigned long) segment->p_offset);
5351 else
5352 {
5353 print_vma (segment->p_offset, FULL_HEX);
5354 putchar (' ');
5355 }
5356
5357 print_vma (segment->p_vaddr, FULL_HEX);
5358 putchar (' ');
5359 print_vma (segment->p_paddr, FULL_HEX);
5360 putchar (' ');
5361
5362 if ((unsigned long) segment->p_filesz == segment->p_filesz)
5363 printf ("0x%6.6lx ", (unsigned long) segment->p_filesz);
5364 else
5365 {
5366 print_vma (segment->p_filesz, FULL_HEX);
5367 putchar (' ');
5368 }
5369
5370 if ((unsigned long) segment->p_memsz == segment->p_memsz)
5371 printf ("0x%6.6lx", (unsigned long) segment->p_memsz);
5372 else
5373 {
f48e6c45 5374 print_vma (segment->p_memsz, FULL_HEX);
d974e256
JJ
5375 }
5376
5377 printf (" %c%c%c ",
5378 (segment->p_flags & PF_R ? 'R' : ' '),
5379 (segment->p_flags & PF_W ? 'W' : ' '),
5380 (segment->p_flags & PF_X ? 'E' : ' '));
5381
5382 if ((unsigned long) segment->p_align == segment->p_align)
5383 printf ("%#lx", (unsigned long) segment->p_align);
5384 else
5385 {
5386 print_vma (segment->p_align, PREFIX_HEX);
5387 }
5388 }
f7a99963
NC
5389 else
5390 {
5391 print_vma (segment->p_offset, FULL_HEX);
5392 putchar (' ');
5393 print_vma (segment->p_vaddr, FULL_HEX);
5394 putchar (' ');
5395 print_vma (segment->p_paddr, FULL_HEX);
5396 printf ("\n ");
5397 print_vma (segment->p_filesz, FULL_HEX);
5398 putchar (' ');
5399 print_vma (segment->p_memsz, FULL_HEX);
5400 printf (" %c%c%c ",
5401 (segment->p_flags & PF_R ? 'R' : ' '),
5402 (segment->p_flags & PF_W ? 'W' : ' '),
5403 (segment->p_flags & PF_X ? 'E' : ' '));
1d262527 5404 print_vma (segment->p_align, PREFIX_HEX);
f7a99963 5405 }
252b5132 5406
1a9ccd70
NC
5407 putc ('\n', stdout);
5408 }
f54498b4 5409
252b5132
RH
5410 switch (segment->p_type)
5411 {
1a9ccd70 5412 case PT_LOAD:
502d895c
NC
5413#if 0 /* Do not warn about out of order PT_LOAD segments. Although officially
5414 required by the ELF standard, several programs, including the Linux
5415 kernel, make use of non-ordered segments. */
1a9ccd70
NC
5416 if (previous_load
5417 && previous_load->p_vaddr > segment->p_vaddr)
5418 error (_("LOAD segments must be sorted in order of increasing VirtAddr\n"));
502d895c 5419#endif
1a9ccd70
NC
5420 if (segment->p_memsz < segment->p_filesz)
5421 error (_("the segment's file size is larger than its memory size\n"));
5422 previous_load = segment;
5423 break;
5424
5425 case PT_PHDR:
5426 /* PR 20815 - Verify that the program header is loaded into memory. */
5427 if (i > 0 && previous_load != NULL)
5428 error (_("the PHDR segment must occur before any LOAD segment\n"));
dda8d76d 5429 if (filedata->file_header.e_machine != EM_PARISC)
1a9ccd70
NC
5430 {
5431 unsigned int j;
5432
dda8d76d 5433 for (j = 1; j < filedata->file_header.e_phnum; j++)
c0c121b0
AM
5434 {
5435 Elf_Internal_Phdr *load = filedata->program_headers + j;
5436 if (load->p_type == PT_LOAD
5437 && load->p_offset <= segment->p_offset
5438 && (load->p_offset + load->p_filesz
5439 >= segment->p_offset + segment->p_filesz)
5440 && load->p_vaddr <= segment->p_vaddr
5441 && (load->p_vaddr + load->p_filesz
5442 >= segment->p_vaddr + segment->p_filesz))
5443 break;
5444 }
dda8d76d 5445 if (j == filedata->file_header.e_phnum)
1a9ccd70
NC
5446 error (_("the PHDR segment is not covered by a LOAD segment\n"));
5447 }
5448 break;
5449
252b5132 5450 case PT_DYNAMIC:
978c4450 5451 if (filedata->dynamic_addr)
252b5132
RH
5452 error (_("more than one dynamic segment\n"));
5453
20737c13
AM
5454 /* By default, assume that the .dynamic section is the first
5455 section in the DYNAMIC segment. */
978c4450
AM
5456 filedata->dynamic_addr = segment->p_offset;
5457 filedata->dynamic_size = segment->p_filesz;
20737c13 5458
b2d38a17
NC
5459 /* Try to locate the .dynamic section. If there is
5460 a section header table, we can easily locate it. */
dda8d76d 5461 if (filedata->section_headers != NULL)
b2d38a17 5462 {
2cf0635d 5463 Elf_Internal_Shdr * sec;
b2d38a17 5464
dda8d76d 5465 sec = find_section (filedata, ".dynamic");
89fac5e3 5466 if (sec == NULL || sec->sh_size == 0)
b2d38a17 5467 {
28f997cf
TG
5468 /* A corresponding .dynamic section is expected, but on
5469 IA-64/OpenVMS it is OK for it to be missing. */
dda8d76d 5470 if (!is_ia64_vms (filedata))
28f997cf 5471 error (_("no .dynamic section in the dynamic segment\n"));
b2d38a17
NC
5472 break;
5473 }
5474
42bb2e33 5475 if (sec->sh_type == SHT_NOBITS)
20737c13 5476 {
978c4450 5477 filedata->dynamic_size = 0;
20737c13
AM
5478 break;
5479 }
42bb2e33 5480
978c4450
AM
5481 filedata->dynamic_addr = sec->sh_offset;
5482 filedata->dynamic_size = sec->sh_size;
b2d38a17 5483
8ac10c5b
L
5484 /* The PT_DYNAMIC segment, which is used by the run-time
5485 loader, should exactly match the .dynamic section. */
5486 if (do_checks
5487 && (filedata->dynamic_addr != segment->p_offset
5488 || filedata->dynamic_size != segment->p_filesz))
5489 warn (_("\
5490the .dynamic section is not the same as the dynamic segment\n"));
b2d38a17 5491 }
39e224f6
MW
5492
5493 /* PR binutils/17512: Avoid corrupt dynamic section info in the
5494 segment. Check this after matching against the section headers
5495 so we don't warn on debuginfo file (which have NOBITS .dynamic
5496 sections). */
978c4450
AM
5497 if (filedata->dynamic_addr > filedata->file_size
5498 || (filedata->dynamic_size
5499 > filedata->file_size - filedata->dynamic_addr))
39e224f6
MW
5500 {
5501 error (_("the dynamic segment offset + size exceeds the size of the file\n"));
978c4450 5502 filedata->dynamic_addr = filedata->dynamic_size = 0;
39e224f6 5503 }
252b5132
RH
5504 break;
5505
5506 case PT_INTERP:
978c4450
AM
5507 if (fseek (filedata->handle,
5508 filedata->archive_file_offset + (long) segment->p_offset,
fb52b2f4 5509 SEEK_SET))
252b5132
RH
5510 error (_("Unable to find program interpreter name\n"));
5511 else
5512 {
f8eae8b2 5513 char fmt [32];
9495b2e6 5514 int ret = snprintf (fmt, sizeof (fmt), "%%%ds", PATH_MAX - 1);
f8eae8b2
L
5515
5516 if (ret >= (int) sizeof (fmt) || ret < 0)
591a748a 5517 error (_("Internal error: failed to create format string to display program interpreter\n"));
f8eae8b2 5518
978c4450
AM
5519 filedata->program_interpreter[0] = 0;
5520 if (fscanf (filedata->handle, fmt,
5521 filedata->program_interpreter) <= 0)
7bd7b3ef 5522 error (_("Unable to read program interpreter name\n"));
252b5132
RH
5523
5524 if (do_segments)
f54498b4 5525 printf (_(" [Requesting program interpreter: %s]\n"),
978c4450 5526 filedata->program_interpreter);
252b5132
RH
5527 }
5528 break;
5529 }
252b5132
RH
5530 }
5531
dda8d76d
NC
5532 if (do_segments
5533 && filedata->section_headers != NULL
5534 && filedata->string_table != NULL)
252b5132
RH
5535 {
5536 printf (_("\n Section to Segment mapping:\n"));
5537 printf (_(" Segment Sections...\n"));
5538
dda8d76d 5539 for (i = 0; i < filedata->file_header.e_phnum; i++)
252b5132 5540 {
9ad5cbcf 5541 unsigned int j;
2cf0635d 5542 Elf_Internal_Shdr * section;
252b5132 5543
dda8d76d
NC
5544 segment = filedata->program_headers + i;
5545 section = filedata->section_headers + 1;
252b5132
RH
5546
5547 printf (" %2.2d ", i);
5548
dda8d76d 5549 for (j = 1; j < filedata->file_header.e_shnum; j++, section++)
252b5132 5550 {
f4638467
AM
5551 if (!ELF_TBSS_SPECIAL (section, segment)
5552 && ELF_SECTION_IN_SEGMENT_STRICT (section, segment))
dda8d76d 5553 printf ("%s ", printable_section_name (filedata, section));
252b5132
RH
5554 }
5555
5556 putc ('\n',stdout);
5557 }
5558 }
5559
32ec8896 5560 return TRUE;
252b5132
RH
5561}
5562
5563
d93f0186
NC
5564/* Find the file offset corresponding to VMA by using the program headers. */
5565
5566static long
dda8d76d 5567offset_from_vma (Filedata * filedata, bfd_vma vma, bfd_size_type size)
d93f0186 5568{
2cf0635d 5569 Elf_Internal_Phdr * seg;
d93f0186 5570
dda8d76d 5571 if (! get_program_headers (filedata))
d93f0186
NC
5572 {
5573 warn (_("Cannot interpret virtual addresses without program headers.\n"));
5574 return (long) vma;
5575 }
5576
dda8d76d
NC
5577 for (seg = filedata->program_headers;
5578 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186
NC
5579 ++seg)
5580 {
5581 if (seg->p_type != PT_LOAD)
5582 continue;
5583
5584 if (vma >= (seg->p_vaddr & -seg->p_align)
5585 && vma + size <= seg->p_vaddr + seg->p_filesz)
5586 return vma - seg->p_vaddr + seg->p_offset;
5587 }
5588
5589 warn (_("Virtual address 0x%lx not located in any PT_LOAD segment.\n"),
0af1713e 5590 (unsigned long) vma);
d93f0186
NC
5591 return (long) vma;
5592}
5593
5594
dda8d76d
NC
5595/* Allocate memory and load the sections headers into FILEDATA->filedata->section_headers.
5596 If PROBE is true, this is just a probe and we do not generate any error
5597 messages if the load fails. */
049b0c3a
NC
5598
5599static bfd_boolean
dda8d76d 5600get_32bit_section_headers (Filedata * filedata, bfd_boolean probe)
252b5132 5601{
2cf0635d
NC
5602 Elf32_External_Shdr * shdrs;
5603 Elf_Internal_Shdr * internal;
dda8d76d
NC
5604 unsigned int i;
5605 unsigned int size = filedata->file_header.e_shentsize;
5606 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5607
5608 /* PR binutils/17531: Cope with unexpected section header sizes. */
5609 if (size == 0 || num == 0)
5610 return FALSE;
5611 if (size < sizeof * shdrs)
5612 {
5613 if (! probe)
5614 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5615 return FALSE;
5616 }
5617 if (!probe && size > sizeof * shdrs)
5618 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
252b5132 5619
dda8d76d 5620 shdrs = (Elf32_External_Shdr *) get_data (NULL, filedata, filedata->file_header.e_shoff,
049b0c3a
NC
5621 size, num,
5622 probe ? NULL : _("section headers"));
5623 if (shdrs == NULL)
5624 return FALSE;
252b5132 5625
dda8d76d
NC
5626 free (filedata->section_headers);
5627 filedata->section_headers = (Elf_Internal_Shdr *)
5628 cmalloc (num, sizeof (Elf_Internal_Shdr));
5629 if (filedata->section_headers == NULL)
252b5132 5630 {
049b0c3a 5631 if (!probe)
8b73c356 5632 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5633 free (shdrs);
049b0c3a 5634 return FALSE;
252b5132
RH
5635 }
5636
dda8d76d 5637 for (i = 0, internal = filedata->section_headers;
560f3c1c 5638 i < num;
b34976b6 5639 i++, internal++)
252b5132
RH
5640 {
5641 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5642 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
5643 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5644 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5645 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5646 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5647 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5648 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5649 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
5650 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
315350be
NC
5651 if (!probe && internal->sh_link > num)
5652 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5653 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5654 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
252b5132
RH
5655 }
5656
5657 free (shdrs);
049b0c3a 5658 return TRUE;
252b5132
RH
5659}
5660
dda8d76d
NC
5661/* Like get_32bit_section_headers, except that it fetches 64-bit headers. */
5662
049b0c3a 5663static bfd_boolean
dda8d76d 5664get_64bit_section_headers (Filedata * filedata, bfd_boolean probe)
9ea033b2 5665{
dda8d76d
NC
5666 Elf64_External_Shdr * shdrs;
5667 Elf_Internal_Shdr * internal;
5668 unsigned int i;
5669 unsigned int size = filedata->file_header.e_shentsize;
5670 unsigned int num = probe ? 1 : filedata->file_header.e_shnum;
049b0c3a
NC
5671
5672 /* PR binutils/17531: Cope with unexpected section header sizes. */
5673 if (size == 0 || num == 0)
5674 return FALSE;
dda8d76d 5675
049b0c3a
NC
5676 if (size < sizeof * shdrs)
5677 {
5678 if (! probe)
5679 error (_("The e_shentsize field in the ELF header is less than the size of an ELF section header\n"));
5680 return FALSE;
5681 }
dda8d76d 5682
049b0c3a
NC
5683 if (! probe && size > sizeof * shdrs)
5684 warn (_("The e_shentsize field in the ELF header is larger than the size of an ELF section header\n"));
9ea033b2 5685
dda8d76d
NC
5686 shdrs = (Elf64_External_Shdr *) get_data (NULL, filedata,
5687 filedata->file_header.e_shoff,
049b0c3a
NC
5688 size, num,
5689 probe ? NULL : _("section headers"));
5690 if (shdrs == NULL)
5691 return FALSE;
9ea033b2 5692
dda8d76d
NC
5693 free (filedata->section_headers);
5694 filedata->section_headers = (Elf_Internal_Shdr *)
5695 cmalloc (num, sizeof (Elf_Internal_Shdr));
5696 if (filedata->section_headers == NULL)
9ea033b2 5697 {
049b0c3a 5698 if (! probe)
8b73c356 5699 error (_("Out of memory reading %u section headers\n"), num);
e3d39609 5700 free (shdrs);
049b0c3a 5701 return FALSE;
9ea033b2
NC
5702 }
5703
dda8d76d 5704 for (i = 0, internal = filedata->section_headers;
560f3c1c 5705 i < num;
b34976b6 5706 i++, internal++)
9ea033b2
NC
5707 {
5708 internal->sh_name = BYTE_GET (shdrs[i].sh_name);
5709 internal->sh_type = BYTE_GET (shdrs[i].sh_type);
66543521
AM
5710 internal->sh_flags = BYTE_GET (shdrs[i].sh_flags);
5711 internal->sh_addr = BYTE_GET (shdrs[i].sh_addr);
5712 internal->sh_size = BYTE_GET (shdrs[i].sh_size);
5713 internal->sh_entsize = BYTE_GET (shdrs[i].sh_entsize);
9ea033b2
NC
5714 internal->sh_link = BYTE_GET (shdrs[i].sh_link);
5715 internal->sh_info = BYTE_GET (shdrs[i].sh_info);
5716 internal->sh_offset = BYTE_GET (shdrs[i].sh_offset);
5717 internal->sh_addralign = BYTE_GET (shdrs[i].sh_addralign);
315350be
NC
5718 if (!probe && internal->sh_link > num)
5719 warn (_("Section %u has an out of range sh_link value of %u\n"), i, internal->sh_link);
5720 if (!probe && internal->sh_flags & SHF_INFO_LINK && internal->sh_info > num)
5721 warn (_("Section %u has an out of range sh_info value of %u\n"), i, internal->sh_info);
9ea033b2
NC
5722 }
5723
5724 free (shdrs);
049b0c3a 5725 return TRUE;
9ea033b2
NC
5726}
5727
252b5132 5728static Elf_Internal_Sym *
dda8d76d
NC
5729get_32bit_elf_symbols (Filedata * filedata,
5730 Elf_Internal_Shdr * section,
5731 unsigned long * num_syms_return)
252b5132 5732{
ba5cdace 5733 unsigned long number = 0;
dd24e3da 5734 Elf32_External_Sym * esyms = NULL;
ba5cdace 5735 Elf_External_Sym_Shndx * shndx = NULL;
dd24e3da 5736 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5737 Elf_Internal_Sym * psym;
b34976b6 5738 unsigned int j;
e3d39609 5739 elf_section_list * entry;
252b5132 5740
c9c1d674
EG
5741 if (section->sh_size == 0)
5742 {
5743 if (num_syms_return != NULL)
5744 * num_syms_return = 0;
5745 return NULL;
5746 }
5747
dd24e3da 5748 /* Run some sanity checks first. */
c9c1d674 5749 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5750 {
c9c1d674 5751 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d
NC
5752 printable_section_name (filedata, section),
5753 (unsigned long) section->sh_entsize);
ba5cdace 5754 goto exit_point;
dd24e3da
NC
5755 }
5756
dda8d76d 5757 if (section->sh_size > filedata->file_size)
f54498b4
NC
5758 {
5759 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d
NC
5760 printable_section_name (filedata, section),
5761 (unsigned long) section->sh_size);
f54498b4
NC
5762 goto exit_point;
5763 }
5764
dd24e3da
NC
5765 number = section->sh_size / section->sh_entsize;
5766
5767 if (number * sizeof (Elf32_External_Sym) > section->sh_size + 1)
5768 {
c9c1d674 5769 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5770 (unsigned long) section->sh_size,
dda8d76d 5771 printable_section_name (filedata, section),
8066deb1 5772 (unsigned long) section->sh_entsize);
ba5cdace 5773 goto exit_point;
dd24e3da
NC
5774 }
5775
dda8d76d 5776 esyms = (Elf32_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5777 section->sh_size, _("symbols"));
dd24e3da 5778 if (esyms == NULL)
ba5cdace 5779 goto exit_point;
252b5132 5780
e3d39609 5781 shndx = NULL;
978c4450 5782 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5783 {
5784 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5785 continue;
5786
5787 if (shndx != NULL)
5788 {
5789 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5790 free (shndx);
5791 }
5792
5793 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5794 entry->hdr->sh_offset,
5795 1, entry->hdr->sh_size,
5796 _("symbol table section indices"));
5797 if (shndx == NULL)
5798 goto exit_point;
5799
5800 /* PR17531: file: heap-buffer-overflow */
5801 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5802 {
5803 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5804 printable_section_name (filedata, entry->hdr),
5805 (unsigned long) entry->hdr->sh_size,
5806 (unsigned long) section->sh_size);
5807 goto exit_point;
c9c1d674 5808 }
e3d39609 5809 }
9ad5cbcf 5810
3f5e193b 5811 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
252b5132
RH
5812
5813 if (isyms == NULL)
5814 {
8b73c356
NC
5815 error (_("Out of memory reading %lu symbols\n"),
5816 (unsigned long) number);
dd24e3da 5817 goto exit_point;
252b5132
RH
5818 }
5819
dd24e3da 5820 for (j = 0, psym = isyms; j < number; j++, psym++)
252b5132
RH
5821 {
5822 psym->st_name = BYTE_GET (esyms[j].st_name);
5823 psym->st_value = BYTE_GET (esyms[j].st_value);
5824 psym->st_size = BYTE_GET (esyms[j].st_size);
5825 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
4fbb74a6 5826 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5827 psym->st_shndx
5828 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5829 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5830 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
252b5132
RH
5831 psym->st_info = BYTE_GET (esyms[j].st_info);
5832 psym->st_other = BYTE_GET (esyms[j].st_other);
5833 }
5834
dd24e3da 5835 exit_point:
e3d39609
NC
5836 free (shndx);
5837 free (esyms);
252b5132 5838
ba5cdace
NC
5839 if (num_syms_return != NULL)
5840 * num_syms_return = isyms == NULL ? 0 : number;
5841
252b5132
RH
5842 return isyms;
5843}
5844
9ea033b2 5845static Elf_Internal_Sym *
dda8d76d
NC
5846get_64bit_elf_symbols (Filedata * filedata,
5847 Elf_Internal_Shdr * section,
5848 unsigned long * num_syms_return)
9ea033b2 5849{
ba5cdace
NC
5850 unsigned long number = 0;
5851 Elf64_External_Sym * esyms = NULL;
5852 Elf_External_Sym_Shndx * shndx = NULL;
5853 Elf_Internal_Sym * isyms = NULL;
2cf0635d 5854 Elf_Internal_Sym * psym;
b34976b6 5855 unsigned int j;
e3d39609 5856 elf_section_list * entry;
9ea033b2 5857
c9c1d674
EG
5858 if (section->sh_size == 0)
5859 {
5860 if (num_syms_return != NULL)
5861 * num_syms_return = 0;
5862 return NULL;
5863 }
5864
dd24e3da 5865 /* Run some sanity checks first. */
c9c1d674 5866 if (section->sh_entsize == 0 || section->sh_entsize > section->sh_size)
dd24e3da 5867 {
c9c1d674 5868 error (_("Section %s has an invalid sh_entsize of 0x%lx\n"),
dda8d76d 5869 printable_section_name (filedata, section),
8066deb1 5870 (unsigned long) section->sh_entsize);
ba5cdace 5871 goto exit_point;
dd24e3da
NC
5872 }
5873
dda8d76d 5874 if (section->sh_size > filedata->file_size)
f54498b4
NC
5875 {
5876 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
dda8d76d 5877 printable_section_name (filedata, section),
8066deb1 5878 (unsigned long) section->sh_size);
f54498b4
NC
5879 goto exit_point;
5880 }
5881
dd24e3da
NC
5882 number = section->sh_size / section->sh_entsize;
5883
5884 if (number * sizeof (Elf64_External_Sym) > section->sh_size + 1)
5885 {
c9c1d674 5886 error (_("Size (0x%lx) of section %s is not a multiple of its sh_entsize (0x%lx)\n"),
8066deb1 5887 (unsigned long) section->sh_size,
dda8d76d 5888 printable_section_name (filedata, section),
8066deb1 5889 (unsigned long) section->sh_entsize);
ba5cdace 5890 goto exit_point;
dd24e3da
NC
5891 }
5892
dda8d76d 5893 esyms = (Elf64_External_Sym *) get_data (NULL, filedata, section->sh_offset, 1,
3f5e193b 5894 section->sh_size, _("symbols"));
a6e9f9df 5895 if (!esyms)
ba5cdace 5896 goto exit_point;
9ea033b2 5897
e3d39609 5898 shndx = NULL;
978c4450 5899 for (entry = filedata->symtab_shndx_list; entry != NULL; entry = entry->next)
e3d39609
NC
5900 {
5901 if (entry->hdr->sh_link != (unsigned long) (section - filedata->section_headers))
5902 continue;
5903
5904 if (shndx != NULL)
5905 {
5906 error (_("Multiple symbol table index sections associated with the same symbol section\n"));
5907 free (shndx);
c9c1d674 5908 }
e3d39609
NC
5909
5910 shndx = (Elf_External_Sym_Shndx *) get_data (NULL, filedata,
5911 entry->hdr->sh_offset,
5912 1, entry->hdr->sh_size,
5913 _("symbol table section indices"));
5914 if (shndx == NULL)
5915 goto exit_point;
5916
5917 /* PR17531: file: heap-buffer-overflow */
5918 if (entry->hdr->sh_size / sizeof (Elf_External_Sym_Shndx) < number)
5919 {
5920 error (_("Index section %s has an sh_size of 0x%lx - expected 0x%lx\n"),
5921 printable_section_name (filedata, entry->hdr),
5922 (unsigned long) entry->hdr->sh_size,
5923 (unsigned long) section->sh_size);
5924 goto exit_point;
5925 }
5926 }
9ad5cbcf 5927
3f5e193b 5928 isyms = (Elf_Internal_Sym *) cmalloc (number, sizeof (Elf_Internal_Sym));
9ea033b2
NC
5929
5930 if (isyms == NULL)
5931 {
8b73c356
NC
5932 error (_("Out of memory reading %lu symbols\n"),
5933 (unsigned long) number);
ba5cdace 5934 goto exit_point;
9ea033b2
NC
5935 }
5936
ba5cdace 5937 for (j = 0, psym = isyms; j < number; j++, psym++)
9ea033b2
NC
5938 {
5939 psym->st_name = BYTE_GET (esyms[j].st_name);
5940 psym->st_info = BYTE_GET (esyms[j].st_info);
5941 psym->st_other = BYTE_GET (esyms[j].st_other);
5942 psym->st_shndx = BYTE_GET (esyms[j].st_shndx);
ba5cdace 5943
4fbb74a6 5944 if (psym->st_shndx == (SHN_XINDEX & 0xffff) && shndx != NULL)
9ad5cbcf
AM
5945 psym->st_shndx
5946 = byte_get ((unsigned char *) &shndx[j], sizeof (shndx[j]));
4fbb74a6
AM
5947 else if (psym->st_shndx >= (SHN_LORESERVE & 0xffff))
5948 psym->st_shndx += SHN_LORESERVE - (SHN_LORESERVE & 0xffff);
ba5cdace 5949
66543521
AM
5950 psym->st_value = BYTE_GET (esyms[j].st_value);
5951 psym->st_size = BYTE_GET (esyms[j].st_size);
9ea033b2
NC
5952 }
5953
ba5cdace 5954 exit_point:
e3d39609
NC
5955 free (shndx);
5956 free (esyms);
ba5cdace
NC
5957
5958 if (num_syms_return != NULL)
5959 * num_syms_return = isyms == NULL ? 0 : number;
9ea033b2
NC
5960
5961 return isyms;
5962}
5963
d1133906 5964static const char *
dda8d76d 5965get_elf_section_flags (Filedata * filedata, bfd_vma sh_flags)
d1133906 5966{
5477e8a0 5967 static char buff[1024];
2cf0635d 5968 char * p = buff;
32ec8896
NC
5969 unsigned int field_size = is_32bit_elf ? 8 : 16;
5970 signed int sindex;
5971 unsigned int size = sizeof (buff) - (field_size + 4 + 1);
8d5ff12c
L
5972 bfd_vma os_flags = 0;
5973 bfd_vma proc_flags = 0;
5974 bfd_vma unknown_flags = 0;
148b93f2 5975 static const struct
5477e8a0 5976 {
2cf0635d 5977 const char * str;
32ec8896 5978 unsigned int len;
5477e8a0
L
5979 }
5980 flags [] =
5981 {
cfcac11d
NC
5982 /* 0 */ { STRING_COMMA_LEN ("WRITE") },
5983 /* 1 */ { STRING_COMMA_LEN ("ALLOC") },
5984 /* 2 */ { STRING_COMMA_LEN ("EXEC") },
5985 /* 3 */ { STRING_COMMA_LEN ("MERGE") },
5986 /* 4 */ { STRING_COMMA_LEN ("STRINGS") },
5987 /* 5 */ { STRING_COMMA_LEN ("INFO LINK") },
5988 /* 6 */ { STRING_COMMA_LEN ("LINK ORDER") },
5989 /* 7 */ { STRING_COMMA_LEN ("OS NONCONF") },
5990 /* 8 */ { STRING_COMMA_LEN ("GROUP") },
5991 /* 9 */ { STRING_COMMA_LEN ("TLS") },
5992 /* IA-64 specific. */
5993 /* 10 */ { STRING_COMMA_LEN ("SHORT") },
5994 /* 11 */ { STRING_COMMA_LEN ("NORECOV") },
5995 /* IA-64 OpenVMS specific. */
5996 /* 12 */ { STRING_COMMA_LEN ("VMS_GLOBAL") },
5997 /* 13 */ { STRING_COMMA_LEN ("VMS_OVERLAID") },
5998 /* 14 */ { STRING_COMMA_LEN ("VMS_SHARED") },
5999 /* 15 */ { STRING_COMMA_LEN ("VMS_VECTOR") },
6000 /* 16 */ { STRING_COMMA_LEN ("VMS_ALLOC_64BIT") },
6001 /* 17 */ { STRING_COMMA_LEN ("VMS_PROTECTED") },
18ae9cc1 6002 /* Generic. */
cfcac11d 6003 /* 18 */ { STRING_COMMA_LEN ("EXCLUDE") },
18ae9cc1 6004 /* SPARC specific. */
77115a4a 6005 /* 19 */ { STRING_COMMA_LEN ("ORDERED") },
ac4c9b04
MG
6006 /* 20 */ { STRING_COMMA_LEN ("COMPRESSED") },
6007 /* ARM specific. */
6008 /* 21 */ { STRING_COMMA_LEN ("ENTRYSECT") },
f0728ee3 6009 /* 22 */ { STRING_COMMA_LEN ("ARM_PURECODE") },
a91e1603
L
6010 /* 23 */ { STRING_COMMA_LEN ("COMDEF") },
6011 /* GNU specific. */
6012 /* 24 */ { STRING_COMMA_LEN ("GNU_MBIND") },
83eef883
AFB
6013 /* VLE specific. */
6014 /* 25 */ { STRING_COMMA_LEN ("VLE") },
99fabbc9
JL
6015 /* GNU specific. */
6016 /* 26 */ { STRING_COMMA_LEN ("GNU_RETAIN") },
5477e8a0
L
6017 };
6018
6019 if (do_section_details)
6020 {
8d5ff12c
L
6021 sprintf (buff, "[%*.*lx]: ",
6022 field_size, field_size, (unsigned long) sh_flags);
6023 p += field_size + 4;
5477e8a0 6024 }
76da6bbe 6025
d1133906
NC
6026 while (sh_flags)
6027 {
6028 bfd_vma flag;
6029
6030 flag = sh_flags & - sh_flags;
6031 sh_flags &= ~ flag;
76da6bbe 6032
5477e8a0 6033 if (do_section_details)
d1133906 6034 {
5477e8a0
L
6035 switch (flag)
6036 {
91d6fa6a
NC
6037 case SHF_WRITE: sindex = 0; break;
6038 case SHF_ALLOC: sindex = 1; break;
6039 case SHF_EXECINSTR: sindex = 2; break;
6040 case SHF_MERGE: sindex = 3; break;
6041 case SHF_STRINGS: sindex = 4; break;
6042 case SHF_INFO_LINK: sindex = 5; break;
6043 case SHF_LINK_ORDER: sindex = 6; break;
6044 case SHF_OS_NONCONFORMING: sindex = 7; break;
6045 case SHF_GROUP: sindex = 8; break;
6046 case SHF_TLS: sindex = 9; break;
18ae9cc1 6047 case SHF_EXCLUDE: sindex = 18; break;
77115a4a 6048 case SHF_COMPRESSED: sindex = 20; break;
76da6bbe 6049
5477e8a0 6050 default:
91d6fa6a 6051 sindex = -1;
dda8d76d 6052 switch (filedata->file_header.e_machine)
148b93f2 6053 {
cfcac11d 6054 case EM_IA_64:
148b93f2 6055 if (flag == SHF_IA_64_SHORT)
91d6fa6a 6056 sindex = 10;
148b93f2 6057 else if (flag == SHF_IA_64_NORECOV)
91d6fa6a 6058 sindex = 11;
148b93f2 6059#ifdef BFD64
dda8d76d 6060 else if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_OPENVMS)
148b93f2
NC
6061 switch (flag)
6062 {
91d6fa6a
NC
6063 case SHF_IA_64_VMS_GLOBAL: sindex = 12; break;
6064 case SHF_IA_64_VMS_OVERLAID: sindex = 13; break;
6065 case SHF_IA_64_VMS_SHARED: sindex = 14; break;
6066 case SHF_IA_64_VMS_VECTOR: sindex = 15; break;
6067 case SHF_IA_64_VMS_ALLOC_64BIT: sindex = 16; break;
6068 case SHF_IA_64_VMS_PROTECTED: sindex = 17; break;
148b93f2
NC
6069 default: break;
6070 }
6071#endif
cfcac11d
NC
6072 break;
6073
caa83f8b 6074 case EM_386:
22abe556 6075 case EM_IAMCU:
caa83f8b 6076 case EM_X86_64:
7f502d6c 6077 case EM_L1OM:
7a9068fe 6078 case EM_K1OM:
cfcac11d
NC
6079 case EM_OLD_SPARCV9:
6080 case EM_SPARC32PLUS:
6081 case EM_SPARCV9:
6082 case EM_SPARC:
18ae9cc1 6083 if (flag == SHF_ORDERED)
91d6fa6a 6084 sindex = 19;
cfcac11d 6085 break;
ac4c9b04
MG
6086
6087 case EM_ARM:
6088 switch (flag)
6089 {
6090 case SHF_ENTRYSECT: sindex = 21; break;
f0728ee3 6091 case SHF_ARM_PURECODE: sindex = 22; break;
ac4c9b04
MG
6092 case SHF_COMDEF: sindex = 23; break;
6093 default: break;
6094 }
6095 break;
83eef883
AFB
6096 case EM_PPC:
6097 if (flag == SHF_PPC_VLE)
6098 sindex = 25;
6099 break;
99fabbc9
JL
6100 default:
6101 break;
6102 }
ac4c9b04 6103
99fabbc9
JL
6104 switch (filedata->file_header.e_ident[EI_OSABI])
6105 {
6106 case ELFOSABI_GNU:
6107 case ELFOSABI_FREEBSD:
6108 if (flag == SHF_GNU_RETAIN)
6109 sindex = 26;
6110 /* Fall through */
6111 case ELFOSABI_NONE:
6112 if (flag == SHF_GNU_MBIND)
6113 /* We should not recognize SHF_GNU_MBIND for
6114 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6115 not set the EI_OSABI header byte. */
6116 sindex = 24;
6117 break;
cfcac11d
NC
6118 default:
6119 break;
148b93f2 6120 }
99fabbc9 6121 break;
5477e8a0
L
6122 }
6123
91d6fa6a 6124 if (sindex != -1)
5477e8a0 6125 {
8d5ff12c
L
6126 if (p != buff + field_size + 4)
6127 {
6128 if (size < (10 + 2))
bee0ee85
NC
6129 {
6130 warn (_("Internal error: not enough buffer room for section flag info"));
6131 return _("<unknown>");
6132 }
8d5ff12c
L
6133 size -= 2;
6134 *p++ = ',';
6135 *p++ = ' ';
6136 }
6137
91d6fa6a
NC
6138 size -= flags [sindex].len;
6139 p = stpcpy (p, flags [sindex].str);
5477e8a0 6140 }
3b22753a 6141 else if (flag & SHF_MASKOS)
8d5ff12c 6142 os_flags |= flag;
d1133906 6143 else if (flag & SHF_MASKPROC)
8d5ff12c 6144 proc_flags |= flag;
d1133906 6145 else
8d5ff12c 6146 unknown_flags |= flag;
5477e8a0
L
6147 }
6148 else
6149 {
6150 switch (flag)
6151 {
6152 case SHF_WRITE: *p = 'W'; break;
6153 case SHF_ALLOC: *p = 'A'; break;
6154 case SHF_EXECINSTR: *p = 'X'; break;
6155 case SHF_MERGE: *p = 'M'; break;
6156 case SHF_STRINGS: *p = 'S'; break;
6157 case SHF_INFO_LINK: *p = 'I'; break;
6158 case SHF_LINK_ORDER: *p = 'L'; break;
6159 case SHF_OS_NONCONFORMING: *p = 'O'; break;
6160 case SHF_GROUP: *p = 'G'; break;
6161 case SHF_TLS: *p = 'T'; break;
18ae9cc1 6162 case SHF_EXCLUDE: *p = 'E'; break;
77115a4a 6163 case SHF_COMPRESSED: *p = 'C'; break;
5477e8a0
L
6164
6165 default:
dda8d76d
NC
6166 if ((filedata->file_header.e_machine == EM_X86_64
6167 || filedata->file_header.e_machine == EM_L1OM
6168 || filedata->file_header.e_machine == EM_K1OM)
5477e8a0
L
6169 && flag == SHF_X86_64_LARGE)
6170 *p = 'l';
dda8d76d 6171 else if (filedata->file_header.e_machine == EM_ARM
f0728ee3 6172 && flag == SHF_ARM_PURECODE)
99fabbc9 6173 *p = 'y';
dda8d76d 6174 else if (filedata->file_header.e_machine == EM_PPC
83eef883 6175 && flag == SHF_PPC_VLE)
99fabbc9 6176 *p = 'v';
5477e8a0
L
6177 else if (flag & SHF_MASKOS)
6178 {
99fabbc9
JL
6179 switch (filedata->file_header.e_ident[EI_OSABI])
6180 {
6181 case ELFOSABI_GNU:
6182 case ELFOSABI_FREEBSD:
6183 if (flag == SHF_GNU_RETAIN)
6184 {
6185 *p = 'R';
6186 break;
6187 }
6188 /* Fall through */
6189 case ELFOSABI_NONE:
6190 if (flag == SHF_GNU_MBIND)
6191 {
6192 /* We should not recognize SHF_GNU_MBIND for
6193 ELFOSABI_NONE, but binutils as of 2019-07-23 did
6194 not set the EI_OSABI header byte. */
6195 *p = 'D';
6196 break;
6197 }
6198 /* Fall through */
6199 default:
6200 *p = 'o';
6201 sh_flags &= ~SHF_MASKOS;
6202 break;
6203 }
5477e8a0
L
6204 }
6205 else if (flag & SHF_MASKPROC)
6206 {
6207 *p = 'p';
6208 sh_flags &= ~ SHF_MASKPROC;
6209 }
6210 else
6211 *p = 'x';
6212 break;
6213 }
6214 p++;
d1133906
NC
6215 }
6216 }
76da6bbe 6217
8d5ff12c
L
6218 if (do_section_details)
6219 {
6220 if (os_flags)
6221 {
6222 size -= 5 + field_size;
6223 if (p != buff + field_size + 4)
6224 {
6225 if (size < (2 + 1))
bee0ee85
NC
6226 {
6227 warn (_("Internal error: not enough buffer room for section flag info"));
6228 return _("<unknown>");
6229 }
8d5ff12c
L
6230 size -= 2;
6231 *p++ = ',';
6232 *p++ = ' ';
6233 }
6234 sprintf (p, "OS (%*.*lx)", field_size, field_size,
6235 (unsigned long) os_flags);
6236 p += 5 + field_size;
6237 }
6238 if (proc_flags)
6239 {
6240 size -= 7 + field_size;
6241 if (p != buff + field_size + 4)
6242 {
6243 if (size < (2 + 1))
bee0ee85
NC
6244 {
6245 warn (_("Internal error: not enough buffer room for section flag info"));
6246 return _("<unknown>");
6247 }
8d5ff12c
L
6248 size -= 2;
6249 *p++ = ',';
6250 *p++ = ' ';
6251 }
6252 sprintf (p, "PROC (%*.*lx)", field_size, field_size,
6253 (unsigned long) proc_flags);
6254 p += 7 + field_size;
6255 }
6256 if (unknown_flags)
6257 {
6258 size -= 10 + field_size;
6259 if (p != buff + field_size + 4)
6260 {
6261 if (size < (2 + 1))
bee0ee85
NC
6262 {
6263 warn (_("Internal error: not enough buffer room for section flag info"));
6264 return _("<unknown>");
6265 }
8d5ff12c
L
6266 size -= 2;
6267 *p++ = ',';
6268 *p++ = ' ';
6269 }
2b692964 6270 sprintf (p, _("UNKNOWN (%*.*lx)"), field_size, field_size,
8d5ff12c
L
6271 (unsigned long) unknown_flags);
6272 p += 10 + field_size;
6273 }
6274 }
6275
e9e44622 6276 *p = '\0';
d1133906
NC
6277 return buff;
6278}
6279
5844b465 6280static unsigned int ATTRIBUTE_WARN_UNUSED_RESULT
ebdf1ebf 6281get_compression_header (Elf_Internal_Chdr *chdr, unsigned char *buf, bfd_size_type size)
77115a4a
L
6282{
6283 if (is_32bit_elf)
6284 {
6285 Elf32_External_Chdr *echdr = (Elf32_External_Chdr *) buf;
d8024a91 6286
ebdf1ebf
NC
6287 if (size < sizeof (* echdr))
6288 {
6289 error (_("Compressed section is too small even for a compression header\n"));
6290 return 0;
6291 }
6292
77115a4a
L
6293 chdr->ch_type = BYTE_GET (echdr->ch_type);
6294 chdr->ch_size = BYTE_GET (echdr->ch_size);
6295 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6296 return sizeof (*echdr);
6297 }
6298 else
6299 {
6300 Elf64_External_Chdr *echdr = (Elf64_External_Chdr *) buf;
d8024a91 6301
ebdf1ebf
NC
6302 if (size < sizeof (* echdr))
6303 {
6304 error (_("Compressed section is too small even for a compression header\n"));
6305 return 0;
6306 }
6307
77115a4a
L
6308 chdr->ch_type = BYTE_GET (echdr->ch_type);
6309 chdr->ch_size = BYTE_GET (echdr->ch_size);
6310 chdr->ch_addralign = BYTE_GET (echdr->ch_addralign);
6311 return sizeof (*echdr);
6312 }
6313}
6314
32ec8896 6315static bfd_boolean
dda8d76d 6316process_section_headers (Filedata * filedata)
252b5132 6317{
2cf0635d 6318 Elf_Internal_Shdr * section;
b34976b6 6319 unsigned int i;
252b5132 6320
8fb879cd 6321 free (filedata->section_headers);
dda8d76d 6322 filedata->section_headers = NULL;
978c4450
AM
6323 free (filedata->dynamic_symbols);
6324 filedata->dynamic_symbols = NULL;
6325 filedata->num_dynamic_syms = 0;
6326 free (filedata->dynamic_strings);
6327 filedata->dynamic_strings = NULL;
6328 filedata->dynamic_strings_length = 0;
6329 free (filedata->dynamic_syminfo);
6330 filedata->dynamic_syminfo = NULL;
6331 while (filedata->symtab_shndx_list != NULL)
8ff66993 6332 {
978c4450
AM
6333 elf_section_list *next = filedata->symtab_shndx_list->next;
6334 free (filedata->symtab_shndx_list);
6335 filedata->symtab_shndx_list = next;
8ff66993 6336 }
252b5132 6337
dda8d76d 6338 if (filedata->file_header.e_shnum == 0)
252b5132 6339 {
82f2dbf7 6340 /* PR binutils/12467. */
dda8d76d 6341 if (filedata->file_header.e_shoff != 0)
32ec8896
NC
6342 {
6343 warn (_("possibly corrupt ELF file header - it has a non-zero"
6344 " section header offset, but no section headers\n"));
6345 return FALSE;
6346 }
82f2dbf7 6347 else if (do_sections)
252b5132
RH
6348 printf (_("\nThere are no sections in this file.\n"));
6349
32ec8896 6350 return TRUE;
252b5132
RH
6351 }
6352
6353 if (do_sections && !do_header)
d3a49aa8
AM
6354 printf (ngettext ("There is %d section header, "
6355 "starting at offset 0x%lx:\n",
6356 "There are %d section headers, "
6357 "starting at offset 0x%lx:\n",
dda8d76d
NC
6358 filedata->file_header.e_shnum),
6359 filedata->file_header.e_shnum,
6360 (unsigned long) filedata->file_header.e_shoff);
252b5132 6361
9ea033b2
NC
6362 if (is_32bit_elf)
6363 {
dda8d76d 6364 if (! get_32bit_section_headers (filedata, FALSE))
32ec8896
NC
6365 return FALSE;
6366 }
6367 else
6368 {
dda8d76d 6369 if (! get_64bit_section_headers (filedata, FALSE))
32ec8896 6370 return FALSE;
9ea033b2 6371 }
252b5132
RH
6372
6373 /* Read in the string table, so that we have names to display. */
dda8d76d
NC
6374 if (filedata->file_header.e_shstrndx != SHN_UNDEF
6375 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
252b5132 6376 {
dda8d76d 6377 section = filedata->section_headers + filedata->file_header.e_shstrndx;
d40ac9bd 6378
c256ffe7
JJ
6379 if (section->sh_size != 0)
6380 {
dda8d76d
NC
6381 filedata->string_table = (char *) get_data (NULL, filedata, section->sh_offset,
6382 1, section->sh_size,
6383 _("string table"));
0de14b54 6384
dda8d76d 6385 filedata->string_table_length = filedata->string_table != NULL ? section->sh_size : 0;
c256ffe7 6386 }
252b5132
RH
6387 }
6388
6389 /* Scan the sections for the dynamic symbol table
e3c8793a 6390 and dynamic string table and debug sections. */
89fac5e3 6391 eh_addr_size = is_32bit_elf ? 4 : 8;
dda8d76d 6392 switch (filedata->file_header.e_machine)
89fac5e3
RS
6393 {
6394 case EM_MIPS:
6395 case EM_MIPS_RS3_LE:
6396 /* The 64-bit MIPS EABI uses a combination of 32-bit ELF and 64-bit
6397 FDE addresses. However, the ABI also has a semi-official ILP32
6398 variant for which the normal FDE address size rules apply.
6399
6400 GCC 4.0 marks EABI64 objects with a dummy .gcc_compiled_longXX
6401 section, where XX is the size of longs in bits. Unfortunately,
6402 earlier compilers provided no way of distinguishing ILP32 objects
6403 from LP64 objects, so if there's any doubt, we should assume that
6404 the official LP64 form is being used. */
dda8d76d
NC
6405 if ((filedata->file_header.e_flags & EF_MIPS_ABI) == E_MIPS_ABI_EABI64
6406 && find_section (filedata, ".gcc_compiled_long32") == NULL)
89fac5e3
RS
6407 eh_addr_size = 8;
6408 break;
0f56a26a
DD
6409
6410 case EM_H8_300:
6411 case EM_H8_300H:
dda8d76d 6412 switch (filedata->file_header.e_flags & EF_H8_MACH)
0f56a26a
DD
6413 {
6414 case E_H8_MACH_H8300:
6415 case E_H8_MACH_H8300HN:
6416 case E_H8_MACH_H8300SN:
6417 case E_H8_MACH_H8300SXN:
6418 eh_addr_size = 2;
6419 break;
6420 case E_H8_MACH_H8300H:
6421 case E_H8_MACH_H8300S:
6422 case E_H8_MACH_H8300SX:
6423 eh_addr_size = 4;
6424 break;
6425 }
f4236fe4
DD
6426 break;
6427
ff7eeb89 6428 case EM_M32C_OLD:
f4236fe4 6429 case EM_M32C:
dda8d76d 6430 switch (filedata->file_header.e_flags & EF_M32C_CPU_MASK)
f4236fe4
DD
6431 {
6432 case EF_M32C_CPU_M16C:
6433 eh_addr_size = 2;
6434 break;
6435 }
6436 break;
89fac5e3
RS
6437 }
6438
76ca31c0
NC
6439#define CHECK_ENTSIZE_VALUES(section, i, size32, size64) \
6440 do \
6441 { \
6442 bfd_size_type expected_entsize = is_32bit_elf ? size32 : size64; \
6443 if (section->sh_entsize != expected_entsize) \
9dd3a467 6444 { \
76ca31c0
NC
6445 char buf[40]; \
6446 sprintf_vma (buf, section->sh_entsize); \
6447 /* Note: coded this way so that there is a single string for \
6448 translation. */ \
6449 error (_("Section %d has invalid sh_entsize of %s\n"), i, buf); \
6450 error (_("(Using the expected size of %u for the rest of this dump)\n"), \
6451 (unsigned) expected_entsize); \
9dd3a467 6452 section->sh_entsize = expected_entsize; \
76ca31c0
NC
6453 } \
6454 } \
08d8fa11 6455 while (0)
9dd3a467
NC
6456
6457#define CHECK_ENTSIZE(section, i, type) \
1b513401 6458 CHECK_ENTSIZE_VALUES (section, i, sizeof (Elf32_External_##type), \
08d8fa11
JJ
6459 sizeof (Elf64_External_##type))
6460
dda8d76d
NC
6461 for (i = 0, section = filedata->section_headers;
6462 i < filedata->file_header.e_shnum;
b34976b6 6463 i++, section++)
252b5132 6464 {
b9e920ec 6465 char * name = SECTION_NAME_PRINT (section);
252b5132 6466
1b513401
NC
6467 /* Run some sanity checks on the headers and
6468 possibly fill in some file data as well. */
6469 switch (section->sh_type)
252b5132 6470 {
1b513401 6471 case SHT_DYNSYM:
978c4450 6472 if (filedata->dynamic_symbols != NULL)
252b5132
RH
6473 {
6474 error (_("File contains multiple dynamic symbol tables\n"));
6475 continue;
6476 }
6477
08d8fa11 6478 CHECK_ENTSIZE (section, i, Sym);
978c4450
AM
6479 filedata->dynamic_symbols
6480 = GET_ELF_SYMBOLS (filedata, section, &filedata->num_dynamic_syms);
8ac10c5b 6481 filedata->dynamic_symtab_section = section;
1b513401
NC
6482 break;
6483
6484 case SHT_STRTAB:
6485 if (streq (name, ".dynstr"))
252b5132 6486 {
1b513401
NC
6487 if (filedata->dynamic_strings != NULL)
6488 {
6489 error (_("File contains multiple dynamic string tables\n"));
6490 continue;
6491 }
6492
6493 filedata->dynamic_strings
6494 = (char *) get_data (NULL, filedata, section->sh_offset,
6495 1, section->sh_size, _("dynamic strings"));
6496 filedata->dynamic_strings_length
6497 = filedata->dynamic_strings == NULL ? 0 : section->sh_size;
8ac10c5b 6498 filedata->dynamic_strtab_section = section;
252b5132 6499 }
1b513401
NC
6500 break;
6501
6502 case SHT_SYMTAB_SHNDX:
6503 {
6504 elf_section_list * entry = xmalloc (sizeof * entry);
6505
6506 entry->hdr = section;
6507 entry->next = filedata->symtab_shndx_list;
6508 filedata->symtab_shndx_list = entry;
6509 }
6510 break;
6511
6512 case SHT_SYMTAB:
6513 CHECK_ENTSIZE (section, i, Sym);
6514 break;
6515
6516 case SHT_GROUP:
6517 CHECK_ENTSIZE_VALUES (section, i, GRP_ENTRY_SIZE, GRP_ENTRY_SIZE);
6518 break;
252b5132 6519
1b513401
NC
6520 case SHT_REL:
6521 CHECK_ENTSIZE (section, i, Rel);
546cb2d8 6522 if (do_checks && section->sh_size == 0)
1b513401
NC
6523 warn (_("Section '%s': zero-sized relocation section\n"), name);
6524 break;
6525
6526 case SHT_RELA:
6527 CHECK_ENTSIZE (section, i, Rela);
546cb2d8 6528 if (do_checks && section->sh_size == 0)
1b513401
NC
6529 warn (_("Section '%s': zero-sized relocation section\n"), name);
6530 break;
6531
6532 case SHT_NOTE:
6533 case SHT_PROGBITS:
546cb2d8
NC
6534 /* Having a zero sized section is not illegal according to the
6535 ELF standard, but it might be an indication that something
6536 is wrong. So issue a warning if we are running in lint mode. */
6537 if (do_checks && section->sh_size == 0)
1b513401
NC
6538 warn (_("Section '%s': has a size of zero - is this intended ?\n"), name);
6539 break;
6540
6541 default:
6542 break;
6543 }
6544
6545 if ((do_debugging || do_debug_info || do_debug_abbrevs
6546 || do_debug_lines || do_debug_pubnames || do_debug_pubtypes
6547 || do_debug_aranges || do_debug_frames || do_debug_macinfo
e4b7104b 6548 || do_debug_str || do_debug_str_offsets || do_debug_loc || do_debug_ranges
1b513401
NC
6549 || do_debug_addr || do_debug_cu_index || do_debug_links)
6550 && (const_strneq (name, ".debug_")
6551 || const_strneq (name, ".zdebug_")))
252b5132 6552 {
1b315056
CS
6553 if (name[1] == 'z')
6554 name += sizeof (".zdebug_") - 1;
6555 else
6556 name += sizeof (".debug_") - 1;
252b5132
RH
6557
6558 if (do_debugging
4723351a
CC
6559 || (do_debug_info && const_strneq (name, "info"))
6560 || (do_debug_info && const_strneq (name, "types"))
6561 || (do_debug_abbrevs && const_strneq (name, "abbrev"))
b40bf0a2
NC
6562 || (do_debug_lines && strcmp (name, "line") == 0)
6563 || (do_debug_lines && const_strneq (name, "line."))
4723351a
CC
6564 || (do_debug_pubnames && const_strneq (name, "pubnames"))
6565 || (do_debug_pubtypes && const_strneq (name, "pubtypes"))
459d52c8
DE
6566 || (do_debug_pubnames && const_strneq (name, "gnu_pubnames"))
6567 || (do_debug_pubtypes && const_strneq (name, "gnu_pubtypes"))
4723351a
CC
6568 || (do_debug_aranges && const_strneq (name, "aranges"))
6569 || (do_debug_ranges && const_strneq (name, "ranges"))
77145576 6570 || (do_debug_ranges && const_strneq (name, "rnglists"))
4723351a
CC
6571 || (do_debug_frames && const_strneq (name, "frame"))
6572 || (do_debug_macinfo && const_strneq (name, "macinfo"))
6573 || (do_debug_macinfo && const_strneq (name, "macro"))
6574 || (do_debug_str && const_strneq (name, "str"))
e4b7104b 6575 || (do_debug_str_offsets && const_strneq (name, "str_offsets"))
4723351a 6576 || (do_debug_loc && const_strneq (name, "loc"))
77145576 6577 || (do_debug_loc && const_strneq (name, "loclists"))
657d0d47
CC
6578 || (do_debug_addr && const_strneq (name, "addr"))
6579 || (do_debug_cu_index && const_strneq (name, "cu_index"))
6580 || (do_debug_cu_index && const_strneq (name, "tu_index"))
252b5132 6581 )
6431e409 6582 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132 6583 }
a262ae96 6584 /* Linkonce section to be combined with .debug_info at link time. */
09fd7e38 6585 else if ((do_debugging || do_debug_info)
0112cd26 6586 && const_strneq (name, ".gnu.linkonce.wi."))
6431e409 6587 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
18bd398b 6588 else if (do_debug_frames && streq (name, ".eh_frame"))
6431e409 6589 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
61364358
JK
6590 else if (do_gdb_index && (streq (name, ".gdb_index")
6591 || streq (name, ".debug_names")))
6431e409 6592 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884
TG
6593 /* Trace sections for Itanium VMS. */
6594 else if ((do_debugging || do_trace_info || do_trace_abbrevs
6595 || do_trace_aranges)
6596 && const_strneq (name, ".trace_"))
6597 {
6598 name += sizeof (".trace_") - 1;
6599
6600 if (do_debugging
6601 || (do_trace_info && streq (name, "info"))
6602 || (do_trace_abbrevs && streq (name, "abbrev"))
6603 || (do_trace_aranges && streq (name, "aranges"))
6604 )
6431e409 6605 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
6f875884 6606 }
dda8d76d
NC
6607 else if ((do_debugging || do_debug_links)
6608 && (const_strneq (name, ".gnu_debuglink")
6609 || const_strneq (name, ".gnu_debugaltlink")))
6431e409 6610 request_dump_bynumber (&filedata->dump, i, DEBUG_DUMP);
252b5132
RH
6611 }
6612
6613 if (! do_sections)
32ec8896 6614 return TRUE;
252b5132 6615
dda8d76d 6616 if (filedata->file_header.e_shnum > 1)
3a1a2036
NC
6617 printf (_("\nSection Headers:\n"));
6618 else
6619 printf (_("\nSection Header:\n"));
76da6bbe 6620
f7a99963 6621 if (is_32bit_elf)
595cf52e 6622 {
5477e8a0 6623 if (do_section_details)
595cf52e
L
6624 {
6625 printf (_(" [Nr] Name\n"));
5477e8a0 6626 printf (_(" Type Addr Off Size ES Lk Inf Al\n"));
595cf52e
L
6627 }
6628 else
6629 printf
6630 (_(" [Nr] Name Type Addr Off Size ES Flg Lk Inf Al\n"));
6631 }
d974e256 6632 else if (do_wide)
595cf52e 6633 {
5477e8a0 6634 if (do_section_details)
595cf52e
L
6635 {
6636 printf (_(" [Nr] Name\n"));
5477e8a0 6637 printf (_(" Type Address Off Size ES Lk Inf Al\n"));
595cf52e
L
6638 }
6639 else
6640 printf
6641 (_(" [Nr] Name Type Address Off Size ES Flg Lk Inf Al\n"));
6642 }
f7a99963
NC
6643 else
6644 {
5477e8a0 6645 if (do_section_details)
595cf52e
L
6646 {
6647 printf (_(" [Nr] Name\n"));
5477e8a0
L
6648 printf (_(" Type Address Offset Link\n"));
6649 printf (_(" Size EntSize Info Align\n"));
595cf52e
L
6650 }
6651 else
6652 {
6653 printf (_(" [Nr] Name Type Address Offset\n"));
6654 printf (_(" Size EntSize Flags Link Info Align\n"));
6655 }
f7a99963 6656 }
252b5132 6657
5477e8a0
L
6658 if (do_section_details)
6659 printf (_(" Flags\n"));
6660
dda8d76d
NC
6661 for (i = 0, section = filedata->section_headers;
6662 i < filedata->file_header.e_shnum;
b34976b6 6663 i++, section++)
252b5132 6664 {
dd905818
NC
6665 /* Run some sanity checks on the section header. */
6666
6667 /* Check the sh_link field. */
6668 switch (section->sh_type)
6669 {
285e3f99
AM
6670 case SHT_REL:
6671 case SHT_RELA:
6672 if (section->sh_link == 0
6673 && (filedata->file_header.e_type == ET_EXEC
6674 || filedata->file_header.e_type == ET_DYN))
6675 /* A dynamic relocation section where all entries use a
6676 zero symbol index need not specify a symtab section. */
6677 break;
6678 /* Fall through. */
dd905818
NC
6679 case SHT_SYMTAB_SHNDX:
6680 case SHT_GROUP:
6681 case SHT_HASH:
6682 case SHT_GNU_HASH:
6683 case SHT_GNU_versym:
285e3f99 6684 if (section->sh_link == 0
dda8d76d
NC
6685 || section->sh_link >= filedata->file_header.e_shnum
6686 || (filedata->section_headers[section->sh_link].sh_type != SHT_SYMTAB
6687 && filedata->section_headers[section->sh_link].sh_type != SHT_DYNSYM))
dd905818
NC
6688 warn (_("[%2u]: Link field (%u) should index a symtab section.\n"),
6689 i, section->sh_link);
6690 break;
6691
6692 case SHT_DYNAMIC:
6693 case SHT_SYMTAB:
6694 case SHT_DYNSYM:
6695 case SHT_GNU_verneed:
6696 case SHT_GNU_verdef:
6697 case SHT_GNU_LIBLIST:
285e3f99 6698 if (section->sh_link == 0
dda8d76d
NC
6699 || section->sh_link >= filedata->file_header.e_shnum
6700 || filedata->section_headers[section->sh_link].sh_type != SHT_STRTAB)
dd905818
NC
6701 warn (_("[%2u]: Link field (%u) should index a string section.\n"),
6702 i, section->sh_link);
6703 break;
6704
6705 case SHT_INIT_ARRAY:
6706 case SHT_FINI_ARRAY:
6707 case SHT_PREINIT_ARRAY:
6708 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6709 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6710 i, section->sh_link);
6711 break;
6712
6713 default:
6714 /* FIXME: Add support for target specific section types. */
6715#if 0 /* Currently we do not check other section types as there are too
6716 many special cases. Stab sections for example have a type
6717 of SHT_PROGBITS but an sh_link field that links to the .stabstr
6718 section. */
6719 if (section->sh_type < SHT_LOOS && section->sh_link != 0)
6720 warn (_("[%2u]: Unexpected value (%u) in link field.\n"),
6721 i, section->sh_link);
6722#endif
6723 break;
6724 }
6725
6726 /* Check the sh_info field. */
6727 switch (section->sh_type)
6728 {
6729 case SHT_REL:
6730 case SHT_RELA:
285e3f99
AM
6731 if (section->sh_info == 0
6732 && (filedata->file_header.e_type == ET_EXEC
6733 || filedata->file_header.e_type == ET_DYN))
6734 /* Dynamic relocations apply to segments, so they do not
6735 need to specify the section they relocate. */
6736 break;
6737 if (section->sh_info == 0
dda8d76d
NC
6738 || section->sh_info >= filedata->file_header.e_shnum
6739 || (filedata->section_headers[section->sh_info].sh_type != SHT_PROGBITS
6740 && filedata->section_headers[section->sh_info].sh_type != SHT_NOBITS
6741 && filedata->section_headers[section->sh_info].sh_type != SHT_NOTE
6742 && filedata->section_headers[section->sh_info].sh_type != SHT_INIT_ARRAY
385e5b90
L
6743 && filedata->section_headers[section->sh_info].sh_type != SHT_FINI_ARRAY
6744 && filedata->section_headers[section->sh_info].sh_type != SHT_PREINIT_ARRAY
dd905818 6745 /* FIXME: Are other section types valid ? */
dda8d76d 6746 && filedata->section_headers[section->sh_info].sh_type < SHT_LOOS))
285e3f99
AM
6747 warn (_("[%2u]: Info field (%u) should index a relocatable section.\n"),
6748 i, section->sh_info);
dd905818
NC
6749 break;
6750
6751 case SHT_DYNAMIC:
6752 case SHT_HASH:
6753 case SHT_SYMTAB_SHNDX:
6754 case SHT_INIT_ARRAY:
6755 case SHT_FINI_ARRAY:
6756 case SHT_PREINIT_ARRAY:
6757 if (section->sh_info != 0)
6758 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6759 i, section->sh_info);
6760 break;
6761
6762 case SHT_GROUP:
6763 case SHT_SYMTAB:
6764 case SHT_DYNSYM:
6765 /* A symbol index - we assume that it is valid. */
6766 break;
6767
6768 default:
6769 /* FIXME: Add support for target specific section types. */
6770 if (section->sh_type == SHT_NOBITS)
6771 /* NOBITS section headers with non-zero sh_info fields can be
6772 created when a binary is stripped of everything but its debug
1a9ccd70
NC
6773 information. The stripped sections have their headers
6774 preserved but their types set to SHT_NOBITS. So do not check
6775 this type of section. */
dd905818
NC
6776 ;
6777 else if (section->sh_flags & SHF_INFO_LINK)
6778 {
dda8d76d 6779 if (section->sh_info < 1 || section->sh_info >= filedata->file_header.e_shnum)
dd905818
NC
6780 warn (_("[%2u]: Expected link to another section in info field"), i);
6781 }
a91e1603
L
6782 else if (section->sh_type < SHT_LOOS
6783 && (section->sh_flags & SHF_GNU_MBIND) == 0
6784 && section->sh_info != 0)
dd905818
NC
6785 warn (_("[%2u]: Unexpected value (%u) in info field.\n"),
6786 i, section->sh_info);
6787 break;
6788 }
6789
3e6b6445 6790 /* Check the sh_size field. */
dda8d76d 6791 if (section->sh_size > filedata->file_size
3e6b6445
NC
6792 && section->sh_type != SHT_NOBITS
6793 && section->sh_type != SHT_NULL
6794 && section->sh_type < SHT_LOOS)
6795 warn (_("Size of section %u is larger than the entire file!\n"), i);
6796
7bfd842d 6797 printf (" [%2u] ", i);
5477e8a0 6798 if (do_section_details)
dda8d76d 6799 printf ("%s\n ", printable_section_name (filedata, section));
595cf52e 6800 else
b9e920ec 6801 print_symbol (-17, SECTION_NAME_PRINT (section));
0b4362b0 6802
ea52a088 6803 printf (do_wide ? " %-15s " : " %-15.15s ",
dda8d76d 6804 get_section_type_name (filedata, section->sh_type));
0b4362b0 6805
f7a99963
NC
6806 if (is_32bit_elf)
6807 {
cfcac11d
NC
6808 const char * link_too_big = NULL;
6809
f7a99963 6810 print_vma (section->sh_addr, LONG_HEX);
76da6bbe 6811
f7a99963
NC
6812 printf ( " %6.6lx %6.6lx %2.2lx",
6813 (unsigned long) section->sh_offset,
6814 (unsigned long) section->sh_size,
6815 (unsigned long) section->sh_entsize);
d1133906 6816
5477e8a0
L
6817 if (do_section_details)
6818 fputs (" ", stdout);
6819 else
dda8d76d 6820 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6821
dda8d76d 6822 if (section->sh_link >= filedata->file_header.e_shnum)
cfcac11d
NC
6823 {
6824 link_too_big = "";
6825 /* The sh_link value is out of range. Normally this indicates
caa83f8b 6826 an error but it can have special values in Solaris binaries. */
dda8d76d 6827 switch (filedata->file_header.e_machine)
cfcac11d 6828 {
caa83f8b 6829 case EM_386:
22abe556 6830 case EM_IAMCU:
caa83f8b 6831 case EM_X86_64:
7f502d6c 6832 case EM_L1OM:
7a9068fe 6833 case EM_K1OM:
cfcac11d
NC
6834 case EM_OLD_SPARCV9:
6835 case EM_SPARC32PLUS:
6836 case EM_SPARCV9:
6837 case EM_SPARC:
6838 if (section->sh_link == (SHN_BEFORE & 0xffff))
6839 link_too_big = "BEFORE";
6840 else if (section->sh_link == (SHN_AFTER & 0xffff))
6841 link_too_big = "AFTER";
6842 break;
6843 default:
6844 break;
6845 }
6846 }
6847
6848 if (do_section_details)
6849 {
6850 if (link_too_big != NULL && * link_too_big)
6851 printf ("<%s> ", link_too_big);
6852 else
6853 printf ("%2u ", section->sh_link);
6854 printf ("%3u %2lu\n", section->sh_info,
6855 (unsigned long) section->sh_addralign);
6856 }
6857 else
6858 printf ("%2u %3u %2lu\n",
6859 section->sh_link,
6860 section->sh_info,
6861 (unsigned long) section->sh_addralign);
6862
6863 if (link_too_big && ! * link_too_big)
6864 warn (_("section %u: sh_link value of %u is larger than the number of sections\n"),
6865 i, section->sh_link);
f7a99963 6866 }
d974e256
JJ
6867 else if (do_wide)
6868 {
6869 print_vma (section->sh_addr, LONG_HEX);
6870
6871 if ((long) section->sh_offset == section->sh_offset)
6872 printf (" %6.6lx", (unsigned long) section->sh_offset);
6873 else
6874 {
6875 putchar (' ');
6876 print_vma (section->sh_offset, LONG_HEX);
6877 }
6878
6879 if ((unsigned long) section->sh_size == section->sh_size)
6880 printf (" %6.6lx", (unsigned long) section->sh_size);
6881 else
6882 {
6883 putchar (' ');
6884 print_vma (section->sh_size, LONG_HEX);
6885 }
6886
6887 if ((unsigned long) section->sh_entsize == section->sh_entsize)
6888 printf (" %2.2lx", (unsigned long) section->sh_entsize);
6889 else
6890 {
6891 putchar (' ');
6892 print_vma (section->sh_entsize, LONG_HEX);
6893 }
6894
5477e8a0
L
6895 if (do_section_details)
6896 fputs (" ", stdout);
6897 else
dda8d76d 6898 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
d974e256 6899
72de5009 6900 printf ("%2u %3u ", section->sh_link, section->sh_info);
d974e256
JJ
6901
6902 if ((unsigned long) section->sh_addralign == section->sh_addralign)
72de5009 6903 printf ("%2lu\n", (unsigned long) section->sh_addralign);
d974e256
JJ
6904 else
6905 {
6906 print_vma (section->sh_addralign, DEC);
6907 putchar ('\n');
6908 }
6909 }
5477e8a0 6910 else if (do_section_details)
595cf52e 6911 {
55cc53e9 6912 putchar (' ');
595cf52e
L
6913 print_vma (section->sh_addr, LONG_HEX);
6914 if ((long) section->sh_offset == section->sh_offset)
5477e8a0 6915 printf (" %16.16lx", (unsigned long) section->sh_offset);
595cf52e
L
6916 else
6917 {
6918 printf (" ");
6919 print_vma (section->sh_offset, LONG_HEX);
6920 }
72de5009 6921 printf (" %u\n ", section->sh_link);
595cf52e 6922 print_vma (section->sh_size, LONG_HEX);
5477e8a0 6923 putchar (' ');
595cf52e
L
6924 print_vma (section->sh_entsize, LONG_HEX);
6925
72de5009
AM
6926 printf (" %-16u %lu\n",
6927 section->sh_info,
595cf52e
L
6928 (unsigned long) section->sh_addralign);
6929 }
f7a99963
NC
6930 else
6931 {
6932 putchar (' ');
6933 print_vma (section->sh_addr, LONG_HEX);
53c7db4b
KH
6934 if ((long) section->sh_offset == section->sh_offset)
6935 printf (" %8.8lx", (unsigned long) section->sh_offset);
6936 else
6937 {
6938 printf (" ");
6939 print_vma (section->sh_offset, LONG_HEX);
6940 }
f7a99963
NC
6941 printf ("\n ");
6942 print_vma (section->sh_size, LONG_HEX);
6943 printf (" ");
6944 print_vma (section->sh_entsize, LONG_HEX);
76da6bbe 6945
dda8d76d 6946 printf (" %3s ", get_elf_section_flags (filedata, section->sh_flags));
76da6bbe 6947
72de5009
AM
6948 printf (" %2u %3u %lu\n",
6949 section->sh_link,
6950 section->sh_info,
f7a99963
NC
6951 (unsigned long) section->sh_addralign);
6952 }
5477e8a0
L
6953
6954 if (do_section_details)
77115a4a 6955 {
dda8d76d 6956 printf (" %s\n", get_elf_section_flags (filedata, section->sh_flags));
77115a4a
L
6957 if ((section->sh_flags & SHF_COMPRESSED) != 0)
6958 {
6959 /* Minimum section size is 12 bytes for 32-bit compression
6960 header + 12 bytes for compressed data header. */
6961 unsigned char buf[24];
d8024a91 6962
77115a4a 6963 assert (sizeof (buf) >= sizeof (Elf64_External_Chdr));
dda8d76d 6964 if (get_data (&buf, filedata, section->sh_offset, 1,
77115a4a
L
6965 sizeof (buf), _("compression header")))
6966 {
6967 Elf_Internal_Chdr chdr;
d8024a91 6968
5844b465
NC
6969 if (get_compression_header (&chdr, buf, sizeof (buf)) == 0)
6970 printf (_(" [<corrupt>]\n"));
77115a4a 6971 else
5844b465
NC
6972 {
6973 if (chdr.ch_type == ELFCOMPRESS_ZLIB)
6974 printf (" ZLIB, ");
6975 else
6976 printf (_(" [<unknown>: 0x%x], "),
6977 chdr.ch_type);
6978 print_vma (chdr.ch_size, LONG_HEX);
6979 printf (", %lu\n", (unsigned long) chdr.ch_addralign);
6980 }
77115a4a
L
6981 }
6982 }
6983 }
252b5132
RH
6984 }
6985
5477e8a0 6986 if (!do_section_details)
3dbcc61d 6987 {
9fb71ee4
NC
6988 /* The ordering of the letters shown here matches the ordering of the
6989 corresponding SHF_xxx values, and hence the order in which these
6990 letters will be displayed to the user. */
6991 printf (_("Key to Flags:\n\
6992 W (write), A (alloc), X (execute), M (merge), S (strings), I (info),\n\
6993 L (link order), O (extra OS processing required), G (group), T (TLS),\n\
fd85a6a1 6994 C (compressed), x (unknown), o (OS specific), E (exclude),\n "));
5424d7ed
L
6995 switch (filedata->file_header.e_ident[EI_OSABI])
6996 {
6997 case ELFOSABI_GNU:
6998 case ELFOSABI_FREEBSD:
6999 printf (_("R (retain), "));
7000 /* Fall through */
7001 case ELFOSABI_NONE:
7002 printf (_("D (mbind), "));
7003 break;
7004 default:
7005 break;
7006 }
dda8d76d
NC
7007 if (filedata->file_header.e_machine == EM_X86_64
7008 || filedata->file_header.e_machine == EM_L1OM
7009 || filedata->file_header.e_machine == EM_K1OM)
9fb71ee4 7010 printf (_("l (large), "));
dda8d76d 7011 else if (filedata->file_header.e_machine == EM_ARM)
f0728ee3 7012 printf (_("y (purecode), "));
dda8d76d 7013 else if (filedata->file_header.e_machine == EM_PPC)
83eef883 7014 printf (_("v (VLE), "));
9fb71ee4 7015 printf ("p (processor specific)\n");
0b4362b0 7016 }
d1133906 7017
32ec8896 7018 return TRUE;
252b5132
RH
7019}
7020
28d13567
AM
7021static bfd_boolean
7022get_symtab (Filedata *filedata, Elf_Internal_Shdr *symsec,
7023 Elf_Internal_Sym **symtab, unsigned long *nsyms,
7024 char **strtab, unsigned long *strtablen)
7025{
7026 *strtab = NULL;
7027 *strtablen = 0;
7028 *symtab = GET_ELF_SYMBOLS (filedata, symsec, nsyms);
7029
7030 if (*symtab == NULL)
7031 return FALSE;
7032
7033 if (symsec->sh_link != 0)
7034 {
7035 Elf_Internal_Shdr *strsec;
7036
7037 if (symsec->sh_link >= filedata->file_header.e_shnum)
7038 {
7039 error (_("Bad sh_link in symbol table section\n"));
7040 free (*symtab);
7041 *symtab = NULL;
7042 *nsyms = 0;
7043 return FALSE;
7044 }
7045
7046 strsec = filedata->section_headers + symsec->sh_link;
7047
7048 *strtab = (char *) get_data (NULL, filedata, strsec->sh_offset,
7049 1, strsec->sh_size, _("string table"));
7050 if (*strtab == NULL)
7051 {
7052 free (*symtab);
7053 *symtab = NULL;
7054 *nsyms = 0;
7055 return FALSE;
7056 }
7057 *strtablen = strsec->sh_size;
7058 }
7059 return TRUE;
7060}
7061
f5842774
L
7062static const char *
7063get_group_flags (unsigned int flags)
7064{
1449284b 7065 static char buff[128];
220453ec 7066
6d913794
NC
7067 if (flags == 0)
7068 return "";
7069 else if (flags == GRP_COMDAT)
7070 return "COMDAT ";
f5842774 7071
89246a0e
AM
7072 snprintf (buff, sizeof buff, "[0x%x: %s%s%s]",
7073 flags,
7074 flags & GRP_MASKOS ? _("<OS specific>") : "",
7075 flags & GRP_MASKPROC ? _("<PROC specific>") : "",
7076 (flags & ~(GRP_COMDAT | GRP_MASKOS | GRP_MASKPROC)
7077 ? _("<unknown>") : ""));
6d913794 7078
f5842774
L
7079 return buff;
7080}
7081
32ec8896 7082static bfd_boolean
dda8d76d 7083process_section_groups (Filedata * filedata)
f5842774 7084{
2cf0635d 7085 Elf_Internal_Shdr * section;
f5842774 7086 unsigned int i;
2cf0635d
NC
7087 struct group * group;
7088 Elf_Internal_Shdr * symtab_sec;
7089 Elf_Internal_Shdr * strtab_sec;
7090 Elf_Internal_Sym * symtab;
ba5cdace 7091 unsigned long num_syms;
2cf0635d 7092 char * strtab;
c256ffe7 7093 size_t strtab_size;
d1f5c6e3
L
7094
7095 /* Don't process section groups unless needed. */
7096 if (!do_unwind && !do_section_groups)
32ec8896 7097 return TRUE;
f5842774 7098
dda8d76d 7099 if (filedata->file_header.e_shnum == 0)
f5842774
L
7100 {
7101 if (do_section_groups)
82f2dbf7 7102 printf (_("\nThere are no sections to group in this file.\n"));
f5842774 7103
32ec8896 7104 return TRUE;
f5842774
L
7105 }
7106
dda8d76d 7107 if (filedata->section_headers == NULL)
f5842774
L
7108 {
7109 error (_("Section headers are not available!\n"));
fa1908fd 7110 /* PR 13622: This can happen with a corrupt ELF header. */
32ec8896 7111 return FALSE;
f5842774
L
7112 }
7113
978c4450
AM
7114 filedata->section_headers_groups
7115 = (struct group **) calloc (filedata->file_header.e_shnum,
7116 sizeof (struct group *));
e4b17d5c 7117
978c4450 7118 if (filedata->section_headers_groups == NULL)
e4b17d5c 7119 {
8b73c356 7120 error (_("Out of memory reading %u section group headers\n"),
dda8d76d 7121 filedata->file_header.e_shnum);
32ec8896 7122 return FALSE;
e4b17d5c
L
7123 }
7124
f5842774 7125 /* Scan the sections for the group section. */
978c4450 7126 filedata->group_count = 0;
dda8d76d
NC
7127 for (i = 0, section = filedata->section_headers;
7128 i < filedata->file_header.e_shnum;
f5842774 7129 i++, section++)
e4b17d5c 7130 if (section->sh_type == SHT_GROUP)
978c4450 7131 filedata->group_count++;
e4b17d5c 7132
978c4450 7133 if (filedata->group_count == 0)
d1f5c6e3
L
7134 {
7135 if (do_section_groups)
7136 printf (_("\nThere are no section groups in this file.\n"));
7137
32ec8896 7138 return TRUE;
d1f5c6e3
L
7139 }
7140
978c4450
AM
7141 filedata->section_groups = (struct group *) calloc (filedata->group_count,
7142 sizeof (struct group));
e4b17d5c 7143
978c4450 7144 if (filedata->section_groups == NULL)
e4b17d5c 7145 {
8b73c356 7146 error (_("Out of memory reading %lu groups\n"),
978c4450 7147 (unsigned long) filedata->group_count);
32ec8896 7148 return FALSE;
e4b17d5c
L
7149 }
7150
d1f5c6e3
L
7151 symtab_sec = NULL;
7152 strtab_sec = NULL;
7153 symtab = NULL;
ba5cdace 7154 num_syms = 0;
d1f5c6e3 7155 strtab = NULL;
c256ffe7 7156 strtab_size = 0;
978c4450 7157 for (i = 0, section = filedata->section_headers, group = filedata->section_groups;
dda8d76d 7158 i < filedata->file_header.e_shnum;
e4b17d5c 7159 i++, section++)
f5842774
L
7160 {
7161 if (section->sh_type == SHT_GROUP)
7162 {
dda8d76d 7163 const char * name = printable_section_name (filedata, section);
74e1a04b 7164 const char * group_name;
2cf0635d
NC
7165 unsigned char * start;
7166 unsigned char * indices;
f5842774 7167 unsigned int entry, j, size;
2cf0635d
NC
7168 Elf_Internal_Shdr * sec;
7169 Elf_Internal_Sym * sym;
f5842774
L
7170
7171 /* Get the symbol table. */
dda8d76d
NC
7172 if (section->sh_link >= filedata->file_header.e_shnum
7173 || ((sec = filedata->section_headers + section->sh_link)->sh_type
c256ffe7 7174 != SHT_SYMTAB))
f5842774
L
7175 {
7176 error (_("Bad sh_link in group section `%s'\n"), name);
7177 continue;
7178 }
d1f5c6e3
L
7179
7180 if (symtab_sec != sec)
7181 {
7182 symtab_sec = sec;
9db70fc3 7183 free (symtab);
dda8d76d 7184 symtab = GET_ELF_SYMBOLS (filedata, symtab_sec, & num_syms);
d1f5c6e3 7185 }
f5842774 7186
dd24e3da
NC
7187 if (symtab == NULL)
7188 {
7189 error (_("Corrupt header in group section `%s'\n"), name);
7190 continue;
7191 }
7192
ba5cdace
NC
7193 if (section->sh_info >= num_syms)
7194 {
7195 error (_("Bad sh_info in group section `%s'\n"), name);
7196 continue;
7197 }
7198
f5842774
L
7199 sym = symtab + section->sh_info;
7200
7201 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
7202 {
4fbb74a6 7203 if (sym->st_shndx == 0
dda8d76d 7204 || sym->st_shndx >= filedata->file_header.e_shnum)
f5842774
L
7205 {
7206 error (_("Bad sh_info in group section `%s'\n"), name);
7207 continue;
7208 }
ba2685cc 7209
b9e920ec
AM
7210 group_name = SECTION_NAME_PRINT (filedata->section_headers
7211 + sym->st_shndx);
c256ffe7 7212 strtab_sec = NULL;
9db70fc3 7213 free (strtab);
f5842774 7214 strtab = NULL;
c256ffe7 7215 strtab_size = 0;
f5842774
L
7216 }
7217 else
7218 {
7219 /* Get the string table. */
dda8d76d 7220 if (symtab_sec->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
7221 {
7222 strtab_sec = NULL;
9db70fc3 7223 free (strtab);
c256ffe7
JJ
7224 strtab = NULL;
7225 strtab_size = 0;
7226 }
7227 else if (strtab_sec
dda8d76d 7228 != (sec = filedata->section_headers + symtab_sec->sh_link))
d1f5c6e3
L
7229 {
7230 strtab_sec = sec;
9db70fc3 7231 free (strtab);
071436c6 7232
dda8d76d 7233 strtab = (char *) get_data (NULL, filedata, strtab_sec->sh_offset,
071436c6
NC
7234 1, strtab_sec->sh_size,
7235 _("string table"));
c256ffe7 7236 strtab_size = strtab != NULL ? strtab_sec->sh_size : 0;
d1f5c6e3 7237 }
c256ffe7 7238 group_name = sym->st_name < strtab_size
2b692964 7239 ? strtab + sym->st_name : _("<corrupt>");
f5842774
L
7240 }
7241
c9c1d674
EG
7242 /* PR 17531: file: loop. */
7243 if (section->sh_entsize > section->sh_size)
7244 {
7245 error (_("Section %s has sh_entsize (0x%lx) which is larger than its size (0x%lx)\n"),
dda8d76d 7246 printable_section_name (filedata, section),
8066deb1
AM
7247 (unsigned long) section->sh_entsize,
7248 (unsigned long) section->sh_size);
61dd8e19 7249 continue;
c9c1d674
EG
7250 }
7251
dda8d76d 7252 start = (unsigned char *) get_data (NULL, filedata, section->sh_offset,
3f5e193b
NC
7253 1, section->sh_size,
7254 _("section data"));
59245841
NC
7255 if (start == NULL)
7256 continue;
f5842774
L
7257
7258 indices = start;
7259 size = (section->sh_size / section->sh_entsize) - 1;
7260 entry = byte_get (indices, 4);
7261 indices += 4;
e4b17d5c
L
7262
7263 if (do_section_groups)
7264 {
2b692964 7265 printf (_("\n%sgroup section [%5u] `%s' [%s] contains %u sections:\n"),
391cb864 7266 get_group_flags (entry), i, name, group_name, size);
ba2685cc 7267
e4b17d5c
L
7268 printf (_(" [Index] Name\n"));
7269 }
7270
7271 group->group_index = i;
7272
f5842774
L
7273 for (j = 0; j < size; j++)
7274 {
2cf0635d 7275 struct group_list * g;
e4b17d5c 7276
f5842774
L
7277 entry = byte_get (indices, 4);
7278 indices += 4;
7279
dda8d76d 7280 if (entry >= filedata->file_header.e_shnum)
391cb864 7281 {
57028622
NC
7282 static unsigned num_group_errors = 0;
7283
7284 if (num_group_errors ++ < 10)
7285 {
7286 error (_("section [%5u] in group section [%5u] > maximum section [%5u]\n"),
dda8d76d 7287 entry, i, filedata->file_header.e_shnum - 1);
57028622 7288 if (num_group_errors == 10)
67ce483b 7289 warn (_("Further error messages about overlarge group section indices suppressed\n"));
57028622 7290 }
391cb864
L
7291 continue;
7292 }
391cb864 7293
978c4450 7294 if (filedata->section_headers_groups [entry] != NULL)
e4b17d5c 7295 {
d1f5c6e3
L
7296 if (entry)
7297 {
57028622
NC
7298 static unsigned num_errs = 0;
7299
7300 if (num_errs ++ < 10)
7301 {
7302 error (_("section [%5u] in group section [%5u] already in group section [%5u]\n"),
7303 entry, i,
978c4450 7304 filedata->section_headers_groups [entry]->group_index);
57028622
NC
7305 if (num_errs == 10)
7306 warn (_("Further error messages about already contained group sections suppressed\n"));
7307 }
d1f5c6e3
L
7308 continue;
7309 }
7310 else
7311 {
7312 /* Intel C/C++ compiler may put section 0 in a
32ec8896 7313 section group. We just warn it the first time
d1f5c6e3 7314 and ignore it afterwards. */
32ec8896 7315 static bfd_boolean warned = FALSE;
d1f5c6e3
L
7316 if (!warned)
7317 {
7318 error (_("section 0 in group section [%5u]\n"),
978c4450 7319 filedata->section_headers_groups [entry]->group_index);
32ec8896 7320 warned = TRUE;
d1f5c6e3
L
7321 }
7322 }
e4b17d5c
L
7323 }
7324
978c4450 7325 filedata->section_headers_groups [entry] = group;
e4b17d5c
L
7326
7327 if (do_section_groups)
7328 {
dda8d76d
NC
7329 sec = filedata->section_headers + entry;
7330 printf (" [%5u] %s\n", entry, printable_section_name (filedata, sec));
ba2685cc
AM
7331 }
7332
3f5e193b 7333 g = (struct group_list *) xmalloc (sizeof (struct group_list));
e4b17d5c
L
7334 g->section_index = entry;
7335 g->next = group->root;
7336 group->root = g;
f5842774
L
7337 }
7338
9db70fc3 7339 free (start);
e4b17d5c
L
7340
7341 group++;
f5842774
L
7342 }
7343 }
7344
9db70fc3
AM
7345 free (symtab);
7346 free (strtab);
32ec8896 7347 return TRUE;
f5842774
L
7348}
7349
28f997cf
TG
7350/* Data used to display dynamic fixups. */
7351
7352struct ia64_vms_dynfixup
7353{
7354 bfd_vma needed_ident; /* Library ident number. */
7355 bfd_vma needed; /* Index in the dstrtab of the library name. */
7356 bfd_vma fixup_needed; /* Index of the library. */
7357 bfd_vma fixup_rela_cnt; /* Number of fixups. */
7358 bfd_vma fixup_rela_off; /* Fixups offset in the dynamic segment. */
7359};
7360
7361/* Data used to display dynamic relocations. */
7362
7363struct ia64_vms_dynimgrela
7364{
7365 bfd_vma img_rela_cnt; /* Number of relocations. */
7366 bfd_vma img_rela_off; /* Reloc offset in the dynamic segment. */
7367};
7368
7369/* Display IA-64 OpenVMS dynamic fixups (used to dynamically link a shared
7370 library). */
7371
32ec8896 7372static bfd_boolean
dda8d76d
NC
7373dump_ia64_vms_dynamic_fixups (Filedata * filedata,
7374 struct ia64_vms_dynfixup * fixup,
7375 const char * strtab,
7376 unsigned int strtab_sz)
28f997cf 7377{
32ec8896 7378 Elf64_External_VMS_IMAGE_FIXUP * imfs;
28f997cf 7379 long i;
32ec8896 7380 const char * lib_name;
28f997cf 7381
978c4450
AM
7382 imfs = get_data (NULL, filedata,
7383 filedata->dynamic_addr + fixup->fixup_rela_off,
95099889 7384 sizeof (*imfs), fixup->fixup_rela_cnt,
28f997cf
TG
7385 _("dynamic section image fixups"));
7386 if (!imfs)
32ec8896 7387 return FALSE;
28f997cf
TG
7388
7389 if (fixup->needed < strtab_sz)
7390 lib_name = strtab + fixup->needed;
7391 else
7392 {
32ec8896 7393 warn (_("corrupt library name index of 0x%lx found in dynamic entry"),
7f01b0c6 7394 (unsigned long) fixup->needed);
28f997cf
TG
7395 lib_name = "???";
7396 }
736990c4 7397
28f997cf
TG
7398 printf (_("\nImage fixups for needed library #%d: %s - ident: %lx\n"),
7399 (int) fixup->fixup_needed, lib_name, (long) fixup->needed_ident);
7400 printf
7401 (_("Seg Offset Type SymVec DataType\n"));
7402
7403 for (i = 0; i < (long) fixup->fixup_rela_cnt; i++)
7404 {
7405 unsigned int type;
7406 const char *rtype;
7407
7408 printf ("%3u ", (unsigned) BYTE_GET (imfs [i].fixup_seg));
7409 printf_vma ((bfd_vma) BYTE_GET (imfs [i].fixup_offset));
7410 type = BYTE_GET (imfs [i].type);
7411 rtype = elf_ia64_reloc_type (type);
7412 if (rtype == NULL)
7413 printf (" 0x%08x ", type);
7414 else
7415 printf (" %-32s ", rtype);
7416 printf ("%6u ", (unsigned) BYTE_GET (imfs [i].symvec_index));
7417 printf ("0x%08x\n", (unsigned) BYTE_GET (imfs [i].data_type));
7418 }
7419
7420 free (imfs);
32ec8896 7421 return TRUE;
28f997cf
TG
7422}
7423
7424/* Display IA-64 OpenVMS dynamic relocations (used to relocate an image). */
7425
32ec8896 7426static bfd_boolean
dda8d76d 7427dump_ia64_vms_dynamic_relocs (Filedata * filedata, struct ia64_vms_dynimgrela *imgrela)
28f997cf
TG
7428{
7429 Elf64_External_VMS_IMAGE_RELA *imrs;
7430 long i;
7431
978c4450
AM
7432 imrs = get_data (NULL, filedata,
7433 filedata->dynamic_addr + imgrela->img_rela_off,
95099889 7434 sizeof (*imrs), imgrela->img_rela_cnt,
9cf03b7e 7435 _("dynamic section image relocations"));
28f997cf 7436 if (!imrs)
32ec8896 7437 return FALSE;
28f997cf
TG
7438
7439 printf (_("\nImage relocs\n"));
7440 printf
7441 (_("Seg Offset Type Addend Seg Sym Off\n"));
7442
7443 for (i = 0; i < (long) imgrela->img_rela_cnt; i++)
7444 {
7445 unsigned int type;
7446 const char *rtype;
7447
7448 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].rela_seg));
7449 printf ("%08" BFD_VMA_FMT "x ",
7450 (bfd_vma) BYTE_GET (imrs [i].rela_offset));
7451 type = BYTE_GET (imrs [i].type);
7452 rtype = elf_ia64_reloc_type (type);
7453 if (rtype == NULL)
7454 printf ("0x%08x ", type);
7455 else
7456 printf ("%-31s ", rtype);
7457 print_vma (BYTE_GET (imrs [i].addend), FULL_HEX);
7458 printf ("%3u ", (unsigned) BYTE_GET (imrs [i].sym_seg));
7459 printf ("%08" BFD_VMA_FMT "x\n",
7460 (bfd_vma) BYTE_GET (imrs [i].sym_offset));
7461 }
7462
7463 free (imrs);
32ec8896 7464 return TRUE;
28f997cf
TG
7465}
7466
7467/* Display IA-64 OpenVMS dynamic relocations and fixups. */
7468
32ec8896 7469static bfd_boolean
dda8d76d 7470process_ia64_vms_dynamic_relocs (Filedata * filedata)
28f997cf
TG
7471{
7472 struct ia64_vms_dynfixup fixup;
7473 struct ia64_vms_dynimgrela imgrela;
7474 Elf_Internal_Dyn *entry;
28f997cf
TG
7475 bfd_vma strtab_off = 0;
7476 bfd_vma strtab_sz = 0;
7477 char *strtab = NULL;
32ec8896 7478 bfd_boolean res = TRUE;
28f997cf
TG
7479
7480 memset (&fixup, 0, sizeof (fixup));
7481 memset (&imgrela, 0, sizeof (imgrela));
7482
7483 /* Note: the order of the entries is specified by the OpenVMS specs. */
978c4450
AM
7484 for (entry = filedata->dynamic_section;
7485 entry < filedata->dynamic_section + filedata->dynamic_nent;
28f997cf
TG
7486 entry++)
7487 {
7488 switch (entry->d_tag)
7489 {
7490 case DT_IA_64_VMS_STRTAB_OFFSET:
7491 strtab_off = entry->d_un.d_val;
7492 break;
7493 case DT_STRSZ:
7494 strtab_sz = entry->d_un.d_val;
7495 if (strtab == NULL)
978c4450
AM
7496 strtab = get_data (NULL, filedata,
7497 filedata->dynamic_addr + strtab_off,
28f997cf 7498 1, strtab_sz, _("dynamic string section"));
736990c4
NC
7499 if (strtab == NULL)
7500 strtab_sz = 0;
28f997cf
TG
7501 break;
7502
7503 case DT_IA_64_VMS_NEEDED_IDENT:
7504 fixup.needed_ident = entry->d_un.d_val;
7505 break;
7506 case DT_NEEDED:
7507 fixup.needed = entry->d_un.d_val;
7508 break;
7509 case DT_IA_64_VMS_FIXUP_NEEDED:
7510 fixup.fixup_needed = entry->d_un.d_val;
7511 break;
7512 case DT_IA_64_VMS_FIXUP_RELA_CNT:
7513 fixup.fixup_rela_cnt = entry->d_un.d_val;
7514 break;
7515 case DT_IA_64_VMS_FIXUP_RELA_OFF:
7516 fixup.fixup_rela_off = entry->d_un.d_val;
dda8d76d 7517 if (! dump_ia64_vms_dynamic_fixups (filedata, &fixup, strtab, strtab_sz))
32ec8896 7518 res = FALSE;
28f997cf 7519 break;
28f997cf
TG
7520 case DT_IA_64_VMS_IMG_RELA_CNT:
7521 imgrela.img_rela_cnt = entry->d_un.d_val;
7522 break;
7523 case DT_IA_64_VMS_IMG_RELA_OFF:
7524 imgrela.img_rela_off = entry->d_un.d_val;
dda8d76d 7525 if (! dump_ia64_vms_dynamic_relocs (filedata, &imgrela))
32ec8896 7526 res = FALSE;
28f997cf
TG
7527 break;
7528
7529 default:
7530 break;
7531 }
7532 }
7533
9db70fc3 7534 free (strtab);
28f997cf
TG
7535
7536 return res;
7537}
7538
85b1c36d 7539static struct
566b0d53 7540{
2cf0635d 7541 const char * name;
566b0d53
L
7542 int reloc;
7543 int size;
7544 int rela;
32ec8896
NC
7545}
7546 dynamic_relocations [] =
566b0d53 7547{
32ec8896
NC
7548 { "REL", DT_REL, DT_RELSZ, FALSE },
7549 { "RELA", DT_RELA, DT_RELASZ, TRUE },
7550 { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
566b0d53
L
7551};
7552
252b5132 7553/* Process the reloc section. */
18bd398b 7554
32ec8896 7555static bfd_boolean
dda8d76d 7556process_relocs (Filedata * filedata)
252b5132 7557{
b34976b6
AM
7558 unsigned long rel_size;
7559 unsigned long rel_offset;
252b5132 7560
252b5132 7561 if (!do_reloc)
32ec8896 7562 return TRUE;
252b5132
RH
7563
7564 if (do_using_dynamic)
7565 {
32ec8896 7566 int is_rela;
2cf0635d 7567 const char * name;
32ec8896 7568 bfd_boolean has_dynamic_reloc;
566b0d53 7569 unsigned int i;
0de14b54 7570
32ec8896 7571 has_dynamic_reloc = FALSE;
252b5132 7572
566b0d53 7573 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
252b5132 7574 {
566b0d53
L
7575 is_rela = dynamic_relocations [i].rela;
7576 name = dynamic_relocations [i].name;
978c4450
AM
7577 rel_size = filedata->dynamic_info[dynamic_relocations [i].size];
7578 rel_offset = filedata->dynamic_info[dynamic_relocations [i].reloc];
103f02d3 7579
32ec8896
NC
7580 if (rel_size)
7581 has_dynamic_reloc = TRUE;
566b0d53
L
7582
7583 if (is_rela == UNKNOWN)
aa903cfb 7584 {
566b0d53 7585 if (dynamic_relocations [i].reloc == DT_JMPREL)
978c4450 7586 switch (filedata->dynamic_info[DT_PLTREL])
566b0d53
L
7587 {
7588 case DT_REL:
7589 is_rela = FALSE;
7590 break;
7591 case DT_RELA:
7592 is_rela = TRUE;
7593 break;
7594 }
aa903cfb 7595 }
252b5132 7596
566b0d53
L
7597 if (rel_size)
7598 {
7599 printf
7600 (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
7601 name, rel_offset, rel_size);
252b5132 7602
dda8d76d
NC
7603 dump_relocations (filedata,
7604 offset_from_vma (filedata, rel_offset, rel_size),
d93f0186 7605 rel_size,
978c4450
AM
7606 filedata->dynamic_symbols,
7607 filedata->num_dynamic_syms,
7608 filedata->dynamic_strings,
7609 filedata->dynamic_strings_length,
32ec8896 7610 is_rela, TRUE /* is_dynamic */);
566b0d53 7611 }
252b5132 7612 }
566b0d53 7613
dda8d76d
NC
7614 if (is_ia64_vms (filedata))
7615 if (process_ia64_vms_dynamic_relocs (filedata))
32ec8896 7616 has_dynamic_reloc = TRUE;
28f997cf 7617
566b0d53 7618 if (! has_dynamic_reloc)
252b5132
RH
7619 printf (_("\nThere are no dynamic relocations in this file.\n"));
7620 }
7621 else
7622 {
2cf0635d 7623 Elf_Internal_Shdr * section;
b34976b6 7624 unsigned long i;
32ec8896 7625 bfd_boolean found = FALSE;
252b5132 7626
dda8d76d
NC
7627 for (i = 0, section = filedata->section_headers;
7628 i < filedata->file_header.e_shnum;
b34976b6 7629 i++, section++)
252b5132
RH
7630 {
7631 if ( section->sh_type != SHT_RELA
7632 && section->sh_type != SHT_REL)
7633 continue;
7634
7635 rel_offset = section->sh_offset;
7636 rel_size = section->sh_size;
7637
7638 if (rel_size)
7639 {
b34976b6 7640 int is_rela;
d3a49aa8 7641 unsigned long num_rela;
103f02d3 7642
252b5132
RH
7643 printf (_("\nRelocation section "));
7644
dda8d76d 7645 if (filedata->string_table == NULL)
19936277 7646 printf ("%d", section->sh_name);
252b5132 7647 else
dda8d76d 7648 printf ("'%s'", printable_section_name (filedata, section));
252b5132 7649
d3a49aa8
AM
7650 num_rela = rel_size / section->sh_entsize;
7651 printf (ngettext (" at offset 0x%lx contains %lu entry:\n",
7652 " at offset 0x%lx contains %lu entries:\n",
7653 num_rela),
7654 rel_offset, num_rela);
252b5132 7655
d79b3d50
NC
7656 is_rela = section->sh_type == SHT_RELA;
7657
4fbb74a6 7658 if (section->sh_link != 0
dda8d76d 7659 && section->sh_link < filedata->file_header.e_shnum)
af3fc3bc 7660 {
2cf0635d
NC
7661 Elf_Internal_Shdr * symsec;
7662 Elf_Internal_Sym * symtab;
d79b3d50 7663 unsigned long nsyms;
c256ffe7 7664 unsigned long strtablen = 0;
2cf0635d 7665 char * strtab = NULL;
57346661 7666
dda8d76d 7667 symsec = filedata->section_headers + section->sh_link;
08d8fa11
JJ
7668 if (symsec->sh_type != SHT_SYMTAB
7669 && symsec->sh_type != SHT_DYNSYM)
7670 continue;
7671
28d13567
AM
7672 if (!get_symtab (filedata, symsec,
7673 &symtab, &nsyms, &strtab, &strtablen))
af3fc3bc 7674 continue;
252b5132 7675
dda8d76d 7676 dump_relocations (filedata, rel_offset, rel_size,
bb4d2ac2
L
7677 symtab, nsyms, strtab, strtablen,
7678 is_rela,
7679 symsec->sh_type == SHT_DYNSYM);
9db70fc3 7680 free (strtab);
d79b3d50
NC
7681 free (symtab);
7682 }
7683 else
dda8d76d 7684 dump_relocations (filedata, rel_offset, rel_size,
32ec8896
NC
7685 NULL, 0, NULL, 0, is_rela,
7686 FALSE /* is_dynamic */);
252b5132 7687
32ec8896 7688 found = TRUE;
252b5132
RH
7689 }
7690 }
7691
7692 if (! found)
45ac8f4f
NC
7693 {
7694 /* Users sometimes forget the -D option, so try to be helpful. */
7695 for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
7696 {
978c4450 7697 if (filedata->dynamic_info[dynamic_relocations [i].size])
45ac8f4f
NC
7698 {
7699 printf (_("\nThere are no static relocations in this file."));
7700 printf (_("\nTo see the dynamic relocations add --use-dynamic to the command line.\n"));
7701
7702 break;
7703 }
7704 }
7705 if (i == ARRAY_SIZE (dynamic_relocations))
7706 printf (_("\nThere are no relocations in this file.\n"));
7707 }
252b5132
RH
7708 }
7709
32ec8896 7710 return TRUE;
252b5132
RH
7711}
7712
4d6ed7c8
NC
7713/* An absolute address consists of a section and an offset. If the
7714 section is NULL, the offset itself is the address, otherwise, the
7715 address equals to LOAD_ADDRESS(section) + offset. */
7716
7717struct absaddr
948f632f
DA
7718{
7719 unsigned short section;
7720 bfd_vma offset;
7721};
4d6ed7c8 7722
948f632f
DA
7723/* Find the nearest symbol at or below ADDR. Returns the symbol
7724 name, if found, and the offset from the symbol to ADDR. */
4d6ed7c8 7725
4d6ed7c8 7726static void
dda8d76d
NC
7727find_symbol_for_address (Filedata * filedata,
7728 Elf_Internal_Sym * symtab,
7729 unsigned long nsyms,
7730 const char * strtab,
7731 unsigned long strtab_size,
7732 struct absaddr addr,
7733 const char ** symname,
7734 bfd_vma * offset)
4d6ed7c8 7735{
d3ba0551 7736 bfd_vma dist = 0x100000;
2cf0635d 7737 Elf_Internal_Sym * sym;
948f632f
DA
7738 Elf_Internal_Sym * beg;
7739 Elf_Internal_Sym * end;
2cf0635d 7740 Elf_Internal_Sym * best = NULL;
4d6ed7c8 7741
0b6ae522 7742 REMOVE_ARCH_BITS (addr.offset);
948f632f
DA
7743 beg = symtab;
7744 end = symtab + nsyms;
0b6ae522 7745
948f632f 7746 while (beg < end)
4d6ed7c8 7747 {
948f632f
DA
7748 bfd_vma value;
7749
7750 sym = beg + (end - beg) / 2;
0b6ae522 7751
948f632f 7752 value = sym->st_value;
0b6ae522
DJ
7753 REMOVE_ARCH_BITS (value);
7754
948f632f 7755 if (sym->st_name != 0
4d6ed7c8 7756 && (addr.section == SHN_UNDEF || addr.section == sym->st_shndx)
0b6ae522
DJ
7757 && addr.offset >= value
7758 && addr.offset - value < dist)
4d6ed7c8
NC
7759 {
7760 best = sym;
0b6ae522 7761 dist = addr.offset - value;
4d6ed7c8
NC
7762 if (!dist)
7763 break;
7764 }
948f632f
DA
7765
7766 if (addr.offset < value)
7767 end = sym;
7768 else
7769 beg = sym + 1;
4d6ed7c8 7770 }
1b31d05e 7771
4d6ed7c8
NC
7772 if (best)
7773 {
57346661 7774 *symname = (best->st_name >= strtab_size
2b692964 7775 ? _("<corrupt>") : strtab + best->st_name);
4d6ed7c8
NC
7776 *offset = dist;
7777 return;
7778 }
1b31d05e 7779
4d6ed7c8
NC
7780 *symname = NULL;
7781 *offset = addr.offset;
7782}
7783
32ec8896 7784static /* signed */ int
948f632f
DA
7785symcmp (const void *p, const void *q)
7786{
7787 Elf_Internal_Sym *sp = (Elf_Internal_Sym *) p;
7788 Elf_Internal_Sym *sq = (Elf_Internal_Sym *) q;
7789
7790 return sp->st_value > sq->st_value ? 1 : (sp->st_value < sq->st_value ? -1 : 0);
7791}
7792
7793/* Process the unwind section. */
7794
7795#include "unwind-ia64.h"
7796
7797struct ia64_unw_table_entry
7798{
7799 struct absaddr start;
7800 struct absaddr end;
7801 struct absaddr info;
7802};
7803
7804struct ia64_unw_aux_info
7805{
32ec8896
NC
7806 struct ia64_unw_table_entry * table; /* Unwind table. */
7807 unsigned long table_len; /* Length of unwind table. */
7808 unsigned char * info; /* Unwind info. */
7809 unsigned long info_size; /* Size of unwind info. */
7810 bfd_vma info_addr; /* Starting address of unwind info. */
7811 bfd_vma seg_base; /* Starting address of segment. */
7812 Elf_Internal_Sym * symtab; /* The symbol table. */
7813 unsigned long nsyms; /* Number of symbols. */
7814 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
7815 unsigned long nfuns; /* Number of entries in funtab. */
7816 char * strtab; /* The string table. */
7817 unsigned long strtab_size; /* Size of string table. */
948f632f
DA
7818};
7819
32ec8896 7820static bfd_boolean
dda8d76d 7821dump_ia64_unwind (Filedata * filedata, struct ia64_unw_aux_info * aux)
4d6ed7c8 7822{
2cf0635d 7823 struct ia64_unw_table_entry * tp;
948f632f 7824 unsigned long j, nfuns;
4d6ed7c8 7825 int in_body;
32ec8896 7826 bfd_boolean res = TRUE;
7036c0e1 7827
948f632f
DA
7828 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
7829 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
7830 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
7831 aux->funtab[nfuns++] = aux->symtab[j];
7832 aux->nfuns = nfuns;
7833 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
7834
4d6ed7c8
NC
7835 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
7836 {
7837 bfd_vma stamp;
7838 bfd_vma offset;
2cf0635d
NC
7839 const unsigned char * dp;
7840 const unsigned char * head;
53774b7e 7841 const unsigned char * end;
2cf0635d 7842 const char * procname;
4d6ed7c8 7843
dda8d76d 7844 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661 7845 aux->strtab_size, tp->start, &procname, &offset);
4d6ed7c8
NC
7846
7847 fputs ("\n<", stdout);
7848
7849 if (procname)
7850 {
7851 fputs (procname, stdout);
7852
7853 if (offset)
7854 printf ("+%lx", (unsigned long) offset);
7855 }
7856
7857 fputs (">: [", stdout);
7858 print_vma (tp->start.offset, PREFIX_HEX);
7859 fputc ('-', stdout);
7860 print_vma (tp->end.offset, PREFIX_HEX);
86f55779 7861 printf ("], info at +0x%lx\n",
4d6ed7c8
NC
7862 (unsigned long) (tp->info.offset - aux->seg_base));
7863
53774b7e
NC
7864 /* PR 17531: file: 86232b32. */
7865 if (aux->info == NULL)
7866 continue;
7867
97c0a079
AM
7868 offset = tp->info.offset;
7869 if (tp->info.section)
7870 {
7871 if (tp->info.section >= filedata->file_header.e_shnum)
7872 {
7873 warn (_("Invalid section %u in table entry %ld\n"),
7874 tp->info.section, (long) (tp - aux->table));
7875 res = FALSE;
7876 continue;
7877 }
7878 offset += filedata->section_headers[tp->info.section].sh_addr;
7879 }
7880 offset -= aux->info_addr;
53774b7e 7881 /* PR 17531: file: 0997b4d1. */
90679903
AM
7882 if (offset >= aux->info_size
7883 || aux->info_size - offset < 8)
53774b7e
NC
7884 {
7885 warn (_("Invalid offset %lx in table entry %ld\n"),
7886 (long) tp->info.offset, (long) (tp - aux->table));
32ec8896 7887 res = FALSE;
53774b7e
NC
7888 continue;
7889 }
7890
97c0a079 7891 head = aux->info + offset;
a4a00738 7892 stamp = byte_get ((unsigned char *) head, sizeof (stamp));
4d6ed7c8 7893
86f55779 7894 printf (" v%u, flags=0x%lx (%s%s), len=%lu bytes\n",
4d6ed7c8
NC
7895 (unsigned) UNW_VER (stamp),
7896 (unsigned long) ((stamp & UNW_FLAG_MASK) >> 32),
7897 UNW_FLAG_EHANDLER (stamp) ? " ehandler" : "",
7898 UNW_FLAG_UHANDLER (stamp) ? " uhandler" : "",
89fac5e3 7899 (unsigned long) (eh_addr_size * UNW_LENGTH (stamp)));
4d6ed7c8
NC
7900
7901 if (UNW_VER (stamp) != 1)
7902 {
2b692964 7903 printf (_("\tUnknown version.\n"));
4d6ed7c8
NC
7904 continue;
7905 }
7906
7907 in_body = 0;
53774b7e
NC
7908 end = head + 8 + eh_addr_size * UNW_LENGTH (stamp);
7909 /* PR 17531: file: 16ceda89. */
7910 if (end > aux->info + aux->info_size)
7911 end = aux->info + aux->info_size;
7912 for (dp = head + 8; dp < end;)
b4477bc8 7913 dp = unw_decode (dp, in_body, & in_body, end);
4d6ed7c8 7914 }
948f632f
DA
7915
7916 free (aux->funtab);
32ec8896
NC
7917
7918 return res;
4d6ed7c8
NC
7919}
7920
53774b7e 7921static bfd_boolean
dda8d76d
NC
7922slurp_ia64_unwind_table (Filedata * filedata,
7923 struct ia64_unw_aux_info * aux,
7924 Elf_Internal_Shdr * sec)
4d6ed7c8 7925{
89fac5e3 7926 unsigned long size, nrelas, i;
2cf0635d
NC
7927 Elf_Internal_Phdr * seg;
7928 struct ia64_unw_table_entry * tep;
7929 Elf_Internal_Shdr * relsec;
7930 Elf_Internal_Rela * rela;
7931 Elf_Internal_Rela * rp;
7932 unsigned char * table;
7933 unsigned char * tp;
7934 Elf_Internal_Sym * sym;
7935 const char * relname;
4d6ed7c8 7936
53774b7e
NC
7937 aux->table_len = 0;
7938
4d6ed7c8
NC
7939 /* First, find the starting address of the segment that includes
7940 this section: */
7941
dda8d76d 7942 if (filedata->file_header.e_phnum)
4d6ed7c8 7943 {
dda8d76d 7944 if (! get_program_headers (filedata))
53774b7e 7945 return FALSE;
4d6ed7c8 7946
dda8d76d
NC
7947 for (seg = filedata->program_headers;
7948 seg < filedata->program_headers + filedata->file_header.e_phnum;
d93f0186 7949 ++seg)
4d6ed7c8
NC
7950 {
7951 if (seg->p_type != PT_LOAD)
7952 continue;
7953
7954 if (sec->sh_addr >= seg->p_vaddr
7955 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
7956 {
7957 aux->seg_base = seg->p_vaddr;
7958 break;
7959 }
7960 }
4d6ed7c8
NC
7961 }
7962
7963 /* Second, build the unwind table from the contents of the unwind section: */
7964 size = sec->sh_size;
dda8d76d 7965 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 7966 _("unwind table"));
a6e9f9df 7967 if (!table)
53774b7e 7968 return FALSE;
4d6ed7c8 7969
53774b7e 7970 aux->table_len = size / (3 * eh_addr_size);
3f5e193b 7971 aux->table = (struct ia64_unw_table_entry *)
53774b7e 7972 xcmalloc (aux->table_len, sizeof (aux->table[0]));
89fac5e3 7973 tep = aux->table;
53774b7e
NC
7974
7975 for (tp = table; tp <= table + size - (3 * eh_addr_size); ++tep)
4d6ed7c8
NC
7976 {
7977 tep->start.section = SHN_UNDEF;
7978 tep->end.section = SHN_UNDEF;
7979 tep->info.section = SHN_UNDEF;
c6a0c689
AM
7980 tep->start.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7981 tep->end.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
7982 tep->info.offset = byte_get (tp, eh_addr_size); tp += eh_addr_size;
4d6ed7c8
NC
7983 tep->start.offset += aux->seg_base;
7984 tep->end.offset += aux->seg_base;
7985 tep->info.offset += aux->seg_base;
7986 }
7987 free (table);
7988
41e92641 7989 /* Third, apply any relocations to the unwind table: */
dda8d76d
NC
7990 for (relsec = filedata->section_headers;
7991 relsec < filedata->section_headers + filedata->file_header.e_shnum;
4d6ed7c8
NC
7992 ++relsec)
7993 {
7994 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
7995 || relsec->sh_info >= filedata->file_header.e_shnum
7996 || filedata->section_headers + relsec->sh_info != sec)
4d6ed7c8
NC
7997 continue;
7998
dda8d76d 7999 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
4d6ed7c8 8000 & rela, & nrelas))
53774b7e
NC
8001 {
8002 free (aux->table);
8003 aux->table = NULL;
8004 aux->table_len = 0;
8005 return FALSE;
8006 }
4d6ed7c8
NC
8007
8008 for (rp = rela; rp < rela + nrelas; ++rp)
8009 {
4770fb94 8010 unsigned int sym_ndx;
726bd37d
AM
8011 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8012 relname = elf_ia64_reloc_type (r_type);
4d6ed7c8 8013
82b1b41b
NC
8014 /* PR 17531: file: 9fa67536. */
8015 if (relname == NULL)
8016 {
726bd37d 8017 warn (_("Skipping unknown relocation type: %u\n"), r_type);
82b1b41b
NC
8018 continue;
8019 }
948f632f 8020
0112cd26 8021 if (! const_strneq (relname, "R_IA64_SEGREL"))
4d6ed7c8 8022 {
82b1b41b 8023 warn (_("Skipping unexpected relocation type: %s\n"), relname);
4d6ed7c8
NC
8024 continue;
8025 }
8026
89fac5e3 8027 i = rp->r_offset / (3 * eh_addr_size);
4d6ed7c8 8028
53774b7e
NC
8029 /* PR 17531: file: 5bc8d9bf. */
8030 if (i >= aux->table_len)
8031 {
8032 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8033 continue;
8034 }
8035
4770fb94
AM
8036 sym_ndx = get_reloc_symindex (rp->r_info);
8037 if (sym_ndx >= aux->nsyms)
8038 {
8039 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8040 sym_ndx);
8041 continue;
8042 }
8043 sym = aux->symtab + sym_ndx;
8044
53774b7e 8045 switch (rp->r_offset / eh_addr_size % 3)
4d6ed7c8
NC
8046 {
8047 case 0:
8048 aux->table[i].start.section = sym->st_shndx;
e466bc6e 8049 aux->table[i].start.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8050 break;
8051 case 1:
8052 aux->table[i].end.section = sym->st_shndx;
e466bc6e 8053 aux->table[i].end.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8054 break;
8055 case 2:
8056 aux->table[i].info.section = sym->st_shndx;
e466bc6e 8057 aux->table[i].info.offset = rp->r_addend + sym->st_value;
4d6ed7c8
NC
8058 break;
8059 default:
8060 break;
8061 }
8062 }
8063
8064 free (rela);
8065 }
8066
53774b7e 8067 return TRUE;
4d6ed7c8
NC
8068}
8069
32ec8896 8070static bfd_boolean
dda8d76d 8071ia64_process_unwind (Filedata * filedata)
4d6ed7c8 8072{
2cf0635d
NC
8073 Elf_Internal_Shdr * sec;
8074 Elf_Internal_Shdr * unwsec = NULL;
89fac5e3 8075 unsigned long i, unwcount = 0, unwstart = 0;
57346661 8076 struct ia64_unw_aux_info aux;
32ec8896 8077 bfd_boolean res = TRUE;
f1467e33 8078
4d6ed7c8
NC
8079 memset (& aux, 0, sizeof (aux));
8080
dda8d76d 8081 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
4d6ed7c8 8082 {
28d13567 8083 if (sec->sh_type == SHT_SYMTAB)
4d6ed7c8 8084 {
28d13567 8085 if (aux.symtab)
4082ef84 8086 {
28d13567
AM
8087 error (_("Multiple symbol tables encountered\n"));
8088 free (aux.symtab);
8089 aux.symtab = NULL;
4082ef84 8090 free (aux.strtab);
28d13567 8091 aux.strtab = NULL;
4082ef84 8092 }
28d13567
AM
8093 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8094 &aux.strtab, &aux.strtab_size))
8095 return FALSE;
4d6ed7c8
NC
8096 }
8097 else if (sec->sh_type == SHT_IA_64_UNWIND)
579f31ac
JJ
8098 unwcount++;
8099 }
8100
8101 if (!unwcount)
8102 printf (_("\nThere are no unwind sections in this file.\n"));
8103
8104 while (unwcount-- > 0)
8105 {
2cf0635d 8106 char * suffix;
579f31ac
JJ
8107 size_t len, len2;
8108
dda8d76d
NC
8109 for (i = unwstart, sec = filedata->section_headers + unwstart, unwsec = NULL;
8110 i < filedata->file_header.e_shnum; ++i, ++sec)
579f31ac
JJ
8111 if (sec->sh_type == SHT_IA_64_UNWIND)
8112 {
8113 unwsec = sec;
8114 break;
8115 }
4082ef84
NC
8116 /* We have already counted the number of SHT_IA64_UNWIND
8117 sections so the loop above should never fail. */
8118 assert (unwsec != NULL);
579f31ac
JJ
8119
8120 unwstart = i + 1;
8121 len = sizeof (ELF_STRING_ia64_unwind_once) - 1;
8122
e4b17d5c
L
8123 if ((unwsec->sh_flags & SHF_GROUP) != 0)
8124 {
8125 /* We need to find which section group it is in. */
4082ef84 8126 struct group_list * g;
e4b17d5c 8127
978c4450
AM
8128 if (filedata->section_headers_groups == NULL
8129 || filedata->section_headers_groups[i] == NULL)
dda8d76d 8130 i = filedata->file_header.e_shnum;
4082ef84 8131 else
e4b17d5c 8132 {
978c4450 8133 g = filedata->section_headers_groups[i]->root;
18bd398b 8134
4082ef84
NC
8135 for (; g != NULL; g = g->next)
8136 {
dda8d76d 8137 sec = filedata->section_headers + g->section_index;
e4b17d5c 8138
b9e920ec
AM
8139 if (SECTION_NAME_VALID (sec)
8140 && streq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info))
4082ef84
NC
8141 break;
8142 }
8143
8144 if (g == NULL)
dda8d76d 8145 i = filedata->file_header.e_shnum;
4082ef84 8146 }
e4b17d5c 8147 }
b9e920ec
AM
8148 else if (SECTION_NAME_VALID (unwsec)
8149 && strneq (SECTION_NAME (unwsec),
8150 ELF_STRING_ia64_unwind_once, len))
579f31ac 8151 {
18bd398b 8152 /* .gnu.linkonce.ia64unw.FOO -> .gnu.linkonce.ia64unwi.FOO. */
579f31ac
JJ
8153 len2 = sizeof (ELF_STRING_ia64_unwind_info_once) - 1;
8154 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8155 for (i = 0, sec = filedata->section_headers;
8156 i < filedata->file_header.e_shnum;
579f31ac 8157 ++i, ++sec)
b9e920ec
AM
8158 if (SECTION_NAME_VALID (sec)
8159 && strneq (SECTION_NAME (sec),
8160 ELF_STRING_ia64_unwind_info_once, len2)
18bd398b 8161 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8162 break;
8163 }
8164 else
8165 {
8166 /* .IA_64.unwindFOO -> .IA_64.unwind_infoFOO
18bd398b 8167 .IA_64.unwind or BAR -> .IA_64.unwind_info. */
579f31ac
JJ
8168 len = sizeof (ELF_STRING_ia64_unwind) - 1;
8169 len2 = sizeof (ELF_STRING_ia64_unwind_info) - 1;
8170 suffix = "";
b9e920ec
AM
8171 if (SECTION_NAME_VALID (unwsec)
8172 && strneq (SECTION_NAME (unwsec), ELF_STRING_ia64_unwind, len))
579f31ac 8173 suffix = SECTION_NAME (unwsec) + len;
b9e920ec
AM
8174 for (i = 0, sec = filedata->section_headers;
8175 i < filedata->file_header.e_shnum;
579f31ac 8176 ++i, ++sec)
b9e920ec
AM
8177 if (SECTION_NAME_VALID (sec)
8178 && strneq (SECTION_NAME (sec), ELF_STRING_ia64_unwind_info, len2)
18bd398b 8179 && streq (SECTION_NAME (sec) + len2, suffix))
579f31ac
JJ
8180 break;
8181 }
8182
dda8d76d 8183 if (i == filedata->file_header.e_shnum)
579f31ac
JJ
8184 {
8185 printf (_("\nCould not find unwind info section for "));
8186
dda8d76d 8187 if (filedata->string_table == NULL)
579f31ac
JJ
8188 printf ("%d", unwsec->sh_name);
8189 else
dda8d76d 8190 printf ("'%s'", printable_section_name (filedata, unwsec));
579f31ac
JJ
8191 }
8192 else
4d6ed7c8 8193 {
4d6ed7c8 8194 aux.info_addr = sec->sh_addr;
dda8d76d 8195 aux.info = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1,
4082ef84
NC
8196 sec->sh_size,
8197 _("unwind info"));
59245841 8198 aux.info_size = aux.info == NULL ? 0 : sec->sh_size;
4d6ed7c8 8199
579f31ac 8200 printf (_("\nUnwind section "));
4d6ed7c8 8201
dda8d76d 8202 if (filedata->string_table == NULL)
579f31ac
JJ
8203 printf ("%d", unwsec->sh_name);
8204 else
dda8d76d 8205 printf ("'%s'", printable_section_name (filedata, unwsec));
4d6ed7c8 8206
579f31ac 8207 printf (_(" at offset 0x%lx contains %lu entries:\n"),
e59b4dfb 8208 (unsigned long) unwsec->sh_offset,
89fac5e3 8209 (unsigned long) (unwsec->sh_size / (3 * eh_addr_size)));
4d6ed7c8 8210
dda8d76d 8211 if (slurp_ia64_unwind_table (filedata, & aux, unwsec)
53774b7e 8212 && aux.table_len > 0)
dda8d76d 8213 dump_ia64_unwind (filedata, & aux);
579f31ac 8214
9db70fc3
AM
8215 free ((char *) aux.table);
8216 free ((char *) aux.info);
579f31ac
JJ
8217 aux.table = NULL;
8218 aux.info = NULL;
8219 }
4d6ed7c8 8220 }
4d6ed7c8 8221
9db70fc3
AM
8222 free (aux.symtab);
8223 free ((char *) aux.strtab);
32ec8896
NC
8224
8225 return res;
4d6ed7c8
NC
8226}
8227
3f5e193b 8228struct hppa_unw_table_entry
32ec8896
NC
8229{
8230 struct absaddr start;
8231 struct absaddr end;
8232 unsigned int Cannot_unwind:1; /* 0 */
8233 unsigned int Millicode:1; /* 1 */
8234 unsigned int Millicode_save_sr0:1; /* 2 */
8235 unsigned int Region_description:2; /* 3..4 */
8236 unsigned int reserved1:1; /* 5 */
8237 unsigned int Entry_SR:1; /* 6 */
8238 unsigned int Entry_FR:4; /* Number saved 7..10 */
8239 unsigned int Entry_GR:5; /* Number saved 11..15 */
8240 unsigned int Args_stored:1; /* 16 */
8241 unsigned int Variable_Frame:1; /* 17 */
8242 unsigned int Separate_Package_Body:1; /* 18 */
8243 unsigned int Frame_Extension_Millicode:1; /* 19 */
8244 unsigned int Stack_Overflow_Check:1; /* 20 */
8245 unsigned int Two_Instruction_SP_Increment:1; /* 21 */
8246 unsigned int Ada_Region:1; /* 22 */
8247 unsigned int cxx_info:1; /* 23 */
8248 unsigned int cxx_try_catch:1; /* 24 */
8249 unsigned int sched_entry_seq:1; /* 25 */
8250 unsigned int reserved2:1; /* 26 */
8251 unsigned int Save_SP:1; /* 27 */
8252 unsigned int Save_RP:1; /* 28 */
8253 unsigned int Save_MRP_in_frame:1; /* 29 */
8254 unsigned int extn_ptr_defined:1; /* 30 */
8255 unsigned int Cleanup_defined:1; /* 31 */
8256
8257 unsigned int MPE_XL_interrupt_marker:1; /* 0 */
8258 unsigned int HP_UX_interrupt_marker:1; /* 1 */
8259 unsigned int Large_frame:1; /* 2 */
8260 unsigned int Pseudo_SP_Set:1; /* 3 */
8261 unsigned int reserved4:1; /* 4 */
8262 unsigned int Total_frame_size:27; /* 5..31 */
8263};
3f5e193b 8264
57346661 8265struct hppa_unw_aux_info
948f632f 8266{
32ec8896
NC
8267 struct hppa_unw_table_entry * table; /* Unwind table. */
8268 unsigned long table_len; /* Length of unwind table. */
8269 bfd_vma seg_base; /* Starting address of segment. */
8270 Elf_Internal_Sym * symtab; /* The symbol table. */
8271 unsigned long nsyms; /* Number of symbols. */
8272 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8273 unsigned long nfuns; /* Number of entries in funtab. */
8274 char * strtab; /* The string table. */
8275 unsigned long strtab_size; /* Size of string table. */
948f632f 8276};
57346661 8277
32ec8896 8278static bfd_boolean
dda8d76d 8279dump_hppa_unwind (Filedata * filedata, struct hppa_unw_aux_info * aux)
57346661 8280{
2cf0635d 8281 struct hppa_unw_table_entry * tp;
948f632f 8282 unsigned long j, nfuns;
32ec8896 8283 bfd_boolean res = TRUE;
948f632f
DA
8284
8285 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
8286 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
8287 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
8288 aux->funtab[nfuns++] = aux->symtab[j];
8289 aux->nfuns = nfuns;
8290 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
57346661 8291
57346661
AM
8292 for (tp = aux->table; tp < aux->table + aux->table_len; ++tp)
8293 {
8294 bfd_vma offset;
2cf0635d 8295 const char * procname;
57346661 8296
dda8d76d 8297 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
57346661
AM
8298 aux->strtab_size, tp->start, &procname,
8299 &offset);
8300
8301 fputs ("\n<", stdout);
8302
8303 if (procname)
8304 {
8305 fputs (procname, stdout);
8306
8307 if (offset)
8308 printf ("+%lx", (unsigned long) offset);
8309 }
8310
8311 fputs (">: [", stdout);
8312 print_vma (tp->start.offset, PREFIX_HEX);
8313 fputc ('-', stdout);
8314 print_vma (tp->end.offset, PREFIX_HEX);
8315 printf ("]\n\t");
8316
18bd398b
NC
8317#define PF(_m) if (tp->_m) printf (#_m " ");
8318#define PV(_m) if (tp->_m) printf (#_m "=%d ", tp->_m);
57346661
AM
8319 PF(Cannot_unwind);
8320 PF(Millicode);
8321 PF(Millicode_save_sr0);
18bd398b 8322 /* PV(Region_description); */
57346661
AM
8323 PF(Entry_SR);
8324 PV(Entry_FR);
8325 PV(Entry_GR);
8326 PF(Args_stored);
8327 PF(Variable_Frame);
8328 PF(Separate_Package_Body);
8329 PF(Frame_Extension_Millicode);
8330 PF(Stack_Overflow_Check);
8331 PF(Two_Instruction_SP_Increment);
8332 PF(Ada_Region);
8333 PF(cxx_info);
8334 PF(cxx_try_catch);
8335 PF(sched_entry_seq);
8336 PF(Save_SP);
8337 PF(Save_RP);
8338 PF(Save_MRP_in_frame);
8339 PF(extn_ptr_defined);
8340 PF(Cleanup_defined);
8341 PF(MPE_XL_interrupt_marker);
8342 PF(HP_UX_interrupt_marker);
8343 PF(Large_frame);
8344 PF(Pseudo_SP_Set);
8345 PV(Total_frame_size);
8346#undef PF
8347#undef PV
8348 }
8349
18bd398b 8350 printf ("\n");
948f632f
DA
8351
8352 free (aux->funtab);
32ec8896
NC
8353
8354 return res;
57346661
AM
8355}
8356
32ec8896 8357static bfd_boolean
dda8d76d
NC
8358slurp_hppa_unwind_table (Filedata * filedata,
8359 struct hppa_unw_aux_info * aux,
8360 Elf_Internal_Shdr * sec)
57346661 8361{
1c0751b2 8362 unsigned long size, unw_ent_size, nentries, nrelas, i;
2cf0635d
NC
8363 Elf_Internal_Phdr * seg;
8364 struct hppa_unw_table_entry * tep;
8365 Elf_Internal_Shdr * relsec;
8366 Elf_Internal_Rela * rela;
8367 Elf_Internal_Rela * rp;
8368 unsigned char * table;
8369 unsigned char * tp;
8370 Elf_Internal_Sym * sym;
8371 const char * relname;
57346661 8372
57346661
AM
8373 /* First, find the starting address of the segment that includes
8374 this section. */
dda8d76d 8375 if (filedata->file_header.e_phnum)
57346661 8376 {
dda8d76d 8377 if (! get_program_headers (filedata))
32ec8896 8378 return FALSE;
57346661 8379
dda8d76d
NC
8380 for (seg = filedata->program_headers;
8381 seg < filedata->program_headers + filedata->file_header.e_phnum;
57346661
AM
8382 ++seg)
8383 {
8384 if (seg->p_type != PT_LOAD)
8385 continue;
8386
8387 if (sec->sh_addr >= seg->p_vaddr
8388 && (sec->sh_addr + sec->sh_size <= seg->p_vaddr + seg->p_memsz))
8389 {
8390 aux->seg_base = seg->p_vaddr;
8391 break;
8392 }
8393 }
8394 }
8395
8396 /* Second, build the unwind table from the contents of the unwind
8397 section. */
8398 size = sec->sh_size;
dda8d76d 8399 table = (unsigned char *) get_data (NULL, filedata, sec->sh_offset, 1, size,
3f5e193b 8400 _("unwind table"));
57346661 8401 if (!table)
32ec8896 8402 return FALSE;
57346661 8403
1c0751b2
DA
8404 unw_ent_size = 16;
8405 nentries = size / unw_ent_size;
8406 size = unw_ent_size * nentries;
57346661 8407
e3fdc001 8408 aux->table_len = nentries;
3f5e193b
NC
8409 tep = aux->table = (struct hppa_unw_table_entry *)
8410 xcmalloc (nentries, sizeof (aux->table[0]));
57346661 8411
1c0751b2 8412 for (tp = table; tp < table + size; tp += unw_ent_size, ++tep)
57346661
AM
8413 {
8414 unsigned int tmp1, tmp2;
8415
8416 tep->start.section = SHN_UNDEF;
8417 tep->end.section = SHN_UNDEF;
8418
1c0751b2
DA
8419 tep->start.offset = byte_get ((unsigned char *) tp + 0, 4);
8420 tep->end.offset = byte_get ((unsigned char *) tp + 4, 4);
8421 tmp1 = byte_get ((unsigned char *) tp + 8, 4);
8422 tmp2 = byte_get ((unsigned char *) tp + 12, 4);
8423
8424 tep->start.offset += aux->seg_base;
8425 tep->end.offset += aux->seg_base;
57346661
AM
8426
8427 tep->Cannot_unwind = (tmp1 >> 31) & 0x1;
8428 tep->Millicode = (tmp1 >> 30) & 0x1;
8429 tep->Millicode_save_sr0 = (tmp1 >> 29) & 0x1;
8430 tep->Region_description = (tmp1 >> 27) & 0x3;
8431 tep->reserved1 = (tmp1 >> 26) & 0x1;
8432 tep->Entry_SR = (tmp1 >> 25) & 0x1;
8433 tep->Entry_FR = (tmp1 >> 21) & 0xf;
8434 tep->Entry_GR = (tmp1 >> 16) & 0x1f;
8435 tep->Args_stored = (tmp1 >> 15) & 0x1;
8436 tep->Variable_Frame = (tmp1 >> 14) & 0x1;
8437 tep->Separate_Package_Body = (tmp1 >> 13) & 0x1;
8438 tep->Frame_Extension_Millicode = (tmp1 >> 12) & 0x1;
8439 tep->Stack_Overflow_Check = (tmp1 >> 11) & 0x1;
8440 tep->Two_Instruction_SP_Increment = (tmp1 >> 10) & 0x1;
8441 tep->Ada_Region = (tmp1 >> 9) & 0x1;
8442 tep->cxx_info = (tmp1 >> 8) & 0x1;
8443 tep->cxx_try_catch = (tmp1 >> 7) & 0x1;
8444 tep->sched_entry_seq = (tmp1 >> 6) & 0x1;
8445 tep->reserved2 = (tmp1 >> 5) & 0x1;
8446 tep->Save_SP = (tmp1 >> 4) & 0x1;
8447 tep->Save_RP = (tmp1 >> 3) & 0x1;
8448 tep->Save_MRP_in_frame = (tmp1 >> 2) & 0x1;
8449 tep->extn_ptr_defined = (tmp1 >> 1) & 0x1;
8450 tep->Cleanup_defined = tmp1 & 0x1;
8451
8452 tep->MPE_XL_interrupt_marker = (tmp2 >> 31) & 0x1;
8453 tep->HP_UX_interrupt_marker = (tmp2 >> 30) & 0x1;
8454 tep->Large_frame = (tmp2 >> 29) & 0x1;
8455 tep->Pseudo_SP_Set = (tmp2 >> 28) & 0x1;
8456 tep->reserved4 = (tmp2 >> 27) & 0x1;
8457 tep->Total_frame_size = tmp2 & 0x7ffffff;
57346661
AM
8458 }
8459 free (table);
8460
8461 /* Third, apply any relocations to the unwind table. */
dda8d76d
NC
8462 for (relsec = filedata->section_headers;
8463 relsec < filedata->section_headers + filedata->file_header.e_shnum;
57346661
AM
8464 ++relsec)
8465 {
8466 if (relsec->sh_type != SHT_RELA
dda8d76d
NC
8467 || relsec->sh_info >= filedata->file_header.e_shnum
8468 || filedata->section_headers + relsec->sh_info != sec)
57346661
AM
8469 continue;
8470
dda8d76d 8471 if (!slurp_rela_relocs (filedata, relsec->sh_offset, relsec->sh_size,
57346661 8472 & rela, & nrelas))
32ec8896 8473 return FALSE;
57346661
AM
8474
8475 for (rp = rela; rp < rela + nrelas; ++rp)
8476 {
4770fb94 8477 unsigned int sym_ndx;
726bd37d
AM
8478 unsigned int r_type = get_reloc_type (filedata, rp->r_info);
8479 relname = elf_hppa_reloc_type (r_type);
57346661 8480
726bd37d
AM
8481 if (relname == NULL)
8482 {
8483 warn (_("Skipping unknown relocation type: %u\n"), r_type);
8484 continue;
8485 }
8486
57346661 8487 /* R_PARISC_SEGREL32 or R_PARISC_SEGREL64. */
0112cd26 8488 if (! const_strneq (relname, "R_PARISC_SEGREL"))
57346661 8489 {
726bd37d 8490 warn (_("Skipping unexpected relocation type: %s\n"), relname);
57346661
AM
8491 continue;
8492 }
8493
8494 i = rp->r_offset / unw_ent_size;
726bd37d
AM
8495 if (i >= aux->table_len)
8496 {
8497 warn (_("Skipping reloc with overlarge offset: %lx\n"), i);
8498 continue;
8499 }
57346661 8500
4770fb94
AM
8501 sym_ndx = get_reloc_symindex (rp->r_info);
8502 if (sym_ndx >= aux->nsyms)
8503 {
8504 warn (_("Skipping reloc with invalid symbol index: %u\n"),
8505 sym_ndx);
8506 continue;
8507 }
8508 sym = aux->symtab + sym_ndx;
8509
43f6cd05 8510 switch ((rp->r_offset % unw_ent_size) / 4)
57346661
AM
8511 {
8512 case 0:
8513 aux->table[i].start.section = sym->st_shndx;
1e456d54 8514 aux->table[i].start.offset = sym->st_value + rp->r_addend;
57346661
AM
8515 break;
8516 case 1:
8517 aux->table[i].end.section = sym->st_shndx;
1e456d54 8518 aux->table[i].end.offset = sym->st_value + rp->r_addend;
57346661
AM
8519 break;
8520 default:
8521 break;
8522 }
8523 }
8524
8525 free (rela);
8526 }
8527
32ec8896 8528 return TRUE;
57346661
AM
8529}
8530
32ec8896 8531static bfd_boolean
dda8d76d 8532hppa_process_unwind (Filedata * filedata)
57346661 8533{
57346661 8534 struct hppa_unw_aux_info aux;
2cf0635d 8535 Elf_Internal_Shdr * unwsec = NULL;
2cf0635d 8536 Elf_Internal_Shdr * sec;
18bd398b 8537 unsigned long i;
32ec8896 8538 bfd_boolean res = TRUE;
57346661 8539
dda8d76d 8540 if (filedata->string_table == NULL)
32ec8896 8541 return FALSE;
1b31d05e
NC
8542
8543 memset (& aux, 0, sizeof (aux));
57346661 8544
dda8d76d 8545 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8546 {
28d13567 8547 if (sec->sh_type == SHT_SYMTAB)
57346661 8548 {
28d13567 8549 if (aux.symtab)
4082ef84 8550 {
28d13567
AM
8551 error (_("Multiple symbol tables encountered\n"));
8552 free (aux.symtab);
8553 aux.symtab = NULL;
4082ef84 8554 free (aux.strtab);
28d13567 8555 aux.strtab = NULL;
4082ef84 8556 }
28d13567
AM
8557 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
8558 &aux.strtab, &aux.strtab_size))
8559 return FALSE;
57346661 8560 }
b9e920ec
AM
8561 else if (SECTION_NAME_VALID (sec)
8562 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661
AM
8563 unwsec = sec;
8564 }
8565
8566 if (!unwsec)
8567 printf (_("\nThere are no unwind sections in this file.\n"));
8568
dda8d76d 8569 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
57346661 8570 {
b9e920ec
AM
8571 if (SECTION_NAME_VALID (sec)
8572 && streq (SECTION_NAME (sec), ".PARISC.unwind"))
57346661 8573 {
43f6cd05 8574 unsigned long num_unwind = sec->sh_size / 16;
dda8d76d 8575
d3a49aa8
AM
8576 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
8577 "contains %lu entry:\n",
8578 "\nUnwind section '%s' at offset 0x%lx "
8579 "contains %lu entries:\n",
8580 num_unwind),
dda8d76d 8581 printable_section_name (filedata, sec),
57346661 8582 (unsigned long) sec->sh_offset,
d3a49aa8 8583 num_unwind);
57346661 8584
dda8d76d 8585 if (! slurp_hppa_unwind_table (filedata, &aux, sec))
32ec8896 8586 res = FALSE;
66b09c7e
S
8587
8588 if (res && aux.table_len > 0)
32ec8896 8589 {
dda8d76d 8590 if (! dump_hppa_unwind (filedata, &aux))
32ec8896
NC
8591 res = FALSE;
8592 }
57346661 8593
9db70fc3 8594 free ((char *) aux.table);
57346661
AM
8595 aux.table = NULL;
8596 }
8597 }
8598
9db70fc3
AM
8599 free (aux.symtab);
8600 free ((char *) aux.strtab);
32ec8896
NC
8601
8602 return res;
57346661
AM
8603}
8604
0b6ae522
DJ
8605struct arm_section
8606{
a734115a
NC
8607 unsigned char * data; /* The unwind data. */
8608 Elf_Internal_Shdr * sec; /* The cached unwind section header. */
8609 Elf_Internal_Rela * rela; /* The cached relocations for this section. */
8610 unsigned long nrelas; /* The number of relocations. */
8611 unsigned int rel_type; /* REL or RELA ? */
8612 Elf_Internal_Rela * next_rela; /* Cyclic pointer to the next reloc to process. */
0b6ae522
DJ
8613};
8614
8615struct arm_unw_aux_info
8616{
dda8d76d 8617 Filedata * filedata; /* The file containing the unwind sections. */
a734115a
NC
8618 Elf_Internal_Sym * symtab; /* The file's symbol table. */
8619 unsigned long nsyms; /* Number of symbols. */
948f632f
DA
8620 Elf_Internal_Sym * funtab; /* Sorted table of STT_FUNC symbols. */
8621 unsigned long nfuns; /* Number of these symbols. */
a734115a
NC
8622 char * strtab; /* The file's string table. */
8623 unsigned long strtab_size; /* Size of string table. */
0b6ae522
DJ
8624};
8625
8626static const char *
dda8d76d
NC
8627arm_print_vma_and_name (Filedata * filedata,
8628 struct arm_unw_aux_info * aux,
8629 bfd_vma fn,
8630 struct absaddr addr)
0b6ae522
DJ
8631{
8632 const char *procname;
8633 bfd_vma sym_offset;
8634
8635 if (addr.section == SHN_UNDEF)
8636 addr.offset = fn;
8637
dda8d76d 8638 find_symbol_for_address (filedata, aux->funtab, aux->nfuns, aux->strtab,
0b6ae522
DJ
8639 aux->strtab_size, addr, &procname,
8640 &sym_offset);
8641
8642 print_vma (fn, PREFIX_HEX);
8643
8644 if (procname)
8645 {
8646 fputs (" <", stdout);
8647 fputs (procname, stdout);
8648
8649 if (sym_offset)
8650 printf ("+0x%lx", (unsigned long) sym_offset);
8651 fputc ('>', stdout);
8652 }
8653
8654 return procname;
8655}
8656
8657static void
8658arm_free_section (struct arm_section *arm_sec)
8659{
9db70fc3
AM
8660 free (arm_sec->data);
8661 free (arm_sec->rela);
0b6ae522
DJ
8662}
8663
a734115a
NC
8664/* 1) If SEC does not match the one cached in ARM_SEC, then free the current
8665 cached section and install SEC instead.
8666 2) Locate the 32-bit word at WORD_OFFSET in unwind section SEC
8667 and return its valued in * WORDP, relocating if necessary.
1b31d05e 8668 3) Update the NEXT_RELA field in ARM_SEC and store the section index and
a734115a 8669 relocation's offset in ADDR.
1b31d05e
NC
8670 4) If SYM_NAME is non-NULL and a relocation was applied, record the offset
8671 into the string table of the symbol associated with the reloc. If no
8672 reloc was applied store -1 there.
8673 5) Return TRUE upon success, FALSE otherwise. */
a734115a
NC
8674
8675static bfd_boolean
dda8d76d
NC
8676get_unwind_section_word (Filedata * filedata,
8677 struct arm_unw_aux_info * aux,
1b31d05e
NC
8678 struct arm_section * arm_sec,
8679 Elf_Internal_Shdr * sec,
8680 bfd_vma word_offset,
8681 unsigned int * wordp,
8682 struct absaddr * addr,
8683 bfd_vma * sym_name)
0b6ae522
DJ
8684{
8685 Elf_Internal_Rela *rp;
8686 Elf_Internal_Sym *sym;
8687 const char * relname;
8688 unsigned int word;
8689 bfd_boolean wrapped;
8690
e0a31db1
NC
8691 if (sec == NULL || arm_sec == NULL)
8692 return FALSE;
8693
0b6ae522
DJ
8694 addr->section = SHN_UNDEF;
8695 addr->offset = 0;
8696
1b31d05e
NC
8697 if (sym_name != NULL)
8698 *sym_name = (bfd_vma) -1;
8699
a734115a 8700 /* If necessary, update the section cache. */
0b6ae522
DJ
8701 if (sec != arm_sec->sec)
8702 {
8703 Elf_Internal_Shdr *relsec;
8704
8705 arm_free_section (arm_sec);
8706
8707 arm_sec->sec = sec;
dda8d76d 8708 arm_sec->data = get_data (NULL, aux->filedata, sec->sh_offset, 1,
0b6ae522 8709 sec->sh_size, _("unwind data"));
0b6ae522
DJ
8710 arm_sec->rela = NULL;
8711 arm_sec->nrelas = 0;
8712
dda8d76d
NC
8713 for (relsec = filedata->section_headers;
8714 relsec < filedata->section_headers + filedata->file_header.e_shnum;
0b6ae522
DJ
8715 ++relsec)
8716 {
dda8d76d
NC
8717 if (relsec->sh_info >= filedata->file_header.e_shnum
8718 || filedata->section_headers + relsec->sh_info != sec
1ae40aa4
NC
8719 /* PR 15745: Check the section type as well. */
8720 || (relsec->sh_type != SHT_REL
8721 && relsec->sh_type != SHT_RELA))
0b6ae522
DJ
8722 continue;
8723
a734115a 8724 arm_sec->rel_type = relsec->sh_type;
0b6ae522
DJ
8725 if (relsec->sh_type == SHT_REL)
8726 {
dda8d76d 8727 if (!slurp_rel_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8728 relsec->sh_size,
8729 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8730 return FALSE;
0b6ae522 8731 }
1ae40aa4 8732 else /* relsec->sh_type == SHT_RELA */
0b6ae522 8733 {
dda8d76d 8734 if (!slurp_rela_relocs (aux->filedata, relsec->sh_offset,
0b6ae522
DJ
8735 relsec->sh_size,
8736 & arm_sec->rela, & arm_sec->nrelas))
a734115a 8737 return FALSE;
0b6ae522 8738 }
1ae40aa4 8739 break;
0b6ae522
DJ
8740 }
8741
8742 arm_sec->next_rela = arm_sec->rela;
8743 }
8744
a734115a 8745 /* If there is no unwind data we can do nothing. */
0b6ae522 8746 if (arm_sec->data == NULL)
a734115a 8747 return FALSE;
0b6ae522 8748
e0a31db1 8749 /* If the offset is invalid then fail. */
f32ba729
NC
8750 if (/* PR 21343 *//* PR 18879 */
8751 sec->sh_size < 4
8752 || word_offset > (sec->sh_size - 4)
1a915552 8753 || ((bfd_signed_vma) word_offset) < 0)
e0a31db1
NC
8754 return FALSE;
8755
a734115a 8756 /* Get the word at the required offset. */
0b6ae522
DJ
8757 word = byte_get (arm_sec->data + word_offset, 4);
8758
0eff7165
NC
8759 /* PR 17531: file: id:000001,src:001266+003044,op:splice,rep:128. */
8760 if (arm_sec->rela == NULL)
8761 {
8762 * wordp = word;
8763 return TRUE;
8764 }
8765
a734115a 8766 /* Look through the relocs to find the one that applies to the provided offset. */
0b6ae522
DJ
8767 wrapped = FALSE;
8768 for (rp = arm_sec->next_rela; rp != arm_sec->rela + arm_sec->nrelas; rp++)
8769 {
8770 bfd_vma prelval, offset;
8771
8772 if (rp->r_offset > word_offset && !wrapped)
8773 {
8774 rp = arm_sec->rela;
8775 wrapped = TRUE;
8776 }
8777 if (rp->r_offset > word_offset)
8778 break;
8779
8780 if (rp->r_offset & 3)
8781 {
8782 warn (_("Skipping unexpected relocation at offset 0x%lx\n"),
8783 (unsigned long) rp->r_offset);
8784 continue;
8785 }
8786
8787 if (rp->r_offset < word_offset)
8788 continue;
8789
74e1a04b
NC
8790 /* PR 17531: file: 027-161405-0.004 */
8791 if (aux->symtab == NULL)
8792 continue;
8793
0b6ae522
DJ
8794 if (arm_sec->rel_type == SHT_REL)
8795 {
8796 offset = word & 0x7fffffff;
8797 if (offset & 0x40000000)
8798 offset |= ~ (bfd_vma) 0x7fffffff;
8799 }
a734115a 8800 else if (arm_sec->rel_type == SHT_RELA)
0b6ae522 8801 offset = rp->r_addend;
a734115a 8802 else
74e1a04b
NC
8803 {
8804 error (_("Unknown section relocation type %d encountered\n"),
8805 arm_sec->rel_type);
8806 break;
8807 }
0b6ae522 8808
071436c6
NC
8809 /* PR 17531 file: 027-1241568-0.004. */
8810 if (ELF32_R_SYM (rp->r_info) >= aux->nsyms)
8811 {
8812 error (_("Bad symbol index in unwind relocation (%lu > %lu)\n"),
8813 (unsigned long) ELF32_R_SYM (rp->r_info), aux->nsyms);
8814 break;
8815 }
8816
8817 sym = aux->symtab + ELF32_R_SYM (rp->r_info);
0b6ae522
DJ
8818 offset += sym->st_value;
8819 prelval = offset - (arm_sec->sec->sh_addr + rp->r_offset);
8820
a734115a 8821 /* Check that we are processing the expected reloc type. */
dda8d76d 8822 if (filedata->file_header.e_machine == EM_ARM)
a734115a
NC
8823 {
8824 relname = elf_arm_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8825 if (relname == NULL)
8826 {
8827 warn (_("Skipping unknown ARM relocation type: %d\n"),
8828 (int) ELF32_R_TYPE (rp->r_info));
8829 continue;
8830 }
a734115a
NC
8831
8832 if (streq (relname, "R_ARM_NONE"))
8833 continue;
0b4362b0 8834
a734115a
NC
8835 if (! streq (relname, "R_ARM_PREL31"))
8836 {
071436c6 8837 warn (_("Skipping unexpected ARM relocation type %s\n"), relname);
a734115a
NC
8838 continue;
8839 }
8840 }
dda8d76d 8841 else if (filedata->file_header.e_machine == EM_TI_C6000)
a734115a
NC
8842 {
8843 relname = elf_tic6x_reloc_type (ELF32_R_TYPE (rp->r_info));
071436c6
NC
8844 if (relname == NULL)
8845 {
8846 warn (_("Skipping unknown C6000 relocation type: %d\n"),
8847 (int) ELF32_R_TYPE (rp->r_info));
8848 continue;
8849 }
0b4362b0 8850
a734115a
NC
8851 if (streq (relname, "R_C6000_NONE"))
8852 continue;
8853
8854 if (! streq (relname, "R_C6000_PREL31"))
8855 {
071436c6 8856 warn (_("Skipping unexpected C6000 relocation type %s\n"), relname);
a734115a
NC
8857 continue;
8858 }
8859
8860 prelval >>= 1;
8861 }
8862 else
74e1a04b
NC
8863 {
8864 /* This function currently only supports ARM and TI unwinders. */
8865 warn (_("Only TI and ARM unwinders are currently supported\n"));
8866 break;
8867 }
fa197c1c 8868
0b6ae522
DJ
8869 word = (word & ~ (bfd_vma) 0x7fffffff) | (prelval & 0x7fffffff);
8870 addr->section = sym->st_shndx;
8871 addr->offset = offset;
74e1a04b 8872
1b31d05e
NC
8873 if (sym_name)
8874 * sym_name = sym->st_name;
0b6ae522
DJ
8875 break;
8876 }
8877
8878 *wordp = word;
8879 arm_sec->next_rela = rp;
8880
a734115a 8881 return TRUE;
0b6ae522
DJ
8882}
8883
a734115a
NC
8884static const char *tic6x_unwind_regnames[16] =
8885{
0b4362b0
RM
8886 "A15", "B15", "B14", "B13", "B12", "B11", "B10", "B3",
8887 "A14", "A13", "A12", "A11", "A10",
a734115a
NC
8888 "[invalid reg 13]", "[invalid reg 14]", "[invalid reg 15]"
8889};
fa197c1c 8890
0b6ae522 8891static void
fa197c1c 8892decode_tic6x_unwind_regmask (unsigned int mask)
0b6ae522 8893{
fa197c1c
PB
8894 int i;
8895
8896 for (i = 12; mask; mask >>= 1, i--)
8897 {
8898 if (mask & 1)
8899 {
8900 fputs (tic6x_unwind_regnames[i], stdout);
8901 if (mask > 1)
8902 fputs (", ", stdout);
8903 }
8904 }
8905}
0b6ae522
DJ
8906
8907#define ADVANCE \
8908 if (remaining == 0 && more_words) \
8909 { \
8910 data_offset += 4; \
dda8d76d 8911 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, \
1b31d05e 8912 data_offset, & word, & addr, NULL)) \
32ec8896 8913 return FALSE; \
0b6ae522
DJ
8914 remaining = 4; \
8915 more_words--; \
8916 } \
8917
8918#define GET_OP(OP) \
8919 ADVANCE; \
8920 if (remaining) \
8921 { \
8922 remaining--; \
8923 (OP) = word >> 24; \
8924 word <<= 8; \
8925 } \
8926 else \
8927 { \
2b692964 8928 printf (_("[Truncated opcode]\n")); \
32ec8896 8929 return FALSE; \
0b6ae522 8930 } \
cc5914eb 8931 printf ("0x%02x ", OP)
0b6ae522 8932
32ec8896 8933static bfd_boolean
dda8d76d
NC
8934decode_arm_unwind_bytecode (Filedata * filedata,
8935 struct arm_unw_aux_info * aux,
948f632f
DA
8936 unsigned int word,
8937 unsigned int remaining,
8938 unsigned int more_words,
8939 bfd_vma data_offset,
8940 Elf_Internal_Shdr * data_sec,
8941 struct arm_section * data_arm_sec)
fa197c1c
PB
8942{
8943 struct absaddr addr;
32ec8896 8944 bfd_boolean res = TRUE;
0b6ae522
DJ
8945
8946 /* Decode the unwinding instructions. */
8947 while (1)
8948 {
8949 unsigned int op, op2;
8950
8951 ADVANCE;
8952 if (remaining == 0)
8953 break;
8954 remaining--;
8955 op = word >> 24;
8956 word <<= 8;
8957
cc5914eb 8958 printf (" 0x%02x ", op);
0b6ae522
DJ
8959
8960 if ((op & 0xc0) == 0x00)
8961 {
8962 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8963
cc5914eb 8964 printf (" vsp = vsp + %d", offset);
0b6ae522
DJ
8965 }
8966 else if ((op & 0xc0) == 0x40)
8967 {
8968 int offset = ((op & 0x3f) << 2) + 4;
61865e30 8969
cc5914eb 8970 printf (" vsp = vsp - %d", offset);
0b6ae522
DJ
8971 }
8972 else if ((op & 0xf0) == 0x80)
8973 {
8974 GET_OP (op2);
8975 if (op == 0x80 && op2 == 0)
8976 printf (_("Refuse to unwind"));
8977 else
8978 {
8979 unsigned int mask = ((op & 0x0f) << 8) | op2;
32ec8896 8980 bfd_boolean first = TRUE;
0b6ae522 8981 int i;
2b692964 8982
0b6ae522
DJ
8983 printf ("pop {");
8984 for (i = 0; i < 12; i++)
8985 if (mask & (1 << i))
8986 {
8987 if (first)
32ec8896 8988 first = FALSE;
0b6ae522
DJ
8989 else
8990 printf (", ");
8991 printf ("r%d", 4 + i);
8992 }
8993 printf ("}");
8994 }
8995 }
8996 else if ((op & 0xf0) == 0x90)
8997 {
8998 if (op == 0x9d || op == 0x9f)
8999 printf (_(" [Reserved]"));
9000 else
cc5914eb 9001 printf (" vsp = r%d", op & 0x0f);
0b6ae522
DJ
9002 }
9003 else if ((op & 0xf0) == 0xa0)
9004 {
9005 int end = 4 + (op & 0x07);
32ec8896 9006 bfd_boolean first = TRUE;
0b6ae522 9007 int i;
61865e30 9008
0b6ae522
DJ
9009 printf (" pop {");
9010 for (i = 4; i <= end; i++)
9011 {
9012 if (first)
32ec8896 9013 first = FALSE;
0b6ae522
DJ
9014 else
9015 printf (", ");
9016 printf ("r%d", i);
9017 }
9018 if (op & 0x08)
9019 {
1b31d05e 9020 if (!first)
0b6ae522
DJ
9021 printf (", ");
9022 printf ("r14");
9023 }
9024 printf ("}");
9025 }
9026 else if (op == 0xb0)
9027 printf (_(" finish"));
9028 else if (op == 0xb1)
9029 {
9030 GET_OP (op2);
9031 if (op2 == 0 || (op2 & 0xf0) != 0)
9032 printf (_("[Spare]"));
9033 else
9034 {
9035 unsigned int mask = op2 & 0x0f;
32ec8896 9036 bfd_boolean first = TRUE;
0b6ae522 9037 int i;
61865e30 9038
0b6ae522
DJ
9039 printf ("pop {");
9040 for (i = 0; i < 12; i++)
9041 if (mask & (1 << i))
9042 {
9043 if (first)
32ec8896 9044 first = FALSE;
0b6ae522
DJ
9045 else
9046 printf (", ");
9047 printf ("r%d", i);
9048 }
9049 printf ("}");
9050 }
9051 }
9052 else if (op == 0xb2)
9053 {
b115cf96 9054 unsigned char buf[9];
0b6ae522
DJ
9055 unsigned int i, len;
9056 unsigned long offset;
61865e30 9057
b115cf96 9058 for (i = 0; i < sizeof (buf); i++)
0b6ae522
DJ
9059 {
9060 GET_OP (buf[i]);
9061 if ((buf[i] & 0x80) == 0)
9062 break;
9063 }
4082ef84 9064 if (i == sizeof (buf))
32ec8896 9065 {
27a45f42 9066 error (_("corrupt change to vsp\n"));
32ec8896
NC
9067 res = FALSE;
9068 }
4082ef84
NC
9069 else
9070 {
cd30bcef 9071 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
4082ef84
NC
9072 assert (len == i + 1);
9073 offset = offset * 4 + 0x204;
9074 printf ("vsp = vsp + %ld", offset);
9075 }
0b6ae522 9076 }
61865e30 9077 else if (op == 0xb3 || op == 0xc8 || op == 0xc9)
0b6ae522 9078 {
61865e30
NC
9079 unsigned int first, last;
9080
9081 GET_OP (op2);
9082 first = op2 >> 4;
9083 last = op2 & 0x0f;
9084 if (op == 0xc8)
9085 first = first + 16;
9086 printf ("pop {D%d", first);
9087 if (last)
9088 printf ("-D%d", first + last);
9089 printf ("}");
9090 }
9091 else if ((op & 0xf8) == 0xb8 || (op & 0xf8) == 0xd0)
9092 {
9093 unsigned int count = op & 0x07;
9094
9095 printf ("pop {D8");
9096 if (count)
9097 printf ("-D%d", 8 + count);
9098 printf ("}");
9099 }
9100 else if (op >= 0xc0 && op <= 0xc5)
9101 {
9102 unsigned int count = op & 0x07;
9103
9104 printf (" pop {wR10");
9105 if (count)
9106 printf ("-wR%d", 10 + count);
9107 printf ("}");
9108 }
9109 else if (op == 0xc6)
9110 {
9111 unsigned int first, last;
9112
9113 GET_OP (op2);
9114 first = op2 >> 4;
9115 last = op2 & 0x0f;
9116 printf ("pop {wR%d", first);
9117 if (last)
9118 printf ("-wR%d", first + last);
9119 printf ("}");
9120 }
9121 else if (op == 0xc7)
9122 {
9123 GET_OP (op2);
9124 if (op2 == 0 || (op2 & 0xf0) != 0)
9125 printf (_("[Spare]"));
0b6ae522
DJ
9126 else
9127 {
61865e30 9128 unsigned int mask = op2 & 0x0f;
32ec8896 9129 bfd_boolean first = TRUE;
61865e30
NC
9130 int i;
9131
9132 printf ("pop {");
9133 for (i = 0; i < 4; i++)
9134 if (mask & (1 << i))
9135 {
9136 if (first)
32ec8896 9137 first = FALSE;
61865e30
NC
9138 else
9139 printf (", ");
9140 printf ("wCGR%d", i);
9141 }
9142 printf ("}");
0b6ae522
DJ
9143 }
9144 }
61865e30 9145 else
32ec8896
NC
9146 {
9147 printf (_(" [unsupported opcode]"));
9148 res = FALSE;
9149 }
9150
0b6ae522
DJ
9151 printf ("\n");
9152 }
32ec8896
NC
9153
9154 return res;
fa197c1c
PB
9155}
9156
32ec8896 9157static bfd_boolean
dda8d76d
NC
9158decode_tic6x_unwind_bytecode (Filedata * filedata,
9159 struct arm_unw_aux_info * aux,
948f632f
DA
9160 unsigned int word,
9161 unsigned int remaining,
9162 unsigned int more_words,
9163 bfd_vma data_offset,
9164 Elf_Internal_Shdr * data_sec,
9165 struct arm_section * data_arm_sec)
fa197c1c
PB
9166{
9167 struct absaddr addr;
9168
9169 /* Decode the unwinding instructions. */
9170 while (1)
9171 {
9172 unsigned int op, op2;
9173
9174 ADVANCE;
9175 if (remaining == 0)
9176 break;
9177 remaining--;
9178 op = word >> 24;
9179 word <<= 8;
9180
9cf03b7e 9181 printf (" 0x%02x ", op);
fa197c1c
PB
9182
9183 if ((op & 0xc0) == 0x00)
9184 {
9185 int offset = ((op & 0x3f) << 3) + 8;
9cf03b7e 9186 printf (" sp = sp + %d", offset);
fa197c1c
PB
9187 }
9188 else if ((op & 0xc0) == 0x80)
9189 {
9190 GET_OP (op2);
9191 if (op == 0x80 && op2 == 0)
9192 printf (_("Refuse to unwind"));
9193 else
9194 {
9195 unsigned int mask = ((op & 0x1f) << 8) | op2;
9196 if (op & 0x20)
9197 printf ("pop compact {");
9198 else
9199 printf ("pop {");
9200
9201 decode_tic6x_unwind_regmask (mask);
9202 printf("}");
9203 }
9204 }
9205 else if ((op & 0xf0) == 0xc0)
9206 {
9207 unsigned int reg;
9208 unsigned int nregs;
9209 unsigned int i;
9210 const char *name;
a734115a
NC
9211 struct
9212 {
32ec8896
NC
9213 unsigned int offset;
9214 unsigned int reg;
fa197c1c
PB
9215 } regpos[16];
9216
9217 /* Scan entire instruction first so that GET_OP output is not
9218 interleaved with disassembly. */
9219 nregs = 0;
9220 for (i = 0; nregs < (op & 0xf); i++)
9221 {
9222 GET_OP (op2);
9223 reg = op2 >> 4;
9224 if (reg != 0xf)
9225 {
9226 regpos[nregs].offset = i * 2;
9227 regpos[nregs].reg = reg;
9228 nregs++;
9229 }
9230
9231 reg = op2 & 0xf;
9232 if (reg != 0xf)
9233 {
9234 regpos[nregs].offset = i * 2 + 1;
9235 regpos[nregs].reg = reg;
9236 nregs++;
9237 }
9238 }
9239
9240 printf (_("pop frame {"));
18344509 9241 if (nregs == 0)
fa197c1c 9242 {
18344509
NC
9243 printf (_("*corrupt* - no registers specified"));
9244 }
9245 else
9246 {
9247 reg = nregs - 1;
9248 for (i = i * 2; i > 0; i--)
fa197c1c 9249 {
18344509
NC
9250 if (regpos[reg].offset == i - 1)
9251 {
9252 name = tic6x_unwind_regnames[regpos[reg].reg];
9253 if (reg > 0)
9254 reg--;
9255 }
9256 else
9257 name = _("[pad]");
fa197c1c 9258
18344509
NC
9259 fputs (name, stdout);
9260 if (i > 1)
9261 printf (", ");
9262 }
fa197c1c
PB
9263 }
9264
9265 printf ("}");
9266 }
9267 else if (op == 0xd0)
9268 printf (" MOV FP, SP");
9269 else if (op == 0xd1)
9270 printf (" __c6xabi_pop_rts");
9271 else if (op == 0xd2)
9272 {
9273 unsigned char buf[9];
9274 unsigned int i, len;
9275 unsigned long offset;
a734115a 9276
fa197c1c
PB
9277 for (i = 0; i < sizeof (buf); i++)
9278 {
9279 GET_OP (buf[i]);
9280 if ((buf[i] & 0x80) == 0)
9281 break;
9282 }
0eff7165
NC
9283 /* PR 17531: file: id:000001,src:001906+004739,op:splice,rep:2. */
9284 if (i == sizeof (buf))
9285 {
0eff7165 9286 warn (_("Corrupt stack pointer adjustment detected\n"));
32ec8896 9287 return FALSE;
0eff7165 9288 }
948f632f 9289
cd30bcef 9290 offset = read_leb128 (buf, buf + i + 1, FALSE, &len, NULL);
fa197c1c
PB
9291 assert (len == i + 1);
9292 offset = offset * 8 + 0x408;
9293 printf (_("sp = sp + %ld"), offset);
9294 }
9295 else if ((op & 0xf0) == 0xe0)
9296 {
9297 if ((op & 0x0f) == 7)
9298 printf (" RETURN");
9299 else
9300 printf (" MV %s, B3", tic6x_unwind_regnames[op & 0x0f]);
9301 }
9302 else
9303 {
9304 printf (_(" [unsupported opcode]"));
9305 }
9306 putchar ('\n');
9307 }
32ec8896
NC
9308
9309 return TRUE;
fa197c1c
PB
9310}
9311
9312static bfd_vma
dda8d76d 9313arm_expand_prel31 (Filedata * filedata, bfd_vma word, bfd_vma where)
fa197c1c
PB
9314{
9315 bfd_vma offset;
9316
9317 offset = word & 0x7fffffff;
9318 if (offset & 0x40000000)
9319 offset |= ~ (bfd_vma) 0x7fffffff;
9320
dda8d76d 9321 if (filedata->file_header.e_machine == EM_TI_C6000)
fa197c1c
PB
9322 offset <<= 1;
9323
9324 return offset + where;
9325}
9326
32ec8896 9327static bfd_boolean
dda8d76d
NC
9328decode_arm_unwind (Filedata * filedata,
9329 struct arm_unw_aux_info * aux,
1b31d05e
NC
9330 unsigned int word,
9331 unsigned int remaining,
9332 bfd_vma data_offset,
9333 Elf_Internal_Shdr * data_sec,
9334 struct arm_section * data_arm_sec)
fa197c1c
PB
9335{
9336 int per_index;
9337 unsigned int more_words = 0;
37e14bc3 9338 struct absaddr addr;
1b31d05e 9339 bfd_vma sym_name = (bfd_vma) -1;
97953bab 9340 bfd_boolean res = TRUE;
fa197c1c
PB
9341
9342 if (remaining == 0)
9343 {
1b31d05e
NC
9344 /* Fetch the first word.
9345 Note - when decoding an object file the address extracted
9346 here will always be 0. So we also pass in the sym_name
9347 parameter so that we can find the symbol associated with
9348 the personality routine. */
dda8d76d 9349 if (! get_unwind_section_word (filedata, aux, data_arm_sec, data_sec, data_offset,
1b31d05e 9350 & word, & addr, & sym_name))
32ec8896 9351 return FALSE;
1b31d05e 9352
fa197c1c
PB
9353 remaining = 4;
9354 }
c93dbb25
CZ
9355 else
9356 {
9357 addr.section = SHN_UNDEF;
9358 addr.offset = 0;
9359 }
fa197c1c
PB
9360
9361 if ((word & 0x80000000) == 0)
9362 {
9363 /* Expand prel31 for personality routine. */
9364 bfd_vma fn;
9365 const char *procname;
9366
dda8d76d 9367 fn = arm_expand_prel31 (filedata, word, data_sec->sh_addr + data_offset);
fa197c1c 9368 printf (_(" Personality routine: "));
1b31d05e
NC
9369 if (fn == 0
9370 && addr.section == SHN_UNDEF && addr.offset == 0
9371 && sym_name != (bfd_vma) -1 && sym_name < aux->strtab_size)
9372 {
9373 procname = aux->strtab + sym_name;
9374 print_vma (fn, PREFIX_HEX);
9375 if (procname)
9376 {
9377 fputs (" <", stdout);
9378 fputs (procname, stdout);
9379 fputc ('>', stdout);
9380 }
9381 }
9382 else
dda8d76d 9383 procname = arm_print_vma_and_name (filedata, aux, fn, addr);
fa197c1c
PB
9384 fputc ('\n', stdout);
9385
9386 /* The GCC personality routines use the standard compact
9387 encoding, starting with one byte giving the number of
9388 words. */
9389 if (procname != NULL
9390 && (const_strneq (procname, "__gcc_personality_v0")
9391 || const_strneq (procname, "__gxx_personality_v0")
9392 || const_strneq (procname, "__gcj_personality_v0")
9393 || const_strneq (procname, "__gnu_objc_personality_v0")))
9394 {
9395 remaining = 0;
9396 more_words = 1;
9397 ADVANCE;
9398 if (!remaining)
9399 {
9400 printf (_(" [Truncated data]\n"));
32ec8896 9401 return FALSE;
fa197c1c
PB
9402 }
9403 more_words = word >> 24;
9404 word <<= 8;
9405 remaining--;
9406 per_index = -1;
9407 }
9408 else
32ec8896 9409 return TRUE;
fa197c1c
PB
9410 }
9411 else
9412 {
1b31d05e 9413 /* ARM EHABI Section 6.3:
0b4362b0 9414
1b31d05e 9415 An exception-handling table entry for the compact model looks like:
0b4362b0 9416
1b31d05e
NC
9417 31 30-28 27-24 23-0
9418 -- ----- ----- ----
9419 1 0 index Data for personalityRoutine[index] */
9420
dda8d76d 9421 if (filedata->file_header.e_machine == EM_ARM
1b31d05e 9422 && (word & 0x70000000))
32ec8896
NC
9423 {
9424 warn (_("Corrupt ARM compact model table entry: %x \n"), word);
9425 res = FALSE;
9426 }
1b31d05e 9427
fa197c1c 9428 per_index = (word >> 24) & 0x7f;
1b31d05e 9429 printf (_(" Compact model index: %d\n"), per_index);
fa197c1c
PB
9430 if (per_index == 0)
9431 {
9432 more_words = 0;
9433 word <<= 8;
9434 remaining--;
9435 }
9436 else if (per_index < 3)
9437 {
9438 more_words = (word >> 16) & 0xff;
9439 word <<= 16;
9440 remaining -= 2;
9441 }
9442 }
9443
dda8d76d 9444 switch (filedata->file_header.e_machine)
fa197c1c
PB
9445 {
9446 case EM_ARM:
9447 if (per_index < 3)
9448 {
dda8d76d 9449 if (! decode_arm_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9450 data_offset, data_sec, data_arm_sec))
9451 res = FALSE;
fa197c1c
PB
9452 }
9453 else
1b31d05e
NC
9454 {
9455 warn (_("Unknown ARM compact model index encountered\n"));
9456 printf (_(" [reserved]\n"));
32ec8896 9457 res = FALSE;
1b31d05e 9458 }
fa197c1c
PB
9459 break;
9460
9461 case EM_TI_C6000:
9462 if (per_index < 3)
9463 {
dda8d76d 9464 if (! decode_tic6x_unwind_bytecode (filedata, aux, word, remaining, more_words,
32ec8896
NC
9465 data_offset, data_sec, data_arm_sec))
9466 res = FALSE;
fa197c1c
PB
9467 }
9468 else if (per_index < 5)
9469 {
9470 if (((word >> 17) & 0x7f) == 0x7f)
9471 printf (_(" Restore stack from frame pointer\n"));
9472 else
9473 printf (_(" Stack increment %d\n"), (word >> 14) & 0x1fc);
9474 printf (_(" Registers restored: "));
9475 if (per_index == 4)
9476 printf (" (compact) ");
9477 decode_tic6x_unwind_regmask ((word >> 4) & 0x1fff);
9478 putchar ('\n');
9479 printf (_(" Return register: %s\n"),
9480 tic6x_unwind_regnames[word & 0xf]);
9481 }
9482 else
1b31d05e 9483 printf (_(" [reserved (%d)]\n"), per_index);
fa197c1c
PB
9484 break;
9485
9486 default:
74e1a04b 9487 error (_("Unsupported architecture type %d encountered when decoding unwind table\n"),
dda8d76d 9488 filedata->file_header.e_machine);
32ec8896 9489 res = FALSE;
fa197c1c 9490 }
0b6ae522
DJ
9491
9492 /* Decode the descriptors. Not implemented. */
32ec8896
NC
9493
9494 return res;
0b6ae522
DJ
9495}
9496
32ec8896 9497static bfd_boolean
dda8d76d
NC
9498dump_arm_unwind (Filedata * filedata,
9499 struct arm_unw_aux_info * aux,
9500 Elf_Internal_Shdr * exidx_sec)
0b6ae522
DJ
9501{
9502 struct arm_section exidx_arm_sec, extab_arm_sec;
9503 unsigned int i, exidx_len;
948f632f 9504 unsigned long j, nfuns;
32ec8896 9505 bfd_boolean res = TRUE;
0b6ae522
DJ
9506
9507 memset (&exidx_arm_sec, 0, sizeof (exidx_arm_sec));
9508 memset (&extab_arm_sec, 0, sizeof (extab_arm_sec));
9509 exidx_len = exidx_sec->sh_size / 8;
9510
948f632f
DA
9511 aux->funtab = xmalloc (aux->nsyms * sizeof (Elf_Internal_Sym));
9512 for (nfuns = 0, j = 0; j < aux->nsyms; j++)
9513 if (aux->symtab[j].st_value && ELF_ST_TYPE (aux->symtab[j].st_info) == STT_FUNC)
9514 aux->funtab[nfuns++] = aux->symtab[j];
9515 aux->nfuns = nfuns;
9516 qsort (aux->funtab, aux->nfuns, sizeof (Elf_Internal_Sym), symcmp);
9517
0b6ae522
DJ
9518 for (i = 0; i < exidx_len; i++)
9519 {
9520 unsigned int exidx_fn, exidx_entry;
9521 struct absaddr fn_addr, entry_addr;
9522 bfd_vma fn;
9523
9524 fputc ('\n', stdout);
9525
dda8d76d 9526 if (! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9527 8 * i, & exidx_fn, & fn_addr, NULL)
dda8d76d 9528 || ! get_unwind_section_word (filedata, aux, & exidx_arm_sec, exidx_sec,
1b31d05e 9529 8 * i + 4, & exidx_entry, & entry_addr, NULL))
0b6ae522 9530 {
948f632f 9531 free (aux->funtab);
1b31d05e
NC
9532 arm_free_section (& exidx_arm_sec);
9533 arm_free_section (& extab_arm_sec);
32ec8896 9534 return FALSE;
0b6ae522
DJ
9535 }
9536
83c257ca
NC
9537 /* ARM EHABI, Section 5:
9538 An index table entry consists of 2 words.
9539 The first word contains a prel31 offset to the start of a function, with bit 31 clear. */
9540 if (exidx_fn & 0x80000000)
32ec8896
NC
9541 {
9542 warn (_("corrupt index table entry: %x\n"), exidx_fn);
9543 res = FALSE;
9544 }
83c257ca 9545
dda8d76d 9546 fn = arm_expand_prel31 (filedata, exidx_fn, exidx_sec->sh_addr + 8 * i);
0b6ae522 9547
dda8d76d 9548 arm_print_vma_and_name (filedata, aux, fn, fn_addr);
0b6ae522
DJ
9549 fputs (": ", stdout);
9550
9551 if (exidx_entry == 1)
9552 {
9553 print_vma (exidx_entry, PREFIX_HEX);
9554 fputs (" [cantunwind]\n", stdout);
9555 }
9556 else if (exidx_entry & 0x80000000)
9557 {
9558 print_vma (exidx_entry, PREFIX_HEX);
9559 fputc ('\n', stdout);
dda8d76d 9560 decode_arm_unwind (filedata, aux, exidx_entry, 4, 0, NULL, NULL);
0b6ae522
DJ
9561 }
9562 else
9563 {
8f73510c 9564 bfd_vma table, table_offset = 0;
0b6ae522
DJ
9565 Elf_Internal_Shdr *table_sec;
9566
9567 fputs ("@", stdout);
dda8d76d 9568 table = arm_expand_prel31 (filedata, exidx_entry, exidx_sec->sh_addr + 8 * i + 4);
0b6ae522
DJ
9569 print_vma (table, PREFIX_HEX);
9570 printf ("\n");
9571
9572 /* Locate the matching .ARM.extab. */
9573 if (entry_addr.section != SHN_UNDEF
dda8d76d 9574 && entry_addr.section < filedata->file_header.e_shnum)
0b6ae522 9575 {
dda8d76d 9576 table_sec = filedata->section_headers + entry_addr.section;
0b6ae522 9577 table_offset = entry_addr.offset;
1a915552
NC
9578 /* PR 18879 */
9579 if (table_offset > table_sec->sh_size
9580 || ((bfd_signed_vma) table_offset) < 0)
9581 {
9582 warn (_("Unwind entry contains corrupt offset (0x%lx) into section %s\n"),
9583 (unsigned long) table_offset,
dda8d76d 9584 printable_section_name (filedata, table_sec));
32ec8896 9585 res = FALSE;
1a915552
NC
9586 continue;
9587 }
0b6ae522
DJ
9588 }
9589 else
9590 {
dda8d76d 9591 table_sec = find_section_by_address (filedata, table);
0b6ae522
DJ
9592 if (table_sec != NULL)
9593 table_offset = table - table_sec->sh_addr;
9594 }
32ec8896 9595
0b6ae522
DJ
9596 if (table_sec == NULL)
9597 {
9598 warn (_("Could not locate .ARM.extab section containing 0x%lx.\n"),
9599 (unsigned long) table);
32ec8896 9600 res = FALSE;
0b6ae522
DJ
9601 continue;
9602 }
32ec8896 9603
dda8d76d 9604 if (! decode_arm_unwind (filedata, aux, 0, 0, table_offset, table_sec,
32ec8896
NC
9605 &extab_arm_sec))
9606 res = FALSE;
0b6ae522
DJ
9607 }
9608 }
9609
9610 printf ("\n");
9611
948f632f 9612 free (aux->funtab);
0b6ae522
DJ
9613 arm_free_section (&exidx_arm_sec);
9614 arm_free_section (&extab_arm_sec);
32ec8896
NC
9615
9616 return res;
0b6ae522
DJ
9617}
9618
fa197c1c 9619/* Used for both ARM and C6X unwinding tables. */
1b31d05e 9620
32ec8896 9621static bfd_boolean
dda8d76d 9622arm_process_unwind (Filedata * filedata)
0b6ae522
DJ
9623{
9624 struct arm_unw_aux_info aux;
9625 Elf_Internal_Shdr *unwsec = NULL;
0b6ae522
DJ
9626 Elf_Internal_Shdr *sec;
9627 unsigned long i;
fa197c1c 9628 unsigned int sec_type;
32ec8896 9629 bfd_boolean res = TRUE;
0b6ae522 9630
dda8d76d 9631 switch (filedata->file_header.e_machine)
fa197c1c
PB
9632 {
9633 case EM_ARM:
9634 sec_type = SHT_ARM_EXIDX;
9635 break;
9636
9637 case EM_TI_C6000:
9638 sec_type = SHT_C6000_UNWIND;
9639 break;
9640
0b4362b0 9641 default:
74e1a04b 9642 error (_("Unsupported architecture type %d encountered when processing unwind table\n"),
dda8d76d 9643 filedata->file_header.e_machine);
32ec8896 9644 return FALSE;
fa197c1c
PB
9645 }
9646
dda8d76d 9647 if (filedata->string_table == NULL)
32ec8896 9648 return FALSE;
1b31d05e
NC
9649
9650 memset (& aux, 0, sizeof (aux));
dda8d76d 9651 aux.filedata = filedata;
0b6ae522 9652
dda8d76d 9653 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
0b6ae522 9654 {
28d13567 9655 if (sec->sh_type == SHT_SYMTAB)
0b6ae522 9656 {
28d13567 9657 if (aux.symtab)
74e1a04b 9658 {
28d13567
AM
9659 error (_("Multiple symbol tables encountered\n"));
9660 free (aux.symtab);
9661 aux.symtab = NULL;
74e1a04b 9662 free (aux.strtab);
28d13567 9663 aux.strtab = NULL;
74e1a04b 9664 }
28d13567
AM
9665 if (!get_symtab (filedata, sec, &aux.symtab, &aux.nsyms,
9666 &aux.strtab, &aux.strtab_size))
9667 return FALSE;
0b6ae522 9668 }
fa197c1c 9669 else if (sec->sh_type == sec_type)
0b6ae522
DJ
9670 unwsec = sec;
9671 }
9672
1b31d05e 9673 if (unwsec == NULL)
0b6ae522 9674 printf (_("\nThere are no unwind sections in this file.\n"));
1b31d05e 9675 else
dda8d76d 9676 for (i = 0, sec = filedata->section_headers; i < filedata->file_header.e_shnum; ++i, ++sec)
1b31d05e
NC
9677 {
9678 if (sec->sh_type == sec_type)
9679 {
d3a49aa8
AM
9680 unsigned long num_unwind = sec->sh_size / (2 * eh_addr_size);
9681 printf (ngettext ("\nUnwind section '%s' at offset 0x%lx "
9682 "contains %lu entry:\n",
9683 "\nUnwind section '%s' at offset 0x%lx "
9684 "contains %lu entries:\n",
9685 num_unwind),
dda8d76d 9686 printable_section_name (filedata, sec),
1b31d05e 9687 (unsigned long) sec->sh_offset,
d3a49aa8 9688 num_unwind);
0b6ae522 9689
dda8d76d 9690 if (! dump_arm_unwind (filedata, &aux, sec))
32ec8896 9691 res = FALSE;
1b31d05e
NC
9692 }
9693 }
0b6ae522 9694
9db70fc3
AM
9695 free (aux.symtab);
9696 free ((char *) aux.strtab);
32ec8896
NC
9697
9698 return res;
0b6ae522
DJ
9699}
9700
32ec8896 9701static bfd_boolean
dda8d76d 9702process_unwind (Filedata * filedata)
57346661 9703{
2cf0635d
NC
9704 struct unwind_handler
9705 {
32ec8896 9706 unsigned int machtype;
dda8d76d 9707 bfd_boolean (* handler)(Filedata *);
2cf0635d
NC
9708 } handlers[] =
9709 {
0b6ae522 9710 { EM_ARM, arm_process_unwind },
57346661
AM
9711 { EM_IA_64, ia64_process_unwind },
9712 { EM_PARISC, hppa_process_unwind },
fa197c1c 9713 { EM_TI_C6000, arm_process_unwind },
32ec8896 9714 { 0, NULL }
57346661
AM
9715 };
9716 int i;
9717
9718 if (!do_unwind)
32ec8896 9719 return TRUE;
57346661
AM
9720
9721 for (i = 0; handlers[i].handler != NULL; i++)
dda8d76d
NC
9722 if (filedata->file_header.e_machine == handlers[i].machtype)
9723 return handlers[i].handler (filedata);
57346661 9724
1b31d05e 9725 printf (_("\nThe decoding of unwind sections for machine type %s is not currently supported.\n"),
dda8d76d 9726 get_machine_name (filedata->file_header.e_machine));
32ec8896 9727 return TRUE;
57346661
AM
9728}
9729
37c18eed
SD
9730static void
9731dynamic_section_aarch64_val (Elf_Internal_Dyn * entry)
9732{
9733 switch (entry->d_tag)
9734 {
9735 case DT_AARCH64_BTI_PLT:
1dbade74 9736 case DT_AARCH64_PAC_PLT:
37c18eed
SD
9737 break;
9738 default:
9739 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9740 break;
9741 }
9742 putchar ('\n');
9743}
9744
252b5132 9745static void
978c4450 9746dynamic_section_mips_val (Filedata * filedata, Elf_Internal_Dyn * entry)
252b5132
RH
9747{
9748 switch (entry->d_tag)
9749 {
9750 case DT_MIPS_FLAGS:
9751 if (entry->d_un.d_val == 0)
4b68bca3 9752 printf (_("NONE"));
252b5132
RH
9753 else
9754 {
9755 static const char * opts[] =
9756 {
9757 "QUICKSTART", "NOTPOT", "NO_LIBRARY_REPLACEMENT",
9758 "NO_MOVE", "SGI_ONLY", "GUARANTEE_INIT", "DELTA_C_PLUS_PLUS",
9759 "GUARANTEE_START_INIT", "PIXIE", "DEFAULT_DELAY_LOAD",
9760 "REQUICKSTART", "REQUICKSTARTED", "CORD", "NO_UNRES_UNDEF",
9761 "RLD_ORDER_SAFE"
9762 };
9763 unsigned int cnt;
32ec8896 9764 bfd_boolean first = TRUE;
2b692964 9765
60bca95a 9766 for (cnt = 0; cnt < ARRAY_SIZE (opts); ++cnt)
252b5132
RH
9767 if (entry->d_un.d_val & (1 << cnt))
9768 {
9769 printf ("%s%s", first ? "" : " ", opts[cnt]);
32ec8896 9770 first = FALSE;
252b5132 9771 }
252b5132
RH
9772 }
9773 break;
103f02d3 9774
252b5132 9775 case DT_MIPS_IVERSION:
978c4450
AM
9776 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
9777 printf (_("Interface Version: %s"),
9778 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 9779 else
76ca31c0
NC
9780 {
9781 char buf[40];
9782 sprintf_vma (buf, entry->d_un.d_ptr);
9783 /* Note: coded this way so that there is a single string for translation. */
9784 printf (_("<corrupt: %s>"), buf);
9785 }
252b5132 9786 break;
103f02d3 9787
252b5132
RH
9788 case DT_MIPS_TIME_STAMP:
9789 {
d5b07ef4 9790 char timebuf[128];
2cf0635d 9791 struct tm * tmp;
91d6fa6a 9792 time_t atime = entry->d_un.d_val;
82b1b41b 9793
91d6fa6a 9794 tmp = gmtime (&atime);
82b1b41b
NC
9795 /* PR 17531: file: 6accc532. */
9796 if (tmp == NULL)
9797 snprintf (timebuf, sizeof (timebuf), _("<corrupt>"));
9798 else
9799 snprintf (timebuf, sizeof (timebuf), "%04u-%02u-%02uT%02u:%02u:%02u",
9800 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
9801 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
4b68bca3 9802 printf (_("Time Stamp: %s"), timebuf);
252b5132
RH
9803 }
9804 break;
103f02d3 9805
252b5132
RH
9806 case DT_MIPS_RLD_VERSION:
9807 case DT_MIPS_LOCAL_GOTNO:
9808 case DT_MIPS_CONFLICTNO:
9809 case DT_MIPS_LIBLISTNO:
9810 case DT_MIPS_SYMTABNO:
9811 case DT_MIPS_UNREFEXTNO:
9812 case DT_MIPS_HIPAGENO:
9813 case DT_MIPS_DELTA_CLASS_NO:
9814 case DT_MIPS_DELTA_INSTANCE_NO:
9815 case DT_MIPS_DELTA_RELOC_NO:
9816 case DT_MIPS_DELTA_SYM_NO:
9817 case DT_MIPS_DELTA_CLASSSYM_NO:
9818 case DT_MIPS_COMPACT_SIZE:
c69075ac 9819 print_vma (entry->d_un.d_val, DEC);
252b5132 9820 break;
103f02d3 9821
f16a9783 9822 case DT_MIPS_XHASH:
978c4450
AM
9823 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
9824 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
f16a9783
MS
9825 /* Falls through. */
9826
103f02d3 9827 default:
4b68bca3 9828 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
103f02d3 9829 }
4b68bca3 9830 putchar ('\n');
103f02d3
UD
9831}
9832
103f02d3 9833static void
2cf0635d 9834dynamic_section_parisc_val (Elf_Internal_Dyn * entry)
103f02d3
UD
9835{
9836 switch (entry->d_tag)
9837 {
9838 case DT_HP_DLD_FLAGS:
9839 {
9840 static struct
9841 {
9842 long int bit;
2cf0635d 9843 const char * str;
5e220199
NC
9844 }
9845 flags[] =
9846 {
9847 { DT_HP_DEBUG_PRIVATE, "HP_DEBUG_PRIVATE" },
9848 { DT_HP_DEBUG_CALLBACK, "HP_DEBUG_CALLBACK" },
9849 { DT_HP_DEBUG_CALLBACK_BOR, "HP_DEBUG_CALLBACK_BOR" },
9850 { DT_HP_NO_ENVVAR, "HP_NO_ENVVAR" },
9851 { DT_HP_BIND_NOW, "HP_BIND_NOW" },
9852 { DT_HP_BIND_NONFATAL, "HP_BIND_NONFATAL" },
9853 { DT_HP_BIND_VERBOSE, "HP_BIND_VERBOSE" },
9854 { DT_HP_BIND_RESTRICTED, "HP_BIND_RESTRICTED" },
9855 { DT_HP_BIND_SYMBOLIC, "HP_BIND_SYMBOLIC" },
9856 { DT_HP_RPATH_FIRST, "HP_RPATH_FIRST" },
eec8f817
DA
9857 { DT_HP_BIND_DEPTH_FIRST, "HP_BIND_DEPTH_FIRST" },
9858 { DT_HP_GST, "HP_GST" },
9859 { DT_HP_SHLIB_FIXED, "HP_SHLIB_FIXED" },
9860 { DT_HP_MERGE_SHLIB_SEG, "HP_MERGE_SHLIB_SEG" },
9861 { DT_HP_NODELETE, "HP_NODELETE" },
9862 { DT_HP_GROUP, "HP_GROUP" },
9863 { DT_HP_PROTECT_LINKAGE_TABLE, "HP_PROTECT_LINKAGE_TABLE" }
5e220199 9864 };
32ec8896 9865 bfd_boolean first = TRUE;
5e220199 9866 size_t cnt;
f7a99963 9867 bfd_vma val = entry->d_un.d_val;
103f02d3 9868
60bca95a 9869 for (cnt = 0; cnt < ARRAY_SIZE (flags); ++cnt)
103f02d3 9870 if (val & flags[cnt].bit)
30800947
NC
9871 {
9872 if (! first)
9873 putchar (' ');
9874 fputs (flags[cnt].str, stdout);
32ec8896 9875 first = FALSE;
30800947
NC
9876 val ^= flags[cnt].bit;
9877 }
76da6bbe 9878
103f02d3 9879 if (val != 0 || first)
f7a99963
NC
9880 {
9881 if (! first)
9882 putchar (' ');
9883 print_vma (val, HEX);
9884 }
103f02d3
UD
9885 }
9886 break;
76da6bbe 9887
252b5132 9888 default:
f7a99963
NC
9889 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9890 break;
252b5132 9891 }
35b1837e 9892 putchar ('\n');
252b5132
RH
9893}
9894
28f997cf
TG
9895#ifdef BFD64
9896
9897/* VMS vs Unix time offset and factor. */
9898
9899#define VMS_EPOCH_OFFSET 35067168000000000LL
9900#define VMS_GRANULARITY_FACTOR 10000000
dccc31de
AM
9901#ifndef INT64_MIN
9902#define INT64_MIN (-9223372036854775807LL - 1)
9903#endif
28f997cf
TG
9904
9905/* Display a VMS time in a human readable format. */
9906
9907static void
9908print_vms_time (bfd_int64_t vmstime)
9909{
dccc31de 9910 struct tm *tm = NULL;
28f997cf
TG
9911 time_t unxtime;
9912
dccc31de
AM
9913 if (vmstime >= INT64_MIN + VMS_EPOCH_OFFSET)
9914 {
9915 vmstime = (vmstime - VMS_EPOCH_OFFSET) / VMS_GRANULARITY_FACTOR;
9916 unxtime = vmstime;
9917 if (unxtime == vmstime)
9918 tm = gmtime (&unxtime);
9919 }
9920 if (tm != NULL)
9921 printf ("%04u-%02u-%02uT%02u:%02u:%02u",
9922 tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
9923 tm->tm_hour, tm->tm_min, tm->tm_sec);
28f997cf
TG
9924}
9925#endif /* BFD64 */
9926
ecc51f48 9927static void
2cf0635d 9928dynamic_section_ia64_val (Elf_Internal_Dyn * entry)
ecc51f48
NC
9929{
9930 switch (entry->d_tag)
9931 {
0de14b54 9932 case DT_IA_64_PLT_RESERVE:
bdf4d63a 9933 /* First 3 slots reserved. */
ecc51f48
NC
9934 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9935 printf (" -- ");
9936 print_vma (entry->d_un.d_ptr + (3 * 8), PREFIX_HEX);
bdf4d63a
JJ
9937 break;
9938
28f997cf
TG
9939 case DT_IA_64_VMS_LINKTIME:
9940#ifdef BFD64
9941 print_vms_time (entry->d_un.d_val);
9942#endif
9943 break;
9944
9945 case DT_IA_64_VMS_LNKFLAGS:
9946 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9947 if (entry->d_un.d_val & VMS_LF_CALL_DEBUG)
9948 printf (" CALL_DEBUG");
9949 if (entry->d_un.d_val & VMS_LF_NOP0BUFS)
9950 printf (" NOP0BUFS");
9951 if (entry->d_un.d_val & VMS_LF_P0IMAGE)
9952 printf (" P0IMAGE");
9953 if (entry->d_un.d_val & VMS_LF_MKTHREADS)
9954 printf (" MKTHREADS");
9955 if (entry->d_un.d_val & VMS_LF_UPCALLS)
9956 printf (" UPCALLS");
9957 if (entry->d_un.d_val & VMS_LF_IMGSTA)
9958 printf (" IMGSTA");
9959 if (entry->d_un.d_val & VMS_LF_INITIALIZE)
9960 printf (" INITIALIZE");
9961 if (entry->d_un.d_val & VMS_LF_MAIN)
9962 printf (" MAIN");
9963 if (entry->d_un.d_val & VMS_LF_EXE_INIT)
9964 printf (" EXE_INIT");
9965 if (entry->d_un.d_val & VMS_LF_TBK_IN_IMG)
9966 printf (" TBK_IN_IMG");
9967 if (entry->d_un.d_val & VMS_LF_DBG_IN_IMG)
9968 printf (" DBG_IN_IMG");
9969 if (entry->d_un.d_val & VMS_LF_TBK_IN_DSF)
9970 printf (" TBK_IN_DSF");
9971 if (entry->d_un.d_val & VMS_LF_DBG_IN_DSF)
9972 printf (" DBG_IN_DSF");
9973 if (entry->d_un.d_val & VMS_LF_SIGNATURES)
9974 printf (" SIGNATURES");
9975 if (entry->d_un.d_val & VMS_LF_REL_SEG_OFF)
9976 printf (" REL_SEG_OFF");
9977 break;
9978
bdf4d63a
JJ
9979 default:
9980 print_vma (entry->d_un.d_ptr, PREFIX_HEX);
9981 break;
ecc51f48 9982 }
bdf4d63a 9983 putchar ('\n');
ecc51f48
NC
9984}
9985
32ec8896 9986static bfd_boolean
dda8d76d 9987get_32bit_dynamic_section (Filedata * filedata)
252b5132 9988{
2cf0635d
NC
9989 Elf32_External_Dyn * edyn;
9990 Elf32_External_Dyn * ext;
9991 Elf_Internal_Dyn * entry;
103f02d3 9992
978c4450
AM
9993 edyn = (Elf32_External_Dyn *) get_data (NULL, filedata,
9994 filedata->dynamic_addr, 1,
9995 filedata->dynamic_size,
9996 _("dynamic section"));
a6e9f9df 9997 if (!edyn)
32ec8896 9998 return FALSE;
103f02d3 9999
071436c6
NC
10000 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10001 might not have the luxury of section headers. Look for the DT_NULL
10002 terminator to determine the number of entries. */
978c4450
AM
10003 for (ext = edyn, filedata->dynamic_nent = 0;
10004 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10005 ext++)
10006 {
978c4450 10007 filedata->dynamic_nent++;
ba2685cc
AM
10008 if (BYTE_GET (ext->d_tag) == DT_NULL)
10009 break;
10010 }
252b5132 10011
978c4450
AM
10012 filedata->dynamic_section
10013 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10014 if (filedata->dynamic_section == NULL)
252b5132 10015 {
8b73c356 10016 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10017 (unsigned long) filedata->dynamic_nent);
9ea033b2 10018 free (edyn);
32ec8896 10019 return FALSE;
9ea033b2 10020 }
252b5132 10021
978c4450
AM
10022 for (ext = edyn, entry = filedata->dynamic_section;
10023 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10024 ext++, entry++)
9ea033b2 10025 {
fb514b26
AM
10026 entry->d_tag = BYTE_GET (ext->d_tag);
10027 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10028 }
10029
9ea033b2
NC
10030 free (edyn);
10031
32ec8896 10032 return TRUE;
9ea033b2
NC
10033}
10034
32ec8896 10035static bfd_boolean
dda8d76d 10036get_64bit_dynamic_section (Filedata * filedata)
9ea033b2 10037{
2cf0635d
NC
10038 Elf64_External_Dyn * edyn;
10039 Elf64_External_Dyn * ext;
10040 Elf_Internal_Dyn * entry;
103f02d3 10041
071436c6 10042 /* Read in the data. */
978c4450
AM
10043 edyn = (Elf64_External_Dyn *) get_data (NULL, filedata,
10044 filedata->dynamic_addr, 1,
10045 filedata->dynamic_size,
10046 _("dynamic section"));
a6e9f9df 10047 if (!edyn)
32ec8896 10048 return FALSE;
103f02d3 10049
071436c6
NC
10050 /* SGI's ELF has more than one section in the DYNAMIC segment, and we
10051 might not have the luxury of section headers. Look for the DT_NULL
10052 terminator to determine the number of entries. */
978c4450 10053 for (ext = edyn, filedata->dynamic_nent = 0;
53c3012c 10054 /* PR 17533 file: 033-67080-0.004 - do not read past end of buffer. */
978c4450 10055 (char *) (ext + 1) <= (char *) edyn + filedata->dynamic_size;
ba2685cc
AM
10056 ext++)
10057 {
978c4450 10058 filedata->dynamic_nent++;
66543521 10059 if (BYTE_GET (ext->d_tag) == DT_NULL)
ba2685cc
AM
10060 break;
10061 }
252b5132 10062
978c4450
AM
10063 filedata->dynamic_section
10064 = (Elf_Internal_Dyn *) cmalloc (filedata->dynamic_nent, sizeof (* entry));
10065 if (filedata->dynamic_section == NULL)
252b5132 10066 {
8b73c356 10067 error (_("Out of memory allocating space for %lu dynamic entries\n"),
978c4450 10068 (unsigned long) filedata->dynamic_nent);
252b5132 10069 free (edyn);
32ec8896 10070 return FALSE;
252b5132
RH
10071 }
10072
071436c6 10073 /* Convert from external to internal formats. */
978c4450
AM
10074 for (ext = edyn, entry = filedata->dynamic_section;
10075 entry < filedata->dynamic_section + filedata->dynamic_nent;
fb514b26 10076 ext++, entry++)
252b5132 10077 {
66543521
AM
10078 entry->d_tag = BYTE_GET (ext->d_tag);
10079 entry->d_un.d_val = BYTE_GET (ext->d_un.d_val);
252b5132
RH
10080 }
10081
10082 free (edyn);
10083
32ec8896 10084 return TRUE;
9ea033b2
NC
10085}
10086
e9e44622
JJ
10087static void
10088print_dynamic_flags (bfd_vma flags)
d1133906 10089{
32ec8896 10090 bfd_boolean first = TRUE;
13ae64f3 10091
d1133906
NC
10092 while (flags)
10093 {
10094 bfd_vma flag;
10095
10096 flag = flags & - flags;
10097 flags &= ~ flag;
10098
e9e44622 10099 if (first)
32ec8896 10100 first = FALSE;
e9e44622
JJ
10101 else
10102 putc (' ', stdout);
13ae64f3 10103
d1133906
NC
10104 switch (flag)
10105 {
e9e44622
JJ
10106 case DF_ORIGIN: fputs ("ORIGIN", stdout); break;
10107 case DF_SYMBOLIC: fputs ("SYMBOLIC", stdout); break;
10108 case DF_TEXTREL: fputs ("TEXTREL", stdout); break;
10109 case DF_BIND_NOW: fputs ("BIND_NOW", stdout); break;
10110 case DF_STATIC_TLS: fputs ("STATIC_TLS", stdout); break;
2b692964 10111 default: fputs (_("unknown"), stdout); break;
d1133906
NC
10112 }
10113 }
e9e44622 10114 puts ("");
d1133906
NC
10115}
10116
10ca4b04
L
10117static bfd_vma *
10118get_dynamic_data (Filedata * filedata, bfd_size_type number, unsigned int ent_size)
10119{
10120 unsigned char * e_data;
10121 bfd_vma * i_data;
10122
10123 /* If the size_t type is smaller than the bfd_size_type, eg because
10124 you are building a 32-bit tool on a 64-bit host, then make sure
10125 that when (number) is cast to (size_t) no information is lost. */
10126 if (sizeof (size_t) < sizeof (bfd_size_type)
10127 && (bfd_size_type) ((size_t) number) != number)
10128 {
10129 error (_("Size truncation prevents reading %s elements of size %u\n"),
10130 bfd_vmatoa ("u", number), ent_size);
10131 return NULL;
10132 }
10133
10134 /* Be kind to memory checkers (eg valgrind, address sanitizer) by not
10135 attempting to allocate memory when the read is bound to fail. */
10136 if (ent_size * number > filedata->file_size)
10137 {
10138 error (_("Invalid number of dynamic entries: %s\n"),
10139 bfd_vmatoa ("u", number));
10140 return NULL;
10141 }
10142
10143 e_data = (unsigned char *) cmalloc ((size_t) number, ent_size);
10144 if (e_data == NULL)
10145 {
10146 error (_("Out of memory reading %s dynamic entries\n"),
10147 bfd_vmatoa ("u", number));
10148 return NULL;
10149 }
10150
10151 if (fread (e_data, ent_size, (size_t) number, filedata->handle) != number)
10152 {
10153 error (_("Unable to read in %s bytes of dynamic data\n"),
10154 bfd_vmatoa ("u", number * ent_size));
10155 free (e_data);
10156 return NULL;
10157 }
10158
10159 i_data = (bfd_vma *) cmalloc ((size_t) number, sizeof (*i_data));
10160 if (i_data == NULL)
10161 {
10162 error (_("Out of memory allocating space for %s dynamic entries\n"),
10163 bfd_vmatoa ("u", number));
10164 free (e_data);
10165 return NULL;
10166 }
10167
10168 while (number--)
10169 i_data[number] = byte_get (e_data + number * ent_size, ent_size);
10170
10171 free (e_data);
10172
10173 return i_data;
10174}
10175
10176static unsigned long
10177get_num_dynamic_syms (Filedata * filedata)
10178{
10179 unsigned long num_of_syms = 0;
10180
10181 if (!do_histogram && (!do_using_dynamic || do_dyn_syms))
10182 return num_of_syms;
10183
978c4450 10184 if (filedata->dynamic_info[DT_HASH])
10ca4b04
L
10185 {
10186 unsigned char nb[8];
10187 unsigned char nc[8];
10188 unsigned int hash_ent_size = 4;
10189
10190 if ((filedata->file_header.e_machine == EM_ALPHA
10191 || filedata->file_header.e_machine == EM_S390
10192 || filedata->file_header.e_machine == EM_S390_OLD)
10193 && filedata->file_header.e_ident[EI_CLASS] == ELFCLASS64)
10194 hash_ent_size = 8;
10195
10196 if (fseek (filedata->handle,
978c4450
AM
10197 (filedata->archive_file_offset
10198 + offset_from_vma (filedata, filedata->dynamic_info[DT_HASH],
10ca4b04
L
10199 sizeof nb + sizeof nc)),
10200 SEEK_SET))
10201 {
10202 error (_("Unable to seek to start of dynamic information\n"));
10203 goto no_hash;
10204 }
10205
10206 if (fread (nb, hash_ent_size, 1, filedata->handle) != 1)
10207 {
10208 error (_("Failed to read in number of buckets\n"));
10209 goto no_hash;
10210 }
10211
10212 if (fread (nc, hash_ent_size, 1, filedata->handle) != 1)
10213 {
10214 error (_("Failed to read in number of chains\n"));
10215 goto no_hash;
10216 }
10217
978c4450
AM
10218 filedata->nbuckets = byte_get (nb, hash_ent_size);
10219 filedata->nchains = byte_get (nc, hash_ent_size);
10ca4b04 10220
2482f306
AM
10221 if (filedata->nbuckets != 0 && filedata->nchains != 0)
10222 {
10223 filedata->buckets = get_dynamic_data (filedata, filedata->nbuckets,
10224 hash_ent_size);
10225 filedata->chains = get_dynamic_data (filedata, filedata->nchains,
10226 hash_ent_size);
001890e1 10227
2482f306
AM
10228 if (filedata->buckets != NULL && filedata->chains != NULL)
10229 num_of_syms = filedata->nchains;
10230 }
ceb9bf11 10231 no_hash:
10ca4b04
L
10232 if (num_of_syms == 0)
10233 {
9db70fc3
AM
10234 free (filedata->buckets);
10235 filedata->buckets = NULL;
10236 free (filedata->chains);
10237 filedata->chains = NULL;
978c4450 10238 filedata->nbuckets = 0;
10ca4b04
L
10239 }
10240 }
10241
978c4450 10242 if (filedata->dynamic_info_DT_GNU_HASH)
10ca4b04
L
10243 {
10244 unsigned char nb[16];
10245 bfd_vma i, maxchain = 0xffffffff, bitmaskwords;
10246 bfd_vma buckets_vma;
10247 unsigned long hn;
10ca4b04
L
10248
10249 if (fseek (filedata->handle,
978c4450
AM
10250 (filedata->archive_file_offset
10251 + offset_from_vma (filedata,
10252 filedata->dynamic_info_DT_GNU_HASH,
10ca4b04
L
10253 sizeof nb)),
10254 SEEK_SET))
10255 {
10256 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10257 goto no_gnu_hash;
10258 }
10259
10260 if (fread (nb, 16, 1, filedata->handle) != 1)
10261 {
10262 error (_("Failed to read in number of buckets\n"));
10ca4b04
L
10263 goto no_gnu_hash;
10264 }
10265
978c4450
AM
10266 filedata->ngnubuckets = byte_get (nb, 4);
10267 filedata->gnusymidx = byte_get (nb + 4, 4);
10ca4b04 10268 bitmaskwords = byte_get (nb + 8, 4);
978c4450 10269 buckets_vma = filedata->dynamic_info_DT_GNU_HASH + 16;
10ca4b04
L
10270 if (is_32bit_elf)
10271 buckets_vma += bitmaskwords * 4;
10272 else
10273 buckets_vma += bitmaskwords * 8;
10274
10275 if (fseek (filedata->handle,
978c4450 10276 (filedata->archive_file_offset
10ca4b04
L
10277 + offset_from_vma (filedata, buckets_vma, 4)),
10278 SEEK_SET))
10279 {
10280 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10281 goto no_gnu_hash;
10282 }
10283
978c4450
AM
10284 filedata->gnubuckets
10285 = get_dynamic_data (filedata, filedata->ngnubuckets, 4);
10ca4b04 10286
978c4450 10287 if (filedata->gnubuckets == NULL)
90837ea7 10288 goto no_gnu_hash;
10ca4b04 10289
978c4450
AM
10290 for (i = 0; i < filedata->ngnubuckets; i++)
10291 if (filedata->gnubuckets[i] != 0)
10ca4b04 10292 {
978c4450 10293 if (filedata->gnubuckets[i] < filedata->gnusymidx)
90837ea7 10294 goto no_gnu_hash;
10ca4b04 10295
978c4450
AM
10296 if (maxchain == 0xffffffff || filedata->gnubuckets[i] > maxchain)
10297 maxchain = filedata->gnubuckets[i];
10ca4b04
L
10298 }
10299
10300 if (maxchain == 0xffffffff)
90837ea7 10301 goto no_gnu_hash;
10ca4b04 10302
978c4450 10303 maxchain -= filedata->gnusymidx;
10ca4b04
L
10304
10305 if (fseek (filedata->handle,
978c4450
AM
10306 (filedata->archive_file_offset
10307 + offset_from_vma (filedata,
10308 buckets_vma + 4 * (filedata->ngnubuckets
10309 + maxchain),
10310 4)),
10ca4b04
L
10311 SEEK_SET))
10312 {
10313 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10314 goto no_gnu_hash;
10315 }
10316
10317 do
10318 {
10319 if (fread (nb, 4, 1, filedata->handle) != 1)
10320 {
10321 error (_("Failed to determine last chain length\n"));
10ca4b04
L
10322 goto no_gnu_hash;
10323 }
10324
10325 if (maxchain + 1 == 0)
90837ea7 10326 goto no_gnu_hash;
10ca4b04
L
10327
10328 ++maxchain;
10329 }
10330 while ((byte_get (nb, 4) & 1) == 0);
10331
10332 if (fseek (filedata->handle,
978c4450
AM
10333 (filedata->archive_file_offset
10334 + offset_from_vma (filedata, (buckets_vma
10335 + 4 * filedata->ngnubuckets),
10336 4)),
10ca4b04
L
10337 SEEK_SET))
10338 {
10339 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10340 goto no_gnu_hash;
10341 }
10342
978c4450
AM
10343 filedata->gnuchains = get_dynamic_data (filedata, maxchain, 4);
10344 filedata->ngnuchains = maxchain;
10ca4b04 10345
978c4450 10346 if (filedata->gnuchains == NULL)
90837ea7 10347 goto no_gnu_hash;
10ca4b04 10348
978c4450 10349 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04
L
10350 {
10351 if (fseek (filedata->handle,
978c4450 10352 (filedata->archive_file_offset
10ca4b04 10353 + offset_from_vma (filedata, (buckets_vma
978c4450 10354 + 4 * (filedata->ngnubuckets
10ca4b04
L
10355 + maxchain)), 4)),
10356 SEEK_SET))
10357 {
10358 error (_("Unable to seek to start of dynamic information\n"));
10ca4b04
L
10359 goto no_gnu_hash;
10360 }
10361
978c4450 10362 filedata->mipsxlat = get_dynamic_data (filedata, maxchain, 4);
90837ea7
AM
10363 if (filedata->mipsxlat == NULL)
10364 goto no_gnu_hash;
10ca4b04
L
10365 }
10366
978c4450
AM
10367 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
10368 if (filedata->gnubuckets[hn] != 0)
10ca4b04 10369 {
978c4450
AM
10370 bfd_vma si = filedata->gnubuckets[hn];
10371 bfd_vma off = si - filedata->gnusymidx;
10ca4b04
L
10372
10373 do
10374 {
978c4450 10375 if (filedata->dynamic_info_DT_MIPS_XHASH)
10ca4b04 10376 {
c31ab5a0
AM
10377 if (off < filedata->ngnuchains
10378 && filedata->mipsxlat[off] >= num_of_syms)
978c4450 10379 num_of_syms = filedata->mipsxlat[off] + 1;
10ca4b04
L
10380 }
10381 else
10382 {
10383 if (si >= num_of_syms)
10384 num_of_syms = si + 1;
10385 }
10386 si++;
10387 }
978c4450
AM
10388 while (off < filedata->ngnuchains
10389 && (filedata->gnuchains[off++] & 1) == 0);
10ca4b04
L
10390 }
10391
90837ea7 10392 if (num_of_syms == 0)
10ca4b04 10393 {
90837ea7 10394 no_gnu_hash:
9db70fc3
AM
10395 free (filedata->mipsxlat);
10396 filedata->mipsxlat = NULL;
10397 free (filedata->gnuchains);
10398 filedata->gnuchains = NULL;
10399 free (filedata->gnubuckets);
10400 filedata->gnubuckets = NULL;
978c4450
AM
10401 filedata->ngnubuckets = 0;
10402 filedata->ngnuchains = 0;
10ca4b04
L
10403 }
10404 }
10405
10406 return num_of_syms;
10407}
10408
b2d38a17
NC
10409/* Parse and display the contents of the dynamic section. */
10410
32ec8896 10411static bfd_boolean
dda8d76d 10412process_dynamic_section (Filedata * filedata)
9ea033b2 10413{
2cf0635d 10414 Elf_Internal_Dyn * entry;
9ea033b2 10415
978c4450 10416 if (filedata->dynamic_size == 0)
9ea033b2
NC
10417 {
10418 if (do_dynamic)
b2d38a17 10419 printf (_("\nThere is no dynamic section in this file.\n"));
9ea033b2 10420
32ec8896 10421 return TRUE;
9ea033b2
NC
10422 }
10423
10424 if (is_32bit_elf)
10425 {
dda8d76d 10426 if (! get_32bit_dynamic_section (filedata))
32ec8896
NC
10427 return FALSE;
10428 }
10429 else
10430 {
dda8d76d 10431 if (! get_64bit_dynamic_section (filedata))
32ec8896 10432 return FALSE;
9ea033b2 10433 }
9ea033b2 10434
252b5132 10435 /* Find the appropriate symbol table. */
978c4450 10436 if (filedata->dynamic_symbols == NULL || do_histogram)
252b5132 10437 {
2482f306
AM
10438 unsigned long num_of_syms;
10439
978c4450
AM
10440 for (entry = filedata->dynamic_section;
10441 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10442 ++entry)
10ca4b04 10443 if (entry->d_tag == DT_SYMTAB)
978c4450 10444 filedata->dynamic_info[DT_SYMTAB] = entry->d_un.d_val;
10ca4b04 10445 else if (entry->d_tag == DT_SYMENT)
978c4450 10446 filedata->dynamic_info[DT_SYMENT] = entry->d_un.d_val;
10ca4b04 10447 else if (entry->d_tag == DT_HASH)
978c4450 10448 filedata->dynamic_info[DT_HASH] = entry->d_un.d_val;
10ca4b04 10449 else if (entry->d_tag == DT_GNU_HASH)
978c4450 10450 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04
L
10451 else if ((filedata->file_header.e_machine == EM_MIPS
10452 || filedata->file_header.e_machine == EM_MIPS_RS3_LE)
10453 && entry->d_tag == DT_MIPS_XHASH)
10454 {
978c4450
AM
10455 filedata->dynamic_info_DT_MIPS_XHASH = entry->d_un.d_val;
10456 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
10ca4b04 10457 }
252b5132 10458
2482f306
AM
10459 num_of_syms = get_num_dynamic_syms (filedata);
10460
10461 if (num_of_syms != 0
10462 && filedata->dynamic_symbols == NULL
10463 && filedata->dynamic_info[DT_SYMTAB]
978c4450 10464 && filedata->dynamic_info[DT_SYMENT])
10ca4b04
L
10465 {
10466 Elf_Internal_Phdr *seg;
2482f306 10467 bfd_vma vma = filedata->dynamic_info[DT_SYMTAB];
252b5132 10468
2482f306
AM
10469 if (! get_program_headers (filedata))
10470 {
10471 error (_("Cannot interpret virtual addresses "
10472 "without program headers.\n"));
10473 return FALSE;
10474 }
252b5132 10475
2482f306
AM
10476 for (seg = filedata->program_headers;
10477 seg < filedata->program_headers + filedata->file_header.e_phnum;
10478 ++seg)
10479 {
10480 if (seg->p_type != PT_LOAD)
10481 continue;
252b5132 10482
2482f306
AM
10483 if (seg->p_offset + seg->p_filesz > filedata->file_size)
10484 {
10485 /* See PR 21379 for a reproducer. */
10486 error (_("Invalid PT_LOAD entry\n"));
10487 return FALSE;
10488 }
252b5132 10489
2482f306
AM
10490 if (vma >= (seg->p_vaddr & -seg->p_align)
10491 && vma < seg->p_vaddr + seg->p_filesz)
10492 {
10493 /* Since we do not know how big the symbol table is,
10494 we default to reading in up to the end of PT_LOAD
10495 segment and processing that. This is overkill, I
10496 know, but it should work. */
10497 Elf_Internal_Shdr section;
10498 section.sh_offset = (vma - seg->p_vaddr
10499 + seg->p_offset);
10500 section.sh_size = (num_of_syms
10501 * filedata->dynamic_info[DT_SYMENT]);
10502 section.sh_entsize = filedata->dynamic_info[DT_SYMENT];
8ac10c5b
L
10503
10504 if (do_checks
10505 && filedata->dynamic_symtab_section != NULL
10506 && ((filedata->dynamic_symtab_section->sh_offset
10507 != section.sh_offset)
10508 || (filedata->dynamic_symtab_section->sh_size
10509 != section.sh_size)
10510 || (filedata->dynamic_symtab_section->sh_entsize
10511 != section.sh_entsize)))
10512 warn (_("\
10513the .dynsym section doesn't match the DT_SYMTAB and DT_SYMENT tags\n"));
10514
2482f306
AM
10515 section.sh_name = filedata->string_table_length;
10516 filedata->dynamic_symbols
10517 = GET_ELF_SYMBOLS (filedata, &section,
10518 &filedata->num_dynamic_syms);
10519 if (filedata->dynamic_symbols == NULL
10520 || filedata->num_dynamic_syms != num_of_syms)
10521 {
10522 error (_("Corrupt DT_SYMTAB dynamic entry\n"));
10523 return FALSE;
10524 }
10525 break;
10526 }
10527 }
10528 }
10529 }
252b5132
RH
10530
10531 /* Similarly find a string table. */
978c4450
AM
10532 if (filedata->dynamic_strings == NULL)
10533 for (entry = filedata->dynamic_section;
10534 entry < filedata->dynamic_section + filedata->dynamic_nent;
10ca4b04
L
10535 ++entry)
10536 {
10537 if (entry->d_tag == DT_STRTAB)
978c4450 10538 filedata->dynamic_info[DT_STRTAB] = entry->d_un.d_val;
252b5132 10539
10ca4b04 10540 if (entry->d_tag == DT_STRSZ)
978c4450 10541 filedata->dynamic_info[DT_STRSZ] = entry->d_un.d_val;
252b5132 10542
978c4450
AM
10543 if (filedata->dynamic_info[DT_STRTAB]
10544 && filedata->dynamic_info[DT_STRSZ])
10ca4b04
L
10545 {
10546 unsigned long offset;
978c4450 10547 bfd_size_type str_tab_len = filedata->dynamic_info[DT_STRSZ];
10ca4b04
L
10548
10549 offset = offset_from_vma (filedata,
978c4450 10550 filedata->dynamic_info[DT_STRTAB],
10ca4b04 10551 str_tab_len);
8ac10c5b
L
10552 if (do_checks
10553 && filedata->dynamic_strtab_section
10554 && ((filedata->dynamic_strtab_section->sh_offset
10555 != (file_ptr) offset)
10556 || (filedata->dynamic_strtab_section->sh_size
10557 != str_tab_len)))
10558 warn (_("\
10559the .dynstr section doesn't match the DT_STRTAB and DT_STRSZ tags\n"));
10560
978c4450
AM
10561 filedata->dynamic_strings
10562 = (char *) get_data (NULL, filedata, offset, 1, str_tab_len,
10563 _("dynamic string table"));
10564 if (filedata->dynamic_strings == NULL)
10ca4b04
L
10565 {
10566 error (_("Corrupt DT_STRTAB dynamic entry\n"));
10567 break;
10568 }
e3d39609 10569
978c4450 10570 filedata->dynamic_strings_length = str_tab_len;
10ca4b04
L
10571 break;
10572 }
10573 }
252b5132
RH
10574
10575 /* And find the syminfo section if available. */
978c4450 10576 if (filedata->dynamic_syminfo == NULL)
252b5132 10577 {
3e8bba36 10578 unsigned long syminsz = 0;
252b5132 10579
978c4450
AM
10580 for (entry = filedata->dynamic_section;
10581 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10582 ++entry)
252b5132
RH
10583 {
10584 if (entry->d_tag == DT_SYMINENT)
10585 {
10586 /* Note: these braces are necessary to avoid a syntax
10587 error from the SunOS4 C compiler. */
049b0c3a
NC
10588 /* PR binutils/17531: A corrupt file can trigger this test.
10589 So do not use an assert, instead generate an error message. */
10590 if (sizeof (Elf_External_Syminfo) != entry->d_un.d_val)
071436c6 10591 error (_("Bad value (%d) for SYMINENT entry\n"),
049b0c3a 10592 (int) entry->d_un.d_val);
252b5132
RH
10593 }
10594 else if (entry->d_tag == DT_SYMINSZ)
10595 syminsz = entry->d_un.d_val;
10596 else if (entry->d_tag == DT_SYMINFO)
978c4450
AM
10597 filedata->dynamic_syminfo_offset
10598 = offset_from_vma (filedata, entry->d_un.d_val, syminsz);
252b5132
RH
10599 }
10600
978c4450 10601 if (filedata->dynamic_syminfo_offset != 0 && syminsz != 0)
252b5132 10602 {
2cf0635d
NC
10603 Elf_External_Syminfo * extsyminfo;
10604 Elf_External_Syminfo * extsym;
10605 Elf_Internal_Syminfo * syminfo;
252b5132
RH
10606
10607 /* There is a syminfo section. Read the data. */
3f5e193b 10608 extsyminfo = (Elf_External_Syminfo *)
978c4450
AM
10609 get_data (NULL, filedata, filedata->dynamic_syminfo_offset,
10610 1, syminsz, _("symbol information"));
a6e9f9df 10611 if (!extsyminfo)
32ec8896 10612 return FALSE;
252b5132 10613
978c4450 10614 if (filedata->dynamic_syminfo != NULL)
e3d39609
NC
10615 {
10616 error (_("Multiple dynamic symbol information sections found\n"));
978c4450 10617 free (filedata->dynamic_syminfo);
e3d39609 10618 }
978c4450
AM
10619 filedata->dynamic_syminfo = (Elf_Internal_Syminfo *) malloc (syminsz);
10620 if (filedata->dynamic_syminfo == NULL)
252b5132 10621 {
2482f306
AM
10622 error (_("Out of memory allocating %lu bytes "
10623 "for dynamic symbol info\n"),
8b73c356 10624 (unsigned long) syminsz);
32ec8896 10625 return FALSE;
252b5132
RH
10626 }
10627
2482f306
AM
10628 filedata->dynamic_syminfo_nent
10629 = syminsz / sizeof (Elf_External_Syminfo);
978c4450 10630 for (syminfo = filedata->dynamic_syminfo, extsym = extsyminfo;
2482f306
AM
10631 syminfo < (filedata->dynamic_syminfo
10632 + filedata->dynamic_syminfo_nent);
86dba8ee 10633 ++syminfo, ++extsym)
252b5132 10634 {
86dba8ee
AM
10635 syminfo->si_boundto = BYTE_GET (extsym->si_boundto);
10636 syminfo->si_flags = BYTE_GET (extsym->si_flags);
252b5132
RH
10637 }
10638
10639 free (extsyminfo);
10640 }
10641 }
10642
978c4450 10643 if (do_dynamic && filedata->dynamic_addr)
d3a49aa8
AM
10644 printf (ngettext ("\nDynamic section at offset 0x%lx "
10645 "contains %lu entry:\n",
10646 "\nDynamic section at offset 0x%lx "
10647 "contains %lu entries:\n",
978c4450
AM
10648 filedata->dynamic_nent),
10649 filedata->dynamic_addr, (unsigned long) filedata->dynamic_nent);
252b5132
RH
10650 if (do_dynamic)
10651 printf (_(" Tag Type Name/Value\n"));
10652
978c4450
AM
10653 for (entry = filedata->dynamic_section;
10654 entry < filedata->dynamic_section + filedata->dynamic_nent;
86dba8ee 10655 entry++)
252b5132
RH
10656 {
10657 if (do_dynamic)
f7a99963 10658 {
2cf0635d 10659 const char * dtype;
e699b9ff 10660
f7a99963
NC
10661 putchar (' ');
10662 print_vma (entry->d_tag, FULL_HEX);
dda8d76d 10663 dtype = get_dynamic_type (filedata, entry->d_tag);
e699b9ff 10664 printf (" (%s)%*s", dtype,
32ec8896 10665 ((is_32bit_elf ? 27 : 19) - (int) strlen (dtype)), " ");
f7a99963 10666 }
252b5132
RH
10667
10668 switch (entry->d_tag)
10669 {
d1133906
NC
10670 case DT_FLAGS:
10671 if (do_dynamic)
e9e44622 10672 print_dynamic_flags (entry->d_un.d_val);
d1133906 10673 break;
76da6bbe 10674
252b5132
RH
10675 case DT_AUXILIARY:
10676 case DT_FILTER:
019148e4
L
10677 case DT_CONFIG:
10678 case DT_DEPAUDIT:
10679 case DT_AUDIT:
252b5132
RH
10680 if (do_dynamic)
10681 {
019148e4 10682 switch (entry->d_tag)
b34976b6 10683 {
019148e4
L
10684 case DT_AUXILIARY:
10685 printf (_("Auxiliary library"));
10686 break;
10687
10688 case DT_FILTER:
10689 printf (_("Filter library"));
10690 break;
10691
b34976b6 10692 case DT_CONFIG:
019148e4
L
10693 printf (_("Configuration file"));
10694 break;
10695
10696 case DT_DEPAUDIT:
10697 printf (_("Dependency audit library"));
10698 break;
10699
10700 case DT_AUDIT:
10701 printf (_("Audit library"));
10702 break;
10703 }
252b5132 10704
978c4450
AM
10705 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10706 printf (": [%s]\n",
10707 GET_DYNAMIC_NAME (filedata, entry->d_un.d_val));
252b5132 10708 else
f7a99963
NC
10709 {
10710 printf (": ");
10711 print_vma (entry->d_un.d_val, PREFIX_HEX);
10712 putchar ('\n');
10713 }
252b5132
RH
10714 }
10715 break;
10716
dcefbbbd 10717 case DT_FEATURE:
252b5132
RH
10718 if (do_dynamic)
10719 {
10720 printf (_("Flags:"));
86f55779 10721
252b5132
RH
10722 if (entry->d_un.d_val == 0)
10723 printf (_(" None\n"));
10724 else
10725 {
10726 unsigned long int val = entry->d_un.d_val;
86f55779 10727
252b5132
RH
10728 if (val & DTF_1_PARINIT)
10729 {
10730 printf (" PARINIT");
10731 val ^= DTF_1_PARINIT;
10732 }
dcefbbbd
L
10733 if (val & DTF_1_CONFEXP)
10734 {
10735 printf (" CONFEXP");
10736 val ^= DTF_1_CONFEXP;
10737 }
252b5132
RH
10738 if (val != 0)
10739 printf (" %lx", val);
10740 puts ("");
10741 }
10742 }
10743 break;
10744
10745 case DT_POSFLAG_1:
10746 if (do_dynamic)
10747 {
10748 printf (_("Flags:"));
86f55779 10749
252b5132
RH
10750 if (entry->d_un.d_val == 0)
10751 printf (_(" None\n"));
10752 else
10753 {
10754 unsigned long int val = entry->d_un.d_val;
86f55779 10755
252b5132
RH
10756 if (val & DF_P1_LAZYLOAD)
10757 {
10758 printf (" LAZYLOAD");
10759 val ^= DF_P1_LAZYLOAD;
10760 }
10761 if (val & DF_P1_GROUPPERM)
10762 {
10763 printf (" GROUPPERM");
10764 val ^= DF_P1_GROUPPERM;
10765 }
10766 if (val != 0)
10767 printf (" %lx", val);
10768 puts ("");
10769 }
10770 }
10771 break;
10772
10773 case DT_FLAGS_1:
10774 if (do_dynamic)
10775 {
10776 printf (_("Flags:"));
10777 if (entry->d_un.d_val == 0)
10778 printf (_(" None\n"));
10779 else
10780 {
10781 unsigned long int val = entry->d_un.d_val;
86f55779 10782
252b5132
RH
10783 if (val & DF_1_NOW)
10784 {
10785 printf (" NOW");
10786 val ^= DF_1_NOW;
10787 }
10788 if (val & DF_1_GLOBAL)
10789 {
10790 printf (" GLOBAL");
10791 val ^= DF_1_GLOBAL;
10792 }
10793 if (val & DF_1_GROUP)
10794 {
10795 printf (" GROUP");
10796 val ^= DF_1_GROUP;
10797 }
10798 if (val & DF_1_NODELETE)
10799 {
10800 printf (" NODELETE");
10801 val ^= DF_1_NODELETE;
10802 }
10803 if (val & DF_1_LOADFLTR)
10804 {
10805 printf (" LOADFLTR");
10806 val ^= DF_1_LOADFLTR;
10807 }
10808 if (val & DF_1_INITFIRST)
10809 {
10810 printf (" INITFIRST");
10811 val ^= DF_1_INITFIRST;
10812 }
10813 if (val & DF_1_NOOPEN)
10814 {
10815 printf (" NOOPEN");
10816 val ^= DF_1_NOOPEN;
10817 }
10818 if (val & DF_1_ORIGIN)
10819 {
10820 printf (" ORIGIN");
10821 val ^= DF_1_ORIGIN;
10822 }
10823 if (val & DF_1_DIRECT)
10824 {
10825 printf (" DIRECT");
10826 val ^= DF_1_DIRECT;
10827 }
10828 if (val & DF_1_TRANS)
10829 {
10830 printf (" TRANS");
10831 val ^= DF_1_TRANS;
10832 }
10833 if (val & DF_1_INTERPOSE)
10834 {
10835 printf (" INTERPOSE");
10836 val ^= DF_1_INTERPOSE;
10837 }
f7db6139 10838 if (val & DF_1_NODEFLIB)
dcefbbbd 10839 {
f7db6139
L
10840 printf (" NODEFLIB");
10841 val ^= DF_1_NODEFLIB;
dcefbbbd
L
10842 }
10843 if (val & DF_1_NODUMP)
10844 {
10845 printf (" NODUMP");
10846 val ^= DF_1_NODUMP;
10847 }
34b60028 10848 if (val & DF_1_CONFALT)
dcefbbbd 10849 {
34b60028
L
10850 printf (" CONFALT");
10851 val ^= DF_1_CONFALT;
10852 }
10853 if (val & DF_1_ENDFILTEE)
10854 {
10855 printf (" ENDFILTEE");
10856 val ^= DF_1_ENDFILTEE;
10857 }
10858 if (val & DF_1_DISPRELDNE)
10859 {
10860 printf (" DISPRELDNE");
10861 val ^= DF_1_DISPRELDNE;
10862 }
10863 if (val & DF_1_DISPRELPND)
10864 {
10865 printf (" DISPRELPND");
10866 val ^= DF_1_DISPRELPND;
10867 }
10868 if (val & DF_1_NODIRECT)
10869 {
10870 printf (" NODIRECT");
10871 val ^= DF_1_NODIRECT;
10872 }
10873 if (val & DF_1_IGNMULDEF)
10874 {
10875 printf (" IGNMULDEF");
10876 val ^= DF_1_IGNMULDEF;
10877 }
10878 if (val & DF_1_NOKSYMS)
10879 {
10880 printf (" NOKSYMS");
10881 val ^= DF_1_NOKSYMS;
10882 }
10883 if (val & DF_1_NOHDR)
10884 {
10885 printf (" NOHDR");
10886 val ^= DF_1_NOHDR;
10887 }
10888 if (val & DF_1_EDITED)
10889 {
10890 printf (" EDITED");
10891 val ^= DF_1_EDITED;
10892 }
10893 if (val & DF_1_NORELOC)
10894 {
10895 printf (" NORELOC");
10896 val ^= DF_1_NORELOC;
10897 }
10898 if (val & DF_1_SYMINTPOSE)
10899 {
10900 printf (" SYMINTPOSE");
10901 val ^= DF_1_SYMINTPOSE;
10902 }
10903 if (val & DF_1_GLOBAUDIT)
10904 {
10905 printf (" GLOBAUDIT");
10906 val ^= DF_1_GLOBAUDIT;
10907 }
10908 if (val & DF_1_SINGLETON)
10909 {
10910 printf (" SINGLETON");
10911 val ^= DF_1_SINGLETON;
dcefbbbd 10912 }
5c383f02
RO
10913 if (val & DF_1_STUB)
10914 {
10915 printf (" STUB");
10916 val ^= DF_1_STUB;
10917 }
10918 if (val & DF_1_PIE)
10919 {
10920 printf (" PIE");
10921 val ^= DF_1_PIE;
10922 }
b1202ffa
L
10923 if (val & DF_1_KMOD)
10924 {
10925 printf (" KMOD");
10926 val ^= DF_1_KMOD;
10927 }
10928 if (val & DF_1_WEAKFILTER)
10929 {
10930 printf (" WEAKFILTER");
10931 val ^= DF_1_WEAKFILTER;
10932 }
10933 if (val & DF_1_NOCOMMON)
10934 {
10935 printf (" NOCOMMON");
10936 val ^= DF_1_NOCOMMON;
10937 }
252b5132
RH
10938 if (val != 0)
10939 printf (" %lx", val);
10940 puts ("");
10941 }
10942 }
10943 break;
10944
10945 case DT_PLTREL:
978c4450 10946 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132 10947 if (do_dynamic)
dda8d76d 10948 puts (get_dynamic_type (filedata, entry->d_un.d_val));
252b5132
RH
10949 break;
10950
10951 case DT_NULL :
10952 case DT_NEEDED :
10953 case DT_PLTGOT :
10954 case DT_HASH :
10955 case DT_STRTAB :
10956 case DT_SYMTAB :
10957 case DT_RELA :
10958 case DT_INIT :
10959 case DT_FINI :
10960 case DT_SONAME :
10961 case DT_RPATH :
10962 case DT_SYMBOLIC:
10963 case DT_REL :
10964 case DT_DEBUG :
10965 case DT_TEXTREL :
10966 case DT_JMPREL :
019148e4 10967 case DT_RUNPATH :
978c4450 10968 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
252b5132
RH
10969
10970 if (do_dynamic)
10971 {
2cf0635d 10972 char * name;
252b5132 10973
978c4450
AM
10974 if (VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
10975 name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 10976 else
d79b3d50 10977 name = NULL;
252b5132
RH
10978
10979 if (name)
10980 {
10981 switch (entry->d_tag)
10982 {
10983 case DT_NEEDED:
10984 printf (_("Shared library: [%s]"), name);
10985
978c4450 10986 if (streq (name, filedata->program_interpreter))
f7a99963 10987 printf (_(" program interpreter"));
252b5132
RH
10988 break;
10989
10990 case DT_SONAME:
f7a99963 10991 printf (_("Library soname: [%s]"), name);
252b5132
RH
10992 break;
10993
10994 case DT_RPATH:
f7a99963 10995 printf (_("Library rpath: [%s]"), name);
252b5132
RH
10996 break;
10997
019148e4
L
10998 case DT_RUNPATH:
10999 printf (_("Library runpath: [%s]"), name);
11000 break;
11001
252b5132 11002 default:
f7a99963
NC
11003 print_vma (entry->d_un.d_val, PREFIX_HEX);
11004 break;
252b5132
RH
11005 }
11006 }
11007 else
f7a99963
NC
11008 print_vma (entry->d_un.d_val, PREFIX_HEX);
11009
11010 putchar ('\n');
252b5132
RH
11011 }
11012 break;
11013
11014 case DT_PLTRELSZ:
11015 case DT_RELASZ :
11016 case DT_STRSZ :
11017 case DT_RELSZ :
11018 case DT_RELAENT :
11019 case DT_SYMENT :
11020 case DT_RELENT :
978c4450 11021 filedata->dynamic_info[entry->d_tag] = entry->d_un.d_val;
1a0670f3 11022 /* Fall through. */
252b5132
RH
11023 case DT_PLTPADSZ:
11024 case DT_MOVEENT :
11025 case DT_MOVESZ :
11026 case DT_INIT_ARRAYSZ:
11027 case DT_FINI_ARRAYSZ:
047b2264
JJ
11028 case DT_GNU_CONFLICTSZ:
11029 case DT_GNU_LIBLISTSZ:
252b5132 11030 if (do_dynamic)
f7a99963
NC
11031 {
11032 print_vma (entry->d_un.d_val, UNSIGNED);
2b692964 11033 printf (_(" (bytes)\n"));
f7a99963 11034 }
252b5132
RH
11035 break;
11036
11037 case DT_VERDEFNUM:
11038 case DT_VERNEEDNUM:
11039 case DT_RELACOUNT:
11040 case DT_RELCOUNT:
11041 if (do_dynamic)
f7a99963
NC
11042 {
11043 print_vma (entry->d_un.d_val, UNSIGNED);
11044 putchar ('\n');
11045 }
252b5132
RH
11046 break;
11047
11048 case DT_SYMINSZ:
11049 case DT_SYMINENT:
11050 case DT_SYMINFO:
11051 case DT_USED:
11052 case DT_INIT_ARRAY:
11053 case DT_FINI_ARRAY:
11054 if (do_dynamic)
11055 {
d79b3d50 11056 if (entry->d_tag == DT_USED
978c4450 11057 && VALID_DYNAMIC_NAME (filedata, entry->d_un.d_val))
252b5132 11058 {
978c4450 11059 char * name = GET_DYNAMIC_NAME (filedata, entry->d_un.d_val);
252b5132 11060
b34976b6 11061 if (*name)
252b5132
RH
11062 {
11063 printf (_("Not needed object: [%s]\n"), name);
11064 break;
11065 }
11066 }
103f02d3 11067
f7a99963
NC
11068 print_vma (entry->d_un.d_val, PREFIX_HEX);
11069 putchar ('\n');
252b5132
RH
11070 }
11071 break;
11072
11073 case DT_BIND_NOW:
11074 /* The value of this entry is ignored. */
35b1837e
AM
11075 if (do_dynamic)
11076 putchar ('\n');
252b5132 11077 break;
103f02d3 11078
047b2264
JJ
11079 case DT_GNU_PRELINKED:
11080 if (do_dynamic)
11081 {
2cf0635d 11082 struct tm * tmp;
91d6fa6a 11083 time_t atime = entry->d_un.d_val;
047b2264 11084
91d6fa6a 11085 tmp = gmtime (&atime);
071436c6
NC
11086 /* PR 17533 file: 041-1244816-0.004. */
11087 if (tmp == NULL)
5a2cbcf4
L
11088 printf (_("<corrupt time val: %lx"),
11089 (unsigned long) atime);
071436c6
NC
11090 else
11091 printf ("%04u-%02u-%02uT%02u:%02u:%02u\n",
11092 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
11093 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
11094
11095 }
11096 break;
11097
fdc90cb4 11098 case DT_GNU_HASH:
978c4450 11099 filedata->dynamic_info_DT_GNU_HASH = entry->d_un.d_val;
fdc90cb4
JJ
11100 if (do_dynamic)
11101 {
11102 print_vma (entry->d_un.d_val, PREFIX_HEX);
11103 putchar ('\n');
11104 }
11105 break;
11106
a5da3dee
VDM
11107 case DT_GNU_FLAGS_1:
11108 if (do_dynamic)
11109 {
11110 printf (_("Flags:"));
11111 if (entry->d_un.d_val == 0)
11112 printf (_(" None\n"));
11113 else
11114 {
11115 unsigned long int val = entry->d_un.d_val;
11116
11117 if (val & DF_GNU_1_UNIQUE)
11118 {
11119 printf (" UNIQUE");
11120 val ^= DF_GNU_1_UNIQUE;
11121 }
11122 if (val != 0)
11123 printf (" %lx", val);
11124 puts ("");
11125 }
11126 }
11127 break;
11128
252b5132
RH
11129 default:
11130 if ((entry->d_tag >= DT_VERSYM) && (entry->d_tag <= DT_VERNEEDNUM))
978c4450
AM
11131 filedata->version_info[DT_VERSIONTAGIDX (entry->d_tag)]
11132 = entry->d_un.d_val;
252b5132
RH
11133
11134 if (do_dynamic)
11135 {
dda8d76d 11136 switch (filedata->file_header.e_machine)
252b5132 11137 {
37c18eed
SD
11138 case EM_AARCH64:
11139 dynamic_section_aarch64_val (entry);
11140 break;
252b5132 11141 case EM_MIPS:
4fe85591 11142 case EM_MIPS_RS3_LE:
978c4450 11143 dynamic_section_mips_val (filedata, entry);
252b5132 11144 break;
103f02d3 11145 case EM_PARISC:
b2d38a17 11146 dynamic_section_parisc_val (entry);
103f02d3 11147 break;
ecc51f48 11148 case EM_IA_64:
b2d38a17 11149 dynamic_section_ia64_val (entry);
ecc51f48 11150 break;
252b5132 11151 default:
f7a99963
NC
11152 print_vma (entry->d_un.d_val, PREFIX_HEX);
11153 putchar ('\n');
252b5132
RH
11154 }
11155 }
11156 break;
11157 }
11158 }
11159
32ec8896 11160 return TRUE;
252b5132
RH
11161}
11162
11163static char *
d3ba0551 11164get_ver_flags (unsigned int flags)
252b5132 11165{
6d4f21f6 11166 static char buff[128];
252b5132
RH
11167
11168 buff[0] = 0;
11169
11170 if (flags == 0)
11171 return _("none");
11172
11173 if (flags & VER_FLG_BASE)
7bb1ad17 11174 strcat (buff, "BASE");
252b5132
RH
11175
11176 if (flags & VER_FLG_WEAK)
11177 {
11178 if (flags & VER_FLG_BASE)
7bb1ad17 11179 strcat (buff, " | ");
252b5132 11180
7bb1ad17 11181 strcat (buff, "WEAK");
252b5132
RH
11182 }
11183
44ec90b9
RO
11184 if (flags & VER_FLG_INFO)
11185 {
11186 if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
7bb1ad17 11187 strcat (buff, " | ");
44ec90b9 11188
7bb1ad17 11189 strcat (buff, "INFO");
44ec90b9
RO
11190 }
11191
11192 if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
7bb1ad17
MR
11193 {
11194 if (flags & (VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
11195 strcat (buff, " | ");
11196
11197 strcat (buff, _("<unknown>"));
11198 }
252b5132
RH
11199
11200 return buff;
11201}
11202
11203/* Display the contents of the version sections. */
98fb390a 11204
32ec8896 11205static bfd_boolean
dda8d76d 11206process_version_sections (Filedata * filedata)
252b5132 11207{
2cf0635d 11208 Elf_Internal_Shdr * section;
b34976b6 11209 unsigned i;
32ec8896 11210 bfd_boolean found = FALSE;
252b5132
RH
11211
11212 if (! do_version)
32ec8896 11213 return TRUE;
252b5132 11214
dda8d76d
NC
11215 for (i = 0, section = filedata->section_headers;
11216 i < filedata->file_header.e_shnum;
b34976b6 11217 i++, section++)
252b5132
RH
11218 {
11219 switch (section->sh_type)
11220 {
11221 case SHT_GNU_verdef:
11222 {
2cf0635d 11223 Elf_External_Verdef * edefs;
452bf675
AM
11224 unsigned long idx;
11225 unsigned long cnt;
2cf0635d 11226 char * endbuf;
252b5132 11227
32ec8896 11228 found = TRUE;
252b5132 11229
d3a49aa8
AM
11230 printf (ngettext ("\nVersion definition section '%s' "
11231 "contains %u entry:\n",
11232 "\nVersion definition section '%s' "
11233 "contains %u entries:\n",
11234 section->sh_info),
dda8d76d 11235 printable_section_name (filedata, section),
74e1a04b 11236 section->sh_info);
252b5132 11237
ae9ac79e 11238 printf (_(" Addr: 0x"));
252b5132 11239 printf_vma (section->sh_addr);
233f82cf 11240 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11241 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11242 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11243
3f5e193b 11244 edefs = (Elf_External_Verdef *)
dda8d76d 11245 get_data (NULL, filedata, section->sh_offset, 1,section->sh_size,
3f5e193b 11246 _("version definition section"));
a6e9f9df
AM
11247 if (!edefs)
11248 break;
59245841 11249 endbuf = (char *) edefs + section->sh_size;
252b5132 11250
1445030f 11251 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
252b5132 11252 {
2cf0635d
NC
11253 char * vstart;
11254 Elf_External_Verdef * edef;
b34976b6 11255 Elf_Internal_Verdef ent;
2cf0635d 11256 Elf_External_Verdaux * eaux;
b34976b6 11257 Elf_Internal_Verdaux aux;
452bf675 11258 unsigned long isum;
b34976b6 11259 int j;
103f02d3 11260
252b5132 11261 vstart = ((char *) edefs) + idx;
54806181
AM
11262 if (vstart + sizeof (*edef) > endbuf)
11263 break;
252b5132
RH
11264
11265 edef = (Elf_External_Verdef *) vstart;
11266
11267 ent.vd_version = BYTE_GET (edef->vd_version);
11268 ent.vd_flags = BYTE_GET (edef->vd_flags);
11269 ent.vd_ndx = BYTE_GET (edef->vd_ndx);
11270 ent.vd_cnt = BYTE_GET (edef->vd_cnt);
11271 ent.vd_hash = BYTE_GET (edef->vd_hash);
11272 ent.vd_aux = BYTE_GET (edef->vd_aux);
11273 ent.vd_next = BYTE_GET (edef->vd_next);
11274
452bf675 11275 printf (_(" %#06lx: Rev: %d Flags: %s"),
252b5132
RH
11276 idx, ent.vd_version, get_ver_flags (ent.vd_flags));
11277
11278 printf (_(" Index: %d Cnt: %d "),
11279 ent.vd_ndx, ent.vd_cnt);
11280
452bf675 11281 /* Check for overflow. */
1445030f 11282 if (ent.vd_aux > (size_t) (endbuf - vstart))
dd24e3da
NC
11283 break;
11284
252b5132
RH
11285 vstart += ent.vd_aux;
11286
1445030f
AM
11287 if (vstart + sizeof (*eaux) > endbuf)
11288 break;
252b5132
RH
11289 eaux = (Elf_External_Verdaux *) vstart;
11290
11291 aux.vda_name = BYTE_GET (eaux->vda_name);
11292 aux.vda_next = BYTE_GET (eaux->vda_next);
11293
978c4450
AM
11294 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
11295 printf (_("Name: %s\n"),
11296 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132
RH
11297 else
11298 printf (_("Name index: %ld\n"), aux.vda_name);
11299
11300 isum = idx + ent.vd_aux;
11301
b34976b6 11302 for (j = 1; j < ent.vd_cnt; j++)
252b5132 11303 {
1445030f
AM
11304 if (aux.vda_next < sizeof (*eaux)
11305 && !(j == ent.vd_cnt - 1 && aux.vda_next == 0))
11306 {
11307 warn (_("Invalid vda_next field of %lx\n"),
11308 aux.vda_next);
11309 j = ent.vd_cnt;
11310 break;
11311 }
dd24e3da 11312 /* Check for overflow. */
7e26601c 11313 if (aux.vda_next > (size_t) (endbuf - vstart))
dd24e3da
NC
11314 break;
11315
252b5132
RH
11316 isum += aux.vda_next;
11317 vstart += aux.vda_next;
11318
54806181
AM
11319 if (vstart + sizeof (*eaux) > endbuf)
11320 break;
1445030f 11321 eaux = (Elf_External_Verdaux *) vstart;
252b5132
RH
11322
11323 aux.vda_name = BYTE_GET (eaux->vda_name);
11324 aux.vda_next = BYTE_GET (eaux->vda_next);
11325
978c4450 11326 if (VALID_DYNAMIC_NAME (filedata, aux.vda_name))
452bf675 11327 printf (_(" %#06lx: Parent %d: %s\n"),
978c4450
AM
11328 isum, j,
11329 GET_DYNAMIC_NAME (filedata, aux.vda_name));
252b5132 11330 else
452bf675 11331 printf (_(" %#06lx: Parent %d, name index: %ld\n"),
252b5132
RH
11332 isum, j, aux.vda_name);
11333 }
dd24e3da 11334
54806181
AM
11335 if (j < ent.vd_cnt)
11336 printf (_(" Version def aux past end of section\n"));
252b5132 11337
c9f02c3e
MR
11338 /* PR 17531:
11339 file: id:000001,src:000172+005151,op:splice,rep:2. */
1445030f
AM
11340 if (ent.vd_next < sizeof (*edef)
11341 && !(cnt == section->sh_info - 1 && ent.vd_next == 0))
11342 {
11343 warn (_("Invalid vd_next field of %lx\n"), ent.vd_next);
11344 cnt = section->sh_info;
11345 break;
11346 }
452bf675 11347 if (ent.vd_next > (size_t) (endbuf - ((char *) edefs + idx)))
5d921cbd
NC
11348 break;
11349
252b5132
RH
11350 idx += ent.vd_next;
11351 }
dd24e3da 11352
54806181
AM
11353 if (cnt < section->sh_info)
11354 printf (_(" Version definition past end of section\n"));
252b5132
RH
11355
11356 free (edefs);
11357 }
11358 break;
103f02d3 11359
252b5132
RH
11360 case SHT_GNU_verneed:
11361 {
2cf0635d 11362 Elf_External_Verneed * eneed;
452bf675
AM
11363 unsigned long idx;
11364 unsigned long cnt;
2cf0635d 11365 char * endbuf;
252b5132 11366
32ec8896 11367 found = TRUE;
252b5132 11368
d3a49aa8
AM
11369 printf (ngettext ("\nVersion needs section '%s' "
11370 "contains %u entry:\n",
11371 "\nVersion needs section '%s' "
11372 "contains %u entries:\n",
11373 section->sh_info),
dda8d76d 11374 printable_section_name (filedata, section), section->sh_info);
252b5132
RH
11375
11376 printf (_(" Addr: 0x"));
11377 printf_vma (section->sh_addr);
72de5009 11378 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11379 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11380 printable_section_name_from_index (filedata, section->sh_link));
252b5132 11381
dda8d76d 11382 eneed = (Elf_External_Verneed *) get_data (NULL, filedata,
3f5e193b
NC
11383 section->sh_offset, 1,
11384 section->sh_size,
9cf03b7e 11385 _("Version Needs section"));
a6e9f9df
AM
11386 if (!eneed)
11387 break;
59245841 11388 endbuf = (char *) eneed + section->sh_size;
252b5132
RH
11389
11390 for (idx = cnt = 0; cnt < section->sh_info; ++cnt)
11391 {
2cf0635d 11392 Elf_External_Verneed * entry;
b34976b6 11393 Elf_Internal_Verneed ent;
452bf675 11394 unsigned long isum;
b34976b6 11395 int j;
2cf0635d 11396 char * vstart;
252b5132
RH
11397
11398 vstart = ((char *) eneed) + idx;
54806181
AM
11399 if (vstart + sizeof (*entry) > endbuf)
11400 break;
252b5132
RH
11401
11402 entry = (Elf_External_Verneed *) vstart;
11403
11404 ent.vn_version = BYTE_GET (entry->vn_version);
11405 ent.vn_cnt = BYTE_GET (entry->vn_cnt);
11406 ent.vn_file = BYTE_GET (entry->vn_file);
11407 ent.vn_aux = BYTE_GET (entry->vn_aux);
11408 ent.vn_next = BYTE_GET (entry->vn_next);
11409
452bf675 11410 printf (_(" %#06lx: Version: %d"), idx, ent.vn_version);
252b5132 11411
978c4450
AM
11412 if (VALID_DYNAMIC_NAME (filedata, ent.vn_file))
11413 printf (_(" File: %s"),
11414 GET_DYNAMIC_NAME (filedata, ent.vn_file));
252b5132
RH
11415 else
11416 printf (_(" File: %lx"), ent.vn_file);
11417
11418 printf (_(" Cnt: %d\n"), ent.vn_cnt);
11419
dd24e3da 11420 /* Check for overflow. */
7e26601c 11421 if (ent.vn_aux > (size_t) (endbuf - vstart))
dd24e3da 11422 break;
252b5132
RH
11423 vstart += ent.vn_aux;
11424
11425 for (j = 0, isum = idx + ent.vn_aux; j < ent.vn_cnt; ++j)
11426 {
2cf0635d 11427 Elf_External_Vernaux * eaux;
b34976b6 11428 Elf_Internal_Vernaux aux;
252b5132 11429
54806181
AM
11430 if (vstart + sizeof (*eaux) > endbuf)
11431 break;
252b5132
RH
11432 eaux = (Elf_External_Vernaux *) vstart;
11433
11434 aux.vna_hash = BYTE_GET (eaux->vna_hash);
11435 aux.vna_flags = BYTE_GET (eaux->vna_flags);
11436 aux.vna_other = BYTE_GET (eaux->vna_other);
11437 aux.vna_name = BYTE_GET (eaux->vna_name);
11438 aux.vna_next = BYTE_GET (eaux->vna_next);
11439
978c4450 11440 if (VALID_DYNAMIC_NAME (filedata, aux.vna_name))
452bf675 11441 printf (_(" %#06lx: Name: %s"),
978c4450 11442 isum, GET_DYNAMIC_NAME (filedata, aux.vna_name));
252b5132 11443 else
452bf675 11444 printf (_(" %#06lx: Name index: %lx"),
252b5132
RH
11445 isum, aux.vna_name);
11446
11447 printf (_(" Flags: %s Version: %d\n"),
11448 get_ver_flags (aux.vna_flags), aux.vna_other);
11449
1445030f
AM
11450 if (aux.vna_next < sizeof (*eaux)
11451 && !(j == ent.vn_cnt - 1 && aux.vna_next == 0))
53774b7e
NC
11452 {
11453 warn (_("Invalid vna_next field of %lx\n"),
11454 aux.vna_next);
11455 j = ent.vn_cnt;
11456 break;
11457 }
1445030f
AM
11458 /* Check for overflow. */
11459 if (aux.vna_next > (size_t) (endbuf - vstart))
11460 break;
252b5132
RH
11461 isum += aux.vna_next;
11462 vstart += aux.vna_next;
11463 }
9cf03b7e 11464
54806181 11465 if (j < ent.vn_cnt)
f9a6a8f0 11466 warn (_("Missing Version Needs auxiliary information\n"));
252b5132 11467
1445030f
AM
11468 if (ent.vn_next < sizeof (*entry)
11469 && !(cnt == section->sh_info - 1 && ent.vn_next == 0))
c24cf8b6 11470 {
452bf675 11471 warn (_("Invalid vn_next field of %lx\n"), ent.vn_next);
c24cf8b6
NC
11472 cnt = section->sh_info;
11473 break;
11474 }
1445030f
AM
11475 if (ent.vn_next > (size_t) (endbuf - ((char *) eneed + idx)))
11476 break;
252b5132
RH
11477 idx += ent.vn_next;
11478 }
9cf03b7e 11479
54806181 11480 if (cnt < section->sh_info)
9cf03b7e 11481 warn (_("Missing Version Needs information\n"));
103f02d3 11482
252b5132
RH
11483 free (eneed);
11484 }
11485 break;
11486
11487 case SHT_GNU_versym:
11488 {
2cf0635d 11489 Elf_Internal_Shdr * link_section;
8b73c356
NC
11490 size_t total;
11491 unsigned int cnt;
2cf0635d
NC
11492 unsigned char * edata;
11493 unsigned short * data;
11494 char * strtab;
11495 Elf_Internal_Sym * symbols;
11496 Elf_Internal_Shdr * string_sec;
ba5cdace 11497 unsigned long num_syms;
d3ba0551 11498 long off;
252b5132 11499
dda8d76d 11500 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11501 break;
11502
dda8d76d 11503 link_section = filedata->section_headers + section->sh_link;
08d8fa11 11504 total = section->sh_size / sizeof (Elf_External_Versym);
252b5132 11505
dda8d76d 11506 if (link_section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
11507 break;
11508
32ec8896 11509 found = TRUE;
252b5132 11510
dda8d76d 11511 symbols = GET_ELF_SYMBOLS (filedata, link_section, & num_syms);
dd24e3da
NC
11512 if (symbols == NULL)
11513 break;
252b5132 11514
dda8d76d 11515 string_sec = filedata->section_headers + link_section->sh_link;
252b5132 11516
dda8d76d 11517 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
11518 string_sec->sh_size,
11519 _("version string table"));
a6e9f9df 11520 if (!strtab)
0429c154
MS
11521 {
11522 free (symbols);
11523 break;
11524 }
252b5132 11525
d3a49aa8
AM
11526 printf (ngettext ("\nVersion symbols section '%s' "
11527 "contains %lu entry:\n",
11528 "\nVersion symbols section '%s' "
11529 "contains %lu entries:\n",
11530 total),
dda8d76d 11531 printable_section_name (filedata, section), (unsigned long) total);
252b5132 11532
ae9ac79e 11533 printf (_(" Addr: 0x"));
252b5132 11534 printf_vma (section->sh_addr);
72de5009 11535 printf (_(" Offset: %#08lx Link: %u (%s)\n"),
1b228002 11536 (unsigned long) section->sh_offset, section->sh_link,
dda8d76d 11537 printable_section_name (filedata, link_section));
252b5132 11538
dda8d76d 11539 off = offset_from_vma (filedata,
978c4450 11540 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
d3ba0551 11541 total * sizeof (short));
95099889
AM
11542 edata = (unsigned char *) get_data (NULL, filedata, off,
11543 sizeof (short), total,
11544 _("version symbol data"));
a6e9f9df
AM
11545 if (!edata)
11546 {
11547 free (strtab);
0429c154 11548 free (symbols);
a6e9f9df
AM
11549 break;
11550 }
252b5132 11551
3f5e193b 11552 data = (short unsigned int *) cmalloc (total, sizeof (short));
252b5132
RH
11553
11554 for (cnt = total; cnt --;)
b34976b6
AM
11555 data[cnt] = byte_get (edata + cnt * sizeof (short),
11556 sizeof (short));
252b5132
RH
11557
11558 free (edata);
11559
11560 for (cnt = 0; cnt < total; cnt += 4)
11561 {
11562 int j, nn;
ab273396
AM
11563 char *name;
11564 char *invalid = _("*invalid*");
252b5132
RH
11565
11566 printf (" %03x:", cnt);
11567
11568 for (j = 0; (j < 4) && (cnt + j) < total; ++j)
b34976b6 11569 switch (data[cnt + j])
252b5132
RH
11570 {
11571 case 0:
11572 fputs (_(" 0 (*local*) "), stdout);
11573 break;
11574
11575 case 1:
11576 fputs (_(" 1 (*global*) "), stdout);
11577 break;
11578
11579 default:
c244d050
NC
11580 nn = printf ("%4x%c", data[cnt + j] & VERSYM_VERSION,
11581 data[cnt + j] & VERSYM_HIDDEN ? 'h' : ' ');
252b5132 11582
dd24e3da 11583 /* If this index value is greater than the size of the symbols
ba5cdace
NC
11584 array, break to avoid an out-of-bounds read. */
11585 if ((unsigned long)(cnt + j) >= num_syms)
dd24e3da
NC
11586 {
11587 warn (_("invalid index into symbol array\n"));
11588 break;
11589 }
11590
ab273396 11591 name = NULL;
978c4450 11592 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
252b5132 11593 {
b34976b6
AM
11594 Elf_Internal_Verneed ivn;
11595 unsigned long offset;
252b5132 11596
d93f0186 11597 offset = offset_from_vma
978c4450
AM
11598 (filedata,
11599 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
d93f0186 11600 sizeof (Elf_External_Verneed));
252b5132 11601
b34976b6 11602 do
252b5132 11603 {
b34976b6
AM
11604 Elf_Internal_Vernaux ivna;
11605 Elf_External_Verneed evn;
11606 Elf_External_Vernaux evna;
11607 unsigned long a_off;
252b5132 11608
dda8d76d 11609 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
59245841
NC
11610 _("version need")) == NULL)
11611 break;
0b4362b0 11612
252b5132
RH
11613 ivn.vn_aux = BYTE_GET (evn.vn_aux);
11614 ivn.vn_next = BYTE_GET (evn.vn_next);
11615
11616 a_off = offset + ivn.vn_aux;
11617
11618 do
11619 {
dda8d76d 11620 if (get_data (&evna, filedata, a_off, sizeof (evna),
59245841
NC
11621 1, _("version need aux (2)")) == NULL)
11622 {
11623 ivna.vna_next = 0;
11624 ivna.vna_other = 0;
11625 }
11626 else
11627 {
11628 ivna.vna_next = BYTE_GET (evna.vna_next);
11629 ivna.vna_other = BYTE_GET (evna.vna_other);
11630 }
252b5132
RH
11631
11632 a_off += ivna.vna_next;
11633 }
b34976b6 11634 while (ivna.vna_other != data[cnt + j]
252b5132
RH
11635 && ivna.vna_next != 0);
11636
b34976b6 11637 if (ivna.vna_other == data[cnt + j])
252b5132
RH
11638 {
11639 ivna.vna_name = BYTE_GET (evna.vna_name);
11640
54806181 11641 if (ivna.vna_name >= string_sec->sh_size)
ab273396 11642 name = invalid;
54806181
AM
11643 else
11644 name = strtab + ivna.vna_name;
252b5132
RH
11645 break;
11646 }
11647
11648 offset += ivn.vn_next;
11649 }
11650 while (ivn.vn_next);
11651 }
00d93f34 11652
ab273396 11653 if (data[cnt + j] != 0x8001
978c4450 11654 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
252b5132 11655 {
b34976b6
AM
11656 Elf_Internal_Verdef ivd;
11657 Elf_External_Verdef evd;
11658 unsigned long offset;
252b5132 11659
d93f0186 11660 offset = offset_from_vma
978c4450
AM
11661 (filedata,
11662 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
d93f0186 11663 sizeof evd);
252b5132
RH
11664
11665 do
11666 {
dda8d76d 11667 if (get_data (&evd, filedata, offset, sizeof (evd), 1,
59245841
NC
11668 _("version def")) == NULL)
11669 {
11670 ivd.vd_next = 0;
948f632f 11671 /* PR 17531: file: 046-1082287-0.004. */
3102e897
NC
11672 ivd.vd_ndx = (data[cnt + j] & VERSYM_VERSION) + 1;
11673 break;
59245841
NC
11674 }
11675 else
11676 {
11677 ivd.vd_next = BYTE_GET (evd.vd_next);
11678 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
11679 }
252b5132
RH
11680
11681 offset += ivd.vd_next;
11682 }
c244d050 11683 while (ivd.vd_ndx != (data[cnt + j] & VERSYM_VERSION)
252b5132
RH
11684 && ivd.vd_next != 0);
11685
c244d050 11686 if (ivd.vd_ndx == (data[cnt + j] & VERSYM_VERSION))
252b5132 11687 {
b34976b6
AM
11688 Elf_External_Verdaux evda;
11689 Elf_Internal_Verdaux ivda;
252b5132
RH
11690
11691 ivd.vd_aux = BYTE_GET (evd.vd_aux);
11692
dda8d76d 11693 if (get_data (&evda, filedata,
59245841
NC
11694 offset - ivd.vd_next + ivd.vd_aux,
11695 sizeof (evda), 1,
11696 _("version def aux")) == NULL)
11697 break;
252b5132
RH
11698
11699 ivda.vda_name = BYTE_GET (evda.vda_name);
11700
54806181 11701 if (ivda.vda_name >= string_sec->sh_size)
ab273396
AM
11702 name = invalid;
11703 else if (name != NULL && name != invalid)
11704 name = _("*both*");
54806181
AM
11705 else
11706 name = strtab + ivda.vda_name;
252b5132
RH
11707 }
11708 }
ab273396
AM
11709 if (name != NULL)
11710 nn += printf ("(%s%-*s",
11711 name,
11712 12 - (int) strlen (name),
11713 ")");
252b5132
RH
11714
11715 if (nn < 18)
11716 printf ("%*c", 18 - nn, ' ');
11717 }
11718
11719 putchar ('\n');
11720 }
11721
11722 free (data);
11723 free (strtab);
11724 free (symbols);
11725 }
11726 break;
103f02d3 11727
252b5132
RH
11728 default:
11729 break;
11730 }
11731 }
11732
11733 if (! found)
11734 printf (_("\nNo version information found in this file.\n"));
11735
32ec8896 11736 return TRUE;
252b5132
RH
11737}
11738
d1133906 11739static const char *
dda8d76d 11740get_symbol_binding (Filedata * filedata, unsigned int binding)
252b5132 11741{
89246a0e 11742 static char buff[64];
252b5132
RH
11743
11744 switch (binding)
11745 {
b34976b6
AM
11746 case STB_LOCAL: return "LOCAL";
11747 case STB_GLOBAL: return "GLOBAL";
11748 case STB_WEAK: return "WEAK";
252b5132
RH
11749 default:
11750 if (binding >= STB_LOPROC && binding <= STB_HIPROC)
e9e44622
JJ
11751 snprintf (buff, sizeof (buff), _("<processor specific>: %d"),
11752 binding);
252b5132 11753 else if (binding >= STB_LOOS && binding <= STB_HIOS)
3e7a7d11
NC
11754 {
11755 if (binding == STB_GNU_UNIQUE
df3a023b 11756 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU)
3e7a7d11
NC
11757 return "UNIQUE";
11758 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), binding);
11759 }
252b5132 11760 else
e9e44622 11761 snprintf (buff, sizeof (buff), _("<unknown>: %d"), binding);
252b5132
RH
11762 return buff;
11763 }
11764}
11765
d1133906 11766static const char *
dda8d76d 11767get_symbol_type (Filedata * filedata, unsigned int type)
252b5132 11768{
89246a0e 11769 static char buff[64];
252b5132
RH
11770
11771 switch (type)
11772 {
b34976b6
AM
11773 case STT_NOTYPE: return "NOTYPE";
11774 case STT_OBJECT: return "OBJECT";
11775 case STT_FUNC: return "FUNC";
11776 case STT_SECTION: return "SECTION";
11777 case STT_FILE: return "FILE";
11778 case STT_COMMON: return "COMMON";
11779 case STT_TLS: return "TLS";
15ab5209
DB
11780 case STT_RELC: return "RELC";
11781 case STT_SRELC: return "SRELC";
252b5132
RH
11782 default:
11783 if (type >= STT_LOPROC && type <= STT_HIPROC)
df75f1af 11784 {
dda8d76d 11785 if (filedata->file_header.e_machine == EM_ARM && type == STT_ARM_TFUNC)
3510a7b8 11786 return "THUMB_FUNC";
103f02d3 11787
dda8d76d 11788 if (filedata->file_header.e_machine == EM_SPARCV9 && type == STT_REGISTER)
103f02d3
UD
11789 return "REGISTER";
11790
dda8d76d 11791 if (filedata->file_header.e_machine == EM_PARISC && type == STT_PARISC_MILLI)
103f02d3
UD
11792 return "PARISC_MILLI";
11793
e9e44622 11794 snprintf (buff, sizeof (buff), _("<processor specific>: %d"), type);
df75f1af 11795 }
252b5132 11796 else if (type >= STT_LOOS && type <= STT_HIOS)
103f02d3 11797 {
dda8d76d 11798 if (filedata->file_header.e_machine == EM_PARISC)
103f02d3
UD
11799 {
11800 if (type == STT_HP_OPAQUE)
11801 return "HP_OPAQUE";
11802 if (type == STT_HP_STUB)
11803 return "HP_STUB";
11804 }
11805
d8045f23 11806 if (type == STT_GNU_IFUNC
dda8d76d 11807 && (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_GNU
df3a023b 11808 || filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_FREEBSD))
d8045f23
NC
11809 return "IFUNC";
11810
e9e44622 11811 snprintf (buff, sizeof (buff), _("<OS specific>: %d"), type);
103f02d3 11812 }
252b5132 11813 else
e9e44622 11814 snprintf (buff, sizeof (buff), _("<unknown>: %d"), type);
252b5132
RH
11815 return buff;
11816 }
11817}
11818
d1133906 11819static const char *
d3ba0551 11820get_symbol_visibility (unsigned int visibility)
d1133906
NC
11821{
11822 switch (visibility)
11823 {
b34976b6
AM
11824 case STV_DEFAULT: return "DEFAULT";
11825 case STV_INTERNAL: return "INTERNAL";
11826 case STV_HIDDEN: return "HIDDEN";
d1133906 11827 case STV_PROTECTED: return "PROTECTED";
bee0ee85 11828 default:
27a45f42 11829 error (_("Unrecognized visibility value: %u\n"), visibility);
bee0ee85 11830 return _("<unknown>");
d1133906
NC
11831 }
11832}
11833
2057d69d
CZ
11834static const char *
11835get_alpha_symbol_other (unsigned int other)
9abca702 11836{
2057d69d
CZ
11837 switch (other)
11838 {
11839 case STO_ALPHA_NOPV: return "NOPV";
11840 case STO_ALPHA_STD_GPLOAD: return "STD GPLOAD";
11841 default:
27a45f42 11842 error (_("Unrecognized alpha specific other value: %u\n"), other);
2057d69d 11843 return _("<unknown>");
9abca702 11844 }
2057d69d
CZ
11845}
11846
fd85a6a1
NC
11847static const char *
11848get_solaris_symbol_visibility (unsigned int visibility)
11849{
11850 switch (visibility)
11851 {
11852 case 4: return "EXPORTED";
11853 case 5: return "SINGLETON";
11854 case 6: return "ELIMINATE";
11855 default: return get_symbol_visibility (visibility);
11856 }
11857}
11858
2301ed1c
SN
11859static const char *
11860get_aarch64_symbol_other (unsigned int other)
11861{
11862 static char buf[32];
11863
11864 if (other & STO_AARCH64_VARIANT_PCS)
11865 {
11866 other &= ~STO_AARCH64_VARIANT_PCS;
11867 if (other == 0)
11868 return "VARIANT_PCS";
11869 snprintf (buf, sizeof buf, "VARIANT_PCS | %x", other);
11870 return buf;
11871 }
11872 return NULL;
11873}
11874
5e2b0d47
NC
11875static const char *
11876get_mips_symbol_other (unsigned int other)
11877{
11878 switch (other)
11879 {
32ec8896
NC
11880 case STO_OPTIONAL: return "OPTIONAL";
11881 case STO_MIPS_PLT: return "MIPS PLT";
11882 case STO_MIPS_PIC: return "MIPS PIC";
11883 case STO_MICROMIPS: return "MICROMIPS";
11884 case STO_MICROMIPS | STO_MIPS_PIC: return "MICROMIPS, MIPS PIC";
11885 case STO_MIPS16: return "MIPS16";
11886 default: return NULL;
5e2b0d47
NC
11887 }
11888}
11889
28f997cf 11890static const char *
dda8d76d 11891get_ia64_symbol_other (Filedata * filedata, unsigned int other)
28f997cf 11892{
dda8d76d 11893 if (is_ia64_vms (filedata))
28f997cf
TG
11894 {
11895 static char res[32];
11896
11897 res[0] = 0;
11898
11899 /* Function types is for images and .STB files only. */
dda8d76d 11900 switch (filedata->file_header.e_type)
28f997cf
TG
11901 {
11902 case ET_DYN:
11903 case ET_EXEC:
11904 switch (VMS_ST_FUNC_TYPE (other))
11905 {
11906 case VMS_SFT_CODE_ADDR:
11907 strcat (res, " CA");
11908 break;
11909 case VMS_SFT_SYMV_IDX:
11910 strcat (res, " VEC");
11911 break;
11912 case VMS_SFT_FD:
11913 strcat (res, " FD");
11914 break;
11915 case VMS_SFT_RESERVE:
11916 strcat (res, " RSV");
11917 break;
11918 default:
bee0ee85
NC
11919 warn (_("Unrecognized IA64 VMS ST Function type: %d\n"),
11920 VMS_ST_FUNC_TYPE (other));
11921 strcat (res, " <unknown>");
11922 break;
28f997cf
TG
11923 }
11924 break;
11925 default:
11926 break;
11927 }
11928 switch (VMS_ST_LINKAGE (other))
11929 {
11930 case VMS_STL_IGNORE:
11931 strcat (res, " IGN");
11932 break;
11933 case VMS_STL_RESERVE:
11934 strcat (res, " RSV");
11935 break;
11936 case VMS_STL_STD:
11937 strcat (res, " STD");
11938 break;
11939 case VMS_STL_LNK:
11940 strcat (res, " LNK");
11941 break;
11942 default:
bee0ee85
NC
11943 warn (_("Unrecognized IA64 VMS ST Linkage: %d\n"),
11944 VMS_ST_LINKAGE (other));
11945 strcat (res, " <unknown>");
11946 break;
28f997cf
TG
11947 }
11948
11949 if (res[0] != 0)
11950 return res + 1;
11951 else
11952 return res;
11953 }
11954 return NULL;
11955}
11956
6911b7dc
AM
11957static const char *
11958get_ppc64_symbol_other (unsigned int other)
11959{
14732552
AM
11960 if ((other & ~STO_PPC64_LOCAL_MASK) != 0)
11961 return NULL;
11962
11963 other >>= STO_PPC64_LOCAL_BIT;
11964 if (other <= 6)
6911b7dc 11965 {
89246a0e 11966 static char buf[64];
14732552
AM
11967 if (other >= 2)
11968 other = ppc64_decode_local_entry (other);
11969 snprintf (buf, sizeof buf, _("<localentry>: %d"), other);
6911b7dc
AM
11970 return buf;
11971 }
11972 return NULL;
11973}
11974
5e2b0d47 11975static const char *
dda8d76d 11976get_symbol_other (Filedata * filedata, unsigned int other)
5e2b0d47
NC
11977{
11978 const char * result = NULL;
89246a0e 11979 static char buff [64];
5e2b0d47
NC
11980
11981 if (other == 0)
11982 return "";
11983
dda8d76d 11984 switch (filedata->file_header.e_machine)
5e2b0d47 11985 {
2057d69d
CZ
11986 case EM_ALPHA:
11987 result = get_alpha_symbol_other (other);
11988 break;
2301ed1c
SN
11989 case EM_AARCH64:
11990 result = get_aarch64_symbol_other (other);
11991 break;
5e2b0d47
NC
11992 case EM_MIPS:
11993 result = get_mips_symbol_other (other);
28f997cf
TG
11994 break;
11995 case EM_IA_64:
dda8d76d 11996 result = get_ia64_symbol_other (filedata, other);
28f997cf 11997 break;
6911b7dc
AM
11998 case EM_PPC64:
11999 result = get_ppc64_symbol_other (other);
12000 break;
5e2b0d47 12001 default:
fd85a6a1 12002 result = NULL;
5e2b0d47
NC
12003 break;
12004 }
12005
12006 if (result)
12007 return result;
12008
12009 snprintf (buff, sizeof buff, _("<other>: %x"), other);
12010 return buff;
12011}
12012
d1133906 12013static const char *
dda8d76d 12014get_symbol_index_type (Filedata * filedata, unsigned int type)
252b5132 12015{
b34976b6 12016 static char buff[32];
5cf1065c 12017
252b5132
RH
12018 switch (type)
12019 {
b34976b6
AM
12020 case SHN_UNDEF: return "UND";
12021 case SHN_ABS: return "ABS";
12022 case SHN_COMMON: return "COM";
252b5132 12023 default:
9ce701e2 12024 if (type == SHN_IA_64_ANSI_COMMON
10ca4b04
L
12025 && filedata->file_header.e_machine == EM_IA_64
12026 && filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_HPUX)
12027 return "ANSI_COM";
12028 else if ((filedata->file_header.e_machine == EM_X86_64
12029 || filedata->file_header.e_machine == EM_L1OM
12030 || filedata->file_header.e_machine == EM_K1OM)
12031 && type == SHN_X86_64_LCOMMON)
12032 return "LARGE_COM";
12033 else if ((type == SHN_MIPS_SCOMMON
12034 && filedata->file_header.e_machine == EM_MIPS)
12035 || (type == SHN_TIC6X_SCOMMON
12036 && filedata->file_header.e_machine == EM_TI_C6000))
12037 return "SCOM";
12038 else if (type == SHN_MIPS_SUNDEFINED
12039 && filedata->file_header.e_machine == EM_MIPS)
12040 return "SUND";
12041 else if (type >= SHN_LOPROC && type <= SHN_HIPROC)
12042 sprintf (buff, "PRC[0x%04x]", type & 0xffff);
12043 else if (type >= SHN_LOOS && type <= SHN_HIOS)
12044 sprintf (buff, "OS [0x%04x]", type & 0xffff);
12045 else if (type >= SHN_LORESERVE)
12046 sprintf (buff, "RSV[0x%04x]", type & 0xffff);
12047 else if (filedata->file_header.e_shnum != 0
12048 && type >= filedata->file_header.e_shnum)
12049 sprintf (buff, _("bad section index[%3d]"), type);
12050 else
12051 sprintf (buff, "%3d", type);
12052 break;
fd85a6a1
NC
12053 }
12054
10ca4b04 12055 return buff;
6bd1a22c
L
12056}
12057
bb4d2ac2 12058static const char *
dda8d76d 12059get_symbol_version_string (Filedata * filedata,
1449284b
NC
12060 bfd_boolean is_dynsym,
12061 const char * strtab,
12062 unsigned long int strtab_size,
12063 unsigned int si,
12064 Elf_Internal_Sym * psym,
12065 enum versioned_symbol_info * sym_info,
12066 unsigned short * vna_other)
bb4d2ac2 12067{
ab273396
AM
12068 unsigned char data[2];
12069 unsigned short vers_data;
12070 unsigned long offset;
7a815dd5 12071 unsigned short max_vd_ndx;
bb4d2ac2 12072
ab273396 12073 if (!is_dynsym
978c4450 12074 || filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)] == 0)
ab273396 12075 return NULL;
bb4d2ac2 12076
978c4450
AM
12077 offset = offset_from_vma (filedata,
12078 filedata->version_info[DT_VERSIONTAGIDX (DT_VERSYM)],
ab273396 12079 sizeof data + si * sizeof (vers_data));
bb4d2ac2 12080
dda8d76d 12081 if (get_data (&data, filedata, offset + si * sizeof (vers_data),
ab273396
AM
12082 sizeof (data), 1, _("version data")) == NULL)
12083 return NULL;
12084
12085 vers_data = byte_get (data, 2);
bb4d2ac2 12086
1f6f5dba 12087 if ((vers_data & VERSYM_HIDDEN) == 0 && vers_data == 0)
ab273396 12088 return NULL;
bb4d2ac2 12089
0b8b7609 12090 *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
7a815dd5
L
12091 max_vd_ndx = 0;
12092
ab273396
AM
12093 /* Usually we'd only see verdef for defined symbols, and verneed for
12094 undefined symbols. However, symbols defined by the linker in
12095 .dynbss for variables copied from a shared library in order to
12096 avoid text relocations are defined yet have verneed. We could
12097 use a heuristic to detect the special case, for example, check
12098 for verneed first on symbols defined in SHT_NOBITS sections, but
12099 it is simpler and more reliable to just look for both verdef and
12100 verneed. .dynbss might not be mapped to a SHT_NOBITS section. */
bb4d2ac2 12101
ab273396
AM
12102 if (psym->st_shndx != SHN_UNDEF
12103 && vers_data != 0x8001
978c4450 12104 && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
ab273396
AM
12105 {
12106 Elf_Internal_Verdef ivd;
12107 Elf_Internal_Verdaux ivda;
12108 Elf_External_Verdaux evda;
12109 unsigned long off;
bb4d2ac2 12110
dda8d76d 12111 off = offset_from_vma (filedata,
978c4450 12112 filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)],
ab273396
AM
12113 sizeof (Elf_External_Verdef));
12114
12115 do
bb4d2ac2 12116 {
ab273396
AM
12117 Elf_External_Verdef evd;
12118
dda8d76d 12119 if (get_data (&evd, filedata, off, sizeof (evd), 1,
ab273396
AM
12120 _("version def")) == NULL)
12121 {
12122 ivd.vd_ndx = 0;
12123 ivd.vd_aux = 0;
12124 ivd.vd_next = 0;
1f6f5dba 12125 ivd.vd_flags = 0;
ab273396
AM
12126 }
12127 else
bb4d2ac2 12128 {
ab273396
AM
12129 ivd.vd_ndx = BYTE_GET (evd.vd_ndx);
12130 ivd.vd_aux = BYTE_GET (evd.vd_aux);
12131 ivd.vd_next = BYTE_GET (evd.vd_next);
1f6f5dba 12132 ivd.vd_flags = BYTE_GET (evd.vd_flags);
ab273396 12133 }
bb4d2ac2 12134
7a815dd5
L
12135 if ((ivd.vd_ndx & VERSYM_VERSION) > max_vd_ndx)
12136 max_vd_ndx = ivd.vd_ndx & VERSYM_VERSION;
12137
ab273396
AM
12138 off += ivd.vd_next;
12139 }
12140 while (ivd.vd_ndx != (vers_data & VERSYM_VERSION) && ivd.vd_next != 0);
bb4d2ac2 12141
ab273396
AM
12142 if (ivd.vd_ndx == (vers_data & VERSYM_VERSION))
12143 {
9abca702 12144 if (ivd.vd_ndx == 1 && ivd.vd_flags == VER_FLG_BASE)
1f6f5dba
L
12145 return NULL;
12146
ab273396
AM
12147 off -= ivd.vd_next;
12148 off += ivd.vd_aux;
bb4d2ac2 12149
dda8d76d 12150 if (get_data (&evda, filedata, off, sizeof (evda), 1,
ab273396
AM
12151 _("version def aux")) != NULL)
12152 {
12153 ivda.vda_name = BYTE_GET (evda.vda_name);
bb4d2ac2 12154
ab273396 12155 if (psym->st_name != ivda.vda_name)
0b8b7609
AM
12156 return (ivda.vda_name < strtab_size
12157 ? strtab + ivda.vda_name : _("<corrupt>"));
ab273396
AM
12158 }
12159 }
12160 }
bb4d2ac2 12161
978c4450 12162 if (filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)])
ab273396
AM
12163 {
12164 Elf_External_Verneed evn;
12165 Elf_Internal_Verneed ivn;
12166 Elf_Internal_Vernaux ivna;
bb4d2ac2 12167
dda8d76d 12168 offset = offset_from_vma (filedata,
978c4450 12169 filedata->version_info[DT_VERSIONTAGIDX (DT_VERNEED)],
ab273396
AM
12170 sizeof evn);
12171 do
12172 {
12173 unsigned long vna_off;
bb4d2ac2 12174
dda8d76d 12175 if (get_data (&evn, filedata, offset, sizeof (evn), 1,
ab273396
AM
12176 _("version need")) == NULL)
12177 {
12178 ivna.vna_next = 0;
12179 ivna.vna_other = 0;
12180 ivna.vna_name = 0;
12181 break;
12182 }
bb4d2ac2 12183
ab273396
AM
12184 ivn.vn_aux = BYTE_GET (evn.vn_aux);
12185 ivn.vn_next = BYTE_GET (evn.vn_next);
bb4d2ac2 12186
ab273396 12187 vna_off = offset + ivn.vn_aux;
bb4d2ac2 12188
ab273396
AM
12189 do
12190 {
12191 Elf_External_Vernaux evna;
bb4d2ac2 12192
dda8d76d 12193 if (get_data (&evna, filedata, vna_off, sizeof (evna), 1,
ab273396 12194 _("version need aux (3)")) == NULL)
bb4d2ac2 12195 {
ab273396
AM
12196 ivna.vna_next = 0;
12197 ivna.vna_other = 0;
12198 ivna.vna_name = 0;
bb4d2ac2 12199 }
bb4d2ac2 12200 else
bb4d2ac2 12201 {
ab273396
AM
12202 ivna.vna_other = BYTE_GET (evna.vna_other);
12203 ivna.vna_next = BYTE_GET (evna.vna_next);
12204 ivna.vna_name = BYTE_GET (evna.vna_name);
12205 }
bb4d2ac2 12206
ab273396
AM
12207 vna_off += ivna.vna_next;
12208 }
12209 while (ivna.vna_other != vers_data && ivna.vna_next != 0);
bb4d2ac2 12210
ab273396
AM
12211 if (ivna.vna_other == vers_data)
12212 break;
bb4d2ac2 12213
ab273396
AM
12214 offset += ivn.vn_next;
12215 }
12216 while (ivn.vn_next != 0);
bb4d2ac2 12217
ab273396
AM
12218 if (ivna.vna_other == vers_data)
12219 {
12220 *sym_info = symbol_undefined;
12221 *vna_other = ivna.vna_other;
12222 return (ivna.vna_name < strtab_size
12223 ? strtab + ivna.vna_name : _("<corrupt>"));
bb4d2ac2 12224 }
7a815dd5
L
12225 else if ((max_vd_ndx || (vers_data & VERSYM_VERSION) != 1)
12226 && (vers_data & VERSYM_VERSION) > max_vd_ndx)
12227 return _("<corrupt>");
bb4d2ac2 12228 }
ab273396 12229 return NULL;
bb4d2ac2
L
12230}
12231
10ca4b04
L
12232static void
12233print_dynamic_symbol (Filedata *filedata, unsigned long si,
12234 Elf_Internal_Sym *symtab,
12235 Elf_Internal_Shdr *section,
12236 char *strtab, size_t strtab_size)
252b5132 12237{
10ca4b04
L
12238 const char *version_string;
12239 enum versioned_symbol_info sym_info;
12240 unsigned short vna_other;
12241 Elf_Internal_Sym *psym = symtab + si;
b9e920ec 12242
10ca4b04
L
12243 printf ("%6ld: ", si);
12244 print_vma (psym->st_value, LONG_HEX);
12245 putchar (' ');
12246 print_vma (psym->st_size, DEC_5);
12247 printf (" %-7s", get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)));
12248 printf (" %-6s", get_symbol_binding (filedata, ELF_ST_BIND (psym->st_info)));
12249 if (filedata->file_header.e_ident[EI_OSABI] == ELFOSABI_SOLARIS)
12250 printf (" %-7s", get_solaris_symbol_visibility (psym->st_other));
12251 else
252b5132 12252 {
10ca4b04 12253 unsigned int vis = ELF_ST_VISIBILITY (psym->st_other);
252b5132 12254
10ca4b04
L
12255 printf (" %-7s", get_symbol_visibility (vis));
12256 /* Check to see if any other bits in the st_other field are set.
12257 Note - displaying this information disrupts the layout of the
12258 table being generated, but for the moment this case is very rare. */
12259 if (psym->st_other ^ vis)
12260 printf (" [%s] ", get_symbol_other (filedata, psym->st_other ^ vis));
252b5132 12261 }
10ca4b04 12262 printf (" %4s ", get_symbol_index_type (filedata, psym->st_shndx));
0942c7ab
NC
12263
12264 bfd_boolean is_valid = VALID_SYMBOL_NAME (strtab, strtab_size,
12265 psym->st_name);
12266 const char * sstr = is_valid ? strtab + psym->st_name : _("<corrupt>");
10ca4b04
L
12267
12268 version_string
12269 = get_symbol_version_string (filedata,
12270 (section == NULL
12271 || section->sh_type == SHT_DYNSYM),
12272 strtab, strtab_size, si,
12273 psym, &sym_info, &vna_other);
b9e920ec 12274
0942c7ab
NC
12275 int len_avail = 21;
12276 if (! do_wide && version_string != NULL)
12277 {
ddb43bab 12278 char buffer[16];
0942c7ab 12279
ddb43bab 12280 len_avail -= 1 + strlen (version_string);
0942c7ab
NC
12281
12282 if (sym_info == symbol_undefined)
12283 len_avail -= sprintf (buffer," (%d)", vna_other);
12284 else if (sym_info != symbol_hidden)
12285 len_avail -= 1;
12286 }
12287
12288 print_symbol (len_avail, sstr);
b9e920ec 12289
10ca4b04
L
12290 if (version_string)
12291 {
12292 if (sym_info == symbol_undefined)
12293 printf ("@%s (%d)", version_string, vna_other);
f7a99963 12294 else
10ca4b04
L
12295 printf (sym_info == symbol_hidden ? "@%s" : "@@%s",
12296 version_string);
12297 }
6bd1a22c 12298
10ca4b04 12299 putchar ('\n');
6bd1a22c 12300
10ca4b04
L
12301 if (ELF_ST_BIND (psym->st_info) == STB_LOCAL
12302 && section != NULL
12303 && si >= section->sh_info
12304 /* Irix 5 and 6 MIPS binaries are known to ignore this requirement. */
12305 && filedata->file_header.e_machine != EM_MIPS
12306 /* Solaris binaries have been found to violate this requirement as
12307 well. Not sure if this is a bug or an ABI requirement. */
12308 && filedata->file_header.e_ident[EI_OSABI] != ELFOSABI_SOLARIS)
12309 warn (_("local symbol %lu found at index >= %s's sh_info value of %u\n"),
12310 si, printable_section_name (filedata, section), section->sh_info);
12311}
f16a9783 12312
0f03783c
NC
12313static const char *
12314get_lto_kind (unsigned int kind)
12315{
12316 switch (kind)
12317 {
12318 case 0: return "DEF";
12319 case 1: return "WEAKDEF";
12320 case 2: return "UNDEF";
12321 case 3: return "WEAKUNDEF";
12322 case 4: return "COMMON";
12323 default:
12324 break;
12325 }
12326
12327 static char buffer[30];
12328 error (_("Unknown LTO symbol definition encountered: %u\n"), kind);
12329 sprintf (buffer, "<unknown: %u>", kind);
12330 return buffer;
12331}
12332
12333static const char *
12334get_lto_visibility (unsigned int visibility)
12335{
12336 switch (visibility)
12337 {
12338 case 0: return "DEFAULT";
12339 case 1: return "PROTECTED";
12340 case 2: return "INTERNAL";
12341 case 3: return "HIDDEN";
12342 default:
12343 break;
12344 }
12345
12346 static char buffer[30];
12347 error (_("Unknown LTO symbol visibility encountered: %u\n"), visibility);
12348 sprintf (buffer, "<unknown: %u>", visibility);
12349 return buffer;
12350}
12351
12352static const char *
12353get_lto_sym_type (unsigned int sym_type)
12354{
12355 switch (sym_type)
12356 {
12357 case 0: return "UNKNOWN";
12358 case 1: return "FUNCTION";
12359 case 2: return "VARIABLE";
12360 default:
12361 break;
12362 }
12363
12364 static char buffer[30];
12365 error (_("Unknown LTO symbol type encountered: %u\n"), sym_type);
12366 sprintf (buffer, "<unknown: %u>", sym_type);
12367 return buffer;
12368}
12369
12370/* Display an LTO format symbol table.
12371 FIXME: The format of LTO symbol tables is not formalized.
12372 So this code could need changing in the future. */
12373
12374static bfd_boolean
12375display_lto_symtab (Filedata * filedata,
12376 Elf_Internal_Shdr * section)
12377{
12378 if (section->sh_size == 0)
12379 {
12380 printf (_("\nLTO Symbol table '%s' is empty!\n"),
12381 printable_section_name (filedata, section));
12382 return TRUE;
12383 }
12384
12385 if (section->sh_size > filedata->file_size)
12386 {
12387 error (_("Section %s has an invalid sh_size of 0x%lx\n"),
12388 printable_section_name (filedata, section),
12389 (unsigned long) section->sh_size);
12390 return FALSE;
12391 }
12392
12393 void * alloced_data = get_data (NULL, filedata, section->sh_offset,
12394 section->sh_size, 1, _("LTO symbols"));
12395 if (alloced_data == NULL)
12396 return FALSE;
12397
12398 /* Look for extended data for the symbol table. */
12399 Elf_Internal_Shdr * ext;
12400 void * ext_data_orig = NULL;
12401 char * ext_data = NULL;
12402 char * ext_data_end = NULL;
12403 char * ext_name = NULL;
12404
12405 if (asprintf (& ext_name, ".gnu.lto_.ext_symtab.%s",
b9e920ec 12406 SECTION_NAME (section) + sizeof (".gnu.lto_.symtab.") - 1) > 0
0f03783c
NC
12407 && ext_name != NULL /* Paranoia. */
12408 && (ext = find_section (filedata, ext_name)) != NULL)
12409 {
12410 if (ext->sh_size < 3)
12411 error (_("LTO Symbol extension table '%s' is empty!\n"),
12412 printable_section_name (filedata, ext));
12413 else
12414 {
12415 ext_data_orig = ext_data = get_data (NULL, filedata, ext->sh_offset,
12416 ext->sh_size, 1,
12417 _("LTO ext symbol data"));
12418 if (ext_data != NULL)
12419 {
12420 ext_data_end = ext_data + ext->sh_size;
12421 if (* ext_data++ != 1)
12422 error (_("Unexpected version number in symbol extension table\n"));
12423 }
12424 }
12425 }
b9e920ec 12426
0f03783c
NC
12427 const unsigned char * data = (const unsigned char *) alloced_data;
12428 const unsigned char * end = data + section->sh_size;
12429
12430 if (ext_data_orig != NULL)
12431 {
12432 if (do_wide)
12433 printf (_("\nLTO Symbol table '%s' and extension table '%s' contain:\n"),
12434 printable_section_name (filedata, section),
12435 printable_section_name (filedata, ext));
12436 else
12437 {
12438 printf (_("\nLTO Symbol table '%s'\n"),
12439 printable_section_name (filedata, section));
12440 printf (_(" and extension table '%s' contain:\n"),
12441 printable_section_name (filedata, ext));
12442 }
12443 }
12444 else
12445 printf (_("\nLTO Symbol table '%s' contains:\n"),
12446 printable_section_name (filedata, section));
b9e920ec 12447
0f03783c
NC
12448
12449 /* FIXME: Add a wide version. */
b9e920ec 12450 if (ext_data_orig != NULL)
0f03783c
NC
12451 printf (_(" Comdat_Key Kind Visibility Size Slot Type Section Name\n"));
12452 else
12453 printf (_(" Comdat_Key Kind Visibility Size Slot Name\n"));
12454
12455 /* FIXME: We do not handle style prefixes. */
12456
12457 while (data < end)
12458 {
12459 const unsigned char * sym_name = data;
12460 data += strnlen ((const char *) sym_name, end - data) + 1;
12461 if (data >= end)
12462 goto fail;
12463
12464 const unsigned char * comdat_key = data;
12465 data += strnlen ((const char *) comdat_key, end - data) + 1;
12466 if (data >= end)
12467 goto fail;
12468
12469 if (data + 2 + 8 + 4 > end)
12470 goto fail;
12471
12472 unsigned int kind = *data++;
12473 unsigned int visibility = *data++;
12474
12475 elf_vma size = byte_get (data, 8);
12476 data += 8;
12477
12478 elf_vma slot = byte_get (data, 4);
12479 data += 4;
12480
12481 if (ext_data != NULL)
12482 {
12483 if (ext_data < (ext_data_end - 1))
12484 {
12485 unsigned int sym_type = * ext_data ++;
12486 unsigned int sec_kind = * ext_data ++;
12487
12488 printf (" %10s %10s %11s %08lx %08lx %9s %08lx _",
12489 * comdat_key == 0 ? "-" : (char *) comdat_key,
12490 get_lto_kind (kind),
12491 get_lto_visibility (visibility),
12492 (long) size,
12493 (long) slot,
12494 get_lto_sym_type (sym_type),
12495 (long) sec_kind);
12496 print_symbol (6, (const char *) sym_name);
12497 }
12498 else
12499 {
12500 error (_("Ran out of LTO symbol extension data\n"));
12501 ext_data = NULL;
12502 /* FIXME: return FAIL result ? */
12503 }
12504 }
12505 else
12506 {
12507 printf (" %10s %10s %11s %08lx %08lx _",
12508 * comdat_key == 0 ? "-" : (char *) comdat_key,
12509 get_lto_kind (kind),
12510 get_lto_visibility (visibility),
12511 (long) size,
12512 (long) slot);
12513 print_symbol (21, (const char *) sym_name);
12514 }
12515 putchar ('\n');
12516 }
12517
12518 if (ext_data != NULL && ext_data < ext_data_end)
12519 {
12520 error (_("Data remains in the LTO symbol extension table\n"));
12521 goto fail;
12522 }
12523
12524 free (alloced_data);
12525 free (ext_data_orig);
12526 free (ext_name);
12527 return TRUE;
b9e920ec 12528
0f03783c
NC
12529 fail:
12530 error (_("Buffer overrun encountered whilst decoding LTO symbol table\n"));
12531 free (alloced_data);
12532 free (ext_data_orig);
12533 free (ext_name);
12534 return FALSE;
12535}
12536
12537/* Display LTO symbol tables. */
12538
12539static bfd_boolean
12540process_lto_symbol_tables (Filedata * filedata)
12541{
12542 Elf_Internal_Shdr * section;
12543 unsigned int i;
12544 bfd_boolean res = TRUE;
12545
12546 if (!do_lto_syms)
12547 return TRUE;
12548
12549 if (filedata->section_headers == NULL)
12550 return TRUE;
12551
12552 for (i = 0, section = filedata->section_headers;
12553 i < filedata->file_header.e_shnum;
12554 i++, section++)
b9e920ec
AM
12555 if (SECTION_NAME_VALID (section)
12556 && CONST_STRNEQ (SECTION_NAME (section), ".gnu.lto_.symtab."))
0f03783c
NC
12557 res &= display_lto_symtab (filedata, section);
12558
b9e920ec 12559 return res;
0f03783c
NC
12560}
12561
10ca4b04 12562/* Dump the symbol table. */
0f03783c 12563
10ca4b04
L
12564static bfd_boolean
12565process_symbol_table (Filedata * filedata)
12566{
12567 Elf_Internal_Shdr * section;
f16a9783 12568
10ca4b04
L
12569 if (!do_syms && !do_dyn_syms && !do_histogram)
12570 return TRUE;
6bd1a22c 12571
978c4450 12572 if ((filedata->dynamic_info[DT_HASH] || filedata->dynamic_info_DT_GNU_HASH)
6bd1a22c
L
12573 && do_syms
12574 && do_using_dynamic
978c4450
AM
12575 && filedata->dynamic_strings != NULL
12576 && filedata->dynamic_symbols != NULL)
6bd1a22c 12577 {
10ca4b04 12578 unsigned long si;
6bd1a22c 12579
10ca4b04
L
12580 printf (ngettext ("\nSymbol table for image contains %lu entry:\n",
12581 "\nSymbol table for image contains %lu entries:\n",
978c4450
AM
12582 filedata->num_dynamic_syms),
12583 filedata->num_dynamic_syms);
10ca4b04
L
12584 if (is_32bit_elf)
12585 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
12586 else
12587 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
6bd1a22c 12588
978c4450
AM
12589 for (si = 0; si < filedata->num_dynamic_syms; si++)
12590 print_dynamic_symbol (filedata, si, filedata->dynamic_symbols, NULL,
12591 filedata->dynamic_strings,
12592 filedata->dynamic_strings_length);
252b5132 12593 }
8b73c356 12594 else if ((do_dyn_syms || (do_syms && !do_using_dynamic))
dda8d76d 12595 && filedata->section_headers != NULL)
252b5132 12596 {
b34976b6 12597 unsigned int i;
252b5132 12598
dda8d76d
NC
12599 for (i = 0, section = filedata->section_headers;
12600 i < filedata->file_header.e_shnum;
252b5132
RH
12601 i++, section++)
12602 {
2cf0635d 12603 char * strtab = NULL;
c256ffe7 12604 unsigned long int strtab_size = 0;
2cf0635d 12605 Elf_Internal_Sym * symtab;
ef3df110 12606 unsigned long si, num_syms;
252b5132 12607
2c610e4b
L
12608 if ((section->sh_type != SHT_SYMTAB
12609 && section->sh_type != SHT_DYNSYM)
12610 || (!do_syms
12611 && section->sh_type == SHT_SYMTAB))
252b5132
RH
12612 continue;
12613
dd24e3da
NC
12614 if (section->sh_entsize == 0)
12615 {
12616 printf (_("\nSymbol table '%s' has a sh_entsize of zero!\n"),
dda8d76d 12617 printable_section_name (filedata, section));
dd24e3da
NC
12618 continue;
12619 }
12620
d3a49aa8
AM
12621 num_syms = section->sh_size / section->sh_entsize;
12622 printf (ngettext ("\nSymbol table '%s' contains %lu entry:\n",
12623 "\nSymbol table '%s' contains %lu entries:\n",
12624 num_syms),
dda8d76d 12625 printable_section_name (filedata, section),
d3a49aa8 12626 num_syms);
dd24e3da 12627
f7a99963 12628 if (is_32bit_elf)
ca47b30c 12629 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
f7a99963 12630 else
ca47b30c 12631 printf (_(" Num: Value Size Type Bind Vis Ndx Name\n"));
252b5132 12632
dda8d76d 12633 symtab = GET_ELF_SYMBOLS (filedata, section, & num_syms);
252b5132
RH
12634 if (symtab == NULL)
12635 continue;
12636
dda8d76d 12637 if (section->sh_link == filedata->file_header.e_shstrndx)
c256ffe7 12638 {
dda8d76d
NC
12639 strtab = filedata->string_table;
12640 strtab_size = filedata->string_table_length;
c256ffe7 12641 }
dda8d76d 12642 else if (section->sh_link < filedata->file_header.e_shnum)
252b5132 12643 {
2cf0635d 12644 Elf_Internal_Shdr * string_sec;
252b5132 12645
dda8d76d 12646 string_sec = filedata->section_headers + section->sh_link;
252b5132 12647
dda8d76d 12648 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset,
3f5e193b
NC
12649 1, string_sec->sh_size,
12650 _("string table"));
c256ffe7 12651 strtab_size = strtab != NULL ? string_sec->sh_size : 0;
252b5132
RH
12652 }
12653
10ca4b04
L
12654 for (si = 0; si < num_syms; si++)
12655 print_dynamic_symbol (filedata, si, symtab, section,
12656 strtab, strtab_size);
252b5132
RH
12657
12658 free (symtab);
dda8d76d 12659 if (strtab != filedata->string_table)
252b5132
RH
12660 free (strtab);
12661 }
12662 }
12663 else if (do_syms)
12664 printf
12665 (_("\nDynamic symbol information is not available for displaying symbols.\n"));
12666
978c4450 12667 if (do_histogram && filedata->buckets != NULL)
252b5132 12668 {
2cf0635d
NC
12669 unsigned long * lengths;
12670 unsigned long * counts;
66543521
AM
12671 unsigned long hn;
12672 bfd_vma si;
12673 unsigned long maxlength = 0;
12674 unsigned long nzero_counts = 0;
12675 unsigned long nsyms = 0;
6bd6a03d 12676 char *visited;
252b5132 12677
d3a49aa8
AM
12678 printf (ngettext ("\nHistogram for bucket list length "
12679 "(total of %lu bucket):\n",
12680 "\nHistogram for bucket list length "
12681 "(total of %lu buckets):\n",
978c4450
AM
12682 (unsigned long) filedata->nbuckets),
12683 (unsigned long) filedata->nbuckets);
252b5132 12684
978c4450
AM
12685 lengths = (unsigned long *) calloc (filedata->nbuckets,
12686 sizeof (*lengths));
252b5132
RH
12687 if (lengths == NULL)
12688 {
8b73c356 12689 error (_("Out of memory allocating space for histogram buckets\n"));
fd486f32 12690 goto err_out;
252b5132 12691 }
978c4450
AM
12692 visited = xcmalloc (filedata->nchains, 1);
12693 memset (visited, 0, filedata->nchains);
8b73c356
NC
12694
12695 printf (_(" Length Number %% of total Coverage\n"));
978c4450 12696 for (hn = 0; hn < filedata->nbuckets; ++hn)
252b5132 12697 {
978c4450 12698 for (si = filedata->buckets[hn]; si > 0; si = filedata->chains[si])
252b5132 12699 {
b34976b6 12700 ++nsyms;
252b5132 12701 if (maxlength < ++lengths[hn])
b34976b6 12702 ++maxlength;
978c4450 12703 if (si >= filedata->nchains || visited[si])
6bd6a03d
AM
12704 {
12705 error (_("histogram chain is corrupt\n"));
12706 break;
12707 }
12708 visited[si] = 1;
252b5132
RH
12709 }
12710 }
6bd6a03d 12711 free (visited);
252b5132 12712
3f5e193b 12713 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
252b5132
RH
12714 if (counts == NULL)
12715 {
b2e951ec 12716 free (lengths);
8b73c356 12717 error (_("Out of memory allocating space for histogram counts\n"));
fd486f32 12718 goto err_out;
252b5132
RH
12719 }
12720
978c4450 12721 for (hn = 0; hn < filedata->nbuckets; ++hn)
b34976b6 12722 ++counts[lengths[hn]];
252b5132 12723
978c4450 12724 if (filedata->nbuckets > 0)
252b5132 12725 {
66543521
AM
12726 unsigned long i;
12727 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12728 counts[0], (counts[0] * 100.0) / filedata->nbuckets);
66543521 12729 for (i = 1; i <= maxlength; ++i)
103f02d3 12730 {
66543521
AM
12731 nzero_counts += counts[i] * i;
12732 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12733 i, counts[i], (counts[i] * 100.0) / filedata->nbuckets,
103f02d3
UD
12734 (nzero_counts * 100.0) / nsyms);
12735 }
252b5132
RH
12736 }
12737
12738 free (counts);
12739 free (lengths);
12740 }
12741
978c4450
AM
12742 free (filedata->buckets);
12743 filedata->buckets = NULL;
12744 filedata->nbuckets = 0;
12745 free (filedata->chains);
12746 filedata->chains = NULL;
252b5132 12747
978c4450 12748 if (do_histogram && filedata->gnubuckets != NULL)
fdc90cb4 12749 {
2cf0635d
NC
12750 unsigned long * lengths;
12751 unsigned long * counts;
fdc90cb4
JJ
12752 unsigned long hn;
12753 unsigned long maxlength = 0;
12754 unsigned long nzero_counts = 0;
12755 unsigned long nsyms = 0;
fdc90cb4 12756
f16a9783 12757 printf (ngettext ("\nHistogram for `%s' bucket list length "
d3a49aa8 12758 "(total of %lu bucket):\n",
f16a9783 12759 "\nHistogram for `%s' bucket list length "
d3a49aa8 12760 "(total of %lu buckets):\n",
978c4450
AM
12761 (unsigned long) filedata->ngnubuckets),
12762 GNU_HASH_SECTION_NAME (filedata),
12763 (unsigned long) filedata->ngnubuckets);
8b73c356 12764
978c4450
AM
12765 lengths = (unsigned long *) calloc (filedata->ngnubuckets,
12766 sizeof (*lengths));
fdc90cb4
JJ
12767 if (lengths == NULL)
12768 {
8b73c356 12769 error (_("Out of memory allocating space for gnu histogram buckets\n"));
fd486f32 12770 goto err_out;
fdc90cb4
JJ
12771 }
12772
fdc90cb4
JJ
12773 printf (_(" Length Number %% of total Coverage\n"));
12774
978c4450
AM
12775 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
12776 if (filedata->gnubuckets[hn] != 0)
fdc90cb4
JJ
12777 {
12778 bfd_vma off, length = 1;
12779
978c4450 12780 for (off = filedata->gnubuckets[hn] - filedata->gnusymidx;
071436c6 12781 /* PR 17531 file: 010-77222-0.004. */
978c4450
AM
12782 off < filedata->ngnuchains
12783 && (filedata->gnuchains[off] & 1) == 0;
071436c6 12784 ++off)
fdc90cb4
JJ
12785 ++length;
12786 lengths[hn] = length;
12787 if (length > maxlength)
12788 maxlength = length;
12789 nsyms += length;
12790 }
12791
3f5e193b 12792 counts = (unsigned long *) calloc (maxlength + 1, sizeof (*counts));
fdc90cb4
JJ
12793 if (counts == NULL)
12794 {
b2e951ec 12795 free (lengths);
8b73c356 12796 error (_("Out of memory allocating space for gnu histogram counts\n"));
fd486f32 12797 goto err_out;
fdc90cb4
JJ
12798 }
12799
978c4450 12800 for (hn = 0; hn < filedata->ngnubuckets; ++hn)
fdc90cb4
JJ
12801 ++counts[lengths[hn]];
12802
978c4450 12803 if (filedata->ngnubuckets > 0)
fdc90cb4
JJ
12804 {
12805 unsigned long j;
12806 printf (" 0 %-10lu (%5.1f%%)\n",
978c4450 12807 counts[0], (counts[0] * 100.0) / filedata->ngnubuckets);
fdc90cb4
JJ
12808 for (j = 1; j <= maxlength; ++j)
12809 {
12810 nzero_counts += counts[j] * j;
12811 printf ("%7lu %-10lu (%5.1f%%) %5.1f%%\n",
978c4450 12812 j, counts[j], (counts[j] * 100.0) / filedata->ngnubuckets,
fdc90cb4
JJ
12813 (nzero_counts * 100.0) / nsyms);
12814 }
12815 }
12816
12817 free (counts);
12818 free (lengths);
fdc90cb4 12819 }
978c4450
AM
12820 free (filedata->gnubuckets);
12821 filedata->gnubuckets = NULL;
12822 filedata->ngnubuckets = 0;
12823 free (filedata->gnuchains);
12824 filedata->gnuchains = NULL;
12825 filedata->ngnuchains = 0;
12826 free (filedata->mipsxlat);
12827 filedata->mipsxlat = NULL;
32ec8896 12828 return TRUE;
fd486f32
AM
12829
12830 err_out:
978c4450
AM
12831 free (filedata->gnubuckets);
12832 filedata->gnubuckets = NULL;
12833 filedata->ngnubuckets = 0;
12834 free (filedata->gnuchains);
12835 filedata->gnuchains = NULL;
12836 filedata->ngnuchains = 0;
12837 free (filedata->mipsxlat);
12838 filedata->mipsxlat = NULL;
12839 free (filedata->buckets);
12840 filedata->buckets = NULL;
12841 filedata->nbuckets = 0;
12842 free (filedata->chains);
12843 filedata->chains = NULL;
fd486f32 12844 return FALSE;
252b5132
RH
12845}
12846
32ec8896 12847static bfd_boolean
dda8d76d 12848process_syminfo (Filedata * filedata ATTRIBUTE_UNUSED)
252b5132 12849{
b4c96d0d 12850 unsigned int i;
252b5132 12851
978c4450 12852 if (filedata->dynamic_syminfo == NULL
252b5132
RH
12853 || !do_dynamic)
12854 /* No syminfo, this is ok. */
32ec8896 12855 return TRUE;
252b5132
RH
12856
12857 /* There better should be a dynamic symbol section. */
978c4450 12858 if (filedata->dynamic_symbols == NULL || filedata->dynamic_strings == NULL)
32ec8896 12859 return FALSE;
252b5132 12860
978c4450 12861 if (filedata->dynamic_addr)
d3a49aa8
AM
12862 printf (ngettext ("\nDynamic info segment at offset 0x%lx "
12863 "contains %d entry:\n",
12864 "\nDynamic info segment at offset 0x%lx "
12865 "contains %d entries:\n",
978c4450
AM
12866 filedata->dynamic_syminfo_nent),
12867 filedata->dynamic_syminfo_offset, filedata->dynamic_syminfo_nent);
252b5132
RH
12868
12869 printf (_(" Num: Name BoundTo Flags\n"));
978c4450 12870 for (i = 0; i < filedata->dynamic_syminfo_nent; ++i)
252b5132 12871 {
978c4450 12872 unsigned short int flags = filedata->dynamic_syminfo[i].si_flags;
252b5132 12873
31104126 12874 printf ("%4d: ", i);
978c4450 12875 if (i >= filedata->num_dynamic_syms)
4082ef84 12876 printf (_("<corrupt index>"));
978c4450
AM
12877 else if (VALID_DYNAMIC_NAME (filedata, filedata->dynamic_symbols[i].st_name))
12878 print_symbol (30, GET_DYNAMIC_NAME (filedata,
12879 filedata->dynamic_symbols[i].st_name));
d79b3d50 12880 else
978c4450 12881 printf (_("<corrupt: %19ld>"), filedata->dynamic_symbols[i].st_name);
31104126 12882 putchar (' ');
252b5132 12883
978c4450 12884 switch (filedata->dynamic_syminfo[i].si_boundto)
252b5132
RH
12885 {
12886 case SYMINFO_BT_SELF:
12887 fputs ("SELF ", stdout);
12888 break;
12889 case SYMINFO_BT_PARENT:
12890 fputs ("PARENT ", stdout);
12891 break;
12892 default:
978c4450
AM
12893 if (filedata->dynamic_syminfo[i].si_boundto > 0
12894 && filedata->dynamic_syminfo[i].si_boundto < filedata->dynamic_nent
12895 && VALID_DYNAMIC_NAME (filedata,
12896 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val))
31104126 12897 {
978c4450
AM
12898 print_symbol (10, GET_DYNAMIC_NAME (filedata,
12899 filedata->dynamic_section[filedata->dynamic_syminfo[i].si_boundto].d_un.d_val));
31104126
NC
12900 putchar (' ' );
12901 }
252b5132 12902 else
978c4450 12903 printf ("%-10d ", filedata->dynamic_syminfo[i].si_boundto);
252b5132
RH
12904 break;
12905 }
12906
12907 if (flags & SYMINFO_FLG_DIRECT)
12908 printf (" DIRECT");
12909 if (flags & SYMINFO_FLG_PASSTHRU)
12910 printf (" PASSTHRU");
12911 if (flags & SYMINFO_FLG_COPY)
12912 printf (" COPY");
12913 if (flags & SYMINFO_FLG_LAZYLOAD)
12914 printf (" LAZYLOAD");
12915
12916 puts ("");
12917 }
12918
32ec8896 12919 return TRUE;
252b5132
RH
12920}
12921
75802ccb
CE
12922/* A macro which evaluates to TRUE if the region ADDR .. ADDR + NELEM
12923 is contained by the region START .. END. The types of ADDR, START
12924 and END should all be the same. Note both ADDR + NELEM and END
12925 point to just beyond the end of the regions that are being tested. */
12926#define IN_RANGE(START,END,ADDR,NELEM) \
12927 (((ADDR) >= (START)) && ((ADDR) < (END)) && ((ADDR) + (NELEM) <= (END)))
b32e566b 12928
cf13d699
NC
12929/* Check to see if the given reloc needs to be handled in a target specific
12930 manner. If so then process the reloc and return TRUE otherwise return
f84ce13b
NC
12931 FALSE.
12932
12933 If called with reloc == NULL, then this is a signal that reloc processing
12934 for the current section has finished, and any saved state should be
12935 discarded. */
09c11c86 12936
cf13d699 12937static bfd_boolean
dda8d76d
NC
12938target_specific_reloc_handling (Filedata * filedata,
12939 Elf_Internal_Rela * reloc,
12940 unsigned char * start,
12941 unsigned char * end,
12942 Elf_Internal_Sym * symtab,
12943 unsigned long num_syms)
252b5132 12944{
f84ce13b
NC
12945 unsigned int reloc_type = 0;
12946 unsigned long sym_index = 0;
12947
12948 if (reloc)
12949 {
dda8d76d 12950 reloc_type = get_reloc_type (filedata, reloc->r_info);
f84ce13b
NC
12951 sym_index = get_reloc_symindex (reloc->r_info);
12952 }
252b5132 12953
dda8d76d 12954 switch (filedata->file_header.e_machine)
252b5132 12955 {
13761a11
NC
12956 case EM_MSP430:
12957 case EM_MSP430_OLD:
12958 {
12959 static Elf_Internal_Sym * saved_sym = NULL;
12960
f84ce13b
NC
12961 if (reloc == NULL)
12962 {
12963 saved_sym = NULL;
12964 return TRUE;
12965 }
12966
13761a11
NC
12967 switch (reloc_type)
12968 {
12969 case 10: /* R_MSP430_SYM_DIFF */
7d81bc93 12970 case 12: /* R_MSP430_GNU_SUB_ULEB128 */
dda8d76d 12971 if (uses_msp430x_relocs (filedata))
13761a11 12972 break;
1a0670f3 12973 /* Fall through. */
13761a11 12974 case 21: /* R_MSP430X_SYM_DIFF */
7d81bc93 12975 case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
f84ce13b
NC
12976 /* PR 21139. */
12977 if (sym_index >= num_syms)
12978 error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
12979 sym_index);
12980 else
12981 saved_sym = symtab + sym_index;
13761a11
NC
12982 return TRUE;
12983
12984 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
12985 case 3: /* R_MSP430_16 or R_MSP430_ABS8 */
12986 goto handle_sym_diff;
0b4362b0 12987
13761a11
NC
12988 case 5: /* R_MSP430_16_BYTE */
12989 case 9: /* R_MSP430_8 */
7d81bc93 12990 case 11: /* R_MSP430_GNU_SET_ULEB128 */
dda8d76d 12991 if (uses_msp430x_relocs (filedata))
13761a11
NC
12992 break;
12993 goto handle_sym_diff;
12994
12995 case 2: /* R_MSP430_ABS16 */
12996 case 15: /* R_MSP430X_ABS16 */
7d81bc93 12997 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
dda8d76d 12998 if (! uses_msp430x_relocs (filedata))
13761a11
NC
12999 break;
13000 goto handle_sym_diff;
0b4362b0 13001
13761a11
NC
13002 handle_sym_diff:
13003 if (saved_sym != NULL)
13004 {
13005 bfd_vma value;
5a805384 13006 unsigned int reloc_size = 0;
7d81bc93
JL
13007 int leb_ret = 0;
13008 switch (reloc_type)
13009 {
13010 case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
13011 reloc_size = 4;
13012 break;
13013 case 11: /* R_MSP430_GNU_SET_ULEB128 */
13014 case 22: /* R_MSP430X_GNU_SET_ULEB128 */
5a805384
AM
13015 if (reloc->r_offset < (size_t) (end - start))
13016 read_leb128 (start + reloc->r_offset, end, FALSE,
13017 &reloc_size, &leb_ret);
7d81bc93
JL
13018 break;
13019 default:
13020 reloc_size = 2;
13021 break;
13022 }
13761a11 13023
5a805384 13024 if (leb_ret != 0 || reloc_size == 0 || reloc_size > 8)
7d81bc93
JL
13025 error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
13026 "ULEB128 value\n"),
13027 (long) reloc->r_offset);
13028 else if (sym_index >= num_syms)
f84ce13b
NC
13029 error (_("MSP430 reloc contains invalid symbol index %lu\n"),
13030 sym_index);
03f7786e 13031 else
f84ce13b
NC
13032 {
13033 value = reloc->r_addend + (symtab[sym_index].st_value
13034 - saved_sym->st_value);
13035
b32e566b 13036 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13037 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13038 else
13039 /* PR 21137 */
13040 error (_("MSP430 sym diff reloc contains invalid offset: 0x%lx\n"),
13041 (long) reloc->r_offset);
f84ce13b 13042 }
13761a11
NC
13043
13044 saved_sym = NULL;
13045 return TRUE;
13046 }
13047 break;
13048
13049 default:
13050 if (saved_sym != NULL)
071436c6 13051 error (_("Unhandled MSP430 reloc type found after SYM_DIFF reloc\n"));
13761a11
NC
13052 break;
13053 }
13054 break;
13055 }
13056
cf13d699
NC
13057 case EM_MN10300:
13058 case EM_CYGNUS_MN10300:
13059 {
13060 static Elf_Internal_Sym * saved_sym = NULL;
252b5132 13061
f84ce13b
NC
13062 if (reloc == NULL)
13063 {
13064 saved_sym = NULL;
13065 return TRUE;
13066 }
13067
cf13d699
NC
13068 switch (reloc_type)
13069 {
13070 case 34: /* R_MN10300_ALIGN */
13071 return TRUE;
13072 case 33: /* R_MN10300_SYM_DIFF */
f84ce13b
NC
13073 if (sym_index >= num_syms)
13074 error (_("MN10300_SYM_DIFF reloc contains invalid symbol index %lu\n"),
13075 sym_index);
13076 else
13077 saved_sym = symtab + sym_index;
cf13d699 13078 return TRUE;
f84ce13b 13079
cf13d699
NC
13080 case 1: /* R_MN10300_32 */
13081 case 2: /* R_MN10300_16 */
13082 if (saved_sym != NULL)
13083 {
03f7786e 13084 int reloc_size = reloc_type == 1 ? 4 : 2;
cf13d699 13085 bfd_vma value;
252b5132 13086
f84ce13b
NC
13087 if (sym_index >= num_syms)
13088 error (_("MN10300 reloc contains invalid symbol index %lu\n"),
13089 sym_index);
03f7786e 13090 else
f84ce13b
NC
13091 {
13092 value = reloc->r_addend + (symtab[sym_index].st_value
13093 - saved_sym->st_value);
13094
b32e566b 13095 if (IN_RANGE (start, end, start + reloc->r_offset, reloc_size))
f84ce13b 13096 byte_put (start + reloc->r_offset, value, reloc_size);
b32e566b
NC
13097 else
13098 error (_("MN10300 sym diff reloc contains invalid offset: 0x%lx\n"),
13099 (long) reloc->r_offset);
f84ce13b 13100 }
252b5132 13101
cf13d699
NC
13102 saved_sym = NULL;
13103 return TRUE;
13104 }
13105 break;
13106 default:
13107 if (saved_sym != NULL)
071436c6 13108 error (_("Unhandled MN10300 reloc type found after SYM_DIFF reloc\n"));
cf13d699
NC
13109 break;
13110 }
13111 break;
13112 }
6ff71e76
NC
13113
13114 case EM_RL78:
13115 {
13116 static bfd_vma saved_sym1 = 0;
13117 static bfd_vma saved_sym2 = 0;
13118 static bfd_vma value;
13119
f84ce13b
NC
13120 if (reloc == NULL)
13121 {
13122 saved_sym1 = saved_sym2 = 0;
13123 return TRUE;
13124 }
13125
6ff71e76
NC
13126 switch (reloc_type)
13127 {
13128 case 0x80: /* R_RL78_SYM. */
13129 saved_sym1 = saved_sym2;
f84ce13b
NC
13130 if (sym_index >= num_syms)
13131 error (_("RL78_SYM reloc contains invalid symbol index %lu\n"),
13132 sym_index);
13133 else
13134 {
13135 saved_sym2 = symtab[sym_index].st_value;
13136 saved_sym2 += reloc->r_addend;
13137 }
6ff71e76
NC
13138 return TRUE;
13139
13140 case 0x83: /* R_RL78_OPsub. */
13141 value = saved_sym1 - saved_sym2;
13142 saved_sym2 = saved_sym1 = 0;
13143 return TRUE;
13144 break;
13145
13146 case 0x41: /* R_RL78_ABS32. */
b32e566b 13147 if (IN_RANGE (start, end, start + reloc->r_offset, 4))
03f7786e 13148 byte_put (start + reloc->r_offset, value, 4);
b32e566b
NC
13149 else
13150 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13151 (long) reloc->r_offset);
6ff71e76
NC
13152 value = 0;
13153 return TRUE;
13154
13155 case 0x43: /* R_RL78_ABS16. */
b32e566b 13156 if (IN_RANGE (start, end, start + reloc->r_offset, 2))
03f7786e 13157 byte_put (start + reloc->r_offset, value, 2);
b32e566b
NC
13158 else
13159 error (_("RL78 sym diff reloc contains invalid offset: 0x%lx\n"),
13160 (long) reloc->r_offset);
6ff71e76
NC
13161 value = 0;
13162 return TRUE;
13163
13164 default:
13165 break;
13166 }
13167 break;
13168 }
252b5132
RH
13169 }
13170
cf13d699 13171 return FALSE;
252b5132
RH
13172}
13173
aca88567
NC
13174/* Returns TRUE iff RELOC_TYPE is a 32-bit absolute RELA relocation used in
13175 DWARF debug sections. This is a target specific test. Note - we do not
13176 go through the whole including-target-headers-multiple-times route, (as
13177 we have already done with <elf/h8.h>) because this would become very
13178 messy and even then this function would have to contain target specific
13179 information (the names of the relocs instead of their numeric values).
13180 FIXME: This is not the correct way to solve this problem. The proper way
13181 is to have target specific reloc sizing and typing functions created by
13182 the reloc-macros.h header, in the same way that it already creates the
13183 reloc naming functions. */
13184
13185static bfd_boolean
dda8d76d 13186is_32bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13187{
d347c9df 13188 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13189 switch (filedata->file_header.e_machine)
aca88567 13190 {
41e92641 13191 case EM_386:
22abe556 13192 case EM_IAMCU:
41e92641 13193 return reloc_type == 1; /* R_386_32. */
aca88567
NC
13194 case EM_68K:
13195 return reloc_type == 1; /* R_68K_32. */
f954747f
AM
13196 case EM_860:
13197 return reloc_type == 1; /* R_860_32. */
13198 case EM_960:
13199 return reloc_type == 2; /* R_960_32. */
a06ea964 13200 case EM_AARCH64:
9282b95a
JW
13201 return (reloc_type == 258
13202 || reloc_type == 1); /* R_AARCH64_ABS32 || R_AARCH64_P32_ABS32 */
aca4efc7
JM
13203 case EM_BPF:
13204 return reloc_type == 11; /* R_BPF_DATA_32 */
d347c9df
PS
13205 case EM_ADAPTEVA_EPIPHANY:
13206 return reloc_type == 3;
aca88567 13207 case EM_ALPHA:
137b6b5f 13208 return reloc_type == 1; /* R_ALPHA_REFLONG. */
41e92641
NC
13209 case EM_ARC:
13210 return reloc_type == 1; /* R_ARC_32. */
886a2506
NC
13211 case EM_ARC_COMPACT:
13212 case EM_ARC_COMPACT2:
13213 return reloc_type == 4; /* R_ARC_32. */
41e92641
NC
13214 case EM_ARM:
13215 return reloc_type == 2; /* R_ARM_ABS32 */
cb8f3167 13216 case EM_AVR_OLD:
aca88567
NC
13217 case EM_AVR:
13218 return reloc_type == 1;
13219 case EM_BLACKFIN:
13220 return reloc_type == 0x12; /* R_byte4_data. */
13221 case EM_CRIS:
13222 return reloc_type == 3; /* R_CRIS_32. */
13223 case EM_CR16:
13224 return reloc_type == 3; /* R_CR16_NUM32. */
13225 case EM_CRX:
13226 return reloc_type == 15; /* R_CRX_NUM32. */
b8891f8d
AJ
13227 case EM_CSKY:
13228 return reloc_type == 1; /* R_CKCORE_ADDR32. */
aca88567
NC
13229 case EM_CYGNUS_FRV:
13230 return reloc_type == 1;
41e92641
NC
13231 case EM_CYGNUS_D10V:
13232 case EM_D10V:
13233 return reloc_type == 6; /* R_D10V_32. */
aca88567
NC
13234 case EM_CYGNUS_D30V:
13235 case EM_D30V:
13236 return reloc_type == 12; /* R_D30V_32_NORMAL. */
41e92641
NC
13237 case EM_DLX:
13238 return reloc_type == 3; /* R_DLX_RELOC_32. */
aca88567
NC
13239 case EM_CYGNUS_FR30:
13240 case EM_FR30:
13241 return reloc_type == 3; /* R_FR30_32. */
3f8107ab
AM
13242 case EM_FT32:
13243 return reloc_type == 1; /* R_FT32_32. */
aca88567
NC
13244 case EM_H8S:
13245 case EM_H8_300:
13246 case EM_H8_300H:
13247 return reloc_type == 1; /* R_H8_DIR32. */
3730236a 13248 case EM_IA_64:
262cdac7
AM
13249 return (reloc_type == 0x64 /* R_IA64_SECREL32MSB. */
13250 || reloc_type == 0x65 /* R_IA64_SECREL32LSB. */
13251 || reloc_type == 0x24 /* R_IA64_DIR32MSB. */
13252 || reloc_type == 0x25 /* R_IA64_DIR32LSB. */);
aca88567
NC
13253 case EM_IP2K_OLD:
13254 case EM_IP2K:
13255 return reloc_type == 2; /* R_IP2K_32. */
13256 case EM_IQ2000:
13257 return reloc_type == 2; /* R_IQ2000_32. */
84e94c90
NC
13258 case EM_LATTICEMICO32:
13259 return reloc_type == 3; /* R_LM32_32. */
ff7eeb89 13260 case EM_M32C_OLD:
aca88567
NC
13261 case EM_M32C:
13262 return reloc_type == 3; /* R_M32C_32. */
13263 case EM_M32R:
13264 return reloc_type == 34; /* R_M32R_32_RELA. */
adec12c1
AM
13265 case EM_68HC11:
13266 case EM_68HC12:
13267 return reloc_type == 6; /* R_M68HC11_32. */
7b4ae824 13268 case EM_S12Z:
2849d19f
JD
13269 return reloc_type == 7 || /* R_S12Z_EXT32 */
13270 reloc_type == 6; /* R_S12Z_CW32. */
aca88567
NC
13271 case EM_MCORE:
13272 return reloc_type == 1; /* R_MCORE_ADDR32. */
13273 case EM_CYGNUS_MEP:
13274 return reloc_type == 4; /* R_MEP_32. */
a3c62988
NC
13275 case EM_METAG:
13276 return reloc_type == 2; /* R_METAG_ADDR32. */
137b6b5f
AM
13277 case EM_MICROBLAZE:
13278 return reloc_type == 1; /* R_MICROBLAZE_32. */
aca88567
NC
13279 case EM_MIPS:
13280 return reloc_type == 2; /* R_MIPS_32. */
13281 case EM_MMIX:
13282 return reloc_type == 4; /* R_MMIX_32. */
13283 case EM_CYGNUS_MN10200:
13284 case EM_MN10200:
13285 return reloc_type == 1; /* R_MN10200_32. */
13286 case EM_CYGNUS_MN10300:
13287 case EM_MN10300:
13288 return reloc_type == 1; /* R_MN10300_32. */
5506d11a
AM
13289 case EM_MOXIE:
13290 return reloc_type == 1; /* R_MOXIE_32. */
aca88567
NC
13291 case EM_MSP430_OLD:
13292 case EM_MSP430:
13761a11 13293 return reloc_type == 1; /* R_MSP430_32 or R_MSP320_ABS32. */
aca88567
NC
13294 case EM_MT:
13295 return reloc_type == 2; /* R_MT_32. */
35c08157
KLC
13296 case EM_NDS32:
13297 return reloc_type == 20; /* R_NDS32_RELA. */
3e0873ac 13298 case EM_ALTERA_NIOS2:
36591ba1 13299 return reloc_type == 12; /* R_NIOS2_BFD_RELOC_32. */
3e0873ac
NC
13300 case EM_NIOS32:
13301 return reloc_type == 1; /* R_NIOS_32. */
73589c9d
CS
13302 case EM_OR1K:
13303 return reloc_type == 1; /* R_OR1K_32. */
aca88567 13304 case EM_PARISC:
9abca702 13305 return (reloc_type == 1 /* R_PARISC_DIR32. */
0df8ad28 13306 || reloc_type == 2 /* R_PARISC_DIR21L. */
5fda8eca 13307 || reloc_type == 41); /* R_PARISC_SECREL32. */
aca88567
NC
13308 case EM_PJ:
13309 case EM_PJ_OLD:
13310 return reloc_type == 1; /* R_PJ_DATA_DIR32. */
13311 case EM_PPC64:
13312 return reloc_type == 1; /* R_PPC64_ADDR32. */
13313 case EM_PPC:
13314 return reloc_type == 1; /* R_PPC_ADDR32. */
2b100bb5
DD
13315 case EM_TI_PRU:
13316 return reloc_type == 11; /* R_PRU_BFD_RELOC_32. */
e23eba97
NC
13317 case EM_RISCV:
13318 return reloc_type == 1; /* R_RISCV_32. */
99c513f6
DD
13319 case EM_RL78:
13320 return reloc_type == 1; /* R_RL78_DIR32. */
c7927a3c
NC
13321 case EM_RX:
13322 return reloc_type == 1; /* R_RX_DIR32. */
f954747f
AM
13323 case EM_S370:
13324 return reloc_type == 1; /* R_I370_ADDR31. */
aca88567
NC
13325 case EM_S390_OLD:
13326 case EM_S390:
13327 return reloc_type == 4; /* R_S390_32. */
41e92641
NC
13328 case EM_SCORE:
13329 return reloc_type == 8; /* R_SCORE_ABS32. */
aca88567
NC
13330 case EM_SH:
13331 return reloc_type == 1; /* R_SH_DIR32. */
13332 case EM_SPARC32PLUS:
13333 case EM_SPARCV9:
13334 case EM_SPARC:
13335 return reloc_type == 3 /* R_SPARC_32. */
13336 || reloc_type == 23; /* R_SPARC_UA32. */
a7dd7d05
AM
13337 case EM_SPU:
13338 return reloc_type == 6; /* R_SPU_ADDR32 */
40b36596
JM
13339 case EM_TI_C6000:
13340 return reloc_type == 1; /* R_C6000_ABS32. */
aa137e4d
NC
13341 case EM_TILEGX:
13342 return reloc_type == 2; /* R_TILEGX_32. */
13343 case EM_TILEPRO:
13344 return reloc_type == 1; /* R_TILEPRO_32. */
aca88567
NC
13345 case EM_CYGNUS_V850:
13346 case EM_V850:
13347 return reloc_type == 6; /* R_V850_ABS32. */
708e2187
NC
13348 case EM_V800:
13349 return reloc_type == 0x33; /* R_V810_WORD. */
aca88567
NC
13350 case EM_VAX:
13351 return reloc_type == 1; /* R_VAX_32. */
619ed720
EB
13352 case EM_VISIUM:
13353 return reloc_type == 3; /* R_VISIUM_32. */
f96bd6c2
PC
13354 case EM_WEBASSEMBLY:
13355 return reloc_type == 1; /* R_WASM32_32. */
aca88567 13356 case EM_X86_64:
8a9036a4 13357 case EM_L1OM:
7a9068fe 13358 case EM_K1OM:
aca88567 13359 return reloc_type == 10; /* R_X86_64_32. */
c29aca4a
NC
13360 case EM_XC16X:
13361 case EM_C166:
13362 return reloc_type == 3; /* R_XC16C_ABS_32. */
f6c1a2d5
NC
13363 case EM_XGATE:
13364 return reloc_type == 4; /* R_XGATE_32. */
aca88567
NC
13365 case EM_XSTORMY16:
13366 return reloc_type == 1; /* R_XSTROMY16_32. */
13367 case EM_XTENSA_OLD:
13368 case EM_XTENSA:
13369 return reloc_type == 1; /* R_XTENSA_32. */
6655dba2
SB
13370 case EM_Z80:
13371 return reloc_type == 6; /* R_Z80_32. */
aca88567 13372 default:
bee0ee85
NC
13373 {
13374 static unsigned int prev_warn = 0;
13375
13376 /* Avoid repeating the same warning multiple times. */
dda8d76d 13377 if (prev_warn != filedata->file_header.e_machine)
bee0ee85 13378 error (_("Missing knowledge of 32-bit reloc types used in DWARF sections of machine number %d\n"),
dda8d76d
NC
13379 filedata->file_header.e_machine);
13380 prev_warn = filedata->file_header.e_machine;
bee0ee85
NC
13381 return FALSE;
13382 }
aca88567
NC
13383 }
13384}
13385
13386/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13387 a 32-bit pc-relative RELA relocation used in DWARF debug sections. */
13388
13389static bfd_boolean
dda8d76d 13390is_32bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13391{
dda8d76d 13392 switch (filedata->file_header.e_machine)
d347c9df 13393 /* Please keep this table alpha-sorted for ease of visual lookup. */
aca88567 13394 {
41e92641 13395 case EM_386:
22abe556 13396 case EM_IAMCU:
3e0873ac 13397 return reloc_type == 2; /* R_386_PC32. */
aca88567 13398 case EM_68K:
3e0873ac 13399 return reloc_type == 4; /* R_68K_PC32. */
a06ea964
NC
13400 case EM_AARCH64:
13401 return reloc_type == 261; /* R_AARCH64_PREL32 */
cfb8c092
NC
13402 case EM_ADAPTEVA_EPIPHANY:
13403 return reloc_type == 6;
aca88567
NC
13404 case EM_ALPHA:
13405 return reloc_type == 10; /* R_ALPHA_SREL32. */
726c18e1
CZ
13406 case EM_ARC_COMPACT:
13407 case EM_ARC_COMPACT2:
13408 return reloc_type == 49; /* R_ARC_32_PCREL. */
41e92641 13409 case EM_ARM:
3e0873ac 13410 return reloc_type == 3; /* R_ARM_REL32 */
d347c9df
PS
13411 case EM_AVR_OLD:
13412 case EM_AVR:
13413 return reloc_type == 36; /* R_AVR_32_PCREL. */
137b6b5f
AM
13414 case EM_MICROBLAZE:
13415 return reloc_type == 2; /* R_MICROBLAZE_32_PCREL. */
73589c9d
CS
13416 case EM_OR1K:
13417 return reloc_type == 9; /* R_OR1K_32_PCREL. */
aca88567 13418 case EM_PARISC:
85acf597 13419 return reloc_type == 9; /* R_PARISC_PCREL32. */
aca88567
NC
13420 case EM_PPC:
13421 return reloc_type == 26; /* R_PPC_REL32. */
13422 case EM_PPC64:
3e0873ac 13423 return reloc_type == 26; /* R_PPC64_REL32. */
25cbdcbb
AS
13424 case EM_RISCV:
13425 return reloc_type == 57; /* R_RISCV_32_PCREL. */
aca88567
NC
13426 case EM_S390_OLD:
13427 case EM_S390:
3e0873ac 13428 return reloc_type == 5; /* R_390_PC32. */
aca88567 13429 case EM_SH:
3e0873ac 13430 return reloc_type == 2; /* R_SH_REL32. */
aca88567
NC
13431 case EM_SPARC32PLUS:
13432 case EM_SPARCV9:
13433 case EM_SPARC:
3e0873ac 13434 return reloc_type == 6; /* R_SPARC_DISP32. */
a7dd7d05
AM
13435 case EM_SPU:
13436 return reloc_type == 13; /* R_SPU_REL32. */
aa137e4d
NC
13437 case EM_TILEGX:
13438 return reloc_type == 6; /* R_TILEGX_32_PCREL. */
13439 case EM_TILEPRO:
13440 return reloc_type == 4; /* R_TILEPRO_32_PCREL. */
619ed720
EB
13441 case EM_VISIUM:
13442 return reloc_type == 6; /* R_VISIUM_32_PCREL */
aca88567 13443 case EM_X86_64:
8a9036a4 13444 case EM_L1OM:
7a9068fe 13445 case EM_K1OM:
3e0873ac 13446 return reloc_type == 2; /* R_X86_64_PC32. */
2057d69d
CZ
13447 case EM_VAX:
13448 return reloc_type == 4; /* R_VAX_PCREL32. */
2fcb9706
BW
13449 case EM_XTENSA_OLD:
13450 case EM_XTENSA:
13451 return reloc_type == 14; /* R_XTENSA_32_PCREL. */
aca88567
NC
13452 default:
13453 /* Do not abort or issue an error message here. Not all targets use
13454 pc-relative 32-bit relocs in their DWARF debug information and we
13455 have already tested for target coverage in is_32bit_abs_reloc. A
cf13d699
NC
13456 more helpful warning message will be generated by apply_relocations
13457 anyway, so just return. */
aca88567
NC
13458 return FALSE;
13459 }
13460}
13461
13462/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13463 a 64-bit absolute RELA relocation used in DWARF debug sections. */
13464
13465static bfd_boolean
dda8d76d 13466is_64bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
aca88567 13467{
dda8d76d 13468 switch (filedata->file_header.e_machine)
aca88567 13469 {
a06ea964
NC
13470 case EM_AARCH64:
13471 return reloc_type == 257; /* R_AARCH64_ABS64. */
aca88567
NC
13472 case EM_ALPHA:
13473 return reloc_type == 2; /* R_ALPHA_REFQUAD. */
3730236a 13474 case EM_IA_64:
262cdac7
AM
13475 return (reloc_type == 0x26 /* R_IA64_DIR64MSB. */
13476 || reloc_type == 0x27 /* R_IA64_DIR64LSB. */);
3e0873ac
NC
13477 case EM_PARISC:
13478 return reloc_type == 80; /* R_PARISC_DIR64. */
aca88567
NC
13479 case EM_PPC64:
13480 return reloc_type == 38; /* R_PPC64_ADDR64. */
e23eba97
NC
13481 case EM_RISCV:
13482 return reloc_type == 2; /* R_RISCV_64. */
aca88567
NC
13483 case EM_SPARC32PLUS:
13484 case EM_SPARCV9:
13485 case EM_SPARC:
714da62f
NC
13486 return reloc_type == 32 /* R_SPARC_64. */
13487 || reloc_type == 54; /* R_SPARC_UA64. */
aca88567 13488 case EM_X86_64:
8a9036a4 13489 case EM_L1OM:
7a9068fe 13490 case EM_K1OM:
aca88567 13491 return reloc_type == 1; /* R_X86_64_64. */
e819ade1
AS
13492 case EM_S390_OLD:
13493 case EM_S390:
aa137e4d
NC
13494 return reloc_type == 22; /* R_S390_64. */
13495 case EM_TILEGX:
13496 return reloc_type == 1; /* R_TILEGX_64. */
85a82265 13497 case EM_MIPS:
aa137e4d 13498 return reloc_type == 18; /* R_MIPS_64. */
aca88567
NC
13499 default:
13500 return FALSE;
13501 }
13502}
13503
85acf597
RH
13504/* Like is_32bit_pcrel_reloc except that it returns TRUE iff RELOC_TYPE is
13505 a 64-bit pc-relative RELA relocation used in DWARF debug sections. */
13506
13507static bfd_boolean
dda8d76d 13508is_64bit_pcrel_reloc (Filedata * filedata, unsigned int reloc_type)
85acf597 13509{
dda8d76d 13510 switch (filedata->file_header.e_machine)
85acf597 13511 {
a06ea964
NC
13512 case EM_AARCH64:
13513 return reloc_type == 260; /* R_AARCH64_PREL64. */
85acf597 13514 case EM_ALPHA:
aa137e4d 13515 return reloc_type == 11; /* R_ALPHA_SREL64. */
85acf597 13516 case EM_IA_64:
262cdac7
AM
13517 return (reloc_type == 0x4e /* R_IA64_PCREL64MSB. */
13518 || reloc_type == 0x4f /* R_IA64_PCREL64LSB. */);
85acf597 13519 case EM_PARISC:
aa137e4d 13520 return reloc_type == 72; /* R_PARISC_PCREL64. */
85acf597 13521 case EM_PPC64:
aa137e4d 13522 return reloc_type == 44; /* R_PPC64_REL64. */
85acf597
RH
13523 case EM_SPARC32PLUS:
13524 case EM_SPARCV9:
13525 case EM_SPARC:
aa137e4d 13526 return reloc_type == 46; /* R_SPARC_DISP64. */
85acf597 13527 case EM_X86_64:
8a9036a4 13528 case EM_L1OM:
7a9068fe 13529 case EM_K1OM:
aa137e4d 13530 return reloc_type == 24; /* R_X86_64_PC64. */
85acf597
RH
13531 case EM_S390_OLD:
13532 case EM_S390:
aa137e4d
NC
13533 return reloc_type == 23; /* R_S390_PC64. */
13534 case EM_TILEGX:
13535 return reloc_type == 5; /* R_TILEGX_64_PCREL. */
85acf597
RH
13536 default:
13537 return FALSE;
13538 }
13539}
13540
4dc3c23d
AM
13541/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13542 a 24-bit absolute RELA relocation used in DWARF debug sections. */
13543
13544static bfd_boolean
dda8d76d 13545is_24bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4dc3c23d 13546{
dda8d76d 13547 switch (filedata->file_header.e_machine)
4dc3c23d
AM
13548 {
13549 case EM_CYGNUS_MN10200:
13550 case EM_MN10200:
13551 return reloc_type == 4; /* R_MN10200_24. */
3ee6e4fb
NC
13552 case EM_FT32:
13553 return reloc_type == 5; /* R_FT32_20. */
6655dba2
SB
13554 case EM_Z80:
13555 return reloc_type == 5; /* R_Z80_24. */
4dc3c23d
AM
13556 default:
13557 return FALSE;
13558 }
13559}
13560
aca88567
NC
13561/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13562 a 16-bit absolute RELA relocation used in DWARF debug sections. */
13563
13564static bfd_boolean
dda8d76d 13565is_16bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
4b78141a 13566{
d347c9df 13567 /* Please keep this table alpha-sorted for ease of visual lookup. */
dda8d76d 13568 switch (filedata->file_header.e_machine)
4b78141a 13569 {
886a2506
NC
13570 case EM_ARC:
13571 case EM_ARC_COMPACT:
13572 case EM_ARC_COMPACT2:
13573 return reloc_type == 2; /* R_ARC_16. */
d347c9df
PS
13574 case EM_ADAPTEVA_EPIPHANY:
13575 return reloc_type == 5;
aca88567
NC
13576 case EM_AVR_OLD:
13577 case EM_AVR:
13578 return reloc_type == 4; /* R_AVR_16. */
41e92641
NC
13579 case EM_CYGNUS_D10V:
13580 case EM_D10V:
13581 return reloc_type == 3; /* R_D10V_16. */
81b42bca
JB
13582 case EM_FT32:
13583 return reloc_type == 2; /* R_FT32_16. */
4b78141a
NC
13584 case EM_H8S:
13585 case EM_H8_300:
13586 case EM_H8_300H:
aca88567
NC
13587 return reloc_type == R_H8_DIR16;
13588 case EM_IP2K_OLD:
13589 case EM_IP2K:
13590 return reloc_type == 1; /* R_IP2K_16. */
ff7eeb89 13591 case EM_M32C_OLD:
f4236fe4
DD
13592 case EM_M32C:
13593 return reloc_type == 1; /* R_M32C_16 */
d347c9df
PS
13594 case EM_CYGNUS_MN10200:
13595 case EM_MN10200:
13596 return reloc_type == 2; /* R_MN10200_16. */
13597 case EM_CYGNUS_MN10300:
13598 case EM_MN10300:
13599 return reloc_type == 2; /* R_MN10300_16. */
aca88567 13600 case EM_MSP430:
dda8d76d 13601 if (uses_msp430x_relocs (filedata))
13761a11 13602 return reloc_type == 2; /* R_MSP430_ABS16. */
1a0670f3 13603 /* Fall through. */
78c8d46c 13604 case EM_MSP430_OLD:
aca88567 13605 return reloc_type == 5; /* R_MSP430_16_BYTE. */
35c08157
KLC
13606 case EM_NDS32:
13607 return reloc_type == 19; /* R_NDS32_RELA. */
3e0873ac 13608 case EM_ALTERA_NIOS2:
36591ba1 13609 return reloc_type == 13; /* R_NIOS2_BFD_RELOC_16. */
3e0873ac
NC
13610 case EM_NIOS32:
13611 return reloc_type == 9; /* R_NIOS_16. */
73589c9d
CS
13612 case EM_OR1K:
13613 return reloc_type == 2; /* R_OR1K_16. */
39e07931
AS
13614 case EM_RISCV:
13615 return reloc_type == 55; /* R_RISCV_SET16. */
2b100bb5
DD
13616 case EM_TI_PRU:
13617 return reloc_type == 8; /* R_PRU_BFD_RELOC_16. */
40b36596
JM
13618 case EM_TI_C6000:
13619 return reloc_type == 2; /* R_C6000_ABS16. */
d347c9df
PS
13620 case EM_VISIUM:
13621 return reloc_type == 2; /* R_VISIUM_16. */
c29aca4a
NC
13622 case EM_XC16X:
13623 case EM_C166:
13624 return reloc_type == 2; /* R_XC16C_ABS_16. */
f6c1a2d5
NC
13625 case EM_XGATE:
13626 return reloc_type == 3; /* R_XGATE_16. */
6655dba2
SB
13627 case EM_Z80:
13628 return reloc_type == 4; /* R_Z80_16. */
4b78141a 13629 default:
aca88567 13630 return FALSE;
4b78141a
NC
13631 }
13632}
13633
39e07931
AS
13634/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13635 a 8-bit absolute RELA relocation used in DWARF debug sections. */
13636
13637static bfd_boolean
13638is_8bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13639{
13640 switch (filedata->file_header.e_machine)
13641 {
13642 case EM_RISCV:
13643 return reloc_type == 54; /* R_RISCV_SET8. */
6655dba2
SB
13644 case EM_Z80:
13645 return reloc_type == 1; /* R_Z80_8. */
39e07931
AS
13646 default:
13647 return FALSE;
13648 }
13649}
13650
13651/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13652 a 6-bit absolute RELA relocation used in DWARF debug sections. */
13653
13654static bfd_boolean
13655is_6bit_abs_reloc (Filedata * filedata, unsigned int reloc_type)
13656{
13657 switch (filedata->file_header.e_machine)
13658 {
13659 case EM_RISCV:
13660 return reloc_type == 53; /* R_RISCV_SET6. */
13661 default:
13662 return FALSE;
13663 }
13664}
13665
03336641
JW
13666/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13667 a 32-bit inplace add RELA relocation used in DWARF debug sections. */
13668
13669static bfd_boolean
13670is_32bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13671{
13672 /* Please keep this table alpha-sorted for ease of visual lookup. */
13673 switch (filedata->file_header.e_machine)
13674 {
13675 case EM_RISCV:
13676 return reloc_type == 35; /* R_RISCV_ADD32. */
13677 default:
13678 return FALSE;
13679 }
13680}
13681
13682/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13683 a 32-bit inplace sub RELA relocation used in DWARF debug sections. */
13684
13685static bfd_boolean
13686is_32bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13687{
13688 /* Please keep this table alpha-sorted for ease of visual lookup. */
13689 switch (filedata->file_header.e_machine)
13690 {
13691 case EM_RISCV:
13692 return reloc_type == 39; /* R_RISCV_SUB32. */
13693 default:
13694 return FALSE;
13695 }
13696}
13697
13698/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13699 a 64-bit inplace add RELA relocation used in DWARF debug sections. */
13700
13701static bfd_boolean
13702is_64bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13703{
13704 /* Please keep this table alpha-sorted for ease of visual lookup. */
13705 switch (filedata->file_header.e_machine)
13706 {
13707 case EM_RISCV:
13708 return reloc_type == 36; /* R_RISCV_ADD64. */
13709 default:
13710 return FALSE;
13711 }
13712}
13713
13714/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13715 a 64-bit inplace sub RELA relocation used in DWARF debug sections. */
13716
13717static bfd_boolean
13718is_64bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13719{
13720 /* Please keep this table alpha-sorted for ease of visual lookup. */
13721 switch (filedata->file_header.e_machine)
13722 {
13723 case EM_RISCV:
13724 return reloc_type == 40; /* R_RISCV_SUB64. */
13725 default:
13726 return FALSE;
13727 }
13728}
13729
13730/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13731 a 16-bit inplace add RELA relocation used in DWARF debug sections. */
13732
13733static bfd_boolean
13734is_16bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13735{
13736 /* Please keep this table alpha-sorted for ease of visual lookup. */
13737 switch (filedata->file_header.e_machine)
13738 {
13739 case EM_RISCV:
13740 return reloc_type == 34; /* R_RISCV_ADD16. */
13741 default:
13742 return FALSE;
13743 }
13744}
13745
13746/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13747 a 16-bit inplace sub RELA relocation used in DWARF debug sections. */
13748
13749static bfd_boolean
13750is_16bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13751{
13752 /* Please keep this table alpha-sorted for ease of visual lookup. */
13753 switch (filedata->file_header.e_machine)
13754 {
13755 case EM_RISCV:
13756 return reloc_type == 38; /* R_RISCV_SUB16. */
13757 default:
13758 return FALSE;
13759 }
13760}
13761
13762/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13763 a 8-bit inplace add RELA relocation used in DWARF debug sections. */
13764
13765static bfd_boolean
13766is_8bit_inplace_add_reloc (Filedata * filedata, unsigned int reloc_type)
13767{
13768 /* Please keep this table alpha-sorted for ease of visual lookup. */
13769 switch (filedata->file_header.e_machine)
13770 {
13771 case EM_RISCV:
13772 return reloc_type == 33; /* R_RISCV_ADD8. */
13773 default:
13774 return FALSE;
13775 }
13776}
13777
13778/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13779 a 8-bit inplace sub RELA relocation used in DWARF debug sections. */
13780
13781static bfd_boolean
13782is_8bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13783{
13784 /* Please keep this table alpha-sorted for ease of visual lookup. */
13785 switch (filedata->file_header.e_machine)
13786 {
13787 case EM_RISCV:
13788 return reloc_type == 37; /* R_RISCV_SUB8. */
13789 default:
13790 return FALSE;
13791 }
13792}
13793
39e07931
AS
13794/* Like is_32bit_abs_reloc except that it returns TRUE iff RELOC_TYPE is
13795 a 6-bit inplace sub RELA relocation used in DWARF debug sections. */
13796
13797static bfd_boolean
13798is_6bit_inplace_sub_reloc (Filedata * filedata, unsigned int reloc_type)
13799{
13800 switch (filedata->file_header.e_machine)
13801 {
13802 case EM_RISCV:
13803 return reloc_type == 52; /* R_RISCV_SUB6. */
13804 default:
13805 return FALSE;
13806 }
13807}
13808
2a7b2e88
JK
13809/* Returns TRUE iff RELOC_TYPE is a NONE relocation used for discarded
13810 relocation entries (possibly formerly used for SHT_GROUP sections). */
13811
13812static bfd_boolean
dda8d76d 13813is_none_reloc (Filedata * filedata, unsigned int reloc_type)
2a7b2e88 13814{
dda8d76d 13815 switch (filedata->file_header.e_machine)
2a7b2e88 13816 {
cb8f3167 13817 case EM_386: /* R_386_NONE. */
d347c9df 13818 case EM_68K: /* R_68K_NONE. */
cfb8c092 13819 case EM_ADAPTEVA_EPIPHANY:
d347c9df
PS
13820 case EM_ALPHA: /* R_ALPHA_NONE. */
13821 case EM_ALTERA_NIOS2: /* R_NIOS2_NONE. */
886a2506 13822 case EM_ARC: /* R_ARC_NONE. */
886a2506 13823 case EM_ARC_COMPACT2: /* R_ARC_NONE. */
d347c9df 13824 case EM_ARC_COMPACT: /* R_ARC_NONE. */
cb8f3167 13825 case EM_ARM: /* R_ARM_NONE. */
d347c9df 13826 case EM_C166: /* R_XC16X_NONE. */
cb8f3167 13827 case EM_CRIS: /* R_CRIS_NONE. */
d347c9df
PS
13828 case EM_FT32: /* R_FT32_NONE. */
13829 case EM_IA_64: /* R_IA64_NONE. */
7a9068fe 13830 case EM_K1OM: /* R_X86_64_NONE. */
d347c9df
PS
13831 case EM_L1OM: /* R_X86_64_NONE. */
13832 case EM_M32R: /* R_M32R_NONE. */
13833 case EM_MIPS: /* R_MIPS_NONE. */
cb8f3167 13834 case EM_MN10300: /* R_MN10300_NONE. */
5506d11a 13835 case EM_MOXIE: /* R_MOXIE_NONE. */
d347c9df
PS
13836 case EM_NIOS32: /* R_NIOS_NONE. */
13837 case EM_OR1K: /* R_OR1K_NONE. */
13838 case EM_PARISC: /* R_PARISC_NONE. */
13839 case EM_PPC64: /* R_PPC64_NONE. */
13840 case EM_PPC: /* R_PPC_NONE. */
e23eba97 13841 case EM_RISCV: /* R_RISCV_NONE. */
d347c9df
PS
13842 case EM_S390: /* R_390_NONE. */
13843 case EM_S390_OLD:
13844 case EM_SH: /* R_SH_NONE. */
13845 case EM_SPARC32PLUS:
13846 case EM_SPARC: /* R_SPARC_NONE. */
13847 case EM_SPARCV9:
aa137e4d
NC
13848 case EM_TILEGX: /* R_TILEGX_NONE. */
13849 case EM_TILEPRO: /* R_TILEPRO_NONE. */
d347c9df
PS
13850 case EM_TI_C6000:/* R_C6000_NONE. */
13851 case EM_X86_64: /* R_X86_64_NONE. */
c29aca4a 13852 case EM_XC16X:
6655dba2 13853 case EM_Z80: /* R_Z80_NONE. */
f96bd6c2 13854 case EM_WEBASSEMBLY: /* R_WASM32_NONE. */
cb8f3167 13855 return reloc_type == 0;
d347c9df 13856
a06ea964
NC
13857 case EM_AARCH64:
13858 return reloc_type == 0 || reloc_type == 256;
d347c9df
PS
13859 case EM_AVR_OLD:
13860 case EM_AVR:
13861 return (reloc_type == 0 /* R_AVR_NONE. */
13862 || reloc_type == 30 /* R_AVR_DIFF8. */
13863 || reloc_type == 31 /* R_AVR_DIFF16. */
13864 || reloc_type == 32 /* R_AVR_DIFF32. */);
13865 case EM_METAG:
13866 return reloc_type == 3; /* R_METAG_NONE. */
35c08157
KLC
13867 case EM_NDS32:
13868 return (reloc_type == 0 /* R_XTENSA_NONE. */
13869 || reloc_type == 204 /* R_NDS32_DIFF8. */
13870 || reloc_type == 205 /* R_NDS32_DIFF16. */
13871 || reloc_type == 206 /* R_NDS32_DIFF32. */
13872 || reloc_type == 207 /* R_NDS32_ULEB128. */);
2b100bb5
DD
13873 case EM_TI_PRU:
13874 return (reloc_type == 0 /* R_PRU_NONE. */
13875 || reloc_type == 65 /* R_PRU_DIFF8. */
13876 || reloc_type == 66 /* R_PRU_DIFF16. */
13877 || reloc_type == 67 /* R_PRU_DIFF32. */);
58332dda
JK
13878 case EM_XTENSA_OLD:
13879 case EM_XTENSA:
4dc3c23d
AM
13880 return (reloc_type == 0 /* R_XTENSA_NONE. */
13881 || reloc_type == 17 /* R_XTENSA_DIFF8. */
13882 || reloc_type == 18 /* R_XTENSA_DIFF16. */
30ce8e47
MF
13883 || reloc_type == 19 /* R_XTENSA_DIFF32. */
13884 || reloc_type == 57 /* R_XTENSA_PDIFF8. */
13885 || reloc_type == 58 /* R_XTENSA_PDIFF16. */
13886 || reloc_type == 59 /* R_XTENSA_PDIFF32. */
13887 || reloc_type == 60 /* R_XTENSA_NDIFF8. */
13888 || reloc_type == 61 /* R_XTENSA_NDIFF16. */
13889 || reloc_type == 62 /* R_XTENSA_NDIFF32. */);
2a7b2e88
JK
13890 }
13891 return FALSE;
13892}
13893
d1c4b12b
NC
13894/* Returns TRUE if there is a relocation against
13895 section NAME at OFFSET bytes. */
13896
13897bfd_boolean
13898reloc_at (struct dwarf_section * dsec, dwarf_vma offset)
13899{
13900 Elf_Internal_Rela * relocs;
13901 Elf_Internal_Rela * rp;
13902
13903 if (dsec == NULL || dsec->reloc_info == NULL)
13904 return FALSE;
13905
13906 relocs = (Elf_Internal_Rela *) dsec->reloc_info;
13907
13908 for (rp = relocs; rp < relocs + dsec->num_relocs; ++rp)
13909 if (rp->r_offset == offset)
13910 return TRUE;
13911
13912 return FALSE;
13913}
13914
cf13d699 13915/* Apply relocations to a section.
32ec8896
NC
13916 Returns TRUE upon success, FALSE otherwise.
13917 If RELOCS_RETURN is non-NULL then it is set to point to the loaded relocs.
13918 It is then the caller's responsibility to free them. NUM_RELOCS_RETURN
13919 will be set to the number of relocs loaded.
13920
cf13d699 13921 Note: So far support has been added only for those relocations
32ec8896
NC
13922 which can be found in debug sections. FIXME: Add support for
13923 more relocations ? */
1b315056 13924
32ec8896 13925static bfd_boolean
dda8d76d 13926apply_relocations (Filedata * filedata,
d1c4b12b
NC
13927 const Elf_Internal_Shdr * section,
13928 unsigned char * start,
13929 bfd_size_type size,
1449284b 13930 void ** relocs_return,
d1c4b12b 13931 unsigned long * num_relocs_return)
1b315056 13932{
cf13d699 13933 Elf_Internal_Shdr * relsec;
0d2a7a93 13934 unsigned char * end = start + size;
cb8f3167 13935
d1c4b12b
NC
13936 if (relocs_return != NULL)
13937 {
13938 * (Elf_Internal_Rela **) relocs_return = NULL;
13939 * num_relocs_return = 0;
13940 }
13941
dda8d76d 13942 if (filedata->file_header.e_type != ET_REL)
32ec8896
NC
13943 /* No relocs to apply. */
13944 return TRUE;
1b315056 13945
cf13d699 13946 /* Find the reloc section associated with the section. */
dda8d76d
NC
13947 for (relsec = filedata->section_headers;
13948 relsec < filedata->section_headers + filedata->file_header.e_shnum;
5b18a4bc 13949 ++relsec)
252b5132 13950 {
41e92641
NC
13951 bfd_boolean is_rela;
13952 unsigned long num_relocs;
2cf0635d
NC
13953 Elf_Internal_Rela * relocs;
13954 Elf_Internal_Rela * rp;
13955 Elf_Internal_Shdr * symsec;
13956 Elf_Internal_Sym * symtab;
ba5cdace 13957 unsigned long num_syms;
2cf0635d 13958 Elf_Internal_Sym * sym;
252b5132 13959
41e92641 13960 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
13961 || relsec->sh_info >= filedata->file_header.e_shnum
13962 || filedata->section_headers + relsec->sh_info != section
c256ffe7 13963 || relsec->sh_size == 0
dda8d76d 13964 || relsec->sh_link >= filedata->file_header.e_shnum)
5b18a4bc 13965 continue;
428409d5 13966
a788aedd
AM
13967 symsec = filedata->section_headers + relsec->sh_link;
13968 if (symsec->sh_type != SHT_SYMTAB
13969 && symsec->sh_type != SHT_DYNSYM)
13970 return FALSE;
13971
41e92641
NC
13972 is_rela = relsec->sh_type == SHT_RELA;
13973
13974 if (is_rela)
13975 {
dda8d76d 13976 if (!slurp_rela_relocs (filedata, relsec->sh_offset,
3f5e193b 13977 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13978 return FALSE;
41e92641
NC
13979 }
13980 else
13981 {
dda8d76d 13982 if (!slurp_rel_relocs (filedata, relsec->sh_offset,
3f5e193b 13983 relsec->sh_size, & relocs, & num_relocs))
32ec8896 13984 return FALSE;
41e92641
NC
13985 }
13986
13987 /* SH uses RELA but uses in place value instead of the addend field. */
dda8d76d 13988 if (filedata->file_header.e_machine == EM_SH)
41e92641 13989 is_rela = FALSE;
428409d5 13990
dda8d76d 13991 symtab = GET_ELF_SYMBOLS (filedata, symsec, & num_syms);
103f02d3 13992
41e92641 13993 for (rp = relocs; rp < relocs + num_relocs; ++rp)
252b5132 13994 {
41e92641
NC
13995 bfd_vma addend;
13996 unsigned int reloc_type;
13997 unsigned int reloc_size;
03336641
JW
13998 bfd_boolean reloc_inplace = FALSE;
13999 bfd_boolean reloc_subtract = FALSE;
91d6fa6a 14000 unsigned char * rloc;
ba5cdace 14001 unsigned long sym_index;
4b78141a 14002
dda8d76d 14003 reloc_type = get_reloc_type (filedata, rp->r_info);
41e92641 14004
dda8d76d 14005 if (target_specific_reloc_handling (filedata, rp, start, end, symtab, num_syms))
2a7b2e88 14006 continue;
dda8d76d 14007 else if (is_none_reloc (filedata, reloc_type))
98fb390a 14008 continue;
dda8d76d
NC
14009 else if (is_32bit_abs_reloc (filedata, reloc_type)
14010 || is_32bit_pcrel_reloc (filedata, reloc_type))
aca88567 14011 reloc_size = 4;
dda8d76d
NC
14012 else if (is_64bit_abs_reloc (filedata, reloc_type)
14013 || is_64bit_pcrel_reloc (filedata, reloc_type))
aca88567 14014 reloc_size = 8;
dda8d76d 14015 else if (is_24bit_abs_reloc (filedata, reloc_type))
4dc3c23d 14016 reloc_size = 3;
dda8d76d 14017 else if (is_16bit_abs_reloc (filedata, reloc_type))
aca88567 14018 reloc_size = 2;
39e07931
AS
14019 else if (is_8bit_abs_reloc (filedata, reloc_type)
14020 || is_6bit_abs_reloc (filedata, reloc_type))
14021 reloc_size = 1;
03336641
JW
14022 else if ((reloc_subtract = is_32bit_inplace_sub_reloc (filedata,
14023 reloc_type))
14024 || is_32bit_inplace_add_reloc (filedata, reloc_type))
14025 {
14026 reloc_size = 4;
14027 reloc_inplace = TRUE;
14028 }
14029 else if ((reloc_subtract = is_64bit_inplace_sub_reloc (filedata,
14030 reloc_type))
14031 || is_64bit_inplace_add_reloc (filedata, reloc_type))
14032 {
14033 reloc_size = 8;
14034 reloc_inplace = TRUE;
14035 }
14036 else if ((reloc_subtract = is_16bit_inplace_sub_reloc (filedata,
14037 reloc_type))
14038 || is_16bit_inplace_add_reloc (filedata, reloc_type))
14039 {
14040 reloc_size = 2;
14041 reloc_inplace = TRUE;
14042 }
14043 else if ((reloc_subtract = is_8bit_inplace_sub_reloc (filedata,
14044 reloc_type))
14045 || is_8bit_inplace_add_reloc (filedata, reloc_type))
14046 {
14047 reloc_size = 1;
14048 reloc_inplace = TRUE;
14049 }
39e07931
AS
14050 else if ((reloc_subtract = is_6bit_inplace_sub_reloc (filedata,
14051 reloc_type)))
14052 {
14053 reloc_size = 1;
14054 reloc_inplace = TRUE;
14055 }
aca88567 14056 else
4b78141a 14057 {
bee0ee85 14058 static unsigned int prev_reloc = 0;
dda8d76d 14059
bee0ee85
NC
14060 if (reloc_type != prev_reloc)
14061 warn (_("unable to apply unsupported reloc type %d to section %s\n"),
dda8d76d 14062 reloc_type, printable_section_name (filedata, section));
bee0ee85 14063 prev_reloc = reloc_type;
4b78141a
NC
14064 continue;
14065 }
103f02d3 14066
91d6fa6a 14067 rloc = start + rp->r_offset;
75802ccb 14068 if (!IN_RANGE (start, end, rloc, reloc_size))
700dd8b7
L
14069 {
14070 warn (_("skipping invalid relocation offset 0x%lx in section %s\n"),
14071 (unsigned long) rp->r_offset,
dda8d76d 14072 printable_section_name (filedata, section));
700dd8b7
L
14073 continue;
14074 }
103f02d3 14075
ba5cdace
NC
14076 sym_index = (unsigned long) get_reloc_symindex (rp->r_info);
14077 if (sym_index >= num_syms)
14078 {
14079 warn (_("skipping invalid relocation symbol index 0x%lx in section %s\n"),
dda8d76d 14080 sym_index, printable_section_name (filedata, section));
ba5cdace
NC
14081 continue;
14082 }
14083 sym = symtab + sym_index;
41e92641
NC
14084
14085 /* If the reloc has a symbol associated with it,
55f25fc3
L
14086 make sure that it is of an appropriate type.
14087
14088 Relocations against symbols without type can happen.
14089 Gcc -feliminate-dwarf2-dups may generate symbols
14090 without type for debug info.
14091
14092 Icc generates relocations against function symbols
14093 instead of local labels.
14094
14095 Relocations against object symbols can happen, eg when
14096 referencing a global array. For an example of this see
14097 the _clz.o binary in libgcc.a. */
aca88567 14098 if (sym != symtab
b8871f35 14099 && ELF_ST_TYPE (sym->st_info) != STT_COMMON
55f25fc3 14100 && ELF_ST_TYPE (sym->st_info) > STT_SECTION)
5b18a4bc 14101 {
d3a49aa8 14102 warn (_("skipping unexpected symbol type %s in section %s relocation %ld\n"),
dda8d76d
NC
14103 get_symbol_type (filedata, ELF_ST_TYPE (sym->st_info)),
14104 printable_section_name (filedata, relsec),
d3a49aa8 14105 (long int)(rp - relocs));
aca88567 14106 continue;
5b18a4bc 14107 }
252b5132 14108
4dc3c23d
AM
14109 addend = 0;
14110 if (is_rela)
14111 addend += rp->r_addend;
c47320c3
AM
14112 /* R_XTENSA_32, R_PJ_DATA_DIR32 and R_D30V_32_NORMAL are
14113 partial_inplace. */
4dc3c23d 14114 if (!is_rela
dda8d76d 14115 || (filedata->file_header.e_machine == EM_XTENSA
4dc3c23d 14116 && reloc_type == 1)
dda8d76d
NC
14117 || ((filedata->file_header.e_machine == EM_PJ
14118 || filedata->file_header.e_machine == EM_PJ_OLD)
c47320c3 14119 && reloc_type == 1)
dda8d76d
NC
14120 || ((filedata->file_header.e_machine == EM_D30V
14121 || filedata->file_header.e_machine == EM_CYGNUS_D30V)
03336641
JW
14122 && reloc_type == 12)
14123 || reloc_inplace)
39e07931
AS
14124 {
14125 if (is_6bit_inplace_sub_reloc (filedata, reloc_type))
14126 addend += byte_get (rloc, reloc_size) & 0x3f;
14127 else
14128 addend += byte_get (rloc, reloc_size);
14129 }
cb8f3167 14130
dda8d76d
NC
14131 if (is_32bit_pcrel_reloc (filedata, reloc_type)
14132 || is_64bit_pcrel_reloc (filedata, reloc_type))
85acf597
RH
14133 {
14134 /* On HPPA, all pc-relative relocations are biased by 8. */
dda8d76d 14135 if (filedata->file_header.e_machine == EM_PARISC)
85acf597 14136 addend -= 8;
91d6fa6a 14137 byte_put (rloc, (addend + sym->st_value) - rp->r_offset,
85acf597
RH
14138 reloc_size);
14139 }
39e07931
AS
14140 else if (is_6bit_abs_reloc (filedata, reloc_type)
14141 || is_6bit_inplace_sub_reloc (filedata, reloc_type))
14142 {
14143 if (reloc_subtract)
14144 addend -= sym->st_value;
14145 else
14146 addend += sym->st_value;
14147 addend = (addend & 0x3f) | (byte_get (rloc, reloc_size) & 0xc0);
14148 byte_put (rloc, addend, reloc_size);
14149 }
03336641
JW
14150 else if (reloc_subtract)
14151 byte_put (rloc, addend - sym->st_value, reloc_size);
41e92641 14152 else
91d6fa6a 14153 byte_put (rloc, addend + sym->st_value, reloc_size);
5b18a4bc 14154 }
252b5132 14155
5b18a4bc 14156 free (symtab);
f84ce13b
NC
14157 /* Let the target specific reloc processing code know that
14158 we have finished with these relocs. */
dda8d76d 14159 target_specific_reloc_handling (filedata, NULL, NULL, NULL, NULL, 0);
d1c4b12b
NC
14160
14161 if (relocs_return)
14162 {
14163 * (Elf_Internal_Rela **) relocs_return = relocs;
14164 * num_relocs_return = num_relocs;
14165 }
14166 else
14167 free (relocs);
14168
5b18a4bc
NC
14169 break;
14170 }
32ec8896 14171
dfc616fa 14172 return TRUE;
5b18a4bc 14173}
103f02d3 14174
cf13d699 14175#ifdef SUPPORT_DISASSEMBLY
32ec8896 14176static bfd_boolean
dda8d76d 14177disassemble_section (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14178{
dda8d76d 14179 printf (_("\nAssembly dump of section %s\n"), printable_section_name (filedata, section));
cf13d699 14180
74e1a04b 14181 /* FIXME: XXX -- to be done --- XXX */
cf13d699 14182
32ec8896 14183 return TRUE;
cf13d699
NC
14184}
14185#endif
14186
14187/* Reads in the contents of SECTION from FILE, returning a pointer
14188 to a malloc'ed buffer or NULL if something went wrong. */
14189
14190static char *
dda8d76d 14191get_section_contents (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14192{
dda8d76d 14193 bfd_size_type num_bytes = section->sh_size;
cf13d699
NC
14194
14195 if (num_bytes == 0 || section->sh_type == SHT_NOBITS)
14196 {
c6b78c96 14197 printf (_("Section '%s' has no data to dump.\n"),
dda8d76d 14198 printable_section_name (filedata, section));
cf13d699
NC
14199 return NULL;
14200 }
14201
dda8d76d 14202 return (char *) get_data (NULL, filedata, section->sh_offset, 1, num_bytes,
3f5e193b 14203 _("section contents"));
cf13d699
NC
14204}
14205
0e602686
NC
14206/* Uncompresses a section that was compressed using zlib, in place. */
14207
14208static bfd_boolean
dda8d76d
NC
14209uncompress_section_contents (unsigned char ** buffer,
14210 dwarf_size_type uncompressed_size,
14211 dwarf_size_type * size)
0e602686
NC
14212{
14213 dwarf_size_type compressed_size = *size;
14214 unsigned char * compressed_buffer = *buffer;
14215 unsigned char * uncompressed_buffer;
14216 z_stream strm;
14217 int rc;
14218
14219 /* It is possible the section consists of several compressed
14220 buffers concatenated together, so we uncompress in a loop. */
14221 /* PR 18313: The state field in the z_stream structure is supposed
14222 to be invisible to the user (ie us), but some compilers will
14223 still complain about it being used without initialisation. So
14224 we first zero the entire z_stream structure and then set the fields
14225 that we need. */
14226 memset (& strm, 0, sizeof strm);
14227 strm.avail_in = compressed_size;
14228 strm.next_in = (Bytef *) compressed_buffer;
14229 strm.avail_out = uncompressed_size;
14230 uncompressed_buffer = (unsigned char *) xmalloc (uncompressed_size);
14231
14232 rc = inflateInit (& strm);
14233 while (strm.avail_in > 0)
14234 {
14235 if (rc != Z_OK)
3624a6c1 14236 break;
0e602686
NC
14237 strm.next_out = ((Bytef *) uncompressed_buffer
14238 + (uncompressed_size - strm.avail_out));
14239 rc = inflate (&strm, Z_FINISH);
14240 if (rc != Z_STREAM_END)
3624a6c1 14241 break;
0e602686
NC
14242 rc = inflateReset (& strm);
14243 }
ad92f33d
AM
14244 if (inflateEnd (& strm) != Z_OK
14245 || rc != Z_OK
0e602686
NC
14246 || strm.avail_out != 0)
14247 goto fail;
14248
14249 *buffer = uncompressed_buffer;
14250 *size = uncompressed_size;
14251 return TRUE;
14252
14253 fail:
14254 free (uncompressed_buffer);
14255 /* Indicate decompression failure. */
14256 *buffer = NULL;
14257 return FALSE;
14258}
dd24e3da 14259
32ec8896 14260static bfd_boolean
dda8d76d 14261dump_section_as_strings (Elf_Internal_Shdr * section, Filedata * filedata)
cf13d699 14262{
0e602686
NC
14263 Elf_Internal_Shdr * relsec;
14264 bfd_size_type num_bytes;
fd8008d8
L
14265 unsigned char * data;
14266 unsigned char * end;
14267 unsigned char * real_start;
14268 unsigned char * start;
0e602686 14269 bfd_boolean some_strings_shown;
cf13d699 14270
dda8d76d 14271 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14272 if (start == NULL)
c6b78c96
NC
14273 /* PR 21820: Do not fail if the section was empty. */
14274 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
14275
0e602686 14276 num_bytes = section->sh_size;
cf13d699 14277
dda8d76d 14278 printf (_("\nString dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14279
0e602686
NC
14280 if (decompress_dumps)
14281 {
14282 dwarf_size_type new_size = num_bytes;
14283 dwarf_size_type uncompressed_size = 0;
14284
14285 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14286 {
14287 Elf_Internal_Chdr chdr;
14288 unsigned int compression_header_size
ebdf1ebf
NC
14289 = get_compression_header (& chdr, (unsigned char *) start,
14290 num_bytes);
5844b465
NC
14291 if (compression_header_size == 0)
14292 /* An error message will have already been generated
14293 by get_compression_header. */
14294 goto error_out;
0e602686 14295
813dabb9 14296 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14297 {
813dabb9 14298 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14299 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14300 goto error_out;
813dabb9 14301 }
813dabb9
L
14302 uncompressed_size = chdr.ch_size;
14303 start += compression_header_size;
14304 new_size -= compression_header_size;
0e602686
NC
14305 }
14306 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14307 {
14308 /* Read the zlib header. In this case, it should be "ZLIB"
14309 followed by the uncompressed section size, 8 bytes in
14310 big-endian order. */
14311 uncompressed_size = start[4]; uncompressed_size <<= 8;
14312 uncompressed_size += start[5]; uncompressed_size <<= 8;
14313 uncompressed_size += start[6]; uncompressed_size <<= 8;
14314 uncompressed_size += start[7]; uncompressed_size <<= 8;
14315 uncompressed_size += start[8]; uncompressed_size <<= 8;
14316 uncompressed_size += start[9]; uncompressed_size <<= 8;
14317 uncompressed_size += start[10]; uncompressed_size <<= 8;
14318 uncompressed_size += start[11];
14319 start += 12;
14320 new_size -= 12;
14321 }
14322
1835f746
NC
14323 if (uncompressed_size)
14324 {
14325 if (uncompress_section_contents (& start,
14326 uncompressed_size, & new_size))
14327 num_bytes = new_size;
14328 else
14329 {
14330 error (_("Unable to decompress section %s\n"),
dda8d76d 14331 printable_section_name (filedata, section));
f761cb13 14332 goto error_out;
1835f746
NC
14333 }
14334 }
bc303e5d
NC
14335 else
14336 start = real_start;
0e602686 14337 }
fd8008d8 14338
cf13d699
NC
14339 /* If the section being dumped has relocations against it the user might
14340 be expecting these relocations to have been applied. Check for this
14341 case and issue a warning message in order to avoid confusion.
14342 FIXME: Maybe we ought to have an option that dumps a section with
14343 relocs applied ? */
dda8d76d
NC
14344 for (relsec = filedata->section_headers;
14345 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14346 ++relsec)
14347 {
14348 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14349 || relsec->sh_info >= filedata->file_header.e_shnum
14350 || filedata->section_headers + relsec->sh_info != section
cf13d699 14351 || relsec->sh_size == 0
dda8d76d 14352 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14353 continue;
14354
14355 printf (_(" Note: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14356 break;
14357 }
14358
cf13d699
NC
14359 data = start;
14360 end = start + num_bytes;
14361 some_strings_shown = FALSE;
14362
ba3265d0
NC
14363#ifdef HAVE_MBSTATE_T
14364 mbstate_t state;
14365 /* Initialise the multibyte conversion state. */
14366 memset (& state, 0, sizeof (state));
14367#endif
14368
14369 bfd_boolean continuing = FALSE;
14370
cf13d699
NC
14371 while (data < end)
14372 {
14373 while (!ISPRINT (* data))
14374 if (++ data >= end)
14375 break;
14376
14377 if (data < end)
14378 {
071436c6
NC
14379 size_t maxlen = end - data;
14380
ba3265d0
NC
14381 if (continuing)
14382 {
14383 printf (" ");
14384 continuing = FALSE;
14385 }
14386 else
14387 {
d1ce973e 14388 printf (" [%6lx] ", (unsigned long) (data - start));
ba3265d0
NC
14389 }
14390
4082ef84
NC
14391 if (maxlen > 0)
14392 {
f3da8a96 14393 char c = 0;
ba3265d0
NC
14394
14395 while (maxlen)
14396 {
14397 c = *data++;
14398
14399 if (c == 0)
14400 break;
14401
14402 /* PR 25543: Treat new-lines as string-ending characters. */
14403 if (c == '\n')
14404 {
14405 printf ("\\n\n");
14406 if (*data != 0)
14407 continuing = TRUE;
14408 break;
14409 }
14410
14411 /* Do not print control characters directly as they can affect terminal
14412 settings. Such characters usually appear in the names generated
14413 by the assembler for local labels. */
14414 if (ISCNTRL (c))
14415 {
14416 printf ("^%c", c + 0x40);
14417 }
14418 else if (ISPRINT (c))
14419 {
14420 putchar (c);
14421 }
14422 else
14423 {
14424 size_t n;
14425#ifdef HAVE_MBSTATE_T
14426 wchar_t w;
14427#endif
14428 /* Let printf do the hard work of displaying multibyte characters. */
14429 printf ("%.1s", data - 1);
14430#ifdef HAVE_MBSTATE_T
14431 /* Try to find out how many bytes made up the character that was
14432 just printed. Advance the symbol pointer past the bytes that
14433 were displayed. */
14434 n = mbrtowc (& w, (char *)(data - 1), MB_CUR_MAX, & state);
14435#else
14436 n = 1;
14437#endif
14438 if (n != (size_t) -1 && n != (size_t) -2 && n > 0)
14439 data += (n - 1);
14440 }
14441 }
14442
14443 if (c != '\n')
14444 putchar ('\n');
4082ef84
NC
14445 }
14446 else
14447 {
14448 printf (_("<corrupt>\n"));
14449 data = end;
14450 }
cf13d699
NC
14451 some_strings_shown = TRUE;
14452 }
14453 }
14454
14455 if (! some_strings_shown)
14456 printf (_(" No strings found in this section."));
14457
0e602686 14458 free (real_start);
cf13d699
NC
14459
14460 putchar ('\n');
32ec8896 14461 return TRUE;
f761cb13
AM
14462
14463error_out:
14464 free (real_start);
14465 return FALSE;
cf13d699
NC
14466}
14467
32ec8896 14468static bfd_boolean
dda8d76d
NC
14469dump_section_as_bytes (Elf_Internal_Shdr * section,
14470 Filedata * filedata,
14471 bfd_boolean relocate)
cf13d699
NC
14472{
14473 Elf_Internal_Shdr * relsec;
0e602686
NC
14474 bfd_size_type bytes;
14475 bfd_size_type section_size;
14476 bfd_vma addr;
14477 unsigned char * data;
14478 unsigned char * real_start;
14479 unsigned char * start;
14480
dda8d76d 14481 real_start = start = (unsigned char *) get_section_contents (section, filedata);
cf13d699 14482 if (start == NULL)
c6b78c96
NC
14483 /* PR 21820: Do not fail if the section was empty. */
14484 return (section->sh_size == 0 || section->sh_type == SHT_NOBITS) ? TRUE : FALSE;
32ec8896 14485
0e602686 14486 section_size = section->sh_size;
cf13d699 14487
dda8d76d 14488 printf (_("\nHex dump of section '%s':\n"), printable_section_name (filedata, section));
cf13d699 14489
0e602686
NC
14490 if (decompress_dumps)
14491 {
14492 dwarf_size_type new_size = section_size;
14493 dwarf_size_type uncompressed_size = 0;
14494
14495 if ((section->sh_flags & SHF_COMPRESSED) != 0)
14496 {
14497 Elf_Internal_Chdr chdr;
14498 unsigned int compression_header_size
ebdf1ebf 14499 = get_compression_header (& chdr, start, section_size);
0e602686 14500
5844b465
NC
14501 if (compression_header_size == 0)
14502 /* An error message will have already been generated
14503 by get_compression_header. */
14504 goto error_out;
14505
813dabb9 14506 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
0e602686 14507 {
813dabb9 14508 warn (_("section '%s' has unsupported compress type: %d\n"),
dda8d76d 14509 printable_section_name (filedata, section), chdr.ch_type);
f761cb13 14510 goto error_out;
0e602686 14511 }
813dabb9
L
14512 uncompressed_size = chdr.ch_size;
14513 start += compression_header_size;
14514 new_size -= compression_header_size;
0e602686
NC
14515 }
14516 else if (new_size > 12 && streq ((char *) start, "ZLIB"))
14517 {
14518 /* Read the zlib header. In this case, it should be "ZLIB"
14519 followed by the uncompressed section size, 8 bytes in
14520 big-endian order. */
14521 uncompressed_size = start[4]; uncompressed_size <<= 8;
14522 uncompressed_size += start[5]; uncompressed_size <<= 8;
14523 uncompressed_size += start[6]; uncompressed_size <<= 8;
14524 uncompressed_size += start[7]; uncompressed_size <<= 8;
14525 uncompressed_size += start[8]; uncompressed_size <<= 8;
14526 uncompressed_size += start[9]; uncompressed_size <<= 8;
14527 uncompressed_size += start[10]; uncompressed_size <<= 8;
14528 uncompressed_size += start[11];
14529 start += 12;
14530 new_size -= 12;
14531 }
14532
f055032e
NC
14533 if (uncompressed_size)
14534 {
14535 if (uncompress_section_contents (& start, uncompressed_size,
14536 & new_size))
bc303e5d
NC
14537 {
14538 section_size = new_size;
14539 }
f055032e
NC
14540 else
14541 {
14542 error (_("Unable to decompress section %s\n"),
dda8d76d 14543 printable_section_name (filedata, section));
bc303e5d 14544 /* FIXME: Print the section anyway ? */
f761cb13 14545 goto error_out;
f055032e
NC
14546 }
14547 }
bc303e5d
NC
14548 else
14549 start = real_start;
0e602686 14550 }
14ae95f2 14551
cf13d699
NC
14552 if (relocate)
14553 {
dda8d76d 14554 if (! apply_relocations (filedata, section, start, section_size, NULL, NULL))
f761cb13 14555 goto error_out;
cf13d699
NC
14556 }
14557 else
14558 {
14559 /* If the section being dumped has relocations against it the user might
14560 be expecting these relocations to have been applied. Check for this
14561 case and issue a warning message in order to avoid confusion.
14562 FIXME: Maybe we ought to have an option that dumps a section with
14563 relocs applied ? */
dda8d76d
NC
14564 for (relsec = filedata->section_headers;
14565 relsec < filedata->section_headers + filedata->file_header.e_shnum;
cf13d699
NC
14566 ++relsec)
14567 {
14568 if ((relsec->sh_type != SHT_RELA && relsec->sh_type != SHT_REL)
dda8d76d
NC
14569 || relsec->sh_info >= filedata->file_header.e_shnum
14570 || filedata->section_headers + relsec->sh_info != section
cf13d699 14571 || relsec->sh_size == 0
dda8d76d 14572 || relsec->sh_link >= filedata->file_header.e_shnum)
cf13d699
NC
14573 continue;
14574
14575 printf (_(" NOTE: This section has relocations against it, but these have NOT been applied to this dump.\n"));
14576 break;
14577 }
14578 }
14579
14580 addr = section->sh_addr;
0e602686 14581 bytes = section_size;
cf13d699
NC
14582 data = start;
14583
14584 while (bytes)
14585 {
14586 int j;
14587 int k;
14588 int lbytes;
14589
14590 lbytes = (bytes > 16 ? 16 : bytes);
14591
14592 printf (" 0x%8.8lx ", (unsigned long) addr);
14593
14594 for (j = 0; j < 16; j++)
14595 {
14596 if (j < lbytes)
14597 printf ("%2.2x", data[j]);
14598 else
14599 printf (" ");
14600
14601 if ((j & 3) == 3)
14602 printf (" ");
14603 }
14604
14605 for (j = 0; j < lbytes; j++)
14606 {
14607 k = data[j];
14608 if (k >= ' ' && k < 0x7f)
14609 printf ("%c", k);
14610 else
14611 printf (".");
14612 }
14613
14614 putchar ('\n');
14615
14616 data += lbytes;
14617 addr += lbytes;
14618 bytes -= lbytes;
14619 }
14620
0e602686 14621 free (real_start);
cf13d699
NC
14622
14623 putchar ('\n');
32ec8896 14624 return TRUE;
f761cb13
AM
14625
14626 error_out:
14627 free (real_start);
14628 return FALSE;
cf13d699
NC
14629}
14630
094e34f2 14631#ifdef ENABLE_LIBCTF
7d9813f1
NA
14632static ctf_sect_t *
14633shdr_to_ctf_sect (ctf_sect_t *buf, Elf_Internal_Shdr *shdr, Filedata *filedata)
14634{
b9e920ec 14635 buf->cts_name = SECTION_NAME_PRINT (shdr);
7d9813f1
NA
14636 buf->cts_size = shdr->sh_size;
14637 buf->cts_entsize = shdr->sh_entsize;
7d9813f1
NA
14638
14639 return buf;
14640}
14641
14642/* Formatting callback function passed to ctf_dump. Returns either the pointer
14643 it is passed, or a pointer to newly-allocated storage, in which case
14644 dump_ctf() will free it when it no longer needs it. */
14645
2f6ecaed
NA
14646static char *
14647dump_ctf_indent_lines (ctf_sect_names_t sect ATTRIBUTE_UNUSED,
14648 char *s, void *arg)
7d9813f1 14649{
3e50a591 14650 const char *blanks = arg;
7d9813f1
NA
14651 char *new_s;
14652
3e50a591 14653 if (asprintf (&new_s, "%s%s", blanks, s) < 0)
7d9813f1
NA
14654 return s;
14655 return new_s;
14656}
14657
926c9e76
NA
14658/* Dump CTF errors/warnings. */
14659static void
139633c3 14660dump_ctf_errs (ctf_dict_t *fp)
926c9e76
NA
14661{
14662 ctf_next_t *it = NULL;
14663 char *errtext;
14664 int is_warning;
14665 int err;
14666
14667 /* Dump accumulated errors and warnings. */
14668 while ((errtext = ctf_errwarning_next (fp, &it, &is_warning, &err)) != NULL)
14669 {
5e9b84f7 14670 error (_("%s: %s"), is_warning ? _("warning"): _("error"),
926c9e76
NA
14671 errtext);
14672 free (errtext);
14673 }
14674 if (err != ECTF_NEXT_END)
14675 error (_("CTF error: cannot get CTF errors: `%s'"), ctf_errmsg (err));
14676}
14677
2f6ecaed
NA
14678/* Dump one CTF archive member. */
14679
14680static int
139633c3 14681dump_ctf_archive_member (ctf_dict_t *ctf, const char *name, void *arg)
2f6ecaed 14682{
139633c3 14683 ctf_dict_t *parent = (ctf_dict_t *) arg;
2f6ecaed
NA
14684 const char *things[] = {"Header", "Labels", "Data objects",
14685 "Function objects", "Variables", "Types", "Strings",
14686 ""};
14687 const char **thing;
14688 size_t i;
8b37e7b6 14689 int err = 0;
2f6ecaed
NA
14690
14691 /* Only print out the name of non-default-named archive members.
14692 The name .ctf appears everywhere, even for things that aren't
14693 really archives, so printing it out is liable to be confusing.
14694
14695 The parent, if there is one, is the default-owned archive member:
14696 avoid importing it into itself. (This does no harm, but looks
14697 confusing.) */
14698
14699 if (strcmp (name, ".ctf") != 0)
14700 {
14701 printf (_("\nCTF archive member: %s:\n"), name);
14702 ctf_import (ctf, parent);
14703 }
14704
14705 for (i = 0, thing = things; *thing[0]; thing++, i++)
14706 {
14707 ctf_dump_state_t *s = NULL;
14708 char *item;
14709
14710 printf ("\n %s:\n", *thing);
14711 while ((item = ctf_dump (ctf, &s, i, dump_ctf_indent_lines,
14712 (void *) " ")) != NULL)
14713 {
14714 printf ("%s\n", item);
14715 free (item);
14716 }
14717
14718 if (ctf_errno (ctf))
14719 {
14720 error (_("Iteration failed: %s, %s\n"), *thing,
14721 ctf_errmsg (ctf_errno (ctf)));
8b37e7b6
NA
14722 err = 1;
14723 goto out;
2f6ecaed
NA
14724 }
14725 }
8b37e7b6
NA
14726
14727 out:
926c9e76 14728 dump_ctf_errs (ctf);
8b37e7b6 14729 return err;
2f6ecaed
NA
14730}
14731
7d9813f1
NA
14732static bfd_boolean
14733dump_section_as_ctf (Elf_Internal_Shdr * section, Filedata * filedata)
14734{
14735 Elf_Internal_Shdr * parent_sec = NULL;
14736 Elf_Internal_Shdr * symtab_sec = NULL;
14737 Elf_Internal_Shdr * strtab_sec = NULL;
d344b407
NA
14738 void * data = NULL;
14739 void * symdata = NULL;
14740 void * strdata = NULL;
14741 void * parentdata = NULL;
14742 ctf_sect_t ctfsect, symsect, strsect, parentsect;
14743 ctf_sect_t * symsectp = NULL;
14744 ctf_sect_t * strsectp = NULL;
2f6ecaed
NA
14745 ctf_archive_t * ctfa = NULL;
14746 ctf_archive_t * parenta = NULL, *lookparent;
139633c3 14747 ctf_dict_t * parent = NULL;
7d9813f1 14748
7d9813f1
NA
14749 int err;
14750 bfd_boolean ret = FALSE;
7d9813f1
NA
14751
14752 shdr_to_ctf_sect (&ctfsect, section, filedata);
14753 data = get_section_contents (section, filedata);
14754 ctfsect.cts_data = data;
14755
616febde 14756 if (!dump_ctf_symtab_name)
3d16b64e 14757 dump_ctf_symtab_name = strdup (".dynsym");
616febde
NA
14758
14759 if (!dump_ctf_strtab_name)
3d16b64e 14760 dump_ctf_strtab_name = strdup (".dynstr");
616febde
NA
14761
14762 if (dump_ctf_symtab_name && dump_ctf_symtab_name[0] != 0)
7d9813f1
NA
14763 {
14764 if ((symtab_sec = find_section (filedata, dump_ctf_symtab_name)) == NULL)
14765 {
14766 error (_("No symbol section named %s\n"), dump_ctf_symtab_name);
14767 goto fail;
14768 }
14769 if ((symdata = (void *) get_data (NULL, filedata,
14770 symtab_sec->sh_offset, 1,
14771 symtab_sec->sh_size,
14772 _("symbols"))) == NULL)
14773 goto fail;
14774 symsectp = shdr_to_ctf_sect (&symsect, symtab_sec, filedata);
14775 symsect.cts_data = symdata;
14776 }
df16e041 14777 if (dump_ctf_strtab_name && dump_ctf_strtab_name[0] != 0)
7d9813f1
NA
14778 {
14779 if ((strtab_sec = find_section (filedata, dump_ctf_strtab_name)) == NULL)
14780 {
14781 error (_("No string table section named %s\n"),
14782 dump_ctf_strtab_name);
14783 goto fail;
14784 }
14785 if ((strdata = (void *) get_data (NULL, filedata,
14786 strtab_sec->sh_offset, 1,
14787 strtab_sec->sh_size,
14788 _("strings"))) == NULL)
14789 goto fail;
14790 strsectp = shdr_to_ctf_sect (&strsect, strtab_sec, filedata);
14791 strsect.cts_data = strdata;
14792 }
14793 if (dump_ctf_parent_name)
14794 {
14795 if ((parent_sec = find_section (filedata, dump_ctf_parent_name)) == NULL)
14796 {
14797 error (_("No CTF parent section named %s\n"), dump_ctf_parent_name);
14798 goto fail;
14799 }
14800 if ((parentdata = (void *) get_data (NULL, filedata,
14801 parent_sec->sh_offset, 1,
14802 parent_sec->sh_size,
14803 _("CTF parent"))) == NULL)
14804 goto fail;
14805 shdr_to_ctf_sect (&parentsect, parent_sec, filedata);
14806 parentsect.cts_data = parentdata;
14807 }
14808
2f6ecaed
NA
14809 /* Load the CTF file and dump it. It may be a raw CTF section, or an archive:
14810 libctf papers over the difference, so we can pretend it is always an
14811 archive. Possibly open the parent as well, if one was specified. */
7d9813f1 14812
2f6ecaed 14813 if ((ctfa = ctf_arc_bufopen (&ctfsect, symsectp, strsectp, &err)) == NULL)
7d9813f1 14814 {
926c9e76 14815 dump_ctf_errs (NULL);
7d9813f1
NA
14816 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14817 goto fail;
14818 }
14819
96c61be5
NA
14820 ctf_arc_symsect_endianness (ctfa, filedata->file_header.e_ident[EI_DATA]
14821 != ELFDATA2MSB);
14822
7d9813f1
NA
14823 if (parentdata)
14824 {
2f6ecaed
NA
14825 if ((parenta = ctf_arc_bufopen (&parentsect, symsectp, strsectp,
14826 &err)) == NULL)
7d9813f1 14827 {
926c9e76 14828 dump_ctf_errs (NULL);
7d9813f1
NA
14829 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14830 goto fail;
14831 }
2f6ecaed
NA
14832 lookparent = parenta;
14833 }
14834 else
14835 lookparent = ctfa;
7d9813f1 14836
2f6ecaed
NA
14837 /* Assume that the applicable parent archive member is the default one.
14838 (This is what all known implementations are expected to do, if they
14839 put CTFs and their parents in archives together.) */
ae41200b 14840 if ((parent = ctf_dict_open (lookparent, NULL, &err)) == NULL)
2f6ecaed 14841 {
926c9e76 14842 dump_ctf_errs (NULL);
2f6ecaed
NA
14843 error (_("CTF open failure: %s\n"), ctf_errmsg (err));
14844 goto fail;
7d9813f1
NA
14845 }
14846
14847 ret = TRUE;
14848
14849 printf (_("\nDump of CTF section '%s':\n"),
14850 printable_section_name (filedata, section));
14851
83d59285
NA
14852 if ((err = ctf_archive_iter (ctfa, dump_ctf_archive_member, parent)) != 0)
14853 {
14854 dump_ctf_errs (NULL);
14855 error (_("CTF member open failure: %s\n"), ctf_errmsg (err));
14856 ret = FALSE;
14857 }
7d9813f1
NA
14858
14859 fail:
139633c3 14860 ctf_dict_close (parent);
2f6ecaed
NA
14861 ctf_close (ctfa);
14862 ctf_close (parenta);
7d9813f1
NA
14863 free (parentdata);
14864 free (data);
14865 free (symdata);
14866 free (strdata);
14867 return ret;
14868}
094e34f2 14869#endif
7d9813f1 14870
32ec8896 14871static bfd_boolean
dda8d76d
NC
14872load_specific_debug_section (enum dwarf_section_display_enum debug,
14873 const Elf_Internal_Shdr * sec,
14874 void * data)
1007acb3 14875{
2cf0635d 14876 struct dwarf_section * section = &debug_displays [debug].section;
19e6b90e 14877 char buf [64];
dda8d76d 14878 Filedata * filedata = (Filedata *) data;
9abca702 14879
19e6b90e 14880 if (section->start != NULL)
dda8d76d
NC
14881 {
14882 /* If it is already loaded, do nothing. */
14883 if (streq (section->filename, filedata->file_name))
14884 return TRUE;
14885 free (section->start);
14886 }
1007acb3 14887
19e6b90e
L
14888 snprintf (buf, sizeof (buf), _("%s section data"), section->name);
14889 section->address = sec->sh_addr;
06614111 14890 section->user_data = NULL;
dda8d76d
NC
14891 section->filename = filedata->file_name;
14892 section->start = (unsigned char *) get_data (NULL, filedata,
3f5e193b
NC
14893 sec->sh_offset, 1,
14894 sec->sh_size, buf);
59245841
NC
14895 if (section->start == NULL)
14896 section->size = 0;
14897 else
14898 {
77115a4a
L
14899 unsigned char *start = section->start;
14900 dwarf_size_type size = sec->sh_size;
dab394de 14901 dwarf_size_type uncompressed_size = 0;
77115a4a
L
14902
14903 if ((sec->sh_flags & SHF_COMPRESSED) != 0)
14904 {
14905 Elf_Internal_Chdr chdr;
d8024a91
NC
14906 unsigned int compression_header_size;
14907
f53be977
L
14908 if (size < (is_32bit_elf
14909 ? sizeof (Elf32_External_Chdr)
14910 : sizeof (Elf64_External_Chdr)))
d8024a91 14911 {
55be8fd0 14912 warn (_("compressed section %s is too small to contain a compression header\n"),
d8024a91 14913 section->name);
32ec8896 14914 return FALSE;
d8024a91
NC
14915 }
14916
ebdf1ebf 14917 compression_header_size = get_compression_header (&chdr, start, size);
5844b465
NC
14918 if (compression_header_size == 0)
14919 /* An error message will have already been generated
14920 by get_compression_header. */
14921 return FALSE;
d8024a91 14922
813dabb9
L
14923 if (chdr.ch_type != ELFCOMPRESS_ZLIB)
14924 {
14925 warn (_("section '%s' has unsupported compress type: %d\n"),
14926 section->name, chdr.ch_type);
32ec8896 14927 return FALSE;
813dabb9 14928 }
dab394de 14929 uncompressed_size = chdr.ch_size;
77115a4a
L
14930 start += compression_header_size;
14931 size -= compression_header_size;
14932 }
dab394de
L
14933 else if (size > 12 && streq ((char *) start, "ZLIB"))
14934 {
14935 /* Read the zlib header. In this case, it should be "ZLIB"
14936 followed by the uncompressed section size, 8 bytes in
14937 big-endian order. */
14938 uncompressed_size = start[4]; uncompressed_size <<= 8;
14939 uncompressed_size += start[5]; uncompressed_size <<= 8;
14940 uncompressed_size += start[6]; uncompressed_size <<= 8;
14941 uncompressed_size += start[7]; uncompressed_size <<= 8;
14942 uncompressed_size += start[8]; uncompressed_size <<= 8;
14943 uncompressed_size += start[9]; uncompressed_size <<= 8;
14944 uncompressed_size += start[10]; uncompressed_size <<= 8;
14945 uncompressed_size += start[11];
14946 start += 12;
14947 size -= 12;
14948 }
14949
1835f746 14950 if (uncompressed_size)
77115a4a 14951 {
1835f746
NC
14952 if (uncompress_section_contents (&start, uncompressed_size,
14953 &size))
14954 {
14955 /* Free the compressed buffer, update the section buffer
14956 and the section size if uncompress is successful. */
14957 free (section->start);
14958 section->start = start;
14959 }
14960 else
14961 {
14962 error (_("Unable to decompress section %s\n"),
dda8d76d 14963 printable_section_name (filedata, sec));
32ec8896 14964 return FALSE;
1835f746 14965 }
77115a4a 14966 }
bc303e5d 14967
77115a4a 14968 section->size = size;
59245841 14969 }
4a114e3e 14970
1b315056 14971 if (section->start == NULL)
32ec8896 14972 return FALSE;
1b315056 14973
19e6b90e 14974 if (debug_displays [debug].relocate)
32ec8896 14975 {
dda8d76d 14976 if (! apply_relocations (filedata, sec, section->start, section->size,
32ec8896
NC
14977 & section->reloc_info, & section->num_relocs))
14978 return FALSE;
14979 }
d1c4b12b
NC
14980 else
14981 {
14982 section->reloc_info = NULL;
14983 section->num_relocs = 0;
14984 }
1007acb3 14985
32ec8896 14986 return TRUE;
1007acb3
L
14987}
14988
301a9420
AM
14989#if HAVE_LIBDEBUGINFOD
14990/* Return a hex string representation of the build-id. */
14991unsigned char *
14992get_build_id (void * data)
14993{
14994 Filedata * filedata = (Filedata *)data;
14995 Elf_Internal_Shdr * shdr;
14996 unsigned long i;
14997
55be8fd0
NC
14998 /* Iterate through notes to find note.gnu.build-id.
14999 FIXME: Only the first note in any note section is examined. */
301a9420
AM
15000 for (i = 0, shdr = filedata->section_headers;
15001 i < filedata->file_header.e_shnum && shdr != NULL;
15002 i++, shdr++)
15003 {
15004 if (shdr->sh_type != SHT_NOTE)
15005 continue;
15006
15007 char * next;
15008 char * end;
15009 size_t data_remaining;
15010 size_t min_notesz;
15011 Elf_External_Note * enote;
15012 Elf_Internal_Note inote;
15013
15014 bfd_vma offset = shdr->sh_offset;
15015 bfd_vma align = shdr->sh_addralign;
15016 bfd_vma length = shdr->sh_size;
15017
15018 enote = (Elf_External_Note *) get_section_contents (shdr, filedata);
15019 if (enote == NULL)
15020 continue;
15021
15022 if (align < 4)
15023 align = 4;
15024 else if (align != 4 && align != 8)
f761cb13
AM
15025 {
15026 free (enote);
15027 continue;
15028 }
301a9420
AM
15029
15030 end = (char *) enote + length;
15031 data_remaining = end - (char *) enote;
15032
15033 if (!is_ia64_vms (filedata))
15034 {
15035 min_notesz = offsetof (Elf_External_Note, name);
15036 if (data_remaining < min_notesz)
15037 {
55be8fd0
NC
15038 warn (_("\
15039malformed note encountered in section %s whilst scanning for build-id note\n"),
15040 printable_section_name (filedata, shdr));
f761cb13 15041 free (enote);
55be8fd0 15042 continue;
301a9420
AM
15043 }
15044 data_remaining -= min_notesz;
15045
15046 inote.type = BYTE_GET (enote->type);
15047 inote.namesz = BYTE_GET (enote->namesz);
15048 inote.namedata = enote->name;
15049 inote.descsz = BYTE_GET (enote->descsz);
15050 inote.descdata = ((char *) enote
15051 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15052 inote.descpos = offset + (inote.descdata - (char *) enote);
15053 next = ((char *) enote
15054 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15055 }
15056 else
15057 {
15058 Elf64_External_VMS_Note *vms_enote;
15059
15060 /* PR binutils/15191
15061 Make sure that there is enough data to read. */
15062 min_notesz = offsetof (Elf64_External_VMS_Note, name);
15063 if (data_remaining < min_notesz)
15064 {
55be8fd0
NC
15065 warn (_("\
15066malformed note encountered in section %s whilst scanning for build-id note\n"),
15067 printable_section_name (filedata, shdr));
f761cb13 15068 free (enote);
55be8fd0 15069 continue;
301a9420
AM
15070 }
15071 data_remaining -= min_notesz;
15072
15073 vms_enote = (Elf64_External_VMS_Note *) enote;
15074 inote.type = BYTE_GET (vms_enote->type);
15075 inote.namesz = BYTE_GET (vms_enote->namesz);
15076 inote.namedata = vms_enote->name;
15077 inote.descsz = BYTE_GET (vms_enote->descsz);
15078 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
15079 inote.descpos = offset + (inote.descdata - (char *) enote);
15080 next = inote.descdata + align_power (inote.descsz, 3);
15081 }
15082
15083 /* Skip malformed notes. */
15084 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
15085 || (size_t) (inote.descdata - inote.namedata) > data_remaining
15086 || (size_t) (next - inote.descdata) < inote.descsz
15087 || ((size_t) (next - inote.descdata)
15088 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
15089 {
55be8fd0
NC
15090 warn (_("\
15091malformed note encountered in section %s whilst scanning for build-id note\n"),
15092 printable_section_name (filedata, shdr));
f761cb13 15093 free (enote);
301a9420
AM
15094 continue;
15095 }
15096
15097 /* Check if this is the build-id note. If so then convert the build-id
15098 bytes to a hex string. */
15099 if (inote.namesz > 0
15100 && const_strneq (inote.namedata, "GNU")
15101 && inote.type == NT_GNU_BUILD_ID)
15102 {
15103 unsigned long j;
15104 char * build_id;
15105
15106 build_id = malloc (inote.descsz * 2 + 1);
15107 if (build_id == NULL)
f761cb13
AM
15108 {
15109 free (enote);
15110 return NULL;
15111 }
301a9420
AM
15112
15113 for (j = 0; j < inote.descsz; ++j)
15114 sprintf (build_id + (j * 2), "%02x", inote.descdata[j] & 0xff);
15115 build_id[inote.descsz * 2] = '\0';
f761cb13 15116 free (enote);
301a9420 15117
55be8fd0 15118 return (unsigned char *) build_id;
301a9420 15119 }
f761cb13 15120 free (enote);
301a9420
AM
15121 }
15122
15123 return NULL;
15124}
15125#endif /* HAVE_LIBDEBUGINFOD */
15126
657d0d47
CC
15127/* If this is not NULL, load_debug_section will only look for sections
15128 within the list of sections given here. */
32ec8896 15129static unsigned int * section_subset = NULL;
657d0d47 15130
32ec8896 15131bfd_boolean
dda8d76d 15132load_debug_section (enum dwarf_section_display_enum debug, void * data)
d966045b 15133{
2cf0635d
NC
15134 struct dwarf_section * section = &debug_displays [debug].section;
15135 Elf_Internal_Shdr * sec;
dda8d76d
NC
15136 Filedata * filedata = (Filedata *) data;
15137
f425ec66
NC
15138 /* Without section headers we cannot find any sections. */
15139 if (filedata->section_headers == NULL)
15140 return FALSE;
15141
9c1ce108
AM
15142 if (filedata->string_table == NULL
15143 && filedata->file_header.e_shstrndx != SHN_UNDEF
15144 && filedata->file_header.e_shstrndx < filedata->file_header.e_shnum)
dda8d76d
NC
15145 {
15146 Elf_Internal_Shdr * strs;
15147
15148 /* Read in the string table, so that we have section names to scan. */
15149 strs = filedata->section_headers + filedata->file_header.e_shstrndx;
15150
4dff97b2 15151 if (strs != NULL && strs->sh_size != 0)
dda8d76d 15152 {
9c1ce108
AM
15153 filedata->string_table
15154 = (char *) get_data (NULL, filedata, strs->sh_offset,
15155 1, strs->sh_size, _("string table"));
dda8d76d 15156
9c1ce108
AM
15157 filedata->string_table_length
15158 = filedata->string_table != NULL ? strs->sh_size : 0;
dda8d76d
NC
15159 }
15160 }
d966045b
DJ
15161
15162 /* Locate the debug section. */
dda8d76d 15163 sec = find_section_in_set (filedata, section->uncompressed_name, section_subset);
d966045b
DJ
15164 if (sec != NULL)
15165 section->name = section->uncompressed_name;
15166 else
15167 {
dda8d76d 15168 sec = find_section_in_set (filedata, section->compressed_name, section_subset);
d966045b
DJ
15169 if (sec != NULL)
15170 section->name = section->compressed_name;
15171 }
15172 if (sec == NULL)
32ec8896 15173 return FALSE;
d966045b 15174
657d0d47
CC
15175 /* If we're loading from a subset of sections, and we've loaded
15176 a section matching this name before, it's likely that it's a
15177 different one. */
15178 if (section_subset != NULL)
15179 free_debug_section (debug);
15180
dda8d76d 15181 return load_specific_debug_section (debug, sec, data);
d966045b
DJ
15182}
15183
19e6b90e
L
15184void
15185free_debug_section (enum dwarf_section_display_enum debug)
1007acb3 15186{
2cf0635d 15187 struct dwarf_section * section = &debug_displays [debug].section;
1007acb3 15188
19e6b90e
L
15189 if (section->start == NULL)
15190 return;
1007acb3 15191
19e6b90e
L
15192 free ((char *) section->start);
15193 section->start = NULL;
15194 section->address = 0;
15195 section->size = 0;
a788aedd 15196
9db70fc3
AM
15197 free (section->reloc_info);
15198 section->reloc_info = NULL;
15199 section->num_relocs = 0;
1007acb3
L
15200}
15201
32ec8896 15202static bfd_boolean
dda8d76d 15203display_debug_section (int shndx, Elf_Internal_Shdr * section, Filedata * filedata)
1007acb3 15204{
b9e920ec 15205 char * name = SECTION_NAME_VALID (section) ? SECTION_NAME (section) : "";
dda8d76d 15206 const char * print_name = printable_section_name (filedata, section);
19e6b90e 15207 bfd_size_type length;
32ec8896 15208 bfd_boolean result = TRUE;
3f5e193b 15209 int i;
1007acb3 15210
19e6b90e
L
15211 length = section->sh_size;
15212 if (length == 0)
1007acb3 15213 {
74e1a04b 15214 printf (_("\nSection '%s' has no debugging data.\n"), print_name);
32ec8896 15215 return TRUE;
1007acb3 15216 }
5dff79d8
NC
15217 if (section->sh_type == SHT_NOBITS)
15218 {
15219 /* There is no point in dumping the contents of a debugging section
15220 which has the NOBITS type - the bits in the file will be random.
15221 This can happen when a file containing a .eh_frame section is
15222 stripped with the --only-keep-debug command line option. */
74e1a04b
NC
15223 printf (_("section '%s' has the NOBITS type - its contents are unreliable.\n"),
15224 print_name);
32ec8896 15225 return FALSE;
5dff79d8 15226 }
1007acb3 15227
0112cd26 15228 if (const_strneq (name, ".gnu.linkonce.wi."))
19e6b90e 15229 name = ".debug_info";
1007acb3 15230
19e6b90e
L
15231 /* See if we know how to display the contents of this section. */
15232 for (i = 0; i < max; i++)
d85bf2ba
NC
15233 {
15234 enum dwarf_section_display_enum id = (enum dwarf_section_display_enum) i;
15235 struct dwarf_section_display * display = debug_displays + i;
15236 struct dwarf_section * sec = & display->section;
d966045b 15237
d85bf2ba
NC
15238 if (streq (sec->uncompressed_name, name)
15239 || (id == line && const_strneq (name, ".debug_line."))
15240 || streq (sec->compressed_name, name))
15241 {
15242 bfd_boolean secondary = (section != find_section (filedata, name));
1007acb3 15243
d85bf2ba
NC
15244 if (secondary)
15245 free_debug_section (id);
dda8d76d 15246
d85bf2ba
NC
15247 if (i == line && const_strneq (name, ".debug_line."))
15248 sec->name = name;
15249 else if (streq (sec->uncompressed_name, name))
15250 sec->name = sec->uncompressed_name;
15251 else
15252 sec->name = sec->compressed_name;
657d0d47 15253
d85bf2ba
NC
15254 if (load_specific_debug_section (id, section, filedata))
15255 {
15256 /* If this debug section is part of a CU/TU set in a .dwp file,
15257 restrict load_debug_section to the sections in that set. */
15258 section_subset = find_cu_tu_set (filedata, shndx);
1007acb3 15259
d85bf2ba 15260 result &= display->display (sec, filedata);
657d0d47 15261
d85bf2ba 15262 section_subset = NULL;
1007acb3 15263
d85bf2ba
NC
15264 if (secondary || (id != info && id != abbrev))
15265 free_debug_section (id);
15266 }
15267 break;
15268 }
15269 }
1007acb3 15270
19e6b90e 15271 if (i == max)
1007acb3 15272 {
74e1a04b 15273 printf (_("Unrecognized debug section: %s\n"), print_name);
32ec8896 15274 result = FALSE;
1007acb3
L
15275 }
15276
19e6b90e 15277 return result;
5b18a4bc 15278}
103f02d3 15279
aef1f6d0
DJ
15280/* Set DUMP_SECTS for all sections where dumps were requested
15281 based on section name. */
15282
15283static void
dda8d76d 15284initialise_dumps_byname (Filedata * filedata)
aef1f6d0 15285{
2cf0635d 15286 struct dump_list_entry * cur;
aef1f6d0
DJ
15287
15288 for (cur = dump_sects_byname; cur; cur = cur->next)
15289 {
15290 unsigned int i;
32ec8896 15291 bfd_boolean any = FALSE;
aef1f6d0 15292
dda8d76d 15293 for (i = 0; i < filedata->file_header.e_shnum; i++)
b9e920ec
AM
15294 if (SECTION_NAME_VALID (filedata->section_headers + i)
15295 && streq (SECTION_NAME (filedata->section_headers + i), cur->name))
aef1f6d0 15296 {
6431e409 15297 request_dump_bynumber (&filedata->dump, i, cur->type);
32ec8896 15298 any = TRUE;
aef1f6d0
DJ
15299 }
15300
15301 if (!any)
15302 warn (_("Section '%s' was not dumped because it does not exist!\n"),
15303 cur->name);
15304 }
15305}
15306
32ec8896 15307static bfd_boolean
dda8d76d 15308process_section_contents (Filedata * filedata)
5b18a4bc 15309{
2cf0635d 15310 Elf_Internal_Shdr * section;
19e6b90e 15311 unsigned int i;
32ec8896 15312 bfd_boolean res = TRUE;
103f02d3 15313
19e6b90e 15314 if (! do_dump)
32ec8896 15315 return TRUE;
103f02d3 15316
dda8d76d 15317 initialise_dumps_byname (filedata);
aef1f6d0 15318
dda8d76d 15319 for (i = 0, section = filedata->section_headers;
6431e409 15320 i < filedata->file_header.e_shnum && i < filedata->dump.num_dump_sects;
19e6b90e
L
15321 i++, section++)
15322 {
6431e409 15323 dump_type dump = filedata->dump.dump_sects[i];
dda8d76d 15324
19e6b90e 15325#ifdef SUPPORT_DISASSEMBLY
dda8d76d
NC
15326 if (dump & DISASS_DUMP)
15327 {
15328 if (! disassemble_section (section, filedata))
15329 res = FALSE;
15330 }
19e6b90e 15331#endif
dda8d76d 15332 if (dump & HEX_DUMP)
32ec8896 15333 {
dda8d76d 15334 if (! dump_section_as_bytes (section, filedata, FALSE))
32ec8896
NC
15335 res = FALSE;
15336 }
103f02d3 15337
dda8d76d 15338 if (dump & RELOC_DUMP)
32ec8896 15339 {
dda8d76d 15340 if (! dump_section_as_bytes (section, filedata, TRUE))
32ec8896
NC
15341 res = FALSE;
15342 }
09c11c86 15343
dda8d76d 15344 if (dump & STRING_DUMP)
32ec8896 15345 {
dda8d76d 15346 if (! dump_section_as_strings (section, filedata))
32ec8896
NC
15347 res = FALSE;
15348 }
cf13d699 15349
dda8d76d 15350 if (dump & DEBUG_DUMP)
32ec8896 15351 {
dda8d76d 15352 if (! display_debug_section (i, section, filedata))
32ec8896
NC
15353 res = FALSE;
15354 }
7d9813f1 15355
094e34f2 15356#ifdef ENABLE_LIBCTF
7d9813f1
NA
15357 if (dump & CTF_DUMP)
15358 {
15359 if (! dump_section_as_ctf (section, filedata))
15360 res = FALSE;
15361 }
094e34f2 15362#endif
5b18a4bc 15363 }
103f02d3 15364
19e6b90e
L
15365 /* Check to see if the user requested a
15366 dump of a section that does not exist. */
6431e409 15367 while (i < filedata->dump.num_dump_sects)
0ee3043f 15368 {
6431e409 15369 if (filedata->dump.dump_sects[i])
32ec8896
NC
15370 {
15371 warn (_("Section %d was not dumped because it does not exist!\n"), i);
15372 res = FALSE;
15373 }
0ee3043f
NC
15374 i++;
15375 }
32ec8896
NC
15376
15377 return res;
5b18a4bc 15378}
103f02d3 15379
5b18a4bc 15380static void
19e6b90e 15381process_mips_fpe_exception (int mask)
5b18a4bc 15382{
19e6b90e
L
15383 if (mask)
15384 {
32ec8896
NC
15385 bfd_boolean first = TRUE;
15386
19e6b90e 15387 if (mask & OEX_FPU_INEX)
32ec8896 15388 fputs ("INEX", stdout), first = FALSE;
19e6b90e 15389 if (mask & OEX_FPU_UFLO)
32ec8896 15390 printf ("%sUFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15391 if (mask & OEX_FPU_OFLO)
32ec8896 15392 printf ("%sOFLO", first ? "" : "|"), first = FALSE;
19e6b90e 15393 if (mask & OEX_FPU_DIV0)
32ec8896 15394 printf ("%sDIV0", first ? "" : "|"), first = FALSE;
19e6b90e
L
15395 if (mask & OEX_FPU_INVAL)
15396 printf ("%sINVAL", first ? "" : "|");
15397 }
5b18a4bc 15398 else
19e6b90e 15399 fputs ("0", stdout);
5b18a4bc 15400}
103f02d3 15401
f6f0e17b
NC
15402/* Display's the value of TAG at location P. If TAG is
15403 greater than 0 it is assumed to be an unknown tag, and
15404 a message is printed to this effect. Otherwise it is
15405 assumed that a message has already been printed.
15406
15407 If the bottom bit of TAG is set it assumed to have a
15408 string value, otherwise it is assumed to have an integer
15409 value.
15410
15411 Returns an updated P pointing to the first unread byte
15412 beyond the end of TAG's value.
15413
15414 Reads at or beyond END will not be made. */
15415
15416static unsigned char *
60abdbed 15417display_tag_value (signed int tag,
f6f0e17b
NC
15418 unsigned char * p,
15419 const unsigned char * const end)
15420{
15421 unsigned long val;
15422
15423 if (tag > 0)
15424 printf (" Tag_unknown_%d: ", tag);
15425
15426 if (p >= end)
15427 {
4082ef84 15428 warn (_("<corrupt tag>\n"));
f6f0e17b
NC
15429 }
15430 else if (tag & 1)
15431 {
071436c6
NC
15432 /* PR 17531 file: 027-19978-0.004. */
15433 size_t maxlen = (end - p) - 1;
15434
15435 putchar ('"');
4082ef84
NC
15436 if (maxlen > 0)
15437 {
15438 print_symbol ((int) maxlen, (const char *) p);
15439 p += strnlen ((char *) p, maxlen) + 1;
15440 }
15441 else
15442 {
15443 printf (_("<corrupt string tag>"));
15444 p = (unsigned char *) end;
15445 }
071436c6 15446 printf ("\"\n");
f6f0e17b
NC
15447 }
15448 else
15449 {
cd30bcef 15450 READ_ULEB (val, p, end);
f6f0e17b
NC
15451 printf ("%ld (0x%lx)\n", val, val);
15452 }
15453
4082ef84 15454 assert (p <= end);
f6f0e17b
NC
15455 return p;
15456}
15457
53a346d8
CZ
15458/* ARC ABI attributes section. */
15459
15460static unsigned char *
15461display_arc_attribute (unsigned char * p,
15462 const unsigned char * const end)
15463{
15464 unsigned int tag;
53a346d8
CZ
15465 unsigned int val;
15466
cd30bcef 15467 READ_ULEB (tag, p, end);
53a346d8
CZ
15468
15469 switch (tag)
15470 {
15471 case Tag_ARC_PCS_config:
cd30bcef 15472 READ_ULEB (val, p, end);
53a346d8
CZ
15473 printf (" Tag_ARC_PCS_config: ");
15474 switch (val)
15475 {
15476 case 0:
15477 printf (_("Absent/Non standard\n"));
15478 break;
15479 case 1:
15480 printf (_("Bare metal/mwdt\n"));
15481 break;
15482 case 2:
15483 printf (_("Bare metal/newlib\n"));
15484 break;
15485 case 3:
15486 printf (_("Linux/uclibc\n"));
15487 break;
15488 case 4:
15489 printf (_("Linux/glibc\n"));
15490 break;
15491 default:
15492 printf (_("Unknown\n"));
15493 break;
15494 }
15495 break;
15496
15497 case Tag_ARC_CPU_base:
cd30bcef 15498 READ_ULEB (val, p, end);
53a346d8
CZ
15499 printf (" Tag_ARC_CPU_base: ");
15500 switch (val)
15501 {
15502 default:
15503 case TAG_CPU_NONE:
15504 printf (_("Absent\n"));
15505 break;
15506 case TAG_CPU_ARC6xx:
15507 printf ("ARC6xx\n");
15508 break;
15509 case TAG_CPU_ARC7xx:
15510 printf ("ARC7xx\n");
15511 break;
15512 case TAG_CPU_ARCEM:
15513 printf ("ARCEM\n");
15514 break;
15515 case TAG_CPU_ARCHS:
15516 printf ("ARCHS\n");
15517 break;
15518 }
15519 break;
15520
15521 case Tag_ARC_CPU_variation:
cd30bcef 15522 READ_ULEB (val, p, end);
53a346d8
CZ
15523 printf (" Tag_ARC_CPU_variation: ");
15524 switch (val)
15525 {
15526 default:
15527 if (val > 0 && val < 16)
53a346d8 15528 printf ("Core%d\n", val);
d8cbc93b
JL
15529 else
15530 printf ("Unknown\n");
15531 break;
15532
53a346d8
CZ
15533 case 0:
15534 printf (_("Absent\n"));
15535 break;
15536 }
15537 break;
15538
15539 case Tag_ARC_CPU_name:
15540 printf (" Tag_ARC_CPU_name: ");
15541 p = display_tag_value (-1, p, end);
15542 break;
15543
15544 case Tag_ARC_ABI_rf16:
cd30bcef 15545 READ_ULEB (val, p, end);
53a346d8
CZ
15546 printf (" Tag_ARC_ABI_rf16: %s\n", val ? _("yes") : _("no"));
15547 break;
15548
15549 case Tag_ARC_ABI_osver:
cd30bcef 15550 READ_ULEB (val, p, end);
53a346d8
CZ
15551 printf (" Tag_ARC_ABI_osver: v%d\n", val);
15552 break;
15553
15554 case Tag_ARC_ABI_pic:
15555 case Tag_ARC_ABI_sda:
cd30bcef 15556 READ_ULEB (val, p, end);
53a346d8
CZ
15557 printf (tag == Tag_ARC_ABI_sda ? " Tag_ARC_ABI_sda: "
15558 : " Tag_ARC_ABI_pic: ");
15559 switch (val)
15560 {
15561 case 0:
15562 printf (_("Absent\n"));
15563 break;
15564 case 1:
15565 printf ("MWDT\n");
15566 break;
15567 case 2:
15568 printf ("GNU\n");
15569 break;
15570 default:
15571 printf (_("Unknown\n"));
15572 break;
15573 }
15574 break;
15575
15576 case Tag_ARC_ABI_tls:
cd30bcef 15577 READ_ULEB (val, p, end);
53a346d8
CZ
15578 printf (" Tag_ARC_ABI_tls: %s\n", val ? "r25": "none");
15579 break;
15580
15581 case Tag_ARC_ABI_enumsize:
cd30bcef 15582 READ_ULEB (val, p, end);
53a346d8
CZ
15583 printf (" Tag_ARC_ABI_enumsize: %s\n", val ? _("default") :
15584 _("smallest"));
15585 break;
15586
15587 case Tag_ARC_ABI_exceptions:
cd30bcef 15588 READ_ULEB (val, p, end);
53a346d8
CZ
15589 printf (" Tag_ARC_ABI_exceptions: %s\n", val ? _("OPTFP")
15590 : _("default"));
15591 break;
15592
15593 case Tag_ARC_ABI_double_size:
cd30bcef 15594 READ_ULEB (val, p, end);
53a346d8
CZ
15595 printf (" Tag_ARC_ABI_double_size: %d\n", val);
15596 break;
15597
15598 case Tag_ARC_ISA_config:
15599 printf (" Tag_ARC_ISA_config: ");
15600 p = display_tag_value (-1, p, end);
15601 break;
15602
15603 case Tag_ARC_ISA_apex:
15604 printf (" Tag_ARC_ISA_apex: ");
15605 p = display_tag_value (-1, p, end);
15606 break;
15607
15608 case Tag_ARC_ISA_mpy_option:
cd30bcef 15609 READ_ULEB (val, p, end);
53a346d8
CZ
15610 printf (" Tag_ARC_ISA_mpy_option: %d\n", val);
15611 break;
15612
db1e1b45 15613 case Tag_ARC_ATR_version:
cd30bcef 15614 READ_ULEB (val, p, end);
db1e1b45 15615 printf (" Tag_ARC_ATR_version: %d\n", val);
15616 break;
15617
53a346d8
CZ
15618 default:
15619 return display_tag_value (tag & 1, p, end);
15620 }
15621
15622 return p;
15623}
15624
11c1ff18
PB
15625/* ARM EABI attributes section. */
15626typedef struct
15627{
70e99720 15628 unsigned int tag;
2cf0635d 15629 const char * name;
11c1ff18 15630 /* 0 = special, 1 = string, 2 = uleb123, > 0x80 == table lookup. */
70e99720 15631 unsigned int type;
288f0ba2 15632 const char *const *table;
11c1ff18
PB
15633} arm_attr_public_tag;
15634
288f0ba2 15635static const char *const arm_attr_tag_CPU_arch[] =
11c1ff18 15636 {"Pre-v4", "v4", "v4T", "v5T", "v5TE", "v5TEJ", "v6", "v6KZ", "v6T2",
ced40572 15637 "v6K", "v7", "v6-M", "v6S-M", "v7E-M", "v8", "v8-R", "v8-M.baseline",
031254f2 15638 "v8-M.mainline", "", "", "", "v8.1-M.mainline"};
288f0ba2
AM
15639static const char *const arm_attr_tag_ARM_ISA_use[] = {"No", "Yes"};
15640static const char *const arm_attr_tag_THUMB_ISA_use[] =
4ed7ed8d 15641 {"No", "Thumb-1", "Thumb-2", "Yes"};
288f0ba2 15642static const char *const arm_attr_tag_FP_arch[] =
bca38921 15643 {"No", "VFPv1", "VFPv2", "VFPv3", "VFPv3-D16", "VFPv4", "VFPv4-D16",
a715796b 15644 "FP for ARMv8", "FPv5/FP-D16 for ARMv8"};
288f0ba2
AM
15645static const char *const arm_attr_tag_WMMX_arch[] = {"No", "WMMXv1", "WMMXv2"};
15646static const char *const arm_attr_tag_Advanced_SIMD_arch[] =
9411fd44
MW
15647 {"No", "NEONv1", "NEONv1 with Fused-MAC", "NEON for ARMv8",
15648 "NEON for ARMv8.1"};
288f0ba2 15649static const char *const arm_attr_tag_PCS_config[] =
11c1ff18
PB
15650 {"None", "Bare platform", "Linux application", "Linux DSO", "PalmOS 2004",
15651 "PalmOS (reserved)", "SymbianOS 2004", "SymbianOS (reserved)"};
288f0ba2 15652static const char *const arm_attr_tag_ABI_PCS_R9_use[] =
11c1ff18 15653 {"V6", "SB", "TLS", "Unused"};
288f0ba2 15654static const char *const arm_attr_tag_ABI_PCS_RW_data[] =
11c1ff18 15655 {"Absolute", "PC-relative", "SB-relative", "None"};
288f0ba2 15656static const char *const arm_attr_tag_ABI_PCS_RO_data[] =
11c1ff18 15657 {"Absolute", "PC-relative", "None"};
288f0ba2 15658static const char *const arm_attr_tag_ABI_PCS_GOT_use[] =
11c1ff18 15659 {"None", "direct", "GOT-indirect"};
288f0ba2 15660static const char *const arm_attr_tag_ABI_PCS_wchar_t[] =
11c1ff18 15661 {"None", "??? 1", "2", "??? 3", "4"};
288f0ba2
AM
15662static const char *const arm_attr_tag_ABI_FP_rounding[] = {"Unused", "Needed"};
15663static const char *const arm_attr_tag_ABI_FP_denormal[] =
f5f53991 15664 {"Unused", "Needed", "Sign only"};
288f0ba2
AM
15665static const char *const arm_attr_tag_ABI_FP_exceptions[] = {"Unused", "Needed"};
15666static const char *const arm_attr_tag_ABI_FP_user_exceptions[] = {"Unused", "Needed"};
15667static const char *const arm_attr_tag_ABI_FP_number_model[] =
11c1ff18 15668 {"Unused", "Finite", "RTABI", "IEEE 754"};
288f0ba2 15669static const char *const arm_attr_tag_ABI_enum_size[] =
11c1ff18 15670 {"Unused", "small", "int", "forced to int"};
288f0ba2 15671static const char *const arm_attr_tag_ABI_HardFP_use[] =
99654aaf 15672 {"As Tag_FP_arch", "SP only", "Reserved", "Deprecated"};
288f0ba2 15673static const char *const arm_attr_tag_ABI_VFP_args[] =
5c294fee 15674 {"AAPCS", "VFP registers", "custom", "compatible"};
288f0ba2 15675static const char *const arm_attr_tag_ABI_WMMX_args[] =
11c1ff18 15676 {"AAPCS", "WMMX registers", "custom"};
288f0ba2 15677static const char *const arm_attr_tag_ABI_optimization_goals[] =
11c1ff18
PB
15678 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15679 "Aggressive Size", "Prefer Debug", "Aggressive Debug"};
288f0ba2 15680static const char *const arm_attr_tag_ABI_FP_optimization_goals[] =
11c1ff18
PB
15681 {"None", "Prefer Speed", "Aggressive Speed", "Prefer Size",
15682 "Aggressive Size", "Prefer Accuracy", "Aggressive Accuracy"};
288f0ba2
AM
15683static const char *const arm_attr_tag_CPU_unaligned_access[] = {"None", "v6"};
15684static const char *const arm_attr_tag_FP_HP_extension[] =
8e79c3df 15685 {"Not Allowed", "Allowed"};
288f0ba2 15686static const char *const arm_attr_tag_ABI_FP_16bit_format[] =
8e79c3df 15687 {"None", "IEEE 754", "Alternative Format"};
288f0ba2 15688static const char *const arm_attr_tag_DSP_extension[] =
15afaa63 15689 {"Follow architecture", "Allowed"};
288f0ba2 15690static const char *const arm_attr_tag_MPextension_use[] =
cd21e546 15691 {"Not Allowed", "Allowed"};
288f0ba2 15692static const char *const arm_attr_tag_DIV_use[] =
dd24e3da 15693 {"Allowed in Thumb-ISA, v7-R or v7-M", "Not allowed",
cd21e546 15694 "Allowed in v7-A with integer division extension"};
288f0ba2
AM
15695static const char *const arm_attr_tag_T2EE_use[] = {"Not Allowed", "Allowed"};
15696static const char *const arm_attr_tag_Virtualization_use[] =
dd24e3da 15697 {"Not Allowed", "TrustZone", "Virtualization Extensions",
cd21e546 15698 "TrustZone and Virtualization Extensions"};
288f0ba2 15699static const char *const arm_attr_tag_MPextension_use_legacy[] =
f5f53991 15700 {"Not Allowed", "Allowed"};
11c1ff18 15701
288f0ba2 15702static const char *const arm_attr_tag_MVE_arch[] =
a7ad558c
AV
15703 {"No MVE", "MVE Integer only", "MVE Integer and FP"};
15704
11c1ff18
PB
15705#define LOOKUP(id, name) \
15706 {id, #name, 0x80 | ARRAY_SIZE(arm_attr_tag_##name), arm_attr_tag_##name}
d70c5fc7 15707static arm_attr_public_tag arm_attr_public_tags[] =
11c1ff18
PB
15708{
15709 {4, "CPU_raw_name", 1, NULL},
15710 {5, "CPU_name", 1, NULL},
15711 LOOKUP(6, CPU_arch),
15712 {7, "CPU_arch_profile", 0, NULL},
15713 LOOKUP(8, ARM_ISA_use),
15714 LOOKUP(9, THUMB_ISA_use),
75375b3e 15715 LOOKUP(10, FP_arch),
11c1ff18 15716 LOOKUP(11, WMMX_arch),
f5f53991
AS
15717 LOOKUP(12, Advanced_SIMD_arch),
15718 LOOKUP(13, PCS_config),
11c1ff18
PB
15719 LOOKUP(14, ABI_PCS_R9_use),
15720 LOOKUP(15, ABI_PCS_RW_data),
f5f53991 15721 LOOKUP(16, ABI_PCS_RO_data),
11c1ff18
PB
15722 LOOKUP(17, ABI_PCS_GOT_use),
15723 LOOKUP(18, ABI_PCS_wchar_t),
15724 LOOKUP(19, ABI_FP_rounding),
15725 LOOKUP(20, ABI_FP_denormal),
15726 LOOKUP(21, ABI_FP_exceptions),
15727 LOOKUP(22, ABI_FP_user_exceptions),
15728 LOOKUP(23, ABI_FP_number_model),
75375b3e
MGD
15729 {24, "ABI_align_needed", 0, NULL},
15730 {25, "ABI_align_preserved", 0, NULL},
11c1ff18
PB
15731 LOOKUP(26, ABI_enum_size),
15732 LOOKUP(27, ABI_HardFP_use),
15733 LOOKUP(28, ABI_VFP_args),
15734 LOOKUP(29, ABI_WMMX_args),
15735 LOOKUP(30, ABI_optimization_goals),
15736 LOOKUP(31, ABI_FP_optimization_goals),
8e79c3df 15737 {32, "compatibility", 0, NULL},
f5f53991 15738 LOOKUP(34, CPU_unaligned_access),
75375b3e 15739 LOOKUP(36, FP_HP_extension),
8e79c3df 15740 LOOKUP(38, ABI_FP_16bit_format),
cd21e546
MGD
15741 LOOKUP(42, MPextension_use),
15742 LOOKUP(44, DIV_use),
15afaa63 15743 LOOKUP(46, DSP_extension),
a7ad558c 15744 LOOKUP(48, MVE_arch),
f5f53991
AS
15745 {64, "nodefaults", 0, NULL},
15746 {65, "also_compatible_with", 0, NULL},
15747 LOOKUP(66, T2EE_use),
15748 {67, "conformance", 1, NULL},
15749 LOOKUP(68, Virtualization_use),
cd21e546 15750 LOOKUP(70, MPextension_use_legacy)
11c1ff18
PB
15751};
15752#undef LOOKUP
15753
11c1ff18 15754static unsigned char *
f6f0e17b
NC
15755display_arm_attribute (unsigned char * p,
15756 const unsigned char * const end)
11c1ff18 15757{
70e99720 15758 unsigned int tag;
70e99720 15759 unsigned int val;
2cf0635d 15760 arm_attr_public_tag * attr;
11c1ff18 15761 unsigned i;
70e99720 15762 unsigned int type;
11c1ff18 15763
cd30bcef 15764 READ_ULEB (tag, p, end);
11c1ff18 15765 attr = NULL;
2cf0635d 15766 for (i = 0; i < ARRAY_SIZE (arm_attr_public_tags); i++)
11c1ff18
PB
15767 {
15768 if (arm_attr_public_tags[i].tag == tag)
15769 {
15770 attr = &arm_attr_public_tags[i];
15771 break;
15772 }
15773 }
15774
15775 if (attr)
15776 {
15777 printf (" Tag_%s: ", attr->name);
15778 switch (attr->type)
15779 {
15780 case 0:
15781 switch (tag)
15782 {
15783 case 7: /* Tag_CPU_arch_profile. */
cd30bcef 15784 READ_ULEB (val, p, end);
11c1ff18
PB
15785 switch (val)
15786 {
2b692964
NC
15787 case 0: printf (_("None\n")); break;
15788 case 'A': printf (_("Application\n")); break;
15789 case 'R': printf (_("Realtime\n")); break;
15790 case 'M': printf (_("Microcontroller\n")); break;
15791 case 'S': printf (_("Application or Realtime\n")); break;
11c1ff18
PB
15792 default: printf ("??? (%d)\n", val); break;
15793 }
15794 break;
15795
75375b3e 15796 case 24: /* Tag_align_needed. */
cd30bcef 15797 READ_ULEB (val, p, end);
75375b3e
MGD
15798 switch (val)
15799 {
2b692964
NC
15800 case 0: printf (_("None\n")); break;
15801 case 1: printf (_("8-byte\n")); break;
15802 case 2: printf (_("4-byte\n")); break;
75375b3e
MGD
15803 case 3: printf ("??? 3\n"); break;
15804 default:
15805 if (val <= 12)
dd24e3da 15806 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15807 1 << val);
15808 else
15809 printf ("??? (%d)\n", val);
15810 break;
15811 }
15812 break;
15813
15814 case 25: /* Tag_align_preserved. */
cd30bcef 15815 READ_ULEB (val, p, end);
75375b3e
MGD
15816 switch (val)
15817 {
2b692964
NC
15818 case 0: printf (_("None\n")); break;
15819 case 1: printf (_("8-byte, except leaf SP\n")); break;
15820 case 2: printf (_("8-byte\n")); break;
75375b3e
MGD
15821 case 3: printf ("??? 3\n"); break;
15822 default:
15823 if (val <= 12)
dd24e3da 15824 printf (_("8-byte and up to %d-byte extended\n"),
75375b3e
MGD
15825 1 << val);
15826 else
15827 printf ("??? (%d)\n", val);
15828 break;
15829 }
15830 break;
15831
11c1ff18 15832 case 32: /* Tag_compatibility. */
071436c6 15833 {
cd30bcef 15834 READ_ULEB (val, p, end);
071436c6 15835 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
15836 if (p < end - 1)
15837 {
15838 size_t maxlen = (end - p) - 1;
15839
15840 print_symbol ((int) maxlen, (const char *) p);
15841 p += strnlen ((char *) p, maxlen) + 1;
15842 }
15843 else
15844 {
15845 printf (_("<corrupt>"));
15846 p = (unsigned char *) end;
15847 }
071436c6 15848 putchar ('\n');
071436c6 15849 }
11c1ff18
PB
15850 break;
15851
f5f53991 15852 case 64: /* Tag_nodefaults. */
541a3cbd
NC
15853 /* PR 17531: file: 001-505008-0.01. */
15854 if (p < end)
15855 p++;
2b692964 15856 printf (_("True\n"));
f5f53991
AS
15857 break;
15858
15859 case 65: /* Tag_also_compatible_with. */
cd30bcef 15860 READ_ULEB (val, p, end);
f5f53991
AS
15861 if (val == 6 /* Tag_CPU_arch. */)
15862 {
cd30bcef 15863 READ_ULEB (val, p, end);
071436c6 15864 if ((unsigned int) val >= ARRAY_SIZE (arm_attr_tag_CPU_arch))
f5f53991
AS
15865 printf ("??? (%d)\n", val);
15866 else
15867 printf ("%s\n", arm_attr_tag_CPU_arch[val]);
15868 }
15869 else
15870 printf ("???\n");
071436c6
NC
15871 while (p < end && *(p++) != '\0' /* NUL terminator. */)
15872 ;
f5f53991
AS
15873 break;
15874
11c1ff18 15875 default:
bee0ee85
NC
15876 printf (_("<unknown: %d>\n"), tag);
15877 break;
11c1ff18
PB
15878 }
15879 return p;
15880
15881 case 1:
f6f0e17b 15882 return display_tag_value (-1, p, end);
11c1ff18 15883 case 2:
f6f0e17b 15884 return display_tag_value (0, p, end);
11c1ff18
PB
15885
15886 default:
15887 assert (attr->type & 0x80);
cd30bcef 15888 READ_ULEB (val, p, end);
11c1ff18
PB
15889 type = attr->type & 0x7f;
15890 if (val >= type)
15891 printf ("??? (%d)\n", val);
15892 else
15893 printf ("%s\n", attr->table[val]);
15894 return p;
15895 }
15896 }
11c1ff18 15897
f6f0e17b 15898 return display_tag_value (tag, p, end);
11c1ff18
PB
15899}
15900
104d59d1 15901static unsigned char *
60bca95a 15902display_gnu_attribute (unsigned char * p,
60abdbed 15903 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const),
f6f0e17b 15904 const unsigned char * const end)
104d59d1 15905{
cd30bcef 15906 unsigned int tag;
60abdbed 15907 unsigned int val;
104d59d1 15908
cd30bcef 15909 READ_ULEB (tag, p, end);
104d59d1
JM
15910
15911 /* Tag_compatibility is the only generic GNU attribute defined at
15912 present. */
15913 if (tag == 32)
15914 {
cd30bcef 15915 READ_ULEB (val, p, end);
071436c6
NC
15916
15917 printf (_("flag = %d, vendor = "), val);
f6f0e17b
NC
15918 if (p == end)
15919 {
071436c6 15920 printf (_("<corrupt>\n"));
f6f0e17b
NC
15921 warn (_("corrupt vendor attribute\n"));
15922 }
15923 else
15924 {
4082ef84
NC
15925 if (p < end - 1)
15926 {
15927 size_t maxlen = (end - p) - 1;
071436c6 15928
4082ef84
NC
15929 print_symbol ((int) maxlen, (const char *) p);
15930 p += strnlen ((char *) p, maxlen) + 1;
15931 }
15932 else
15933 {
15934 printf (_("<corrupt>"));
15935 p = (unsigned char *) end;
15936 }
071436c6 15937 putchar ('\n');
f6f0e17b 15938 }
104d59d1
JM
15939 return p;
15940 }
15941
15942 if ((tag & 2) == 0 && display_proc_gnu_attribute)
f6f0e17b 15943 return display_proc_gnu_attribute (p, tag, end);
104d59d1 15944
f6f0e17b 15945 return display_tag_value (tag, p, end);
104d59d1
JM
15946}
15947
85f7484a
PB
15948static unsigned char *
15949display_m68k_gnu_attribute (unsigned char * p,
15950 unsigned int tag,
15951 const unsigned char * const end)
15952{
15953 unsigned int val;
15954
15955 if (tag == Tag_GNU_M68K_ABI_FP)
15956 {
15957 printf (" Tag_GNU_M68K_ABI_FP: ");
15958 if (p == end)
15959 {
15960 printf (_("<corrupt>\n"));
15961 return p;
15962 }
15963 READ_ULEB (val, p, end);
15964
15965 if (val > 3)
15966 printf ("(%#x), ", val);
15967
15968 switch (val & 3)
15969 {
15970 case 0:
15971 printf (_("unspecified hard/soft float\n"));
15972 break;
15973 case 1:
15974 printf (_("hard float\n"));
15975 break;
15976 case 2:
15977 printf (_("soft float\n"));
15978 break;
15979 }
15980 return p;
15981 }
15982
15983 return display_tag_value (tag & 1, p, end);
15984}
15985
34c8bcba 15986static unsigned char *
f6f0e17b 15987display_power_gnu_attribute (unsigned char * p,
60abdbed 15988 unsigned int tag,
f6f0e17b 15989 const unsigned char * const end)
34c8bcba 15990{
005d79fd 15991 unsigned int val;
34c8bcba
JM
15992
15993 if (tag == Tag_GNU_Power_ABI_FP)
15994 {
34c8bcba 15995 printf (" Tag_GNU_Power_ABI_FP: ");
cd30bcef 15996 if (p == end)
005d79fd
AM
15997 {
15998 printf (_("<corrupt>\n"));
15999 return p;
16000 }
cd30bcef 16001 READ_ULEB (val, p, end);
60bca95a 16002
005d79fd
AM
16003 if (val > 15)
16004 printf ("(%#x), ", val);
16005
16006 switch (val & 3)
34c8bcba
JM
16007 {
16008 case 0:
005d79fd 16009 printf (_("unspecified hard/soft float, "));
34c8bcba
JM
16010 break;
16011 case 1:
005d79fd 16012 printf (_("hard float, "));
34c8bcba
JM
16013 break;
16014 case 2:
005d79fd 16015 printf (_("soft float, "));
34c8bcba 16016 break;
3c7b9897 16017 case 3:
005d79fd 16018 printf (_("single-precision hard float, "));
3c7b9897 16019 break;
005d79fd
AM
16020 }
16021
16022 switch (val & 0xC)
16023 {
16024 case 0:
16025 printf (_("unspecified long double\n"));
16026 break;
16027 case 4:
16028 printf (_("128-bit IBM long double\n"));
16029 break;
16030 case 8:
16031 printf (_("64-bit long double\n"));
16032 break;
16033 case 12:
16034 printf (_("128-bit IEEE long double\n"));
34c8bcba
JM
16035 break;
16036 }
16037 return p;
005d79fd 16038 }
34c8bcba 16039
c6e65352
DJ
16040 if (tag == Tag_GNU_Power_ABI_Vector)
16041 {
c6e65352 16042 printf (" Tag_GNU_Power_ABI_Vector: ");
cd30bcef 16043 if (p == end)
005d79fd
AM
16044 {
16045 printf (_("<corrupt>\n"));
16046 return p;
16047 }
cd30bcef 16048 READ_ULEB (val, p, end);
005d79fd
AM
16049
16050 if (val > 3)
16051 printf ("(%#x), ", val);
16052
16053 switch (val & 3)
c6e65352
DJ
16054 {
16055 case 0:
005d79fd 16056 printf (_("unspecified\n"));
c6e65352
DJ
16057 break;
16058 case 1:
005d79fd 16059 printf (_("generic\n"));
c6e65352
DJ
16060 break;
16061 case 2:
16062 printf ("AltiVec\n");
16063 break;
16064 case 3:
16065 printf ("SPE\n");
16066 break;
c6e65352
DJ
16067 }
16068 return p;
005d79fd 16069 }
c6e65352 16070
f82e0623
NF
16071 if (tag == Tag_GNU_Power_ABI_Struct_Return)
16072 {
005d79fd 16073 printf (" Tag_GNU_Power_ABI_Struct_Return: ");
cd30bcef 16074 if (p == end)
f6f0e17b 16075 {
005d79fd 16076 printf (_("<corrupt>\n"));
f6f0e17b
NC
16077 return p;
16078 }
cd30bcef 16079 READ_ULEB (val, p, end);
0b4362b0 16080
005d79fd
AM
16081 if (val > 2)
16082 printf ("(%#x), ", val);
16083
16084 switch (val & 3)
16085 {
16086 case 0:
16087 printf (_("unspecified\n"));
16088 break;
16089 case 1:
16090 printf ("r3/r4\n");
16091 break;
16092 case 2:
16093 printf (_("memory\n"));
16094 break;
16095 case 3:
16096 printf ("???\n");
16097 break;
16098 }
f82e0623
NF
16099 return p;
16100 }
16101
f6f0e17b 16102 return display_tag_value (tag & 1, p, end);
34c8bcba
JM
16103}
16104
643f7afb
AK
16105static unsigned char *
16106display_s390_gnu_attribute (unsigned char * p,
60abdbed 16107 unsigned int tag,
643f7afb
AK
16108 const unsigned char * const end)
16109{
cd30bcef 16110 unsigned int val;
643f7afb
AK
16111
16112 if (tag == Tag_GNU_S390_ABI_Vector)
16113 {
643f7afb 16114 printf (" Tag_GNU_S390_ABI_Vector: ");
cd30bcef 16115 READ_ULEB (val, p, end);
643f7afb
AK
16116
16117 switch (val)
16118 {
16119 case 0:
16120 printf (_("any\n"));
16121 break;
16122 case 1:
16123 printf (_("software\n"));
16124 break;
16125 case 2:
16126 printf (_("hardware\n"));
16127 break;
16128 default:
16129 printf ("??? (%d)\n", val);
16130 break;
16131 }
16132 return p;
16133 }
16134
16135 return display_tag_value (tag & 1, p, end);
16136}
16137
9e8c70f9 16138static void
60abdbed 16139display_sparc_hwcaps (unsigned int mask)
9e8c70f9
DM
16140{
16141 if (mask)
16142 {
32ec8896 16143 bfd_boolean first = TRUE;
071436c6 16144
9e8c70f9 16145 if (mask & ELF_SPARC_HWCAP_MUL32)
32ec8896 16146 fputs ("mul32", stdout), first = FALSE;
9e8c70f9 16147 if (mask & ELF_SPARC_HWCAP_DIV32)
32ec8896 16148 printf ("%sdiv32", first ? "" : "|"), first = FALSE;
9e8c70f9 16149 if (mask & ELF_SPARC_HWCAP_FSMULD)
32ec8896 16150 printf ("%sfsmuld", first ? "" : "|"), first = FALSE;
9e8c70f9 16151 if (mask & ELF_SPARC_HWCAP_V8PLUS)
32ec8896 16152 printf ("%sv8plus", first ? "" : "|"), first = FALSE;
9e8c70f9 16153 if (mask & ELF_SPARC_HWCAP_POPC)
32ec8896 16154 printf ("%spopc", first ? "" : "|"), first = FALSE;
9e8c70f9 16155 if (mask & ELF_SPARC_HWCAP_VIS)
32ec8896 16156 printf ("%svis", first ? "" : "|"), first = FALSE;
9e8c70f9 16157 if (mask & ELF_SPARC_HWCAP_VIS2)
32ec8896 16158 printf ("%svis2", first ? "" : "|"), first = FALSE;
9e8c70f9 16159 if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
32ec8896 16160 printf ("%sASIBlkInit", first ? "" : "|"), first = FALSE;
9e8c70f9 16161 if (mask & ELF_SPARC_HWCAP_FMAF)
32ec8896 16162 printf ("%sfmaf", first ? "" : "|"), first = FALSE;
9e8c70f9 16163 if (mask & ELF_SPARC_HWCAP_VIS3)
32ec8896 16164 printf ("%svis3", first ? "" : "|"), first = FALSE;
9e8c70f9 16165 if (mask & ELF_SPARC_HWCAP_HPC)
32ec8896 16166 printf ("%shpc", first ? "" : "|"), first = FALSE;
9e8c70f9 16167 if (mask & ELF_SPARC_HWCAP_RANDOM)
32ec8896 16168 printf ("%srandom", first ? "" : "|"), first = FALSE;
9e8c70f9 16169 if (mask & ELF_SPARC_HWCAP_TRANS)
32ec8896 16170 printf ("%strans", first ? "" : "|"), first = FALSE;
9e8c70f9 16171 if (mask & ELF_SPARC_HWCAP_FJFMAU)
32ec8896 16172 printf ("%sfjfmau", first ? "" : "|"), first = FALSE;
9e8c70f9 16173 if (mask & ELF_SPARC_HWCAP_IMA)
32ec8896 16174 printf ("%sima", first ? "" : "|"), first = FALSE;
9e8c70f9 16175 if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
32ec8896 16176 printf ("%scspare", first ? "" : "|"), first = FALSE;
9e8c70f9
DM
16177 }
16178 else
071436c6
NC
16179 fputc ('0', stdout);
16180 fputc ('\n', stdout);
9e8c70f9
DM
16181}
16182
3d68f91c 16183static void
60abdbed 16184display_sparc_hwcaps2 (unsigned int mask)
3d68f91c
JM
16185{
16186 if (mask)
16187 {
32ec8896 16188 bfd_boolean first = TRUE;
071436c6 16189
3d68f91c 16190 if (mask & ELF_SPARC_HWCAP2_FJATHPLUS)
32ec8896 16191 fputs ("fjathplus", stdout), first = FALSE;
3d68f91c 16192 if (mask & ELF_SPARC_HWCAP2_VIS3B)
32ec8896 16193 printf ("%svis3b", first ? "" : "|"), first = FALSE;
3d68f91c 16194 if (mask & ELF_SPARC_HWCAP2_ADP)
32ec8896 16195 printf ("%sadp", first ? "" : "|"), first = FALSE;
3d68f91c 16196 if (mask & ELF_SPARC_HWCAP2_SPARC5)
32ec8896 16197 printf ("%ssparc5", first ? "" : "|"), first = FALSE;
3d68f91c 16198 if (mask & ELF_SPARC_HWCAP2_MWAIT)
32ec8896 16199 printf ("%smwait", first ? "" : "|"), first = FALSE;
3d68f91c 16200 if (mask & ELF_SPARC_HWCAP2_XMPMUL)
32ec8896 16201 printf ("%sxmpmul", first ? "" : "|"), first = FALSE;
3d68f91c 16202 if (mask & ELF_SPARC_HWCAP2_XMONT)
32ec8896 16203 printf ("%sxmont2", first ? "" : "|"), first = FALSE;
3d68f91c 16204 if (mask & ELF_SPARC_HWCAP2_NSEC)
32ec8896 16205 printf ("%snsec", first ? "" : "|"), first = FALSE;
3d68f91c 16206 if (mask & ELF_SPARC_HWCAP2_FJATHHPC)
32ec8896 16207 printf ("%sfjathhpc", first ? "" : "|"), first = FALSE;
3d68f91c 16208 if (mask & ELF_SPARC_HWCAP2_FJDES)
32ec8896 16209 printf ("%sfjdes", first ? "" : "|"), first = FALSE;
3d68f91c 16210 if (mask & ELF_SPARC_HWCAP2_FJAES)
32ec8896 16211 printf ("%sfjaes", first ? "" : "|"), first = FALSE;
3d68f91c
JM
16212 }
16213 else
071436c6
NC
16214 fputc ('0', stdout);
16215 fputc ('\n', stdout);
3d68f91c
JM
16216}
16217
9e8c70f9 16218static unsigned char *
f6f0e17b 16219display_sparc_gnu_attribute (unsigned char * p,
60abdbed 16220 unsigned int tag,
f6f0e17b 16221 const unsigned char * const end)
9e8c70f9 16222{
cd30bcef 16223 unsigned int val;
3d68f91c 16224
9e8c70f9
DM
16225 if (tag == Tag_GNU_Sparc_HWCAPS)
16226 {
cd30bcef 16227 READ_ULEB (val, p, end);
9e8c70f9 16228 printf (" Tag_GNU_Sparc_HWCAPS: ");
9e8c70f9
DM
16229 display_sparc_hwcaps (val);
16230 return p;
3d68f91c
JM
16231 }
16232 if (tag == Tag_GNU_Sparc_HWCAPS2)
16233 {
cd30bcef 16234 READ_ULEB (val, p, end);
3d68f91c
JM
16235 printf (" Tag_GNU_Sparc_HWCAPS2: ");
16236 display_sparc_hwcaps2 (val);
16237 return p;
16238 }
9e8c70f9 16239
f6f0e17b 16240 return display_tag_value (tag, p, end);
9e8c70f9
DM
16241}
16242
351cdf24 16243static void
32ec8896 16244print_mips_fp_abi_value (unsigned int val)
351cdf24
MF
16245{
16246 switch (val)
16247 {
16248 case Val_GNU_MIPS_ABI_FP_ANY:
16249 printf (_("Hard or soft float\n"));
16250 break;
16251 case Val_GNU_MIPS_ABI_FP_DOUBLE:
16252 printf (_("Hard float (double precision)\n"));
16253 break;
16254 case Val_GNU_MIPS_ABI_FP_SINGLE:
16255 printf (_("Hard float (single precision)\n"));
16256 break;
16257 case Val_GNU_MIPS_ABI_FP_SOFT:
16258 printf (_("Soft float\n"));
16259 break;
16260 case Val_GNU_MIPS_ABI_FP_OLD_64:
16261 printf (_("Hard float (MIPS32r2 64-bit FPU 12 callee-saved)\n"));
16262 break;
16263 case Val_GNU_MIPS_ABI_FP_XX:
16264 printf (_("Hard float (32-bit CPU, Any FPU)\n"));
16265 break;
16266 case Val_GNU_MIPS_ABI_FP_64:
16267 printf (_("Hard float (32-bit CPU, 64-bit FPU)\n"));
16268 break;
16269 case Val_GNU_MIPS_ABI_FP_64A:
16270 printf (_("Hard float compat (32-bit CPU, 64-bit FPU)\n"));
16271 break;
3350cc01
CM
16272 case Val_GNU_MIPS_ABI_FP_NAN2008:
16273 printf (_("NaN 2008 compatibility\n"));
16274 break;
351cdf24
MF
16275 default:
16276 printf ("??? (%d)\n", val);
16277 break;
16278 }
16279}
16280
2cf19d5c 16281static unsigned char *
f6f0e17b 16282display_mips_gnu_attribute (unsigned char * p,
60abdbed 16283 unsigned int tag,
f6f0e17b 16284 const unsigned char * const end)
2cf19d5c 16285{
2cf19d5c
JM
16286 if (tag == Tag_GNU_MIPS_ABI_FP)
16287 {
32ec8896 16288 unsigned int val;
f6f0e17b 16289
2cf19d5c 16290 printf (" Tag_GNU_MIPS_ABI_FP: ");
cd30bcef 16291 READ_ULEB (val, p, end);
351cdf24 16292 print_mips_fp_abi_value (val);
2cf19d5c
JM
16293 return p;
16294 }
16295
a9f58168
CF
16296 if (tag == Tag_GNU_MIPS_ABI_MSA)
16297 {
32ec8896 16298 unsigned int val;
a9f58168 16299
a9f58168 16300 printf (" Tag_GNU_MIPS_ABI_MSA: ");
cd30bcef 16301 READ_ULEB (val, p, end);
a9f58168
CF
16302
16303 switch (val)
16304 {
16305 case Val_GNU_MIPS_ABI_MSA_ANY:
16306 printf (_("Any MSA or not\n"));
16307 break;
16308 case Val_GNU_MIPS_ABI_MSA_128:
16309 printf (_("128-bit MSA\n"));
16310 break;
16311 default:
16312 printf ("??? (%d)\n", val);
16313 break;
16314 }
16315 return p;
16316 }
16317
f6f0e17b 16318 return display_tag_value (tag & 1, p, end);
2cf19d5c
JM
16319}
16320
59e6276b 16321static unsigned char *
f6f0e17b
NC
16322display_tic6x_attribute (unsigned char * p,
16323 const unsigned char * const end)
59e6276b 16324{
60abdbed 16325 unsigned int tag;
cd30bcef 16326 unsigned int val;
59e6276b 16327
cd30bcef 16328 READ_ULEB (tag, p, end);
59e6276b
JM
16329
16330 switch (tag)
16331 {
75fa6dc1 16332 case Tag_ISA:
75fa6dc1 16333 printf (" Tag_ISA: ");
cd30bcef 16334 READ_ULEB (val, p, end);
59e6276b
JM
16335
16336 switch (val)
16337 {
75fa6dc1 16338 case C6XABI_Tag_ISA_none:
59e6276b
JM
16339 printf (_("None\n"));
16340 break;
75fa6dc1 16341 case C6XABI_Tag_ISA_C62X:
59e6276b
JM
16342 printf ("C62x\n");
16343 break;
75fa6dc1 16344 case C6XABI_Tag_ISA_C67X:
59e6276b
JM
16345 printf ("C67x\n");
16346 break;
75fa6dc1 16347 case C6XABI_Tag_ISA_C67XP:
59e6276b
JM
16348 printf ("C67x+\n");
16349 break;
75fa6dc1 16350 case C6XABI_Tag_ISA_C64X:
59e6276b
JM
16351 printf ("C64x\n");
16352 break;
75fa6dc1 16353 case C6XABI_Tag_ISA_C64XP:
59e6276b
JM
16354 printf ("C64x+\n");
16355 break;
75fa6dc1 16356 case C6XABI_Tag_ISA_C674X:
59e6276b
JM
16357 printf ("C674x\n");
16358 break;
16359 default:
16360 printf ("??? (%d)\n", val);
16361 break;
16362 }
16363 return p;
16364
87779176 16365 case Tag_ABI_wchar_t:
87779176 16366 printf (" Tag_ABI_wchar_t: ");
cd30bcef 16367 READ_ULEB (val, p, end);
87779176
JM
16368 switch (val)
16369 {
16370 case 0:
16371 printf (_("Not used\n"));
16372 break;
16373 case 1:
16374 printf (_("2 bytes\n"));
16375 break;
16376 case 2:
16377 printf (_("4 bytes\n"));
16378 break;
16379 default:
16380 printf ("??? (%d)\n", val);
16381 break;
16382 }
16383 return p;
16384
16385 case Tag_ABI_stack_align_needed:
87779176 16386 printf (" Tag_ABI_stack_align_needed: ");
cd30bcef 16387 READ_ULEB (val, p, end);
87779176
JM
16388 switch (val)
16389 {
16390 case 0:
16391 printf (_("8-byte\n"));
16392 break;
16393 case 1:
16394 printf (_("16-byte\n"));
16395 break;
16396 default:
16397 printf ("??? (%d)\n", val);
16398 break;
16399 }
16400 return p;
16401
16402 case Tag_ABI_stack_align_preserved:
cd30bcef 16403 READ_ULEB (val, p, end);
87779176
JM
16404 printf (" Tag_ABI_stack_align_preserved: ");
16405 switch (val)
16406 {
16407 case 0:
16408 printf (_("8-byte\n"));
16409 break;
16410 case 1:
16411 printf (_("16-byte\n"));
16412 break;
16413 default:
16414 printf ("??? (%d)\n", val);
16415 break;
16416 }
16417 return p;
16418
b5593623 16419 case Tag_ABI_DSBT:
cd30bcef 16420 READ_ULEB (val, p, end);
b5593623
JM
16421 printf (" Tag_ABI_DSBT: ");
16422 switch (val)
16423 {
16424 case 0:
16425 printf (_("DSBT addressing not used\n"));
16426 break;
16427 case 1:
16428 printf (_("DSBT addressing used\n"));
16429 break;
16430 default:
16431 printf ("??? (%d)\n", val);
16432 break;
16433 }
16434 return p;
16435
87779176 16436 case Tag_ABI_PID:
cd30bcef 16437 READ_ULEB (val, p, end);
87779176
JM
16438 printf (" Tag_ABI_PID: ");
16439 switch (val)
16440 {
16441 case 0:
16442 printf (_("Data addressing position-dependent\n"));
16443 break;
16444 case 1:
16445 printf (_("Data addressing position-independent, GOT near DP\n"));
16446 break;
16447 case 2:
16448 printf (_("Data addressing position-independent, GOT far from DP\n"));
16449 break;
16450 default:
16451 printf ("??? (%d)\n", val);
16452 break;
16453 }
16454 return p;
16455
16456 case Tag_ABI_PIC:
cd30bcef 16457 READ_ULEB (val, p, end);
87779176
JM
16458 printf (" Tag_ABI_PIC: ");
16459 switch (val)
16460 {
16461 case 0:
16462 printf (_("Code addressing position-dependent\n"));
16463 break;
16464 case 1:
16465 printf (_("Code addressing position-independent\n"));
16466 break;
16467 default:
16468 printf ("??? (%d)\n", val);
16469 break;
16470 }
16471 return p;
16472
16473 case Tag_ABI_array_object_alignment:
cd30bcef 16474 READ_ULEB (val, p, end);
87779176
JM
16475 printf (" Tag_ABI_array_object_alignment: ");
16476 switch (val)
16477 {
16478 case 0:
16479 printf (_("8-byte\n"));
16480 break;
16481 case 1:
16482 printf (_("4-byte\n"));
16483 break;
16484 case 2:
16485 printf (_("16-byte\n"));
16486 break;
16487 default:
16488 printf ("??? (%d)\n", val);
16489 break;
16490 }
16491 return p;
16492
16493 case Tag_ABI_array_object_align_expected:
cd30bcef 16494 READ_ULEB (val, p, end);
87779176
JM
16495 printf (" Tag_ABI_array_object_align_expected: ");
16496 switch (val)
16497 {
16498 case 0:
16499 printf (_("8-byte\n"));
16500 break;
16501 case 1:
16502 printf (_("4-byte\n"));
16503 break;
16504 case 2:
16505 printf (_("16-byte\n"));
16506 break;
16507 default:
16508 printf ("??? (%d)\n", val);
16509 break;
16510 }
16511 return p;
16512
3cbd1c06 16513 case Tag_ABI_compatibility:
071436c6 16514 {
cd30bcef 16515 READ_ULEB (val, p, end);
071436c6 16516 printf (" Tag_ABI_compatibility: ");
071436c6 16517 printf (_("flag = %d, vendor = "), val);
4082ef84
NC
16518 if (p < end - 1)
16519 {
16520 size_t maxlen = (end - p) - 1;
16521
16522 print_symbol ((int) maxlen, (const char *) p);
16523 p += strnlen ((char *) p, maxlen) + 1;
16524 }
16525 else
16526 {
16527 printf (_("<corrupt>"));
16528 p = (unsigned char *) end;
16529 }
071436c6 16530 putchar ('\n');
071436c6
NC
16531 return p;
16532 }
87779176
JM
16533
16534 case Tag_ABI_conformance:
071436c6 16535 {
4082ef84
NC
16536 printf (" Tag_ABI_conformance: \"");
16537 if (p < end - 1)
16538 {
16539 size_t maxlen = (end - p) - 1;
071436c6 16540
4082ef84
NC
16541 print_symbol ((int) maxlen, (const char *) p);
16542 p += strnlen ((char *) p, maxlen) + 1;
16543 }
16544 else
16545 {
16546 printf (_("<corrupt>"));
16547 p = (unsigned char *) end;
16548 }
071436c6 16549 printf ("\"\n");
071436c6
NC
16550 return p;
16551 }
59e6276b
JM
16552 }
16553
f6f0e17b
NC
16554 return display_tag_value (tag, p, end);
16555}
59e6276b 16556
f6f0e17b 16557static void
60abdbed 16558display_raw_attribute (unsigned char * p, unsigned char const * const end)
f6f0e17b
NC
16559{
16560 unsigned long addr = 0;
16561 size_t bytes = end - p;
16562
feceaa59 16563 assert (end >= p);
f6f0e17b 16564 while (bytes)
87779176 16565 {
f6f0e17b
NC
16566 int j;
16567 int k;
16568 int lbytes = (bytes > 16 ? 16 : bytes);
16569
16570 printf (" 0x%8.8lx ", addr);
16571
16572 for (j = 0; j < 16; j++)
16573 {
16574 if (j < lbytes)
16575 printf ("%2.2x", p[j]);
16576 else
16577 printf (" ");
16578
16579 if ((j & 3) == 3)
16580 printf (" ");
16581 }
16582
16583 for (j = 0; j < lbytes; j++)
16584 {
16585 k = p[j];
16586 if (k >= ' ' && k < 0x7f)
16587 printf ("%c", k);
16588 else
16589 printf (".");
16590 }
16591
16592 putchar ('\n');
16593
16594 p += lbytes;
16595 bytes -= lbytes;
16596 addr += lbytes;
87779176 16597 }
59e6276b 16598
f6f0e17b 16599 putchar ('\n');
59e6276b
JM
16600}
16601
13761a11 16602static unsigned char *
b0191216 16603display_msp430_attribute (unsigned char * p,
13761a11
NC
16604 const unsigned char * const end)
16605{
60abdbed
NC
16606 unsigned int val;
16607 unsigned int tag;
13761a11 16608
cd30bcef 16609 READ_ULEB (tag, p, end);
0b4362b0 16610
13761a11
NC
16611 switch (tag)
16612 {
16613 case OFBA_MSPABI_Tag_ISA:
13761a11 16614 printf (" Tag_ISA: ");
cd30bcef 16615 READ_ULEB (val, p, end);
13761a11
NC
16616 switch (val)
16617 {
16618 case 0: printf (_("None\n")); break;
16619 case 1: printf (_("MSP430\n")); break;
16620 case 2: printf (_("MSP430X\n")); break;
16621 default: printf ("??? (%d)\n", val); break;
16622 }
16623 break;
16624
16625 case OFBA_MSPABI_Tag_Code_Model:
13761a11 16626 printf (" Tag_Code_Model: ");
cd30bcef 16627 READ_ULEB (val, p, end);
13761a11
NC
16628 switch (val)
16629 {
16630 case 0: printf (_("None\n")); break;
16631 case 1: printf (_("Small\n")); break;
16632 case 2: printf (_("Large\n")); break;
16633 default: printf ("??? (%d)\n", val); break;
16634 }
16635 break;
16636
16637 case OFBA_MSPABI_Tag_Data_Model:
13761a11 16638 printf (" Tag_Data_Model: ");
cd30bcef 16639 READ_ULEB (val, p, end);
13761a11
NC
16640 switch (val)
16641 {
16642 case 0: printf (_("None\n")); break;
16643 case 1: printf (_("Small\n")); break;
16644 case 2: printf (_("Large\n")); break;
16645 case 3: printf (_("Restricted Large\n")); break;
16646 default: printf ("??? (%d)\n", val); break;
16647 }
16648 break;
16649
16650 default:
16651 printf (_(" <unknown tag %d>: "), tag);
16652
16653 if (tag & 1)
16654 {
071436c6 16655 putchar ('"');
4082ef84
NC
16656 if (p < end - 1)
16657 {
16658 size_t maxlen = (end - p) - 1;
16659
16660 print_symbol ((int) maxlen, (const char *) p);
16661 p += strnlen ((char *) p, maxlen) + 1;
16662 }
16663 else
16664 {
16665 printf (_("<corrupt>"));
16666 p = (unsigned char *) end;
16667 }
071436c6 16668 printf ("\"\n");
13761a11
NC
16669 }
16670 else
16671 {
cd30bcef 16672 READ_ULEB (val, p, end);
13761a11
NC
16673 printf ("%d (0x%x)\n", val, val);
16674 }
16675 break;
16676 }
16677
4082ef84 16678 assert (p <= end);
13761a11
NC
16679 return p;
16680}
16681
c0ea7c52
JL
16682static unsigned char *
16683display_msp430_gnu_attribute (unsigned char * p,
16684 unsigned int tag,
16685 const unsigned char * const end)
16686{
16687 if (tag == Tag_GNU_MSP430_Data_Region)
16688 {
cd30bcef 16689 unsigned int val;
c0ea7c52 16690
c0ea7c52 16691 printf (" Tag_GNU_MSP430_Data_Region: ");
cd30bcef 16692 READ_ULEB (val, p, end);
c0ea7c52
JL
16693
16694 switch (val)
16695 {
16696 case Val_GNU_MSP430_Data_Region_Any:
16697 printf (_("Any Region\n"));
16698 break;
16699 case Val_GNU_MSP430_Data_Region_Lower:
16700 printf (_("Lower Region Only\n"));
16701 break;
16702 default:
cd30bcef 16703 printf ("??? (%u)\n", val);
c0ea7c52
JL
16704 }
16705 return p;
16706 }
16707 return display_tag_value (tag & 1, p, end);
16708}
16709
2dc8dd17
JW
16710struct riscv_attr_tag_t {
16711 const char *name;
cd30bcef 16712 unsigned int tag;
2dc8dd17
JW
16713};
16714
16715static struct riscv_attr_tag_t riscv_attr_tag[] =
16716{
16717#define T(tag) {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
16718 T(arch),
16719 T(priv_spec),
16720 T(priv_spec_minor),
16721 T(priv_spec_revision),
16722 T(unaligned_access),
16723 T(stack_align),
16724#undef T
16725};
16726
16727static unsigned char *
16728display_riscv_attribute (unsigned char *p,
16729 const unsigned char * const end)
16730{
cd30bcef
AM
16731 unsigned int val;
16732 unsigned int tag;
2dc8dd17
JW
16733 struct riscv_attr_tag_t *attr = NULL;
16734 unsigned i;
16735
cd30bcef 16736 READ_ULEB (tag, p, end);
2dc8dd17
JW
16737
16738 /* Find the name of attribute. */
16739 for (i = 0; i < ARRAY_SIZE (riscv_attr_tag); i++)
16740 {
16741 if (riscv_attr_tag[i].tag == tag)
16742 {
16743 attr = &riscv_attr_tag[i];
16744 break;
16745 }
16746 }
16747
16748 if (attr)
16749 printf (" %s: ", attr->name);
16750 else
16751 return display_tag_value (tag, p, end);
16752
16753 switch (tag)
16754 {
16755 case Tag_RISCV_priv_spec:
16756 case Tag_RISCV_priv_spec_minor:
16757 case Tag_RISCV_priv_spec_revision:
cd30bcef
AM
16758 READ_ULEB (val, p, end);
16759 printf (_("%u\n"), val);
2dc8dd17
JW
16760 break;
16761 case Tag_RISCV_unaligned_access:
cd30bcef 16762 READ_ULEB (val, p, end);
2dc8dd17
JW
16763 switch (val)
16764 {
16765 case 0:
16766 printf (_("No unaligned access\n"));
16767 break;
16768 case 1:
16769 printf (_("Unaligned access\n"));
16770 break;
16771 }
16772 break;
16773 case Tag_RISCV_stack_align:
cd30bcef
AM
16774 READ_ULEB (val, p, end);
16775 printf (_("%u-bytes\n"), val);
2dc8dd17
JW
16776 break;
16777 case Tag_RISCV_arch:
16778 p = display_tag_value (-1, p, end);
16779 break;
16780 default:
16781 return display_tag_value (tag, p, end);
16782 }
16783
16784 return p;
16785}
16786
0861f561
CQ
16787static unsigned char *
16788display_csky_attribute (unsigned char * p,
16789 const unsigned char * const end)
16790{
16791 unsigned int tag;
16792 unsigned int val;
16793 READ_ULEB (tag, p, end);
16794
16795 if (tag >= Tag_CSKY_MAX)
16796 {
16797 return display_tag_value (-1, p, end);
16798 }
16799
16800 switch (tag)
16801 {
16802 case Tag_CSKY_ARCH_NAME:
16803 printf (" Tag_CSKY_ARCH_NAME:\t\t");
16804 return display_tag_value (-1, p, end);
16805 case Tag_CSKY_CPU_NAME:
16806 printf (" Tag_CSKY_CPU_NAME:\t\t");
16807 return display_tag_value (-1, p, end);
16808
16809 case Tag_CSKY_ISA_FLAGS:
16810 printf (" Tag_CSKY_ISA_FLAGS:\t\t");
16811 return display_tag_value (0, p, end);
16812 case Tag_CSKY_ISA_EXT_FLAGS:
16813 printf (" Tag_CSKY_ISA_EXT_FLAGS:\t");
16814 return display_tag_value (0, p, end);
16815
16816 case Tag_CSKY_DSP_VERSION:
16817 printf (" Tag_CSKY_DSP_VERSION:\t\t");
16818 READ_ULEB (val, p, end);
16819 if (val == VAL_CSKY_DSP_VERSION_EXTENSION)
16820 printf ("DSP Extension\n");
16821 else if (val == VAL_CSKY_DSP_VERSION_2)
16822 printf ("DSP 2.0\n");
16823 break;
16824
16825 case Tag_CSKY_VDSP_VERSION:
16826 printf (" Tag_CSKY_VDSP_VERSION:\t");
16827 READ_ULEB (val, p, end);
16828 printf ("VDSP Version %d\n", val);
16829 break;
16830
16831 case Tag_CSKY_FPU_VERSION:
16832 printf (" Tag_CSKY_FPU_VERSION:\t\t");
16833 READ_ULEB (val, p, end);
16834 if (val == VAL_CSKY_FPU_VERSION_1)
16835 printf ("ABIV1 FPU Version 1\n");
16836 else if (val == VAL_CSKY_FPU_VERSION_2)
16837 printf ("FPU Version 2\n");
16838 break;
16839
16840 case Tag_CSKY_FPU_ABI:
16841 printf (" Tag_CSKY_FPU_ABI:\t\t");
16842 READ_ULEB (val, p, end);
16843 if (val == VAL_CSKY_FPU_ABI_HARD)
16844 printf ("Hard\n");
16845 else if (val == VAL_CSKY_FPU_ABI_SOFTFP)
16846 printf ("SoftFP\n");
16847 else if (val == VAL_CSKY_FPU_ABI_SOFT)
16848 printf ("Soft\n");
16849 break;
16850 case Tag_CSKY_FPU_ROUNDING:
16851 READ_ULEB (val, p, end);
16852 if (val == 1) {
16853 printf (" Tag_CSKY_FPU_ROUNDING:\t");
16854 printf ("Needed\n");
16855 }
16856 break;
16857 case Tag_CSKY_FPU_DENORMAL:
16858 READ_ULEB (val, p, end);
16859 if (val == 1) {
16860 printf (" Tag_CSKY_FPU_DENORMAL:\t");
16861 printf ("Needed\n");
16862 }
16863 break;
16864 case Tag_CSKY_FPU_Exception:
16865 READ_ULEB (val, p, end);
16866 if (val == 1) {
16867 printf (" Tag_CSKY_FPU_Exception:\t");
16868 printf ("Needed\n");
16869 }
16870 break;
16871 case Tag_CSKY_FPU_NUMBER_MODULE:
16872 printf (" Tag_CSKY_FPU_NUMBER_MODULE:\t");
16873 return display_tag_value (-1, p, end);
16874 case Tag_CSKY_FPU_HARDFP:
16875 printf (" Tag_CSKY_FPU_HARDFP:\t\t");
16876 READ_ULEB (val, p, end);
16877 if (val & VAL_CSKY_FPU_HARDFP_HALF)
16878 printf (" Half");
16879 if (val & VAL_CSKY_FPU_HARDFP_SINGLE)
16880 printf (" Single");
16881 if (val & VAL_CSKY_FPU_HARDFP_DOUBLE)
16882 printf (" Double");
16883 printf ("\n");
16884 break;
16885 default:
16886 return display_tag_value (tag, p, end);
16887 }
16888 return p;
16889}
16890
32ec8896 16891static bfd_boolean
dda8d76d 16892process_attributes (Filedata * filedata,
60bca95a 16893 const char * public_name,
104d59d1 16894 unsigned int proc_type,
f6f0e17b 16895 unsigned char * (* display_pub_attribute) (unsigned char *, const unsigned char * const),
60abdbed 16896 unsigned char * (* display_proc_gnu_attribute) (unsigned char *, unsigned int, const unsigned char * const))
11c1ff18 16897{
2cf0635d 16898 Elf_Internal_Shdr * sect;
11c1ff18 16899 unsigned i;
32ec8896 16900 bfd_boolean res = TRUE;
11c1ff18
PB
16901
16902 /* Find the section header so that we get the size. */
dda8d76d
NC
16903 for (i = 0, sect = filedata->section_headers;
16904 i < filedata->file_header.e_shnum;
11c1ff18
PB
16905 i++, sect++)
16906 {
071436c6
NC
16907 unsigned char * contents;
16908 unsigned char * p;
16909
104d59d1 16910 if (sect->sh_type != proc_type && sect->sh_type != SHT_GNU_ATTRIBUTES)
11c1ff18
PB
16911 continue;
16912
dda8d76d 16913 contents = (unsigned char *) get_data (NULL, filedata, sect->sh_offset, 1,
3f5e193b 16914 sect->sh_size, _("attributes"));
60bca95a 16915 if (contents == NULL)
32ec8896
NC
16916 {
16917 res = FALSE;
16918 continue;
16919 }
60bca95a 16920
11c1ff18 16921 p = contents;
60abdbed
NC
16922 /* The first character is the version of the attributes.
16923 Currently only version 1, (aka 'A') is recognised here. */
16924 if (*p != 'A')
32ec8896
NC
16925 {
16926 printf (_("Unknown attributes version '%c'(%d) - expecting 'A'\n"), *p, *p);
16927 res = FALSE;
16928 }
60abdbed 16929 else
11c1ff18 16930 {
071436c6
NC
16931 bfd_vma section_len;
16932
16933 section_len = sect->sh_size - 1;
11c1ff18 16934 p++;
60bca95a 16935
071436c6 16936 while (section_len > 0)
11c1ff18 16937 {
071436c6 16938 bfd_vma attr_len;
e9847026 16939 unsigned int namelen;
11c1ff18 16940 bfd_boolean public_section;
104d59d1 16941 bfd_boolean gnu_section;
11c1ff18 16942
071436c6 16943 if (section_len <= 4)
e0a31db1
NC
16944 {
16945 error (_("Tag section ends prematurely\n"));
32ec8896 16946 res = FALSE;
e0a31db1
NC
16947 break;
16948 }
071436c6 16949 attr_len = byte_get (p, 4);
11c1ff18 16950 p += 4;
60bca95a 16951
071436c6 16952 if (attr_len > section_len)
11c1ff18 16953 {
071436c6
NC
16954 error (_("Bad attribute length (%u > %u)\n"),
16955 (unsigned) attr_len, (unsigned) section_len);
16956 attr_len = section_len;
32ec8896 16957 res = FALSE;
11c1ff18 16958 }
74e1a04b 16959 /* PR 17531: file: 001-101425-0.004 */
071436c6 16960 else if (attr_len < 5)
74e1a04b 16961 {
071436c6 16962 error (_("Attribute length of %u is too small\n"), (unsigned) attr_len);
32ec8896 16963 res = FALSE;
74e1a04b
NC
16964 break;
16965 }
e9847026 16966
071436c6
NC
16967 section_len -= attr_len;
16968 attr_len -= 4;
16969
16970 namelen = strnlen ((char *) p, attr_len) + 1;
16971 if (namelen == 0 || namelen >= attr_len)
e9847026
NC
16972 {
16973 error (_("Corrupt attribute section name\n"));
32ec8896 16974 res = FALSE;
e9847026
NC
16975 break;
16976 }
16977
071436c6
NC
16978 printf (_("Attribute Section: "));
16979 print_symbol (INT_MAX, (const char *) p);
16980 putchar ('\n');
60bca95a
NC
16981
16982 if (public_name && streq ((char *) p, public_name))
11c1ff18
PB
16983 public_section = TRUE;
16984 else
16985 public_section = FALSE;
60bca95a
NC
16986
16987 if (streq ((char *) p, "gnu"))
104d59d1
JM
16988 gnu_section = TRUE;
16989 else
16990 gnu_section = FALSE;
60bca95a 16991
11c1ff18 16992 p += namelen;
071436c6 16993 attr_len -= namelen;
e0a31db1 16994
071436c6 16995 while (attr_len > 0 && p < contents + sect->sh_size)
11c1ff18 16996 {
e0a31db1 16997 int tag;
cd30bcef 16998 unsigned int val;
11c1ff18 16999 bfd_vma size;
071436c6 17000 unsigned char * end;
60bca95a 17001
e0a31db1 17002 /* PR binutils/17531: Safe handling of corrupt files. */
071436c6 17003 if (attr_len < 6)
e0a31db1
NC
17004 {
17005 error (_("Unused bytes at end of section\n"));
32ec8896 17006 res = FALSE;
e0a31db1
NC
17007 section_len = 0;
17008 break;
17009 }
17010
17011 tag = *(p++);
11c1ff18 17012 size = byte_get (p, 4);
071436c6 17013 if (size > attr_len)
11c1ff18 17014 {
e9847026 17015 error (_("Bad subsection length (%u > %u)\n"),
071436c6 17016 (unsigned) size, (unsigned) attr_len);
32ec8896 17017 res = FALSE;
071436c6 17018 size = attr_len;
11c1ff18 17019 }
e0a31db1
NC
17020 /* PR binutils/17531: Safe handling of corrupt files. */
17021 if (size < 6)
17022 {
17023 error (_("Bad subsection length (%u < 6)\n"),
17024 (unsigned) size);
32ec8896 17025 res = FALSE;
e0a31db1
NC
17026 section_len = 0;
17027 break;
17028 }
60bca95a 17029
071436c6 17030 attr_len -= size;
11c1ff18 17031 end = p + size - 1;
071436c6 17032 assert (end <= contents + sect->sh_size);
11c1ff18 17033 p += 4;
60bca95a 17034
11c1ff18
PB
17035 switch (tag)
17036 {
17037 case 1:
2b692964 17038 printf (_("File Attributes\n"));
11c1ff18
PB
17039 break;
17040 case 2:
2b692964 17041 printf (_("Section Attributes:"));
11c1ff18
PB
17042 goto do_numlist;
17043 case 3:
2b692964 17044 printf (_("Symbol Attributes:"));
1a0670f3 17045 /* Fall through. */
11c1ff18
PB
17046 do_numlist:
17047 for (;;)
17048 {
cd30bcef 17049 READ_ULEB (val, p, end);
11c1ff18
PB
17050 if (val == 0)
17051 break;
17052 printf (" %d", val);
17053 }
17054 printf ("\n");
17055 break;
17056 default:
2b692964 17057 printf (_("Unknown tag: %d\n"), tag);
11c1ff18
PB
17058 public_section = FALSE;
17059 break;
17060 }
60bca95a 17061
071436c6 17062 if (public_section && display_pub_attribute != NULL)
11c1ff18
PB
17063 {
17064 while (p < end)
f6f0e17b 17065 p = display_pub_attribute (p, end);
60abdbed 17066 assert (p == end);
104d59d1 17067 }
071436c6 17068 else if (gnu_section && display_proc_gnu_attribute != NULL)
104d59d1
JM
17069 {
17070 while (p < end)
17071 p = display_gnu_attribute (p,
f6f0e17b
NC
17072 display_proc_gnu_attribute,
17073 end);
60abdbed 17074 assert (p == end);
11c1ff18 17075 }
071436c6 17076 else if (p < end)
11c1ff18 17077 {
071436c6 17078 printf (_(" Unknown attribute:\n"));
f6f0e17b 17079 display_raw_attribute (p, end);
11c1ff18
PB
17080 p = end;
17081 }
071436c6
NC
17082 else
17083 attr_len = 0;
11c1ff18
PB
17084 }
17085 }
17086 }
d70c5fc7 17087
60bca95a 17088 free (contents);
11c1ff18 17089 }
32ec8896
NC
17090
17091 return res;
11c1ff18
PB
17092}
17093
ccb4c951
RS
17094/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
17095 Print the Address, Access and Initial fields of an entry at VMA ADDR
82b1b41b
NC
17096 and return the VMA of the next entry, or -1 if there was a problem.
17097 Does not read from DATA_END or beyond. */
ccb4c951
RS
17098
17099static bfd_vma
82b1b41b
NC
17100print_mips_got_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr,
17101 unsigned char * data_end)
ccb4c951
RS
17102{
17103 printf (" ");
17104 print_vma (addr, LONG_HEX);
17105 printf (" ");
17106 if (addr < pltgot + 0xfff0)
17107 printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
17108 else
17109 printf ("%10s", "");
17110 printf (" ");
17111 if (data == NULL)
2b692964 17112 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
ccb4c951
RS
17113 else
17114 {
17115 bfd_vma entry;
82b1b41b 17116 unsigned char * from = data + addr - pltgot;
ccb4c951 17117
82b1b41b
NC
17118 if (from + (is_32bit_elf ? 4 : 8) > data_end)
17119 {
17120 warn (_("MIPS GOT entry extends beyond the end of available data\n"));
17121 printf ("%*s", is_32bit_elf ? 8 : 16, _("<corrupt>"));
17122 return (bfd_vma) -1;
17123 }
17124 else
17125 {
17126 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17127 print_vma (entry, LONG_HEX);
17128 }
ccb4c951
RS
17129 }
17130 return addr + (is_32bit_elf ? 4 : 8);
17131}
17132
861fb55a
DJ
17133/* DATA points to the contents of a MIPS PLT GOT that starts at VMA
17134 PLTGOT. Print the Address and Initial fields of an entry at VMA
17135 ADDR and return the VMA of the next entry. */
17136
17137static bfd_vma
2cf0635d 17138print_mips_pltgot_entry (unsigned char * data, bfd_vma pltgot, bfd_vma addr)
861fb55a
DJ
17139{
17140 printf (" ");
17141 print_vma (addr, LONG_HEX);
17142 printf (" ");
17143 if (data == NULL)
2b692964 17144 printf ("%*s", is_32bit_elf ? 8 : 16, _("<unknown>"));
861fb55a
DJ
17145 else
17146 {
17147 bfd_vma entry;
17148
17149 entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
17150 print_vma (entry, LONG_HEX);
17151 }
17152 return addr + (is_32bit_elf ? 4 : 8);
17153}
17154
351cdf24
MF
17155static void
17156print_mips_ases (unsigned int mask)
17157{
17158 if (mask & AFL_ASE_DSP)
17159 fputs ("\n\tDSP ASE", stdout);
17160 if (mask & AFL_ASE_DSPR2)
17161 fputs ("\n\tDSP R2 ASE", stdout);
8f4f9071
MF
17162 if (mask & AFL_ASE_DSPR3)
17163 fputs ("\n\tDSP R3 ASE", stdout);
351cdf24
MF
17164 if (mask & AFL_ASE_EVA)
17165 fputs ("\n\tEnhanced VA Scheme", stdout);
17166 if (mask & AFL_ASE_MCU)
17167 fputs ("\n\tMCU (MicroController) ASE", stdout);
17168 if (mask & AFL_ASE_MDMX)
17169 fputs ("\n\tMDMX ASE", stdout);
17170 if (mask & AFL_ASE_MIPS3D)
17171 fputs ("\n\tMIPS-3D ASE", stdout);
17172 if (mask & AFL_ASE_MT)
17173 fputs ("\n\tMT ASE", stdout);
17174 if (mask & AFL_ASE_SMARTMIPS)
17175 fputs ("\n\tSmartMIPS ASE", stdout);
17176 if (mask & AFL_ASE_VIRT)
17177 fputs ("\n\tVZ ASE", stdout);
17178 if (mask & AFL_ASE_MSA)
17179 fputs ("\n\tMSA ASE", stdout);
17180 if (mask & AFL_ASE_MIPS16)
17181 fputs ("\n\tMIPS16 ASE", stdout);
17182 if (mask & AFL_ASE_MICROMIPS)
17183 fputs ("\n\tMICROMIPS ASE", stdout);
17184 if (mask & AFL_ASE_XPA)
17185 fputs ("\n\tXPA ASE", stdout);
25499ac7
MR
17186 if (mask & AFL_ASE_MIPS16E2)
17187 fputs ("\n\tMIPS16e2 ASE", stdout);
730c3174
SE
17188 if (mask & AFL_ASE_CRC)
17189 fputs ("\n\tCRC ASE", stdout);
6f20c942
FS
17190 if (mask & AFL_ASE_GINV)
17191 fputs ("\n\tGINV ASE", stdout);
8095d2f7
CX
17192 if (mask & AFL_ASE_LOONGSON_MMI)
17193 fputs ("\n\tLoongson MMI ASE", stdout);
716c08de
CX
17194 if (mask & AFL_ASE_LOONGSON_CAM)
17195 fputs ("\n\tLoongson CAM ASE", stdout);
bdc6c06e
CX
17196 if (mask & AFL_ASE_LOONGSON_EXT)
17197 fputs ("\n\tLoongson EXT ASE", stdout);
a693765e
CX
17198 if (mask & AFL_ASE_LOONGSON_EXT2)
17199 fputs ("\n\tLoongson EXT2 ASE", stdout);
351cdf24
MF
17200 if (mask == 0)
17201 fprintf (stdout, "\n\t%s", _("None"));
00ac7aa0
MF
17202 else if ((mask & ~AFL_ASE_MASK) != 0)
17203 fprintf (stdout, "\n\t%s (%x)", _("Unknown"), mask & ~AFL_ASE_MASK);
351cdf24
MF
17204}
17205
17206static void
17207print_mips_isa_ext (unsigned int isa_ext)
17208{
17209 switch (isa_ext)
17210 {
17211 case 0:
17212 fputs (_("None"), stdout);
17213 break;
17214 case AFL_EXT_XLR:
17215 fputs ("RMI XLR", stdout);
17216 break;
2c629856
N
17217 case AFL_EXT_OCTEON3:
17218 fputs ("Cavium Networks Octeon3", stdout);
17219 break;
351cdf24
MF
17220 case AFL_EXT_OCTEON2:
17221 fputs ("Cavium Networks Octeon2", stdout);
17222 break;
17223 case AFL_EXT_OCTEONP:
17224 fputs ("Cavium Networks OcteonP", stdout);
17225 break;
351cdf24
MF
17226 case AFL_EXT_OCTEON:
17227 fputs ("Cavium Networks Octeon", stdout);
17228 break;
17229 case AFL_EXT_5900:
17230 fputs ("Toshiba R5900", stdout);
17231 break;
17232 case AFL_EXT_4650:
17233 fputs ("MIPS R4650", stdout);
17234 break;
17235 case AFL_EXT_4010:
17236 fputs ("LSI R4010", stdout);
17237 break;
17238 case AFL_EXT_4100:
17239 fputs ("NEC VR4100", stdout);
17240 break;
17241 case AFL_EXT_3900:
17242 fputs ("Toshiba R3900", stdout);
17243 break;
17244 case AFL_EXT_10000:
17245 fputs ("MIPS R10000", stdout);
17246 break;
17247 case AFL_EXT_SB1:
17248 fputs ("Broadcom SB-1", stdout);
17249 break;
17250 case AFL_EXT_4111:
17251 fputs ("NEC VR4111/VR4181", stdout);
17252 break;
17253 case AFL_EXT_4120:
17254 fputs ("NEC VR4120", stdout);
17255 break;
17256 case AFL_EXT_5400:
17257 fputs ("NEC VR5400", stdout);
17258 break;
17259 case AFL_EXT_5500:
17260 fputs ("NEC VR5500", stdout);
17261 break;
17262 case AFL_EXT_LOONGSON_2E:
17263 fputs ("ST Microelectronics Loongson 2E", stdout);
17264 break;
17265 case AFL_EXT_LOONGSON_2F:
17266 fputs ("ST Microelectronics Loongson 2F", stdout);
17267 break;
38bf472a
MR
17268 case AFL_EXT_INTERAPTIV_MR2:
17269 fputs ("Imagination interAptiv MR2", stdout);
17270 break;
351cdf24 17271 default:
00ac7aa0 17272 fprintf (stdout, "%s (%d)", _("Unknown"), isa_ext);
351cdf24
MF
17273 }
17274}
17275
32ec8896 17276static signed int
351cdf24
MF
17277get_mips_reg_size (int reg_size)
17278{
17279 return (reg_size == AFL_REG_NONE) ? 0
17280 : (reg_size == AFL_REG_32) ? 32
17281 : (reg_size == AFL_REG_64) ? 64
17282 : (reg_size == AFL_REG_128) ? 128
17283 : -1;
17284}
17285
32ec8896 17286static bfd_boolean
dda8d76d 17287process_mips_specific (Filedata * filedata)
5b18a4bc 17288{
2cf0635d 17289 Elf_Internal_Dyn * entry;
351cdf24 17290 Elf_Internal_Shdr *sect = NULL;
19e6b90e
L
17291 size_t liblist_offset = 0;
17292 size_t liblistno = 0;
17293 size_t conflictsno = 0;
17294 size_t options_offset = 0;
17295 size_t conflicts_offset = 0;
861fb55a
DJ
17296 size_t pltrelsz = 0;
17297 size_t pltrel = 0;
ccb4c951 17298 bfd_vma pltgot = 0;
861fb55a
DJ
17299 bfd_vma mips_pltgot = 0;
17300 bfd_vma jmprel = 0;
ccb4c951
RS
17301 bfd_vma local_gotno = 0;
17302 bfd_vma gotsym = 0;
17303 bfd_vma symtabno = 0;
32ec8896 17304 bfd_boolean res = TRUE;
103f02d3 17305
dda8d76d 17306 if (! process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
32ec8896
NC
17307 display_mips_gnu_attribute))
17308 res = FALSE;
2cf19d5c 17309
dda8d76d 17310 sect = find_section (filedata, ".MIPS.abiflags");
351cdf24
MF
17311
17312 if (sect != NULL)
17313 {
17314 Elf_External_ABIFlags_v0 *abiflags_ext;
17315 Elf_Internal_ABIFlags_v0 abiflags_in;
17316
17317 if (sizeof (Elf_External_ABIFlags_v0) != sect->sh_size)
32ec8896
NC
17318 {
17319 error (_("Corrupt MIPS ABI Flags section.\n"));
17320 res = FALSE;
17321 }
351cdf24
MF
17322 else
17323 {
dda8d76d 17324 abiflags_ext = get_data (NULL, filedata, sect->sh_offset, 1,
351cdf24
MF
17325 sect->sh_size, _("MIPS ABI Flags section"));
17326 if (abiflags_ext)
17327 {
17328 abiflags_in.version = BYTE_GET (abiflags_ext->version);
17329 abiflags_in.isa_level = BYTE_GET (abiflags_ext->isa_level);
17330 abiflags_in.isa_rev = BYTE_GET (abiflags_ext->isa_rev);
17331 abiflags_in.gpr_size = BYTE_GET (abiflags_ext->gpr_size);
17332 abiflags_in.cpr1_size = BYTE_GET (abiflags_ext->cpr1_size);
17333 abiflags_in.cpr2_size = BYTE_GET (abiflags_ext->cpr2_size);
17334 abiflags_in.fp_abi = BYTE_GET (abiflags_ext->fp_abi);
17335 abiflags_in.isa_ext = BYTE_GET (abiflags_ext->isa_ext);
17336 abiflags_in.ases = BYTE_GET (abiflags_ext->ases);
17337 abiflags_in.flags1 = BYTE_GET (abiflags_ext->flags1);
17338 abiflags_in.flags2 = BYTE_GET (abiflags_ext->flags2);
17339
17340 printf ("\nMIPS ABI Flags Version: %d\n", abiflags_in.version);
17341 printf ("\nISA: MIPS%d", abiflags_in.isa_level);
17342 if (abiflags_in.isa_rev > 1)
17343 printf ("r%d", abiflags_in.isa_rev);
17344 printf ("\nGPR size: %d",
17345 get_mips_reg_size (abiflags_in.gpr_size));
17346 printf ("\nCPR1 size: %d",
17347 get_mips_reg_size (abiflags_in.cpr1_size));
17348 printf ("\nCPR2 size: %d",
17349 get_mips_reg_size (abiflags_in.cpr2_size));
17350 fputs ("\nFP ABI: ", stdout);
17351 print_mips_fp_abi_value (abiflags_in.fp_abi);
17352 fputs ("ISA Extension: ", stdout);
17353 print_mips_isa_ext (abiflags_in.isa_ext);
17354 fputs ("\nASEs:", stdout);
17355 print_mips_ases (abiflags_in.ases);
17356 printf ("\nFLAGS 1: %8.8lx", abiflags_in.flags1);
17357 printf ("\nFLAGS 2: %8.8lx", abiflags_in.flags2);
17358 fputc ('\n', stdout);
17359 free (abiflags_ext);
17360 }
17361 }
17362 }
17363
19e6b90e 17364 /* We have a lot of special sections. Thanks SGI! */
978c4450 17365 if (filedata->dynamic_section == NULL)
bbdd9a68
MR
17366 {
17367 /* No dynamic information available. See if there is static GOT. */
dda8d76d 17368 sect = find_section (filedata, ".got");
bbdd9a68
MR
17369 if (sect != NULL)
17370 {
17371 unsigned char *data_end;
17372 unsigned char *data;
17373 bfd_vma ent, end;
17374 int addr_size;
17375
17376 pltgot = sect->sh_addr;
17377
17378 ent = pltgot;
17379 addr_size = (is_32bit_elf ? 4 : 8);
17380 end = pltgot + sect->sh_size;
17381
dda8d76d 17382 data = (unsigned char *) get_data (NULL, filedata, sect->sh_offset,
bbdd9a68
MR
17383 end - pltgot, 1,
17384 _("Global Offset Table data"));
17385 /* PR 12855: Null data is handled gracefully throughout. */
17386 data_end = data + (end - pltgot);
17387
17388 printf (_("\nStatic GOT:\n"));
17389 printf (_(" Canonical gp value: "));
17390 print_vma (ent + 0x7ff0, LONG_HEX);
17391 printf ("\n\n");
17392
17393 /* In a dynamic binary GOT[0] is reserved for the dynamic
17394 loader to store the lazy resolver pointer, however in
17395 a static binary it may well have been omitted and GOT
17396 reduced to a table of addresses.
17397 PR 21344: Check for the entry being fully available
17398 before fetching it. */
17399 if (data
17400 && data + ent - pltgot + addr_size <= data_end
17401 && byte_get (data + ent - pltgot, addr_size) == 0)
17402 {
17403 printf (_(" Reserved entries:\n"));
17404 printf (_(" %*s %10s %*s\n"),
17405 addr_size * 2, _("Address"), _("Access"),
17406 addr_size * 2, _("Value"));
17407 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17408 printf ("\n");
17409 if (ent == (bfd_vma) -1)
17410 goto sgot_print_fail;
17411
17412 /* Check for the MSB of GOT[1] being set, identifying a
17413 GNU object. This entry will be used by some runtime
17414 loaders, to store the module pointer. Otherwise this
17415 is an ordinary local entry.
17416 PR 21344: Check for the entry being fully available
17417 before fetching it. */
17418 if (data
17419 && data + ent - pltgot + addr_size <= data_end
17420 && (byte_get (data + ent - pltgot, addr_size)
17421 >> (addr_size * 8 - 1)) != 0)
17422 {
17423 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17424 printf ("\n");
17425 if (ent == (bfd_vma) -1)
17426 goto sgot_print_fail;
17427 }
17428 printf ("\n");
17429 }
17430
f17e9d8a 17431 if (data != NULL && ent < end)
bbdd9a68
MR
17432 {
17433 printf (_(" Local entries:\n"));
17434 printf (" %*s %10s %*s\n",
17435 addr_size * 2, _("Address"), _("Access"),
17436 addr_size * 2, _("Value"));
17437 while (ent < end)
17438 {
17439 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17440 printf ("\n");
17441 if (ent == (bfd_vma) -1)
17442 goto sgot_print_fail;
17443 }
17444 printf ("\n");
17445 }
17446
17447 sgot_print_fail:
9db70fc3 17448 free (data);
bbdd9a68
MR
17449 }
17450 return res;
17451 }
252b5132 17452
978c4450 17453 for (entry = filedata->dynamic_section;
071436c6 17454 /* PR 17531 file: 012-50589-0.004. */
978c4450
AM
17455 (entry < filedata->dynamic_section + filedata->dynamic_nent
17456 && entry->d_tag != DT_NULL);
071436c6 17457 ++entry)
252b5132
RH
17458 switch (entry->d_tag)
17459 {
17460 case DT_MIPS_LIBLIST:
d93f0186 17461 liblist_offset
dda8d76d 17462 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17463 liblistno * sizeof (Elf32_External_Lib));
252b5132
RH
17464 break;
17465 case DT_MIPS_LIBLISTNO:
17466 liblistno = entry->d_un.d_val;
17467 break;
17468 case DT_MIPS_OPTIONS:
dda8d76d 17469 options_offset = offset_from_vma (filedata, entry->d_un.d_val, 0);
252b5132
RH
17470 break;
17471 case DT_MIPS_CONFLICT:
d93f0186 17472 conflicts_offset
dda8d76d 17473 = offset_from_vma (filedata, entry->d_un.d_val,
d93f0186 17474 conflictsno * sizeof (Elf32_External_Conflict));
252b5132
RH
17475 break;
17476 case DT_MIPS_CONFLICTNO:
17477 conflictsno = entry->d_un.d_val;
17478 break;
ccb4c951 17479 case DT_PLTGOT:
861fb55a
DJ
17480 pltgot = entry->d_un.d_ptr;
17481 break;
ccb4c951
RS
17482 case DT_MIPS_LOCAL_GOTNO:
17483 local_gotno = entry->d_un.d_val;
17484 break;
17485 case DT_MIPS_GOTSYM:
17486 gotsym = entry->d_un.d_val;
17487 break;
17488 case DT_MIPS_SYMTABNO:
17489 symtabno = entry->d_un.d_val;
17490 break;
861fb55a
DJ
17491 case DT_MIPS_PLTGOT:
17492 mips_pltgot = entry->d_un.d_ptr;
17493 break;
17494 case DT_PLTREL:
17495 pltrel = entry->d_un.d_val;
17496 break;
17497 case DT_PLTRELSZ:
17498 pltrelsz = entry->d_un.d_val;
17499 break;
17500 case DT_JMPREL:
17501 jmprel = entry->d_un.d_ptr;
17502 break;
252b5132
RH
17503 default:
17504 break;
17505 }
17506
17507 if (liblist_offset != 0 && liblistno != 0 && do_dynamic)
17508 {
2cf0635d 17509 Elf32_External_Lib * elib;
252b5132
RH
17510 size_t cnt;
17511
dda8d76d 17512 elib = (Elf32_External_Lib *) get_data (NULL, filedata, liblist_offset,
95099889
AM
17513 sizeof (Elf32_External_Lib),
17514 liblistno,
17515 _("liblist section data"));
a6e9f9df 17516 if (elib)
252b5132 17517 {
d3a49aa8
AM
17518 printf (ngettext ("\nSection '.liblist' contains %lu entry:\n",
17519 "\nSection '.liblist' contains %lu entries:\n",
17520 (unsigned long) liblistno),
a6e9f9df 17521 (unsigned long) liblistno);
2b692964 17522 fputs (_(" Library Time Stamp Checksum Version Flags\n"),
a6e9f9df
AM
17523 stdout);
17524
17525 for (cnt = 0; cnt < liblistno; ++cnt)
252b5132 17526 {
a6e9f9df 17527 Elf32_Lib liblist;
91d6fa6a 17528 time_t atime;
d5b07ef4 17529 char timebuf[128];
2cf0635d 17530 struct tm * tmp;
a6e9f9df
AM
17531
17532 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 17533 atime = BYTE_GET (elib[cnt].l_time_stamp);
a6e9f9df
AM
17534 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
17535 liblist.l_version = BYTE_GET (elib[cnt].l_version);
17536 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
17537
91d6fa6a 17538 tmp = gmtime (&atime);
e9e44622
JJ
17539 snprintf (timebuf, sizeof (timebuf),
17540 "%04u-%02u-%02uT%02u:%02u:%02u",
17541 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
17542 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
a6e9f9df 17543
31104126 17544 printf ("%3lu: ", (unsigned long) cnt);
978c4450
AM
17545 if (VALID_DYNAMIC_NAME (filedata, liblist.l_name))
17546 print_symbol (20, GET_DYNAMIC_NAME (filedata, liblist.l_name));
d79b3d50 17547 else
2b692964 17548 printf (_("<corrupt: %9ld>"), liblist.l_name);
31104126
NC
17549 printf (" %s %#10lx %-7ld", timebuf, liblist.l_checksum,
17550 liblist.l_version);
a6e9f9df
AM
17551
17552 if (liblist.l_flags == 0)
2b692964 17553 puts (_(" NONE"));
a6e9f9df
AM
17554 else
17555 {
17556 static const struct
252b5132 17557 {
2cf0635d 17558 const char * name;
a6e9f9df 17559 int bit;
252b5132 17560 }
a6e9f9df
AM
17561 l_flags_vals[] =
17562 {
17563 { " EXACT_MATCH", LL_EXACT_MATCH },
17564 { " IGNORE_INT_VER", LL_IGNORE_INT_VER },
17565 { " REQUIRE_MINOR", LL_REQUIRE_MINOR },
17566 { " EXPORTS", LL_EXPORTS },
17567 { " DELAY_LOAD", LL_DELAY_LOAD },
17568 { " DELTA", LL_DELTA }
17569 };
17570 int flags = liblist.l_flags;
17571 size_t fcnt;
17572
60bca95a 17573 for (fcnt = 0; fcnt < ARRAY_SIZE (l_flags_vals); ++fcnt)
a6e9f9df
AM
17574 if ((flags & l_flags_vals[fcnt].bit) != 0)
17575 {
17576 fputs (l_flags_vals[fcnt].name, stdout);
17577 flags ^= l_flags_vals[fcnt].bit;
17578 }
17579 if (flags != 0)
17580 printf (" %#x", (unsigned int) flags);
252b5132 17581
a6e9f9df
AM
17582 puts ("");
17583 }
252b5132 17584 }
252b5132 17585
a6e9f9df
AM
17586 free (elib);
17587 }
32ec8896
NC
17588 else
17589 res = FALSE;
252b5132
RH
17590 }
17591
17592 if (options_offset != 0)
17593 {
2cf0635d 17594 Elf_External_Options * eopt;
252b5132
RH
17595 size_t offset;
17596 int cnt;
dda8d76d 17597 sect = filedata->section_headers;
252b5132
RH
17598
17599 /* Find the section header so that we get the size. */
dda8d76d 17600 sect = find_section_by_type (filedata, SHT_MIPS_OPTIONS);
948f632f 17601 /* PR 17533 file: 012-277276-0.004. */
071436c6
NC
17602 if (sect == NULL)
17603 {
17604 error (_("No MIPS_OPTIONS header found\n"));
32ec8896 17605 return FALSE;
071436c6 17606 }
7fc0c668
NC
17607 /* PR 24243 */
17608 if (sect->sh_size < sizeof (* eopt))
17609 {
17610 error (_("The MIPS options section is too small.\n"));
17611 return FALSE;
17612 }
252b5132 17613
dda8d76d 17614 eopt = (Elf_External_Options *) get_data (NULL, filedata, options_offset, 1,
3f5e193b 17615 sect->sh_size, _("options"));
a6e9f9df 17616 if (eopt)
252b5132 17617 {
fd17d1e6 17618 Elf_Internal_Options option;
76da6bbe 17619
a6e9f9df 17620 offset = cnt = 0;
82b1b41b 17621 while (offset <= sect->sh_size - sizeof (* eopt))
a6e9f9df 17622 {
2cf0635d 17623 Elf_External_Options * eoption;
fd17d1e6 17624 unsigned int optsize;
252b5132 17625
a6e9f9df 17626 eoption = (Elf_External_Options *) ((char *) eopt + offset);
252b5132 17627
fd17d1e6 17628 optsize = BYTE_GET (eoption->size);
76da6bbe 17629
82b1b41b 17630 /* PR 17531: file: ffa0fa3b. */
fd17d1e6
AM
17631 if (optsize < sizeof (* eopt)
17632 || optsize > sect->sh_size - offset)
82b1b41b 17633 {
645f43a8 17634 error (_("Invalid size (%u) for MIPS option\n"),
fd17d1e6 17635 optsize);
645f43a8 17636 free (eopt);
32ec8896 17637 return FALSE;
82b1b41b 17638 }
fd17d1e6 17639 offset += optsize;
a6e9f9df
AM
17640 ++cnt;
17641 }
252b5132 17642
d3a49aa8
AM
17643 printf (ngettext ("\nSection '%s' contains %d entry:\n",
17644 "\nSection '%s' contains %d entries:\n",
17645 cnt),
dda8d76d 17646 printable_section_name (filedata, sect), cnt);
76da6bbe 17647
82b1b41b 17648 offset = 0;
a6e9f9df 17649 while (cnt-- > 0)
252b5132 17650 {
a6e9f9df 17651 size_t len;
fd17d1e6
AM
17652 Elf_External_Options * eoption;
17653
17654 eoption = (Elf_External_Options *) ((char *) eopt + offset);
17655
17656 option.kind = BYTE_GET (eoption->kind);
17657 option.size = BYTE_GET (eoption->size);
17658 option.section = BYTE_GET (eoption->section);
17659 option.info = BYTE_GET (eoption->info);
a6e9f9df 17660
fd17d1e6 17661 switch (option.kind)
252b5132 17662 {
a6e9f9df
AM
17663 case ODK_NULL:
17664 /* This shouldn't happen. */
d0c4e780 17665 printf (" NULL %" PRId16 " %" PRIx32,
fd17d1e6 17666 option.section, option.info);
a6e9f9df 17667 break;
2e6be59c 17668
a6e9f9df
AM
17669 case ODK_REGINFO:
17670 printf (" REGINFO ");
dda8d76d 17671 if (filedata->file_header.e_machine == EM_MIPS)
a6e9f9df 17672 {
2cf0635d 17673 Elf32_External_RegInfo * ereg;
b34976b6 17674 Elf32_RegInfo reginfo;
a6e9f9df 17675
2e6be59c 17676 /* 32bit form. */
fd17d1e6
AM
17677 if (option.size < (sizeof (Elf_External_Options)
17678 + sizeof (Elf32_External_RegInfo)))
2e6be59c
NC
17679 {
17680 printf (_("<corrupt>\n"));
17681 error (_("Truncated MIPS REGINFO option\n"));
17682 cnt = 0;
17683 break;
17684 }
17685
fd17d1e6 17686 ereg = (Elf32_External_RegInfo *) (eoption + 1);
2e6be59c 17687
a6e9f9df
AM
17688 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17689 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17690 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17691 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17692 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
17693 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
17694
d0c4e780
AM
17695 printf ("GPR %08" PRIx32 " GP 0x%" PRIx32 "\n",
17696 reginfo.ri_gprmask, reginfo.ri_gp_value);
17697 printf (" "
17698 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17699 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17700 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17701 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17702 }
17703 else
17704 {
17705 /* 64 bit form. */
2cf0635d 17706 Elf64_External_RegInfo * ereg;
a6e9f9df
AM
17707 Elf64_Internal_RegInfo reginfo;
17708
fd17d1e6
AM
17709 if (option.size < (sizeof (Elf_External_Options)
17710 + sizeof (Elf64_External_RegInfo)))
2e6be59c
NC
17711 {
17712 printf (_("<corrupt>\n"));
17713 error (_("Truncated MIPS REGINFO option\n"));
17714 cnt = 0;
17715 break;
17716 }
17717
fd17d1e6 17718 ereg = (Elf64_External_RegInfo *) (eoption + 1);
a6e9f9df
AM
17719 reginfo.ri_gprmask = BYTE_GET (ereg->ri_gprmask);
17720 reginfo.ri_cprmask[0] = BYTE_GET (ereg->ri_cprmask[0]);
17721 reginfo.ri_cprmask[1] = BYTE_GET (ereg->ri_cprmask[1]);
17722 reginfo.ri_cprmask[2] = BYTE_GET (ereg->ri_cprmask[2]);
17723 reginfo.ri_cprmask[3] = BYTE_GET (ereg->ri_cprmask[3]);
66543521 17724 reginfo.ri_gp_value = BYTE_GET (ereg->ri_gp_value);
a6e9f9df 17725
d0c4e780
AM
17726 printf ("GPR %08" PRIx32 " GP 0x%" PRIx64 "\n",
17727 reginfo.ri_gprmask, reginfo.ri_gp_value);
17728 printf (" "
17729 " CPR0 %08" PRIx32 " CPR1 %08" PRIx32
17730 " CPR2 %08" PRIx32 " CPR3 %08" PRIx32 "\n",
a6e9f9df
AM
17731 reginfo.ri_cprmask[0], reginfo.ri_cprmask[1],
17732 reginfo.ri_cprmask[2], reginfo.ri_cprmask[3]);
17733 }
fd17d1e6 17734 offset += option.size;
a6e9f9df 17735 continue;
2e6be59c 17736
a6e9f9df
AM
17737 case ODK_EXCEPTIONS:
17738 fputs (" EXCEPTIONS fpe_min(", stdout);
fd17d1e6 17739 process_mips_fpe_exception (option.info & OEX_FPU_MIN);
a6e9f9df 17740 fputs (") fpe_max(", stdout);
fd17d1e6 17741 process_mips_fpe_exception ((option.info & OEX_FPU_MAX) >> 8);
a6e9f9df
AM
17742 fputs (")", stdout);
17743
fd17d1e6 17744 if (option.info & OEX_PAGE0)
a6e9f9df 17745 fputs (" PAGE0", stdout);
fd17d1e6 17746 if (option.info & OEX_SMM)
a6e9f9df 17747 fputs (" SMM", stdout);
fd17d1e6 17748 if (option.info & OEX_FPDBUG)
a6e9f9df 17749 fputs (" FPDBUG", stdout);
fd17d1e6 17750 if (option.info & OEX_DISMISS)
a6e9f9df
AM
17751 fputs (" DISMISS", stdout);
17752 break;
2e6be59c 17753
a6e9f9df
AM
17754 case ODK_PAD:
17755 fputs (" PAD ", stdout);
fd17d1e6 17756 if (option.info & OPAD_PREFIX)
a6e9f9df 17757 fputs (" PREFIX", stdout);
fd17d1e6 17758 if (option.info & OPAD_POSTFIX)
a6e9f9df 17759 fputs (" POSTFIX", stdout);
fd17d1e6 17760 if (option.info & OPAD_SYMBOL)
a6e9f9df
AM
17761 fputs (" SYMBOL", stdout);
17762 break;
2e6be59c 17763
a6e9f9df
AM
17764 case ODK_HWPATCH:
17765 fputs (" HWPATCH ", stdout);
fd17d1e6 17766 if (option.info & OHW_R4KEOP)
a6e9f9df 17767 fputs (" R4KEOP", stdout);
fd17d1e6 17768 if (option.info & OHW_R8KPFETCH)
a6e9f9df 17769 fputs (" R8KPFETCH", stdout);
fd17d1e6 17770 if (option.info & OHW_R5KEOP)
a6e9f9df 17771 fputs (" R5KEOP", stdout);
fd17d1e6 17772 if (option.info & OHW_R5KCVTL)
a6e9f9df
AM
17773 fputs (" R5KCVTL", stdout);
17774 break;
2e6be59c 17775
a6e9f9df
AM
17776 case ODK_FILL:
17777 fputs (" FILL ", stdout);
17778 /* XXX Print content of info word? */
17779 break;
2e6be59c 17780
a6e9f9df
AM
17781 case ODK_TAGS:
17782 fputs (" TAGS ", stdout);
17783 /* XXX Print content of info word? */
17784 break;
2e6be59c 17785
a6e9f9df
AM
17786 case ODK_HWAND:
17787 fputs (" HWAND ", stdout);
fd17d1e6 17788 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17789 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17790 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17791 fputs (" R4KEOP_CLEAN", stdout);
17792 break;
2e6be59c 17793
a6e9f9df
AM
17794 case ODK_HWOR:
17795 fputs (" HWOR ", stdout);
fd17d1e6 17796 if (option.info & OHWA0_R4KEOP_CHECKED)
a6e9f9df 17797 fputs (" R4KEOP_CHECKED", stdout);
fd17d1e6 17798 if (option.info & OHWA0_R4KEOP_CLEAN)
a6e9f9df
AM
17799 fputs (" R4KEOP_CLEAN", stdout);
17800 break;
2e6be59c 17801
a6e9f9df 17802 case ODK_GP_GROUP:
d0c4e780 17803 printf (" GP_GROUP %#06x self-contained %#06x",
fd17d1e6
AM
17804 option.info & OGP_GROUP,
17805 (option.info & OGP_SELF) >> 16);
a6e9f9df 17806 break;
2e6be59c 17807
a6e9f9df 17808 case ODK_IDENT:
d0c4e780 17809 printf (" IDENT %#06x self-contained %#06x",
fd17d1e6
AM
17810 option.info & OGP_GROUP,
17811 (option.info & OGP_SELF) >> 16);
a6e9f9df 17812 break;
2e6be59c 17813
a6e9f9df
AM
17814 default:
17815 /* This shouldn't happen. */
d0c4e780 17816 printf (" %3d ??? %" PRId16 " %" PRIx32,
fd17d1e6 17817 option.kind, option.section, option.info);
a6e9f9df 17818 break;
252b5132 17819 }
a6e9f9df 17820
2cf0635d 17821 len = sizeof (* eopt);
fd17d1e6 17822 while (len < option.size)
82b1b41b 17823 {
fd17d1e6 17824 unsigned char datum = *((unsigned char *) eoption + len);
a6e9f9df 17825
82b1b41b
NC
17826 if (ISPRINT (datum))
17827 printf ("%c", datum);
17828 else
17829 printf ("\\%03o", datum);
17830 len ++;
17831 }
a6e9f9df 17832 fputs ("\n", stdout);
82b1b41b 17833
fd17d1e6 17834 offset += option.size;
252b5132 17835 }
a6e9f9df 17836 free (eopt);
252b5132 17837 }
32ec8896
NC
17838 else
17839 res = FALSE;
252b5132
RH
17840 }
17841
17842 if (conflicts_offset != 0 && conflictsno != 0)
17843 {
2cf0635d 17844 Elf32_Conflict * iconf;
252b5132
RH
17845 size_t cnt;
17846
978c4450 17847 if (filedata->dynamic_symbols == NULL)
252b5132 17848 {
591a748a 17849 error (_("conflict list found without a dynamic symbol table\n"));
32ec8896 17850 return FALSE;
252b5132
RH
17851 }
17852
7296a62a
NC
17853 /* PR 21345 - print a slightly more helpful error message
17854 if we are sure that the cmalloc will fail. */
645f43a8 17855 if (conflictsno > filedata->file_size / sizeof (* iconf))
7296a62a
NC
17856 {
17857 error (_("Overlarge number of conflicts detected: %lx\n"),
17858 (long) conflictsno);
17859 return FALSE;
17860 }
17861
3f5e193b 17862 iconf = (Elf32_Conflict *) cmalloc (conflictsno, sizeof (* iconf));
252b5132
RH
17863 if (iconf == NULL)
17864 {
8b73c356 17865 error (_("Out of memory allocating space for dynamic conflicts\n"));
32ec8896 17866 return FALSE;
252b5132
RH
17867 }
17868
9ea033b2 17869 if (is_32bit_elf)
252b5132 17870 {
2cf0635d 17871 Elf32_External_Conflict * econf32;
a6e9f9df 17872
3f5e193b 17873 econf32 = (Elf32_External_Conflict *)
95099889
AM
17874 get_data (NULL, filedata, conflicts_offset,
17875 sizeof (*econf32), conflictsno, _("conflict"));
a6e9f9df 17876 if (!econf32)
5a814d6d
AM
17877 {
17878 free (iconf);
17879 return FALSE;
17880 }
252b5132
RH
17881
17882 for (cnt = 0; cnt < conflictsno; ++cnt)
17883 iconf[cnt] = BYTE_GET (econf32[cnt]);
a6e9f9df
AM
17884
17885 free (econf32);
252b5132
RH
17886 }
17887 else
17888 {
2cf0635d 17889 Elf64_External_Conflict * econf64;
a6e9f9df 17890
3f5e193b 17891 econf64 = (Elf64_External_Conflict *)
95099889
AM
17892 get_data (NULL, filedata, conflicts_offset,
17893 sizeof (*econf64), conflictsno, _("conflict"));
a6e9f9df 17894 if (!econf64)
5a814d6d
AM
17895 {
17896 free (iconf);
17897 return FALSE;
17898 }
252b5132
RH
17899
17900 for (cnt = 0; cnt < conflictsno; ++cnt)
17901 iconf[cnt] = BYTE_GET (econf64[cnt]);
a6e9f9df
AM
17902
17903 free (econf64);
252b5132
RH
17904 }
17905
d3a49aa8
AM
17906 printf (ngettext ("\nSection '.conflict' contains %lu entry:\n",
17907 "\nSection '.conflict' contains %lu entries:\n",
17908 (unsigned long) conflictsno),
c7e7ca54 17909 (unsigned long) conflictsno);
252b5132
RH
17910 puts (_(" Num: Index Value Name"));
17911
17912 for (cnt = 0; cnt < conflictsno; ++cnt)
17913 {
b34976b6 17914 printf ("%5lu: %8lu ", (unsigned long) cnt, iconf[cnt]);
e0a31db1 17915
978c4450 17916 if (iconf[cnt] >= filedata->num_dynamic_syms)
e0a31db1 17917 printf (_("<corrupt symbol index>"));
d79b3d50 17918 else
e0a31db1
NC
17919 {
17920 Elf_Internal_Sym * psym;
17921
978c4450 17922 psym = & filedata->dynamic_symbols[iconf[cnt]];
e0a31db1
NC
17923 print_vma (psym->st_value, FULL_HEX);
17924 putchar (' ');
978c4450
AM
17925 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
17926 print_symbol (25, GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
17927 else
17928 printf (_("<corrupt: %14ld>"), psym->st_name);
17929 }
31104126 17930 putchar ('\n');
252b5132
RH
17931 }
17932
252b5132
RH
17933 free (iconf);
17934 }
17935
ccb4c951
RS
17936 if (pltgot != 0 && local_gotno != 0)
17937 {
91d6fa6a 17938 bfd_vma ent, local_end, global_end;
bbeee7ea 17939 size_t i, offset;
2cf0635d 17940 unsigned char * data;
82b1b41b 17941 unsigned char * data_end;
bbeee7ea 17942 int addr_size;
ccb4c951 17943
91d6fa6a 17944 ent = pltgot;
ccb4c951
RS
17945 addr_size = (is_32bit_elf ? 4 : 8);
17946 local_end = pltgot + local_gotno * addr_size;
ccb4c951 17947
74e1a04b
NC
17948 /* PR binutils/17533 file: 012-111227-0.004 */
17949 if (symtabno < gotsym)
17950 {
17951 error (_("The GOT symbol offset (%lu) is greater than the symbol table size (%lu)\n"),
82b1b41b 17952 (unsigned long) gotsym, (unsigned long) symtabno);
32ec8896 17953 return FALSE;
74e1a04b 17954 }
82b1b41b 17955
74e1a04b 17956 global_end = local_end + (symtabno - gotsym) * addr_size;
82b1b41b
NC
17957 /* PR 17531: file: 54c91a34. */
17958 if (global_end < local_end)
17959 {
17960 error (_("Too many GOT symbols: %lu\n"), (unsigned long) symtabno);
32ec8896 17961 return FALSE;
82b1b41b 17962 }
948f632f 17963
dda8d76d
NC
17964 offset = offset_from_vma (filedata, pltgot, global_end - pltgot);
17965 data = (unsigned char *) get_data (NULL, filedata, offset,
9cf03b7e
NC
17966 global_end - pltgot, 1,
17967 _("Global Offset Table data"));
919383ac 17968 /* PR 12855: Null data is handled gracefully throughout. */
82b1b41b 17969 data_end = data + (global_end - pltgot);
59245841 17970
ccb4c951
RS
17971 printf (_("\nPrimary GOT:\n"));
17972 printf (_(" Canonical gp value: "));
17973 print_vma (pltgot + 0x7ff0, LONG_HEX);
17974 printf ("\n\n");
17975
17976 printf (_(" Reserved entries:\n"));
17977 printf (_(" %*s %10s %*s Purpose\n"),
2b692964
NC
17978 addr_size * 2, _("Address"), _("Access"),
17979 addr_size * 2, _("Initial"));
82b1b41b 17980 ent = print_mips_got_entry (data, pltgot, ent, data_end);
2b692964 17981 printf (_(" Lazy resolver\n"));
82b1b41b
NC
17982 if (ent == (bfd_vma) -1)
17983 goto got_print_fail;
75ec1fdb 17984
c4ab9505
MR
17985 /* Check for the MSB of GOT[1] being set, denoting a GNU object.
17986 This entry will be used by some runtime loaders, to store the
17987 module pointer. Otherwise this is an ordinary local entry.
17988 PR 21344: Check for the entry being fully available before
17989 fetching it. */
17990 if (data
17991 && data + ent - pltgot + addr_size <= data_end
17992 && (byte_get (data + ent - pltgot, addr_size)
17993 >> (addr_size * 8 - 1)) != 0)
17994 {
17995 ent = print_mips_got_entry (data, pltgot, ent, data_end);
17996 printf (_(" Module pointer (GNU extension)\n"));
17997 if (ent == (bfd_vma) -1)
17998 goto got_print_fail;
ccb4c951
RS
17999 }
18000 printf ("\n");
18001
f17e9d8a 18002 if (data != NULL && ent < local_end)
ccb4c951
RS
18003 {
18004 printf (_(" Local entries:\n"));
cc5914eb 18005 printf (" %*s %10s %*s\n",
2b692964
NC
18006 addr_size * 2, _("Address"), _("Access"),
18007 addr_size * 2, _("Initial"));
91d6fa6a 18008 while (ent < local_end)
ccb4c951 18009 {
82b1b41b 18010 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18011 printf ("\n");
82b1b41b
NC
18012 if (ent == (bfd_vma) -1)
18013 goto got_print_fail;
ccb4c951
RS
18014 }
18015 printf ("\n");
18016 }
18017
f17e9d8a 18018 if (data != NULL && gotsym < symtabno)
ccb4c951
RS
18019 {
18020 int sym_width;
18021
18022 printf (_(" Global entries:\n"));
cc5914eb 18023 printf (" %*s %10s %*s %*s %-7s %3s %s\n",
9cf03b7e
NC
18024 addr_size * 2, _("Address"),
18025 _("Access"),
2b692964 18026 addr_size * 2, _("Initial"),
9cf03b7e
NC
18027 addr_size * 2, _("Sym.Val."),
18028 _("Type"),
18029 /* Note for translators: "Ndx" = abbreviated form of "Index". */
18030 _("Ndx"), _("Name"));
0b4362b0 18031
ccb4c951 18032 sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
e0a31db1 18033
ccb4c951
RS
18034 for (i = gotsym; i < symtabno; i++)
18035 {
82b1b41b 18036 ent = print_mips_got_entry (data, pltgot, ent, data_end);
ccb4c951 18037 printf (" ");
e0a31db1 18038
978c4450 18039 if (filedata->dynamic_symbols == NULL)
e0a31db1 18040 printf (_("<no dynamic symbols>"));
978c4450 18041 else if (i < filedata->num_dynamic_syms)
e0a31db1 18042 {
978c4450 18043 Elf_Internal_Sym * psym = filedata->dynamic_symbols + i;
e0a31db1
NC
18044
18045 print_vma (psym->st_value, LONG_HEX);
18046 printf (" %-7s %3s ",
dda8d76d
NC
18047 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18048 get_symbol_index_type (filedata, psym->st_shndx));
e0a31db1 18049
978c4450
AM
18050 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18051 print_symbol (sym_width,
18052 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18053 else
18054 printf (_("<corrupt: %14ld>"), psym->st_name);
18055 }
ccb4c951 18056 else
7fc5ac57
JBG
18057 printf (_("<symbol index %lu exceeds number of dynamic symbols>"),
18058 (unsigned long) i);
e0a31db1 18059
ccb4c951 18060 printf ("\n");
82b1b41b
NC
18061 if (ent == (bfd_vma) -1)
18062 break;
ccb4c951
RS
18063 }
18064 printf ("\n");
18065 }
18066
82b1b41b 18067 got_print_fail:
9db70fc3 18068 free (data);
ccb4c951
RS
18069 }
18070
861fb55a
DJ
18071 if (mips_pltgot != 0 && jmprel != 0 && pltrel != 0 && pltrelsz != 0)
18072 {
91d6fa6a 18073 bfd_vma ent, end;
861fb55a
DJ
18074 size_t offset, rel_offset;
18075 unsigned long count, i;
2cf0635d 18076 unsigned char * data;
861fb55a 18077 int addr_size, sym_width;
2cf0635d 18078 Elf_Internal_Rela * rels;
861fb55a 18079
dda8d76d 18080 rel_offset = offset_from_vma (filedata, jmprel, pltrelsz);
861fb55a
DJ
18081 if (pltrel == DT_RELA)
18082 {
dda8d76d 18083 if (!slurp_rela_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 18084 return FALSE;
861fb55a
DJ
18085 }
18086 else
18087 {
dda8d76d 18088 if (!slurp_rel_relocs (filedata, rel_offset, pltrelsz, &rels, &count))
32ec8896 18089 return FALSE;
861fb55a
DJ
18090 }
18091
91d6fa6a 18092 ent = mips_pltgot;
861fb55a
DJ
18093 addr_size = (is_32bit_elf ? 4 : 8);
18094 end = mips_pltgot + (2 + count) * addr_size;
18095
dda8d76d
NC
18096 offset = offset_from_vma (filedata, mips_pltgot, end - mips_pltgot);
18097 data = (unsigned char *) get_data (NULL, filedata, offset, end - mips_pltgot,
9cf03b7e 18098 1, _("Procedure Linkage Table data"));
59245841 18099 if (data == NULL)
288f0ba2
AM
18100 {
18101 free (rels);
18102 return FALSE;
18103 }
59245841 18104
9cf03b7e 18105 printf ("\nPLT GOT:\n\n");
861fb55a
DJ
18106 printf (_(" Reserved entries:\n"));
18107 printf (_(" %*s %*s Purpose\n"),
2b692964 18108 addr_size * 2, _("Address"), addr_size * 2, _("Initial"));
91d6fa6a 18109 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18110 printf (_(" PLT lazy resolver\n"));
91d6fa6a 18111 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
2b692964 18112 printf (_(" Module pointer\n"));
861fb55a
DJ
18113 printf ("\n");
18114
18115 printf (_(" Entries:\n"));
cc5914eb 18116 printf (" %*s %*s %*s %-7s %3s %s\n",
2b692964
NC
18117 addr_size * 2, _("Address"),
18118 addr_size * 2, _("Initial"),
18119 addr_size * 2, _("Sym.Val."), _("Type"), _("Ndx"), _("Name"));
861fb55a
DJ
18120 sym_width = (is_32bit_elf ? 80 : 160) - 17 - addr_size * 6 - 1;
18121 for (i = 0; i < count; i++)
18122 {
df97ab2a 18123 unsigned long idx = get_reloc_symindex (rels[i].r_info);
861fb55a 18124
91d6fa6a 18125 ent = print_mips_pltgot_entry (data, mips_pltgot, ent);
861fb55a 18126 printf (" ");
e0a31db1 18127
978c4450 18128 if (idx >= filedata->num_dynamic_syms)
df97ab2a 18129 printf (_("<corrupt symbol index: %lu>"), idx);
861fb55a 18130 else
e0a31db1 18131 {
978c4450 18132 Elf_Internal_Sym * psym = filedata->dynamic_symbols + idx;
e0a31db1
NC
18133
18134 print_vma (psym->st_value, LONG_HEX);
18135 printf (" %-7s %3s ",
dda8d76d
NC
18136 get_symbol_type (filedata, ELF_ST_TYPE (psym->st_info)),
18137 get_symbol_index_type (filedata, psym->st_shndx));
978c4450
AM
18138 if (VALID_DYNAMIC_NAME (filedata, psym->st_name))
18139 print_symbol (sym_width,
18140 GET_DYNAMIC_NAME (filedata, psym->st_name));
e0a31db1
NC
18141 else
18142 printf (_("<corrupt: %14ld>"), psym->st_name);
18143 }
861fb55a
DJ
18144 printf ("\n");
18145 }
18146 printf ("\n");
18147
9db70fc3 18148 free (data);
861fb55a
DJ
18149 free (rels);
18150 }
18151
32ec8896 18152 return res;
252b5132
RH
18153}
18154
32ec8896 18155static bfd_boolean
dda8d76d 18156process_nds32_specific (Filedata * filedata)
35c08157
KLC
18157{
18158 Elf_Internal_Shdr *sect = NULL;
18159
dda8d76d 18160 sect = find_section (filedata, ".nds32_e_flags");
9c7b8e9b 18161 if (sect != NULL && sect->sh_size >= 4)
35c08157 18162 {
9c7b8e9b
AM
18163 unsigned char *buf;
18164 unsigned int flag;
35c08157
KLC
18165
18166 printf ("\nNDS32 elf flags section:\n");
9c7b8e9b
AM
18167 buf = get_data (NULL, filedata, sect->sh_offset, 1, 4,
18168 _("NDS32 elf flags section"));
35c08157 18169
9c7b8e9b 18170 if (buf == NULL)
32ec8896
NC
18171 return FALSE;
18172
9c7b8e9b
AM
18173 flag = byte_get (buf, 4);
18174 free (buf);
18175 switch (flag & 0x3)
35c08157
KLC
18176 {
18177 case 0:
18178 printf ("(VEC_SIZE):\tNo entry.\n");
18179 break;
18180 case 1:
18181 printf ("(VEC_SIZE):\t4 bytes\n");
18182 break;
18183 case 2:
18184 printf ("(VEC_SIZE):\t16 bytes\n");
18185 break;
18186 case 3:
18187 printf ("(VEC_SIZE):\treserved\n");
18188 break;
18189 }
18190 }
18191
18192 return TRUE;
18193}
18194
32ec8896 18195static bfd_boolean
dda8d76d 18196process_gnu_liblist (Filedata * filedata)
047b2264 18197{
2cf0635d
NC
18198 Elf_Internal_Shdr * section;
18199 Elf_Internal_Shdr * string_sec;
18200 Elf32_External_Lib * elib;
18201 char * strtab;
c256ffe7 18202 size_t strtab_size;
047b2264 18203 size_t cnt;
d3a49aa8 18204 unsigned long num_liblist;
047b2264 18205 unsigned i;
32ec8896 18206 bfd_boolean res = TRUE;
047b2264
JJ
18207
18208 if (! do_arch)
32ec8896 18209 return TRUE;
047b2264 18210
dda8d76d
NC
18211 for (i = 0, section = filedata->section_headers;
18212 i < filedata->file_header.e_shnum;
b34976b6 18213 i++, section++)
047b2264
JJ
18214 {
18215 switch (section->sh_type)
18216 {
18217 case SHT_GNU_LIBLIST:
dda8d76d 18218 if (section->sh_link >= filedata->file_header.e_shnum)
c256ffe7
JJ
18219 break;
18220
3f5e193b 18221 elib = (Elf32_External_Lib *)
dda8d76d 18222 get_data (NULL, filedata, section->sh_offset, 1, section->sh_size,
9cf03b7e 18223 _("liblist section data"));
047b2264
JJ
18224
18225 if (elib == NULL)
32ec8896
NC
18226 {
18227 res = FALSE;
18228 break;
18229 }
047b2264 18230
dda8d76d
NC
18231 string_sec = filedata->section_headers + section->sh_link;
18232 strtab = (char *) get_data (NULL, filedata, string_sec->sh_offset, 1,
3f5e193b
NC
18233 string_sec->sh_size,
18234 _("liblist string table"));
047b2264
JJ
18235 if (strtab == NULL
18236 || section->sh_entsize != sizeof (Elf32_External_Lib))
18237 {
18238 free (elib);
2842702f 18239 free (strtab);
32ec8896 18240 res = FALSE;
047b2264
JJ
18241 break;
18242 }
59245841 18243 strtab_size = string_sec->sh_size;
047b2264 18244
d3a49aa8
AM
18245 num_liblist = section->sh_size / sizeof (Elf32_External_Lib);
18246 printf (ngettext ("\nLibrary list section '%s' contains %lu entries:\n",
18247 "\nLibrary list section '%s' contains %lu entries:\n",
18248 num_liblist),
dda8d76d 18249 printable_section_name (filedata, section),
d3a49aa8 18250 num_liblist);
047b2264 18251
2b692964 18252 puts (_(" Library Time Stamp Checksum Version Flags"));
047b2264
JJ
18253
18254 for (cnt = 0; cnt < section->sh_size / sizeof (Elf32_External_Lib);
18255 ++cnt)
18256 {
18257 Elf32_Lib liblist;
91d6fa6a 18258 time_t atime;
d5b07ef4 18259 char timebuf[128];
2cf0635d 18260 struct tm * tmp;
047b2264
JJ
18261
18262 liblist.l_name = BYTE_GET (elib[cnt].l_name);
91d6fa6a 18263 atime = BYTE_GET (elib[cnt].l_time_stamp);
047b2264
JJ
18264 liblist.l_checksum = BYTE_GET (elib[cnt].l_checksum);
18265 liblist.l_version = BYTE_GET (elib[cnt].l_version);
18266 liblist.l_flags = BYTE_GET (elib[cnt].l_flags);
18267
91d6fa6a 18268 tmp = gmtime (&atime);
e9e44622
JJ
18269 snprintf (timebuf, sizeof (timebuf),
18270 "%04u-%02u-%02uT%02u:%02u:%02u",
18271 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
18272 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
047b2264
JJ
18273
18274 printf ("%3lu: ", (unsigned long) cnt);
18275 if (do_wide)
c256ffe7 18276 printf ("%-20s", liblist.l_name < strtab_size
2b692964 18277 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264 18278 else
c256ffe7 18279 printf ("%-20.20s", liblist.l_name < strtab_size
2b692964 18280 ? strtab + liblist.l_name : _("<corrupt>"));
047b2264
JJ
18281 printf (" %s %#010lx %-7ld %-7ld\n", timebuf, liblist.l_checksum,
18282 liblist.l_version, liblist.l_flags);
18283 }
18284
18285 free (elib);
2842702f 18286 free (strtab);
047b2264
JJ
18287 }
18288 }
18289
32ec8896 18290 return res;
047b2264
JJ
18291}
18292
9437c45b 18293static const char *
dda8d76d 18294get_note_type (Filedata * filedata, unsigned e_type)
779fe533
NC
18295{
18296 static char buff[64];
103f02d3 18297
dda8d76d 18298 if (filedata->file_header.e_type == ET_CORE)
1ec5cd37
NC
18299 switch (e_type)
18300 {
57346661 18301 case NT_AUXV:
1ec5cd37 18302 return _("NT_AUXV (auxiliary vector)");
57346661 18303 case NT_PRSTATUS:
1ec5cd37 18304 return _("NT_PRSTATUS (prstatus structure)");
57346661 18305 case NT_FPREGSET:
1ec5cd37 18306 return _("NT_FPREGSET (floating point registers)");
57346661 18307 case NT_PRPSINFO:
1ec5cd37 18308 return _("NT_PRPSINFO (prpsinfo structure)");
57346661 18309 case NT_TASKSTRUCT:
1ec5cd37 18310 return _("NT_TASKSTRUCT (task structure)");
57346661 18311 case NT_PRXFPREG:
1ec5cd37 18312 return _("NT_PRXFPREG (user_xfpregs structure)");
e1e95dec
AM
18313 case NT_PPC_VMX:
18314 return _("NT_PPC_VMX (ppc Altivec registers)");
89eeb0bc
LM
18315 case NT_PPC_VSX:
18316 return _("NT_PPC_VSX (ppc VSX registers)");
66c3b5f8
GR
18317 case NT_PPC_TAR:
18318 return _("NT_PPC_TAR (ppc TAR register)");
18319 case NT_PPC_PPR:
18320 return _("NT_PPC_PPR (ppc PPR register)");
18321 case NT_PPC_DSCR:
18322 return _("NT_PPC_DSCR (ppc DSCR register)");
18323 case NT_PPC_EBB:
18324 return _("NT_PPC_EBB (ppc EBB registers)");
18325 case NT_PPC_PMU:
18326 return _("NT_PPC_PMU (ppc PMU registers)");
18327 case NT_PPC_TM_CGPR:
18328 return _("NT_PPC_TM_CGPR (ppc checkpointed GPR registers)");
18329 case NT_PPC_TM_CFPR:
18330 return _("NT_PPC_TM_CFPR (ppc checkpointed floating point registers)");
18331 case NT_PPC_TM_CVMX:
18332 return _("NT_PPC_TM_CVMX (ppc checkpointed Altivec registers)");
18333 case NT_PPC_TM_CVSX:
3fd21718 18334 return _("NT_PPC_TM_CVSX (ppc checkpointed VSX registers)");
66c3b5f8
GR
18335 case NT_PPC_TM_SPR:
18336 return _("NT_PPC_TM_SPR (ppc TM special purpose registers)");
18337 case NT_PPC_TM_CTAR:
18338 return _("NT_PPC_TM_CTAR (ppc checkpointed TAR register)");
18339 case NT_PPC_TM_CPPR:
18340 return _("NT_PPC_TM_CPPR (ppc checkpointed PPR register)");
18341 case NT_PPC_TM_CDSCR:
18342 return _("NT_PPC_TM_CDSCR (ppc checkpointed DSCR register)");
ff826ef3
TT
18343 case NT_386_TLS:
18344 return _("NT_386_TLS (x86 TLS information)");
18345 case NT_386_IOPERM:
18346 return _("NT_386_IOPERM (x86 I/O permissions)");
4339cae0
L
18347 case NT_X86_XSTATE:
18348 return _("NT_X86_XSTATE (x86 XSAVE extended state)");
8d58ed37
L
18349 case NT_X86_CET:
18350 return _("NT_X86_CET (x86 CET state)");
0675e188
UW
18351 case NT_S390_HIGH_GPRS:
18352 return _("NT_S390_HIGH_GPRS (s390 upper register halves)");
d7eeb400
MS
18353 case NT_S390_TIMER:
18354 return _("NT_S390_TIMER (s390 timer register)");
18355 case NT_S390_TODCMP:
18356 return _("NT_S390_TODCMP (s390 TOD comparator register)");
18357 case NT_S390_TODPREG:
18358 return _("NT_S390_TODPREG (s390 TOD programmable register)");
18359 case NT_S390_CTRS:
18360 return _("NT_S390_CTRS (s390 control registers)");
18361 case NT_S390_PREFIX:
18362 return _("NT_S390_PREFIX (s390 prefix register)");
a367d729
AK
18363 case NT_S390_LAST_BREAK:
18364 return _("NT_S390_LAST_BREAK (s390 last breaking event address)");
18365 case NT_S390_SYSTEM_CALL:
18366 return _("NT_S390_SYSTEM_CALL (s390 system call restart data)");
abb3f6cc
NC
18367 case NT_S390_TDB:
18368 return _("NT_S390_TDB (s390 transaction diagnostic block)");
4ef9f41a
AA
18369 case NT_S390_VXRS_LOW:
18370 return _("NT_S390_VXRS_LOW (s390 vector registers 0-15 upper half)");
18371 case NT_S390_VXRS_HIGH:
18372 return _("NT_S390_VXRS_HIGH (s390 vector registers 16-31)");
88ab90e8
AA
18373 case NT_S390_GS_CB:
18374 return _("NT_S390_GS_CB (s390 guarded-storage registers)");
18375 case NT_S390_GS_BC:
18376 return _("NT_S390_GS_BC (s390 guarded-storage broadcast control)");
faa9a424
UW
18377 case NT_ARM_VFP:
18378 return _("NT_ARM_VFP (arm VFP registers)");
652451f8
YZ
18379 case NT_ARM_TLS:
18380 return _("NT_ARM_TLS (AArch TLS registers)");
18381 case NT_ARM_HW_BREAK:
18382 return _("NT_ARM_HW_BREAK (AArch hardware breakpoint registers)");
18383 case NT_ARM_HW_WATCH:
18384 return _("NT_ARM_HW_WATCH (AArch hardware watchpoint registers)");
27456742
AK
18385 case NT_ARC_V2:
18386 return _("NT_ARC_V2 (ARC HS accumulator/extra registers)");
57346661 18387 case NT_PSTATUS:
1ec5cd37 18388 return _("NT_PSTATUS (pstatus structure)");
57346661 18389 case NT_FPREGS:
1ec5cd37 18390 return _("NT_FPREGS (floating point registers)");
57346661 18391 case NT_PSINFO:
1ec5cd37 18392 return _("NT_PSINFO (psinfo structure)");
57346661 18393 case NT_LWPSTATUS:
1ec5cd37 18394 return _("NT_LWPSTATUS (lwpstatus_t structure)");
57346661 18395 case NT_LWPSINFO:
1ec5cd37 18396 return _("NT_LWPSINFO (lwpsinfo_t structure)");
57346661 18397 case NT_WIN32PSTATUS:
1ec5cd37 18398 return _("NT_WIN32PSTATUS (win32_pstatus structure)");
9ece1fa9
TT
18399 case NT_SIGINFO:
18400 return _("NT_SIGINFO (siginfo_t data)");
18401 case NT_FILE:
18402 return _("NT_FILE (mapped files)");
1ec5cd37
NC
18403 default:
18404 break;
18405 }
18406 else
18407 switch (e_type)
18408 {
18409 case NT_VERSION:
18410 return _("NT_VERSION (version)");
18411 case NT_ARCH:
18412 return _("NT_ARCH (architecture)");
9ef920e9 18413 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
6f156d7a 18414 return _("OPEN");
9ef920e9 18415 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
6f156d7a 18416 return _("func");
1ec5cd37
NC
18417 default:
18418 break;
18419 }
18420
e9e44622 18421 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
1ec5cd37 18422 return buff;
779fe533
NC
18423}
18424
32ec8896 18425static bfd_boolean
9ece1fa9
TT
18426print_core_note (Elf_Internal_Note *pnote)
18427{
18428 unsigned int addr_size = is_32bit_elf ? 4 : 8;
18429 bfd_vma count, page_size;
18430 unsigned char *descdata, *filenames, *descend;
18431
18432 if (pnote->type != NT_FILE)
04ac15ab
AS
18433 {
18434 if (do_wide)
18435 printf ("\n");
18436 return TRUE;
18437 }
9ece1fa9
TT
18438
18439#ifndef BFD64
18440 if (!is_32bit_elf)
18441 {
18442 printf (_(" Cannot decode 64-bit note in 32-bit build\n"));
18443 /* Still "successful". */
32ec8896 18444 return TRUE;
9ece1fa9
TT
18445 }
18446#endif
18447
18448 if (pnote->descsz < 2 * addr_size)
18449 {
32ec8896
NC
18450 error (_(" Malformed note - too short for header\n"));
18451 return FALSE;
9ece1fa9
TT
18452 }
18453
18454 descdata = (unsigned char *) pnote->descdata;
18455 descend = descdata + pnote->descsz;
18456
18457 if (descdata[pnote->descsz - 1] != '\0')
18458 {
32ec8896
NC
18459 error (_(" Malformed note - does not end with \\0\n"));
18460 return FALSE;
9ece1fa9
TT
18461 }
18462
18463 count = byte_get (descdata, addr_size);
18464 descdata += addr_size;
18465
18466 page_size = byte_get (descdata, addr_size);
18467 descdata += addr_size;
18468
5396a86e
AM
18469 if (count > ((bfd_vma) -1 - 2 * addr_size) / (3 * addr_size)
18470 || pnote->descsz < 2 * addr_size + count * 3 * addr_size)
9ece1fa9 18471 {
32ec8896
NC
18472 error (_(" Malformed note - too short for supplied file count\n"));
18473 return FALSE;
9ece1fa9
TT
18474 }
18475
18476 printf (_(" Page size: "));
18477 print_vma (page_size, DEC);
18478 printf ("\n");
18479
18480 printf (_(" %*s%*s%*s\n"),
18481 (int) (2 + 2 * addr_size), _("Start"),
18482 (int) (4 + 2 * addr_size), _("End"),
18483 (int) (4 + 2 * addr_size), _("Page Offset"));
18484 filenames = descdata + count * 3 * addr_size;
595712bb 18485 while (count-- > 0)
9ece1fa9
TT
18486 {
18487 bfd_vma start, end, file_ofs;
18488
18489 if (filenames == descend)
18490 {
32ec8896
NC
18491 error (_(" Malformed note - filenames end too early\n"));
18492 return FALSE;
9ece1fa9
TT
18493 }
18494
18495 start = byte_get (descdata, addr_size);
18496 descdata += addr_size;
18497 end = byte_get (descdata, addr_size);
18498 descdata += addr_size;
18499 file_ofs = byte_get (descdata, addr_size);
18500 descdata += addr_size;
18501
18502 printf (" ");
18503 print_vma (start, FULL_HEX);
18504 printf (" ");
18505 print_vma (end, FULL_HEX);
18506 printf (" ");
18507 print_vma (file_ofs, FULL_HEX);
18508 printf ("\n %s\n", filenames);
18509
18510 filenames += 1 + strlen ((char *) filenames);
18511 }
18512
32ec8896 18513 return TRUE;
9ece1fa9
TT
18514}
18515
1118d252
RM
18516static const char *
18517get_gnu_elf_note_type (unsigned e_type)
18518{
1449284b 18519 /* NB/ Keep this switch statement in sync with print_gnu_note (). */
1118d252
RM
18520 switch (e_type)
18521 {
18522 case NT_GNU_ABI_TAG:
18523 return _("NT_GNU_ABI_TAG (ABI version tag)");
18524 case NT_GNU_HWCAP:
18525 return _("NT_GNU_HWCAP (DSO-supplied software HWCAP info)");
18526 case NT_GNU_BUILD_ID:
18527 return _("NT_GNU_BUILD_ID (unique build ID bitstring)");
0297aed6
DM
18528 case NT_GNU_GOLD_VERSION:
18529 return _("NT_GNU_GOLD_VERSION (gold version)");
9ef920e9
NC
18530 case NT_GNU_PROPERTY_TYPE_0:
18531 return _("NT_GNU_PROPERTY_TYPE_0");
18532 case NT_GNU_BUILD_ATTRIBUTE_OPEN:
18533 return _("NT_GNU_BUILD_ATTRIBUTE_OPEN");
18534 case NT_GNU_BUILD_ATTRIBUTE_FUNC:
18535 return _("NT_GNU_BUILD_ATTRIBUTE_FUNC");
1118d252 18536 default:
1449284b
NC
18537 {
18538 static char buff[64];
1118d252 18539
1449284b
NC
18540 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
18541 return buff;
18542 }
18543 }
1118d252
RM
18544}
18545
a9eafb08
L
18546static void
18547decode_x86_compat_isa (unsigned int bitmask)
18548{
18549 while (bitmask)
18550 {
18551 unsigned int bit = bitmask & (- bitmask);
18552
18553 bitmask &= ~ bit;
18554 switch (bit)
18555 {
18556 case GNU_PROPERTY_X86_COMPAT_ISA_1_486:
18557 printf ("i486");
18558 break;
18559 case GNU_PROPERTY_X86_COMPAT_ISA_1_586:
18560 printf ("586");
18561 break;
18562 case GNU_PROPERTY_X86_COMPAT_ISA_1_686:
18563 printf ("686");
18564 break;
18565 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE:
18566 printf ("SSE");
18567 break;
18568 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE2:
18569 printf ("SSE2");
18570 break;
18571 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE3:
18572 printf ("SSE3");
18573 break;
18574 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSSE3:
18575 printf ("SSSE3");
18576 break;
18577 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_1:
18578 printf ("SSE4_1");
18579 break;
18580 case GNU_PROPERTY_X86_COMPAT_ISA_1_SSE4_2:
18581 printf ("SSE4_2");
18582 break;
18583 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX:
18584 printf ("AVX");
18585 break;
18586 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX2:
18587 printf ("AVX2");
18588 break;
18589 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512F:
18590 printf ("AVX512F");
18591 break;
18592 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512CD:
18593 printf ("AVX512CD");
18594 break;
18595 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512ER:
18596 printf ("AVX512ER");
18597 break;
18598 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512PF:
18599 printf ("AVX512PF");
18600 break;
18601 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512VL:
18602 printf ("AVX512VL");
18603 break;
18604 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512DQ:
18605 printf ("AVX512DQ");
18606 break;
18607 case GNU_PROPERTY_X86_COMPAT_ISA_1_AVX512BW:
18608 printf ("AVX512BW");
18609 break;
65b3d26e
L
18610 default:
18611 printf (_("<unknown: %x>"), bit);
18612 break;
a9eafb08
L
18613 }
18614 if (bitmask)
18615 printf (", ");
18616 }
18617}
18618
9ef920e9 18619static void
32930e4e 18620decode_x86_compat_2_isa (unsigned int bitmask)
9ef920e9 18621{
0a59decb 18622 if (!bitmask)
90c745dc
L
18623 {
18624 printf (_("<None>"));
18625 return;
18626 }
90c745dc 18627
9ef920e9
NC
18628 while (bitmask)
18629 {
1fc87489 18630 unsigned int bit = bitmask & (- bitmask);
9ef920e9
NC
18631
18632 bitmask &= ~ bit;
18633 switch (bit)
18634 {
32930e4e 18635 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_CMOV:
a9eafb08
L
18636 printf ("CMOV");
18637 break;
32930e4e 18638 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE:
a9eafb08
L
18639 printf ("SSE");
18640 break;
32930e4e 18641 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE2:
a9eafb08
L
18642 printf ("SSE2");
18643 break;
32930e4e 18644 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE3:
a9eafb08
L
18645 printf ("SSE3");
18646 break;
32930e4e 18647 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSSE3:
a9eafb08
L
18648 printf ("SSSE3");
18649 break;
32930e4e 18650 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_1:
a9eafb08
L
18651 printf ("SSE4_1");
18652 break;
32930e4e 18653 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_SSE4_2:
a9eafb08
L
18654 printf ("SSE4_2");
18655 break;
32930e4e 18656 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX:
a9eafb08
L
18657 printf ("AVX");
18658 break;
32930e4e 18659 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX2:
a9eafb08
L
18660 printf ("AVX2");
18661 break;
32930e4e 18662 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_FMA:
a9eafb08
L
18663 printf ("FMA");
18664 break;
32930e4e 18665 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512F:
a9eafb08
L
18666 printf ("AVX512F");
18667 break;
32930e4e 18668 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512CD:
a9eafb08
L
18669 printf ("AVX512CD");
18670 break;
32930e4e 18671 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512ER:
a9eafb08
L
18672 printf ("AVX512ER");
18673 break;
32930e4e 18674 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512PF:
a9eafb08
L
18675 printf ("AVX512PF");
18676 break;
32930e4e 18677 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512VL:
a9eafb08
L
18678 printf ("AVX512VL");
18679 break;
32930e4e 18680 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512DQ:
a9eafb08
L
18681 printf ("AVX512DQ");
18682 break;
32930e4e 18683 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512BW:
a9eafb08
L
18684 printf ("AVX512BW");
18685 break;
32930e4e 18686 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4FMAPS:
a9eafb08
L
18687 printf ("AVX512_4FMAPS");
18688 break;
32930e4e 18689 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_4VNNIW:
a9eafb08
L
18690 printf ("AVX512_4VNNIW");
18691 break;
32930e4e 18692 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BITALG:
a9eafb08
L
18693 printf ("AVX512_BITALG");
18694 break;
32930e4e 18695 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_IFMA:
a9eafb08
L
18696 printf ("AVX512_IFMA");
18697 break;
32930e4e 18698 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI:
a9eafb08
L
18699 printf ("AVX512_VBMI");
18700 break;
32930e4e 18701 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VBMI2:
a9eafb08
L
18702 printf ("AVX512_VBMI2");
18703 break;
32930e4e 18704 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_VNNI:
a9eafb08
L
18705 printf ("AVX512_VNNI");
18706 break;
32930e4e 18707 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_AVX512_BF16:
462cac58
L
18708 printf ("AVX512_BF16");
18709 break;
65b3d26e
L
18710 default:
18711 printf (_("<unknown: %x>"), bit);
18712 break;
9ef920e9
NC
18713 }
18714 if (bitmask)
18715 printf (", ");
18716 }
18717}
18718
32930e4e
L
18719static void
18720decode_x86_isa (unsigned int bitmask)
18721{
32930e4e
L
18722 while (bitmask)
18723 {
18724 unsigned int bit = bitmask & (- bitmask);
18725
18726 bitmask &= ~ bit;
18727 switch (bit)
18728 {
b0ab0693
L
18729 case GNU_PROPERTY_X86_ISA_1_BASELINE:
18730 printf ("x86-64-baseline");
18731 break;
32930e4e
L
18732 case GNU_PROPERTY_X86_ISA_1_V2:
18733 printf ("x86-64-v2");
18734 break;
18735 case GNU_PROPERTY_X86_ISA_1_V3:
18736 printf ("x86-64-v3");
18737 break;
18738 case GNU_PROPERTY_X86_ISA_1_V4:
18739 printf ("x86-64-v4");
18740 break;
18741 default:
18742 printf (_("<unknown: %x>"), bit);
18743 break;
18744 }
18745 if (bitmask)
18746 printf (", ");
18747 }
18748}
18749
ee2fdd6f 18750static void
a9eafb08 18751decode_x86_feature_1 (unsigned int bitmask)
ee2fdd6f 18752{
0a59decb 18753 if (!bitmask)
90c745dc
L
18754 {
18755 printf (_("<None>"));
18756 return;
18757 }
90c745dc 18758
ee2fdd6f
L
18759 while (bitmask)
18760 {
18761 unsigned int bit = bitmask & (- bitmask);
18762
18763 bitmask &= ~ bit;
18764 switch (bit)
18765 {
18766 case GNU_PROPERTY_X86_FEATURE_1_IBT:
a9eafb08 18767 printf ("IBT");
ee2fdd6f 18768 break;
48580982 18769 case GNU_PROPERTY_X86_FEATURE_1_SHSTK:
a9eafb08 18770 printf ("SHSTK");
48580982 18771 break;
279d901e
L
18772 case GNU_PROPERTY_X86_FEATURE_1_LAM_U48:
18773 printf ("LAM_U48");
18774 break;
18775 case GNU_PROPERTY_X86_FEATURE_1_LAM_U57:
18776 printf ("LAM_U57");
18777 break;
ee2fdd6f
L
18778 default:
18779 printf (_("<unknown: %x>"), bit);
18780 break;
18781 }
18782 if (bitmask)
18783 printf (", ");
18784 }
18785}
18786
a9eafb08
L
18787static void
18788decode_x86_feature_2 (unsigned int bitmask)
18789{
0a59decb 18790 if (!bitmask)
90c745dc
L
18791 {
18792 printf (_("<None>"));
18793 return;
18794 }
90c745dc 18795
a9eafb08
L
18796 while (bitmask)
18797 {
18798 unsigned int bit = bitmask & (- bitmask);
18799
18800 bitmask &= ~ bit;
18801 switch (bit)
18802 {
18803 case GNU_PROPERTY_X86_FEATURE_2_X86:
18804 printf ("x86");
18805 break;
18806 case GNU_PROPERTY_X86_FEATURE_2_X87:
18807 printf ("x87");
18808 break;
18809 case GNU_PROPERTY_X86_FEATURE_2_MMX:
18810 printf ("MMX");
18811 break;
18812 case GNU_PROPERTY_X86_FEATURE_2_XMM:
18813 printf ("XMM");
18814 break;
18815 case GNU_PROPERTY_X86_FEATURE_2_YMM:
18816 printf ("YMM");
18817 break;
18818 case GNU_PROPERTY_X86_FEATURE_2_ZMM:
18819 printf ("ZMM");
18820 break;
a308b89d
L
18821 case GNU_PROPERTY_X86_FEATURE_2_TMM:
18822 printf ("TMM");
18823 break;
32930e4e
L
18824 case GNU_PROPERTY_X86_FEATURE_2_MASK:
18825 printf ("MASK");
18826 break;
a9eafb08
L
18827 case GNU_PROPERTY_X86_FEATURE_2_FXSR:
18828 printf ("FXSR");
18829 break;
18830 case GNU_PROPERTY_X86_FEATURE_2_XSAVE:
18831 printf ("XSAVE");
18832 break;
18833 case GNU_PROPERTY_X86_FEATURE_2_XSAVEOPT:
18834 printf ("XSAVEOPT");
18835 break;
18836 case GNU_PROPERTY_X86_FEATURE_2_XSAVEC:
18837 printf ("XSAVEC");
18838 break;
65b3d26e
L
18839 default:
18840 printf (_("<unknown: %x>"), bit);
18841 break;
a9eafb08
L
18842 }
18843 if (bitmask)
18844 printf (", ");
18845 }
18846}
18847
cd702818
SD
18848static void
18849decode_aarch64_feature_1_and (unsigned int bitmask)
18850{
18851 while (bitmask)
18852 {
18853 unsigned int bit = bitmask & (- bitmask);
18854
18855 bitmask &= ~ bit;
18856 switch (bit)
18857 {
18858 case GNU_PROPERTY_AARCH64_FEATURE_1_BTI:
18859 printf ("BTI");
18860 break;
18861
18862 case GNU_PROPERTY_AARCH64_FEATURE_1_PAC:
18863 printf ("PAC");
18864 break;
18865
18866 default:
18867 printf (_("<unknown: %x>"), bit);
18868 break;
18869 }
18870 if (bitmask)
18871 printf (", ");
18872 }
18873}
18874
9ef920e9 18875static void
dda8d76d 18876print_gnu_property_note (Filedata * filedata, Elf_Internal_Note * pnote)
9ef920e9
NC
18877{
18878 unsigned char * ptr = (unsigned char *) pnote->descdata;
18879 unsigned char * ptr_end = ptr + pnote->descsz;
18880 unsigned int size = is_32bit_elf ? 4 : 8;
18881
18882 printf (_(" Properties: "));
18883
1fc87489 18884 if (pnote->descsz < 8 || (pnote->descsz % size) != 0)
9ef920e9
NC
18885 {
18886 printf (_("<corrupt GNU_PROPERTY_TYPE, size = %#lx>\n"), pnote->descsz);
18887 return;
18888 }
18889
6ab2c4ed 18890 while (ptr < ptr_end)
9ef920e9 18891 {
1fc87489 18892 unsigned int j;
6ab2c4ed
MC
18893 unsigned int type;
18894 unsigned int datasz;
18895
18896 if ((size_t) (ptr_end - ptr) < 8)
18897 {
18898 printf (_("<corrupt descsz: %#lx>\n"), pnote->descsz);
18899 break;
18900 }
18901
18902 type = byte_get (ptr, 4);
18903 datasz = byte_get (ptr + 4, 4);
9ef920e9 18904
1fc87489 18905 ptr += 8;
9ef920e9 18906
6ab2c4ed 18907 if (datasz > (size_t) (ptr_end - ptr))
9ef920e9 18908 {
1fc87489
L
18909 printf (_("<corrupt type (%#x) datasz: %#x>\n"),
18910 type, datasz);
9ef920e9 18911 break;
1fc87489 18912 }
9ef920e9 18913
1fc87489
L
18914 if (type >= GNU_PROPERTY_LOPROC && type <= GNU_PROPERTY_HIPROC)
18915 {
dda8d76d
NC
18916 if (filedata->file_header.e_machine == EM_X86_64
18917 || filedata->file_header.e_machine == EM_IAMCU
18918 || filedata->file_header.e_machine == EM_386)
1fc87489 18919 {
aa7bca9b
L
18920 unsigned int bitmask;
18921
18922 if (datasz == 4)
0a59decb 18923 bitmask = byte_get (ptr, 4);
aa7bca9b
L
18924 else
18925 bitmask = 0;
18926
1fc87489
L
18927 switch (type)
18928 {
18929 case GNU_PROPERTY_X86_ISA_1_USED:
1fc87489 18930 if (datasz != 4)
aa7bca9b
L
18931 printf (_("x86 ISA used: <corrupt length: %#x> "),
18932 datasz);
1fc87489 18933 else
aa7bca9b
L
18934 {
18935 printf ("x86 ISA used: ");
18936 decode_x86_isa (bitmask);
18937 }
1fc87489 18938 goto next;
9ef920e9 18939
1fc87489 18940 case GNU_PROPERTY_X86_ISA_1_NEEDED:
1fc87489 18941 if (datasz != 4)
aa7bca9b
L
18942 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18943 datasz);
1fc87489 18944 else
aa7bca9b
L
18945 {
18946 printf ("x86 ISA needed: ");
18947 decode_x86_isa (bitmask);
18948 }
1fc87489 18949 goto next;
9ef920e9 18950
ee2fdd6f 18951 case GNU_PROPERTY_X86_FEATURE_1_AND:
ee2fdd6f 18952 if (datasz != 4)
aa7bca9b
L
18953 printf (_("x86 feature: <corrupt length: %#x> "),
18954 datasz);
ee2fdd6f 18955 else
aa7bca9b
L
18956 {
18957 printf ("x86 feature: ");
a9eafb08
L
18958 decode_x86_feature_1 (bitmask);
18959 }
18960 goto next;
18961
18962 case GNU_PROPERTY_X86_FEATURE_2_USED:
18963 if (datasz != 4)
18964 printf (_("x86 feature used: <corrupt length: %#x> "),
18965 datasz);
18966 else
18967 {
18968 printf ("x86 feature used: ");
18969 decode_x86_feature_2 (bitmask);
18970 }
18971 goto next;
18972
18973 case GNU_PROPERTY_X86_FEATURE_2_NEEDED:
18974 if (datasz != 4)
18975 printf (_("x86 feature needed: <corrupt length: %#x> "), datasz);
18976 else
18977 {
18978 printf ("x86 feature needed: ");
18979 decode_x86_feature_2 (bitmask);
18980 }
18981 goto next;
18982
18983 case GNU_PROPERTY_X86_COMPAT_ISA_1_USED:
18984 if (datasz != 4)
18985 printf (_("x86 ISA used: <corrupt length: %#x> "),
18986 datasz);
18987 else
18988 {
18989 printf ("x86 ISA used: ");
18990 decode_x86_compat_isa (bitmask);
18991 }
18992 goto next;
18993
18994 case GNU_PROPERTY_X86_COMPAT_ISA_1_NEEDED:
18995 if (datasz != 4)
18996 printf (_("x86 ISA needed: <corrupt length: %#x> "),
18997 datasz);
18998 else
18999 {
19000 printf ("x86 ISA needed: ");
19001 decode_x86_compat_isa (bitmask);
aa7bca9b 19002 }
ee2fdd6f
L
19003 goto next;
19004
32930e4e
L
19005 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_USED:
19006 if (datasz != 4)
19007 printf (_("x86 ISA used: <corrupt length: %#x> "),
19008 datasz);
19009 else
19010 {
19011 printf ("x86 ISA used: ");
19012 decode_x86_compat_2_isa (bitmask);
19013 }
19014 goto next;
19015
19016 case GNU_PROPERTY_X86_COMPAT_2_ISA_1_NEEDED:
19017 if (datasz != 4)
19018 printf (_("x86 ISA needed: <corrupt length: %#x> "),
19019 datasz);
19020 else
19021 {
19022 printf ("x86 ISA needed: ");
19023 decode_x86_compat_2_isa (bitmask);
19024 }
19025 goto next;
19026
1fc87489
L
19027 default:
19028 break;
19029 }
19030 }
cd702818
SD
19031 else if (filedata->file_header.e_machine == EM_AARCH64)
19032 {
19033 if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND)
19034 {
19035 printf ("AArch64 feature: ");
19036 if (datasz != 4)
19037 printf (_("<corrupt length: %#x> "), datasz);
19038 else
19039 decode_aarch64_feature_1_and (byte_get (ptr, 4));
19040 goto next;
19041 }
19042 }
1fc87489
L
19043 }
19044 else
19045 {
19046 switch (type)
9ef920e9 19047 {
1fc87489
L
19048 case GNU_PROPERTY_STACK_SIZE:
19049 printf (_("stack size: "));
19050 if (datasz != size)
19051 printf (_("<corrupt length: %#x> "), datasz);
19052 else
19053 printf ("%#lx", (unsigned long) byte_get (ptr, size));
19054 goto next;
19055
19056 case GNU_PROPERTY_NO_COPY_ON_PROTECTED:
19057 printf ("no copy on protected ");
19058 if (datasz)
19059 printf (_("<corrupt length: %#x> "), datasz);
19060 goto next;
19061
19062 default:
9ef920e9
NC
19063 break;
19064 }
9ef920e9
NC
19065 }
19066
1fc87489
L
19067 if (type < GNU_PROPERTY_LOPROC)
19068 printf (_("<unknown type %#x data: "), type);
19069 else if (type < GNU_PROPERTY_LOUSER)
19070 printf (_("<procesor-specific type %#x data: "), type);
19071 else
19072 printf (_("<application-specific type %#x data: "), type);
19073 for (j = 0; j < datasz; ++j)
19074 printf ("%02x ", ptr[j] & 0xff);
19075 printf (">");
19076
dc1e8a47 19077 next:
9ef920e9 19078 ptr += ((datasz + (size - 1)) & ~ (size - 1));
1fc87489
L
19079 if (ptr == ptr_end)
19080 break;
1fc87489 19081
6ab2c4ed
MC
19082 if (do_wide)
19083 printf (", ");
19084 else
19085 printf ("\n\t");
9ef920e9
NC
19086 }
19087
19088 printf ("\n");
19089}
19090
32ec8896 19091static bfd_boolean
dda8d76d 19092print_gnu_note (Filedata * filedata, Elf_Internal_Note *pnote)
664f90a3 19093{
1449284b 19094 /* NB/ Keep this switch statement in sync with get_gnu_elf_note_type (). */
664f90a3
TT
19095 switch (pnote->type)
19096 {
19097 case NT_GNU_BUILD_ID:
19098 {
19099 unsigned long i;
19100
19101 printf (_(" Build ID: "));
19102 for (i = 0; i < pnote->descsz; ++i)
19103 printf ("%02x", pnote->descdata[i] & 0xff);
9cf03b7e 19104 printf ("\n");
664f90a3
TT
19105 }
19106 break;
19107
19108 case NT_GNU_ABI_TAG:
19109 {
19110 unsigned long os, major, minor, subminor;
19111 const char *osname;
19112
3102e897
NC
19113 /* PR 17531: file: 030-599401-0.004. */
19114 if (pnote->descsz < 16)
19115 {
19116 printf (_(" <corrupt GNU_ABI_TAG>\n"));
19117 break;
19118 }
19119
664f90a3
TT
19120 os = byte_get ((unsigned char *) pnote->descdata, 4);
19121 major = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19122 minor = byte_get ((unsigned char *) pnote->descdata + 8, 4);
19123 subminor = byte_get ((unsigned char *) pnote->descdata + 12, 4);
19124
19125 switch (os)
19126 {
19127 case GNU_ABI_TAG_LINUX:
19128 osname = "Linux";
19129 break;
19130 case GNU_ABI_TAG_HURD:
19131 osname = "Hurd";
19132 break;
19133 case GNU_ABI_TAG_SOLARIS:
19134 osname = "Solaris";
19135 break;
19136 case GNU_ABI_TAG_FREEBSD:
19137 osname = "FreeBSD";
19138 break;
19139 case GNU_ABI_TAG_NETBSD:
19140 osname = "NetBSD";
19141 break;
14ae95f2
RM
19142 case GNU_ABI_TAG_SYLLABLE:
19143 osname = "Syllable";
19144 break;
19145 case GNU_ABI_TAG_NACL:
19146 osname = "NaCl";
19147 break;
664f90a3
TT
19148 default:
19149 osname = "Unknown";
19150 break;
19151 }
19152
19153 printf (_(" OS: %s, ABI: %ld.%ld.%ld\n"), osname,
19154 major, minor, subminor);
19155 }
19156 break;
926c5385
CC
19157
19158 case NT_GNU_GOLD_VERSION:
19159 {
19160 unsigned long i;
19161
19162 printf (_(" Version: "));
19163 for (i = 0; i < pnote->descsz && pnote->descdata[i] != '\0'; ++i)
19164 printf ("%c", pnote->descdata[i]);
19165 printf ("\n");
19166 }
19167 break;
1449284b
NC
19168
19169 case NT_GNU_HWCAP:
19170 {
19171 unsigned long num_entries, mask;
19172
19173 /* Hardware capabilities information. Word 0 is the number of entries.
19174 Word 1 is a bitmask of enabled entries. The rest of the descriptor
19175 is a series of entries, where each entry is a single byte followed
19176 by a nul terminated string. The byte gives the bit number to test
19177 if enabled in the bitmask. */
19178 printf (_(" Hardware Capabilities: "));
19179 if (pnote->descsz < 8)
19180 {
32ec8896
NC
19181 error (_("<corrupt GNU_HWCAP>\n"));
19182 return FALSE;
1449284b
NC
19183 }
19184 num_entries = byte_get ((unsigned char *) pnote->descdata, 4);
19185 mask = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19186 printf (_("num entries: %ld, enabled mask: %lx\n"), num_entries, mask);
19187 /* FIXME: Add code to display the entries... */
19188 }
19189 break;
19190
9ef920e9 19191 case NT_GNU_PROPERTY_TYPE_0:
dda8d76d 19192 print_gnu_property_note (filedata, pnote);
9ef920e9 19193 break;
9abca702 19194
1449284b
NC
19195 default:
19196 /* Handle unrecognised types. An error message should have already been
19197 created by get_gnu_elf_note_type(), so all that we need to do is to
19198 display the data. */
19199 {
19200 unsigned long i;
19201
19202 printf (_(" Description data: "));
19203 for (i = 0; i < pnote->descsz; ++i)
19204 printf ("%02x ", pnote->descdata[i] & 0xff);
19205 printf ("\n");
19206 }
19207 break;
664f90a3
TT
19208 }
19209
32ec8896 19210 return TRUE;
664f90a3
TT
19211}
19212
685080f2
NC
19213static const char *
19214get_v850_elf_note_type (enum v850_notes n_type)
19215{
19216 static char buff[64];
19217
19218 switch (n_type)
19219 {
19220 case V850_NOTE_ALIGNMENT: return _("Alignment of 8-byte objects");
19221 case V850_NOTE_DATA_SIZE: return _("Sizeof double and long double");
19222 case V850_NOTE_FPU_INFO: return _("Type of FPU support needed");
19223 case V850_NOTE_SIMD_INFO: return _("Use of SIMD instructions");
19224 case V850_NOTE_CACHE_INFO: return _("Use of cache");
19225 case V850_NOTE_MMU_INFO: return _("Use of MMU");
19226 default:
19227 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), n_type);
19228 return buff;
19229 }
19230}
19231
32ec8896 19232static bfd_boolean
685080f2
NC
19233print_v850_note (Elf_Internal_Note * pnote)
19234{
19235 unsigned int val;
19236
19237 if (pnote->descsz != 4)
32ec8896
NC
19238 return FALSE;
19239
685080f2
NC
19240 val = byte_get ((unsigned char *) pnote->descdata, pnote->descsz);
19241
19242 if (val == 0)
19243 {
19244 printf (_("not set\n"));
32ec8896 19245 return TRUE;
685080f2
NC
19246 }
19247
19248 switch (pnote->type)
19249 {
19250 case V850_NOTE_ALIGNMENT:
19251 switch (val)
19252 {
32ec8896
NC
19253 case EF_RH850_DATA_ALIGN4: printf (_("4-byte\n")); return TRUE;
19254 case EF_RH850_DATA_ALIGN8: printf (_("8-byte\n")); return TRUE;
685080f2
NC
19255 }
19256 break;
14ae95f2 19257
685080f2
NC
19258 case V850_NOTE_DATA_SIZE:
19259 switch (val)
19260 {
32ec8896
NC
19261 case EF_RH850_DOUBLE32: printf (_("4-bytes\n")); return TRUE;
19262 case EF_RH850_DOUBLE64: printf (_("8-bytes\n")); return TRUE;
685080f2
NC
19263 }
19264 break;
14ae95f2 19265
685080f2
NC
19266 case V850_NOTE_FPU_INFO:
19267 switch (val)
19268 {
32ec8896
NC
19269 case EF_RH850_FPU20: printf (_("FPU-2.0\n")); return TRUE;
19270 case EF_RH850_FPU30: printf (_("FPU-3.0\n")); return TRUE;
685080f2
NC
19271 }
19272 break;
14ae95f2 19273
685080f2
NC
19274 case V850_NOTE_MMU_INFO:
19275 case V850_NOTE_CACHE_INFO:
19276 case V850_NOTE_SIMD_INFO:
19277 if (val == EF_RH850_SIMD)
19278 {
19279 printf (_("yes\n"));
32ec8896 19280 return TRUE;
685080f2
NC
19281 }
19282 break;
19283
19284 default:
19285 /* An 'unknown note type' message will already have been displayed. */
19286 break;
19287 }
19288
19289 printf (_("unknown value: %x\n"), val);
32ec8896 19290 return FALSE;
685080f2
NC
19291}
19292
32ec8896 19293static bfd_boolean
c6056a74
SF
19294process_netbsd_elf_note (Elf_Internal_Note * pnote)
19295{
19296 unsigned int version;
19297
19298 switch (pnote->type)
19299 {
19300 case NT_NETBSD_IDENT:
b966f55f
AM
19301 if (pnote->descsz < 1)
19302 break;
c6056a74
SF
19303 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19304 if ((version / 10000) % 100)
b966f55f 19305 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u%s%c)\n", pnote->descsz,
c6056a74
SF
19306 version, version / 100000000, (version / 1000000) % 100,
19307 (version / 10000) % 100 > 26 ? "Z" : "",
15f205b1 19308 'A' + (version / 10000) % 26);
c6056a74
SF
19309 else
19310 printf (" NetBSD\t\t0x%08lx\tIDENT %u (%u.%u.%u)\n", pnote->descsz,
b966f55f 19311 version, version / 100000000, (version / 1000000) % 100,
15f205b1 19312 (version / 100) % 100);
32ec8896 19313 return TRUE;
c6056a74
SF
19314
19315 case NT_NETBSD_MARCH:
9abca702 19316 printf (" NetBSD\t\t0x%08lx\tMARCH <%s>\n", pnote->descsz,
c6056a74 19317 pnote->descdata);
32ec8896 19318 return TRUE;
c6056a74 19319
9abca702
CZ
19320#ifdef NT_NETBSD_PAX
19321 case NT_NETBSD_PAX:
b966f55f
AM
19322 if (pnote->descsz < 1)
19323 break;
9abca702
CZ
19324 version = byte_get ((unsigned char *) pnote->descdata, sizeof (version));
19325 printf (" NetBSD\t\t0x%08lx\tPaX <%s%s%s%s%s%s>\n", pnote->descsz,
19326 ((version & NT_NETBSD_PAX_MPROTECT) ? "+mprotect" : ""),
19327 ((version & NT_NETBSD_PAX_NOMPROTECT) ? "-mprotect" : ""),
19328 ((version & NT_NETBSD_PAX_GUARD) ? "+guard" : ""),
19329 ((version & NT_NETBSD_PAX_NOGUARD) ? "-guard" : ""),
19330 ((version & NT_NETBSD_PAX_ASLR) ? "+ASLR" : ""),
19331 ((version & NT_NETBSD_PAX_NOASLR) ? "-ASLR" : ""));
19332 return TRUE;
19333#endif
c6056a74 19334 }
b966f55f
AM
19335
19336 printf (" NetBSD\t0x%08lx\tUnknown note type: (0x%08lx)\n",
19337 pnote->descsz, pnote->type);
19338 return FALSE;
c6056a74
SF
19339}
19340
f4ddf30f 19341static const char *
dda8d76d 19342get_freebsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
f4ddf30f 19343{
f4ddf30f
JB
19344 switch (e_type)
19345 {
19346 case NT_FREEBSD_THRMISC:
19347 return _("NT_THRMISC (thrmisc structure)");
19348 case NT_FREEBSD_PROCSTAT_PROC:
19349 return _("NT_PROCSTAT_PROC (proc data)");
19350 case NT_FREEBSD_PROCSTAT_FILES:
19351 return _("NT_PROCSTAT_FILES (files data)");
19352 case NT_FREEBSD_PROCSTAT_VMMAP:
19353 return _("NT_PROCSTAT_VMMAP (vmmap data)");
19354 case NT_FREEBSD_PROCSTAT_GROUPS:
19355 return _("NT_PROCSTAT_GROUPS (groups data)");
19356 case NT_FREEBSD_PROCSTAT_UMASK:
19357 return _("NT_PROCSTAT_UMASK (umask data)");
19358 case NT_FREEBSD_PROCSTAT_RLIMIT:
19359 return _("NT_PROCSTAT_RLIMIT (rlimit data)");
19360 case NT_FREEBSD_PROCSTAT_OSREL:
19361 return _("NT_PROCSTAT_OSREL (osreldate data)");
19362 case NT_FREEBSD_PROCSTAT_PSSTRINGS:
19363 return _("NT_PROCSTAT_PSSTRINGS (ps_strings data)");
19364 case NT_FREEBSD_PROCSTAT_AUXV:
19365 return _("NT_PROCSTAT_AUXV (auxv data)");
0b9305ed
JB
19366 case NT_FREEBSD_PTLWPINFO:
19367 return _("NT_PTLWPINFO (ptrace_lwpinfo structure)");
f4ddf30f 19368 }
dda8d76d 19369 return get_note_type (filedata, e_type);
f4ddf30f
JB
19370}
19371
9437c45b 19372static const char *
dda8d76d 19373get_netbsd_elfcore_note_type (Filedata * filedata, unsigned e_type)
9437c45b
JT
19374{
19375 static char buff[64];
19376
540e6170
CZ
19377 switch (e_type)
19378 {
19379 case NT_NETBSDCORE_PROCINFO:
19380 /* NetBSD core "procinfo" structure. */
19381 return _("NetBSD procinfo structure");
9437c45b 19382
540e6170
CZ
19383#ifdef NT_NETBSDCORE_AUXV
19384 case NT_NETBSDCORE_AUXV:
19385 return _("NetBSD ELF auxiliary vector data");
19386#endif
9437c45b 19387
06d949ec
KR
19388#ifdef NT_NETBSDCORE_LWPSTATUS
19389 case NT_NETBSDCORE_LWPSTATUS:
19390 return _("PT_LWPSTATUS (ptrace_lwpstatus structure)");
19391#endif
19392
540e6170 19393 default:
06d949ec 19394 /* As of Jan 2020 there are no other machine-independent notes
540e6170
CZ
19395 defined for NetBSD core files. If the note type is less
19396 than the start of the machine-dependent note types, we don't
19397 understand it. */
19398
19399 if (e_type < NT_NETBSDCORE_FIRSTMACH)
19400 {
19401 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19402 return buff;
19403 }
19404 break;
9437c45b
JT
19405 }
19406
dda8d76d 19407 switch (filedata->file_header.e_machine)
9437c45b
JT
19408 {
19409 /* On the Alpha, SPARC (32-bit and 64-bit), PT_GETREGS == mach+0
19410 and PT_GETFPREGS == mach+2. */
19411
19412 case EM_OLD_ALPHA:
19413 case EM_ALPHA:
19414 case EM_SPARC:
19415 case EM_SPARC32PLUS:
19416 case EM_SPARCV9:
19417 switch (e_type)
19418 {
2b692964 19419 case NT_NETBSDCORE_FIRSTMACH + 0:
b4db1224 19420 return _("PT_GETREGS (reg structure)");
2b692964 19421 case NT_NETBSDCORE_FIRSTMACH + 2:
b4db1224 19422 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19423 default:
19424 break;
19425 }
19426 break;
19427
c0d38b0e
CZ
19428 /* On SuperH, PT_GETREGS == mach+3 and PT_GETFPREGS == mach+5.
19429 There's also old PT___GETREGS40 == mach + 1 for old reg
19430 structure which lacks GBR. */
19431 case EM_SH:
19432 switch (e_type)
19433 {
19434 case NT_NETBSDCORE_FIRSTMACH + 1:
19435 return _("PT___GETREGS40 (old reg structure)");
19436 case NT_NETBSDCORE_FIRSTMACH + 3:
19437 return _("PT_GETREGS (reg structure)");
19438 case NT_NETBSDCORE_FIRSTMACH + 5:
19439 return _("PT_GETFPREGS (fpreg structure)");
19440 default:
19441 break;
19442 }
19443 break;
19444
9437c45b
JT
19445 /* On all other arch's, PT_GETREGS == mach+1 and
19446 PT_GETFPREGS == mach+3. */
19447 default:
19448 switch (e_type)
19449 {
2b692964 19450 case NT_NETBSDCORE_FIRSTMACH + 1:
b4db1224 19451 return _("PT_GETREGS (reg structure)");
2b692964 19452 case NT_NETBSDCORE_FIRSTMACH + 3:
b4db1224 19453 return _("PT_GETFPREGS (fpreg structure)");
9437c45b
JT
19454 default:
19455 break;
19456 }
19457 }
19458
9cf03b7e 19459 snprintf (buff, sizeof (buff), "PT_FIRSTMACH+%d",
e9e44622 19460 e_type - NT_NETBSDCORE_FIRSTMACH);
9437c45b
JT
19461 return buff;
19462}
19463
70616151
TT
19464static const char *
19465get_stapsdt_note_type (unsigned e_type)
19466{
19467 static char buff[64];
19468
19469 switch (e_type)
19470 {
19471 case NT_STAPSDT:
19472 return _("NT_STAPSDT (SystemTap probe descriptors)");
19473
19474 default:
19475 break;
19476 }
19477
19478 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19479 return buff;
19480}
19481
32ec8896 19482static bfd_boolean
c6a9fc58
TT
19483print_stapsdt_note (Elf_Internal_Note *pnote)
19484{
3ca60c57
NC
19485 size_t len, maxlen;
19486 unsigned long addr_size = is_32bit_elf ? 4 : 8;
c6a9fc58
TT
19487 char *data = pnote->descdata;
19488 char *data_end = pnote->descdata + pnote->descsz;
19489 bfd_vma pc, base_addr, semaphore;
19490 char *provider, *probe, *arg_fmt;
19491
3ca60c57
NC
19492 if (pnote->descsz < (addr_size * 3))
19493 goto stapdt_note_too_small;
19494
c6a9fc58
TT
19495 pc = byte_get ((unsigned char *) data, addr_size);
19496 data += addr_size;
3ca60c57 19497
c6a9fc58
TT
19498 base_addr = byte_get ((unsigned char *) data, addr_size);
19499 data += addr_size;
3ca60c57 19500
c6a9fc58
TT
19501 semaphore = byte_get ((unsigned char *) data, addr_size);
19502 data += addr_size;
19503
3ca60c57
NC
19504 if (data >= data_end)
19505 goto stapdt_note_too_small;
19506 maxlen = data_end - data;
19507 len = strnlen (data, maxlen);
19508 if (len < maxlen)
19509 {
19510 provider = data;
19511 data += len + 1;
19512 }
19513 else
19514 goto stapdt_note_too_small;
19515
19516 if (data >= data_end)
19517 goto stapdt_note_too_small;
19518 maxlen = data_end - data;
19519 len = strnlen (data, maxlen);
19520 if (len < maxlen)
19521 {
19522 probe = data;
19523 data += len + 1;
19524 }
19525 else
19526 goto stapdt_note_too_small;
9abca702 19527
3ca60c57
NC
19528 if (data >= data_end)
19529 goto stapdt_note_too_small;
19530 maxlen = data_end - data;
19531 len = strnlen (data, maxlen);
19532 if (len < maxlen)
19533 {
19534 arg_fmt = data;
19535 data += len + 1;
19536 }
19537 else
19538 goto stapdt_note_too_small;
c6a9fc58
TT
19539
19540 printf (_(" Provider: %s\n"), provider);
19541 printf (_(" Name: %s\n"), probe);
19542 printf (_(" Location: "));
19543 print_vma (pc, FULL_HEX);
19544 printf (_(", Base: "));
19545 print_vma (base_addr, FULL_HEX);
19546 printf (_(", Semaphore: "));
19547 print_vma (semaphore, FULL_HEX);
9cf03b7e 19548 printf ("\n");
c6a9fc58
TT
19549 printf (_(" Arguments: %s\n"), arg_fmt);
19550
19551 return data == data_end;
3ca60c57
NC
19552
19553 stapdt_note_too_small:
19554 printf (_(" <corrupt - note is too small>\n"));
19555 error (_("corrupt stapdt note - the data size is too small\n"));
19556 return FALSE;
c6a9fc58
TT
19557}
19558
00e98fc7
TG
19559static const char *
19560get_ia64_vms_note_type (unsigned e_type)
19561{
19562 static char buff[64];
19563
19564 switch (e_type)
19565 {
19566 case NT_VMS_MHD:
19567 return _("NT_VMS_MHD (module header)");
19568 case NT_VMS_LNM:
19569 return _("NT_VMS_LNM (language name)");
19570 case NT_VMS_SRC:
19571 return _("NT_VMS_SRC (source files)");
19572 case NT_VMS_TITLE:
9cf03b7e 19573 return "NT_VMS_TITLE";
00e98fc7
TG
19574 case NT_VMS_EIDC:
19575 return _("NT_VMS_EIDC (consistency check)");
19576 case NT_VMS_FPMODE:
19577 return _("NT_VMS_FPMODE (FP mode)");
19578 case NT_VMS_LINKTIME:
9cf03b7e 19579 return "NT_VMS_LINKTIME";
00e98fc7
TG
19580 case NT_VMS_IMGNAM:
19581 return _("NT_VMS_IMGNAM (image name)");
19582 case NT_VMS_IMGID:
19583 return _("NT_VMS_IMGID (image id)");
19584 case NT_VMS_LINKID:
19585 return _("NT_VMS_LINKID (link id)");
19586 case NT_VMS_IMGBID:
19587 return _("NT_VMS_IMGBID (build id)");
19588 case NT_VMS_GSTNAM:
19589 return _("NT_VMS_GSTNAM (sym table name)");
19590 case NT_VMS_ORIG_DYN:
9cf03b7e 19591 return "NT_VMS_ORIG_DYN";
00e98fc7 19592 case NT_VMS_PATCHTIME:
9cf03b7e 19593 return "NT_VMS_PATCHTIME";
00e98fc7
TG
19594 default:
19595 snprintf (buff, sizeof (buff), _("Unknown note type: (0x%08x)"), e_type);
19596 return buff;
19597 }
19598}
19599
32ec8896 19600static bfd_boolean
00e98fc7
TG
19601print_ia64_vms_note (Elf_Internal_Note * pnote)
19602{
8d18bf79
NC
19603 int maxlen = pnote->descsz;
19604
19605 if (maxlen < 2 || (unsigned long) maxlen != pnote->descsz)
19606 goto desc_size_fail;
19607
00e98fc7
TG
19608 switch (pnote->type)
19609 {
19610 case NT_VMS_MHD:
8d18bf79
NC
19611 if (maxlen <= 36)
19612 goto desc_size_fail;
19613
19614 int l = (int) strnlen (pnote->descdata + 34, maxlen - 34);
19615
19616 printf (_(" Creation date : %.17s\n"), pnote->descdata);
19617 printf (_(" Last patch date: %.17s\n"), pnote->descdata + 17);
19618 if (l + 34 < maxlen)
19619 {
19620 printf (_(" Module name : %s\n"), pnote->descdata + 34);
19621 if (l + 35 < maxlen)
19622 printf (_(" Module version : %s\n"), pnote->descdata + 34 + l + 1);
19623 else
19624 printf (_(" Module version : <missing>\n"));
19625 }
00e98fc7 19626 else
8d18bf79
NC
19627 {
19628 printf (_(" Module name : <missing>\n"));
19629 printf (_(" Module version : <missing>\n"));
19630 }
00e98fc7 19631 break;
8d18bf79 19632
00e98fc7 19633 case NT_VMS_LNM:
8d18bf79 19634 printf (_(" Language: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19635 break;
8d18bf79 19636
00e98fc7
TG
19637#ifdef BFD64
19638 case NT_VMS_FPMODE:
9cf03b7e 19639 printf (_(" Floating Point mode: "));
8d18bf79
NC
19640 if (maxlen < 8)
19641 goto desc_size_fail;
19642 /* FIXME: Generate an error if descsz > 8 ? */
19643
4a5cb34f 19644 printf ("0x%016" BFD_VMA_FMT "x\n",
8d18bf79 19645 (bfd_vma) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7 19646 break;
8d18bf79 19647
00e98fc7
TG
19648 case NT_VMS_LINKTIME:
19649 printf (_(" Link time: "));
8d18bf79
NC
19650 if (maxlen < 8)
19651 goto desc_size_fail;
19652 /* FIXME: Generate an error if descsz > 8 ? */
19653
00e98fc7 19654 print_vms_time
8d18bf79 19655 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19656 printf ("\n");
19657 break;
8d18bf79 19658
00e98fc7
TG
19659 case NT_VMS_PATCHTIME:
19660 printf (_(" Patch time: "));
8d18bf79
NC
19661 if (maxlen < 8)
19662 goto desc_size_fail;
19663 /* FIXME: Generate an error if descsz > 8 ? */
19664
00e98fc7 19665 print_vms_time
8d18bf79 19666 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata, 8));
00e98fc7
TG
19667 printf ("\n");
19668 break;
8d18bf79 19669
00e98fc7 19670 case NT_VMS_ORIG_DYN:
8d18bf79
NC
19671 if (maxlen < 34)
19672 goto desc_size_fail;
19673
00e98fc7
TG
19674 printf (_(" Major id: %u, minor id: %u\n"),
19675 (unsigned) byte_get ((unsigned char *)pnote->descdata, 4),
19676 (unsigned) byte_get ((unsigned char *)pnote->descdata + 4, 4));
9cf03b7e 19677 printf (_(" Last modified : "));
00e98fc7
TG
19678 print_vms_time
19679 ((bfd_int64_t) byte_get ((unsigned char *)pnote->descdata + 8, 8));
9cf03b7e 19680 printf (_("\n Link flags : "));
4a5cb34f 19681 printf ("0x%016" BFD_VMA_FMT "x\n",
948f632f 19682 (bfd_vma) byte_get ((unsigned char *)pnote->descdata + 16, 8));
00e98fc7 19683 printf (_(" Header flags: 0x%08x\n"),
948f632f 19684 (unsigned) byte_get ((unsigned char *)pnote->descdata + 24, 4));
8d18bf79 19685 printf (_(" Image id : %.*s\n"), maxlen - 32, pnote->descdata + 32);
00e98fc7
TG
19686 break;
19687#endif
8d18bf79 19688
00e98fc7 19689 case NT_VMS_IMGNAM:
8d18bf79 19690 printf (_(" Image name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19691 break;
8d18bf79 19692
00e98fc7 19693 case NT_VMS_GSTNAM:
8d18bf79 19694 printf (_(" Global symbol table name: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19695 break;
8d18bf79 19696
00e98fc7 19697 case NT_VMS_IMGID:
8d18bf79 19698 printf (_(" Image id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19699 break;
8d18bf79 19700
00e98fc7 19701 case NT_VMS_LINKID:
8d18bf79 19702 printf (_(" Linker id: %.*s\n"), maxlen, pnote->descdata);
00e98fc7 19703 break;
8d18bf79 19704
00e98fc7 19705 default:
32ec8896 19706 return FALSE;
00e98fc7 19707 }
8d18bf79 19708
32ec8896 19709 return TRUE;
8d18bf79
NC
19710
19711 desc_size_fail:
19712 printf (_(" <corrupt - data size is too small>\n"));
19713 error (_("corrupt IA64 note: data size is too small\n"));
19714 return FALSE;
00e98fc7
TG
19715}
19716
fd486f32
AM
19717struct build_attr_cache {
19718 Filedata *filedata;
19719 char *strtab;
19720 unsigned long strtablen;
19721 Elf_Internal_Sym *symtab;
19722 unsigned long nsyms;
19723} ba_cache;
19724
6f156d7a
NC
19725/* Find the symbol associated with a build attribute that is attached
19726 to address OFFSET. If PNAME is non-NULL then store the name of
19727 the symbol (if found) in the provided pointer, Returns NULL if a
19728 symbol could not be found. */
c799a79d 19729
6f156d7a
NC
19730static Elf_Internal_Sym *
19731get_symbol_for_build_attribute (Filedata * filedata,
19732 unsigned long offset,
19733 bfd_boolean is_open_attr,
19734 const char ** pname)
9ef920e9 19735{
fd486f32
AM
19736 Elf_Internal_Sym *saved_sym = NULL;
19737 Elf_Internal_Sym *sym;
9ef920e9 19738
dda8d76d 19739 if (filedata->section_headers != NULL
fd486f32 19740 && (ba_cache.filedata == NULL || filedata != ba_cache.filedata))
9ef920e9 19741 {
c799a79d 19742 Elf_Internal_Shdr * symsec;
9ef920e9 19743
fd486f32
AM
19744 free (ba_cache.strtab);
19745 ba_cache.strtab = NULL;
19746 free (ba_cache.symtab);
19747 ba_cache.symtab = NULL;
19748
c799a79d 19749 /* Load the symbol and string sections. */
dda8d76d
NC
19750 for (symsec = filedata->section_headers;
19751 symsec < filedata->section_headers + filedata->file_header.e_shnum;
c799a79d 19752 symsec ++)
9ef920e9 19753 {
28d13567
AM
19754 if (symsec->sh_type == SHT_SYMTAB
19755 && get_symtab (filedata, symsec,
19756 &ba_cache.symtab, &ba_cache.nsyms,
19757 &ba_cache.strtab, &ba_cache.strtablen))
19758 break;
9ef920e9 19759 }
fd486f32 19760 ba_cache.filedata = filedata;
9ef920e9
NC
19761 }
19762
fd486f32 19763 if (ba_cache.symtab == NULL)
6f156d7a 19764 return NULL;
9ef920e9 19765
c799a79d 19766 /* Find a symbol whose value matches offset. */
fd486f32 19767 for (sym = ba_cache.symtab; sym < ba_cache.symtab + ba_cache.nsyms; sym ++)
c799a79d
NC
19768 if (sym->st_value == offset)
19769 {
fd486f32 19770 if (sym->st_name >= ba_cache.strtablen)
c799a79d
NC
19771 /* Huh ? This should not happen. */
19772 continue;
9ef920e9 19773
fd486f32 19774 if (ba_cache.strtab[sym->st_name] == 0)
c799a79d 19775 continue;
9ef920e9 19776
8fd75781
NC
19777 /* The AArch64 and ARM architectures define mapping symbols
19778 (eg $d, $x, $t) which we want to ignore. */
fd486f32
AM
19779 if (ba_cache.strtab[sym->st_name] == '$'
19780 && ba_cache.strtab[sym->st_name + 1] != 0
19781 && ba_cache.strtab[sym->st_name + 2] == 0)
8fd75781
NC
19782 continue;
19783
c799a79d
NC
19784 if (is_open_attr)
19785 {
19786 /* For OPEN attributes we prefer GLOBAL over LOCAL symbols
19787 and FILE or OBJECT symbols over NOTYPE symbols. We skip
19788 FUNC symbols entirely. */
19789 switch (ELF_ST_TYPE (sym->st_info))
19790 {
c799a79d 19791 case STT_OBJECT:
6f156d7a 19792 case STT_FILE:
c799a79d 19793 saved_sym = sym;
6f156d7a
NC
19794 if (sym->st_size)
19795 {
19796 /* If the symbol has a size associated
19797 with it then we can stop searching. */
fd486f32 19798 sym = ba_cache.symtab + ba_cache.nsyms;
6f156d7a 19799 }
c799a79d 19800 continue;
9ef920e9 19801
c799a79d
NC
19802 case STT_FUNC:
19803 /* Ignore function symbols. */
19804 continue;
19805
19806 default:
19807 break;
19808 }
19809
19810 switch (ELF_ST_BIND (sym->st_info))
9ef920e9 19811 {
c799a79d
NC
19812 case STB_GLOBAL:
19813 if (saved_sym == NULL
19814 || ELF_ST_TYPE (saved_sym->st_info) != STT_OBJECT)
19815 saved_sym = sym;
19816 break;
c871dade 19817
c799a79d
NC
19818 case STB_LOCAL:
19819 if (saved_sym == NULL)
19820 saved_sym = sym;
19821 break;
19822
19823 default:
9ef920e9
NC
19824 break;
19825 }
19826 }
c799a79d
NC
19827 else
19828 {
19829 if (ELF_ST_TYPE (sym->st_info) != STT_FUNC)
19830 continue;
19831
19832 saved_sym = sym;
19833 break;
19834 }
19835 }
19836
6f156d7a 19837 if (saved_sym && pname)
fd486f32 19838 * pname = ba_cache.strtab + saved_sym->st_name;
6f156d7a
NC
19839
19840 return saved_sym;
c799a79d
NC
19841}
19842
d20e98ab
NC
19843/* Returns true iff addr1 and addr2 are in the same section. */
19844
19845static bfd_boolean
19846same_section (Filedata * filedata, unsigned long addr1, unsigned long addr2)
19847{
19848 Elf_Internal_Shdr * a1;
19849 Elf_Internal_Shdr * a2;
19850
19851 a1 = find_section_by_address (filedata, addr1);
19852 a2 = find_section_by_address (filedata, addr2);
9abca702 19853
d20e98ab
NC
19854 return a1 == a2 && a1 != NULL;
19855}
19856
c799a79d 19857static bfd_boolean
dda8d76d
NC
19858print_gnu_build_attribute_description (Elf_Internal_Note * pnote,
19859 Filedata * filedata)
c799a79d 19860{
6f156d7a
NC
19861 static unsigned long global_offset = 0;
19862 static unsigned long global_end = 0;
19863 static unsigned long func_offset = 0;
19864 static unsigned long func_end = 0;
c871dade 19865
6f156d7a
NC
19866 Elf_Internal_Sym * sym;
19867 const char * name;
19868 unsigned long start;
19869 unsigned long end;
19870 bfd_boolean is_open_attr = pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN;
19871
19872 switch (pnote->descsz)
c799a79d 19873 {
6f156d7a
NC
19874 case 0:
19875 /* A zero-length description means that the range of
19876 the previous note of the same type should be used. */
c799a79d 19877 if (is_open_attr)
c871dade 19878 {
6f156d7a
NC
19879 if (global_end > global_offset)
19880 printf (_(" Applies to region from %#lx to %#lx\n"),
19881 global_offset, global_end);
19882 else
19883 printf (_(" Applies to region from %#lx\n"), global_offset);
c799a79d
NC
19884 }
19885 else
19886 {
6f156d7a
NC
19887 if (func_end > func_offset)
19888 printf (_(" Applies to region from %#lx to %#lx\n"), func_offset, func_end);
19889 else
19890 printf (_(" Applies to region from %#lx\n"), func_offset);
c871dade 19891 }
6f156d7a 19892 return TRUE;
9ef920e9 19893
6f156d7a
NC
19894 case 4:
19895 start = byte_get ((unsigned char *) pnote->descdata, 4);
19896 end = 0;
19897 break;
19898
19899 case 8:
19900 if (is_32bit_elf)
19901 {
19902 /* FIXME: We should check that version 3+ notes are being used here... */
19903 start = byte_get ((unsigned char *) pnote->descdata, 4);
19904 end = byte_get ((unsigned char *) pnote->descdata + 4, 4);
19905 }
19906 else
19907 {
19908 start = byte_get ((unsigned char *) pnote->descdata, 8);
19909 end = 0;
19910 }
19911 break;
19912
19913 case 16:
19914 start = byte_get ((unsigned char *) pnote->descdata, 8);
19915 end = byte_get ((unsigned char *) pnote->descdata + 8, 8);
19916 break;
9abca702 19917
6f156d7a 19918 default:
c799a79d
NC
19919 error (_(" <invalid description size: %lx>\n"), pnote->descsz);
19920 printf (_(" <invalid descsz>"));
19921 return FALSE;
19922 }
19923
6f156d7a
NC
19924 name = NULL;
19925 sym = get_symbol_for_build_attribute (filedata, start, is_open_attr, & name);
8fd75781
NC
19926 /* As of version 5 of the annobin plugin, filename symbols are biased by 2
19927 in order to avoid them being confused with the start address of the
19928 first function in the file... */
19929 if (sym == NULL && is_open_attr)
19930 sym = get_symbol_for_build_attribute (filedata, start + 2, is_open_attr,
19931 & name);
6f156d7a
NC
19932
19933 if (end == 0 && sym != NULL && sym->st_size > 0)
19934 end = start + sym->st_size;
c799a79d
NC
19935
19936 if (is_open_attr)
19937 {
d20e98ab
NC
19938 /* FIXME: Need to properly allow for section alignment.
19939 16 is just the alignment used on x86_64. */
19940 if (global_end > 0
19941 && start > BFD_ALIGN (global_end, 16)
19942 /* Build notes are not guaranteed to be organised in order of
19943 increasing address, but we should find the all of the notes
19944 for one section in the same place. */
19945 && same_section (filedata, start, global_end))
6f156d7a
NC
19946 warn (_("Gap in build notes detected from %#lx to %#lx\n"),
19947 global_end + 1, start - 1);
19948
19949 printf (_(" Applies to region from %#lx"), start);
19950 global_offset = start;
19951
19952 if (end)
19953 {
19954 printf (_(" to %#lx"), end);
19955 global_end = end;
19956 }
c799a79d
NC
19957 }
19958 else
19959 {
6f156d7a
NC
19960 printf (_(" Applies to region from %#lx"), start);
19961 func_offset = start;
19962
19963 if (end)
19964 {
19965 printf (_(" to %#lx"), end);
19966 func_end = end;
19967 }
c799a79d
NC
19968 }
19969
6f156d7a
NC
19970 if (sym && name)
19971 printf (_(" (%s)"), name);
19972
19973 printf ("\n");
19974 return TRUE;
9ef920e9
NC
19975}
19976
19977static bfd_boolean
19978print_gnu_build_attribute_name (Elf_Internal_Note * pnote)
19979{
1d15e434
NC
19980 static const char string_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_STRING, 0 };
19981 static const char number_expected [2] = { GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC, 0 };
19982 static const char bool_expected [3] = { GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE, GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE, 0 };
9ef920e9
NC
19983 char name_type;
19984 char name_attribute;
1d15e434 19985 const char * expected_types;
9ef920e9
NC
19986 const char * name = pnote->namedata;
19987 const char * text;
88305e1b 19988 signed int left;
9ef920e9
NC
19989
19990 if (name == NULL || pnote->namesz < 2)
19991 {
19992 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
7296a62a 19993 print_symbol (-20, _(" <corrupt name>"));
9ef920e9
NC
19994 return FALSE;
19995 }
19996
6f156d7a
NC
19997 if (do_wide)
19998 left = 28;
19999 else
20000 left = 20;
88305e1b
NC
20001
20002 /* Version 2 of the spec adds a "GA" prefix to the name field. */
20003 if (name[0] == 'G' && name[1] == 'A')
20004 {
6f156d7a
NC
20005 if (pnote->namesz < 4)
20006 {
20007 error (_("corrupt name field in GNU build attribute note: size = %ld\n"), pnote->namesz);
20008 print_symbol (-20, _(" <corrupt name>"));
20009 return FALSE;
20010 }
20011
88305e1b
NC
20012 printf ("GA");
20013 name += 2;
20014 left -= 2;
20015 }
20016
9ef920e9
NC
20017 switch ((name_type = * name))
20018 {
20019 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20020 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20021 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20022 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20023 printf ("%c", * name);
88305e1b 20024 left --;
9ef920e9
NC
20025 break;
20026 default:
20027 error (_("unrecognised attribute type in name field: %d\n"), name_type);
20028 print_symbol (-20, _("<unknown name type>"));
20029 return FALSE;
20030 }
20031
9ef920e9
NC
20032 ++ name;
20033 text = NULL;
20034
20035 switch ((name_attribute = * name))
20036 {
20037 case GNU_BUILD_ATTRIBUTE_VERSION:
20038 text = _("<version>");
1d15e434 20039 expected_types = string_expected;
9ef920e9
NC
20040 ++ name;
20041 break;
20042 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20043 text = _("<stack prot>");
75d7d298 20044 expected_types = "!+*";
9ef920e9
NC
20045 ++ name;
20046 break;
20047 case GNU_BUILD_ATTRIBUTE_RELRO:
20048 text = _("<relro>");
1d15e434 20049 expected_types = bool_expected;
9ef920e9
NC
20050 ++ name;
20051 break;
20052 case GNU_BUILD_ATTRIBUTE_STACK_SIZE:
20053 text = _("<stack size>");
1d15e434 20054 expected_types = number_expected;
9ef920e9
NC
20055 ++ name;
20056 break;
20057 case GNU_BUILD_ATTRIBUTE_TOOL:
20058 text = _("<tool>");
1d15e434 20059 expected_types = string_expected;
9ef920e9
NC
20060 ++ name;
20061 break;
20062 case GNU_BUILD_ATTRIBUTE_ABI:
20063 text = _("<ABI>");
20064 expected_types = "$*";
20065 ++ name;
20066 break;
20067 case GNU_BUILD_ATTRIBUTE_PIC:
20068 text = _("<PIC>");
1d15e434 20069 expected_types = number_expected;
9ef920e9
NC
20070 ++ name;
20071 break;
a8be5506
NC
20072 case GNU_BUILD_ATTRIBUTE_SHORT_ENUM:
20073 text = _("<short enum>");
1d15e434 20074 expected_types = bool_expected;
a8be5506
NC
20075 ++ name;
20076 break;
9ef920e9
NC
20077 default:
20078 if (ISPRINT (* name))
20079 {
20080 int len = strnlen (name, pnote->namesz - (name - pnote->namedata)) + 1;
20081
20082 if (len > left && ! do_wide)
20083 len = left;
75d7d298 20084 printf ("%.*s:", len, name);
9ef920e9 20085 left -= len;
0dd6ae21 20086 name += len;
9ef920e9
NC
20087 }
20088 else
20089 {
3e6b6445 20090 static char tmpbuf [128];
88305e1b 20091
3e6b6445
NC
20092 error (_("unrecognised byte in name field: %d\n"), * name);
20093 sprintf (tmpbuf, _("<unknown:_%d>"), * name);
20094 text = tmpbuf;
20095 name ++;
9ef920e9
NC
20096 }
20097 expected_types = "*$!+";
20098 break;
20099 }
20100
20101 if (text)
88305e1b 20102 left -= printf ("%s", text);
9ef920e9
NC
20103
20104 if (strchr (expected_types, name_type) == NULL)
75d7d298 20105 warn (_("attribute does not have an expected type (%c)\n"), name_type);
9ef920e9
NC
20106
20107 if ((unsigned long)(name - pnote->namedata) > pnote->namesz)
20108 {
20109 error (_("corrupt name field: namesz: %lu but parsing gets to %ld\n"),
20110 (unsigned long) pnote->namesz,
20111 (long) (name - pnote->namedata));
20112 return FALSE;
20113 }
20114
20115 if (left < 1 && ! do_wide)
20116 return TRUE;
20117
20118 switch (name_type)
20119 {
20120 case GNU_BUILD_ATTRIBUTE_TYPE_NUMERIC:
20121 {
b06b2c92 20122 unsigned int bytes;
ddef72cd
NC
20123 unsigned long long val = 0;
20124 unsigned int shift = 0;
20125 char * decoded = NULL;
20126
b06b2c92
NC
20127 bytes = pnote->namesz - (name - pnote->namedata);
20128 if (bytes > 0)
20129 /* The -1 is because the name field is always 0 terminated, and we
20130 want to be able to ensure that the shift in the while loop below
20131 will not overflow. */
20132 -- bytes;
20133
ddef72cd
NC
20134 if (bytes > sizeof (val))
20135 {
3e6b6445
NC
20136 error (_("corrupt numeric name field: too many bytes in the value: %x\n"),
20137 bytes);
20138 bytes = sizeof (val);
ddef72cd 20139 }
3e6b6445
NC
20140 /* We do not bother to warn if bytes == 0 as this can
20141 happen with some early versions of the gcc plugin. */
9ef920e9
NC
20142
20143 while (bytes --)
20144 {
54b8331d 20145 unsigned long long byte = *name++ & 0xff;
79a964dc
NC
20146
20147 val |= byte << shift;
9ef920e9
NC
20148 shift += 8;
20149 }
20150
75d7d298 20151 switch (name_attribute)
9ef920e9 20152 {
75d7d298 20153 case GNU_BUILD_ATTRIBUTE_PIC:
9ef920e9
NC
20154 switch (val)
20155 {
75d7d298
NC
20156 case 0: decoded = "static"; break;
20157 case 1: decoded = "pic"; break;
20158 case 2: decoded = "PIC"; break;
20159 case 3: decoded = "pie"; break;
20160 case 4: decoded = "PIE"; break;
20161 default: break;
9ef920e9 20162 }
75d7d298
NC
20163 break;
20164 case GNU_BUILD_ATTRIBUTE_STACK_PROT:
20165 switch (val)
9ef920e9 20166 {
75d7d298
NC
20167 /* Based upon the SPCT_FLAG_xxx enum values in gcc/cfgexpand.c. */
20168 case 0: decoded = "off"; break;
20169 case 1: decoded = "on"; break;
20170 case 2: decoded = "all"; break;
20171 case 3: decoded = "strong"; break;
20172 case 4: decoded = "explicit"; break;
20173 default: break;
9ef920e9 20174 }
75d7d298
NC
20175 break;
20176 default:
20177 break;
9ef920e9
NC
20178 }
20179
75d7d298 20180 if (decoded != NULL)
3e6b6445
NC
20181 {
20182 print_symbol (-left, decoded);
20183 left = 0;
20184 }
20185 else if (val == 0)
20186 {
20187 printf ("0x0");
20188 left -= 3;
20189 }
9ef920e9 20190 else
75d7d298
NC
20191 {
20192 if (do_wide)
ddef72cd 20193 left -= printf ("0x%llx", val);
75d7d298 20194 else
ddef72cd 20195 left -= printf ("0x%-.*llx", left, val);
75d7d298 20196 }
9ef920e9
NC
20197 }
20198 break;
20199 case GNU_BUILD_ATTRIBUTE_TYPE_STRING:
20200 left -= print_symbol (- left, name);
20201 break;
20202 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_TRUE:
20203 left -= print_symbol (- left, "true");
20204 break;
20205 case GNU_BUILD_ATTRIBUTE_TYPE_BOOL_FALSE:
20206 left -= print_symbol (- left, "false");
20207 break;
20208 }
20209
20210 if (do_wide && left > 0)
20211 printf ("%-*s", left, " ");
9abca702 20212
9ef920e9
NC
20213 return TRUE;
20214}
20215
6d118b09
NC
20216/* Note that by the ELF standard, the name field is already null byte
20217 terminated, and namesz includes the terminating null byte.
20218 I.E. the value of namesz for the name "FSF" is 4.
20219
e3c8793a 20220 If the value of namesz is zero, there is no name present. */
9ef920e9 20221
32ec8896 20222static bfd_boolean
9ef920e9 20223process_note (Elf_Internal_Note * pnote,
dda8d76d 20224 Filedata * filedata)
779fe533 20225{
2cf0635d
NC
20226 const char * name = pnote->namesz ? pnote->namedata : "(NONE)";
20227 const char * nt;
9437c45b
JT
20228
20229 if (pnote->namesz == 0)
1ec5cd37
NC
20230 /* If there is no note name, then use the default set of
20231 note type strings. */
dda8d76d 20232 nt = get_note_type (filedata, pnote->type);
1ec5cd37 20233
1118d252
RM
20234 else if (const_strneq (pnote->namedata, "GNU"))
20235 /* GNU-specific object file notes. */
20236 nt = get_gnu_elf_note_type (pnote->type);
f4ddf30f
JB
20237
20238 else if (const_strneq (pnote->namedata, "FreeBSD"))
20239 /* FreeBSD-specific core file notes. */
dda8d76d 20240 nt = get_freebsd_elfcore_note_type (filedata, pnote->type);
1118d252 20241
0112cd26 20242 else if (const_strneq (pnote->namedata, "NetBSD-CORE"))
1ec5cd37 20243 /* NetBSD-specific core file notes. */
dda8d76d 20244 nt = get_netbsd_elfcore_note_type (filedata, pnote->type);
1ec5cd37 20245
c6056a74
SF
20246 else if (const_strneq (pnote->namedata, "NetBSD"))
20247 /* NetBSD-specific core file notes. */
20248 return process_netbsd_elf_note (pnote);
20249
9abca702
CZ
20250 else if (const_strneq (pnote->namedata, "PaX"))
20251 /* NetBSD-specific core file notes. */
20252 return process_netbsd_elf_note (pnote);
20253
b15fa79e
AM
20254 else if (strneq (pnote->namedata, "SPU/", 4))
20255 {
20256 /* SPU-specific core file notes. */
20257 nt = pnote->namedata + 4;
20258 name = "SPU";
20259 }
20260
00e98fc7
TG
20261 else if (const_strneq (pnote->namedata, "IPF/VMS"))
20262 /* VMS/ia64-specific file notes. */
20263 nt = get_ia64_vms_note_type (pnote->type);
20264
70616151
TT
20265 else if (const_strneq (pnote->namedata, "stapsdt"))
20266 nt = get_stapsdt_note_type (pnote->type);
20267
9437c45b 20268 else
1ec5cd37
NC
20269 /* Don't recognize this note name; just use the default set of
20270 note type strings. */
dda8d76d 20271 nt = get_note_type (filedata, pnote->type);
9437c45b 20272
1449284b 20273 printf (" ");
9ef920e9 20274
483767a3
AM
20275 if (((const_strneq (pnote->namedata, "GA")
20276 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20277 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20278 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20279 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
9ef920e9
NC
20280 print_gnu_build_attribute_name (pnote);
20281 else
20282 print_symbol (-20, name);
20283
20284 if (do_wide)
20285 printf (" 0x%08lx\t%s\t", pnote->descsz, nt);
20286 else
20287 printf (" 0x%08lx\t%s\n", pnote->descsz, nt);
00e98fc7
TG
20288
20289 if (const_strneq (pnote->namedata, "IPF/VMS"))
20290 return print_ia64_vms_note (pnote);
664f90a3 20291 else if (const_strneq (pnote->namedata, "GNU"))
dda8d76d 20292 return print_gnu_note (filedata, pnote);
c6a9fc58
TT
20293 else if (const_strneq (pnote->namedata, "stapsdt"))
20294 return print_stapsdt_note (pnote);
9ece1fa9
TT
20295 else if (const_strneq (pnote->namedata, "CORE"))
20296 return print_core_note (pnote);
483767a3
AM
20297 else if (((const_strneq (pnote->namedata, "GA")
20298 && strchr ("*$!+", pnote->namedata[2]) != NULL)
20299 || strchr ("*$!+", pnote->namedata[0]) != NULL)
20300 && (pnote->type == NT_GNU_BUILD_ATTRIBUTE_OPEN
20301 || pnote->type == NT_GNU_BUILD_ATTRIBUTE_FUNC))
dda8d76d 20302 return print_gnu_build_attribute_description (pnote, filedata);
779fe533 20303
9ef920e9 20304 if (pnote->descsz)
1449284b
NC
20305 {
20306 unsigned long i;
20307
20308 printf (_(" description data: "));
20309 for (i = 0; i < pnote->descsz; i++)
178d8719 20310 printf ("%02x ", pnote->descdata[i] & 0xff);
04ac15ab
AS
20311 if (!do_wide)
20312 printf ("\n");
1449284b
NC
20313 }
20314
9ef920e9
NC
20315 if (do_wide)
20316 printf ("\n");
20317
32ec8896 20318 return TRUE;
1449284b 20319}
6d118b09 20320
32ec8896 20321static bfd_boolean
dda8d76d
NC
20322process_notes_at (Filedata * filedata,
20323 Elf_Internal_Shdr * section,
20324 bfd_vma offset,
82ed9683
L
20325 bfd_vma length,
20326 bfd_vma align)
779fe533 20327{
2cf0635d
NC
20328 Elf_External_Note * pnotes;
20329 Elf_External_Note * external;
4dff97b2
NC
20330 char * end;
20331 bfd_boolean res = TRUE;
103f02d3 20332
779fe533 20333 if (length <= 0)
32ec8896 20334 return FALSE;
103f02d3 20335
1449284b
NC
20336 if (section)
20337 {
dda8d76d 20338 pnotes = (Elf_External_Note *) get_section_contents (section, filedata);
1449284b 20339 if (pnotes)
32ec8896 20340 {
dda8d76d 20341 if (! apply_relocations (filedata, section, (unsigned char *) pnotes, length, NULL, NULL))
f761cb13
AM
20342 {
20343 free (pnotes);
20344 return FALSE;
20345 }
32ec8896 20346 }
1449284b
NC
20347 }
20348 else
82ed9683 20349 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
1449284b 20350 _("notes"));
4dff97b2 20351
dd24e3da 20352 if (pnotes == NULL)
32ec8896 20353 return FALSE;
779fe533 20354
103f02d3 20355 external = pnotes;
103f02d3 20356
1449284b 20357 if (section)
dda8d76d 20358 printf (_("\nDisplaying notes found in: %s\n"), printable_section_name (filedata, section));
1449284b
NC
20359 else
20360 printf (_("\nDisplaying notes found at file offset 0x%08lx with length 0x%08lx:\n"),
20361 (unsigned long) offset, (unsigned long) length);
20362
82ed9683
L
20363 /* NB: Some note sections may have alignment value of 0 or 1. gABI
20364 specifies that notes should be aligned to 4 bytes in 32-bit
20365 objects and to 8 bytes in 64-bit objects. As a Linux extension,
20366 we also support 4 byte alignment in 64-bit objects. If section
20367 alignment is less than 4, we treate alignment as 4 bytes. */
20368 if (align < 4)
20369 align = 4;
20370 else if (align != 4 && align != 8)
20371 {
20372 warn (_("Corrupt note: alignment %ld, expecting 4 or 8\n"),
20373 (long) align);
a788aedd 20374 free (pnotes);
82ed9683
L
20375 return FALSE;
20376 }
20377
dbe15e4e 20378 printf (_(" %-20s %-10s\tDescription\n"), _("Owner"), _("Data size"));
103f02d3 20379
c8071705
NC
20380 end = (char *) pnotes + length;
20381 while ((char *) external < end)
779fe533 20382 {
b34976b6 20383 Elf_Internal_Note inote;
15b42fb0 20384 size_t min_notesz;
4dff97b2 20385 char * next;
2cf0635d 20386 char * temp = NULL;
c8071705 20387 size_t data_remaining = end - (char *) external;
6d118b09 20388
dda8d76d 20389 if (!is_ia64_vms (filedata))
15b42fb0 20390 {
9dd3a467
NC
20391 /* PR binutils/15191
20392 Make sure that there is enough data to read. */
15b42fb0
AM
20393 min_notesz = offsetof (Elf_External_Note, name);
20394 if (data_remaining < min_notesz)
9dd3a467 20395 {
d3a49aa8
AM
20396 warn (ngettext ("Corrupt note: only %ld byte remains, "
20397 "not enough for a full note\n",
20398 "Corrupt note: only %ld bytes remain, "
20399 "not enough for a full note\n",
20400 data_remaining),
20401 (long) data_remaining);
9dd3a467
NC
20402 break;
20403 }
5396a86e
AM
20404 data_remaining -= min_notesz;
20405
15b42fb0
AM
20406 inote.type = BYTE_GET (external->type);
20407 inote.namesz = BYTE_GET (external->namesz);
20408 inote.namedata = external->name;
20409 inote.descsz = BYTE_GET (external->descsz);
276da9b3 20410 inote.descdata = ((char *) external
4dff97b2 20411 + ELF_NOTE_DESC_OFFSET (inote.namesz, align));
15b42fb0 20412 inote.descpos = offset + (inote.descdata - (char *) pnotes);
276da9b3 20413 next = ((char *) external
4dff97b2 20414 + ELF_NOTE_NEXT_OFFSET (inote.namesz, inote.descsz, align));
15b42fb0 20415 }
00e98fc7 20416 else
15b42fb0
AM
20417 {
20418 Elf64_External_VMS_Note *vms_external;
00e98fc7 20419
9dd3a467
NC
20420 /* PR binutils/15191
20421 Make sure that there is enough data to read. */
15b42fb0
AM
20422 min_notesz = offsetof (Elf64_External_VMS_Note, name);
20423 if (data_remaining < min_notesz)
9dd3a467 20424 {
d3a49aa8
AM
20425 warn (ngettext ("Corrupt note: only %ld byte remains, "
20426 "not enough for a full note\n",
20427 "Corrupt note: only %ld bytes remain, "
20428 "not enough for a full note\n",
20429 data_remaining),
20430 (long) data_remaining);
9dd3a467
NC
20431 break;
20432 }
5396a86e 20433 data_remaining -= min_notesz;
3e55a963 20434
15b42fb0
AM
20435 vms_external = (Elf64_External_VMS_Note *) external;
20436 inote.type = BYTE_GET (vms_external->type);
20437 inote.namesz = BYTE_GET (vms_external->namesz);
20438 inote.namedata = vms_external->name;
20439 inote.descsz = BYTE_GET (vms_external->descsz);
20440 inote.descdata = inote.namedata + align_power (inote.namesz, 3);
20441 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20442 next = inote.descdata + align_power (inote.descsz, 3);
20443 }
20444
5396a86e
AM
20445 /* PR 17531: file: 3443835e. */
20446 /* PR 17531: file: id:000000,sig:11,src:006986,op:havoc,rep:4. */
20447 if ((size_t) (inote.descdata - inote.namedata) < inote.namesz
20448 || (size_t) (inote.descdata - inote.namedata) > data_remaining
20449 || (size_t) (next - inote.descdata) < inote.descsz
20450 || ((size_t) (next - inote.descdata)
20451 > data_remaining - (size_t) (inote.descdata - inote.namedata)))
3e55a963 20452 {
15b42fb0 20453 warn (_("note with invalid namesz and/or descsz found at offset 0x%lx\n"),
0af1713e 20454 (unsigned long) ((char *) external - (char *) pnotes));
4dff97b2
NC
20455 warn (_(" type: 0x%lx, namesize: 0x%08lx, descsize: 0x%08lx, alignment: %u\n"),
20456 inote.type, inote.namesz, inote.descsz, (int) align);
3e55a963
NC
20457 break;
20458 }
20459
15b42fb0 20460 external = (Elf_External_Note *) next;
dd24e3da 20461
6d118b09
NC
20462 /* Verify that name is null terminated. It appears that at least
20463 one version of Linux (RedHat 6.0) generates corefiles that don't
20464 comply with the ELF spec by failing to include the null byte in
20465 namesz. */
18344509 20466 if (inote.namesz > 0 && inote.namedata[inote.namesz - 1] != '\0')
6d118b09 20467 {
5396a86e 20468 if ((size_t) (inote.descdata - inote.namedata) == inote.namesz)
6d118b09 20469 {
5396a86e
AM
20470 temp = (char *) malloc (inote.namesz + 1);
20471 if (temp == NULL)
20472 {
20473 error (_("Out of memory allocating space for inote name\n"));
20474 res = FALSE;
20475 break;
20476 }
76da6bbe 20477
5396a86e
AM
20478 memcpy (temp, inote.namedata, inote.namesz);
20479 inote.namedata = temp;
20480 }
20481 inote.namedata[inote.namesz] = 0;
6d118b09
NC
20482 }
20483
dda8d76d 20484 if (! process_note (& inote, filedata))
6b4bf3bc 20485 res = FALSE;
103f02d3 20486
9db70fc3
AM
20487 free (temp);
20488 temp = NULL;
779fe533
NC
20489 }
20490
20491 free (pnotes);
103f02d3 20492
779fe533
NC
20493 return res;
20494}
20495
32ec8896 20496static bfd_boolean
dda8d76d 20497process_corefile_note_segments (Filedata * filedata)
779fe533 20498{
2cf0635d 20499 Elf_Internal_Phdr * segment;
b34976b6 20500 unsigned int i;
32ec8896 20501 bfd_boolean res = TRUE;
103f02d3 20502
dda8d76d 20503 if (! get_program_headers (filedata))
6b4bf3bc 20504 return TRUE;
103f02d3 20505
dda8d76d
NC
20506 for (i = 0, segment = filedata->program_headers;
20507 i < filedata->file_header.e_phnum;
b34976b6 20508 i++, segment++)
779fe533
NC
20509 {
20510 if (segment->p_type == PT_NOTE)
dda8d76d 20511 if (! process_notes_at (filedata, NULL,
32ec8896 20512 (bfd_vma) segment->p_offset,
82ed9683
L
20513 (bfd_vma) segment->p_filesz,
20514 (bfd_vma) segment->p_align))
32ec8896 20515 res = FALSE;
779fe533 20516 }
103f02d3 20517
779fe533
NC
20518 return res;
20519}
20520
32ec8896 20521static bfd_boolean
dda8d76d 20522process_v850_notes (Filedata * filedata, bfd_vma offset, bfd_vma length)
685080f2
NC
20523{
20524 Elf_External_Note * pnotes;
20525 Elf_External_Note * external;
c8071705 20526 char * end;
32ec8896 20527 bfd_boolean res = TRUE;
685080f2
NC
20528
20529 if (length <= 0)
32ec8896 20530 return FALSE;
685080f2 20531
dda8d76d 20532 pnotes = (Elf_External_Note *) get_data (NULL, filedata, offset, 1, length,
685080f2
NC
20533 _("v850 notes"));
20534 if (pnotes == NULL)
32ec8896 20535 return FALSE;
685080f2
NC
20536
20537 external = pnotes;
c8071705 20538 end = (char*) pnotes + length;
685080f2
NC
20539
20540 printf (_("\nDisplaying contents of Renesas V850 notes section at offset 0x%lx with length 0x%lx:\n"),
20541 (unsigned long) offset, (unsigned long) length);
20542
c8071705 20543 while ((char *) external + sizeof (Elf_External_Note) < end)
685080f2
NC
20544 {
20545 Elf_External_Note * next;
20546 Elf_Internal_Note inote;
20547
20548 inote.type = BYTE_GET (external->type);
20549 inote.namesz = BYTE_GET (external->namesz);
20550 inote.namedata = external->name;
20551 inote.descsz = BYTE_GET (external->descsz);
20552 inote.descdata = inote.namedata + align_power (inote.namesz, 2);
20553 inote.descpos = offset + (inote.descdata - (char *) pnotes);
20554
c8071705
NC
20555 if (inote.descdata < (char *) pnotes || inote.descdata >= end)
20556 {
20557 warn (_("Corrupt note: name size is too big: %lx\n"), inote.namesz);
20558 inote.descdata = inote.namedata;
20559 inote.namesz = 0;
20560 }
20561
685080f2
NC
20562 next = (Elf_External_Note *) (inote.descdata + align_power (inote.descsz, 2));
20563
c8071705 20564 if ( ((char *) next > end)
685080f2
NC
20565 || ((char *) next < (char *) pnotes))
20566 {
20567 warn (_("corrupt descsz found in note at offset 0x%lx\n"),
20568 (unsigned long) ((char *) external - (char *) pnotes));
20569 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20570 inote.type, inote.namesz, inote.descsz);
20571 break;
20572 }
20573
20574 external = next;
20575
20576 /* Prevent out-of-bounds indexing. */
c8071705 20577 if ( inote.namedata + inote.namesz > end
685080f2
NC
20578 || inote.namedata + inote.namesz < inote.namedata)
20579 {
20580 warn (_("corrupt namesz found in note at offset 0x%lx\n"),
20581 (unsigned long) ((char *) external - (char *) pnotes));
20582 warn (_(" type: 0x%lx, namesize: 0x%lx, descsize: 0x%lx\n"),
20583 inote.type, inote.namesz, inote.descsz);
20584 break;
20585 }
20586
20587 printf (" %s: ", get_v850_elf_note_type (inote.type));
20588
20589 if (! print_v850_note (& inote))
20590 {
32ec8896 20591 res = FALSE;
685080f2
NC
20592 printf ("<corrupt sizes: namesz: %lx, descsz: %lx>\n",
20593 inote.namesz, inote.descsz);
20594 }
20595 }
20596
20597 free (pnotes);
20598
20599 return res;
20600}
20601
32ec8896 20602static bfd_boolean
dda8d76d 20603process_note_sections (Filedata * filedata)
1ec5cd37 20604{
2cf0635d 20605 Elf_Internal_Shdr * section;
1ec5cd37 20606 unsigned long i;
32ec8896
NC
20607 unsigned int n = 0;
20608 bfd_boolean res = TRUE;
1ec5cd37 20609
dda8d76d
NC
20610 for (i = 0, section = filedata->section_headers;
20611 i < filedata->file_header.e_shnum && section != NULL;
1ec5cd37 20612 i++, section++)
685080f2
NC
20613 {
20614 if (section->sh_type == SHT_NOTE)
20615 {
dda8d76d 20616 if (! process_notes_at (filedata, section,
32ec8896 20617 (bfd_vma) section->sh_offset,
82ed9683
L
20618 (bfd_vma) section->sh_size,
20619 (bfd_vma) section->sh_addralign))
32ec8896 20620 res = FALSE;
685080f2
NC
20621 n++;
20622 }
20623
dda8d76d
NC
20624 if (( filedata->file_header.e_machine == EM_V800
20625 || filedata->file_header.e_machine == EM_V850
20626 || filedata->file_header.e_machine == EM_CYGNUS_V850)
685080f2
NC
20627 && section->sh_type == SHT_RENESAS_INFO)
20628 {
dda8d76d 20629 if (! process_v850_notes (filedata,
32ec8896
NC
20630 (bfd_vma) section->sh_offset,
20631 (bfd_vma) section->sh_size))
20632 res = FALSE;
685080f2
NC
20633 n++;
20634 }
20635 }
df565f32
NC
20636
20637 if (n == 0)
20638 /* Try processing NOTE segments instead. */
dda8d76d 20639 return process_corefile_note_segments (filedata);
1ec5cd37
NC
20640
20641 return res;
20642}
20643
32ec8896 20644static bfd_boolean
dda8d76d 20645process_notes (Filedata * filedata)
779fe533
NC
20646{
20647 /* If we have not been asked to display the notes then do nothing. */
20648 if (! do_notes)
32ec8896 20649 return TRUE;
103f02d3 20650
dda8d76d
NC
20651 if (filedata->file_header.e_type != ET_CORE)
20652 return process_note_sections (filedata);
103f02d3 20653
779fe533 20654 /* No program headers means no NOTE segment. */
dda8d76d
NC
20655 if (filedata->file_header.e_phnum > 0)
20656 return process_corefile_note_segments (filedata);
779fe533 20657
1ec5cd37 20658 printf (_("No note segments present in the core file.\n"));
32ec8896 20659 return TRUE;
779fe533
NC
20660}
20661
60abdbed
NC
20662static unsigned char *
20663display_public_gnu_attributes (unsigned char * start,
20664 const unsigned char * const end)
20665{
20666 printf (_(" Unknown GNU attribute: %s\n"), start);
20667
20668 start += strnlen ((char *) start, end - start);
20669 display_raw_attribute (start, end);
20670
20671 return (unsigned char *) end;
20672}
20673
20674static unsigned char *
20675display_generic_attribute (unsigned char * start,
20676 unsigned int tag,
20677 const unsigned char * const end)
20678{
20679 if (tag == 0)
20680 return (unsigned char *) end;
20681
20682 return display_tag_value (tag, start, end);
20683}
20684
32ec8896 20685static bfd_boolean
dda8d76d 20686process_arch_specific (Filedata * filedata)
252b5132 20687{
a952a375 20688 if (! do_arch)
32ec8896 20689 return TRUE;
a952a375 20690
dda8d76d 20691 switch (filedata->file_header.e_machine)
252b5132 20692 {
53a346d8
CZ
20693 case EM_ARC:
20694 case EM_ARC_COMPACT:
20695 case EM_ARC_COMPACT2:
dda8d76d 20696 return process_attributes (filedata, "ARC", SHT_ARC_ATTRIBUTES,
53a346d8
CZ
20697 display_arc_attribute,
20698 display_generic_attribute);
11c1ff18 20699 case EM_ARM:
dda8d76d 20700 return process_attributes (filedata, "aeabi", SHT_ARM_ATTRIBUTES,
60abdbed
NC
20701 display_arm_attribute,
20702 display_generic_attribute);
20703
252b5132 20704 case EM_MIPS:
4fe85591 20705 case EM_MIPS_RS3_LE:
dda8d76d 20706 return process_mips_specific (filedata);
60abdbed
NC
20707
20708 case EM_MSP430:
dda8d76d 20709 return process_attributes (filedata, "mspabi", SHT_MSP430_ATTRIBUTES,
b0191216 20710 display_msp430_attribute,
c0ea7c52 20711 display_msp430_gnu_attribute);
60abdbed 20712
2dc8dd17
JW
20713 case EM_RISCV:
20714 return process_attributes (filedata, "riscv", SHT_RISCV_ATTRIBUTES,
20715 display_riscv_attribute,
20716 display_generic_attribute);
20717
35c08157 20718 case EM_NDS32:
dda8d76d 20719 return process_nds32_specific (filedata);
60abdbed 20720
85f7484a
PB
20721 case EM_68K:
20722 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
20723 display_m68k_gnu_attribute);
20724
34c8bcba 20725 case EM_PPC:
b82317dd 20726 case EM_PPC64:
dda8d76d 20727 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20728 display_power_gnu_attribute);
20729
643f7afb
AK
20730 case EM_S390:
20731 case EM_S390_OLD:
dda8d76d 20732 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20733 display_s390_gnu_attribute);
20734
9e8c70f9
DM
20735 case EM_SPARC:
20736 case EM_SPARC32PLUS:
20737 case EM_SPARCV9:
dda8d76d 20738 return process_attributes (filedata, NULL, SHT_GNU_ATTRIBUTES, NULL,
60abdbed
NC
20739 display_sparc_gnu_attribute);
20740
59e6276b 20741 case EM_TI_C6000:
dda8d76d 20742 return process_attributes (filedata, "c6xabi", SHT_C6000_ATTRIBUTES,
60abdbed
NC
20743 display_tic6x_attribute,
20744 display_generic_attribute);
20745
0861f561
CQ
20746 case EM_CSKY:
20747 return process_attributes (filedata, "csky", SHT_CSKY_ATTRIBUTES,
20748 display_csky_attribute, NULL);
20749
252b5132 20750 default:
dda8d76d 20751 return process_attributes (filedata, "gnu", SHT_GNU_ATTRIBUTES,
60abdbed
NC
20752 display_public_gnu_attributes,
20753 display_generic_attribute);
252b5132 20754 }
252b5132
RH
20755}
20756
32ec8896 20757static bfd_boolean
dda8d76d 20758get_file_header (Filedata * filedata)
252b5132 20759{
9ea033b2 20760 /* Read in the identity array. */
dda8d76d 20761 if (fread (filedata->file_header.e_ident, EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20762 return FALSE;
252b5132 20763
9ea033b2 20764 /* Determine how to read the rest of the header. */
dda8d76d 20765 switch (filedata->file_header.e_ident[EI_DATA])
9ea033b2 20766 {
1a0670f3
AM
20767 default:
20768 case ELFDATANONE:
adab8cdc
AO
20769 case ELFDATA2LSB:
20770 byte_get = byte_get_little_endian;
20771 byte_put = byte_put_little_endian;
20772 break;
20773 case ELFDATA2MSB:
20774 byte_get = byte_get_big_endian;
20775 byte_put = byte_put_big_endian;
20776 break;
9ea033b2
NC
20777 }
20778
20779 /* For now we only support 32 bit and 64 bit ELF files. */
dda8d76d 20780 is_32bit_elf = (filedata->file_header.e_ident[EI_CLASS] != ELFCLASS64);
9ea033b2
NC
20781
20782 /* Read in the rest of the header. */
20783 if (is_32bit_elf)
20784 {
20785 Elf32_External_Ehdr ehdr32;
252b5132 20786
dda8d76d 20787 if (fread (ehdr32.e_type, sizeof (ehdr32) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20788 return FALSE;
103f02d3 20789
dda8d76d
NC
20790 filedata->file_header.e_type = BYTE_GET (ehdr32.e_type);
20791 filedata->file_header.e_machine = BYTE_GET (ehdr32.e_machine);
20792 filedata->file_header.e_version = BYTE_GET (ehdr32.e_version);
20793 filedata->file_header.e_entry = BYTE_GET (ehdr32.e_entry);
20794 filedata->file_header.e_phoff = BYTE_GET (ehdr32.e_phoff);
20795 filedata->file_header.e_shoff = BYTE_GET (ehdr32.e_shoff);
20796 filedata->file_header.e_flags = BYTE_GET (ehdr32.e_flags);
20797 filedata->file_header.e_ehsize = BYTE_GET (ehdr32.e_ehsize);
20798 filedata->file_header.e_phentsize = BYTE_GET (ehdr32.e_phentsize);
20799 filedata->file_header.e_phnum = BYTE_GET (ehdr32.e_phnum);
20800 filedata->file_header.e_shentsize = BYTE_GET (ehdr32.e_shentsize);
20801 filedata->file_header.e_shnum = BYTE_GET (ehdr32.e_shnum);
20802 filedata->file_header.e_shstrndx = BYTE_GET (ehdr32.e_shstrndx);
9ea033b2 20803 }
252b5132 20804 else
9ea033b2
NC
20805 {
20806 Elf64_External_Ehdr ehdr64;
a952a375
NC
20807
20808 /* If we have been compiled with sizeof (bfd_vma) == 4, then
20809 we will not be able to cope with the 64bit data found in
20810 64 ELF files. Detect this now and abort before we start
50c2245b 20811 overwriting things. */
a952a375
NC
20812 if (sizeof (bfd_vma) < 8)
20813 {
e3c8793a
NC
20814 error (_("This instance of readelf has been built without support for a\n\
2081564 bit data type and so it cannot read 64 bit ELF files.\n"));
32ec8896 20816 return FALSE;
a952a375 20817 }
103f02d3 20818
dda8d76d 20819 if (fread (ehdr64.e_type, sizeof (ehdr64) - EI_NIDENT, 1, filedata->handle) != 1)
32ec8896 20820 return FALSE;
103f02d3 20821
dda8d76d
NC
20822 filedata->file_header.e_type = BYTE_GET (ehdr64.e_type);
20823 filedata->file_header.e_machine = BYTE_GET (ehdr64.e_machine);
20824 filedata->file_header.e_version = BYTE_GET (ehdr64.e_version);
20825 filedata->file_header.e_entry = BYTE_GET (ehdr64.e_entry);
20826 filedata->file_header.e_phoff = BYTE_GET (ehdr64.e_phoff);
20827 filedata->file_header.e_shoff = BYTE_GET (ehdr64.e_shoff);
20828 filedata->file_header.e_flags = BYTE_GET (ehdr64.e_flags);
20829 filedata->file_header.e_ehsize = BYTE_GET (ehdr64.e_ehsize);
20830 filedata->file_header.e_phentsize = BYTE_GET (ehdr64.e_phentsize);
20831 filedata->file_header.e_phnum = BYTE_GET (ehdr64.e_phnum);
20832 filedata->file_header.e_shentsize = BYTE_GET (ehdr64.e_shentsize);
20833 filedata->file_header.e_shnum = BYTE_GET (ehdr64.e_shnum);
20834 filedata->file_header.e_shstrndx = BYTE_GET (ehdr64.e_shstrndx);
9ea033b2 20835 }
252b5132 20836
dda8d76d 20837 if (filedata->file_header.e_shoff)
7ece0d85
JJ
20838 {
20839 /* There may be some extensions in the first section header. Don't
20840 bomb if we can't read it. */
20841 if (is_32bit_elf)
dda8d76d 20842 get_32bit_section_headers (filedata, TRUE);
7ece0d85 20843 else
dda8d76d 20844 get_64bit_section_headers (filedata, TRUE);
7ece0d85 20845 }
560f3c1c 20846
32ec8896 20847 return TRUE;
252b5132
RH
20848}
20849
dda8d76d
NC
20850static void
20851close_file (Filedata * filedata)
20852{
20853 if (filedata)
20854 {
20855 if (filedata->handle)
20856 fclose (filedata->handle);
20857 free (filedata);
20858 }
20859}
20860
20861void
20862close_debug_file (void * data)
20863{
20864 close_file ((Filedata *) data);
20865}
20866
20867static Filedata *
20868open_file (const char * pathname)
20869{
20870 struct stat statbuf;
20871 Filedata * filedata = NULL;
20872
20873 if (stat (pathname, & statbuf) < 0
20874 || ! S_ISREG (statbuf.st_mode))
20875 goto fail;
20876
20877 filedata = calloc (1, sizeof * filedata);
20878 if (filedata == NULL)
20879 goto fail;
20880
20881 filedata->handle = fopen (pathname, "rb");
20882 if (filedata->handle == NULL)
20883 goto fail;
20884
20885 filedata->file_size = (bfd_size_type) statbuf.st_size;
20886 filedata->file_name = pathname;
20887
20888 if (! get_file_header (filedata))
20889 goto fail;
20890
20891 if (filedata->file_header.e_shoff)
20892 {
20893 bfd_boolean res;
20894
20895 /* Read the section headers again, this time for real. */
20896 if (is_32bit_elf)
20897 res = get_32bit_section_headers (filedata, FALSE);
20898 else
20899 res = get_64bit_section_headers (filedata, FALSE);
20900
20901 if (!res)
20902 goto fail;
20903 }
20904
20905 return filedata;
20906
20907 fail:
20908 if (filedata)
20909 {
20910 if (filedata->handle)
20911 fclose (filedata->handle);
20912 free (filedata);
20913 }
20914 return NULL;
20915}
20916
20917void *
20918open_debug_file (const char * pathname)
20919{
20920 return open_file (pathname);
20921}
20922
fb52b2f4
NC
20923/* Process one ELF object file according to the command line options.
20924 This file may actually be stored in an archive. The file is
32ec8896
NC
20925 positioned at the start of the ELF object. Returns TRUE if no
20926 problems were encountered, FALSE otherwise. */
fb52b2f4 20927
32ec8896 20928static bfd_boolean
dda8d76d 20929process_object (Filedata * filedata)
252b5132 20930{
24841daa 20931 bfd_boolean have_separate_files;
252b5132 20932 unsigned int i;
2482f306 20933 bfd_boolean res;
252b5132 20934
dda8d76d 20935 if (! get_file_header (filedata))
252b5132 20936 {
dda8d76d 20937 error (_("%s: Failed to read file header\n"), filedata->file_name);
32ec8896 20938 return FALSE;
252b5132
RH
20939 }
20940
20941 /* Initialise per file variables. */
978c4450
AM
20942 for (i = ARRAY_SIZE (filedata->version_info); i--;)
20943 filedata->version_info[i] = 0;
252b5132 20944
978c4450
AM
20945 for (i = ARRAY_SIZE (filedata->dynamic_info); i--;)
20946 filedata->dynamic_info[i] = 0;
20947 filedata->dynamic_info_DT_GNU_HASH = 0;
20948 filedata->dynamic_info_DT_MIPS_XHASH = 0;
252b5132
RH
20949
20950 /* Process the file. */
20951 if (show_name)
dda8d76d 20952 printf (_("\nFile: %s\n"), filedata->file_name);
252b5132 20953
18bd398b
NC
20954 /* Initialise the dump_sects array from the cmdline_dump_sects array.
20955 Note we do this even if cmdline_dump_sects is empty because we
20956 must make sure that the dump_sets array is zeroed out before each
20957 object file is processed. */
6431e409
AM
20958 if (filedata->dump.num_dump_sects > cmdline.num_dump_sects)
20959 memset (filedata->dump.dump_sects, 0,
20960 filedata->dump.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20961
dda8d76d 20962 if (cmdline.num_dump_sects > 0)
18bd398b 20963 {
6431e409 20964 if (filedata->dump.num_dump_sects == 0)
18bd398b 20965 /* A sneaky way of allocating the dump_sects array. */
6431e409 20966 request_dump_bynumber (&filedata->dump, cmdline.num_dump_sects, 0);
18bd398b 20967
6431e409
AM
20968 assert (filedata->dump.num_dump_sects >= cmdline.num_dump_sects);
20969 memcpy (filedata->dump.dump_sects, cmdline.dump_sects,
20970 cmdline.num_dump_sects * sizeof (*filedata->dump.dump_sects));
18bd398b 20971 }
d70c5fc7 20972
dda8d76d 20973 if (! process_file_header (filedata))
32ec8896 20974 return FALSE;
252b5132 20975
dda8d76d 20976 if (! process_section_headers (filedata))
2f62977e 20977 {
32ec8896
NC
20978 /* Without loaded section headers we cannot process lots of things. */
20979 do_unwind = do_version = do_dump = do_arch = FALSE;
252b5132 20980
2f62977e 20981 if (! do_using_dynamic)
32ec8896 20982 do_syms = do_dyn_syms = do_reloc = FALSE;
2f62977e 20983 }
252b5132 20984
dda8d76d 20985 if (! process_section_groups (filedata))
32ec8896
NC
20986 /* Without loaded section groups we cannot process unwind. */
20987 do_unwind = FALSE;
d1f5c6e3 20988
2482f306
AM
20989 res = process_program_headers (filedata);
20990 if (res)
20991 res = process_dynamic_section (filedata);
252b5132 20992
dda8d76d 20993 if (! process_relocs (filedata))
32ec8896 20994 res = FALSE;
252b5132 20995
dda8d76d 20996 if (! process_unwind (filedata))
32ec8896 20997 res = FALSE;
4d6ed7c8 20998
dda8d76d 20999 if (! process_symbol_table (filedata))
32ec8896 21000 res = FALSE;
252b5132 21001
0f03783c
NC
21002 if (! process_lto_symbol_tables (filedata))
21003 res = FALSE;
b9e920ec 21004
dda8d76d 21005 if (! process_syminfo (filedata))
32ec8896 21006 res = FALSE;
252b5132 21007
dda8d76d 21008 if (! process_version_sections (filedata))
32ec8896 21009 res = FALSE;
252b5132 21010
82ed9683 21011 if (filedata->file_header.e_shstrndx != SHN_UNDEF)
24841daa 21012 have_separate_files = load_separate_debug_files (filedata, filedata->file_name);
82ed9683 21013 else
24841daa 21014 have_separate_files = FALSE;
dda8d76d
NC
21015
21016 if (! process_section_contents (filedata))
32ec8896 21017 res = FALSE;
f5842774 21018
24841daa 21019 if (have_separate_files)
dda8d76d 21020 {
24841daa
NC
21021 separate_info * d;
21022
21023 for (d = first_separate_info; d != NULL; d = d->next)
21024 {
21025 if (! process_section_headers (d->handle))
21026 res = FALSE;
21027 else if (! process_section_contents (d->handle))
21028 res = FALSE;
21029 }
21030
21031 /* The file handles are closed by the call to free_debug_memory() below. */
dda8d76d
NC
21032 }
21033
21034 if (! process_notes (filedata))
32ec8896 21035 res = FALSE;
103f02d3 21036
dda8d76d 21037 if (! process_gnu_liblist (filedata))
32ec8896 21038 res = FALSE;
047b2264 21039
dda8d76d 21040 if (! process_arch_specific (filedata))
32ec8896 21041 res = FALSE;
252b5132 21042
dda8d76d
NC
21043 free (filedata->program_headers);
21044 filedata->program_headers = NULL;
d93f0186 21045
dda8d76d
NC
21046 free (filedata->section_headers);
21047 filedata->section_headers = NULL;
252b5132 21048
dda8d76d
NC
21049 free (filedata->string_table);
21050 filedata->string_table = NULL;
21051 filedata->string_table_length = 0;
252b5132 21052
9db70fc3
AM
21053 free (filedata->dump.dump_sects);
21054 filedata->dump.dump_sects = NULL;
21055 filedata->dump.num_dump_sects = 0;
a788aedd 21056
9db70fc3
AM
21057 free (filedata->dynamic_strings);
21058 filedata->dynamic_strings = NULL;
21059 filedata->dynamic_strings_length = 0;
252b5132 21060
9db70fc3
AM
21061 free (filedata->dynamic_symbols);
21062 filedata->dynamic_symbols = NULL;
21063 filedata->num_dynamic_syms = 0;
252b5132 21064
9db70fc3
AM
21065 free (filedata->dynamic_syminfo);
21066 filedata->dynamic_syminfo = NULL;
ff78d6d6 21067
9db70fc3
AM
21068 free (filedata->dynamic_section);
21069 filedata->dynamic_section = NULL;
293c573e 21070
978c4450 21071 while (filedata->symtab_shndx_list != NULL)
8fb879cd 21072 {
978c4450
AM
21073 elf_section_list *next = filedata->symtab_shndx_list->next;
21074 free (filedata->symtab_shndx_list);
21075 filedata->symtab_shndx_list = next;
8fb879cd
AM
21076 }
21077
9db70fc3
AM
21078 free (filedata->section_headers_groups);
21079 filedata->section_headers_groups = NULL;
e4b17d5c 21080
978c4450 21081 if (filedata->section_groups)
e4b17d5c 21082 {
2cf0635d
NC
21083 struct group_list * g;
21084 struct group_list * next;
e4b17d5c 21085
978c4450 21086 for (i = 0; i < filedata->group_count; i++)
e4b17d5c 21087 {
978c4450 21088 for (g = filedata->section_groups [i].root; g != NULL; g = next)
e4b17d5c
L
21089 {
21090 next = g->next;
21091 free (g);
21092 }
21093 }
21094
978c4450
AM
21095 free (filedata->section_groups);
21096 filedata->section_groups = NULL;
e4b17d5c
L
21097 }
21098
19e6b90e 21099 free_debug_memory ();
18bd398b 21100
32ec8896 21101 return res;
252b5132
RH
21102}
21103
2cf0635d 21104/* Process an ELF archive.
32ec8896
NC
21105 On entry the file is positioned just after the ARMAG string.
21106 Returns TRUE upon success, FALSE otherwise. */
2cf0635d 21107
32ec8896 21108static bfd_boolean
dda8d76d 21109process_archive (Filedata * filedata, bfd_boolean is_thin_archive)
2cf0635d
NC
21110{
21111 struct archive_info arch;
21112 struct archive_info nested_arch;
21113 size_t got;
32ec8896 21114 bfd_boolean ret = TRUE;
2cf0635d 21115
32ec8896 21116 show_name = TRUE;
2cf0635d
NC
21117
21118 /* The ARCH structure is used to hold information about this archive. */
21119 arch.file_name = NULL;
21120 arch.file = NULL;
21121 arch.index_array = NULL;
21122 arch.sym_table = NULL;
21123 arch.longnames = NULL;
21124
21125 /* The NESTED_ARCH structure is used as a single-item cache of information
21126 about a nested archive (when members of a thin archive reside within
21127 another regular archive file). */
21128 nested_arch.file_name = NULL;
21129 nested_arch.file = NULL;
21130 nested_arch.index_array = NULL;
21131 nested_arch.sym_table = NULL;
21132 nested_arch.longnames = NULL;
21133
dda8d76d 21134 if (setup_archive (&arch, filedata->file_name, filedata->handle,
780f96ae
AM
21135 filedata->file_size, is_thin_archive,
21136 do_archive_index) != 0)
2cf0635d 21137 {
32ec8896 21138 ret = FALSE;
2cf0635d 21139 goto out;
4145f1d5 21140 }
fb52b2f4 21141
4145f1d5
NC
21142 if (do_archive_index)
21143 {
2cf0635d 21144 if (arch.sym_table == NULL)
1cb7d8b1
AM
21145 error (_("%s: unable to dump the index as none was found\n"),
21146 filedata->file_name);
4145f1d5
NC
21147 else
21148 {
591f7597 21149 unsigned long i, l;
4145f1d5
NC
21150 unsigned long current_pos;
21151
1cb7d8b1
AM
21152 printf (_("Index of archive %s: (%lu entries, 0x%lx bytes "
21153 "in the symbol table)\n"),
21154 filedata->file_name, (unsigned long) arch.index_num,
21155 arch.sym_size);
dda8d76d
NC
21156
21157 current_pos = ftell (filedata->handle);
4145f1d5 21158
2cf0635d 21159 for (i = l = 0; i < arch.index_num; i++)
4145f1d5 21160 {
1cb7d8b1
AM
21161 if (i == 0
21162 || (i > 0 && arch.index_array[i] != arch.index_array[i - 1]))
21163 {
21164 char * member_name
21165 = get_archive_member_name_at (&arch, arch.index_array[i],
21166 &nested_arch);
2cf0635d 21167
1cb7d8b1
AM
21168 if (member_name != NULL)
21169 {
21170 char * qualified_name
21171 = make_qualified_name (&arch, &nested_arch,
21172 member_name);
2cf0635d 21173
1cb7d8b1
AM
21174 if (qualified_name != NULL)
21175 {
21176 printf (_("Contents of binary %s at offset "),
21177 qualified_name);
c2a7d3f5
NC
21178 (void) print_vma (arch.index_array[i], PREFIX_HEX);
21179 putchar ('\n');
1cb7d8b1
AM
21180 free (qualified_name);
21181 }
fd486f32 21182 free (member_name);
4145f1d5
NC
21183 }
21184 }
2cf0635d
NC
21185
21186 if (l >= arch.sym_size)
4145f1d5 21187 {
1cb7d8b1
AM
21188 error (_("%s: end of the symbol table reached "
21189 "before the end of the index\n"),
dda8d76d 21190 filedata->file_name);
32ec8896 21191 ret = FALSE;
cb8f3167 21192 break;
4145f1d5 21193 }
591f7597 21194 /* PR 17531: file: 0b6630b2. */
1cb7d8b1
AM
21195 printf ("\t%.*s\n",
21196 (int) (arch.sym_size - l), arch.sym_table + l);
591f7597 21197 l += strnlen (arch.sym_table + l, arch.sym_size - l) + 1;
4145f1d5
NC
21198 }
21199
67ce483b 21200 if (arch.uses_64bit_indices)
c2a7d3f5
NC
21201 l = (l + 7) & ~ 7;
21202 else
21203 l += l & 1;
21204
2cf0635d 21205 if (l < arch.sym_size)
32ec8896 21206 {
d3a49aa8
AM
21207 error (ngettext ("%s: %ld byte remains in the symbol table, "
21208 "but without corresponding entries in "
21209 "the index table\n",
21210 "%s: %ld bytes remain in the symbol table, "
21211 "but without corresponding entries in "
21212 "the index table\n",
21213 arch.sym_size - l),
dda8d76d 21214 filedata->file_name, arch.sym_size - l);
32ec8896
NC
21215 ret = FALSE;
21216 }
4145f1d5 21217
dda8d76d 21218 if (fseek (filedata->handle, current_pos, SEEK_SET) != 0)
4145f1d5 21219 {
1cb7d8b1
AM
21220 error (_("%s: failed to seek back to start of object files "
21221 "in the archive\n"),
dda8d76d 21222 filedata->file_name);
32ec8896 21223 ret = FALSE;
2cf0635d 21224 goto out;
4145f1d5 21225 }
fb52b2f4 21226 }
4145f1d5
NC
21227
21228 if (!do_dynamic && !do_syms && !do_reloc && !do_unwind && !do_sections
21229 && !do_segments && !do_header && !do_dump && !do_version
21230 && !do_histogram && !do_debugging && !do_arch && !do_notes
2c610e4b 21231 && !do_section_groups && !do_dyn_syms)
2cf0635d 21232 {
32ec8896 21233 ret = TRUE; /* Archive index only. */
2cf0635d
NC
21234 goto out;
21235 }
fb52b2f4
NC
21236 }
21237
fb52b2f4
NC
21238 while (1)
21239 {
2cf0635d
NC
21240 char * name;
21241 size_t namelen;
21242 char * qualified_name;
21243
21244 /* Read the next archive header. */
dda8d76d 21245 if (fseek (filedata->handle, arch.next_arhdr_offset, SEEK_SET) != 0)
1cb7d8b1
AM
21246 {
21247 error (_("%s: failed to seek to next archive header\n"),
21248 arch.file_name);
21249 ret = FALSE;
21250 break;
21251 }
dda8d76d 21252 got = fread (&arch.arhdr, 1, sizeof arch.arhdr, filedata->handle);
2cf0635d 21253 if (got != sizeof arch.arhdr)
1cb7d8b1
AM
21254 {
21255 if (got == 0)
2cf0635d 21256 break;
28e817cc
NC
21257 /* PR 24049 - we cannot use filedata->file_name as this will
21258 have already been freed. */
21259 error (_("%s: failed to read archive header\n"), arch.file_name);
9abca702 21260
1cb7d8b1
AM
21261 ret = FALSE;
21262 break;
21263 }
2cf0635d 21264 if (memcmp (arch.arhdr.ar_fmag, ARFMAG, 2) != 0)
1cb7d8b1
AM
21265 {
21266 error (_("%s: did not find a valid archive header\n"),
21267 arch.file_name);
21268 ret = FALSE;
21269 break;
21270 }
2cf0635d
NC
21271
21272 arch.next_arhdr_offset += sizeof arch.arhdr;
21273
978c4450
AM
21274 filedata->archive_file_size = strtoul (arch.arhdr.ar_size, NULL, 10);
21275 if (filedata->archive_file_size & 01)
21276 ++filedata->archive_file_size;
2cf0635d
NC
21277
21278 name = get_archive_member_name (&arch, &nested_arch);
21279 if (name == NULL)
fb52b2f4 21280 {
28e817cc 21281 error (_("%s: bad archive file name\n"), arch.file_name);
32ec8896 21282 ret = FALSE;
d989285c 21283 break;
fb52b2f4 21284 }
2cf0635d 21285 namelen = strlen (name);
fb52b2f4 21286
2cf0635d
NC
21287 qualified_name = make_qualified_name (&arch, &nested_arch, name);
21288 if (qualified_name == NULL)
fb52b2f4 21289 {
28e817cc 21290 error (_("%s: bad archive file name\n"), arch.file_name);
fd486f32 21291 free (name);
32ec8896 21292 ret = FALSE;
d989285c 21293 break;
fb52b2f4
NC
21294 }
21295
2cf0635d 21296 if (is_thin_archive && arch.nested_member_origin == 0)
1cb7d8b1
AM
21297 {
21298 /* This is a proxy for an external member of a thin archive. */
21299 Filedata * member_filedata;
21300 char * member_file_name = adjust_relative_path
dda8d76d 21301 (filedata->file_name, name, namelen);
32ec8896 21302
fd486f32 21303 free (name);
1cb7d8b1
AM
21304 if (member_file_name == NULL)
21305 {
fd486f32 21306 free (qualified_name);
1cb7d8b1
AM
21307 ret = FALSE;
21308 break;
21309 }
2cf0635d 21310
1cb7d8b1
AM
21311 member_filedata = open_file (member_file_name);
21312 if (member_filedata == NULL)
21313 {
21314 error (_("Input file '%s' is not readable.\n"), member_file_name);
21315 free (member_file_name);
fd486f32 21316 free (qualified_name);
1cb7d8b1
AM
21317 ret = FALSE;
21318 break;
21319 }
2cf0635d 21320
978c4450 21321 filedata->archive_file_offset = arch.nested_member_origin;
dda8d76d 21322 member_filedata->file_name = qualified_name;
2cf0635d 21323
1cb7d8b1 21324 if (! process_object (member_filedata))
32ec8896 21325 ret = FALSE;
2cf0635d 21326
1cb7d8b1
AM
21327 close_file (member_filedata);
21328 free (member_file_name);
1cb7d8b1 21329 }
2cf0635d 21330 else if (is_thin_archive)
1cb7d8b1
AM
21331 {
21332 Filedata thin_filedata;
eb02c04d 21333
1cb7d8b1 21334 memset (&thin_filedata, 0, sizeof (thin_filedata));
dda8d76d 21335
a043396b
NC
21336 /* PR 15140: Allow for corrupt thin archives. */
21337 if (nested_arch.file == NULL)
21338 {
21339 error (_("%s: contains corrupt thin archive: %s\n"),
28e817cc 21340 qualified_name, name);
fd486f32
AM
21341 free (qualified_name);
21342 free (name);
32ec8896 21343 ret = FALSE;
a043396b
NC
21344 break;
21345 }
fd486f32 21346 free (name);
a043396b 21347
1cb7d8b1 21348 /* This is a proxy for a member of a nested archive. */
978c4450
AM
21349 filedata->archive_file_offset
21350 = arch.nested_member_origin + sizeof arch.arhdr;
2cf0635d 21351
1cb7d8b1
AM
21352 /* The nested archive file will have been opened and setup by
21353 get_archive_member_name. */
978c4450
AM
21354 if (fseek (nested_arch.file, filedata->archive_file_offset,
21355 SEEK_SET) != 0)
1cb7d8b1
AM
21356 {
21357 error (_("%s: failed to seek to archive member.\n"),
21358 nested_arch.file_name);
fd486f32 21359 free (qualified_name);
1cb7d8b1
AM
21360 ret = FALSE;
21361 break;
21362 }
2cf0635d 21363
dda8d76d
NC
21364 thin_filedata.handle = nested_arch.file;
21365 thin_filedata.file_name = qualified_name;
9abca702 21366
1cb7d8b1 21367 if (! process_object (& thin_filedata))
32ec8896 21368 ret = FALSE;
1cb7d8b1 21369 }
2cf0635d 21370 else
1cb7d8b1 21371 {
fd486f32 21372 free (name);
978c4450 21373 filedata->archive_file_offset = arch.next_arhdr_offset;
6a6196fc 21374 filedata->file_name = qualified_name;
1cb7d8b1 21375 if (! process_object (filedata))
32ec8896 21376 ret = FALSE;
978c4450 21377 arch.next_arhdr_offset += filedata->archive_file_size;
4c836627 21378 /* Stop looping with "negative" archive_file_size. */
978c4450 21379 if (arch.next_arhdr_offset < filedata->archive_file_size)
80e2a3b6 21380 arch.next_arhdr_offset = -1ul;
1cb7d8b1 21381 }
fb52b2f4 21382
2cf0635d 21383 free (qualified_name);
fb52b2f4
NC
21384 }
21385
4145f1d5 21386 out:
2cf0635d
NC
21387 if (nested_arch.file != NULL)
21388 fclose (nested_arch.file);
21389 release_archive (&nested_arch);
21390 release_archive (&arch);
fb52b2f4 21391
d989285c 21392 return ret;
fb52b2f4
NC
21393}
21394
32ec8896 21395static bfd_boolean
2cf0635d 21396process_file (char * file_name)
fb52b2f4 21397{
dda8d76d 21398 Filedata * filedata = NULL;
fb52b2f4
NC
21399 struct stat statbuf;
21400 char armag[SARMAG];
32ec8896 21401 bfd_boolean ret = TRUE;
fb52b2f4
NC
21402
21403 if (stat (file_name, &statbuf) < 0)
21404 {
f24ddbdd
NC
21405 if (errno == ENOENT)
21406 error (_("'%s': No such file\n"), file_name);
21407 else
21408 error (_("Could not locate '%s'. System error message: %s\n"),
21409 file_name, strerror (errno));
32ec8896 21410 return FALSE;
f24ddbdd
NC
21411 }
21412
21413 if (! S_ISREG (statbuf.st_mode))
21414 {
21415 error (_("'%s' is not an ordinary file\n"), file_name);
32ec8896 21416 return FALSE;
fb52b2f4
NC
21417 }
21418
dda8d76d
NC
21419 filedata = calloc (1, sizeof * filedata);
21420 if (filedata == NULL)
21421 {
21422 error (_("Out of memory allocating file data structure\n"));
21423 return FALSE;
21424 }
21425
21426 filedata->file_name = file_name;
21427 filedata->handle = fopen (file_name, "rb");
21428 if (filedata->handle == NULL)
fb52b2f4 21429 {
f24ddbdd 21430 error (_("Input file '%s' is not readable.\n"), file_name);
dda8d76d 21431 free (filedata);
32ec8896 21432 return FALSE;
fb52b2f4
NC
21433 }
21434
dda8d76d 21435 if (fread (armag, SARMAG, 1, filedata->handle) != 1)
fb52b2f4 21436 {
4145f1d5 21437 error (_("%s: Failed to read file's magic number\n"), file_name);
dda8d76d
NC
21438 fclose (filedata->handle);
21439 free (filedata);
32ec8896 21440 return FALSE;
fb52b2f4
NC
21441 }
21442
dda8d76d 21443 filedata->file_size = (bfd_size_type) statbuf.st_size;
f54498b4 21444
fb52b2f4 21445 if (memcmp (armag, ARMAG, SARMAG) == 0)
32ec8896 21446 {
dda8d76d 21447 if (! process_archive (filedata, FALSE))
32ec8896
NC
21448 ret = FALSE;
21449 }
2cf0635d 21450 else if (memcmp (armag, ARMAGT, SARMAG) == 0)
32ec8896 21451 {
dda8d76d 21452 if ( ! process_archive (filedata, TRUE))
32ec8896
NC
21453 ret = FALSE;
21454 }
fb52b2f4
NC
21455 else
21456 {
1b513401 21457 if (do_archive_index && !check_all)
4145f1d5
NC
21458 error (_("File %s is not an archive so its index cannot be displayed.\n"),
21459 file_name);
21460
dda8d76d 21461 rewind (filedata->handle);
978c4450 21462 filedata->archive_file_size = filedata->archive_file_offset = 0;
32ec8896 21463
dda8d76d 21464 if (! process_object (filedata))
32ec8896 21465 ret = FALSE;
fb52b2f4
NC
21466 }
21467
dda8d76d 21468 fclose (filedata->handle);
8fb879cd
AM
21469 free (filedata->section_headers);
21470 free (filedata->program_headers);
21471 free (filedata->string_table);
6431e409 21472 free (filedata->dump.dump_sects);
dda8d76d 21473 free (filedata);
32ec8896 21474
fd486f32 21475 free (ba_cache.strtab);
1bd6175a 21476 ba_cache.strtab = NULL;
fd486f32 21477 free (ba_cache.symtab);
1bd6175a 21478 ba_cache.symtab = NULL;
fd486f32
AM
21479 ba_cache.filedata = NULL;
21480
fb52b2f4
NC
21481 return ret;
21482}
21483
252b5132
RH
21484#ifdef SUPPORT_DISASSEMBLY
21485/* Needed by the i386 disassembler. For extra credit, someone could
9ea033b2 21486 fix this so that we insert symbolic addresses here, esp for GOT/PLT
e3c8793a 21487 symbols. */
252b5132
RH
21488
21489void
2cf0635d 21490print_address (unsigned int addr, FILE * outfile)
252b5132
RH
21491{
21492 fprintf (outfile,"0x%8.8x", addr);
21493}
21494
e3c8793a 21495/* Needed by the i386 disassembler. */
dda8d76d 21496
252b5132
RH
21497void
21498db_task_printsym (unsigned int addr)
21499{
21500 print_address (addr, stderr);
21501}
21502#endif
21503
21504int
2cf0635d 21505main (int argc, char ** argv)
252b5132 21506{
ff78d6d6
L
21507 int err;
21508
252b5132
RH
21509#if defined (HAVE_SETLOCALE) && defined (HAVE_LC_MESSAGES)
21510 setlocale (LC_MESSAGES, "");
3882b010
L
21511#endif
21512#if defined (HAVE_SETLOCALE)
21513 setlocale (LC_CTYPE, "");
252b5132
RH
21514#endif
21515 bindtextdomain (PACKAGE, LOCALEDIR);
21516 textdomain (PACKAGE);
21517
869b9d07
MM
21518 expandargv (&argc, &argv);
21519
dda8d76d 21520 parse_args (& cmdline, argc, argv);
59f14fc0 21521
18bd398b 21522 if (optind < (argc - 1))
1b513401
NC
21523 /* When displaying information for more than one file,
21524 prefix the information with the file name. */
32ec8896 21525 show_name = TRUE;
5656ba2c
L
21526 else if (optind >= argc)
21527 {
1b513401
NC
21528 /* Ensure that the warning is always displayed. */
21529 do_checks = TRUE;
21530
5656ba2c
L
21531 warn (_("Nothing to do.\n"));
21532 usage (stderr);
21533 }
18bd398b 21534
32ec8896 21535 err = FALSE;
252b5132 21536 while (optind < argc)
32ec8896
NC
21537 if (! process_file (argv[optind++]))
21538 err = TRUE;
252b5132 21539
9db70fc3 21540 free (cmdline.dump_sects);
252b5132 21541
7d9813f1
NA
21542 free (dump_ctf_symtab_name);
21543 free (dump_ctf_strtab_name);
21544 free (dump_ctf_parent_name);
21545
32ec8896 21546 return err ? EXIT_FAILURE : EXIT_SUCCESS;
252b5132 21547}